From 5bec8cdf811e43465da37c9c4d82210abc001d50 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Sun, 18 Dec 2022 18:54:38 -0700 Subject: [PATCH 001/170] introduce simple data mode as an constant configurable forcing. in this initial commit, it is just a copy of CORE2-NYF. --- datm/CMakeLists.txt | 3 +- datm/atm_comp_nuopc.F90 | 24 +- datm/cime_config/config_component.xml | 6 +- datm/cime_config/namelist_definition_datm.xml | 10 +- datm/cime_config/stream_definition_datm.xml | 1 + datm/datm_datamode_simple_mod.F90 | 344 ++++++++++++++++++ 6 files changed, 383 insertions(+), 5 deletions(-) create mode 100644 datm/datm_datamode_simple_mod.F90 diff --git a/datm/CMakeLists.txt b/datm/CMakeLists.txt index d96060ab2..d095d0c53 100644 --- a/datm/CMakeLists.txt +++ b/datm/CMakeLists.txt @@ -6,7 +6,8 @@ set(SRCFILES atm_comp_nuopc.F90 datm_datamode_jra_mod.F90 datm_datamode_gefs_mod.F90 datm_datamode_cfsr_mod.F90 - datm_datamode_era5_mod.F90) + datm_datamode_era5_mod.F90 + datm_datamode_simple_mod.F90) foreach(FILE ${SRCFILES}) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 99a91841b..f989d498a 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -81,6 +81,12 @@ module cdeps_datm_comp use datm_datamode_cfsr_mod , only : datm_datamode_cfsr_restart_write use datm_datamode_cfsr_mod , only : datm_datamode_cfsr_restart_read + use datm_datamode_simple_mod , only : datm_datamode_simple_advertise + use datm_datamode_simple_mod , only : datm_datamode_simple_init_pointers + use datm_datamode_simple_mod , only : datm_datamode_simple_advance + use datm_datamode_simple_mod , only : datm_datamode_simple_restart_write + use datm_datamode_simple_mod , only : datm_datamode_simple_restart_read + implicit none private ! except @@ -305,7 +311,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) trim(datamode) == 'CPLHIST' .or. & trim(datamode) == 'GEFS' .or. & trim(datamode) == 'CFSR' .or. & - trim(datamode) == 'ERA5') then + trim(datamode) == 'ERA5' .or. & + trim(datamode) == 'SIMPLE') then else call shr_sys_abort(' ERROR illegal datm datamode = '//trim(datamode)) endif @@ -337,6 +344,9 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) case ('CFSR') call datm_datamode_cfsr_advertise(exportState, fldsExport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case ('SIMPLE') + call datm_datamode_simple_advertise(exportState, fldsExport, flds_scalar_name, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select end subroutine InitializeAdvertise @@ -580,6 +590,9 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe case('CFSR') call datm_datamode_cfsr_init_pointers(exportState, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('SIMPLE') + call datm_datamode_simple_init_pointers(exportState, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Read restart if needed @@ -599,6 +612,8 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe call datm_datamode_gefs_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) case('CFSR') call datm_datamode_cfsr_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + case('SIMPLE') + call datm_datamode_simple_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) end select end if @@ -653,6 +668,10 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe call datm_datamode_cfsr_advance(exportstate, mainproc, logunit, mpicom, target_ymd, & target_tod, sdat%model_calendar, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('SIMPLE') + call datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & + sdat%model_calendar, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Write restarts if needed @@ -681,6 +700,9 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe call datm_datamode_cfsr_restart_write(case_name, inst_suffix, target_ymd, target_tod, & logunit, my_task, sdat) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('SIMPLE') + call datm_datamode_simple_restart_write(case_name, inst_suffix, target_ymd, target_tod, & + logunit, my_task, sdat) end select end if diff --git a/datm/cime_config/config_component.xml b/datm/cime_config/config_component.xml index 9ff459f51..9dc3a2dc0 100644 --- a/datm/cime_config/config_component.xml +++ b/datm/cime_config/config_component.xml @@ -10,7 +10,7 @@ This file may have atm desc entries. --> - Data driven ATM + Data driven ATM QIAN data set QIAN with water isotopes CRUNCEP data set @@ -27,6 +27,7 @@ JRA55 Repeat Year Forcing v1.3 1990-1991 JRA55 Repeat Year Forcing v1.3 2003-2004 ERA5 interannual forcing + Namelist-configurable, constant datm forcing for simple experiments @@ -40,7 +41,7 @@ char - CORE2_NYF,CORE2_IAF,CLM_QIAN,CLM_QIAN_WISO,1PT,CLMCRUNCEP,CLMCRUNCEPv7,CLMGSWP3v1,CLMNLDAS2,CPLHIST,CORE_IAF_JRA,CORE_IAF_JRA_1p4_2018,ERA5 + CORE2_NYF,CORE2_IAF,CLM_QIAN,CLM_QIAN_WISO,1PT,CLMCRUNCEP,CLMCRUNCEPv7,CLMGSWP3v1,CLMNLDAS2,CPLHIST,CORE_IAF_JRA,CORE_IAF_JRA_1p4_2018,ERA5,SIMPLE CORE2_NYF run_component_datm env_run.xml @@ -61,6 +62,7 @@ 1PT CPLHIST ERA5 + SIMPLE diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index c677bffe0..0ced9fb87 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -70,6 +70,9 @@ ERA5_HOURLY + + CORE2_NYF.GISS,CORE2_NYF.NCEP + CPLHISTForcing.Solar,CPLHISTForcing.nonSolarFlux,CPLHISTForcing.State3hr,CPLHISTForcing.State1hr @@ -80,7 +83,7 @@ char datm datm_nml - CLMNCEP,CORE2_NYF,CORE2_IAF,CORE_IAF_JRA,ERA5,CPLHIST,1PT + CLMNCEP,CORE2_NYF,CORE2_IAF,CORE_IAF_JRA,ERA5,SIMPLE,CPLHIST,1PT general method that operates on the data. ----datamode = "CPLHIST"---- @@ -114,6 +117,8 @@ active-land-only simulations. ----datamode = "ERA5"---- Fifth generation ECMWF atmospheric reanalysis of the global climate + ----datamode = "SIMPLE"---- + Namelist-configurable, constant datm forcing for simple experiments ----datamode = "CPLHIST" ---- @@ -132,6 +137,9 @@ ERA5 + + SIMPLE + CPLHIST diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index c29decdca..dd10c860e 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -41,6 +41,7 @@ CORE_RYF9091_JRA = JRA55 repeat year forcing, v1.3, 1990-1991 (for forcing POP and CICE) CORE_RYF0304_JRA = JRA55 repeat year forcing, v1.3, 2003-2004 (for forcing POP and CICE) ERA5 = ERA5 intra-annual year forcing + SIMPLE = Namelist-configurable, constant datm forcing for simple experiments CPLHIST = Streams for lnd or ocn/ice forcing used for spinup Currently the following optional streams are supported diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 new file mode 100644 index 000000000..88945dee9 --- /dev/null +++ b/datm/datm_datamode_simple_mod.F90 @@ -0,0 +1,344 @@ +module datm_datamode_simple_mod + + use ESMF , only : ESMF_State, ESMF_StateGet, ESMF_Field, ESMF_FieldBundle + use ESMF , only : ESMF_DistGrid, ESMF_RouteHandle, ESMF_MeshCreate + use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MeshCreate + use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_FILEFORMAT_ESMFMESH + use ESMF , only : ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND, operator(/=) + use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldCreate, ESMF_MESHLOC_ELEMENT + use ESMF , only : ESMF_FieldBundleAdd, ESMF_LOGMSG_INFO, ESMF_TYPEKIND_R8 + use ESMF , only : ESMF_RouteHandleDestroy, ESMF_EXTRAPMETHOD_NEAREST_STOD + use ESMF , only : ESMF_POLEMETHOD_ALLAVG, ESMF_REGRIDMETHOD_BILINEAR + use ESMF , only : ESMF_DistGridGet, ESMF_FieldRegridStore, ESMF_FieldRedistStore + use pio , only : Var_Desc_t, file_desc_t, io_desc_t, pio_read_darray, pio_freedecomp + use pio , only : pio_openfile, PIO_NOWRITE, pio_seterrorhandling, PIO_BCAST_ERROR + use pio , only : pio_initdecomp, pio_inq_dimlen, pio_inq_varid + use pio , only : pio_inq_varndims, pio_inq_vardimid, pio_double + use pio , only : pio_closefile + use NUOPC , only : NUOPC_Advertise + use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use shr_cal_mod , only : shr_cal_date2julian + use shr_const_mod , only : shr_const_tkfrz, shr_const_pi + use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type + use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, dshr_fldbun_regrid, chkerr + use dshr_mod , only : dshr_restart_read, dshr_restart_write + use dshr_strdata_mod , only : shr_strdata_type + use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add + + implicit none + private ! except + + public :: datm_datamode_simple_advertise + public :: datm_datamode_simple_init_pointers + public :: datm_datamode_simple_advance + public :: datm_datamode_simple_restart_write + public :: datm_datamode_simple_restart_read + + ! export state pointers + real(r8), pointer :: Sa_u(:) => null() + real(r8), pointer :: Sa_v(:) => null() + real(r8), pointer :: Sa_z(:) => null() + real(r8), pointer :: Sa_tbot(:) => null() + real(r8), pointer :: Sa_ptem(:) => null() + real(r8), pointer :: Sa_shum(:) => null() + real(r8), pointer :: Sa_pbot(:) => null() + real(r8), pointer :: Sa_pslv(:) => null() + real(r8), pointer :: Faxa_lwdn(:) => null() + real(r8), pointer :: Faxa_rainc(:) => null() + real(r8), pointer :: Faxa_rainl(:) => null() + real(r8), pointer :: Faxa_snowc(:) => null() + real(r8), pointer :: Faxa_snowl(:) => null() + real(r8), pointer :: Faxa_swndr(:) => null() + real(r8), pointer :: Faxa_swndf(:) => null() + real(r8), pointer :: Faxa_swvdr(:) => null() + real(r8), pointer :: Faxa_swvdf(:) => null() + real(r8), pointer :: Faxa_swnet(:) => null() + real(r8), pointer :: Faxa_ndep(:,:) => null() + + ! stream data + real(r8), pointer :: strm_swdn(:) => null() + real(r8), pointer :: strm_tarcf(:) => null() + + ! othe module arrays + real(R8), pointer :: yc(:) ! array of model latitudes + + ! constants + real(R8) , parameter :: tKFrz = SHR_CONST_TKFRZ + real(R8) , parameter :: degtorad = SHR_CONST_PI/180.0_R8 + real(R8) , parameter :: phs_c0 = 0.298_R8 + real(R8) , parameter :: dLWarc = -5.000_R8 + + character(*), parameter :: nullstr = 'null' + character(*), parameter :: rpfile = 'rpointer.atm' + character(*), parameter :: u_FILE_u = & + __FILE__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_name, rc) + + ! input/output variables + type(esmf_State) , intent(inout) :: exportState + type(fldlist_type) , pointer :: fldsexport + character(len=*) , intent(in) :: flds_scalar_name + integer , intent(out) :: rc + + ! local variables + type(fldlist_type), pointer :: fldList + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsExport, 'Sa_z' ) + call dshr_fldList_add(fldsExport, 'Sa_u' ) + call dshr_fldList_add(fldsExport, 'Sa_v' ) + call dshr_fldList_add(fldsExport, 'Sa_ptem' ) + call dshr_fldList_add(fldsExport, 'Sa_dens' ) + call dshr_fldList_add(fldsExport, 'Sa_pslv' ) + call dshr_fldList_add(fldsExport, 'Sa_tbot' ) + call dshr_fldList_add(fldsExport, 'Sa_pbot' ) + call dshr_fldList_add(fldsExport, 'Sa_shum' ) + call dshr_fldList_add(fldsExport, 'Faxa_rainc' ) + call dshr_fldList_add(fldsExport, 'Faxa_rainl' ) + call dshr_fldList_add(fldsExport, 'Faxa_snowc' ) + call dshr_fldList_add(fldsExport, 'Faxa_snowl' ) + call dshr_fldList_add(fldsExport, 'Faxa_swndr' ) + call dshr_fldList_add(fldsExport, 'Faxa_swvdr' ) + call dshr_fldList_add(fldsExport, 'Faxa_swndf' ) + call dshr_fldList_add(fldsExport, 'Faxa_swvdf' ) + call dshr_fldList_add(fldsExport, 'Faxa_swnet' ) + call dshr_fldList_add(fldsExport, 'Faxa_lwdn' ) + call dshr_fldList_add(fldsExport, 'Faxa_swdn' ) + + fldlist => fldsExport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(exportState, standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite('(datm_comp_advertise): Fr_atm'//trim(fldList%stdname), ESMF_LOGMSG_INFO) + fldList => fldList%next + enddo + + end subroutine datm_datamode_simple_advertise + + !=============================================================================== + subroutine datm_datamode_simple_init_pointers(exportState, sdat, rc) + + ! input/output variables + type(ESMF_State) , intent(inout) :: exportState + type(shr_strdata_type) , intent(in) :: sdat + integer , intent(out) :: rc + + ! local variables + integer :: n + integer :: lsize + integer :: spatialDim ! number of dimension in mesh + integer :: numOwnedElements ! size of mesh + real(r8), pointer :: ownedElemCoords(:) ! mesh lat and lons + type(ESMF_StateItem_Flag) :: itemFlag + character(len=*), parameter :: subname='(datm_init_pointers): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + lsize = sdat%model_lsize + + call ESMF_MeshGet(sdat%model_mesh, spatialDim=spatialDim, numOwnedElements=numOwnedElements, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(ownedElemCoords(spatialDim*numOwnedElements)) + allocate(yc(numOwnedElements)) + call ESMF_MeshGet(sdat%model_mesh, ownedElemCoords=ownedElemCoords) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1,numOwnedElements + yc(n) = ownedElemCoords(2*n) + end do + + ! get stream pointers + !todo call shr_strdata_get_stream_pointer( sdat, 'Faxa_prec' , strm_prec , rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call shr_strdata_get_stream_pointer( sdat, 'Faxa_swdn' , strm_swdn , rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call shr_strdata_get_stream_pointer( sdat, 'tarcf' , strm_tarcf , rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! get export state pointers + call dshr_state_getfldptr(exportState, 'Sa_z' , fldptr1=Sa_z , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_u' , fldptr1=Sa_u , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_v' , fldptr1=Sa_v , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_tbot' , fldptr1=Sa_tbot , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_pbot' , fldptr1=Sa_pbot , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_pslv' , fldptr1=Sa_pslv , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_ptem' , fldptr1=Sa_ptem , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_shum' , fldptr1=Sa_shum , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_rainc' , fldptr1=Faxa_rainc , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_rainl' , fldptr1=Faxa_rainl , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_snowc' , fldptr1=Faxa_snowc , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_snowl' , fldptr1=Faxa_snowl , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_swvdr' , fldptr1=Faxa_swvdr , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_swvdf' , fldptr1=Faxa_swvdf , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_swndr' , fldptr1=Faxa_swndr , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_swndf' , fldptr1=Faxa_swndf , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_swnet' , fldptr1=Faxa_swnet , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_lwdn' , fldptr1=Faxa_lwdn , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_StateGet(exportstate, 'Faxa_ndep', itemFlag, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (itemflag /= ESMF_STATEITEM_NOTFOUND) then + call dshr_state_getfldptr(exportState, 'Faxa_ndep', fldptr2=Faxa_ndep, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + if (.not. associated(strm_swdn)) then + call shr_sys_abort(trim(subname)//'ERROR: swdn must be in streams for SIMPLE') + endif + + end subroutine datm_datamode_simple_init_pointers + + !=============================================================================== + subroutine datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & + model_calendar, rc) + + ! input/output variables + integer , intent(in) :: target_ymd + integer , intent(in) :: target_tod + integer , intent(in) :: target_mon + character(len=*) , intent(in) :: model_calendar + integer , intent(out) :: rc + + ! local variables + integer :: n + integer :: lsize + real(R8) :: avg_alb ! average albedo + real(R8) :: rday ! elapsed day + real(R8) :: cosFactor ! cosine factor + real(R8) :: factor ! generic/temporary correction factor + real(R8) :: tMin ! minimum temperature + real(R8) :: uprime,vprime + character(len=*), parameter :: subname='(datm_datamode_simple): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + lsize = size(Sa_z) + + call shr_cal_date2julian(target_ymd, target_tod, rday, model_calendar) + rday = mod((rday - 1.0_R8),365.0_R8) + cosfactor = cos((2.0_R8*SHR_CONST_PI*rday)/365 - phs_c0) + + do n = 1,lsize + Sa_z(n) = 10.0_R8 + + !--- density and pslv taken directly from input stream, set pbot --- + Sa_pbot(n) = Sa_pslv(n) + + Sa_ptem(n) = Sa_tbot(n) + + !--- Dupont correction to NCEP Arctic air T --- + !--- don't correct during summer months (July-September) + !--- ONLY correct when forcing year is 1997->2004 + + Faxa_rainc(n) = 0.0_R8 ! default zero + Faxa_snowc(n) = 0.0_R8 + if (Sa_tbot(n) < tKFrz ) then ! assign precip to rain/snow components + Faxa_rainl(n) = 0.0_R8 + Faxa_snowl(n) = 0.0_R8 ! todo + else + Faxa_rainl(n) = 0.0_R8 ! todo + Faxa_snowl(n) = 0.0_R8 + endif + + ! RADIATION DATA + !--- fabricate required swdn components from net swdn --- + Faxa_swvdr(n) = strm_swdn(n)*(0.28_R8) + Faxa_swndr(n) = strm_swdn(n)*(0.31_R8) + Faxa_swvdf(n) = strm_swdn(n)*(0.24_R8) + Faxa_swndf(n) = strm_swdn(n)*(0.17_R8) + !--- compute net short-wave based on LY08 latitudinally-varying albedo --- + avg_alb = ( 0.069 - 0.011*cos(2.0_R8*yc(n)*degtorad ) ) + Faxa_swnet(n) = strm_swdn(n)*(1.0_R8 - avg_alb) + !--- corrections to GISS sswdn for heat budget balancing --- + factor = 1.0_R8 + if ( -60.0_R8 < yc(n) .and. yc(n) < -50.0_R8 ) then + factor = 1.0_R8 - (yc(n) + 60.0_R8)*(0.05_R8/10.0_R8) + else if ( -50.0_R8 < yc(n) .and. yc(n) < 30.0_R8 ) then + factor = 0.95_R8 + else if ( 30.0_R8 < yc(n) .and. yc(n) < 40._R8 ) then + factor = 1.0_R8 - (40.0_R8 - yc(n))*(0.05_R8/10.0_R8) + endif + Faxa_swnet(n) = Faxa_swnet(n)*factor + Faxa_swvdr(n) = Faxa_swvdr(n)*factor + Faxa_swndr(n) = Faxa_swndr(n)*factor + Faxa_swvdf(n) = Faxa_swvdf(n)*factor + Faxa_swndf(n) = Faxa_swndf(n)*factor + !--- correction to GISS lwdn in Arctic --- + if ( yc(n) > 60._R8 ) then + factor = MIN(1.0_R8, 0.1_R8*(yc(n)-60.0_R8) ) + Faxa_lwdn(n) = Faxa_lwdn(n) + factor * dLWarc + endif + + enddo ! lsize + + if (associated(Faxa_ndep)) then + ! convert ndep flux to units of kgN/m2/s (input is in gN/m2/s) + Faxa_ndep(:,:) = Faxa_ndep(:,:) / 1000._r8 + end if + + end subroutine datm_datamode_simple_advance + + !=============================================================================== + subroutine datm_datamode_simple_restart_write(case_name, inst_suffix, ymd, tod, & + logunit, my_task, sdat) + + ! input/output variables + character(len=*) , intent(in) :: case_name + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: ymd ! model date + integer , intent(in) :: tod ! model sec into model date + integer , intent(in) :: logunit + integer , intent(in) :: my_task + type(shr_strdata_type) , intent(inout) :: sdat + !------------------------------------------------------------------------------- + + call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & + logunit, my_task, sdat) + + end subroutine datm_datamode_simple_restart_write + + !=============================================================================== + subroutine datm_datamode_simple_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + + ! input/output arguments + character(len=*) , intent(inout) :: rest_filem + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: logunit + integer , intent(in) :: my_task + integer , intent(in) :: mpicom + type(shr_strdata_type) , intent(inout) :: sdat + !------------------------------------------------------------------------------- + + call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + + end subroutine datm_datamode_simple_restart_read + +end module datm_datamode_simple_mod From 916ca86c3321eb59af68d1fecfc2eef07132d7af Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Mon, 19 Dec 2022 10:54:22 -0700 Subject: [PATCH 002/170] add constant forcing namelist and set forcing fields to values from nml --- datm/atm_comp_nuopc.F90 | 5 +- datm/cime_config/buildnml | 2 +- datm/cime_config/namelist_definition_datm.xml | 81 +++++++++- datm/datm_datamode_simple_mod.F90 | 151 +++++++++++------- 4 files changed, 180 insertions(+), 59 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index f989d498a..aa42be306 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -255,8 +255,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) mainproc = (my_task == main_task) ! Read atm_nml from nlfilename + nlfilename = "datm_in"//trim(inst_suffix) if (my_task == main_task) then - nlfilename = "datm_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") read (nu,nml=datm_nml,iostat=ierr) close(nu) @@ -345,7 +345,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call datm_datamode_cfsr_advertise(exportState, fldsExport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('SIMPLE') - call datm_datamode_simple_advertise(exportState, fldsExport, flds_scalar_name, rc) + call datm_datamode_simple_advertise(exportState, fldsExport, flds_scalar_name, & + nlfilename, my_task, mpicom, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml index 575949b10..43f94f7d1 100755 --- a/datm/cime_config/buildnml +++ b/datm/cime_config/buildnml @@ -167,7 +167,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path # Generate datm_in namelist_file = os.path.join(confdir, "datm_in") - nmlgen.write_output_file(namelist_file, data_list_path, groups=['datm_nml']) + nmlgen.write_output_file(namelist_file, data_list_path, groups=['datm_nml','const_forcing_nml']) # Determine streams streamlist = nmlgen.get_streams() diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index 0ced9fb87..01a1505b9 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -71,7 +71,7 @@ ERA5_HOURLY - CORE2_NYF.GISS,CORE2_NYF.NCEP + CORE2_NYF.GISS CPLHISTForcing.Solar,CPLHISTForcing.nonSolarFlux,CPLHISTForcing.State3hr,CPLHISTForcing.State1hr @@ -372,4 +372,83 @@ + + real + datm + const_forcing_nml + + density at the lowest model layer + units: kg m-3 + + + 1.204 + + + + + real + datm + const_forcing_nml + + inst_pres_height_surface + units: Pa + + + 101325.0 + + + + + real + datm + const_forcing_nml + + Constant bottom layer specific humidity + units: kg kg-1 + + + 0.0 + + + + + real + datm + const_forcing_nml + + Constant air temperature at lowest model layer + units: K + + + 273.15 + + + + + real + datm + const_forcing_nml + + Constant zonal wind speed forcing for simple models. + units: m s-1 + + + 0.0 + + + + + real + datm + const_forcing_nml + + Constant meridional wind speed forcing for simple models. + units: m s-1 + + + 0.0 + + + + diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 index 88945dee9..c622d0ca3 100644 --- a/datm/datm_datamode_simple_mod.F90 +++ b/datm/datm_datamode_simple_mod.F90 @@ -19,6 +19,7 @@ module datm_datamode_simple_mod use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort use shr_cal_mod , only : shr_cal_date2julian + use shr_mpi_mod , only : shr_mpi_bcast use shr_const_mod , only : shr_const_tkfrz, shr_const_pi use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, dshr_fldbun_regrid, chkerr @@ -43,6 +44,7 @@ module datm_datamode_simple_mod real(r8), pointer :: Sa_ptem(:) => null() real(r8), pointer :: Sa_shum(:) => null() real(r8), pointer :: Sa_pbot(:) => null() + real(r8), pointer :: Sa_dens(:) => null() real(r8), pointer :: Sa_pslv(:) => null() real(r8), pointer :: Faxa_lwdn(:) => null() real(r8), pointer :: Faxa_rainc(:) => null() @@ -58,11 +60,18 @@ module datm_datamode_simple_mod ! stream data real(r8), pointer :: strm_swdn(:) => null() - real(r8), pointer :: strm_tarcf(:) => null() ! othe module arrays real(R8), pointer :: yc(:) ! array of model latitudes + ! constant forcing values + real(R8) :: dn10 = 1.204_R8 + real(R8) :: slp = 101325.0_R8 + real(R8) :: q = 0.0_R8 + real(R8) :: t = 273.15_R8 + real(R8) :: u = 0.0_R8 + real(R8) :: v = 0.0_R8 + ! constants real(R8) , parameter :: tKFrz = SHR_CONST_TKFRZ real(R8) , parameter :: degtorad = SHR_CONST_PI/180.0_R8 @@ -78,20 +87,48 @@ module datm_datamode_simple_mod contains !=============================================================================== - subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_name, rc) + subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_name, & + nlfilename, my_task, mpicom, rc) ! input/output variables type(esmf_State) , intent(inout) :: exportState type(fldlist_type) , pointer :: fldsexport character(len=*) , intent(in) :: flds_scalar_name + character(len=*) , intent(in) :: nlfilename + integer , intent(in) :: my_task + integer , intent(in) :: mpicom integer , intent(out) :: rc ! local variables - type(fldlist_type), pointer :: fldList + type(fldlist_type), pointer :: fldList + integer , parameter :: main_task = 0 ! task number of main task + integer :: ierr ! error code + integer :: nu ! unit number + character(len=*) , parameter :: subname='(datm_datamode_simple_advertise): ' + !------------------------------------------------------------------------------- + namelist / const_forcing_nml / dn10, slp, q, t, u, v + rc = ESMF_SUCCESS + ! Read const_forcing_nml from nlfilename + if (my_task == main_task) then + open (newunit=nu,file=trim(nlfilename),status="old",action="read") + read (nu,nml=const_forcing_nml,iostat=ierr) + close(nu) + if (ierr > 0) then + call shr_sys_abort(subName//': namelist read error '//trim(nlfilename)) + end if + end if + + call shr_mpi_bcast(dn10 , mpicom, 'dn10') + call shr_mpi_bcast(slp , mpicom, 'slp') + call shr_mpi_bcast(q , mpicom, 'q') + call shr_mpi_bcast(t , mpicom, 't') + call shr_mpi_bcast(u , mpicom, 'u') + call shr_mpi_bcast(v , mpicom, 'v') + call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) call dshr_fldList_add(fldsExport, 'Sa_z' ) call dshr_fldList_add(fldsExport, 'Sa_u' ) @@ -158,11 +195,9 @@ subroutine datm_datamode_simple_init_pointers(exportState, sdat, rc) ! get stream pointers !todo call shr_strdata_get_stream_pointer( sdat, 'Faxa_prec' , strm_prec , rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + !if (ChkErr(rc,__LINE__,u_FILE_u)) return call shr_strdata_get_stream_pointer( sdat, 'Faxa_swdn' , strm_swdn , rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call shr_strdata_get_stream_pointer( sdat, 'tarcf' , strm_tarcf , rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return ! get export state pointers call dshr_state_getfldptr(exportState, 'Sa_z' , fldptr1=Sa_z , rc=rc) @@ -175,6 +210,8 @@ subroutine datm_datamode_simple_init_pointers(exportState, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Sa_pbot' , fldptr1=Sa_pbot , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_dens' , fldptr1=Sa_dens , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Sa_pslv' , fldptr1=Sa_pslv , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Sa_ptem' , fldptr1=Sa_ptem , rc=rc) @@ -247,55 +284,59 @@ subroutine datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & cosfactor = cos((2.0_R8*SHR_CONST_PI*rday)/365 - phs_c0) do n = 1,lsize - Sa_z(n) = 10.0_R8 - - !--- density and pslv taken directly from input stream, set pbot --- - Sa_pbot(n) = Sa_pslv(n) - - Sa_ptem(n) = Sa_tbot(n) - - !--- Dupont correction to NCEP Arctic air T --- - !--- don't correct during summer months (July-September) - !--- ONLY correct when forcing year is 1997->2004 - - Faxa_rainc(n) = 0.0_R8 ! default zero - Faxa_snowc(n) = 0.0_R8 - if (Sa_tbot(n) < tKFrz ) then ! assign precip to rain/snow components - Faxa_rainl(n) = 0.0_R8 - Faxa_snowl(n) = 0.0_R8 ! todo - else - Faxa_rainl(n) = 0.0_R8 ! todo - Faxa_snowl(n) = 0.0_R8 - endif - - ! RADIATION DATA - !--- fabricate required swdn components from net swdn --- - Faxa_swvdr(n) = strm_swdn(n)*(0.28_R8) - Faxa_swndr(n) = strm_swdn(n)*(0.31_R8) - Faxa_swvdf(n) = strm_swdn(n)*(0.24_R8) - Faxa_swndf(n) = strm_swdn(n)*(0.17_R8) - !--- compute net short-wave based on LY08 latitudinally-varying albedo --- - avg_alb = ( 0.069 - 0.011*cos(2.0_R8*yc(n)*degtorad ) ) - Faxa_swnet(n) = strm_swdn(n)*(1.0_R8 - avg_alb) - !--- corrections to GISS sswdn for heat budget balancing --- - factor = 1.0_R8 - if ( -60.0_R8 < yc(n) .and. yc(n) < -50.0_R8 ) then - factor = 1.0_R8 - (yc(n) + 60.0_R8)*(0.05_R8/10.0_R8) - else if ( -50.0_R8 < yc(n) .and. yc(n) < 30.0_R8 ) then - factor = 0.95_R8 - else if ( 30.0_R8 < yc(n) .and. yc(n) < 40._R8 ) then - factor = 1.0_R8 - (40.0_R8 - yc(n))*(0.05_R8/10.0_R8) - endif - Faxa_swnet(n) = Faxa_swnet(n)*factor - Faxa_swvdr(n) = Faxa_swvdr(n)*factor - Faxa_swndr(n) = Faxa_swndr(n)*factor - Faxa_swvdf(n) = Faxa_swvdf(n)*factor - Faxa_swndf(n) = Faxa_swndf(n)*factor - !--- correction to GISS lwdn in Arctic --- - if ( yc(n) > 60._R8 ) then - factor = MIN(1.0_R8, 0.1_R8*(yc(n)-60.0_R8) ) - Faxa_lwdn(n) = Faxa_lwdn(n) + factor * dLWarc - endif + Sa_z(n) = 10.0_R8 + + !--- (i) Set forcing fields to constant values read from the namelist file --- + Sa_dens(n) = dn10 + Sa_pslv(n) = slp + Sa_pbot(n) = Sa_pslv(n) + Sa_shum(n) = q + Sa_tbot(n) = t + Sa_ptem(n) = Sa_tbot(n) + Sa_u(n) = u + Sa_v(n) = v + + !--- (ii) Set precipitation (currently all zeros) --- + + Faxa_rainc(n) = 0.0_R8 ! default zero + Faxa_snowc(n) = 0.0_R8 + if (Sa_tbot(n) < tKFrz ) then ! assign precip to rain/snow components + Faxa_rainl(n) = 0.0_R8 + Faxa_snowl(n) = 0.0_R8 ! todo + else + Faxa_rainl(n) = 0.0_R8 ! todo + Faxa_snowl(n) = 0.0_R8 + endif + + !--- (iii) RADIATION DATA --- + + !--- fabricate required swdn components from net swdn --- + Faxa_swvdr(n) = strm_swdn(n)*(0.28_R8) + Faxa_swndr(n) = strm_swdn(n)*(0.31_R8) + Faxa_swvdf(n) = strm_swdn(n)*(0.24_R8) + Faxa_swndf(n) = strm_swdn(n)*(0.17_R8) + !--- compute net short-wave based on LY08 latitudinally-varying albedo --- + avg_alb = ( 0.069 - 0.011*cos(2.0_R8*yc(n)*degtorad ) ) + Faxa_swnet(n) = strm_swdn(n)*(1.0_R8 - avg_alb) + !--- corrections to GISS sswdn for heat budget balancing --- + factor = 1.0_R8 + if ( -60.0_R8 < yc(n) .and. yc(n) < -50.0_R8 ) then + factor = 1.0_R8 - (yc(n) + 60.0_R8)*(0.05_R8/10.0_R8) + else if ( -50.0_R8 < yc(n) .and. yc(n) < 30.0_R8 ) then + factor = 0.95_R8 + else if ( 30.0_R8 < yc(n) .and. yc(n) < 40._R8 ) then + factor = 1.0_R8 - (40.0_R8 - yc(n))*(0.05_R8/10.0_R8) + endif + Faxa_swnet(n) = Faxa_swnet(n)*factor + Faxa_swvdr(n) = Faxa_swvdr(n)*factor + Faxa_swndr(n) = Faxa_swndr(n)*factor + Faxa_swvdf(n) = Faxa_swvdf(n)*factor + Faxa_swndf(n) = Faxa_swndf(n)*factor + !--- correction to GISS lwdn in Arctic --- + if ( yc(n) > 60._R8 ) then + factor = MIN(1.0_R8, 0.1_R8*(yc(n)-60.0_R8) ) + Faxa_lwdn(n) = Faxa_lwdn(n) + factor * dLWarc + endif enddo ! lsize From 27e1c3eceed2ead33fa79b11c79f8926e3f78b62 Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Fri, 28 Apr 2023 09:35:59 -0600 Subject: [PATCH 003/170] Update stream definitions for new coupler history file format. --- datm/cime_config/stream_definition_datm.xml | 84 ++++++++++----------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index c29decdca..ebdae330e 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -4546,10 +4546,10 @@ $ATM_DOMAIN_MESH - $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.ha2x3h.%ym.nc + $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.hx.atm.3h.avrg.%ymd-10800.nc - a2x3h_Sa_topo Sa_topo + atmImp_Sa_topo Sa_topo null @@ -4576,23 +4576,23 @@ $ATM_DOMAIN_MESH - $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.ha2x1d.%ym.nc + $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.hx.atm.24h.avrg.%ymd-00000.nc - a2x1d_Faxa_bcphiwet Faxa_bcphiwet - a2x1d_Faxa_bcphodry Faxa_bcphodry - a2x1d_Faxa_bcphidry Faxa_bcphidry - a2x1d_Faxa_ocphiwet Faxa_ocphiwet - a2x1d_Faxa_ocphidry Faxa_ocphidry - a2x1d_Faxa_ocphodry Faxa_ocphodry - a2x1d_Faxa_dstwet1 Faxa_dstwet1 - a2x1d_Faxa_dstdry1 Faxa_dstdry1 - a2x1d_Faxa_dstwet2 Faxa_dstwet2 - a2x1d_Faxa_dstdry2 Faxa_dstdry2 - a2x1d_Faxa_dstwet3 Faxa_dstwet3 - a2x1d_Faxa_dstdry3 Faxa_dstdry3 - a2x1d_Faxa_dstwet4 Faxa_dstwet4 - a2x1d_Faxa_dstdry4 Faxa_dstdry4 + atmImp_Faxa_bcph1 Faxa_bcphidry + atmImp_Faxa_bcph2 Faxa_bcphodry + atmImp_Faxa_bcph3 Faxa_bcphiwet + atmImp_Faxa_ocph1 Faxa_ocphidry + atmImp_Faxa_ocph2 Faxa_ocphodry + atmImp_Faxa_ocph3 Faxa_ocphiwet + atmImp_Faxa_dstwet1 Faxa_dstwet1 + atmImp_Faxa_dstdry1 Faxa_dstdry1 + atmImp_Faxa_dstwet2 Faxa_dstwet2 + atmImp_Faxa_dstdry2 Faxa_dstdry2 + atmImp_Faxa_dstwet3 Faxa_dstwet3 + atmImp_Faxa_dstdry3 Faxa_dstdry3 + atmImp_Faxa_dstwet4 Faxa_dstwet4 + atmImp_Faxa_dstdry4 Faxa_dstdry4 null @@ -4651,13 +4651,13 @@ $ATM_DOMAIN_MESH - $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.ha2x1hi.%ym.nc + $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.hx.atm.1h.inst.%ymd-03600.nc - a2x1hi_Faxa_swndr Faxa_swndr - a2x1hi_Faxa_swvdr Faxa_swvdr - a2x1hi_Faxa_swndf Faxa_swndf - a2x1hi_Faxa_swvdf Faxa_swvdf + atmImp_Faxa_swndr Faxa_swndr + atmImp_Faxa_swvdr Faxa_swvdr + atmImp_Faxa_swndf Faxa_swndf + atmImp_Faxa_swvdf Faxa_swvdf null @@ -4667,7 +4667,7 @@ $DATM_YR_ALIGN $DATM_YR_START $DATM_YR_END - 2700 + -900 nearest @@ -4685,14 +4685,14 @@ $ATM_DOMAIN_MESH - $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.ha2x3h.%ym.nc + $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.hx.atm.3h.avrg.%ymd-10800.nc - a2x3h_Faxa_rainc Faxa_rainc - a2x3h_Faxa_rainl Faxa_rainl - a2x3h_Faxa_snowc Faxa_snowc - a2x3h_Faxa_snowl Faxa_snowl - a2x3h_Faxa_lwdn Faxa_lwdn + atmImp_Faxa_rainc Faxa_rainc + atmImp_Faxa_rainl Faxa_rainl + atmImp_Faxa_snowc Faxa_snowc + atmImp_Faxa_snowl Faxa_snowl + atmImp_Faxa_lwdn Faxa_lwdn null @@ -4720,18 +4720,18 @@ $ATM_DOMAIN_MESH - $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.ha2x3h.%ym.nc + $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.hx.atm.3h.avrg.%ymd-10800.nc - a2x3h_Sa_z Sa_z - a2x3h_Sa_tbot Sa_tbot - a2x3h_Sa_ptem Sa_ptem - a2x3h_Sa_shum Sa_shum - a2x3h_Sa_pbot Sa_pbot - a2x3h_Sa_dens Sa_dens - a2x3h_Sa_pslv Sa_pslv - a2x3h_Sa_co2diag Sa_co2diag - a2x3h_Sa_co2prog Sa_co2prog + atmImp_Sa_z Sa_z + atmImp_Sa_tbot Sa_tbot + atmImp_Sa_ptem Sa_ptem + atmImp_Sa_shum Sa_shum + atmImp_Sa_pbot Sa_pbot + atmImp_Sa_dens Sa_dens + atmImp_Sa_pslv Sa_pslv + atmImp_Sa_co2diag Sa_co2diag + atmImp_Sa_co2prog Sa_co2prog null @@ -4759,11 +4759,11 @@ $ATM_DOMAIN_MESH - $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.ha2x1h.%ym.nc + $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.hx.atm.1h.avrg.%ymd-03600.nc - a2x1h_Sa_u Sa_u - a2x1h_Sa_v Sa_v + atmImp_Sa_u Sa_u + atmImp_Sa_v Sa_v null From d47f1ba679933d244453ea2ef483e0e96d889b42 Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Fri, 28 Apr 2023 09:52:43 -0600 Subject: [PATCH 004/170] filename_add_days to filename_advance_days --- datm/cime_config/stream_definition_datm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index ebdae330e..c1eb0e891 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -4576,7 +4576,7 @@ $ATM_DOMAIN_MESH - $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.hx.atm.24h.avrg.%ymd-00000.nc + $DATM_CPLHIST_DIR/$DATM_CPLHIST_CASE.cpl.hx.atm.24h.avrg.%ymd-00000.nc atmImp_Faxa_bcph1 Faxa_bcphidry From 2afdcd9649dc5081a526d2372ccf32d55e89b23f Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Tue, 2 May 2023 10:59:31 -0600 Subject: [PATCH 005/170] Change nextsw_cday calculation for CAM7 in cplhist mode. Note that cplhist_nextsw_cday_calc is intended to be a namelist parameter but is not yet implemented here. --- datm/atm_comp_nuopc.F90 | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index c84e10f79..c0f60a5c3 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -872,10 +872,18 @@ real(R8) function getNextRadCDay( julday, tod, stepno, dtime, iradsw ) if (liradsw > 1) then delta_radsw = liradsw * dtime - if (mod(tod+dtime,delta_radsw) == 0 .and. stepno > 0) then - nextsw_cday = julday + 2*dtime/shr_const_cday + if (trim(cplhist_nextsw_cday_calc) == 'cam7' ) then + if (mod(tod,delta_radsw) == 0 .and. stepno > 0) then + nextsw_cday = julday + 1*dtime/shr_const_cday + else + nextsw_cday = -1._r8 + end if else - nextsw_cday = -1._r8 + if (mod(tod+dtime,delta_radsw) == 0 .and. stepno > 0) then + nextsw_cday = julday + 2*dtime/shr_const_cday + else + nextsw_cday = -1._r8 + end if end if else nextsw_cday = julday + dtime/shr_const_cday From 00414e165ed4c1b9e88d3cbdffebb213564a6fa7 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 May 2023 14:52:19 -0600 Subject: [PATCH 006/170] Remove tabs fixing #231 --- datm/cime_config/buildnml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml index c3d59375a..d8c11a452 100755 --- a/datm/cime_config/buildnml +++ b/datm/cime_config/buildnml @@ -64,10 +64,10 @@ def _get_neon_data_availability(case, neonsite): for version in dataversions: # Once a date range for a version has been determined for any version, the loop is complete. - # Eg, if data is available for v3, the loop will not continue to v2; - # however, if data is not available for v3, it will check for v2. - # Thus, it is important for dataversions to be listed from newest to oldest. - if not newestdate: + # Eg, if data is available for v3, the loop will not continue to v2; + # however, if data is not available for v3, it will check for v2. + # Thus, it is important for dataversions to be listed from newest to oldest. + if not newestdate: with open(fullpath, "r") as fd: for line in fd.readlines(): fpath, fname = os.path.split(line) @@ -220,7 +220,7 @@ def _create_drv_flds_in(case, confdir): # for now we are hard-coding this file name and values because we only need it for ozone if datm_preso3 != "none": - # Generate drv_flds_in file + # Generate drv_flds_in file outfile = os.path.join(confdir, "drv_flds_in") ozone_nl_name = "&ozone_coupling_nl" ozone_freq_par = "atm_ozone_frequency" From 977260a80b23bbdcd826218fdc496c7f04a42340 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 May 2023 14:52:42 -0600 Subject: [PATCH 007/170] Add externals to the git ignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 34b286f3e..625692541 100644 --- a/.gitignore +++ b/.gitignore @@ -31,5 +31,9 @@ *.out *.app +# Externals +fox +share/genf90 + # ignore pycache __pycache__ From 1ca35a55ebd1db1547b6b4fd56086b36cd867d0b Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 16 May 2023 15:07:36 -0600 Subject: [PATCH 008/170] black reformat these python files --- cime_config/buildlib | 4 +- cime_config/buildlib_comps | 22 ++- cime_config/stream_cdeps.py | 377 +++++++++++++++++++++++------------- 3 files changed, 262 insertions(+), 141 deletions(-) diff --git a/cime_config/buildlib b/cime_config/buildlib index 965836cff..2fc2b3ff2 100755 --- a/cime_config/buildlib +++ b/cime_config/buildlib @@ -77,9 +77,7 @@ def buildlib(bldroot, libroot, case): logger.info("Running cmake for CDEPS") srcpath = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) - cmake_flags = get_standard_cmake_args( - case, os.path.join(sharedpath, "cdeps") - ) + cmake_flags = get_standard_cmake_args(case, os.path.join(sharedpath, "cdeps")) # base path of install to be completed by setting DESTDIR in make install cmake_flags += " -DCMAKE_INSTALL_PREFIX:PATH=/" cmake_flags += " -DLIBROOT={} ".format(libroot) diff --git a/cime_config/buildlib_comps b/cime_config/buildlib_comps index 1eba5bee6..281f0d4e9 100755 --- a/cime_config/buildlib_comps +++ b/cime_config/buildlib_comps @@ -11,7 +11,7 @@ if _CIMEROOT is None: raise SystemExit("ERROR: must set CIMEROOT environment variable") sys.path.append(os.path.join(_CIMEROOT, "CIME", "Tools")) -_LIBDIR = os.path.join(_CIMEROOT, "scripts", "lib") +_LIBDIR = os.path.join(_CIMEROOT, "CIME") sys.path.append(_LIBDIR) from standard_script_setup import * @@ -19,28 +19,36 @@ from CIME.buildlib import parse_input from CIME.case import Case from CIME.utils import run_cmd, symlink_force, expect +# pragma pylint: disable=unused-argument,undefined-variable + logger = logging.getLogger(__name__) + def buildlib(bldroot, libroot, case, compname=None): if not compname: - expect(bldroot.endswith("obj"), - "It appears that buildlib_comps is being called for the main CDEPS build\n" - "(the main CDEPS build should use buildlib, not buildlib_comps)") - compname = os.path.basename(os.path.abspath(os.path.join(bldroot,os.pardir))) + expect( + bldroot.endswith("obj"), + "It appears that buildlib_comps is being called for the main CDEPS build\n" + "(the main CDEPS build should use buildlib, not buildlib_comps)", + ) + compname = os.path.basename(os.path.abspath(os.path.join(bldroot, os.pardir))) _, o, e = run_cmd("make d{}".format(compname), from_dir=bldroot, verbose=True) libname = "lib{}.a".format(compname) dlibname = "libd{}.a".format(compname) dlibpath = os.path.join(bldroot, dlibname) if os.path.exists(dlibpath): - symlink_force(os.path.join(bldroot,dlibname), os.path.join(libroot,libname)) + symlink_force(os.path.join(bldroot, dlibname), os.path.join(libroot, libname)) else: - expect(False, "ERROR in {} build {} {}".format(compname,o,e)) + expect(False, "ERROR in {} build {} {}".format(compname, o, e)) + logger.info(f"build successful for comp={compname}") + def _main_func(args): caseroot, libroot, bldroot = parse_input(args) with Case(caseroot) as case: buildlib(bldroot, libroot, case) + if __name__ == "__main__": _main_func(sys.argv) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index ead74bbf2..1f702a13c 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -7,12 +7,11 @@ import re import hashlib -from standard_script_setup import * from CIME.XML.standard_module_setup import * from CIME.XML.generic_xml import GenericXML -from CIME.XML.files import Files from CIME.utils import expect +# pragma pylint: disable=undefined-variable logger = logging.getLogger(__name__) _var_ref_re = re.compile(r"\$(\{)?(?P\w+)(?(1)\})") @@ -44,25 +43,40 @@ """ valid_values = {} -valid_values["mapalgo"] = ["bilinear", "nn", "redist", "mapconsd", "mapconf", "none"] +valid_values["mapalgo"] = ["bilinear", "nn", "redist", "mapconsd", "mapconf", "none"] valid_values["tintalgo"] = ["lower", "upper", "nearest", "linear", "coszen"] -valid_values["taxmode"] = ["cycle", "extend", "limit"] +valid_values["taxmode"] = ["cycle", "extend", "limit"] -xml_scalar_names = ["stream_meshfile", "stream_mapalgo", "stream_tintalgo", "stream_taxmode", "stream_dtlimit"] +xml_scalar_names = [ + "stream_meshfile", + "stream_mapalgo", + "stream_tintalgo", + "stream_taxmode", + "stream_dtlimit", +] -class StreamCDEPS(GenericXML): +class StreamCDEPS(GenericXML): def __init__(self, infile, schema): """ Initialize a CDEPS stream object """ logger.debug("Verifying using schema {}".format(schema)) GenericXML.__init__(self, infile, schema) + self.stream_nodes = None + if os.path.exists(infile): GenericXML.read(self, infile, schema) - def create_stream_xml(self, stream_names, case, streams_xml_file, data_list_file, user_mods_file, - available_neon_data=None): + def create_stream_xml( + self, + stream_names, + case, + streams_xml_file, + data_list_file, + user_mods_file, + available_neon_data=None, + ): """ Create the stream xml file and append the required stream input data to the input data list file available_neon_data is an optional list of NEON tower data available for the given case, if provided @@ -71,98 +85,134 @@ def create_stream_xml(self, stream_names, case, streams_xml_file, data_list_file # determine if there are user mods lines_input = [] - expect (os.path.isfile(user_mods_file), - "No file {} found in case directory".format(user_mods_file)) - with open(user_mods_file, "r", encoding='utf-8') as stream_mods_file: + expect( + os.path.isfile(user_mods_file), + "No file {} found in case directory".format(user_mods_file), + ) + with open(user_mods_file, "r", encoding="utf-8") as stream_mods_file: lines_input = stream_mods_file.readlines() stream_mod_dict = {} n = len(lines_input) index = 0 lines_input_new = [] - while index < len(lines_input): + while index < n: line = lines_input[index].strip() - if line.startswith('!') or (not line): + if line.startswith("!") or (not line): index = index + 1 continue - while line[-1] == '\\': + while line[-1] == "\\": index += 1 - if index < len(lines_input): - line = line[:-1].strip() + ' ' + lines_input[index].strip() + if index < n: + line = line[:-1].strip() + " " + lines_input[index].strip() else: - line = line.replace('\\', '').strip() + line = line.replace("\\", "").strip() break # endif # end while index += 1 line = case.get_resolved_value(line) lines_input_new.append(line) - #end while + # end while for line in lines_input_new: # read in a single line in user_nl_xxx_streams and parse it if it is not a comment - stream_mods = [x.strip() for x in line.strip().split(":",maxsplit=1) if x] - expect(len(stream_mods) == 2, - "input stream mod can only be of the form streamname:var=value(s)") - stream,varmod = stream_mods - expect (stream in stream_names, - "{} contains a streamname \'{}\' that is not part of valid streamnames {}". - format(user_mods_file,stream,stream_names)) - if stream not in stream_mod_dict: + stream_mods = [x.strip() for x in line.strip().split(":", maxsplit=1) if x] + expect( + len(stream_mods) == 2, + "input stream mod can only be of the form streamname:var=value(s)", + ) + stream, varmod = stream_mods + expect( + stream in stream_names, + "{} contains a streamname '{}' that is not part of valid streamnames {}".format( + user_mods_file, stream, stream_names + ), + ) + if stream not in stream_mod_dict: stream_mod_dict[stream] = {} # var=value and check the validity varmod_args = [x.strip() for x in varmod.split("=") if x] - expect(len(varmod_args) == 2, - "input stream mod can only be of the form streamname:var=value(s)") + expect( + len(varmod_args) == 2, + "input stream mod can only be of the form streamname:var=value(s)", + ) # allow multiple entries for varmod_args, most recent wins - varname,varval = varmod_args + varname, varval = varmod_args if varname in stream_mod_dict[stream]: - logger.warning("varname {} is already in stream mod dictionary".format(varname)) + logger.warning( + "varname {} is already in stream mod dictionary".format(varname) + ) if varname == "datavars" or varname == "datafiles": if varname == "datavars": - varvals = ["{}".format(x.strip()) for x in varval.split(",") if x] + varvals = [ + "{}".format(x.strip()) + for x in varval.split(",") + if x + ] if varname == "datafiles": - varvals = ["{}".format(x.strip()) for x in varval.split(",") if x] + varvals = [ + "{}".format(x.strip()) + for x in varval.split(",") + if x + ] varval = " " + "\n ".join(varvals) varval = varval.strip() stream_mod_dict[stream][varname] = varval # write header of stream file - with open(streams_xml_file, 'w', encoding='utf-8') as stream_file: + with open(streams_xml_file, "w", encoding="utf-8") as stream_file: stream_file.write('\n') stream_file.write('\n') # write contents of stream file for stream_name in stream_names: # include NEON.$NEONSITE non-precipitation data streams whether use PRISM or NEON precip - if stream_name.startswith("NEON.") and ('PRECIP' not in stream_name): - self.stream_nodes = super(StreamCDEPS,self).get_child("stream_entry", {"name" : "NEON.$NEONSITE"}, - err_msg="No stream_entry {} found".format(stream_name)) + if stream_name.startswith("NEON.") and ("PRECIP" not in stream_name): + self.stream_nodes = super(StreamCDEPS, self).get_child( + "stream_entry", + {"name": "NEON.$NEONSITE"}, + err_msg="No stream_entry {} found".format(stream_name), + ) elif stream_name.startswith("NEON.PRISM_PRECIP"): - self.stream_nodes = super(StreamCDEPS,self).get_child("stream_entry", {"name" : "NEON.PRISM_PRECIP.$NEONSITE"}, - err_msg="No stream_entry {} found".format(stream_name)) + self.stream_nodes = super(StreamCDEPS, self).get_child( + "stream_entry", + {"name": "NEON.PRISM_PRECIP.$NEONSITE"}, + err_msg="No stream_entry {} found".format(stream_name), + ) elif stream_name.startswith("NEON.NEON_PRECIP"): - self.stream_nodes = super(StreamCDEPS,self).get_child("stream_entry", {"name" : "NEON.NEON_PRECIP.$NEONSITE"}, - err_msg="No stream_entry {} found".format(stream_name)) + self.stream_nodes = super(StreamCDEPS, self).get_child( + "stream_entry", + {"name": "NEON.NEON_PRECIP.$NEONSITE"}, + err_msg="No stream_entry {} found".format(stream_name), + ) elif stream_name.startswith("CLM_USRDAT."): - self.stream_nodes = super(StreamCDEPS,self).get_child("stream_entry", {"name" : "CLM_USRDAT.$CLM_USRDAT_NAME"}, - err_msg="No stream_entry {} found".format(stream_name)) + self.stream_nodes = super(StreamCDEPS, self).get_child( + "stream_entry", + {"name": "CLM_USRDAT.$CLM_USRDAT_NAME"}, + err_msg="No stream_entry {} found".format(stream_name), + ) elif stream_name: - self.stream_nodes = super(StreamCDEPS,self).get_child("stream_entry", {"name" : stream_name}, - err_msg="No stream_entry {} found".format(stream_name)) + self.stream_nodes = super(StreamCDEPS, self).get_child( + "stream_entry", + {"name": stream_name}, + err_msg="No stream_entry {} found".format(stream_name), + ) # determine stream_year_first and stream_year_list - data_year_first,data_year_last = self._get_stream_first_and_last_dates(self.stream_nodes, case) + data_year_first, data_year_last = self._get_stream_first_and_last_dates( + self.stream_nodes, case + ) # now write the data model streams xml file stream_vars = {} - stream_vars['streamname'] = stream_name + stream_vars["streamname"] = stream_name attributes = {} for node in self.get_children(root=self.stream_nodes): node_name = node.xml_element.tag.strip() - if node_name == 'stream_datavars': + if node_name == "stream_datavars": # Get the resolved stream data variables stream_vars[node_name] = None for child in self.get_children(root=node): @@ -171,52 +221,79 @@ def create_stream_xml(self, stream_names, case, streams_xml_file, data_list_file datavars = self._sub_glc_fields(datavars, case) datavars = self._add_xml_delimiter(datavars.split("\n"), "var") if stream_vars[node_name]: - stream_vars[node_name] = stream_vars[node_name] + "\n " + datavars.strip() + stream_vars[node_name] = ( + stream_vars[node_name] + "\n " + datavars.strip() + ) else: stream_vars[node_name] = datavars.strip() # endif - elif node_name == 'stream_datafiles': + elif node_name == "stream_datafiles": # Get the resolved stream data files stream_vars[node_name] = "" stream_datafiles = "" for child in self.get_children(root=node): - if available_neon_data and stream_name.startswith("NEON") and ('PRISM' not in stream_name): + if ( + available_neon_data + and stream_name.startswith("NEON") + and ("PRISM" not in stream_name) + ): rundir = case.get_value("RUNDIR") for neon in available_neon_data: - stream_datafiles += os.path.join(rundir,"inputdata","atm",neon) + "\n" + stream_datafiles += ( + os.path.join(rundir, "inputdata", "atm", neon) + + "\n" + ) else: stream_datafiles = child.xml_element.text - stream_datafiles = self._resolve_values(case, stream_datafiles) - #endif neon - if 'first_year' in child.xml_element.attrib and 'last_year' in child.xml_element.attrib: - value = child.xml_element.get('first_year') + stream_datafiles = self._resolve_values( + case, stream_datafiles + ) + # endif neon + if ( + "first_year" in child.xml_element.attrib + and "last_year" in child.xml_element.attrib + ): + value = child.xml_element.get("first_year") value = self._resolve_values(case, value) - stream_year_first= int(value) - value = child.xml_element.get('last_year') + stream_year_first = int(value) + value = child.xml_element.get("last_year") value = self._resolve_values(case, value) stream_year_last = int(value) year_first = max(stream_year_first, data_year_first) year_last = min(stream_year_last, data_year_last) - if 'filename_advance_days' in child.xml_element.attrib: - filename_advance_days = int(child.xml_element.get('filename_advance_days')) + if "filename_advance_days" in child.xml_element.attrib: + filename_advance_days = int( + child.xml_element.get("filename_advance_days") + ) else: filename_advance_days = 0 - stream_datafiles = self._sub_paths(stream_name, - stream_datafiles, - year_first, year_last, - filename_advance_days) + stream_datafiles = self._sub_paths( + stream_name, + stream_datafiles, + year_first, + year_last, + filename_advance_days, + ) stream_datafiles = stream_datafiles.strip() - #endif + # endif if stream_vars[node_name]: - stream_vars[node_name] += "\n " + self._add_xml_delimiter(stream_datafiles.split("\n"), "file") + stream_vars[ + node_name + ] += "\n " + self._add_xml_delimiter( + stream_datafiles.split("\n"), "file" + ) else: - stream_vars[node_name] = self._add_xml_delimiter(stream_datafiles.split("\n"), "file") - #endif - elif (node_name in xml_scalar_names): - attributes['model_grid'] = case.get_value("GRID") - attributes['compset'] = case.get_value("COMPSET") - value = self._get_value_match(node, node_name[7:], attributes=attributes) + stream_vars[node_name] = self._add_xml_delimiter( + stream_datafiles.split("\n"), "file" + ) + # endif + elif node_name in xml_scalar_names: + attributes["model_grid"] = case.get_value("GRID") + attributes["compset"] = case.get_value("COMPSET") + value = self._get_value_match( + node, node_name[7:], attributes=attributes + ) if value: value = self._resolve_values(case, value) value = value.strip() @@ -224,36 +301,50 @@ def create_stream_xml(self, stream_names, case, streams_xml_file, data_list_file elif node_name.strip(): # Get the other dependencies - stream_dict = self._add_value_to_dict(stream_vars, case, node) + self._add_value_to_dict(stream_vars, case, node) # substitute user_mods in generated stream file (i.e. stream_vars) mod_dict = {} - if stream_vars['streamname'] in stream_mod_dict: - mod_dict = stream_mod_dict[stream_vars['streamname']] + if stream_vars["streamname"] in stream_mod_dict: + mod_dict = stream_mod_dict[stream_vars["streamname"]] for var_key in mod_dict: - expect( 'stream_' + var_key in stream_vars, - "stream mod {} is not a valid name in {}".format(var_key,user_mods_file)) + expect( + "stream_" + var_key in stream_vars, + "stream mod {} is not a valid name in {}".format( + var_key, user_mods_file + ), + ) if var_key in valid_values: - expect(mod_dict[var_key] in valid_values[var_key], - "{} can only have values of {} for stream {} in file {}". - format(var_key, valid_values[var_key], stream_name, user_mods_file)) - stream_vars['stream_' + var_key] = mod_dict[var_key] - if var_key == 'datafiles': + expect( + mod_dict[var_key] in valid_values[var_key], + "{} can only have values of {} for stream {} in file {}".format( + var_key, + valid_values[var_key], + stream_name, + user_mods_file, + ), + ) + stream_vars["stream_" + var_key] = mod_dict[var_key] + if var_key == "datafiles": stream_datafiles = mod_dict[var_key] - stream_datafiles = stream_datafiles.replace('','').replace('','') + stream_datafiles = stream_datafiles.replace( + "", "" + ).replace("", "") # append to stream xml file stream_file_text = _stream_file_template.format(**stream_vars) - with open(streams_xml_file, 'a', encoding='utf-8') as stream_file: + with open(streams_xml_file, "a", encoding="utf-8") as stream_file: stream_file.write(case.get_resolved_value(stream_file_text)) # append to input_data_list - if stream_vars['stream_meshfile']: - stream_meshfile = stream_vars['stream_meshfile'].strip() - self._add_entries_to_inputdata_list(stream_meshfile, stream_datafiles.split("\n"), data_list_file) + if stream_vars["stream_meshfile"]: + stream_meshfile = stream_vars["stream_meshfile"].strip() + self._add_entries_to_inputdata_list( + stream_meshfile, stream_datafiles.split("\n"), data_list_file + ) # write close of stream xml file - with open(streams_xml_file, 'a', encoding='utf-8') as stream_file: + with open(streams_xml_file, "a", encoding="utf-8") as stream_file: stream_file.write("\n") def _get_stream_first_and_last_dates(self, stream, case): @@ -261,32 +352,34 @@ def _get_stream_first_and_last_dates(self, stream, case): Get first and last dates for data for the stream file """ for node in self.get_children(root=stream): - if node.xml_element.tag == 'stream_year_first': + if node.xml_element.tag == "stream_year_first": data_year_first = node.xml_element.text.strip() data_year_first = int(self._resolve_values(case, data_year_first)) - if node.xml_element.tag == 'stream_year_last': + if node.xml_element.tag == "stream_year_last": data_year_last = node.xml_element.text.strip() data_year_last = int(self._resolve_values(case, data_year_last)) return data_year_first, data_year_last - def _add_entries_to_inputdata_list(self, stream_meshfile, stream_datafiles, data_list_file): + def _add_entries_to_inputdata_list( + self, stream_meshfile, stream_datafiles, data_list_file + ): """ Appends input data information entries to input data list file and writes out the new file """ lines_hash = self._get_input_file_hash(data_list_file) - with open(data_list_file, 'a', encoding='utf-8') as input_data_list: + with open(data_list_file, "a", encoding="utf-8") as input_data_list: # write out the mesh file separately string = "mesh = {}\n".format(stream_meshfile) - hashValue = hashlib.md5(string.rstrip().encode('utf-8')).hexdigest() + hashValue = hashlib.md5(string.rstrip().encode("utf-8")).hexdigest() if hashValue not in lines_hash: input_data_list.write(string) # now append the stream_datafile entries for i, filename in enumerate(stream_datafiles): - if filename.strip() == '': + if filename.strip() == "": continue - string = "file{:d} = {}\n".format(i+1, filename.strip()) - hashValue = hashlib.md5(string.rstrip().encode('utf-8')).hexdigest() + string = "file{:d} = {}\n".format(i + 1, filename.strip()) + hashValue = hashlib.md5(string.rstrip().encode("utf-8")).hexdigest() if hashValue not in lines_hash: input_data_list.write(string) @@ -296,15 +389,15 @@ def _get_input_file_hash(self, data_list_file): """ lines_hash = set() if os.path.isfile(data_list_file): - with open(data_list_file, "r", encoding='utf-8') as input_data_list: + with open(data_list_file, "r", encoding="utf-8") as input_data_list: for line in input_data_list: - hashValue = hashlib.md5(line.rstrip().encode('utf-8')).hexdigest() - logger.debug( "Found line {} with hash {}".format(line,hashValue)) + hashValue = hashlib.md5(line.rstrip().encode("utf-8")).hexdigest() + logger.debug("Found line {} with hash {}".format(line, hashValue)) lines_hash.add(hashValue) return lines_hash def _get_value_match(self, node, child_name, attributes=None, exact_match=False): - ''' + """ Get the first best match for multiple tags in child_name based on the attributes input @@ -314,7 +407,7 @@ def _get_value_match(self, node, child_name, attributes=None, exact_match=False) Z - ''' + """ # Store nodes that match the attributes and their scores. matches = [] nodes = self.get_children(child_name, root=node) @@ -328,13 +421,15 @@ def _get_value_match(self, node, child_name, attributes=None, exact_match=False) # If some attribute is specified that we don't know about, # or the values don't match, it's not a match we want. if exact_match: - if attribute not in attributes or \ - attributes[attribute] != self.get(vnode, attribute): + if attribute not in attributes or attributes[ + attribute + ] != self.get(vnode, attribute): score = -1 break else: - if attribute not in attributes or not \ - re.search(self.get(vnode, attribute),attributes[attribute]): + if attribute not in attributes or not re.search( + self.get(vnode, attribute), attributes[attribute] + ): score = -1 break @@ -348,7 +443,7 @@ def _get_value_match(self, node, child_name, attributes=None, exact_match=False) # Get maximum score using either a "last" or "first" match in case of a tie max_score = -1 mnode = None - for score,node in matches: + for score, node in matches: # take the *first* best match if score > max_score: max_score = score @@ -374,10 +469,13 @@ def _resolve_values(self, case, value): """ match = _var_ref_re.search(value) while match: - env_val = case.get_value(match.group('name')) - expect(env_val is not None, - "Namelist default for variable {} refers to unknown XML variable {}.". - format(value, match.group('name'))) + env_val = case.get_value(match.group("name")) + expect( + env_val is not None, + "Namelist default for variable {} refers to unknown XML variable {}.".format( + value, match.group("name") + ), + ) value = value.replace(match.group(0), str(env_val), 1) match = _var_ref_re.search(value) return value @@ -413,10 +511,10 @@ def _sub_glc_fields(self, datavars, case): if not line: continue if "%glc" in line: - if case.get_value('GLC_NEC') == 0: + if case.get_value("GLC_NEC") == 0: glc_nec_indices = [] else: - glc_nec_indices = range(case.get_value('GLC_NEC')+1) + glc_nec_indices = range(case.get_value("GLC_NEC") + 1) for i in glc_nec_indices: new_lines.append(line.replace("%glc", "{:02d}".format(i))) else: @@ -432,7 +530,7 @@ def _days_in_month(month, year=1): """ month_start = datetime.date(year, month, 1) if month == 12: - next_year = year+1 + next_year = year + 1 next_month = 1 else: next_year = year @@ -466,7 +564,9 @@ def _add_day(cls, year, month, day): adjusted_year = adjusted_year + 1 return (adjusted_year, adjusted_month, adjusted_day) - def _sub_paths(self, stream_name, filenames, year_start, year_end, filename_advance_days): + def _sub_paths( + self, stream_name, filenames, year_start, year_end, filename_advance_days + ): """Substitute indicators with given values in a list of filenames. Replace any instance of the following substring indicators with the @@ -500,9 +600,12 @@ def _sub_paths(self, stream_name, filenames, year_start, year_end, filename_adva Returns a string (filenames separated by newlines). """ - expect(filename_advance_days == 0 or filename_advance_days == 1, - "Bad filename_advance_days attribute ({}) for {}: must be 0 or 1".format( - filename_advance_days, stream_name)) + expect( + filename_advance_days == 0 or filename_advance_days == 1, + "Bad filename_advance_days attribute ({}) for {}: must be 0 or 1".format( + filename_advance_days, stream_name + ), + ) lines = [line for line in filenames.split("\n") if line] new_lines = [] @@ -511,23 +614,33 @@ def _sub_paths(self, stream_name, filenames, year_start, year_end, filename_adva if match is None: new_lines.append(line) continue - if match.group('digits'): - year_format = "{:0"+match.group('digits')+"d}" + if match.group("digits"): + year_format = "{:0" + match.group("digits") + "d}" else: year_format = "{:04d}" - for year in range(year_start, year_end+1): - if match.group('day'): + for year in range(year_start, year_end + 1): + if match.group("day"): for month in range(1, 13): days = self._days_in_month(month) - for day in range(1, days+1): + for day in range(1, days + 1): if filename_advance_days == 1: - (adjusted_year, adjusted_month, adjusted_day) = self._add_day(year, month, day) + ( + adjusted_year, + adjusted_month, + adjusted_day, + ) = self._add_day(year, month, day) else: - (adjusted_year, adjusted_month, adjusted_day) = (year, month, day) - date_string = (year_format + "-{:02d}-{:02d}").format(adjusted_year, adjusted_month, adjusted_day) + (adjusted_year, adjusted_month, adjusted_day) = ( + year, + month, + day, + ) + date_string = (year_format + "-{:02d}-{:02d}").format( + adjusted_year, adjusted_month, adjusted_day + ) new_line = line.replace(match.group(0), date_string) new_lines.append(new_line) - elif match.group('month'): + elif match.group("month"): for month in range(1, 13): date_string = (year_format + "-{:02d}").format(year, month) new_line = line.replace(match.group(0), date_string) @@ -543,22 +656,24 @@ def _add_xml_delimiter(list_to_deliminate, delimiter): expect(delimiter and not " " in delimiter, "Missing or badly formed delimiter") pred = "<{}>".format(delimiter) postd = "".format(delimiter) - for n,item in enumerate(list_to_deliminate): + for n, item in enumerate(list_to_deliminate): if item.strip(): list_to_deliminate[n] = pred + item.strip() + postd - #endif - #endfor + # endif + # endfor return "\n ".join(list_to_deliminate) def update_input_data_list(self, data_list_file): - ''' From the stream object parse out and list required input files ''' + """From the stream object parse out and list required input files""" sinodes = self.scan_children("stream_info") for node in sinodes: meshnode = self.scan_child("stream_mesh_file", root=node) stream_meshfile = self.text(meshnode) data_file_node = self.scan_child("stream_data_files", root=node) - filenodes = self.scan_children("file",root=data_file_node) + filenodes = self.scan_children("file", root=data_file_node) stream_datafiles = [] for fnode in filenodes: stream_datafiles.append(self.text(fnode)) - self._add_entries_to_inputdata_list(stream_meshfile, stream_datafiles, data_list_file) + self._add_entries_to_inputdata_list( + stream_meshfile, stream_datafiles, data_list_file + ) From 380f6fed4b19b385a5eaf47e1f4b40fe34f02def Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 19 May 2023 09:55:20 -0600 Subject: [PATCH 009/170] update github to make cdeps ext build an action --- .github/actions/buildcdeps/action.yaml | 41 ++++++++++++++++++++++++++ .github/workflows/extbuild.yml | 15 ++++------ 2 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 .github/actions/buildcdeps/action.yaml diff --git a/.github/actions/buildcdeps/action.yaml b/.github/actions/buildcdeps/action.yaml new file mode 100644 index 000000000..b02be9af4 --- /dev/null +++ b/.github/actions/buildcdeps/action.yaml @@ -0,0 +1,41 @@ +name: CDEPS build and cache +description: 'Build the CDEPS library' +inputs: + cdeps_version: + description: 'Tag in the CDEPS repository to use' + default: main + required: False + type: string + pio_path: + description: 'Path to the installed parallelio code root' + default: $HOME/pio + required: False + type: string + esmfmkfile: + description: 'Path to the installed ESMF library mkfile' + default: $HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk + required: False + type: string + src_root: + description: 'Path to cdeps source' + default: $GITHUB_WORKSPACE + required: False + type: string + install_prefix: + description: 'Install path of cdeps' + default: $HOME/cdeps + required: False + type: string +runs: + using: composite + steps: + - id : Build-CDEPS + shell: bash + run: | + mkdir build-cdeps + pushd build-cdeps + export ESMFMKFILE=${{ inputs.esmfmkfile }} + export PIO=${{ inputs.pio_path }} + cmake -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-DCPRGNU -g -Wall -ffree-form -ffree-line-length-none -fallow-argument-mismatch " -DWERROR=ON ${{ inputs.src_root }} + make VERBOSE=1 + popd diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index c3a54360e..08a92812f 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -93,12 +93,9 @@ jobs: pnetcdf_path: /usr parallelio_path: $HOME/pio - name: Build CDEPS - run: | - export ESMFMKFILE=$HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk - export PIO=$HOME/pio - export SRC_ROOT= - mkdir build-cdeps - pushd build-cdeps - cmake -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-DCPRGNU -g -Wall -ffree-form -ffree-line-length-none -fallow-argument-mismatch " -DWERROR=ON ../ - make VERBOSE=1 - popd + uses: ESCOMP/CDEPS/.github/actions/buildcdeps + with: + esmfmkfile: $HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk + pio_path: $HOME/pio + src_root: $GITHUB_WORKSPACE + From 895f31bed41c7b7714d308facc2d7a5335410769 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 19 May 2023 10:28:57 -0600 Subject: [PATCH 010/170] debug action --- .github/actions/buildcdeps/action.yaml | 8 ++++++-- .github/workflows/extbuild.yml | 7 ++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/actions/buildcdeps/action.yaml b/.github/actions/buildcdeps/action.yaml index b02be9af4..237992127 100644 --- a/.github/actions/buildcdeps/action.yaml +++ b/.github/actions/buildcdeps/action.yaml @@ -21,6 +21,11 @@ inputs: default: $GITHUB_WORKSPACE required: False type: string + cmake_flags: + description: 'Extra flags for cmake command' + default: -Wno-dev + required: False + type: string install_prefix: description: 'Install path of cdeps' default: $HOME/cdeps @@ -36,6 +41,5 @@ runs: pushd build-cdeps export ESMFMKFILE=${{ inputs.esmfmkfile }} export PIO=${{ inputs.pio_path }} - cmake -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-DCPRGNU -g -Wall -ffree-form -ffree-line-length-none -fallow-argument-mismatch " -DWERROR=ON ${{ inputs.src_root }} - make VERBOSE=1 + cmake ${{ inputs.cmake_flags }} ${{ inputs.src_root }} popd diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 08a92812f..e75c7a73a 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -98,4 +98,9 @@ jobs: esmfmkfile: $HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk pio_path: $HOME/pio src_root: $GITHUB_WORKSPACE - + cmake_flags: " -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DWERROR=ON -DCMAKE_Fortran_FLAGS=\"-DCPRGNU -g -Wall \ + -ffree-form -ffree-line-length-none -fallow-argument-mismatch \"" + - name: Test CDEPS + run: + cd build-cdeps + make VERBOSE=1 From cae6d80329b9e7562722c3b760c0ddd6176edeb5 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 19 May 2023 11:04:38 -0600 Subject: [PATCH 011/170] try again --- .github/workflows/extbuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index e75c7a73a..cc945c998 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -93,7 +93,7 @@ jobs: pnetcdf_path: /usr parallelio_path: $HOME/pio - name: Build CDEPS - uses: ESCOMP/CDEPS/.github/actions/buildcdeps + uses: ./.github/actions/buildcdeps with: esmfmkfile: $HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk pio_path: $HOME/pio From 169c2801e2fc2e6789dd61f2e6f0c254377b7374 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 19 May 2023 11:28:22 -0600 Subject: [PATCH 012/170] fix run statement format --- .github/workflows/extbuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index cc945c998..b2127bdc5 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -101,6 +101,6 @@ jobs: cmake_flags: " -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DWERROR=ON -DCMAKE_Fortran_FLAGS=\"-DCPRGNU -g -Wall \ -ffree-form -ffree-line-length-none -fallow-argument-mismatch \"" - name: Test CDEPS - run: + run: | cd build-cdeps make VERBOSE=1 From 4a1f889add5392378f0a2722e487b108795ea1d1 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 19 May 2023 15:11:01 -0600 Subject: [PATCH 013/170] need to build in action to make it useable by other repos --- .github/actions/buildcdeps/action.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/buildcdeps/action.yaml b/.github/actions/buildcdeps/action.yaml index 237992127..9d775dd12 100644 --- a/.github/actions/buildcdeps/action.yaml +++ b/.github/actions/buildcdeps/action.yaml @@ -42,4 +42,5 @@ runs: export ESMFMKFILE=${{ inputs.esmfmkfile }} export PIO=${{ inputs.pio_path }} cmake ${{ inputs.cmake_flags }} ${{ inputs.src_root }} + make VERBOSE=1 popd From 9a1d6f96a038219a7d1c02cf02ba7bea54396e66 Mon Sep 17 00:00:00 2001 From: Francis Vitt Date: Mon, 5 Jun 2023 11:32:49 -0600 Subject: [PATCH 014/170] update SST files for historical configurations --- docn/cime_config/config_component.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docn/cime_config/config_component.xml b/docn/cime_config/config_component.xml index a06201aaa..0e03abf26 100644 --- a/docn/cime_config/config_component.xml +++ b/docn/cime_config/config_component.xml @@ -155,12 +155,12 @@ $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.9x1.25_clim_c040926.nc $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.47x0.63_clim_c061106.nc $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.23x0.31_clim_c110526.nc - $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_1x1_1850_2012_c130411.nc - $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_48x96_1850_2012_c130411.nc - $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_1.9x2.5_1850_2012_c130411.nc - $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.9x1.25_1850_2012_c130411.nc - $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.47x0.63_1850_2012_c130411.nc - $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.23x0.31_1850_2012_c130411.nc + $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_1x1_1850_2021_c120422.nc + $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_48x96_1850_2021_c120422.nc + $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_1.9x2.5_1850_2021_c120422.nc + $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.9x1.25_1850_2021_c120422.nc + $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.47x0.63_1850_2021_c120422.nc + $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_0.23x0.31_1850_2021_c120422.nc $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_1x1_clim_pi_c101029.nc $DIN_LOC_ROOT/ocn/docn7/SSTDATA/sst_ice_CMIP6_DECK_E3SM_1x1_1850_clim_c20190125.nc $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_48x96_clim_pi_c101028.nc @@ -240,7 +240,7 @@ 0 - 2012 + 2021 run_component_cam_sstice env_run.xml From f5ad1193fc5e2fc3d6ac9efe3099f070bb1a82ec Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Tue, 27 Jun 2023 11:13:03 -0600 Subject: [PATCH 015/170] correct docs link in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e46df19ae..00da8d28c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Community Data Models for Earth Prediction Systems For documentation see -https://escomp.github.io/CDEPS/html/index.html +https://escomp.github.io/CDEPS/versions/master/html/index.html ## A note on github tag action From bb232d875611639b10b9bfeb6a82910341a14d25 Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Mon, 3 Jul 2023 15:10:14 -0600 Subject: [PATCH 016/170] enable DISABLE_FoX for standalone build --- CMakeLists.txt | 56 ++++++++++++++++++++++++++---------------- datm/CMakeLists.txt | 4 ++- dice/CMakeLists.txt | 4 ++- dlnd/CMakeLists.txt | 4 ++- docn/CMakeLists.txt | 4 ++- drof/CMakeLists.txt | 2 ++ dwav/CMakeLists.txt | 2 ++ streams/CMakeLists.txt | 8 +++--- 8 files changed, 56 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d88135b8..28fb2a269 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,12 @@ cmake_minimum_required(VERSION 3.10) include(ExternalProject) include(FetchContent) +set(DISABLE_FoX OFF CACHE BOOL "Disable FoX library to process XML files.") +message("DISABLE_FoX = ${DISABLE_FoX}") +if(DISABLE_FoX) + add_definitions(-DDISABLE_FoX) +endif() + if (DEFINED CIMEROOT) message("Using CIME in ${CIMEROOT} with compiler ${COMPILER}") include(${CASEROOT}/Macros.cmake) @@ -23,7 +29,9 @@ else() set(BLD_STANDALONE TRUE) project(NUOPC_DATA_MODELS LANGUAGES Fortran VERSION 0.1) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) - set(FOX_ROOT ${CMAKE_SOURCE_DIR}/fox) + if(NOT DISABLE_FoX) + set(FOX_ROOT ${CMAKE_SOURCE_DIR}/fox) + endif() endif() message("CMAKE_MODULE_PATH is ${CMAKE_MODULE_PATH}, CMAKE_Fortran_COMPILER is ${CMAKE_Fortran_COMPILER}") enable_language(Fortran) @@ -62,29 +70,32 @@ endif() add_subdirectory(streams) add_subdirectory(dshr) -if(IS_DIRECTORY "${FOX_ROOT}") - message(STATUS "FoX library is already checked out!") - message(STATUS "FoX source dir: ${FOX_ROOT}") -else() - FetchContent_Declare(fox - GIT_REPOSITORY https://github.com/ESMCI/fox.git - GIT_TAG 4.1.2.1 - SOURCE_DIR ${FOX_ROOT} - BINARY_DIR ${FOX_ROOT}/.. - ) - FetchContent_GetProperties(fox) - if(NOT fox_POPULATED) - FetchContent_Populate(fox) - message(STATUS "FoX source dir: ${fox_SOURCE_DIR}") - message(STATUS "FoX binary dir: ${fox_BINARY_DIR}") +if(NOT DISABLE_FoX) + if(IS_DIRECTORY "${FOX_ROOT}") + message(STATUS "FoX library is already checked out!") + message(STATUS "FoX source dir: ${FOX_ROOT}") + else() + FetchContent_Declare(fox + GIT_REPOSITORY https://github.com/ESMCI/fox.git + GIT_TAG 4.1.2.1 + SOURCE_DIR ${FOX_ROOT} + BINARY_DIR ${FOX_ROOT}/.. + ) + FetchContent_GetProperties(fox) + if(NOT fox_POPULATED) + FetchContent_Populate(fox) + message(STATUS "FoX source dir: ${fox_SOURCE_DIR}") + message(STATUS "FoX binary dir: ${fox_BINARY_DIR}") + endif() endif() + add_subdirectory(fox) + + target_include_directories(streams PUBLIC $ + $) + target_include_directories(dshr PUBLIC $ + $) endif() -add_subdirectory(fox) -target_include_directories(streams PUBLIC $ - $) -target_include_directories(dshr PUBLIC $ - $) target_include_directories(dshr PUBLIC $ $) @@ -112,6 +123,9 @@ foreach(COMP datm dice dlnd docn drof dwav) endforeach(COMP) foreach(DEPS streams dshr cdeps_share FoX_dom FoX_wxml FoX_sax FoX_common FoX_utils FoX_fsys) + if(DISABLE_FoX AND ${DEPS} MATCHES "^FoX") + continue() + endif() if(NOT BLD_STANDALONE AND ${DEPS} STREQUAL "cdeps_share") continue() endif() diff --git a/datm/CMakeLists.txt b/datm/CMakeLists.txt index b9413c0bc..0226ba739 100644 --- a/datm/CMakeLists.txt +++ b/datm/CMakeLists.txt @@ -25,4 +25,6 @@ add_dependencies(datm dshr streams) target_include_directories (datm PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (datm PRIVATE ${CMAKE_SOURCE_DIR}) target_include_directories (datm PRIVATE ${PIO_Fortran_INCLUDE_DIR}) -target_include_directories (datm PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +if(NOT DISABLE_FoX) + target_include_directories (datm PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +endif() diff --git a/dice/CMakeLists.txt b/dice/CMakeLists.txt index 02b48d36c..accd2c65f 100644 --- a/dice/CMakeLists.txt +++ b/dice/CMakeLists.txt @@ -19,4 +19,6 @@ add_dependencies(dice dshr streams) target_include_directories (dice PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (dice PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories (dice PRIVATE "${PIO_Fortran_INCLUDE_DIR}") -target_include_directories (dice PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +if(NOT DISABLE_FoX) + target_include_directories (dice PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +endif() diff --git a/dlnd/CMakeLists.txt b/dlnd/CMakeLists.txt index 38d6a416a..642bf63a1 100644 --- a/dlnd/CMakeLists.txt +++ b/dlnd/CMakeLists.txt @@ -17,4 +17,6 @@ add_dependencies(dlnd dshr streams) target_include_directories (dlnd PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (dlnd PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories (dlnd PRIVATE "${PIO_Fortran_INCLUDE_DIR}") -target_include_directories (dlnd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +if(NOT DISABLE_FoX) + target_include_directories (dlnd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +endif() diff --git a/docn/CMakeLists.txt b/docn/CMakeLists.txt index b8a2b44ee..0e085ba11 100644 --- a/docn/CMakeLists.txt +++ b/docn/CMakeLists.txt @@ -23,4 +23,6 @@ add_dependencies(docn dshr streams) target_include_directories (docn PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (docn PRIVATE ${CMAKE_SOURCE_DIR}) target_include_directories (docn PRIVATE ${PIO_Fortran_INCLUDE_DIR}) -target_include_directories (docn PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +if(NOT DISABLE_FoX) + target_include_directories (docn PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +endif() diff --git a/drof/CMakeLists.txt b/drof/CMakeLists.txt index 6cfc91167..e29dab041 100644 --- a/drof/CMakeLists.txt +++ b/drof/CMakeLists.txt @@ -17,4 +17,6 @@ add_dependencies(drof dshr streams) target_include_directories (drof PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (drof PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories (drof PRIVATE "${PIO_Fortran_INCLUDE_DIR}") +if(NOT DISABLE_FoX) target_include_directories (drof PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +endif() diff --git a/dwav/CMakeLists.txt b/dwav/CMakeLists.txt index 676b30040..6e338db2c 100644 --- a/dwav/CMakeLists.txt +++ b/dwav/CMakeLists.txt @@ -17,4 +17,6 @@ add_dependencies(dwav dshr streams) target_include_directories (dwav PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (dwav PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories (dwav PRIVATE "${PIO_Fortran_INCLUDE_DIR}") +if(NOT DISABLE_FoX) target_include_directories (dwav PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +endif() diff --git a/streams/CMakeLists.txt b/streams/CMakeLists.txt index 99066e802..ab4b534ba 100644 --- a/streams/CMakeLists.txt +++ b/streams/CMakeLists.txt @@ -18,14 +18,16 @@ message("Stream srcfiles are ${SRCFILES}") add_library(streams ${SRCFILES}) -add_dependencies(streams FoX_dom) +if(NOT DISABLE_FoX) + add_dependencies(streams FoX_dom) + target_include_directories (streams PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +endif() + if(BLD_STANDALONE) add_dependencies(streams cdeps_share) target_include_directories (streams PRIVATE ${CMAKE_BINARY_DIR}/share) endif() - -target_include_directories (streams PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) target_include_directories (streams PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (streams PRIVATE ${PIO_Fortran_INCLUDE_DIR}) From f3a837b9d94aa147f95855452f5ac57b1847f8c4 Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Mon, 3 Jul 2023 23:28:10 -0600 Subject: [PATCH 017/170] install data component specific module files --- datm/CMakeLists.txt | 11 +++++++++++ dice/CMakeLists.txt | 11 +++++++++++ dlnd/CMakeLists.txt | 11 +++++++++++ docn/CMakeLists.txt | 11 +++++++++++ drof/CMakeLists.txt | 11 +++++++++++ dwav/CMakeLists.txt | 11 +++++++++++ 6 files changed, 66 insertions(+) diff --git a/datm/CMakeLists.txt b/datm/CMakeLists.txt index 0226ba739..1676125d7 100644 --- a/datm/CMakeLists.txt +++ b/datm/CMakeLists.txt @@ -28,3 +28,14 @@ target_include_directories (datm PRIVATE ${PIO_Fortran_INCLUDE_DIR}) if(NOT DISABLE_FoX) target_include_directories (datm PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) endif() + +if(BLD_STANDALONE) + # ESMX requires mod files + foreach (SRC ${SRCFILES}) + string(REGEX REPLACE "[.]F90$" ".mod" MOD ${SRC}) + if (NOT DEFINED CIMEROOT AND MOD STREQUAL atm_comp_nuopc.mod) + set(MOD cdeps_datm_comp.mod) + endif() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MOD}" DESTINATION include) + endforeach () +endif() diff --git a/dice/CMakeLists.txt b/dice/CMakeLists.txt index accd2c65f..acfc26d47 100644 --- a/dice/CMakeLists.txt +++ b/dice/CMakeLists.txt @@ -22,3 +22,14 @@ target_include_directories (dice PRIVATE "${PIO_Fortran_INCLUDE_DIR}") if(NOT DISABLE_FoX) target_include_directories (dice PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) endif() + +if(BLD_STANDALONE) + # ESMX requires mod files + foreach (SRC ${SRCFILES}) + string(REGEX REPLACE "[.]F90$" ".mod" MOD ${SRC}) + if (NOT DEFINED CIMEROOT AND MOD STREQUAL ice_comp_nuopc.mod) + set(MOD cdeps_dice_comp.mod) + endif() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MOD}" DESTINATION include) + endforeach () +endif() diff --git a/dlnd/CMakeLists.txt b/dlnd/CMakeLists.txt index 642bf63a1..865f31e6b 100644 --- a/dlnd/CMakeLists.txt +++ b/dlnd/CMakeLists.txt @@ -20,3 +20,14 @@ target_include_directories (dlnd PRIVATE "${PIO_Fortran_INCLUDE_DIR}") if(NOT DISABLE_FoX) target_include_directories (dlnd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) endif() + +if(BLD_STANDALONE) + # ESMX requires mod files + foreach (SRC ${SRCFILES}) + string(REGEX REPLACE "[.]F90$" ".mod" MOD ${SRC}) + if (NOT DEFINED CIMEROOT AND MOD STREQUAL lnd_comp_nuopc.mod) + set(MOD cdeps_dlnd_comp.mod) + endif() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MOD}" DESTINATION include) + endforeach () +endif() diff --git a/docn/CMakeLists.txt b/docn/CMakeLists.txt index 0e085ba11..007d595ca 100644 --- a/docn/CMakeLists.txt +++ b/docn/CMakeLists.txt @@ -26,3 +26,14 @@ target_include_directories (docn PRIVATE ${PIO_Fortran_INCLUDE_DIR}) if(NOT DISABLE_FoX) target_include_directories (docn PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) endif() + +if(BLD_STANDALONE) + # ESMX requires mod files + foreach (SRC ${SRCFILES}) + string(REGEX REPLACE "[.]F90$" ".mod" MOD ${SRC}) + if (NOT DEFINED CIMEROOT AND MOD STREQUAL ocn_comp_nuopc.mod) + set(MOD cdeps_docn_comp.mod) + endif() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MOD}" DESTINATION include) + endforeach () +endif() diff --git a/drof/CMakeLists.txt b/drof/CMakeLists.txt index e29dab041..444c855e6 100644 --- a/drof/CMakeLists.txt +++ b/drof/CMakeLists.txt @@ -20,3 +20,14 @@ target_include_directories (drof PRIVATE "${PIO_Fortran_INCLUDE_DIR}") if(NOT DISABLE_FoX) target_include_directories (drof PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) endif() + +if(BLD_STANDALONE) + # ESMX requires mod files + foreach (SRC ${SRCFILES}) + string(REGEX REPLACE "[.]F90$" ".mod" MOD ${SRC}) + if (NOT DEFINED CIMEROOT AND MOD STREQUAL rof_comp_nuopc.mod) + set(MOD cdeps_drof_comp.mod) + endif() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MOD}" DESTINATION include) + endforeach () +endif() diff --git a/dwav/CMakeLists.txt b/dwav/CMakeLists.txt index 6e338db2c..2d96bf3a6 100644 --- a/dwav/CMakeLists.txt +++ b/dwav/CMakeLists.txt @@ -20,3 +20,14 @@ target_include_directories (dwav PRIVATE "${PIO_Fortran_INCLUDE_DIR}") if(NOT DISABLE_FoX) target_include_directories (dwav PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) endif() + +if(BLD_STANDALONE) + # ESMX requires mod files + foreach (SRC ${SRCFILES}) + string(REGEX REPLACE "[.]F90$" ".mod" MOD ${SRC}) + if (NOT DEFINED CIMEROOT AND MOD STREQUAL wav_comp_nuopc.mod) + set(MOD cdeps_dwav_comp.mod) + endif() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MOD}" DESTINATION include) + endforeach () +endif() From 2521e4e2e5788e2c69f2a6e7dea52c51da49fc5a Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Thu, 30 Jun 2022 22:00:58 +0000 Subject: [PATCH 018/170] introduce export_all option --- datm/atm_comp_nuopc.F90 | 17 +++++++++++------ dice/ice_comp_nuopc.F90 | 14 +++++++++----- dlnd/lnd_comp_nuopc.F90 | 17 ++++++++++++----- docn/ocn_comp_nuopc.F90 | 12 ++++++++---- drof/rof_comp_nuopc.F90 | 14 +++++++++----- dshr/dshr_fldlist_mod.F90 | 11 +++++++++-- dwav/wav_comp_nuopc.F90 | 18 ++++++++++++------ 7 files changed, 70 insertions(+), 33 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index c84e10f79..5e504a0fb 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -136,6 +136,7 @@ module cdeps_datm_comp integer :: nx_global ! global nx integer :: ny_global ! global ny logical :: skip_restart_read = .false. ! true => skip restart read in continuation run + logical :: export_all = .false. ! true => export all fields, do not check connected or not ! linked lists type(fldList_type) , pointer :: fldsImport => null() @@ -222,7 +223,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! local variables integer :: nu ! unit number integer :: ierr ! error code - integer :: bcasttmp(9) + integer :: bcasttmp(10) type(ESMF_VM) :: vm character(len=*),parameter :: subname=trim(modName) // ':(InitializeAdvertise) ' character(*) ,parameter :: F00 = "('(" // trim(modName) // ") ',8a)" @@ -247,7 +248,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) anomaly_forcing, & skip_restart_read, & flds_presndep, & - flds_preso3 + flds_preso3, & + export_all rc = ESMF_SUCCESS @@ -284,7 +286,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if(flds_co2) bcasttmp(7) = 1 if(flds_wiso) bcasttmp(8) = 1 if(skip_restart_read) bcasttmp(9) = 1 - + if(export_all) bcasttmp(10) = 1 end if call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -305,7 +307,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, restfilm, CL, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMBroadcast(vm, bcasttmp, 9, main_task, rc=rc) + call ESMF_VMBroadcast(vm, bcasttmp, 10, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return nx_global = bcasttmp(1) ny_global = bcasttmp(2) @@ -316,6 +318,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) flds_co2 = (bcasttmp(7) == 1) flds_wiso = (bcasttmp(8) == 1) skip_restart_read = (bcasttmp(9) == 1) + export_all = (bcasttmp(10) == 1) ! write namelist input to standard out if (my_task == main_task) then @@ -335,6 +338,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,F02)' flds_co2 = ',flds_co2 write(logunit,F02)' flds_wiso = ',flds_wiso write(logunit,F02)' skip_restart_read = ',skip_restart_read + write(logunit,F02)' export_all = ',export_all end if ! Validate sdat datamode @@ -433,10 +437,10 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState ! by replacing the advertised fields with the newly created fields of the same name. call dshr_fldlist_realize( exportState, fldsExport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//':datmExport', rc=rc) + subname//':datmExport', export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_fldlist_realize( importState, fldsImport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//':datmImport', rc=rc) + subname//':datmImport', .false., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get the time to interpolate the stream data to @@ -770,6 +774,7 @@ subroutine datm_init_dfields(rc) call ESMF_StateGet(exportState, itemNameList=lfieldnames, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do n = 1, fieldCount + call ESMF_LogWrite(trim(subname)//': field name = '//trim(lfieldnames(n)), ESMF_LOGMSG_INFO) call ESMF_StateGet(exportState, itemName=trim(lfieldnames(n)), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, rank=rank, rc=rc) diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index 266d86495..ba368983d 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -85,6 +85,7 @@ module cdeps_dice_comp character(CL) :: restfilm = nullstr ! model restart file namelist integer :: nx_global integer :: ny_global + logical :: export_all = .false. ! true => export all fields, do not check connected or not ! linked lists type(fldList_type) , pointer :: fldsImport => null() @@ -183,7 +184,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) namelist / dice_nml / datamode, & model_meshfile, model_maskfile, & - restfilm, nx_global, ny_global, flux_swpf, flux_Qmin, flux_Qacc, flux_Qacc0 + restfilm, nx_global, ny_global, & + flux_swpf, flux_Qmin, flux_Qacc, flux_Qacc0, export_all rc = ESMF_SUCCESS @@ -212,7 +214,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) end if ! write namelist input to standard out - write(logunit,F00)' datamode = ',trim(datamode) + write(logunit,F00)' datamode = ',trim(datamode) write(logunit,F00)' model_meshfile = ',trim(model_meshfile) write(logunit,F00)' model_maskfile = ',trim(model_maskfile) write(logunit,F01)' nx_global = ',nx_global @@ -222,10 +224,12 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,F02)' flux_Qacc = ',flux_Qacc write(logunit,F03)' flux_Qacc0 = ',flux_Qacc0 write(logunit,F00)' restfilm = ',trim(restfilm) + write(logunit,F02)' export_all = ',export_all bcasttmp = 0 bcasttmp(1) = nx_global bcasttmp(2) = ny_global if(flux_Qacc) bcasttmp(3) = 1 + if(export_all) bcasttmp(4) = 1 rbcasttmp(1) = flux_swpf rbcasttmp(2) = flux_Qmin rbcasttmp(3) = flux_Qacc0 @@ -251,12 +255,12 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) nx_global = bcasttmp(1) ny_global = bcasttmp(2) flux_Qacc = (bcasttmp(3) == 1) + export_all= (bcasttmp(4) == 1) flux_swpf = rbcasttmp(1) flux_Qmin = rbcasttmp(2) flux_Qacc0 = rbcasttmp(3) - ! Validate datamode if ( trim(datamode) == 'ssmi' .or. trim(datamode) == 'ssmi_iaf') then if (my_task == main_task) write(logunit,*) ' dice datamode = ',trim(datamode) @@ -327,10 +331,10 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState ! by replacing the advertised fields with the newly created fields of the same name. call dshr_fldlist_realize( exportState, fldsExport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//':diceExport', rc=rc) + subname//':diceExport', export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_fldlist_realize( importState, fldsImport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//':diceImport', rc=rc) + subname//':diceImport', .false., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! for single column, the target point might not be a point where the ice/ocn mask is > 0 diff --git a/dlnd/lnd_comp_nuopc.F90 b/dlnd/lnd_comp_nuopc.F90 index 320540581..df901dd0c 100644 --- a/dlnd/lnd_comp_nuopc.F90 +++ b/dlnd/lnd_comp_nuopc.F90 @@ -81,6 +81,8 @@ module cdeps_dlnd_comp integer :: nx_global ! global nx dimension of model mesh integer :: ny_global ! global ny dimension of model mesh logical :: skip_restart_read = .false. ! true => skip restart read in continuation + logical :: export_all = .false. ! true => export all fields, do not check connected or not + ! linked lists type(fldList_type) , pointer :: fldsExport => null() type(dfield_type) , pointer :: dfields => null() @@ -166,7 +168,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) type(ESMF_VM) :: vm character(CL) :: cvalue integer :: nu ! unit number - integer :: bcasttmp(3) + integer :: bcasttmp(4) integer :: ierr ! error code character(len=*) , parameter :: subname=trim(modName)//':(InitializeAdvertise) ' character(*) , parameter :: F00 = "('(" // trim(modName) // ") ',8a)" @@ -175,7 +177,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) !------------------------------------------------------------------------------- namelist / dlnd_nml / datamode, model_meshfile, model_maskfile, & - nx_global, ny_global, restfilm, skip_restart_read + nx_global, ny_global, restfilm, skip_restart_read, export_all rc = ESMF_SUCCESS @@ -206,7 +208,9 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) bcasttmp(1) = nx_global bcasttmp(2) = ny_global if(skip_restart_read) bcasttmp(3) = 1 + if(export_all) bcasttmp(4) = 1 end if + call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -223,6 +227,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) nx_global = bcasttmp(1) ny_global = bcasttmp(2) skip_restart_read = (bcasttmp(3) == 1) + export_all = (bcasttmp(4) == 1) ! write namelist input to standard out if (my_task == main_task) then @@ -233,6 +238,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,F01)' ny_global = ',ny_global write(logunit,F00)' restfilm = ',trim(restfilm) write(logunit,F02)' skip_restart_read = ',skip_restart_read + write(logunit,F02)' export_all = ',export_all endif ! Validate sdat datamode @@ -289,7 +295,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! Realize the actively coupled fields, now that a mesh is established and ! initialize dfields data type (to map streams to export state fields) - call dlnd_comp_realize(importState, exportState, rc=rc) + call dlnd_comp_realize(importState, exportState, export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Read restart if necessary @@ -459,11 +465,12 @@ subroutine dlnd_comp_advertise(importState, exportState, rc) end subroutine dlnd_comp_advertise !=============================================================================== - subroutine dlnd_comp_realize(importState, exportState, rc) + subroutine dlnd_comp_realize(importState, exportState, export_all, rc) ! input/output variables type(ESMF_State) , intent(inout) :: importState type(ESMF_State) , intent(inout) :: exportState + logical , intent(in) :: export_all integer , intent(out) :: rc ! local variables @@ -478,7 +485,7 @@ subroutine dlnd_comp_realize(importState, exportState, rc) ! ------------------------------------- call dshr_fldlist_realize( exportState, fldsExport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//':dlndExport', rc=rc) + subname//':dlndExport', export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine dlnd_comp_realize diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index d885b248b..e61474cbd 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -103,6 +103,7 @@ module cdeps_docn_comp integer :: nx_global integer :: ny_global logical :: skip_restart_read = .false. ! true => skip restart read in continuation run + logical :: export_all = .false. ! true => export all fields, do not check connected or not ! linked lists type(fldList_type) , pointer :: fldsImport => null() @@ -189,7 +190,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: nu ! unit number integer :: ierr ! error code character(len=CL) :: import_data_fields ! colon deliminted strings of input data fields - integer :: bcasttmp(3) + integer :: bcasttmp(4) real(r8) :: rtmp(1) type(ESMF_VM) :: vm character(len=*),parameter :: subname=trim(module_name)//':(InitializeAdvertise) ' @@ -202,7 +203,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) namelist / docn_nml / datamode, & model_meshfile, model_maskfile, & restfilm, nx_global, ny_global, sst_constant_value, skip_restart_read, & - import_data_fields + import_data_fields, export_all rc = ESMF_SUCCESS @@ -241,11 +242,13 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,F02)' skip_restart_read = ',skip_restart_read write(logunit,F00)' import_data_fields = ',trim(import_data_fields) write(logunit,*) ' sst_constant_value = ',sst_constant_value + write(logunit,F02)' export_all = ', export_all bcasttmp = 0 bcasttmp(1) = nx_global bcasttmp(2) = ny_global if(skip_restart_read) bcasttmp(3) = 1 + if(export_all) bcasttmp(4) = 1 rtmp(1) = sst_constant_value endif @@ -273,6 +276,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) nx_global = bcasttmp(1) ny_global = bcasttmp(2) skip_restart_read = (bcasttmp(3) == 1) + export_all = (bcasttmp(4) == 1) sst_constant_value = rtmp(1) ! Special logic for prescribed aquaplanet @@ -390,10 +394,10 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState ! by replacing the advertised fields with the newly created fields of the same name. call dshr_fldlist_realize( exportState, fldsExport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//trim(modelname)//':Export', rc=rc) + subname//trim(modelname)//':Export', export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_fldlist_realize( importState, fldsImport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//trim(modelname)//':Import', rc=rc) + subname//trim(modelname)//':Import', .false., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! for single column, the target point might not be a valid ocn point diff --git a/drof/rof_comp_nuopc.F90 b/drof/rof_comp_nuopc.F90 index 2dbe97d3c..f2172e7c5 100644 --- a/drof/rof_comp_nuopc.F90 +++ b/drof/rof_comp_nuopc.F90 @@ -76,6 +76,8 @@ module cdeps_drof_comp integer :: nx_global integer :: ny_global logical :: skip_restart_read = .false. ! true => skip restart read + logical :: export_all = .false. ! true => export all fields, do not check connected or not + logical :: diagnose_data = .true. integer , parameter :: main_task=0 ! task number of main task character(*) , parameter :: rpfile = 'rpointer.rof' @@ -164,7 +166,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: ierr ! error code type(fldlist_type), pointer :: fldList type(ESMF_VM) :: vm - integer :: bcasttmp(3) + integer :: bcasttmp(4) character(len=*),parameter :: subname=trim(modName)//':(InitializeAdvertise) ' character(*) ,parameter :: F00 = "('(" // trim(modName) // ") ',8a)" character(*) ,parameter :: F01 = "('(" // trim(modName) // ") ',a,2x,i8)" @@ -172,7 +174,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) !------------------------------------------------------------------------------- namelist / drof_nml / datamode, model_meshfile, model_maskfile, & - restfilm, nx_global, ny_global, skip_restart_read + restfilm, nx_global, ny_global, skip_restart_read, export_all rc = ESMF_SUCCESS @@ -201,17 +203,19 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) end if ! write namelist input to standard out - write(logunit,F00)' datamode = ',trim(datamode) + write(logunit,F00)' datamode = ',trim(datamode) write(logunit,F00)' model_meshfile = ',trim(model_meshfile) write(logunit,F00)' model_maskfile = ',trim(model_maskfile) write(logunit,F01)' nx_global = ',nx_global write(logunit,F01)' ny_global = ',ny_global write(logunit,F00)' restfilm = ',trim(restfilm) write(logunit,F02)' skip_restart_read = ',skip_restart_read + write(logunit,F02)' export_all = ', export_all bcasttmp = 0 bcasttmp(1) = nx_global bcasttmp(2) = ny_global if(skip_restart_read) bcasttmp(3) = 1 + if(export_all) bcasttmp(4) = 1 end if ! broadcast namelist input @@ -231,7 +235,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) nx_global = bcasttmp(1) ny_global = bcasttmp(2) skip_restart_read = (bcasttmp(3) == 1) - + export_all = (bcasttmp(4) == 1) ! Validate datamode if (trim(datamode) == 'copyall') then @@ -294,7 +298,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState ! by replacing the advertised fields with the newly created fields of the same name. call dshr_fldlist_realize( exportState, fldsExport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//':drofExport', rc=rc) + subname//':drofExport', export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get the time to interpolate the stream data to diff --git a/dshr/dshr_fldlist_mod.F90 b/dshr/dshr_fldlist_mod.F90 index 11b0ab5e3..398e1ce61 100644 --- a/dshr/dshr_fldlist_mod.F90 +++ b/dshr/dshr_fldlist_mod.F90 @@ -53,7 +53,7 @@ end subroutine dshr_fldlist_add !=============================================================================== - subroutine dshr_fldlist_realize(state, fldLists, flds_scalar_name, flds_scalar_num, mesh, tag, rc) + subroutine dshr_fldlist_realize(state, fldLists, flds_scalar_name, flds_scalar_num, mesh, tag, export_all, rc) ! input/output variables type(ESMF_State) , intent(inout) :: state @@ -62,6 +62,7 @@ subroutine dshr_fldlist_realize(state, fldLists, flds_scalar_name, flds_scalar_n integer , intent(in) :: flds_scalar_num type(ESMF_Mesh) , intent(in) :: mesh character(len=*) , intent(in) :: tag + logical , intent(in) :: export_all integer , intent(inout) :: rc ! local variables @@ -77,7 +78,13 @@ subroutine dshr_fldlist_realize(state, fldLists, flds_scalar_name, flds_scalar_n do while (associated(fldList)) stdname = fldList%stdname - if (NUOPC_IsConnected(state, fieldName=stdname)) then + if (NUOPC_IsConnected(state, fieldName=stdname) .or. export_all) then + ! Check field name since linked list might have empty string + if (trim(stdname) == '') then + fldList => fldList%next + cycle + end if + if (stdname == trim(flds_scalar_name)) then call ESMF_LogWrite(trim(subname)//trim(tag)//" Field = "//trim(stdname)//" is connected on root pe", & ESMF_LOGMSG_INFO) diff --git a/dwav/wav_comp_nuopc.F90 b/dwav/wav_comp_nuopc.F90 index abf1a029f..665aeb8d8 100644 --- a/dwav/wav_comp_nuopc.F90 +++ b/dwav/wav_comp_nuopc.F90 @@ -77,6 +77,8 @@ module cdeps_dwav_comp integer :: nx_global integer :: ny_global logical :: skip_restart_read = .false. ! true => skip restart read + logical :: export_all = .false. ! true => export all fields, do not check connected or not + ! constants logical :: diagnose_data = .true. integer , parameter :: main_task=0 ! task number of main task @@ -161,7 +163,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: nu ! unit number integer :: ierr ! error code type(ESMF_VM) :: vm - integer :: bcasttmp(3) + integer :: bcasttmp(4) character(len=*),parameter :: subname=trim(modName)//':(InitializeAdvertise) ' character(*) ,parameter :: F00 = "('(" // trim(modName) // ") ',8a)" character(*) ,parameter :: F01 = "('(" // trim(modName) // ") ',a,2x,i8)" @@ -169,7 +171,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) !------------------------------------------------------------------------------- namelist / dwav_nml / datamode, model_meshfile, model_maskfile, & - restfilm, nx_global, ny_global, skip_restart_read + restfilm, nx_global, ny_global, skip_restart_read, export_all rc = ESMF_SUCCESS @@ -198,17 +200,19 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) end if ! write namelist input to standard out - write(logunit,F00)' datamode = ',trim(datamode) + write(logunit,F00)' datamode = ',trim(datamode) write(logunit,F00)' model_meshfile = ',trim(model_meshfile) write(logunit,F00)' model_maskfile = ',trim(model_maskfile) write(logunit,F01)' nx_global = ',nx_global write(logunit,F01)' ny_global = ',ny_global write(logunit,F00)' restfilm = ',trim(restfilm) write(logunit,F02)' skip_restart_read = ',skip_restart_read + write(logunit,F02)' export_all = ', export_all bcasttmp = 0 bcasttmp(1) = nx_global bcasttmp(2) = ny_global if(skip_restart_read) bcasttmp(3) = 1 + if(export_all) bcasttmp(4) = 1 endif ! broadcast namelist input @@ -228,6 +232,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) nx_global = bcasttmp(1) ny_global = bcasttmp(2) skip_restart_read = (bcasttmp(3) == 1) + export_all = (bcasttmp(4) == 1) ! Call advertise phase if (trim(datamode) == 'copyall') then @@ -278,7 +283,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! Realize the actively coupled fields, now that a mesh is established and ! initialize dfields data type (to map streams to export state fields) - call dwav_comp_realize(importState, exportState, rc=rc) + call dwav_comp_realize(importState, exportState, export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Read restart if necessary @@ -427,11 +432,12 @@ subroutine dwav_comp_advertise(importState, exportState, rc) end subroutine dwav_comp_advertise !=============================================================================== - subroutine dwav_comp_realize(importState, exportState, rc) + subroutine dwav_comp_realize(importState, exportState, export_all, rc) ! input/output variables type(ESMF_State) , intent(inout) :: importState type(ESMF_State) , intent(inout) :: exportState + logical , intent(in) :: export_all integer , intent(out) :: rc ! local variables @@ -446,7 +452,7 @@ subroutine dwav_comp_realize(importState, exportState, rc) ! ------------------------------------- call dshr_fldlist_realize( exportState, fldsExport, flds_scalar_name, flds_scalar_num, model_mesh, & - subname//':dwavExport', rc=rc) + subname//':dwavExport', export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Create stream-> export state mapping From 707b505020670e9552cae757c400807755e4cd31 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Thu, 13 Jul 2023 11:51:20 -0600 Subject: [PATCH 019/170] fix for docn --- docn/ocn_comp_nuopc.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index e61474cbd..14b2b6d3c 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -267,7 +267,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call ESMF_VMBroadcast(vm, import_data_fields, CL, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMBroadcast(vm, bcasttmp, 3, main_task, rc=rc) + call ESMF_VMBroadcast(vm, bcasttmp, 4, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, rtmp, 1, main_task, rc=rc) From 4750a27a3f68f2cbc6526873290f834d85e960a3 Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 16 Aug 2023 11:25:21 -0600 Subject: [PATCH 020/170] update esmf bld to use official esmf action --- .github/workflows/extbuild.yml | 37 +++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index b2127bdc5..f95b1dd32 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -80,18 +80,31 @@ jobs: with: path: ~/ESMF key: ${{ runner.os }}-${{ env.ESMF_VERSION }}-ESMF2 - - name: Build ESMF - if: steps.cache-esmf.outputs.cache-hit != 'true' - uses: ./.github/actions/buildesmf - with: - esmf_version: ${{ env.ESMF_VERSION }} - esmf_bopt: g - esmf_comm: openmpi - install_prefix: $HOME/ESMF - netcdf_c_path: /usr - netcdf_fortran_path: /usr - pnetcdf_path: /usr - parallelio_path: $HOME/pio + # - name: Build ESMF + # if: steps.cache-esmf.outputs.cache-hit != 'true' + # uses: ./.github/actions/buildesmf + # with: + # esmf_version: ${{ env.ESMF_VERSION }} + # esmf_bopt: g + # esmf_comm: openmpi + # install_prefix: $HOME/ESMF + # netcdf_c_path: /usr + # netcdf_fortran_path: /usr + # pnetcdf_path: /usr + # parallelio_path: $HOME/pio + - name: Install ESMF + uses: esmf-org/install-esmf-action@v1 + env: + ESMF_COMPILER: gfortran + ESMF_BOPT: g + ESMF_COMM: openmpi + ESMF_NETCDF: nc-config + ESMF_INSTALL_PREFIX: $HOME/ESMF + with: + version: ${{ env.ESMF_VERSION }} + esmpy: false + cache: false + - name: Build CDEPS uses: ./.github/actions/buildcdeps with: From bb60bdcd6a7e70a3af54b68f9104304a116be17b Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 16 Aug 2023 11:30:13 -0600 Subject: [PATCH 021/170] update esmf bld to use official esmf action --- .github/workflows/extbuild.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index f95b1dd32..03ddaeb62 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -19,10 +19,10 @@ jobs: CPPFLAGS: "-I/usr/include -I/usr/local/include " LDFLAGS: "-L/usr/lib/x86_64-linux-gnu " # Versions of all dependencies can be updated here - these match tag names in the github repo - ESMF_VERSION: v8.4.0 + ESMF_VERSION: v8.5.0 #PNETCDF_VERSION: checkpoint.1.12.3 #NETCDF_FORTRAN_VERSION: v4.6.0 - ParallelIO_VERSION: pio2_5_10 + ParallelIO_VERSION: pio2_6_0 steps: - id: checkout-CDEPS uses: actions/checkout@v3 @@ -100,10 +100,10 @@ jobs: ESMF_COMM: openmpi ESMF_NETCDF: nc-config ESMF_INSTALL_PREFIX: $HOME/ESMF - with: - version: ${{ env.ESMF_VERSION }} - esmpy: false - cache: false + with: + version: ${{ env.ESMF_VERSION }} + esmpy: false + cache: false - name: Build CDEPS uses: ./.github/actions/buildcdeps From aab9411b89b58e6a99f655e02befe8d02daf22f7 Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 16 Aug 2023 12:35:21 -0600 Subject: [PATCH 022/170] add pio as external to esmf build --- .github/workflows/extbuild.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 03ddaeb62..ecadab3d5 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -100,6 +100,9 @@ jobs: ESMF_COMM: openmpi ESMF_NETCDF: nc-config ESMF_INSTALL_PREFIX: $HOME/ESMF + ESMF_PIO: external + ESMF_PIO_INCLUDE: $HOME/pio/include + ESMF_PIO_LIBPATH: $HOME/pio/lib with: version: ${{ env.ESMF_VERSION }} esmpy: false @@ -108,7 +111,7 @@ jobs: - name: Build CDEPS uses: ./.github/actions/buildcdeps with: - esmfmkfile: $HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk + esmfmkfile: $HOME/ESMF/lib/esmf.mk pio_path: $HOME/pio src_root: $GITHUB_WORKSPACE cmake_flags: " -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DWERROR=ON -DCMAKE_Fortran_FLAGS=\"-DCPRGNU -g -Wall \ From 2e1b9f8a59b5259da7f1ea461abaeb574cac9c67 Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 16 Aug 2023 12:50:51 -0600 Subject: [PATCH 023/170] add pio as external to esmf build --- .github/workflows/extbuild.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index ecadab3d5..f5bf9da8c 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -99,10 +99,10 @@ jobs: ESMF_BOPT: g ESMF_COMM: openmpi ESMF_NETCDF: nc-config - ESMF_INSTALL_PREFIX: $HOME/ESMF + ESMF_INSTALL_PREFIX: /home/runner/ESMF ESMF_PIO: external - ESMF_PIO_INCLUDE: $HOME/pio/include - ESMF_PIO_LIBPATH: $HOME/pio/lib + ESMF_PIO_INCLUDE: /home/runner/pio/include + ESMF_PIO_LIBPATH: /home/runner/pio/lib with: version: ${{ env.ESMF_VERSION }} esmpy: false From 57ef5ec5302794087350a53ae67dd1aca1599851 Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 16 Aug 2023 13:27:37 -0600 Subject: [PATCH 024/170] add pnetcdf-config --- .github/workflows/extbuild.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index f5bf9da8c..ba4e9ada4 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -74,12 +74,12 @@ jobs: parallelio_version: ${{ env.ParallelIO_VERSION }} enable_fortran: True install_prefix: $HOME/pio - - name: Cache ESMF - id: cache-esmf - uses: actions/cache@v3 - with: - path: ~/ESMF - key: ${{ runner.os }}-${{ env.ESMF_VERSION }}-ESMF2 + # - name: Cache ESMF + # id: cache-esmf + # uses: actions/cache@v3 + # with: + # path: ~/ESMF + # key: ${{ runner.os }}-${{ env.ESMF_VERSION }}-ESMF2 # - name: Build ESMF # if: steps.cache-esmf.outputs.cache-hit != 'true' # uses: ./.github/actions/buildesmf @@ -99,6 +99,7 @@ jobs: ESMF_BOPT: g ESMF_COMM: openmpi ESMF_NETCDF: nc-config + ESMF_PNETCDF: pnetcdf-config ESMF_INSTALL_PREFIX: /home/runner/ESMF ESMF_PIO: external ESMF_PIO_INCLUDE: /home/runner/pio/include From 6dce40229847d9e67da4972c1806e860d8306912 Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 16 Aug 2023 13:59:48 -0600 Subject: [PATCH 025/170] cleanup github workflow script --- .github/workflows/extbuild.yml | 46 +--------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index ba4e9ada4..8f063952e 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -20,8 +20,6 @@ jobs: LDFLAGS: "-L/usr/lib/x86_64-linux-gnu " # Versions of all dependencies can be updated here - these match tag names in the github repo ESMF_VERSION: v8.5.0 - #PNETCDF_VERSION: checkpoint.1.12.3 - #NETCDF_FORTRAN_VERSION: v4.6.0 ParallelIO_VERSION: pio2_6_0 steps: - id: checkout-CDEPS @@ -37,30 +35,6 @@ jobs: sudo apt-get install netcdf-bin libnetcdf-dev libnetcdff-dev sudo apt-get install pnetcdf-bin libpnetcdf-dev sudo apt-get install autotools-dev autoconf - # - id: cache-pnetcdf - # uses: actions/cache@v3 - # with: - # path: ~/pnetcdf - # key: ${{ runner.os }}-${{ env.PNETCDF_VERSION}}-pnetcdf1 - # - name: Build PNetCDF - # if: steps.cache-pnetcdf.outputs.cache-hit != 'true' - # uses: ./.github/actions/buildpnetcdf - # with: - # pnetcdf_version: ${{ env.PNETCDF_VERSION }} - # install_prefix: $HOME/pnetcdf - # - name: Cache netcdf-fortran - # id: cache-netcdf-fortran - # uses: actions/cache@v3 - # with: - # path: ~/netcdf-fortran - # key: ${{ runner.os }}-${{ env.NETCDF_FORTRAN_VERSION }}-netcdf-fortran1 - # - name: Build NetCDF Fortran - # if: steps.cache-netcdf-fortran.outputs.cache-hit != 'true' - # uses: ./.github/actions/buildnetcdff - # with: - # netcdf_fortran_version: ${{ env.NETCDF_FORTRAN_VERSION }} - # install_prefix: $HOME/netcdf-fortran - # netcdf_c_path: /usr - name: Cache PARALLELIO id: cache-PARALLELIO uses: actions/cache@v3 @@ -74,24 +48,6 @@ jobs: parallelio_version: ${{ env.ParallelIO_VERSION }} enable_fortran: True install_prefix: $HOME/pio - # - name: Cache ESMF - # id: cache-esmf - # uses: actions/cache@v3 - # with: - # path: ~/ESMF - # key: ${{ runner.os }}-${{ env.ESMF_VERSION }}-ESMF2 - # - name: Build ESMF - # if: steps.cache-esmf.outputs.cache-hit != 'true' - # uses: ./.github/actions/buildesmf - # with: - # esmf_version: ${{ env.ESMF_VERSION }} - # esmf_bopt: g - # esmf_comm: openmpi - # install_prefix: $HOME/ESMF - # netcdf_c_path: /usr - # netcdf_fortran_path: /usr - # pnetcdf_path: /usr - # parallelio_path: $HOME/pio - name: Install ESMF uses: esmf-org/install-esmf-action@v1 env: @@ -107,7 +63,7 @@ jobs: with: version: ${{ env.ESMF_VERSION }} esmpy: false - cache: false + cache: true - name: Build CDEPS uses: ./.github/actions/buildcdeps From 8276318340c99a933e3b72210814c9bd9c071258 Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 16 Aug 2023 15:46:47 -0600 Subject: [PATCH 026/170] response to review --- .github/workflows/extbuild.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 8f063952e..6e4aa00cf 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -39,7 +39,7 @@ jobs: id: cache-PARALLELIO uses: actions/cache@v3 with: - path: ~/pio + path: $GITHUB_WORKSPACE/pio key: ${{ runner.os }}-${{ env.ParallelIO_VERSION }}-parallelio2 - name: Build ParallelIO if: steps.cache-PARALLELIO.outputs.cache-hit != 'true' @@ -47,7 +47,7 @@ jobs: with: parallelio_version: ${{ env.ParallelIO_VERSION }} enable_fortran: True - install_prefix: $HOME/pio + install_prefix: $GITHUB_WORKSPACE/pio - name: Install ESMF uses: esmf-org/install-esmf-action@v1 env: @@ -56,10 +56,10 @@ jobs: ESMF_COMM: openmpi ESMF_NETCDF: nc-config ESMF_PNETCDF: pnetcdf-config - ESMF_INSTALL_PREFIX: /home/runner/ESMF + ESMF_INSTALL_PREFIX: $GITHUB_WORKSPACE/ESMF ESMF_PIO: external - ESMF_PIO_INCLUDE: /home/runner/pio/include - ESMF_PIO_LIBPATH: /home/runner/pio/lib + ESMF_PIO_INCLUDE: $GITHUB_WORKSPACE/pio/include + ESMF_PIO_LIBPATH: $GITHUB_WORKSPACE/pio/lib with: version: ${{ env.ESMF_VERSION }} esmpy: false @@ -68,8 +68,8 @@ jobs: - name: Build CDEPS uses: ./.github/actions/buildcdeps with: - esmfmkfile: $HOME/ESMF/lib/esmf.mk - pio_path: $HOME/pio + esmfmkfile: $ESMFMKFILE + pio_path: $GITHUB_WORKSPACE/pio src_root: $GITHUB_WORKSPACE cmake_flags: " -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DWERROR=ON -DCMAKE_Fortran_FLAGS=\"-DCPRGNU -g -Wall \ -ffree-form -ffree-line-length-none -fallow-argument-mismatch \"" From f415e668e5bd8e029b8c2756bc21df4a102be58e Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 16 Aug 2023 15:56:05 -0600 Subject: [PATCH 027/170] response to review --- .github/workflows/extbuild.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 6e4aa00cf..52afb7b81 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -39,7 +39,7 @@ jobs: id: cache-PARALLELIO uses: actions/cache@v3 with: - path: $GITHUB_WORKSPACE/pio + path: ${GITHUB_WORKSPACE}/pio key: ${{ runner.os }}-${{ env.ParallelIO_VERSION }}-parallelio2 - name: Build ParallelIO if: steps.cache-PARALLELIO.outputs.cache-hit != 'true' @@ -47,7 +47,7 @@ jobs: with: parallelio_version: ${{ env.ParallelIO_VERSION }} enable_fortran: True - install_prefix: $GITHUB_WORKSPACE/pio + install_prefix: ${GITHUB_WORKSPACE}/pio - name: Install ESMF uses: esmf-org/install-esmf-action@v1 env: @@ -56,10 +56,10 @@ jobs: ESMF_COMM: openmpi ESMF_NETCDF: nc-config ESMF_PNETCDF: pnetcdf-config - ESMF_INSTALL_PREFIX: $GITHUB_WORKSPACE/ESMF + ESMF_INSTALL_PREFIX: ${GITHUB_WORKSPACE}/ESMF ESMF_PIO: external - ESMF_PIO_INCLUDE: $GITHUB_WORKSPACE/pio/include - ESMF_PIO_LIBPATH: $GITHUB_WORKSPACE/pio/lib + ESMF_PIO_INCLUDE: ${GITHUB_WORKSPACE}/pio/include + ESMF_PIO_LIBPATH: ${GITHUB_WORKSPACE}/pio/lib with: version: ${{ env.ESMF_VERSION }} esmpy: false @@ -69,8 +69,8 @@ jobs: uses: ./.github/actions/buildcdeps with: esmfmkfile: $ESMFMKFILE - pio_path: $GITHUB_WORKSPACE/pio - src_root: $GITHUB_WORKSPACE + pio_path: ${GITHUB_WORKSPACE}/pio + src_root: ${GITHUB_WORKSPACE} cmake_flags: " -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DWERROR=ON -DCMAKE_Fortran_FLAGS=\"-DCPRGNU -g -Wall \ -ffree-form -ffree-line-length-none -fallow-argument-mismatch \"" - name: Test CDEPS From d31de600982edc7955a6611e2411868df094ae41 Mon Sep 17 00:00:00 2001 From: adrifoster Date: Mon, 21 Aug 2023 12:07:33 -0600 Subject: [PATCH 028/170] simple fix --- cime_config/buildlib | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/buildlib b/cime_config/buildlib index 965836cff..d62fa4e09 100755 --- a/cime_config/buildlib +++ b/cime_config/buildlib @@ -180,8 +180,8 @@ def buildlib(bldroot, libroot, case): # Do not allow any warnings except from fox external nextline = "" for line in e.split("\n"): - if "F90" in line and not "fox" in line: - nextline.append(line) + if "f90" in line.lower() and not "fox" in line.lower(): + nextline = nextline + line if len(nextline) > 0: expect(False, nextline) From 8b7bb12fb24e2c08ee701144d8791024388d6529 Mon Sep 17 00:00:00 2001 From: adrifoster Date: Mon, 21 Aug 2023 12:21:12 -0600 Subject: [PATCH 029/170] make a little nicer --- cime_config/buildlib | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/buildlib b/cime_config/buildlib index a692a4e50..6e2ee0426 100755 --- a/cime_config/buildlib +++ b/cime_config/buildlib @@ -177,8 +177,8 @@ def buildlib(bldroot, libroot, case): if compiler == "gnu" and case.get_value("DEBUG"): # Do not allow any warnings except from fox external nextline = "" - for line in e.split("\n"): - if "f90" in line.lower() and not "fox" in line.lower(): + for line in e.split("\n").lower(): + if "f90" in line and not "fox" in line: nextline = nextline + line if len(nextline) > 0: expect(False, nextline) From a04df35accf9bca1ebe5b999dc3c569f488418d9 Mon Sep 17 00:00:00 2001 From: adrifoster Date: Mon, 21 Aug 2023 13:03:30 -0600 Subject: [PATCH 030/170] put back... --- cime_config/buildlib | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/buildlib b/cime_config/buildlib index 6e2ee0426..a692a4e50 100755 --- a/cime_config/buildlib +++ b/cime_config/buildlib @@ -177,8 +177,8 @@ def buildlib(bldroot, libroot, case): if compiler == "gnu" and case.get_value("DEBUG"): # Do not allow any warnings except from fox external nextline = "" - for line in e.split("\n").lower(): - if "f90" in line and not "fox" in line: + for line in e.split("\n"): + if "f90" in line.lower() and not "fox" in line.lower(): nextline = nextline + line if len(nextline) > 0: expect(False, nextline) From 57cd466a821906808851ba59bd88c3a3609c5cf2 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Sun, 8 Oct 2023 15:04:36 -0600 Subject: [PATCH 031/170] in simple (idealized) data mode, replace giss radiation with an idealized forcing controlled via nml params --- datm/cime_config/namelist_definition_datm.xml | 28 ++++++- datm/datm_datamode_simple_mod.F90 | 74 +++++++------------ 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index 8afbf6446..491b6f6d1 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -70,9 +70,7 @@ ERA5_HOURLY - - CORE2_NYF.GISS - + CPLHISTForcing.Solar,CPLHISTForcing.nonSolarFlux,CPLHISTForcing.State3hr,CPLHISTForcing.State1hr @@ -450,5 +448,29 @@ + + real + datm + const_forcing_nml + + Peak idealized shortwave radiation to be passed to ice/ocean surface. + units: W m-2 + + + 330.0 + + + + real + datm + const_forcing_nml + + Peak idealized longwave radiation to be passed to ice/ocean surface. + units: W m-2 + + + 450.0 + + diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 index c622d0ca3..ce8c71457 100644 --- a/datm/datm_datamode_simple_mod.F90 +++ b/datm/datm_datamode_simple_mod.F90 @@ -58,19 +58,19 @@ module datm_datamode_simple_mod real(r8), pointer :: Faxa_swnet(:) => null() real(r8), pointer :: Faxa_ndep(:,:) => null() - ! stream data - real(r8), pointer :: strm_swdn(:) => null() - ! othe module arrays real(R8), pointer :: yc(:) ! array of model latitudes + real(R8), pointer :: xc(:) ! array of model longitudes - ! constant forcing values + ! constant forcing values to be set via const_forcing_nml real(R8) :: dn10 = 1.204_R8 real(R8) :: slp = 101325.0_R8 real(R8) :: q = 0.0_R8 real(R8) :: t = 273.15_R8 real(R8) :: u = 0.0_R8 real(R8) :: v = 0.0_R8 + real(R8) :: peak_swdn = 330.0_R8 + real(R8) :: peak_lwdn = 450.0_R8 ! constants real(R8) , parameter :: tKFrz = SHR_CONST_TKFRZ @@ -108,7 +108,7 @@ subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_n !------------------------------------------------------------------------------- - namelist / const_forcing_nml / dn10, slp, q, t, u, v + namelist / const_forcing_nml / dn10, slp, q, t, u, v, peak_swdn, peak_lwdn rc = ESMF_SUCCESS @@ -128,6 +128,8 @@ subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_n call shr_mpi_bcast(t , mpicom, 't') call shr_mpi_bcast(u , mpicom, 'u') call shr_mpi_bcast(v , mpicom, 'v') + call shr_mpi_bcast(peak_swdn , mpicom, 'peak_swdn') + call shr_mpi_bcast(peak_lwdn , mpicom, 'peak_lwdn') call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) call dshr_fldList_add(fldsExport, 'Sa_z' ) @@ -187,18 +189,14 @@ subroutine datm_datamode_simple_init_pointers(exportState, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(ownedElemCoords(spatialDim*numOwnedElements)) allocate(yc(numOwnedElements)) + allocate(xc(numOwnedElements)) call ESMF_MeshGet(sdat%model_mesh, ownedElemCoords=ownedElemCoords) if (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1,numOwnedElements yc(n) = ownedElemCoords(2*n) + xc(n) = ownedElemCoords(2*n-1) end do - ! get stream pointers - !todo call shr_strdata_get_stream_pointer( sdat, 'Faxa_prec' , strm_prec , rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) return - call shr_strdata_get_stream_pointer( sdat, 'Faxa_swdn' , strm_swdn , rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! get export state pointers call dshr_state_getfldptr(exportState, 'Sa_z' , fldptr1=Sa_z , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -246,10 +244,6 @@ subroutine datm_datamode_simple_init_pointers(exportState, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - if (.not. associated(strm_swdn)) then - call shr_sys_abort(trim(subname)//'ERROR: swdn must be in streams for SIMPLE') - endif - end subroutine datm_datamode_simple_init_pointers !=============================================================================== @@ -266,13 +260,12 @@ subroutine datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & ! local variables integer :: n integer :: lsize - real(R8) :: avg_alb ! average albedo real(R8) :: rday ! elapsed day - real(R8) :: cosFactor ! cosine factor - real(R8) :: factor ! generic/temporary correction factor - real(R8) :: tMin ! minimum temperature - real(R8) :: uprime,vprime character(len=*), parameter :: subname='(datm_datamode_simple): ' + real(R8), parameter :: epsilon_deg = 23.45 ! axial tilt of the Earth + real(R8) :: solar_decl ! solar declination angle (rad) to be used in idealized radiation calculations + real(R8) :: hour_angle ! hour angle (rad) to be used in idealized radiation calculations + real(R8) :: zenith_angle ! solar senith angle (rad) to be used in idealized radiation calculations !------------------------------------------------------------------------------- rc = ESMF_SUCCESS @@ -281,7 +274,6 @@ subroutine datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & call shr_cal_date2julian(target_ymd, target_tod, rday, model_calendar) rday = mod((rday - 1.0_R8),365.0_R8) - cosfactor = cos((2.0_R8*SHR_CONST_PI*rday)/365 - phs_c0) do n = 1,lsize Sa_z(n) = 10.0_R8 @@ -310,33 +302,19 @@ subroutine datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & !--- (iii) RADIATION DATA --- - !--- fabricate required swdn components from net swdn --- - Faxa_swvdr(n) = strm_swdn(n)*(0.28_R8) - Faxa_swndr(n) = strm_swdn(n)*(0.31_R8) - Faxa_swvdf(n) = strm_swdn(n)*(0.24_R8) - Faxa_swndf(n) = strm_swdn(n)*(0.17_R8) - !--- compute net short-wave based on LY08 latitudinally-varying albedo --- - avg_alb = ( 0.069 - 0.011*cos(2.0_R8*yc(n)*degtorad ) ) - Faxa_swnet(n) = strm_swdn(n)*(1.0_R8 - avg_alb) - !--- corrections to GISS sswdn for heat budget balancing --- - factor = 1.0_R8 - if ( -60.0_R8 < yc(n) .and. yc(n) < -50.0_R8 ) then - factor = 1.0_R8 - (yc(n) + 60.0_R8)*(0.05_R8/10.0_R8) - else if ( -50.0_R8 < yc(n) .and. yc(n) < 30.0_R8 ) then - factor = 0.95_R8 - else if ( 30.0_R8 < yc(n) .and. yc(n) < 40._R8 ) then - factor = 1.0_R8 - (40.0_R8 - yc(n))*(0.05_R8/10.0_R8) - endif - Faxa_swnet(n) = Faxa_swnet(n)*factor - Faxa_swvdr(n) = Faxa_swvdr(n)*factor - Faxa_swndr(n) = Faxa_swndr(n)*factor - Faxa_swvdf(n) = Faxa_swvdf(n)*factor - Faxa_swndf(n) = Faxa_swndf(n)*factor - !--- correction to GISS lwdn in Arctic --- - if ( yc(n) > 60._R8 ) then - factor = MIN(1.0_R8, 0.1_R8*(yc(n)-60.0_R8) ) - Faxa_lwdn(n) = Faxa_lwdn(n) + factor * dLWarc - endif + ! long wave + solar_decl = (epsilon_deg * degtorad) * sin( 2.0_R8 * shr_const_pi * (int(rday) + 284.0_R8) / 365.0_R8) + zenith_angle = acos(sin(yc(n) * degtorad ) * sin(solar_decl) + cos(yc(n) * degtorad) * cos(solar_decl) ) + Faxa_lwdn(n) = max(0.0_R8, peak_lwdn * cos(zenith_angle)) + + ! short wave + hour_angle = (15.0_R8 * (target_tod/3600.0_R8 - 12.0_R8) + xc(n) ) * degtorad + zenith_angle = acos(sin(yc(n) * degtorad ) * sin(solar_decl) + cos(yc(n) * degtorad) * cos(solar_decl) * cos(hour_angle) ) + Faxa_swnet(n) = max(0.0_R8, peak_swdn * cos(zenith_angle)) + Faxa_swvdr(n) = Faxa_swnet(n)*(0.28_R8) + Faxa_swndr(n) = Faxa_swnet(n)*(0.31_R8) + Faxa_swvdf(n) = Faxa_swnet(n)*(0.24_R8) + Faxa_swndf(n) = Faxa_swnet(n)*(0.17_R8) enddo ! lsize From 3501b2092a7dda7093e0a719dc072a62374968e1 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Sun, 8 Oct 2023 19:29:35 -0600 Subject: [PATCH 032/170] address change requests: undo nlfilename assignment reorder, use ESMF_VMBroadcast --- datm/atm_comp_nuopc.F90 | 4 ++-- datm/datm_datamode_simple_mod.F90 | 36 +++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 816726739..8d9a4835c 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -273,8 +273,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) mainproc = (my_task == main_task) ! Read atm_nml from nlfilename - nlfilename = "datm_in"//trim(inst_suffix) if (my_task == main_task) then + nlfilename = "datm_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") read (nu,nml=datm_nml,iostat=ierr) close(nu) @@ -391,7 +391,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('SIMPLE') call datm_datamode_simple_advertise(exportState, fldsExport, flds_scalar_name, & - nlfilename, my_task, mpicom, rc) + nlfilename, my_task, vm, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 index ce8c71457..9d670dbea 100644 --- a/datm/datm_datamode_simple_mod.F90 +++ b/datm/datm_datamode_simple_mod.F90 @@ -10,6 +10,7 @@ module datm_datamode_simple_mod use ESMF , only : ESMF_RouteHandleDestroy, ESMF_EXTRAPMETHOD_NEAREST_STOD use ESMF , only : ESMF_POLEMETHOD_ALLAVG, ESMF_REGRIDMETHOD_BILINEAR use ESMF , only : ESMF_DistGridGet, ESMF_FieldRegridStore, ESMF_FieldRedistStore + use ESMF , only : ESMF_VM, ESMF_VMBroadcast use pio , only : Var_Desc_t, file_desc_t, io_desc_t, pio_read_darray, pio_freedecomp use pio , only : pio_openfile, PIO_NOWRITE, pio_seterrorhandling, PIO_BCAST_ERROR use pio , only : pio_initdecomp, pio_inq_dimlen, pio_inq_varid @@ -19,7 +20,6 @@ module datm_datamode_simple_mod use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort use shr_cal_mod , only : shr_cal_date2julian - use shr_mpi_mod , only : shr_mpi_bcast use shr_const_mod , only : shr_const_tkfrz, shr_const_pi use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, dshr_fldbun_regrid, chkerr @@ -88,7 +88,7 @@ module datm_datamode_simple_mod !=============================================================================== subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_name, & - nlfilename, my_task, mpicom, rc) + nlfilename, my_task, vm, rc) ! input/output variables type(esmf_State) , intent(inout) :: exportState @@ -96,7 +96,7 @@ subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_n character(len=*) , intent(in) :: flds_scalar_name character(len=*) , intent(in) :: nlfilename integer , intent(in) :: my_task - integer , intent(in) :: mpicom + type(ESMF_VM) , intent(in) :: vm integer , intent(out) :: rc ! local variables @@ -105,6 +105,7 @@ subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_n integer :: ierr ! error code integer :: nu ! unit number character(len=*) , parameter :: subname='(datm_datamode_simple_advertise): ' + real(R8) :: bcasttmp(8) !------------------------------------------------------------------------------- @@ -120,16 +121,29 @@ subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_n if (ierr > 0) then call shr_sys_abort(subName//': namelist read error '//trim(nlfilename)) end if + + bcasttmp = 0 + bcasttmp(1) = dn10 + bcasttmp(2) = slp + bcasttmp(3) = q + bcasttmp(4) = t + bcasttmp(5) = u + bcasttmp(6) = v + bcasttmp(7) = peak_swdn + bcasttmp(8) = peak_lwdn end if - call shr_mpi_bcast(dn10 , mpicom, 'dn10') - call shr_mpi_bcast(slp , mpicom, 'slp') - call shr_mpi_bcast(q , mpicom, 'q') - call shr_mpi_bcast(t , mpicom, 't') - call shr_mpi_bcast(u , mpicom, 'u') - call shr_mpi_bcast(v , mpicom, 'v') - call shr_mpi_bcast(peak_swdn , mpicom, 'peak_swdn') - call shr_mpi_bcast(peak_lwdn , mpicom, 'peak_lwdn') + call ESMF_VMBroadcast(vm, bcasttmp, 8, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + dn10 = bcasttmp(1) + slp = bcasttmp(2) + q = bcasttmp(3) + t = bcasttmp(4) + u = bcasttmp(5) + v = bcasttmp(6) + peak_swdn = bcasttmp(7) + peak_lwdn = bcasttmp(8) call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) call dshr_fldList_add(fldsExport, 'Sa_z' ) From 4a38196540e9397147eacac244960ce72ad8f8d3 Mon Sep 17 00:00:00 2001 From: James Edwards Date: Tue, 17 Oct 2023 11:43:03 -0600 Subject: [PATCH 033/170] add save attribute to this variable --- dshr/dshr_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index 579296a9a..f253adc05 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -1346,7 +1346,7 @@ subroutine dshr_orbital_update(Time, logunit, maintask, eccen, obliqr, lambm0, integer :: orb_year ! orbital year for current orbital computation character(len=CL) :: msgstr ! temporary logical :: lprint - logical :: first_time = .true. + logical, save :: first_time = .true. character(len=*) , parameter :: subname = "(dshr_orbital_update)" !------------------------------------------- From a0e50c9badde2a23b9c45907907d49429def7d99 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 20 Oct 2023 14:07:01 -0600 Subject: [PATCH 034/170] add namelist lookup to each namelist read call --- datm/atm_comp_nuopc.F90 | 7 ++++++- datm/datm_datamode_simple_mod.F90 | 2 ++ dice/ice_comp_nuopc.F90 | 3 +++ dlnd/lnd_comp_nuopc.F90 | 3 +++ docn/ocn_comp_nuopc.F90 | 3 ++- drof/rof_comp_nuopc.F90 | 3 ++- dwav/wav_comp_nuopc.F90 | 2 ++ 7 files changed, 20 insertions(+), 3 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 8d9a4835c..dbd441085 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -219,7 +219,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) - + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp type(ESMF_State) :: importState, exportState @@ -276,6 +276,11 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (my_task == main_task) then nlfilename = "datm_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'datm_nml', status=ierr) + if (ierr > 0) then + write(logunit,*) 'ERROR: reading input namelist, '//trim(nlfilename)//' iostat=',ierr + call shr_sys_abort(subName//': namelist read error '//trim(nlfilename)) + end if read (nu,nml=datm_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 index 9d670dbea..ca978c153 100644 --- a/datm/datm_datamode_simple_mod.F90 +++ b/datm/datm_datamode_simple_mod.F90 @@ -89,6 +89,7 @@ module datm_datamode_simple_mod subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_name, & nlfilename, my_task, vm, rc) + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(esmf_State) , intent(inout) :: exportState @@ -116,6 +117,7 @@ subroutine datm_datamode_simple_advertise(exportState, fldsexport, flds_scalar_n ! Read const_forcing_nml from nlfilename if (my_task == main_task) then open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'const_forcing_nml', status=ierr) read (nu,nml=const_forcing_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index ba368983d..fd552bbcb 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -160,6 +160,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp @@ -206,6 +207,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (my_task == main_task) then nlfilename = "dice_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'dice_nml', status=ierr) + read (nu,nml=dice_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/dlnd/lnd_comp_nuopc.F90 b/dlnd/lnd_comp_nuopc.F90 index df901dd0c..ff84bae05 100644 --- a/dlnd/lnd_comp_nuopc.F90 +++ b/dlnd/lnd_comp_nuopc.F90 @@ -157,6 +157,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp @@ -198,6 +199,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (my_task == main_task) then nlfilename = "dlnd_in"//trim(inst_suffix) open (newunit=nu, file=trim(nlfilename), status="old", action="read") + call shr_nl_find_group_name(nu, 'dlnd_nml', status=ierr) + read (nu,nml=dlnd_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index 14b2b6d3c..462989995 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -178,7 +178,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) - + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp type(ESMF_State) :: importState, exportState @@ -224,6 +224,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Read docn_nml from nlfilename nlfilename = "docn_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'docn_nml', status=ierr) read (nu,nml=docn_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/drof/rof_comp_nuopc.F90 b/drof/rof_comp_nuopc.F90 index f2172e7c5..c3602cd97 100644 --- a/drof/rof_comp_nuopc.F90 +++ b/drof/rof_comp_nuopc.F90 @@ -153,7 +153,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) - + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp type(ESMF_State) :: importState, exportState @@ -195,6 +195,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (mainproc) then nlfilename = "drof_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'drof_nml', status=ierr) read (nu,nml=drof_nml,iostat=ierr) close(nu) if (ierr > 0) then diff --git a/dwav/wav_comp_nuopc.F90 b/dwav/wav_comp_nuopc.F90 index 665aeb8d8..e200e00b6 100644 --- a/dwav/wav_comp_nuopc.F90 +++ b/dwav/wav_comp_nuopc.F90 @@ -151,6 +151,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) + use shr_nl_mod, only: shr_nl_find_group_name ! input/output variables type(ESMF_GridComp) :: gcomp @@ -192,6 +193,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (my_task == main_task) then nlfilename = "dwav_in"//trim(inst_suffix) open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'dwav_nml', status=ierr) read (nu,nml=dwav_nml,iostat=ierr) close(nu) if (ierr > 0) then From 7f79dc66e5ddc9ff97b02bde7be62ba41426098b Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 20 Oct 2023 15:06:46 -0600 Subject: [PATCH 035/170] need to add shr_nl_mod for standalone builds --- share/CMakeLists.txt | 1 + share/shr_nl_mod.F90 | 88 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 share/shr_nl_mod.F90 diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 215847dae..fa5f4844e 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -5,6 +5,7 @@ set (GenF90_SRCS shr_infnan_mod.F90 shr_assert_mod.F90) add_library(cdeps_share ${GenF90_SRCS} + shr_nl_mod.F90 glc_elevclass_mod.F90 shr_timer_mod.F90 shr_cal_mod.F90 diff --git a/share/shr_nl_mod.F90 b/share/shr_nl_mod.F90 new file mode 100644 index 000000000..f06f2185c --- /dev/null +++ b/share/shr_nl_mod.F90 @@ -0,0 +1,88 @@ +module shr_nl_mod + +! Utilities for namelist reading +! Adapted Fall 2012 from CAM's namelist_utils. + +implicit none +private + +save + +public :: & + shr_nl_find_group_name ! seek through a file to find a specified namelist + +contains + +! This routine probably discards more error code information than it needs to. + +subroutine shr_nl_find_group_name(unit, group, status) + + use shr_string_mod, only: shr_string_toLower + +!--------------------------------------------------------------------------------------- +! Purpose: +! Search a file that contains namelist input for the specified namelist group name. +! Leave the file positioned so that the current record is the first record of the +! input for the specified group. +! +! Method: +! Read the file line by line. Each line is searched for an '&' which may only +! be preceded by blanks, immediately followed by the group name which is case +! insensitive. If found then backspace the file so the current record is the +! one containing the group name and return success. Otherwise return -1. +! +! Author: B. Eaton, August 2007 +!--------------------------------------------------------------------------------------- + + integer, intent(in) :: unit ! fortran unit attached to file + character(len=*), intent(in) :: group ! namelist group name + integer, intent(out) :: status ! 0 for success, -1 if group name not found + + ! Local variables + + integer :: len_grp + integer :: ios ! io status + character(len=80) :: inrec ! first 80 characters of input record + character(len=80) :: inrec2 ! left adjusted input record + character(len=len(group)) :: lc_group + + !--------------------------------------------------------------------------- + + len_grp = len_trim(group) + lc_group = shr_string_toLower(group) + + ios = 0 + do while (ios <= 0) + + read(unit, '(a)', iostat=ios, end=100) inrec + + if (ios <= 0) then ! ios < 0 indicates an end of record condition + + ! look for group name in this record + + ! remove leading blanks + inrec2 = adjustl(inrec) + + ! check for leading '&' + if (inrec2(1:1) == '&') then + + ! check for case insensitive group name + if (trim(lc_group) == shr_string_toLower(inrec2(2:len_grp+1))) then + + ! found group name. backspace to leave file position at this record + backspace(unit) + status = 0 + return + + end if + end if + end if + + end do + + 100 continue ! end of file processing + status = -1 + +end subroutine shr_nl_find_group_name + +end module shr_nl_mod From 9de323ec521f9fbbb82c7ff07af530843cf7adf0 Mon Sep 17 00:00:00 2001 From: Alper Altuntas Date: Tue, 24 Oct 2023 16:07:12 -0600 Subject: [PATCH 036/170] fix minor typo in drof modifier mode --- drof/cime_config/config_component.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drof/cime_config/config_component.xml b/drof/cime_config/config_component.xml index 8400ada9d..c87e1f1c6 100644 --- a/drof/cime_config/config_component.xml +++ b/drof/cime_config/config_component.xml @@ -13,7 +13,7 @@ --> - Data runoff model + Data runoff model NULL mode COREv2 normal year forcing: COREv2 interannual year forcing: From 9945da533e6c99d9b20a7b1f558113d0318d1ff6 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 27 Oct 2023 13:27:30 -0600 Subject: [PATCH 037/170] allow path changes and symlinks in stream filenames --- share/CMakeLists.txt | 1 + share/shr_file_mod.F90 | 1048 +++++++++++++++++++++++++++++++++++ streams/dshr_stream_mod.F90 | 29 +- 3 files changed, 1071 insertions(+), 7 deletions(-) create mode 100644 share/shr_file_mod.F90 diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index fa5f4844e..6d1c3607d 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(cdeps_share ${GenF90_SRCS} shr_timer_mod.F90 shr_cal_mod.F90 shr_kind_mod.F90 + shr_file_mod.F90 shr_sys_mod.F90 shr_abort_mod.F90 shr_const_mod.F90 diff --git a/share/shr_file_mod.F90 b/share/shr_file_mod.F90 new file mode 100644 index 000000000..c76bfca58 --- /dev/null +++ b/share/shr_file_mod.F90 @@ -0,0 +1,1048 @@ +! !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 :: shr_file_get_real_path ! Get a fully resolved path +#if defined NEMO_IN_CCSM + public :: shr_file_maxUnit ! Max unit number to give +#endif + + ! !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 + prefix = shr_file_queryPrefix( rem_fn ) + + 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)) + 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) + 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)) + cmd = '/bin/cp -f '//trim(rfn)//' '//trim(loc_fn) + if (async2) cmd = trim(cmd)//' & ' + call shr_sys_system(trim(cmd),rcode) + 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: + !------------------------------------------------------------------------------- + shr_file_getUnit = -1 + 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) ',3a,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) ',3a,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)," nonexistent" + 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 + ! Depricated - use shr_log_setLogUnit + ! !INTERFACE: ------------------------------------------------------------------ + + SUBROUTINE shr_file_setLogUnit(unit) + use shr_log_mod, only: shr_log_setLogUnit + 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 DEBUG + if (s_loglev > 2 .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 + if(unit /= 6) print *,__FILE__,__LINE__,'This routine is depricated - use shr_log_setLogUnit instead', unit +#endif + call shr_log_setLogUnit(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 + + !=============================================================================== + subroutine shr_file_get_real_path(path, resolved_path) + use, intrinsic :: iso_c_binding + character(len=*), intent(in) :: path + character(len=*), intent(out) :: resolved_path + + ! Define + integer :: n + character(len=1) :: a(SHR_KIND_CL) + type(c_ptr) :: ptr + + ! Fortran interface to C function, realpath() + interface + function realpath(path,resolved_path) bind(c,name="realpath") + use, intrinsic :: iso_c_binding + type(c_ptr) :: realpath + character(len=1,kind=c_char), intent(in) :: path(*) + character(len=1,kind=c_char), intent(out) :: resolved_path(*) + end function realpath + end interface + + ! Initialize + a="" + + ptr=realpath(trim(path)//C_NULL_CHAR,a) + + ! Transfer character array to character string + resolved_path = transfer(a,resolved_path) + + ! Determine the first null char + do n=1,SHR_KIND_CL + if(iachar(resolved_path(n:n)).eq.0) exit + end do + resolved_path=resolved_path(:n-1) + end subroutine shr_file_get_real_path + + + !=============================================================================== + +END MODULE shr_file_mod diff --git a/streams/dshr_stream_mod.F90 b/streams/dshr_stream_mod.F90 index da206732a..6228bdc07 100644 --- a/streams/dshr_stream_mod.F90 +++ b/streams/dshr_stream_mod.F90 @@ -1711,7 +1711,7 @@ end subroutine shr_stream_getNFiles !=============================================================================== subroutine shr_stream_restIO(pioid, streams, mode) - + use shr_file_mod, only : shr_file_get_real_path use pio, only : pio_def_dim, pio_def_var, pio_put_var, pio_get_var, file_desc_t, var_desc_t use pio, only : pio_int, pio_char @@ -1727,7 +1727,9 @@ subroutine shr_stream_restIO(pioid, streams, mode) integer :: n, k, maxnfiles=0 integer :: maxnt = 0 integer, allocatable :: tmp(:) - character(len=CL) :: fname + integer :: logunit + character(len=CL) :: fname, rfname, rsfname + !------------------------------------------------------------------------------- if (mode .eq. 'define') then @@ -1735,6 +1737,7 @@ subroutine shr_stream_restIO(pioid, streams, mode) rcode = pio_def_dim(pioid, 'strlen', CL, dimid_str) do k=1,size(streams) ! maxnfiles is the maximum number of files across all streams + logunit = streams(k)%logunit if (streams(k)%nfiles > maxnfiles) then maxnfiles = streams(k)%nfiles endif @@ -1923,16 +1926,28 @@ subroutine shr_stream_restIO(pioid, streams, mode) rcode = pio_inq_varid(pioid, 'timeofday', tvarid) rcode = pio_inq_varid(pioid, 'haveData' , hdvarid) do k=1,size(streams) + logunit = streams(k)%logunit do n=1,streams(k)%nfiles ! read in filename rcode = pio_get_var(pioid, varid, (/1,n,k/), fname) - if (trim(fname) /= trim(streams(k)%file(n)%name)) then - write(6,'(a)')' fname = '//trim(fname) - write(6,'(a,i8,2x,i8,2x,a)')' k,n,streams(k)%file(n)%name = ',k,n,trim(streams(k)%file(n)%name) - call shr_sys_abort('ERROR reading in filename') + + if(trim(fname) /= trim(streams(k)%file(n)%name)) then + write(logunit,*) 'Filename does not match restart record, checking realpath' + call shr_file_get_real_path(fname, rfname) + call shr_file_get_real_path(trim(streams(k)%file(n)%name), rsfname) + if (trim(rfname) /= trim(rsfname)) then + write(logunit,*) 'Filename path does not match restartfile, checking filename' + rfname = fname(index(fname,'/',.true.):) + rsfname = streams(k)%file(n)%name(index(streams(k)%file(n)%name, '/',.true.):) + if (trim(rfname) /= trim(rsfname)) then + write(logunit,*) trim(rfname), '<>', trim(rsfname) + write(logunit,'(a)')' fname = '//trim(fname) + write(logunit,'(a,i8,2x,i8,2x,a)')' k,n,streams(k)%file(n)%name = ',k,n,trim(streams(k)%file(n)%name) + call shr_sys_abort('ERROR reading in filename') + endif + endif endif - ! read in nt allocate(tmp(1)) rcode = pio_get_var(pioid, ntvarid, (/n,k/), tmp(1)) From ee00179b7515f374bf9c59a0205a98bcc88b55f8 Mon Sep 17 00:00:00 2001 From: James Edwards Date: Tue, 12 Dec 2023 17:37:51 -0700 Subject: [PATCH 038/170] update default SSTICE_DATA_FILENAME to match that previously used in cam --- docn/cime_config/config_component.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docn/cime_config/config_component.xml b/docn/cime_config/config_component.xml index 0e03abf26..3a98b7878 100644 --- a/docn/cime_config/config_component.xml +++ b/docn/cime_config/config_component.xml @@ -148,7 +148,7 @@ char - $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_1x1_clim_c101029.nc + $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_1x1_2000climo_c180511.nc $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_48x96_clim_c050526.nc $DIN_LOC_ROOT/atm/cam/sst/sst_HadOIBl_bc_1.9x2.5_clim_c061031.nc From 416b566409bc765560db4f3db4dd61610111b8c9 Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Thu, 9 Nov 2023 12:03:04 -0600 Subject: [PATCH 039/170] enabling setting source and destination mask for interpolation --- streams/dshr_strdata_mod.F90 | 56 ++++++++++++++++++++++-------------- streams/dshr_stream_mod.F90 | 21 ++++++++++++-- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index ce39cc7c4..c056639d3 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -240,7 +240,8 @@ subroutine shr_strdata_init_from_inline(sdat, my_task, logunit, compname, & stream_meshfile, stream_lev_dimname, stream_mapalgo, & stream_filenames, stream_fldlistFile, stream_fldListModel, & stream_yearFirst, stream_yearLast, stream_yearAlign, & - stream_offset, stream_taxmode, stream_dtlimit, stream_tintalgo, stream_name, rc) + stream_offset, stream_taxmode, stream_dtlimit, stream_tintalgo, & + stream_src_mask, stream_dst_mask, stream_name, rc) ! input/output variables type(shr_strdata_type) , intent(inout) :: sdat ! stream data type @@ -262,8 +263,14 @@ subroutine shr_strdata_init_from_inline(sdat, my_task, logunit, compname, & character(*) , intent(in) :: stream_taxMode ! time axis mode real(r8) , intent(in) :: stream_dtlimit ! ratio of max/min stream delta times character(*) , intent(in) :: stream_tintalgo ! time interpolation algorithm + integer, optional , intent(in) :: stream_src_mask ! source mask value + integer, optional , intent(in) :: stream_dst_mask ! destination mask value character(*), optional , intent(in) :: stream_name ! name of stream - integer , intent(out) :: rc ! error code + integer, optional , intent(out) :: rc ! error code + + ! local variables + integer :: src_mask = 0 + integer :: dst_mask = 0 ! ---------------------------------------------- rc = ESMF_SUCCESS @@ -277,6 +284,10 @@ subroutine shr_strdata_init_from_inline(sdat, my_task, logunit, compname, & sdat%io_format = shr_pio_getioformat(trim(compname)) #endif + ! Check source and destination mask, defaults are 0 + if (present(stream_src_mask)) src_mask = stream_src_mask + if (present(stream_dst_mask)) dst_mask = stream_dst_mask + ! Initialize sdat%pstrm - ASSUME only 1 stream allocate(sdat%pstrm(1)) @@ -292,7 +303,7 @@ subroutine shr_strdata_init_from_inline(sdat, my_task, logunit, compname, & stream_yearFirst, stream_yearLast, stream_yearAlign, & stream_offset, stream_taxmode, stream_tintalgo, stream_dtlimit, & stream_fldlistFile, stream_fldListModel, stream_fileNames, & - logunit, trim(compname)) + logunit, trim(compname), src_mask, dst_mask) ! Now finish initializing sdat call shr_strdata_init(sdat, model_clock, stream_name, rc) @@ -549,8 +560,8 @@ subroutine shr_strdata_init(sdat, model_clock, stream_name, rc) regridmethod=ESMF_REGRIDMETHOD_BILINEAR, & polemethod=ESMF_POLEMETHOD_ALLAVG, & extrapMethod=ESMF_EXTRAPMETHOD_NEAREST_STOD, & - dstMaskValues = (/0/), & ! ignore destination points where the mask is 0 - srcMaskValues = (/0/), & ! ignore source points where the mask is 0 + dstMaskValues=(/sdat%stream(ns)%dst_mask_val/), & + srcMaskValues=(/sdat%stream(ns)%src_mask_val/), & srcTermProcessing=srcTermProcessing_Value, ignoreDegenerate=.true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (trim(sdat%stream(ns)%mapalgo) == 'redist') then @@ -562,8 +573,8 @@ subroutine shr_strdata_init(sdat, model_clock, stream_name, rc) call ESMF_FieldReGridStore(sdat%pstrm(ns)%field_stream, lfield_dst, & routehandle=sdat%pstrm(ns)%routehandle, & regridmethod=ESMF_REGRIDMETHOD_NEAREST_STOD, & - dstMaskValues = (/0/), & ! ignore destination points where the mask is 0 - srcMaskValues = (/0/), & ! ignore source points where the mask is 0 + dstMaskValues=(/sdat%stream(ns)%dst_mask_val/), & + srcMaskValues=(/sdat%stream(ns)%src_mask_val/), & srcTermProcessing=srcTermProcessing_Value, ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) else if (trim(sdat%stream(ns)%mapalgo) == 'consf') then @@ -571,8 +582,8 @@ subroutine shr_strdata_init(sdat, model_clock, stream_name, rc) routehandle=sdat%pstrm(ns)%routehandle, & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & normType=ESMF_NORMTYPE_FRACAREA, & - dstMaskValues = (/0/), & ! ignore destination points where the mask is 0 - srcMaskValues = (/0/), & ! ignore source points where the mask is 0 + dstMaskValues=(/sdat%stream(ns)%dst_mask_val/), & + srcMaskValues=(/sdat%stream(ns)%src_mask_val/), & srcTermProcessing=srcTermProcessing_Value, ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) else if (trim(sdat%stream(ns)%mapalgo) == 'consd') then @@ -580,8 +591,8 @@ subroutine shr_strdata_init(sdat, model_clock, stream_name, rc) routehandle=sdat%pstrm(ns)%routehandle, & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & normType=ESMF_NORMTYPE_DSTAREA, & - dstMaskValues = (/0/), & ! ignore destination points where the mask is 0 - srcMaskValues = (/0/), & ! ignore source points where the mask is 0 + dstMaskValues=(/sdat%stream(ns)%dst_mask_val/), & + srcMaskValues=(/sdat%stream(ns)%src_mask_val/), & srcTermProcessing=srcTermProcessing_Value, ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) else if (trim(sdat%stream(ns)%mapalgo) == 'none') then @@ -1235,9 +1246,10 @@ subroutine shr_strdata_print(sdat, name) character(*),parameter :: F00 = "('(shr_strdata_print) ',8a)" character(*),parameter :: F01 = "('(shr_strdata_print) ',a,i6,a)" character(*),parameter :: F02 = "('(shr_strdata_print) ',a,es13.6)" - character(*),parameter :: F04 = "('(shr_strdata_print) ',a,i2,a,a)" - character(*),parameter :: F05 = "('(shr_strdata_print) ',a)" - character(*),parameter :: F07 = "('(shr_strdata_print) ',a,i2,a,es13.6)" + character(*),parameter :: F03 = "('(shr_strdata_print) ',a,i2,a,a)" + character(*),parameter :: F04 = "('(shr_strdata_print) ',a)" + character(*),parameter :: F05 = "('(shr_strdata_print) ',a,i2,a,es13.6)" + character(*),parameter :: F06 = "('(shr_strdata_print) ',a,i2,a,i1)" character(*),parameter :: F90 = "('(shr_strdata_print) ',58('-'))" !------------------------------------------------------------------------------- @@ -1251,14 +1263,16 @@ subroutine shr_strdata_print(sdat, name) write(sdat%stream(1)%logunit,F02) "obliqr = ",sdat%obliqr write(sdat%stream(1)%logunit,F01) "pio_iotype = ",sdat%io_type write(sdat%stream(1)%logunit,F01) "nstreams = ",shr_strdata_get_stream_count(sdat) - write(sdat%stream(1)%logunit,F05) "Per stream information " + write(sdat%stream(1)%logunit,F04) "Per stream information " do ns = 1, shr_strdata_get_stream_count(sdat) - write(sdat%stream(1)%logunit,F04) " taxMode (",ns,") = ",trim(sdat%stream(ns)%taxmode) - write(sdat%stream(1)%logunit,F07) " dtlimit (",ns,") = ",sdat%stream(ns)%dtlimit - write(sdat%stream(1)%logunit,F04) " mapalgo (",ns,") = ",trim(sdat%stream(ns)%mapalgo) - write(sdat%stream(1)%logunit,F04) " tintalgo(",ns,") = ",trim(sdat%stream(ns)%tinterpalgo) - write(sdat%stream(1)%logunit,F04) " readmode(",ns,") = ",trim(sdat%stream(ns)%readmode) - write(sdat%stream(1)%logunit,F04) " vectors (",ns,") = ",trim(sdat%stream(ns)%stream_vectors) + write(sdat%stream(1)%logunit,F03) " taxMode (",ns,") = ",trim(sdat%stream(ns)%taxmode) + write(sdat%stream(1)%logunit,F05) " dtlimit (",ns,") = ",sdat%stream(ns)%dtlimit + write(sdat%stream(1)%logunit,F03) " mapalgo (",ns,") = ",trim(sdat%stream(ns)%mapalgo) + write(sdat%stream(1)%logunit,F03) " tintalgo(",ns,") = ",trim(sdat%stream(ns)%tinterpalgo) + write(sdat%stream(1)%logunit,F03) " readmode(",ns,") = ",trim(sdat%stream(ns)%readmode) + write(sdat%stream(1)%logunit,F03) " vectors (",ns,") = ",trim(sdat%stream(ns)%stream_vectors) + write(sdat%stream(1)%logunit,F06) " src_mask(",ns,") = ",sdat%stream(ns)%src_mask_val + write(sdat%stream(1)%logunit,F06) " dst_mask(",ns,") = ",sdat%stream(ns)%dst_mask_val write(sdat%stream(1)%logunit,F01) " " end do write(sdat%stream(1)%logunit,F90) diff --git a/streams/dshr_stream_mod.F90 b/streams/dshr_stream_mod.F90 index 6228bdc07..ac16d18d6 100644 --- a/streams/dshr_stream_mod.F90 +++ b/streams/dshr_stream_mod.F90 @@ -131,6 +131,8 @@ module dshr_stream_mod type(file_desc_t) :: currpioid ! current pio file desc type(shr_stream_file_type) , allocatable :: file(:) ! filenames of stream data files (full pathname) type(shr_stream_data_variable), allocatable :: varlist(:) ! stream variable names (on file and in model) + integer :: src_mask_val = 0 ! mask value for src mesh + integer :: dst_mask_val = 0 ! mask value for dst mesh end type shr_stream_streamType !----- parameters ----- @@ -445,7 +447,7 @@ subroutine shr_stream_init_from_inline(streamdat, & stream_yearFirst, stream_yearLast, stream_yearAlign, & stream_offset, stream_taxmode, stream_tintalgo, stream_dtlimit, & stream_fldlistFile, stream_fldListModel, stream_fileNames, & - logunit, compname) + logunit, compname, stream_src_mask_val, stream_dst_mask_val) ! -------------------------------------------------------- ! set values of stream datatype independent of a reading in a stream text file @@ -472,6 +474,8 @@ subroutine shr_stream_init_from_inline(streamdat, & character(*) ,intent(in) :: stream_filenames(:) ! stream data filenames (full pathnamesa) integer ,intent(in) :: logunit ! stdout unit character(len=*) ,intent(in) :: compname ! component name (e.g. ATM, OCN...) + integer ,optional, intent(in) :: stream_src_mask_val ! source mask value + integer ,optional, intent(in) :: stream_dst_mask_val ! destination mask value ! local variables integer :: n @@ -534,10 +538,15 @@ subroutine shr_stream_init_from_inline(streamdat, & ! Initialize logunit streamdat(:)%logunit = logunit + ! Get stream calendar call shr_stream_getCalendar(streamdat(1), 1, calendar) streamdat(1)%calendar = trim(calendar) + ! Set source and destination mask + if (present(stream_src_mask_val)) streamdat(1)%src_mask_val = stream_src_mask_val + if (present(stream_dst_mask_val)) streamdat(1)%dst_mask_val = stream_dst_mask_val + ! Initialize flag that stream has been set streamdat(1)%init = .true. @@ -571,6 +580,8 @@ subroutine shr_stream_init_from_esmfconfig(streamfilename, streamdat, logunit, !! stream_data_files: !! stream_data_variables: !! stream_offset: + !! stream_src_mask: + !! stream_dst_mask: !!--------------------------------------------------------------------- ! input/output variables @@ -606,7 +617,6 @@ subroutine shr_stream_init_from_esmfconfig(streamfilename, streamdat, logunit, call ESMF_ConfigLoadFile(config=CF ,filename=trim(streamfilename), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! get number of streams nstrms = ESMF_ConfigGetLen(config=CF, label='stream_info:', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -720,6 +730,13 @@ subroutine shr_stream_init_from_esmfconfig(streamfilename, streamdat, logunit, call shr_stream_getCalendar(streamdat(i), 1, streamdat(i)%calendar) + ! Get source and destination mask, 0 by default + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%src_mask_val,label="stream_src_mask"//mystrm//':', default=0, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%dst_mask_val,label="stream_dst_mask"//mystrm//':', default=0, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Error check if (trim(streamdat(i)%taxmode) == shr_stream_taxis_extend .and. streamdat(i)%dtlimit < 1.e10) then call shr_sys_abort(trim(subName)//" ERROR: if taxmode value is extend set dtlimit to 1.e30") From 8c435897cebfa62400091cc21ec68c02cf3da96f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 10 Jan 2024 14:12:04 +0100 Subject: [PATCH 040/170] new passing of 10m wind explicitly to ww3 - done in a backwards compatible way --- datm/datm_datamode_core2_mod.F90 | 12 ++++++++++++ datm/datm_datamode_jra_mod.F90 | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/datm/datm_datamode_core2_mod.F90 b/datm/datm_datamode_core2_mod.F90 index 552b35dae..41d2caae8 100644 --- a/datm/datm_datamode_core2_mod.F90 +++ b/datm/datm_datamode_core2_mod.F90 @@ -40,6 +40,8 @@ module datm_datamode_core2_mod ! export state pointers real(r8), pointer :: Sa_u(:) => null() real(r8), pointer :: Sa_v(:) => null() + real(r8), pointer :: Sa_u10m(:) => null() + real(r8), pointer :: Sa_v10m(:) => null() real(r8), pointer :: Sa_z(:) => null() real(r8), pointer :: Sa_tbot(:) => null() real(r8), pointer :: Sa_ptem(:) => null() @@ -115,6 +117,8 @@ subroutine datm_datamode_core2_advertise(exportState, fldsexport, flds_scalar_na call dshr_fldList_add(fldsExport, 'Sa_z' ) call dshr_fldList_add(fldsExport, 'Sa_u' ) call dshr_fldList_add(fldsExport, 'Sa_v' ) + call dshr_fldList_add(fldsExport, 'Sa_u10m' ) + call dshr_fldList_add(fldsExport, 'Sa_v10m' ) call dshr_fldList_add(fldsExport, 'Sa_ptem' ) call dshr_fldList_add(fldsExport, 'Sa_dens' ) call dshr_fldList_add(fldsExport, 'Sa_pslv' ) @@ -219,6 +223,10 @@ subroutine datm_datamode_core2_init_pointers(exportState, sdat, datamode, factor if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Sa_v' , fldptr1=Sa_v , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_u10m' , fldptr1=Sa_u10m , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_v10m' , fldptr1=Sa_v10m , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Sa_tbot' , fldptr1=Sa_tbot , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Sa_pbot' , fldptr1=Sa_pbot , rc=rc) @@ -315,6 +323,10 @@ subroutine datm_datamode_core2_advance(datamode, target_ymd, target_tod, target_ Sa_u(n) = uprime*cos(winddFactor(n)*degtorad) - vprime*sin(winddFactor(n)*degtorad) Sa_v(n) = uprime*sin(winddFactor(n)*degtorad) + vprime*cos(winddFactor(n)*degtorad) + ! Set Sa_u10m and Sa_v10m to Sa_u and Sa_v + Sa_u10m(n) = Sa_u(n) + Sa_v10m(n) = Sa_v(n) + !--- density and pslv taken directly from input stream, set pbot --- Sa_pbot(n) = Sa_pslv(n) diff --git a/datm/datm_datamode_jra_mod.F90 b/datm/datm_datamode_jra_mod.F90 index d280bf860..9eb815150 100644 --- a/datm/datm_datamode_jra_mod.F90 +++ b/datm/datm_datamode_jra_mod.F90 @@ -25,6 +25,10 @@ module datm_datamode_jra_mod ! export state pointers real(r8), pointer :: Sa_z(:) => null() + real(r8), pointer :: Sa_u(:) => null() + real(r8), pointer :: Sa_v(:) => null() + real(r8), pointer :: Sa_u10m(:) => null() + real(r8), pointer :: Sa_v10m(:) => null() real(r8), pointer :: Sa_tbot(:) => null() real(r8), pointer :: Sa_ptem(:) => null() real(r8), pointer :: Sa_shum(:) => null() @@ -88,6 +92,8 @@ subroutine datm_datamode_jra_advertise(exportState, fldsexport, flds_scalar_name call dshr_fldList_add(fldsExport, 'Sa_z' ) call dshr_fldList_add(fldsExport, 'Sa_u' ) call dshr_fldList_add(fldsExport, 'Sa_v' ) + call dshr_fldList_add(fldsExport, 'Sa_u10m' ) + call dshr_fldList_add(fldsExport, 'Sa_v10m' ) call dshr_fldList_add(fldsExport, 'Sa_ptem' ) call dshr_fldList_add(fldsExport, 'Sa_dens' ) call dshr_fldList_add(fldsExport, 'Sa_pslv' ) @@ -174,6 +180,14 @@ subroutine datm_datamode_jra_init_pointers(exportState, sdat, rc) call shr_strdata_get_stream_pointer( sdat, 'Faxa_swdn' , strm_swdn , rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_u' , fldptr1=Sa_u , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_v' , fldptr1=Sa_v , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_u10m' , fldptr1=Sa_u10m , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_v10m' , fldptr1=Sa_v10m , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Sa_z' , fldptr1=Sa_z , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Sa_tbot' , fldptr1=Sa_tbot , rc=rc) @@ -253,6 +267,10 @@ subroutine datm_datamode_jra_advance(exportstate, target_ymd, target_tod, model_ Sa_pbot(n) = Sa_pslv(n) Sa_ptem(n) = Sa_tbot(n) + ! Set Sa_u10m and Sa_v10m to Sa_u and Sa_v + Sa_u10m(n) = Sa_u(n) + Sa_v10m(n) = Sa_v(n) + ! density computation for JRA55 forcing Sa_dens(n) = Sa_pbot(n)/(rdair*Sa_tbot(n)*(1 + 0.608*Sa_shum(n))) From cda4168966eb7e482413cfcf7cfe0a905d30a76e Mon Sep 17 00:00:00 2001 From: Teagan King Date: Fri, 8 Mar 2024 13:57:33 -0700 Subject: [PATCH 041/170] preliminary cdeps updatesls --- cime_config/stream_cdeps.py | 7 ++++ datm/cime_config/buildnml | 2 ++ datm/cime_config/stream_definition_datm.xml | 37 +++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index 1f702a13c..bf3e6e788 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -187,6 +187,12 @@ def create_stream_xml( {"name": "NEON.NEON_PRECIP.$NEONSITE"}, err_msg="No stream_entry {} found".format(stream_name), ) + elif stream_name.startswith("PLUMBER"): + self.stream_nodes = super(StreamCDEPS, self).get_child( + "stream_entry", + {"name": "PLUMBER.$PLUMBER2SITE"}, + err_msg="No stream_entry {} found".format(stream_name), + ) elif stream_name.startswith("CLM_USRDAT."): self.stream_nodes = super(StreamCDEPS, self).get_child( "stream_entry", @@ -239,6 +245,7 @@ def create_stream_xml( and ("PRISM" not in stream_name) ): rundir = case.get_value("RUNDIR") + #TODO: may need to add a similar PLUMBER line for neon in available_neon_data: stream_datafiles += ( os.path.join(rundir, "inputdata", "atm", neon) diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml index afee50344..1fd77c642 100755 --- a/datm/cime_config/buildnml +++ b/datm/cime_config/buildnml @@ -194,6 +194,8 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path streamlist.append(clm_usrdat_name+"_PRECIP."+neonsite) if clm_usrdat_name == 'NEON': streamlist.append(clm_usrdat_name+".NEON_PRECIP."+neonsite) + if clm_usrdat_name == 'PLUMBER': + streamlist.append(clm_usrdat_name+plumber2site) bias_correct = nmlgen.get_value("bias_correct") if bias_correct is not None: diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 310c5097e..4936eb0a0 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -341,6 +341,43 @@ single + + + + + + + + none + + + $DIN_LOC_ROOT/atm/cdeps/PLUMBER2/${NEONSITE}_%y.nc + + + PRECIP Faxa_precn # this will probably need updating + + null + + none + + null + $DATM_YR_ALIGN + $DATM_YR_START + $DATM_YR_END + 0 + + linear + + + cycle + limit + + + 1.5 + + single + + From b7840047af885357ab219d2ac1f6fe7d0cf574e7 Mon Sep 17 00:00:00 2001 From: Teagan King Date: Fri, 8 Mar 2024 13:58:23 -0700 Subject: [PATCH 042/170] namelist def datm update --- datm/cime_config/namelist_definition_datm.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index 491b6f6d1..4fa625935 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -40,6 +40,9 @@ NEON.$NEONSITE + + PLUMBER.$PLUMBER2SITE + CLM_USRDAT.$CLM_USRDAT_NAME From 56a3eb54870e7d5812336811b2537a016ed4d36a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 18 Mar 2024 10:44:25 +0100 Subject: [PATCH 043/170] first draft implementation of multiple ice sheets in the dglc code - namelist still needs to be implemented --- datm/atm_comp_nuopc.F90 | 2 +- dice/ice_comp_nuopc.F90 | 2 +- dlnd/lnd_comp_nuopc.F90 | 4 ++-- docn/ocn_comp_nuopc.F90 | 2 +- drof/rof_comp_nuopc.F90 | 4 ++-- dshr/dshr_mod.F90 | 5 ++--- dwav/wav_comp_nuopc.F90 | 2 +- 7 files changed, 10 insertions(+), 11 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index dbd441085..233e4c2b5 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -264,7 +264,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Obtain flds_scalar values, mpi values, multi-instance values and ! set logunit and set shr logging to my log file - call dshr_init(gcomp, 'ATM', sdat, mpicom, my_task, inst_index, inst_suffix, & + call dshr_init(gcomp, 'ATM', mpicom, my_task, inst_index, inst_suffix, & flds_scalar_name, flds_scalar_num, flds_scalar_index_nx, flds_scalar_index_ny, & logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index fd552bbcb..63539e812 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -195,7 +195,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Obtain flds_scalar values, mpi values, multi-instance values and ! set logunit and set shr logging to my log file - call dshr_init(gcomp, 'ICE', sdat, mpicom, my_task, inst_index, inst_suffix, & + call dshr_init(gcomp, 'ICE', mpicom, my_task, inst_index, inst_suffix, & flds_scalar_name, flds_scalar_num, flds_scalar_index_nx, flds_scalar_index_ny, & logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/dlnd/lnd_comp_nuopc.F90 b/dlnd/lnd_comp_nuopc.F90 index ff84bae05..56a360c83 100644 --- a/dlnd/lnd_comp_nuopc.F90 +++ b/dlnd/lnd_comp_nuopc.F90 @@ -25,7 +25,7 @@ module cdeps_dlnd_comp use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort use shr_cal_mod , only : shr_cal_ymd2date - use shr_log_mod , only : shr_log_setLogUnit + use shr_log_mod , only : shr_log_setLogUnit use dshr_methods_mod , only : dshr_state_getfldptr, dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_get_stream_domain use dshr_strdata_mod , only : shr_strdata_init_from_config @@ -187,7 +187,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Obtain flds_scalar values, mpi values, multi-instance values and ! set logunit and set shr logging to my log file - call dshr_init(gcomp, 'LND', sdat, mpicom, my_task, inst_index, inst_suffix, & + call dshr_init(gcomp, 'LND', mpicom, my_task, inst_index, inst_suffix, & flds_scalar_name, flds_scalar_num, flds_scalar_index_nx, flds_scalar_index_ny, & logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index 462989995..4bdeb81f6 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -212,7 +212,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Obtain flds_scalar values, mpi values, multi-instance values and ! set logunit and set shr logging to my log file - call dshr_init(gcomp, 'OCN', sdat, mpicom, my_task, inst_index, inst_suffix, & + call dshr_init(gcomp, 'OCN', mpicom, my_task, inst_index, inst_suffix, & flds_scalar_name, flds_scalar_num, flds_scalar_index_nx, flds_scalar_index_ny, logunit, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/drof/rof_comp_nuopc.F90 b/drof/rof_comp_nuopc.F90 index c3602cd97..959421a70 100644 --- a/drof/rof_comp_nuopc.F90 +++ b/drof/rof_comp_nuopc.F90 @@ -27,7 +27,7 @@ module cdeps_drof_comp use shr_const_mod , only : SHR_CONST_SPVAL use shr_sys_mod , only : shr_sys_abort use shr_cal_mod , only : shr_cal_ymd2date - use shr_log_mod , only : shr_log_setLogUnit + use shr_log_mod , only : shr_log_setLogUnit use dshr_methods_mod , only : dshr_state_getfldptr, dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_get_stream_domain use dshr_strdata_mod , only : shr_strdata_init_from_config @@ -183,7 +183,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Obtain flds_scalar values, mpi values, multi-instance values and ! set logunit and set shr logging to my log file - call dshr_init(gcomp, 'ROF', sdat, mpicom, my_task, inst_index, inst_suffix, & + call dshr_init(gcomp, 'ROF', mpicom, my_task, inst_index, inst_suffix, & flds_scalar_name, flds_scalar_num, flds_scalar_index_nx, flds_scalar_index_ny, & logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index f253adc05..977b9d439 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -111,14 +111,13 @@ subroutine dshr_model_initphase(gcomp, importState, exportState, clock, rc) end subroutine dshr_model_initphase !=============================================================================== - subroutine dshr_init(gcomp, compname, sdat, mpicom, my_task, inst_index, inst_suffix, & + subroutine dshr_init(gcomp, compname, mpicom, my_task, inst_index, inst_suffix, & flds_scalar_name, flds_scalar_num, flds_scalar_index_nx, flds_scalar_index_ny, logunit, rc) #ifdef CESMCOUPLED use nuopc_shr_methods, only : set_component_logging #endif ! input/output variables type(ESMF_GridComp) :: gcomp - type(shr_strdata_type), intent(in) :: sdat ! No longer used character(len=*) , intent(in) :: compname !e.g. ATM, OCN, ... integer , intent(inout) :: mpicom integer , intent(out) :: my_task @@ -246,7 +245,7 @@ subroutine dshr_mesh_init(gcomp, sdat, nullstr, logunit, compname, model_nxg, mo ! input/output variables type(ESMF_GridComp) , intent(inout) :: gcomp - type(shr_strdata_type) , intent(inout) :: sdat + type(shr_strdata_type) , intent(inout) :: sdat integer , intent(in) :: logunit character(len=*) , intent(in) :: compname !e.g. ATM, OCN, ... character(len=*) , intent(in) :: nullstr diff --git a/dwav/wav_comp_nuopc.F90 b/dwav/wav_comp_nuopc.F90 index e200e00b6..13728738a 100644 --- a/dwav/wav_comp_nuopc.F90 +++ b/dwav/wav_comp_nuopc.F90 @@ -181,7 +181,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Obtain flds_scalar values, mpi values, multi-instance values and ! set logunit and set shr logging to my log file - call dshr_init(gcomp, 'WAV', sdat, mpicom, my_task, inst_index, inst_suffix, & + call dshr_init(gcomp, 'WAV', mpicom, my_task, inst_index, inst_suffix, & flds_scalar_name, flds_scalar_num, flds_scalar_index_nx, flds_scalar_index_ny, & logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return From e1f092749b7ff45ee120298250cb1ffd1e415628 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 19 Mar 2024 11:13:50 +0100 Subject: [PATCH 044/170] additional changes for noevolve mode --- dglc/CMakeLists.txt | 34 + dglc/cime_config/buildlib | 54 ++ dglc/cime_config/buildnml | 198 ++++++ dglc/cime_config/config_archive.xml | 11 + dglc/cime_config/config_component.xml | 59 ++ dglc/cime_config/namelist_definition_dglc.xml | 109 ++++ dglc/cime_config/stream_definition_dglc.xml | 16 + dglc/cime_config/user_nl_dglc | 13 + dglc/cime_config/user_nl_dglc_streams | 33 + dglc/dglc_datamode_noevolve_mod.F90 | 279 ++++++++ dglc/glc_comp_nuopc.F90 | 617 ++++++++++++++++++ 11 files changed, 1423 insertions(+) create mode 100644 dglc/CMakeLists.txt create mode 100755 dglc/cime_config/buildlib create mode 100755 dglc/cime_config/buildnml create mode 100644 dglc/cime_config/config_archive.xml create mode 100644 dglc/cime_config/config_component.xml create mode 100644 dglc/cime_config/namelist_definition_dglc.xml create mode 100644 dglc/cime_config/stream_definition_dglc.xml create mode 100644 dglc/cime_config/user_nl_dglc create mode 100644 dglc/cime_config/user_nl_dglc_streams create mode 100644 dglc/dglc_datamode_noevolve_mod.F90 create mode 100644 dglc/glc_comp_nuopc.F90 diff --git a/dglc/CMakeLists.txt b/dglc/CMakeLists.txt new file mode 100644 index 000000000..2c62d04b0 --- /dev/null +++ b/dglc/CMakeLists.txt @@ -0,0 +1,34 @@ +project(dglc Fortran) +set(SRCFILES glc_comp_nuopc.F90 + dglc_datamode_noevolve_mod.F90) + +foreach(FILE ${SRCFILES}) + if(EXISTS "${CASEROOT}/SourceMods/src.dglc/${FILE}") + list(REMOVE_ITEM SRCFILES ${FILE}) + list(APPEND SRCFILES "${CASEROOT}/SourceMods/src.dglc/${FILE}") + message("Using ${FILE} from ${CASEROOT}/SourceMods/src.dglc") + endif() +endforeach() + +message("DGLC srcfiles are ${SRCFILES}") + +add_library(dglc ${SRCFILES}) + +add_dependencies(dglc dshr streams) +target_include_directories (dglc PRIVATE ${ESMF_F90COMPILEPATHS}) +target_include_directories (dglc PRIVATE ${CMAKE_SOURCE_DIR}) +target_include_directories (dglc PRIVATE ${PIO_Fortran_INCLUDE_DIR}) +if(NOT DISABLE_FoX) + target_include_directories (dglc PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../fox/include) +endif() + +if(BLD_STANDALONE) + # ESMX requires mod files + foreach (SRC ${SRCFILES}) + string(REGEX REPLACE "[.]F90$" ".mod" MOD ${SRC}) + if (NOT DEFINED CIMEROOT AND MOD STREQUAL glc_comp_nuopc.mod) + set(MOD cdeps_dglc_comp.mod) + endif() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MOD}" DESTINATION include) + endforeach () +endif() diff --git a/dglc/cime_config/buildlib b/dglc/cime_config/buildlib new file mode 100755 index 000000000..281f0d4e9 --- /dev/null +++ b/dglc/cime_config/buildlib @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 + +""" +build cime component model library. This buildlib script is used by all CDEPS components. +""" + +import sys, os + +_CIMEROOT = os.environ.get("CIMEROOT") +if _CIMEROOT is None: + raise SystemExit("ERROR: must set CIMEROOT environment variable") +sys.path.append(os.path.join(_CIMEROOT, "CIME", "Tools")) + +_LIBDIR = os.path.join(_CIMEROOT, "CIME") +sys.path.append(_LIBDIR) + +from standard_script_setup import * +from CIME.buildlib import parse_input +from CIME.case import Case +from CIME.utils import run_cmd, symlink_force, expect + +# pragma pylint: disable=unused-argument,undefined-variable + +logger = logging.getLogger(__name__) + + +def buildlib(bldroot, libroot, case, compname=None): + if not compname: + expect( + bldroot.endswith("obj"), + "It appears that buildlib_comps is being called for the main CDEPS build\n" + "(the main CDEPS build should use buildlib, not buildlib_comps)", + ) + compname = os.path.basename(os.path.abspath(os.path.join(bldroot, os.pardir))) + + _, o, e = run_cmd("make d{}".format(compname), from_dir=bldroot, verbose=True) + libname = "lib{}.a".format(compname) + dlibname = "libd{}.a".format(compname) + dlibpath = os.path.join(bldroot, dlibname) + if os.path.exists(dlibpath): + symlink_force(os.path.join(bldroot, dlibname), os.path.join(libroot, libname)) + else: + expect(False, "ERROR in {} build {} {}".format(compname, o, e)) + logger.info(f"build successful for comp={compname}") + + +def _main_func(args): + caseroot, libroot, bldroot = parse_input(args) + with Case(caseroot) as case: + buildlib(bldroot, libroot, case) + + +if __name__ == "__main__": + _main_func(sys.argv) diff --git a/dglc/cime_config/buildnml b/dglc/cime_config/buildnml new file mode 100755 index 000000000..6994b7051 --- /dev/null +++ b/dglc/cime_config/buildnml @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 + +"""Namelist creator for CIME's data glc model. +""" + +# Typically ignore this. +# pylint: disable=invalid-name + +# Disable these because this is our standard setup +# pylint: disable=wildcard-import,unused-wildcard-import,wrong-import-position + +import os, sys + +_CDEPS_CONFIG = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir,os.pardir,"cime_config") +_CIMEROOT = os.environ.get("CIMEROOT") +if _CIMEROOT is None: + raise SystemExit("ERROR: must set CIMEROOT environment variable") +_LIBDIR = os.path.join(_CIMEROOT, "CIME", "Tools") +sys.path.append(_LIBDIR) +sys.path.append(_CDEPS_CONFIG) + +from standard_script_setup import * +from CIME.case import Case +from CIME.nmlgen import NamelistGenerator +from CIME.utils import expect, safe_copy +from CIME.XML.files import Files +from CIME.buildnml import create_namelist_infile, parse_input, copy_inputs_to_rundir +from stream_cdeps import StreamCDEPS + +logger = logging.getLogger(__name__) + +# pylint: disable=too-many-arguments,too-many-locals,too-many-branches,too-many-statements +#################################################################################### +def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path): +#################################################################################### + """Write out the namelist and stream xml files for this component. + + Most arguments are the same as those for `NamelistGenerator`. The + `inst_string` argument is used as a suffix to distinguish files for + different instances. The `confdir` argument is used to specify the directory + in which output files will be placed. + """ + #---------------------------------------------------- + # Write out dglc_in and dglc.streams.xml + #---------------------------------------------------- + caseroot = case.get_value("CASEROOT") + dglc_mode = case.get_value("DGLC_MODE") + glc_grid = case.get_value("GLC_GRID") + + # Check for incompatible options. + expect(glc_grid != "null", + "DGLC_GRID cannot be null") + + # Log some settings. + logger.debug("DGLC mode is {}".format(dglc_mode)) + + # Initialize namelist defaults + # Note: always use model mesh file to set mask for drof + config = {} + config['dglc_mode'] = dglc_mode + config['glc_grid'] = glc_grid + + # Do not allow single column mode for dglc + if case.get_value('PTS_LON'): + scol_lon = float(case.get_value('PTS_LON')) + else: + scol_lon = -999. + if case.get_value('PTS_LAT'): + scol_lat = float(case.get_value('PTS_LAT')) + else: + scol_lat = -999. + if (scol_lon > -999. and scol_lat > 999.): + expect(False, + "single column mode for DGLC is not currently allowed") + + # Initialize nmlgen + nmlgen.init_defaults(infile, config) + + # Generate dglc_in + namelist_file = os.path.join(confdir, "dglc_in") + nmlgen.write_output_file(namelist_file, data_list_path, groups=['dglc_nml']) + + # Determine streams + streamlist = nmlgen.get_streams() + if type(streamlist) == type(str()): + streamlist = [] + + # Generate dglc.streams.xml + print("dglc_mode is {}".format(dglc_mode)) + if 'NOEVOLVE' in dglc_mode: + generate_stream_file = False + else: + generate_stream_file = True + #endif + if generate_stream_file: + outfile = os.path.join(confdir, "dglc.streams"+inst_string+".xml" ) + schema_file = os.path.join(_CDEPS_CONFIG,"stream_definition_v2.0.xsd") + stream_file = os.path.join(_CDEPS_CONFIG,os.pardir, "dglc","cime_config","stream_definition_dglc.xml") + streams = StreamCDEPS(stream_file, schema_file) + streams.create_stream_xml(streamlist, case, outfile, data_list_path, + os.path.join(caseroot,'user_nl_dglc_streams'+inst_string)) + #endif + +############################################################################### +def buildnml(case, caseroot, compname): +############################################################################### + rundir = case.get_value("RUNDIR") + inst_name = compname.upper()[1:] + ninst = case.get_value("NINST_"+inst_name) + if ninst is None: + ninst = case.get_value("NINST") + confdir = os.path.join(caseroot,"Buildconf",compname + "conf") + if not os.path.isdir(confdir): + os.makedirs(confdir) + + #---------------------------------------------------- + # Construct the namelist generator + #---------------------------------------------------- + # determine directory for user modified namelist_definitions.xml + user_xml_dir = os.path.join(caseroot, "SourceMods", "src." + compname) + expect (os.path.isdir(user_xml_dir), + "user_xml_dir {} does not exist ".format(user_xml_dir)) + + # NOTE: User definition *replaces* existing definition. + files = Files(comp_interface="nuopc") + definition_file = [files.get_value("NAMELIST_DEFINITION_FILE", {"component":compname})] + + user_definition = os.path.join(user_xml_dir, "namelist_definition_"+compname+".xml") + if os.path.isfile(user_definition): + definition_file = [user_definition] + for file_ in definition_file: + expect(os.path.isfile(file_), "Namelist XML file {} not found!".format(file_)) + + # Create the namelist generator object - independent of instance + nmlgen = NamelistGenerator(case, definition_file, files=files) + + #---------------------------------------------------- + # Clear out old data. + #---------------------------------------------------- + + data_list_path = os.path.join(caseroot, "Buildconf", compname+".input_data_list") + if os.path.exists(data_list_path): + os.remove(data_list_path) + + #---------------------------------------------------- + # Loop over instances + #---------------------------------------------------- + for inst_counter in range(1, ninst+1): + # determine instance string + inst_string = "" + if ninst > 1: + inst_string = '_' + "{:04d}".format(inst_counter) + + # If multi-instance case does not have restart file, use + # single-case restart for each instance + rpointer = "rpointer." + compname + if (os.path.isfile(os.path.join(rundir,rpointer)) and + (not os.path.isfile(os.path.join(rundir,rpointer + inst_string)))): + safe_copy(os.path.join(rundir, rpointer), + os.path.join(rundir, rpointer + inst_string)) + + inst_string_label = inst_string + if not inst_string_label: + inst_string_label = "\"\"" + + # create namelist output infile using user_nl_file as input + user_nl_file = os.path.join(caseroot, "user_nl_" + compname + inst_string) + expect(os.path.isfile(user_nl_file), + "Missing required user_nl_file {} ".format(user_nl_file)) + infile = os.path.join(confdir, "namelist_infile") + create_namelist_infile(case, user_nl_file, infile) + namelist_infile = [infile] + + # create namelist and xml stream file(s) + _create_namelists(case, confdir, inst_string, namelist_infile, nmlgen, data_list_path) + + # copy namelist files and stream text files, to rundir + copy_inputs_to_rundir(caseroot, compname, confdir, rundir, inst_string) + +############################################################################### +def get_user_nl_list(case): +############################################################################### + """Returns a list of user_nl_dglc* files needed in this case + This function is called by CIME to stage the user_nl_dglc* files in the case + directory. + """ + user_nl_list = ["user_nl_dglc", "user_nl_dglc_streams"] + return user_nl_list + +############################################################################### +def _main_func(): + # Build the component namelist and required stream xml files + caseroot = parse_input(sys.argv) + with Case(caseroot) as case: + buildnml(case, caseroot, "dglc") + +if __name__ == "__main__": + _main_func() diff --git a/dglc/cime_config/config_archive.xml b/dglc/cime_config/config_archive.xml new file mode 100644 index 000000000..f61daec79 --- /dev/null +++ b/dglc/cime_config/config_archive.xml @@ -0,0 +1,11 @@ + + + r + rs1 + unset + + rpointer.glc$NINST_STRING + $CASE.dglc$NINST_STRING.r.$DATENAME.nc,$CASE.dglc$NINST_STRING.rs1.$DATENAME.bin + + + diff --git a/dglc/cime_config/config_component.xml b/dglc/cime_config/config_component.xml new file mode 100644 index 000000000..ae4a0549a --- /dev/null +++ b/dglc/cime_config/config_component.xml @@ -0,0 +1,59 @@ + + + + + + + + Data glc model (DGLC) + no evolve mode + + + + char + dglc + dglc + case_comp + env_case.xml + Name of land component + + + + char + NOEVOLVE + NOEVOLVE + + noevolve + + run_component_dglc + env_run.xml + + model mode. + TODO: fill in what noevolve mode does + + + + + logical + TRUE,FALSE + FALSE + run_component_dglc + env_run.xml + If set to true, than dglc restarts will not be read on a continuation run. + + + + + ========================================= + DGLC naming conventions + ========================================= + + + diff --git a/dglc/cime_config/namelist_definition_dglc.xml b/dglc/cime_config/namelist_definition_dglc.xml new file mode 100644 index 000000000..2fabb50a8 --- /dev/null +++ b/dglc/cime_config/namelist_definition_dglc.xml @@ -0,0 +1,109 @@ + + + + + + + + + + char(100) + streams + streams_file + List of streams used for each supported dglc_mode + + none + + + + + char + dglc + dglc_nml + noevolve + + Copies all fields directly from the input data streams Any required + fields not found on an input stream will be set to zero. + + + noevolve + + + + + char + streams + abs + dglc_nml + + $GLC_DOMAIN_MESH + + + file(s) specifying model mesh + for more than one ice sheets this will contain an array of mesh file names + + + + + integer(20) + streams + dglc_nml + + 704,416 + 704 + 416 + 76 + + + global size(s) of nx + for more than one ice sheets this will contain an array of nx values + + + + + integer(20) + streams + dglc_nml + + 576,704 + 576 + 704 + 141 + + + global size(s) of ny + for more than one ice sheets this will contain an array of ny values + + + + + char + dglc + dglc_nml + + main restart file name for dglc model + + + null + + + + + logical + dglc + dglc_nml + + If set to true, than dglc restarts will not be read on a continuation run. + This capability is used, for example, in CTSM spinup runs. + + + $DGLC_SKIP_RESTART_READ + + + + diff --git a/dglc/cime_config/stream_definition_dglc.xml b/dglc/cime_config/stream_definition_dglc.xml new file mode 100644 index 000000000..2811e8806 --- /dev/null +++ b/dglc/cime_config/stream_definition_dglc.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/dglc/cime_config/user_nl_dglc b/dglc/cime_config/user_nl_dglc new file mode 100644 index 000000000..2cbcf3997 --- /dev/null +++ b/dglc/cime_config/user_nl_dglc @@ -0,0 +1,13 @@ +!------------------------------------------------------------------------ +! Users should ONLY USE user_nl_dglc to change namelists variables +! Users should add all user specific namelist changes below in the form of +! namelist_var = new_namelist_value +! Note that any namelist variable from shr_strdata_nml and dglc_nml can +! be modified below using the above syntax +! User preview_namelists to view (not modify) the output namelist in the +! directory $CASEROOT/CaseDocs +! To modify the contents of a stream txt file, first use preview_namelists +! to obtain the contents of the stream txt files in CaseDocs, and then +! place a copy of the modified stream txt file in $CASEROOT with the string +! user_ prepended. +!------------------------------------------------------------------------ diff --git a/dglc/cime_config/user_nl_dglc_streams b/dglc/cime_config/user_nl_dglc_streams new file mode 100644 index 000000000..856ee8944 --- /dev/null +++ b/dglc/cime_config/user_nl_dglc_streams @@ -0,0 +1,33 @@ +!------------------------------------------------------------------------ +! This file is used to modify datm.streams.xml generated in $RUNDIR +! Entries should have the form +! :<= new stream_value> +! The following are accepted values for an assume streamname of foo +! foo:meshfile = character string +! foo:datafiles = comma separated string of full pathnames (e.g. file1,file2,file3...) +! foo:datavars = comma separated string of field pairs (e.g. foo foobar,foo2 foobar2...) +! foo:taxmode = one of [cycle, extend, limit] +! foo:tintalgo = one of [lower,upper,nearest,linear,coszen] +! foo:readmode = single (only suported mode right now) +! foo:mapalgo = one of [bilinear,redist,nn,consf,consd,none] +! foo:dtlimit = real (1.5 is default) +! foo:year_first = integer +! foo:year_last = integer +! foo:year_align = integer +! foo:vectors = one of [none,u:v] +! foo:lev_dimname: = one of [null,name of level dimenion name] +! foo:offset = integer +! As an example: +! foo:year_first = 1950 +! would change the stream year_first stream_entry to 1950 for the foo stream block +! NOTE: multi-line inputs are enabled by adding a \ at the end of the line +! As an emaple: +! foo:datafiles=foo1,foo2, \ +! foo3 +! Will yield the following new entry for datafiles in stream foo +! +! foo1 +! foo2 +! foo3 +! +!------------------------------------------------------------------------ diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 new file mode 100644 index 000000000..b1e77c6d2 --- /dev/null +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -0,0 +1,279 @@ +module dglc_datamode_noevolve_mod + + use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS + use NUOPC , only : NUOPC_Advertise + use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr + use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add + use dshr_mod , only : dshr_restart_read, dshr_restart_write + use dshr_strdata_mod , only : shr_strdata_type + + implicit none + private ! except + + public :: dglc_datamode_noevolve_advertise + public :: dglc_datamode_noevolve_init_pointers + public :: dglc_datamode_noevolve_advance + public :: dglc_datamode_noevolve_restart_read + public :: dglc_datamode_noevolve_restart_write + + integer :: num_icesheets + + ! export fields + type icesheet_ptr_t + real(r8), pointer :: ptr => null() ! pointer to array + endtype icesheet_ptr_t + type(icesheet_ptr_t), allocatable :: Sg_area(:) + type(icesheet_ptr_t), allocatable :: Sg_ice_covered(:) + type(icesheet_ptr_t), allocatable :: Sg_topo(:) + type(icesheet_ptr_t), allocatable :: Sg_icemask(:) + + character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' + character(len=*), parameter :: field_in_qice = 'Flgl_qice' + + character(len=*), parameter :: field_out_area = 'Sg_area' + character(len=*), parameter :: field_out_ice_covered = 'Sg_ice_covered' + character(len=*), parameter :: field_out_topo = 'Sg_topo' + character(len=*), parameter :: field_out_icemask = 'Sg_icemask' + character(len=*), parameter :: field_out_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' + + character(len=*), parameter :: field_out_hflx_to_lnd = 'Flgg_hflx' + character(len=*), parameter :: field_out_rofi_to_ice = 'Figg_rofi' + character(len=*), parameter :: field_out_rofi_to_ocn = 'Fogg_rofi' + character(len=*), parameter :: field_out_rofl_to_ocn = 'Fogg_rofl' + + character(*) , parameter :: nullstr = 'null' + character(*) , parameter :: rpfile = 'rpointer.glc' + character(*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_name, rc) + + ! input/output variables + type(esmf_State) , intent(inout) :: NstateExp(num_icesheets_in) + type(fldlist_type) , pointer :: fldsexport + character(len=*) , intent(in) :: flds_scalar_name + integer , intent(out) :: rc + + ! local variables + integer :: nf,ns + character(len=CS) :: cnum + character(len=CL) :: cvalue + character(len=CL) :: logmsg + logical :: isPresent, isSet + type(fldlist_type), pointer :: fldList + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + !-------------------------------- + ! Create nested state for active ice sheets only + !-------------------------------- + + num_icesheets = size(NStateExp) + + do ns = 1,num_icesheets + write(cnum,'(i0)') ns + call NUOPC_AddNestedState(importState, CplSet="GLC"//trim(cnum), nestedState=NStateImp(ns), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_AddNestedState(exportState, CplSet="GLC"//trim(cnum), nestedState=NStateExp(ns), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + + ! Advertise export fields + call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsExport, field_out_ice_covered) + call dshr_fldList_add(fldsExport, field_out_topo) + call dshr_fldList_add(fldsExport, field_out_icemask) + call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) + + do ns = 1,num_icesheets + fldlist => fldsExport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(NStateExp(ns), standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (ns == 1) then + call ESMF_LogWrite('(dglc_comp_advertise): Fr_glc'//trim(fldList%stdname), ESMF_LOGMSG_INFO) + end if + fldList => fldList%next + end do + enddo + + end subroutine dglc_datamode_noevolve_advertise + + !=============================================================================== + subroutine dglc_datamode_noevolve_init_pointers(NStateExport, rc) + + ! input/output variables + type(ESMF_State) , intent(inout) :: NStateExport(:) + integer , intent(out) :: rc + + ! local variables + character(len=*), parameter :: subname='(dglc_init_pointers): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! So this is tricky since you need pointers to fields in the nested state + ! So this will have to be done below in a loop + + ! initialize pointers to export fields + allocate(Sg_area(num_icesheets)) + allocate(Sg_topo(num_icesheets)) + allocate(Sg_ice_covered(num_icesheets)) + allocate(Sg_icemask(num_icesheets)) + + do ns = 1,num_icesheets + call dshr_state_getfldptr(NStateExport, 'Sg_topo', fldptr1=Sg_topo(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do + + end subroutine dglc_datamode_noevolve_init_pointers + + !=============================================================================== + subroutine dglc_datamode_noevolve_advance(sdat, mesh, fileName_data, thickness, topo, rc) + + ! Assume that the model mesh is the same as the input data mesh + + ! input/output variables + integer, intent(out) :: rc + + ! local variables + character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' + !------------------------------------------------------------------------------- + + ! input/output variables + type(shr_strdata_type) , intent(in) :: sdat + type(ESMF_Mesh) , intent(in) :: mesh ! mesh read in from fileName_mesh + character(*) , intent(in) :: fileName_data ! file name string + real(R8) , pointer :: thickness(:) ! ice thickness + real(R8) , pointer :: topo(:) ! topography + integer , intent(out) :: rc + + ! local variables + type(ESMF_DistGrid) :: distgrid + type(ESMF_FieldBundle) :: fldbun_src + type(ESMF_Field) :: field_src + integer :: lsize + integer, pointer :: gindex(:) ! domain decomposition of data + integer :: ndims ! number of dims + integer, allocatable :: dimid(:) + type(var_desc_t) :: varid + type(file_desc_t) :: pioid + type(io_desc_t) :: pio_iodesc + integer :: rcode + integer :: nxg, nyg + real(r8), pointer :: data(:) + integer :: srcTermProcessing_Value = 0 + character(*) ,parameter :: subName = '(datm_get_adjustment_factors) ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Create input + fldbun_src = ESMF_FieldBundleCreate(rc=rc) ! input field bundle + + ! "ice thickness" ; + field_src = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_src, (/field_src/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! "bed topography" ; + field_src = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_src, (/field_src/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! "area" + field_src = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, name='area', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_src, (/field_src/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Get mesh info + 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(gindex(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Create_pio_iodesc + rcode = pio_openfile(sdat%pio_subsystem, pioid, sdat%io_type, trim(filename_data), pio_nowrite) + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + rcode = pio_inq_varid(pioid, 'thk', varid) + rcode = pio_inq_varndims(pioid, varid, ndims) + allocate(dimid(ndims)) + rcode = pio_inq_varid(pioid, 'topg', varid) + rcode = pio_inq_vardimid(pioid, varid, dimid(1:ndims)) + rcode = pio_inq_dimlen(pioid, dimid(1), nxg) + rcode = pio_inq_dimlen(pioid, dimid(2), nyg) + call pio_initdecomp(sdat%pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) + deallocate(gindex) + + ! Read in the data into the appropriate field bundle pointers + call dshr_fldbun_getFldPtr(fldbun_src, 'thk', data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + rcode = pio_inq_varid(pioid, 'thk', varid) + call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) + + call dshr_fldbun_getFldPtr(fldbun_src, 'topg', data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + rcode = pio_inq_varid(pioid, 'topg', varid) + call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) + + call pio_closefile(pioid) + call pio_freedecomp(sdat%pio_subsystem, pio_iodesc) + call ESMF_RouteHandleDestroy(route_handle, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + + + + + + end subroutine dglc_datamode_noevolve_advance + + !=============================================================================== + subroutine dglc_datamode_noevolve_restart_write(case_name, inst_suffix, ymd, tod, & + logunit, my_task, sdat) + + ! input/output variables + character(len=*) , intent(in) :: case_name + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: ymd ! model date + integer , intent(in) :: tod ! model sec into model date + integer , intent(in) :: logunit + integer , intent(in) :: my_task + type(shr_strdata_type) , intent(inout) :: sdat + !------------------------------------------------------------------------------- + + call dshr_restart_write(rpfile, case_name, 'dglc', inst_suffix, ymd, tod, & + logunit, my_task, sdat) + + end subroutine dglc_datamode_noevolve_restart_write + + !=============================================================================== + subroutine dglc_datamode_noevolve_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + + ! input/output arguments + character(len=*) , intent(inout) :: rest_filem + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: logunit + integer , intent(in) :: my_task + integer , intent(in) :: mpicom + type(shr_strdata_type) , intent(inout) :: sdat + !------------------------------------------------------------------------------- + + call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + + end subroutine dglc_datamode_noevolve_restart_read + +end module dglc_datamode_noevolve_mod diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 new file mode 100644 index 000000000..8b4257fe3 --- /dev/null +++ b/dglc/glc_comp_nuopc.F90 @@ -0,0 +1,617 @@ +#ifdef CESMCOUPLED +module glc_comp_nuopc +#else +module cdeps_dglc_comp +#endif + + !---------------------------------------------------------------------------- + ! This is the NUOPC cap for DGLC + !---------------------------------------------------------------------------- + use ESMF , only : ESMF_VM, ESMF_VMBroadcast, ESMF_GridCompGet + use ESMF , only : ESMF_Mesh, ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_Time + use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_METHOD_INITIALIZE + use ESMF , only : ESMF_TraceRegionEnter, ESMF_TraceRegionExit, ESMF_ClockGet + use ESMF , only : ESMF_TimeGet, ESMF_TimeInterval, ESMF_Field, ESMF_MAXSTR + use ESMF , only : ESMF_Alarm, ESMF_MethodRemove, ESMF_MethodAdd + use ESMF , only : ESMF_GridCompSetEntryPoint, ESMF_ClockGetAlarm, ESMF_AlarmIsRinging + use ESMF , only : ESMF_StateGet, operator(+), ESMF_AlarmRingerOff, ESMF_LogWrite + use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_VmLogMemInfo + use NUOPC , only : NUOPC_CompDerive, NUOPC_CompSetEntryPoint, NUOPC_CompSpecialize + use NUOPC , only : NUOPC_Advertise, NUOPC_CompAttributeGet, NUOPC_CompAttributeSet + use NUOPC_Model , only : model_routine_SS => SetServices + use NUOPC_Model , only : model_label_Advance => label_Advance + use NUOPC_Model , only : model_label_SetRunClock => label_SetRunClock + use NUOPC_Model , only : model_label_Finalize => label_Finalize + use NUOPC_Model , only : NUOPC_ModelGet, SetVM + use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use shr_cal_mod , only : shr_cal_ymd2date + use shr_log_mod , only : shr_log_setLogUnit + use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck + use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_init_from_config + use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init + use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_check_restart_alarm + use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy + use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_realize + + ! Datamode specialized modules + use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_advertise + use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_init_pointers + use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_advance + use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_restart_read + use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_restart_write + + implicit none + private ! except + + public :: SetServices + public :: SetVM + private :: InitializeAdvertise + private :: InitializeRealize + private :: ModelAdvance + private :: dglc_comp_run + private :: ModelFinalize + + !-------------------------------------------------------------------------- + ! Private module data + !-------------------------------------------------------------------------- + + ! module variables for multiple ice sheets + type(ESMF_State) , allocatable :: NStateImp(:) + type(ESMF_State) , allocatable :: NStateExp(:) + type(shr_strdata_type) , allocatable :: sdat(:) + type(ESMF_Mesh) , allocatable :: model_mesh(:) + + ! module variables common to all data models + character(CS) :: flds_scalar_name = '' + integer :: flds_scalar_num = 0 + integer :: flds_scalar_index_nx = 0 + integer :: flds_scalar_index_ny = 0 + integer :: mpicom ! mpi communicator + integer :: my_task ! my task in mpi communicator mpicom + logical :: mainproc ! true of my_task == main_task + character(len=16) :: inst_suffix = "" ! char string associated with instance (ie. "_0001" or "") + integer :: logunit ! logging unit number + logical :: restart_read ! start from restart + character(CL) :: case_name + character(*) , parameter :: nullstr = 'null' + + ! dglc_in namelist input + integer ,parameter :: max_icesheets = 10 + integer :: num_icesheets = 0 + character(CL) :: streamfilename = nullstr ! filename to obtain stream info from + character(CL) :: nlfilename = nullstr ! filename to obtain namelist info from + character(CL) :: datamode = nullstr ! flags physics options wrt input data + character(CS) :: icesheet_names(max_icesheets) + integer :: nx_global(max_ice_sheets) = -999 + integer :: ny_global(max_ice_sheets) = -999 + character(CL) :: model_meshfile(max_icesheets) = nullstr ! full pathname to model meshfile + character(CL) :: restfilm = nullstr ! model restart file namelist + logical :: skip_restart_read = .false. ! true => skip restart read in continuation run + logical :: export_all = .false. ! true => export all fields, do not check connected or not + + ! linked lists + type(fldList_type) , pointer :: fldsImport => null() + type(fldList_type) , pointer :: fldsExport => null() + + type dfields_icesheets_type + type(dfield_type), pointer :: dfields => null() + end type dfields_icesheets_type + type(dfields_icesheets_type), allocatable :: dfields_icesheets(:) + + ! constants + logical :: diagnose_data = .true. + integer , parameter :: main_task = 0 ! task number of main task +#ifdef CESMCOUPLED + character(*) , parameter :: module_name = "(glc_comp_nuopc)" +#else + character(*) , parameter :: module_name = "(cdeps_dglc_comp)" +#endif + character(*) , parameter :: modelname = 'dglc' + character(*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine SetServices(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! Local varaibles + character(len=*),parameter :: subname=trim(module_name)//':(SetServices) ' + !-------------------------------- + + rc = ESMF_SUCCESS + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + + ! the NUOPC gcomp component will register the generic methods + call NUOPC_CompDerive(gcomp, model_routine_SS, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! switching to IPD versions + call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, & + userRoutine=dshr_model_initphase, phase=0, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! set entry point for methods that require specific implementation + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, & + phaseLabelList=(/"IPDv01p1"/), userRoutine=InitializeAdvertise, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, & + phaseLabelList=(/"IPDv01p3"/), userRoutine=InitializeRealize, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! attach specializing method(s) + call NUOPC_CompSpecialize(gcomp, specLabel=model_label_Advance, specRoutine=ModelAdvance, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_MethodRemove(gcomp, label=model_label_SetRunClock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=model_label_SetRunClock, specRoutine=dshr_set_runclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call NUOPC_CompSpecialize(gcomp, specLabel=model_label_Finalize, specRoutine=ModelFinalize, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) + + end subroutine SetServices + + !=============================================================================== + subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) + + use shr_nl_mod, only: shr_nl_find_group_name + + ! input/output variables + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: importState, exportState + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! local variables + integer :: inst_index ! number of current instance (ie. 1) + integer :: nu ! unit number + integer :: ierr ! error code + integer :: bcasttmp(1) + type(ESMF_VM) :: vm + integer :: ns, n + character(len=CS) :: cnum + character(len=*),parameter :: subname=trim(module_name)//':(InitializeAdvertise) ' + !------------------------------------------------------------------------------- + + !icesheet_names = "ais", "gris" + !num_icesheets = 2 + + namelist / dglc_nml / datamode, & + model_meshfile, ice_sheet_names, nx_global, ny_global, + restfilm, skip_restart_read + + rc = ESMF_SUCCESS + + call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine logical mainproc + mainproc = (my_task == main_task) + + ! Obtain flds_scalar values, mpi values, multi-instance values and + ! set logunit and set shr logging to my log file + call dshr_init(gcomp, 'GLC', mpicom, my_task, inst_index, inst_suffix, & + flds_scalar_name, flds_scalar_num, flds_scalar_index_nx, flds_scalar_index_ny, logunit, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Read dglc_nml from nlfilename + if (my_task == main_task) then + nlfilename = "dglc_in"//trim(inst_suffix) + open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'dglc_nml', status=ierr) + read (nu,nml=dglc_nml,iostat=ierr) + close(nu) + if (ierr > 0) then + write(logunit,'(a,i8)') 'ERROR: reading input namelist, '//trim(nlfilename)//' iostat=',ierr + call shr_sys_abort(subName//': namelist read error '//trim(nlfilename)) + end if + + ! write namelist input to standard out + write(logunit,'(a,a)')' case_name = ',trim(case_name) + write(logunit,'(a,a)')' datamode = ',trim(datamode) + do ns = 1,max_ice_sheets + if (model_meshfile(n) == nullstr) exit + num_icesheets = num_icesheets + 1 + write(logunit,'(a,i4 )')' ice_sheet index = ',ns + write(logunit,'(a,a )')' model_meshfile = ',trim(model_meshfile(ns)) + write(logunit,'(a,i10)')' nx_global = ',nx_global(ns) + write(logunit,'(a,i10)')' ny_global = ',ny_global(ns) + end do + write(logunit,'(a,a )')' restfilm = ',trim(restfilm) + write(logunit,'(a,l6)')' skip_restart_read = ',skip_restart_read + if (skip_restart_read) then + bcasttmp = 1 + else + bcasttmp = 0 + end if + endif + + ! Broadcast namelist input + call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, datamode, CL, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, restfilm, CL, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do ns = 1,num_icesheets + call ESMF_VMBroadcast(vm, model_meshfile(n), CL, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, nx_global(ns), 1, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, ny_global(ns), 1, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Validate datamode + if ( trim(datamode) == 'noevolve') ! read stream, no import data + else + call shr_sys_abort(' ERROR illegal dglc datamode = '//trim(datamode)) + endif + + ! Allocate module variables + allocate(NStateImp(num_icesheets)) + allocate(NStateExp(num_icesheets)) + allocate(sdat(num_icesheets)) + allocate(model_mesh(num_icesheets)) + allocate(dfields_icesheets(num_icesheets)) + + ! Create nested states + do ns = 1,num_icesheets + write(cnum,'(i0)') ns + call NUOPC_AddNestedState(importState, CplSet="GLC"//trim(cnum), nestedState=NStateImp(ns), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_AddNestedState(exportState, CplSet="GLC"//trim(cnum), nestedState=NStateExp(ns), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + + ! Advertise dglc fields + if (trim(datamode)=='noevolve') then + call dglc_datamode_noevolve_advertise(exportState, fldsExport, flds_scalar_name, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + end subroutine InitializeAdvertise + + !=============================================================================== + subroutine InitializeRealize(gcomp, clock, rc) + + ! input/output variables + type(ESMF_GridComp) :: gcomp + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! local variables + type(ESMF_Time) :: currTime + integer :: current_ymd ! model date + integer :: current_year ! model year + integer :: current_mon ! model month + integer :: current_day ! model day + integer :: current_tod ! model sec into model date + type(ESMF_Field) :: lfield + character(CL) ,pointer :: lfieldnamelist(:) => null() + integer :: fieldcount + real(r8), pointer :: fldptr(:) + integer :: n + integer :: imask + real(r8) :: rmask + character(CL) :: cvalue + character(len=*), parameter :: subname=trim(module_name)//':(InitializeRealize) ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + call ESMF_VMLogMemInfo("Entering "//trim(subname)) + + ! Initialize model mesh, restart flag, logunit, model_mask and model_frac + call ESMF_TraceRegionEnter('dglc_strdata_init') + + ! Determine stream filename + streamfilename = trim(modelname)//'.streams'//trim(inst_suffix) +#ifndef DISABLE_FoX + streamfilename = trim(streamfilename)//'.xml' +#endif + + ! generate local mpi comm + call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMGet(vm, localPet=my_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + mainproc = (my_task == main_task) + call shr_log_setLogUnit(logunit) + + ! Set restart flag + call NUOPC_CompAttributeGet(gcomp, name='read_restart', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + read(cvalue,*) read_restart + else + call shr_sys_abort(subname//' ERROR: read restart flag must be present') + end if + + ! Loop over ice sheets + do ns = 1,num_icesheets + write(cns,'(i0)') ns + + ! Initialize pio subsystem +#ifdef CESMCOUPLED + sdat(ns)%pio_subsystem => shr_pio_getiosys('GLC') + sdat(ns)%io_type = shr_pio_getiotype('GLC') + sdat(ns)%io_format = shr_pio_getioformat('GLC') +#else + call dshr_pio_init(gcomp, sdat(ns), logunit, rc) +#endif + + ! Check that model_meshfile exists + if (my_task == main_task) then + inquire(file=trim(model_meshfile(ns)), exist=exists) + if (.not.exists) then + write(logunit, *)' ERROR: model_meshfile '//trim(model_meshfile)//' does not exist' + call shr_sys_abort(trim(subname)//' ERROR: model_meshfile '//trim(model_meshfile)//' does not exist') + end if + endif + + ! Read in model mesh + model_mesh(ns) = ESMF_MeshCreate(trim(model_meshfile(ns)), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Initialize stream data type + call shr_strdata_init_from_config(sdat(ns), streamfilename, model_mesh(ns), clock, 'GLC', logunit, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit('dglc_strdata_init') + + ! Realize the actively coupled fields, now that a mesh is established and + ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState + ! by replacing the advertised fields with the newly created fields of the same name. + + call dshr_fldlist_realize( NStateExp(ns), fldsExport, flds_scalar_name, flds_scalar_num, model_mesh(ns), & + subname//trim(modelname)//':Export', export_all, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call dshr_fldlist_realize( NStateImp(ns), fldsImport, flds_scalar_name, flds_scalar_num, model_mesh(ns), & + subname//trim(modelname)//':Import', .false., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end do ! loop over ice sheets + + ! Get the time to interpolate the stream data to + call ESMF_ClockGet(clock, currTime=currTime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeGet(currTime, yy=current_year, mm=current_mon, dd=current_day, s=current_tod, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call shr_cal_ymd2date(current_year, current_mon, current_day, current_ymd) + + ! loop over ice sheets + do ns = 1,num_icesheets + ! Run dglc + call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Add scalars to export state + call dshr_state_SetScalar(dble(nx_global(ns)),flds_scalar_index_nx, & + NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_SetScalar(dble(ny_global(ns)),flds_scalar_index_ny,& + NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + + call ESMF_VMLogMemInfo("Leaving "//trim(subname)) + + end subroutine InitializeRealize + + !=============================================================================== + subroutine ModelAdvance(gcomp, rc) + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(ESMF_Clock) :: clock + type(ESMF_TimeInterval) :: timeStep + type(ESMF_Time) :: currTime, nextTime + integer :: next_ymd ! model date + integer :: next_tod ! model sec into model date + integer :: yr ! year + integer :: mon ! month + integer :: day ! day in month + logical :: restart_write + character(len=*),parameter :: subname=trim(module_name)//':(ModelAdvance) ' + !------------------------------------------------------------------------------- + + + rc = ESMF_SUCCESS + call shr_log_setLogUnit(logunit) + + call memcheck(subname, 5, my_task == main_task) + + ! query the Component for its clock + call NUOPC_ModelGet(gcomp, modelClock=clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! For nuopc - the component clock is advanced at the end of the time interval + ! Need to advance nuopc one timestep ahead for shr_strdata time interpolation + call ESMF_ClockGet( clock, currTime=currTime, timeStep=timeStep, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + nextTime = currTime + timeStep + call ESMF_TimeGet( nextTime, yy=yr, mm=mon, dd=day, s=next_tod, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call shr_cal_ymd2date(yr, mon, day, next_ymd) + + ! determine if will write restart + restart_write = dshr_check_restart_alarm(clock, rc=rc) + + ! run dglc + call dglc_comp_run(clock, next_ymd, next_tod, restart_write, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine ModelAdvance + + !=============================================================================== + subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) + + ! -------------------------- + ! advance dglc + ! -------------------------- + + ! input/output variables: + type(ESMF_Clock) , intent(in) :: clock + integer , intent(in) :: target_ymd ! model date + integer , intent(in) :: target_tod ! model sec into model date + logical , intent(in) :: restart_write + integer , intent(out) :: rc + + ! local variables + character(len=CS) :: cnum + integer :: ns ! ice sheet index + logical :: first_time = .true. + character(*), parameter :: subName = "(dglc_comp_run) " + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_TraceRegionEnter('DGLC_RUN') + + ! Loop over ice sheets + do ns = 1,size(NStateImp) + + !-------------------- + ! First time initialization + !-------------------- + + if (first_time) then + ! Initialize dfields for given ice sheet + call dglc_init_dfields(NStateImp(ns), NStateExp(ns), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Initialize datamode module ponters + select case (trim(datamode)) + case('noevolve') + call dglc_datamode_copyall_init_pointers(NStateExp(ns), rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end select + + ! Read restart if needed + ! if (restart_read .and. .not. skip_restart_read) then + ! select case (trim(datamode)) + ! case('noevolve') + ! call dglc_datamode_copyall_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat(ns)) + ! end select + ! end if + + ! Reset first_time + first_time = .false. + end if + + !-------------------- + ! Update export (and possibly import data model states) + !-------------------- + + ! Advance data model streams - time and spatially interpolate to model time and grid + call ESMF_TraceRegionEnter('dglc_strdata_advance') + call shr_strdata_advance(sdat(ns), target_ymd, target_tod, logunit, 'dglc', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit('dglc_strdata_advance') + + ! Copy all fields from streams to export state as default + ! This automatically will update the fields in the export state + call ESMF_TraceRegionEnter('dglc_dfield_copy') + call dshr_dfield_copy(dfields_icesheets(ns)%dfields, sdat(ns), rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit('dglc_dfield_copy') + + ! Perform data mode specific calculations + select case (trim(datamode)) + case('noevolve') + call dglc_datamode_noevolve_advance(rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end select + + ! Write restarts if needed + if (restart_write) then + select case (trim(datamode)) + case('noevolve') + call dglc_datamode_noevolve_restart_write(case_name, inst_suffix, target_ymd, target_tod, & + logunit, my_task, sdat(ns)) + end select + end if + + ! Write diagnostics + if (diagnose_data) then + write(cnum,'(i0)') ns + call dshr_state_diagnose(NStateExp, flds_scalar_name, trim(subname)//':ES_'//trim(cnum), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + end do ! end of loop over ice sheets + + call ESMF_TraceRegionExit('DGLC_RUN') + + contains + + subroutine dglc_init_dfields(ns, rc) + ! ----------------------------- + ! Initialize dfields arrays + ! ----------------------------- + + ! input/output variables + integer , intent(in) :: ns ! ice sheet index + integer , intent(out) :: rc + + ! local variables + integer :: n + integer :: fieldcount + type(ESMF_Field) :: lfield + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(*), parameter :: subName = "(dglc_init_dfields) " + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Initialize dfields data type (to map streams to export state fields) + ! Create dfields linked list - used for copying stream fields to export state fields + call ESMF_StateGet(NStateExp(ns), itemCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(lfieldnamelist(fieldCount)) + call ESMF_StateGet(NStateExp(ns), itemNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1, fieldCount + call ESMF_StateGet(NStateExp(ns), itemName=trim(lfieldNameList(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (trim(lfieldnamelist(n)) /= flds_scalar_name) then + call dshr_dfield_add( dfields, sdat(ns), trim(lfieldnamelist(n)), trim(lfieldnamelist(n)), NStateExp(ns), & + logunit, mainproc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + end do + end subroutine dglc_init_dfields + + end subroutine dglc_comp_run + + !=============================================================================== + subroutine ModelFinalize(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + !------------------------------------------------------------------------------- + rc = ESMF_SUCCESS + if (my_task == main_task) then + write(logunit,*) + write(logunit,*) 'dglc : end of main integration loop' + write(logunit,*) + end if + end subroutine ModelFinalize + +#ifdef CESMCOUPLED +end module glc_comp_nuopc +#else +end module cdeps_dglc_comp +#endif From 96f8b7af94516b647a1bdda28988fefb2df68b5f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 19 Mar 2024 19:34:35 +0100 Subject: [PATCH 045/170] more updates to fix compilation issues - not there yet --- CMakeLists.txt | 2 +- dglc/dglc_datamode_noevolve_mod.F90 | 483 +++++++++++++--------------- dglc/glc_comp_nuopc.F90 | 144 +++++---- 3 files changed, 293 insertions(+), 336 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 28fb2a269..bc7cce6df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,7 @@ endif() target_include_directories(dshr PUBLIC $ $) -foreach(COMP datm dice dlnd docn drof dwav) +foreach(COMP datm dice dglc dlnd docn drof dwav) add_subdirectory("${COMP}") if(BLD_STANDALONE) target_include_directories(${COMP} PUBLIC $ diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index b1e77c6d2..3e06254fc 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -1,52 +1,57 @@ module dglc_datamode_noevolve_mod - use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS - use NUOPC , only : NUOPC_Advertise - use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs - use shr_sys_mod , only : shr_sys_abort - use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr - use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add - use dshr_mod , only : dshr_restart_read, dshr_restart_write - use dshr_strdata_mod , only : shr_strdata_type - - implicit none - private ! except - - public :: dglc_datamode_noevolve_advertise - public :: dglc_datamode_noevolve_init_pointers - public :: dglc_datamode_noevolve_advance - public :: dglc_datamode_noevolve_restart_read - public :: dglc_datamode_noevolve_restart_write - - integer :: num_icesheets - - ! export fields - type icesheet_ptr_t - real(r8), pointer :: ptr => null() ! pointer to array - endtype icesheet_ptr_t - type(icesheet_ptr_t), allocatable :: Sg_area(:) - type(icesheet_ptr_t), allocatable :: Sg_ice_covered(:) - type(icesheet_ptr_t), allocatable :: Sg_topo(:) - type(icesheet_ptr_t), allocatable :: Sg_icemask(:) - - character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' - character(len=*), parameter :: field_in_qice = 'Flgl_qice' - - character(len=*), parameter :: field_out_area = 'Sg_area' - character(len=*), parameter :: field_out_ice_covered = 'Sg_ice_covered' - character(len=*), parameter :: field_out_topo = 'Sg_topo' - character(len=*), parameter :: field_out_icemask = 'Sg_icemask' - character(len=*), parameter :: field_out_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' - - character(len=*), parameter :: field_out_hflx_to_lnd = 'Flgg_hflx' - character(len=*), parameter :: field_out_rofi_to_ice = 'Figg_rofi' - character(len=*), parameter :: field_out_rofi_to_ocn = 'Fogg_rofi' - character(len=*), parameter :: field_out_rofl_to_ocn = 'Fogg_rofl' - - character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.glc' - character(*) , parameter :: u_FILE_u = & - __FILE__ + use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS + use ESMF , only : ESMF_Mesh, ESMF_DistGrid, ESMF_FieldBundle, ESMF_Field + use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldCreate, ESMF_MeshLoc_Element + use ESMF , only : ESMF_FieldBundleAdd, ESMF_MeshGet, ESMF_DistGridGet, ESMF_Typekind_R8 + use NUOPC , only : NUOPC_Advertise, NUOPC_AddNestedState + use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr + use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add + use dshr_strdata_mod , only : shr_strdata_type + use pio , only : file_desc_t, io_desc_t, var_desc_t, PIO_BCAST_ERROR, PIO_NOWRITE + use pio , only : pio_openfile, pio_inq_varid, pio_inq_varndims, pio_inq_vardimid + use pio , only : pio_inq_dimlen, pio_initdecomp, pio_read_darray, pio_double + use pio , only : pio_closefile, pio_freedecomp, pio_subsystem_t + + implicit none + private ! except + + public :: dglc_datamode_noevolve_advertise + public :: dglc_datamode_noevolve_init_pointers + public :: dglc_datamode_noevolve_advance + + integer :: num_icesheets + + ! export fields + type icesheet_ptr_t + real(r8), pointer :: ptr(:) => null() ! pointer to array + endtype icesheet_ptr_t + type(icesheet_ptr_t), allocatable :: Sg_area(:) + type(icesheet_ptr_t), allocatable :: Sg_topo(:) + type(icesheet_ptr_t), allocatable :: Sg_ice_covered(:) + type(icesheet_ptr_t), allocatable :: Sg_icemask(:) + + character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' + character(len=*), parameter :: field_in_qice = 'Flgl_qice' + + character(len=*), parameter :: field_out_area = 'Sg_area' + character(len=*), parameter :: field_out_ice_covered = 'Sg_ice_covered' + character(len=*), parameter :: field_out_topo = 'Sg_topo' + character(len=*), parameter :: field_out_icemask = 'Sg_icemask' + character(len=*), parameter :: field_out_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' + + character(len=*), parameter :: field_out_hflx_to_lnd = 'Flgg_hflx' + character(len=*), parameter :: field_out_rofi_to_ice = 'Figg_rofi' + character(len=*), parameter :: field_out_rofi_to_ocn = 'Fogg_rofi' + character(len=*), parameter :: field_out_rofl_to_ocn = 'Fogg_rofl' + + character(*) , parameter :: nullstr = 'null' + character(*) , parameter :: rpfile = 'rpointer.glc' + + character(*) , parameter :: u_FILE_u = & + __FILE__ !=============================================================================== contains @@ -54,226 +59,168 @@ module dglc_datamode_noevolve_mod subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_name, rc) - ! input/output variables - type(esmf_State) , intent(inout) :: NstateExp(num_icesheets_in) - type(fldlist_type) , pointer :: fldsexport - character(len=*) , intent(in) :: flds_scalar_name - integer , intent(out) :: rc - - ! local variables - integer :: nf,ns - character(len=CS) :: cnum - character(len=CL) :: cvalue - character(len=CL) :: logmsg - logical :: isPresent, isSet - type(fldlist_type), pointer :: fldList - !------------------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - !-------------------------------- - ! Create nested state for active ice sheets only - !-------------------------------- - - num_icesheets = size(NStateExp) - - do ns = 1,num_icesheets - write(cnum,'(i0)') ns - call NUOPC_AddNestedState(importState, CplSet="GLC"//trim(cnum), nestedState=NStateImp(ns), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_AddNestedState(exportState, CplSet="GLC"//trim(cnum), nestedState=NStateExp(ns), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end do - - ! Advertise export fields - call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) - call dshr_fldList_add(fldsExport, field_out_ice_covered) - call dshr_fldList_add(fldsExport, field_out_topo) - call dshr_fldList_add(fldsExport, field_out_icemask) - call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) - - do ns = 1,num_icesheets - fldlist => fldsExport ! the head of the linked list - do while (associated(fldlist)) - call NUOPC_Advertise(NStateExp(ns), standardName=fldlist%stdname, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (ns == 1) then - call ESMF_LogWrite('(dglc_comp_advertise): Fr_glc'//trim(fldList%stdname), ESMF_LOGMSG_INFO) - end if - fldList => fldList%next - end do - enddo - - end subroutine dglc_datamode_noevolve_advertise - - !=============================================================================== - subroutine dglc_datamode_noevolve_init_pointers(NStateExport, rc) - - ! input/output variables - type(ESMF_State) , intent(inout) :: NStateExport(:) - integer , intent(out) :: rc - - ! local variables - character(len=*), parameter :: subname='(dglc_init_pointers): ' - !------------------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - ! So this is tricky since you need pointers to fields in the nested state - ! So this will have to be done below in a loop - - ! initialize pointers to export fields - allocate(Sg_area(num_icesheets)) - allocate(Sg_topo(num_icesheets)) - allocate(Sg_ice_covered(num_icesheets)) - allocate(Sg_icemask(num_icesheets)) - - do ns = 1,num_icesheets - call dshr_state_getfldptr(NStateExport, 'Sg_topo', fldptr1=Sg_topo(ns)%ptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end do - - end subroutine dglc_datamode_noevolve_init_pointers - - !=============================================================================== - subroutine dglc_datamode_noevolve_advance(sdat, mesh, fileName_data, thickness, topo, rc) - - ! Assume that the model mesh is the same as the input data mesh - - ! input/output variables - integer, intent(out) :: rc - - ! local variables - character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' - !------------------------------------------------------------------------------- - - ! input/output variables - type(shr_strdata_type) , intent(in) :: sdat - type(ESMF_Mesh) , intent(in) :: mesh ! mesh read in from fileName_mesh - character(*) , intent(in) :: fileName_data ! file name string - real(R8) , pointer :: thickness(:) ! ice thickness - real(R8) , pointer :: topo(:) ! topography - integer , intent(out) :: rc - - ! local variables - type(ESMF_DistGrid) :: distgrid - type(ESMF_FieldBundle) :: fldbun_src - type(ESMF_Field) :: field_src - integer :: lsize - integer, pointer :: gindex(:) ! domain decomposition of data - integer :: ndims ! number of dims - integer, allocatable :: dimid(:) - type(var_desc_t) :: varid - type(file_desc_t) :: pioid - type(io_desc_t) :: pio_iodesc - integer :: rcode - integer :: nxg, nyg - real(r8), pointer :: data(:) - integer :: srcTermProcessing_Value = 0 - character(*) ,parameter :: subName = '(datm_get_adjustment_factors) ' - !------------------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - ! Create input - fldbun_src = ESMF_FieldBundleCreate(rc=rc) ! input field bundle - - ! "ice thickness" ; - field_src = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(fldbun_src, (/field_src/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! "bed topography" ; - field_src = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(fldbun_src, (/field_src/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! "area" - field_src = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, name='area', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(fldbun_src, (/field_src/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Get mesh info - 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(gindex(lsize)) - call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Create_pio_iodesc - rcode = pio_openfile(sdat%pio_subsystem, pioid, sdat%io_type, trim(filename_data), pio_nowrite) - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) - rcode = pio_inq_varid(pioid, 'thk', varid) - rcode = pio_inq_varndims(pioid, varid, ndims) - allocate(dimid(ndims)) - rcode = pio_inq_varid(pioid, 'topg', varid) - rcode = pio_inq_vardimid(pioid, varid, dimid(1:ndims)) - rcode = pio_inq_dimlen(pioid, dimid(1), nxg) - rcode = pio_inq_dimlen(pioid, dimid(2), nyg) - call pio_initdecomp(sdat%pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) - deallocate(gindex) - - ! Read in the data into the appropriate field bundle pointers - call dshr_fldbun_getFldPtr(fldbun_src, 'thk', data, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - rcode = pio_inq_varid(pioid, 'thk', varid) - call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) - - call dshr_fldbun_getFldPtr(fldbun_src, 'topg', data, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - rcode = pio_inq_varid(pioid, 'topg', varid) - call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) - - call pio_closefile(pioid) - call pio_freedecomp(sdat%pio_subsystem, pio_iodesc) - call ESMF_RouteHandleDestroy(route_handle, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - - - - - - end subroutine dglc_datamode_noevolve_advance - - !=============================================================================== - subroutine dglc_datamode_noevolve_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'dglc', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine dglc_datamode_noevolve_restart_write - - !=============================================================================== - subroutine dglc_datamode_noevolve_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - - ! input/output arguments - character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) - - end subroutine dglc_datamode_noevolve_restart_read + ! input/output variables + type(ESMF_State) , intent(inout) :: NStateExp(:) + type(fldlist_type) , pointer :: fldsexport + character(len=*) , intent(in) :: flds_scalar_name + integer , intent(out) :: rc + + ! local variables + integer :: ns + logical :: isPresent, isSet + type(fldlist_type), pointer :: fldList + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + !-------------------------------- + ! Create nested state for active ice sheets only + !-------------------------------- + + ! Set module variable for number of ice sheets + num_icesheets = size(NStateExp) + + ! Advertise export fields + call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsExport, field_out_ice_covered) + call dshr_fldList_add(fldsExport, field_out_topo) + call dshr_fldList_add(fldsExport, field_out_icemask) + Call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) + + do ns = 1,num_icesheets + fldlist => fldsExport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(NStateExp(ns), standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (ns == 1) then + call ESMF_LogWrite('(dglc_comp_advertise): Fr_glc'//trim(fldList%stdname), ESMF_LOGMSG_INFO) + end if + fldList => fldList%next + end do + enddo + + end subroutine dglc_datamode_noevolve_advertise + + !=============================================================================== + subroutine dglc_datamode_noevolve_init_pointers(NStateExp, rc) + + ! input/output variables + type(ESMF_State) , intent(inout) :: NStateExp(:) + integer , intent(out) :: rc + + ! local variables + integer :: ns + character(len=*), parameter :: subname='(dglc_init_pointers): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! So this is tricky since you need pointers to fields in the nested state + ! So this will have to be done below in a loop + + ! initialize pointers to export fields + allocate(Sg_area(num_icesheets)) + allocate(Sg_topo(num_icesheets)) + allocate(Sg_ice_covered(num_icesheets)) + allocate(Sg_icemask(num_icesheets)) + + do ns = 1,num_icesheets + call dshr_state_getfldptr(NStateExp(ns), 'Sg_topo' , fldptr1=Sg_topo(ns)%ptr , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(NStateExp(ns), 'Sg_ice_covered' , fldptr1=Sg_ice_covered(ns)%ptr , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(NStateExp(ns), 'Sg_icemask' , fldptr1=Sg_icemask(ns)%ptr , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do + + end subroutine dglc_datamode_noevolve_init_pointers + + !=============================================================================== + subroutine dglc_datamode_noevolve_advance(ns, pio_subsystem, io_type, io_format, & + model_mesh, input_file, rc) + + ! Assume that the model mesh is the same as the input data mesh + + ! input/output variables + integer , intent(in) :: ns ! ice sheet index + type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info + integer , intent(in) :: io_type ! pio info + integer , intent(in) :: io_format ! pio info + type(ESMF_Mesh) , intent(in) :: model_mesh ! mesh read in from fileName_mesh + character(len=*) , intent(in) :: input_file ! file name string + integer , intent(out) :: rc + + ! local variables + type(ESMF_FieldBundle) :: fldbun_noevolve + type(file_desc_t) :: pioid + type(io_desc_t) :: pio_iodesc + type(ESMF_DistGrid) :: distgrid + type(ESMF_Field) :: field_noevolve + integer :: lsize + integer, pointer :: gindex(:) ! domain decomposition of data + integer :: ndims ! number of dims + integer, allocatable :: dimid(:) + type(var_desc_t) :: varid + integer :: rcode + integer :: nxg, nyg + real(r8), pointer :: data(:) + character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Create module level field bundle + fldbun_noevolve = ESMF_FieldBundleCreate(rc=rc) ! input field bundle + + ! "ice thickness" ; + field_noevolve = ESMF_FieldCreate(model_mesh, ESMF_TYPEKIND_R8, name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! "bed topography" ; + field_noevolve = ESMF_FieldCreate(model_mesh, ESMF_TYPEKIND_R8, name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Get mesh info + call ESMF_MeshGet(model_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(gindex(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Create pioid and pio_iodesc at the module level + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(input_file), pio_nowrite) + rcode = pio_inq_varid(pioid, 'thk', varid) + rcode = pio_inq_varndims(pioid, varid, ndims) + allocate(dimid(ndims)) + rcode = pio_inq_vardimid(pioid, varid, dimid(1:ndims)) + rcode = pio_inq_dimlen(pioid, dimid(1), nxg) + rcode = pio_inq_dimlen(pioid, dimid(2), nyg) + call pio_initdecomp(pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) + deallocate(gindex) + + ! Read in the data into the appropriate field bundle pointers + call dshr_fldbun_getFldPtr(fldbun_noevolve, 'thk', data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + rcode = pio_inq_varid(pioid, 'thk', varid) + call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) + Sg_ice_covered(ns)%ptr(:) = data(:) + + call dshr_fldbun_getFldPtr(fldbun_noevolve, 'topg', data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + rcode = pio_inq_varid(pioid, 'topg', varid) + call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) + Sg_topo(ns)%ptr(:) = data(:) + + call pio_closefile(pioid) + call pio_freedecomp(pio_subsystem, pio_iodesc) + + end subroutine dglc_datamode_noevolve_advance end module dglc_datamode_noevolve_mod diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 8b4257fe3..586404a35 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -7,7 +7,7 @@ module cdeps_dglc_comp !---------------------------------------------------------------------------- ! This is the NUOPC cap for DGLC !---------------------------------------------------------------------------- - use ESMF , only : ESMF_VM, ESMF_VMBroadcast, ESMF_GridCompGet + use ESMF , only : ESMF_VM, ESMF_VmGet, ESMF_VMBroadcast, ESMF_GridCompGet use ESMF , only : ESMF_Mesh, ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_Time use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_METHOD_INITIALIZE use ESMF , only : ESMF_TraceRegionEnter, ESMF_TraceRegionExit, ESMF_ClockGet @@ -16,8 +16,10 @@ module cdeps_dglc_comp use ESMF , only : ESMF_GridCompSetEntryPoint, ESMF_ClockGetAlarm, ESMF_AlarmIsRinging use ESMF , only : ESMF_StateGet, operator(+), ESMF_AlarmRingerOff, ESMF_LogWrite use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_VmLogMemInfo + use ESMF , only : ESMF_MeshCreate, ESMF_FILEFORMAT_ESMFMESH use NUOPC , only : NUOPC_CompDerive, NUOPC_CompSetEntryPoint, NUOPC_CompSpecialize use NUOPC , only : NUOPC_Advertise, NUOPC_CompAttributeGet, NUOPC_CompAttributeSet + use NUOPC , only : NUOPC_AddNestedState use NUOPC_Model , only : model_routine_SS => SetServices use NUOPC_Model , only : model_label_Advance => label_Advance use NUOPC_Model , only : model_label_SetRunClock => label_SetRunClock @@ -27,6 +29,8 @@ module cdeps_dglc_comp use shr_sys_mod , only : shr_sys_abort use shr_cal_mod , only : shr_cal_ymd2date use shr_log_mod , only : shr_log_setLogUnit + use shr_string_mod , only : shr_string_listgetnum + use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_init_from_config use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init @@ -38,8 +42,6 @@ module cdeps_dglc_comp use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_advertise use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_init_pointers use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_advance - use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_restart_read - use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_restart_write implicit none private ! except @@ -57,10 +59,14 @@ module cdeps_dglc_comp !-------------------------------------------------------------------------- ! module variables for multiple ice sheets + type(shr_strdata_type) , allocatable :: sdat(:) type(ESMF_State) , allocatable :: NStateImp(:) type(ESMF_State) , allocatable :: NStateExp(:) - type(shr_strdata_type) , allocatable :: sdat(:) - type(ESMF_Mesh) , allocatable :: model_mesh(:) + type(ESMF_Mesh) , allocatable :: model_meshes(:) + character(CL) , allocatable :: model_meshfiles(:) + character(CS) , allocatable :: icesheet_names(:) + integer , allocatable :: nx_global(:) + integer , allocatable :: ny_global(:) ! module variables common to all data models character(CS) :: flds_scalar_name = '' @@ -69,7 +75,7 @@ module cdeps_dglc_comp integer :: flds_scalar_index_ny = 0 integer :: mpicom ! mpi communicator integer :: my_task ! my task in mpi communicator mpicom - logical :: mainproc ! true of my_task == main_task + logical :: mainproc ! true of my_task == main_task character(len=16) :: inst_suffix = "" ! char string associated with instance (ie. "_0001" or "") integer :: logunit ! logging unit number logical :: restart_read ! start from restart @@ -77,15 +83,11 @@ module cdeps_dglc_comp character(*) , parameter :: nullstr = 'null' ! dglc_in namelist input - integer ,parameter :: max_icesheets = 10 integer :: num_icesheets = 0 + character(ESMF_MAXSTR) :: model_meshfiles_list ! colon separated string containing model meshfiles character(CL) :: streamfilename = nullstr ! filename to obtain stream info from character(CL) :: nlfilename = nullstr ! filename to obtain namelist info from character(CL) :: datamode = nullstr ! flags physics options wrt input data - character(CS) :: icesheet_names(max_icesheets) - integer :: nx_global(max_ice_sheets) = -999 - integer :: ny_global(max_ice_sheets) = -999 - character(CL) :: model_meshfile(max_icesheets) = nullstr ! full pathname to model meshfile character(CL) :: restfilm = nullstr ! model restart file namelist logical :: skip_restart_read = .false. ! true => skip restart read in continuation run logical :: export_all = .false. ! true => export all fields, do not check connected or not @@ -171,11 +173,11 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer, intent(out) :: rc ! local variables + type(ESMF_VM) :: vm integer :: inst_index ! number of current instance (ie. 1) integer :: nu ! unit number integer :: ierr ! error code integer :: bcasttmp(1) - type(ESMF_VM) :: vm integer :: ns, n character(len=CS) :: cnum character(len=*),parameter :: subname=trim(module_name)//':(InitializeAdvertise) ' @@ -185,7 +187,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) !num_icesheets = 2 namelist / dglc_nml / datamode, & - model_meshfile, ice_sheet_names, nx_global, ny_global, + ice_sheet_names, model_meshfiles_list, nx_global, ny_global, & restfilm, skip_restart_read rc = ESMF_SUCCESS @@ -217,11 +219,13 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! write namelist input to standard out write(logunit,'(a,a)')' case_name = ',trim(case_name) write(logunit,'(a,a)')' datamode = ',trim(datamode) - do ns = 1,max_ice_sheets - if (model_meshfile(n) == nullstr) exit - num_icesheets = num_icesheets + 1 + + num_icesheets = shr_string_listGetNum(model_meshfiles_list) + do ns = 1,num_icesheets + ! determine mesh filename + call shr_string_listGetName(model_meshfiles_list, ns, model_meshfile(ns)) write(logunit,'(a,i4 )')' ice_sheet index = ',ns - write(logunit,'(a,a )')' model_meshfile = ',trim(model_meshfile(ns)) + write(logunit,'(a,a )')' model_meshfile = ',trim(model_meshfiles(ns)) write(logunit,'(a,i10)')' nx_global = ',nx_global(ns) write(logunit,'(a,i10)')' ny_global = ',ny_global(ns) end do @@ -242,7 +246,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call ESMF_VMBroadcast(vm, restfilm, CL, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do ns = 1,num_icesheets - call ESMF_VMBroadcast(vm, model_meshfile(n), CL, main_task, rc=rc) + call ESMF_VMBroadcast(vm, model_meshfiles(ns), CL, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, nx_global(ns), 1, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -253,7 +257,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Validate datamode - if ( trim(datamode) == 'noevolve') ! read stream, no import data + if ( trim(datamode) == 'noevolve') then ! read stream, no import data + ! do nothing else call shr_sys_abort(' ERROR illegal dglc datamode = '//trim(datamode)) endif @@ -262,7 +267,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) allocate(NStateImp(num_icesheets)) allocate(NStateExp(num_icesheets)) allocate(sdat(num_icesheets)) - allocate(model_mesh(num_icesheets)) + allocate(model_meshes(num_icesheets)) allocate(dfields_icesheets(num_icesheets)) ! Create nested states @@ -276,7 +281,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Advertise dglc fields if (trim(datamode)=='noevolve') then - call dglc_datamode_noevolve_advertise(exportState, fldsExport, flds_scalar_name, rc) + call dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -291,20 +296,20 @@ subroutine InitializeRealize(gcomp, clock, rc) integer, intent(out) :: rc ! local variables - type(ESMF_Time) :: currTime - integer :: current_ymd ! model date - integer :: current_year ! model year - integer :: current_mon ! model month - integer :: current_day ! model day - integer :: current_tod ! model sec into model date - type(ESMF_Field) :: lfield - character(CL) ,pointer :: lfieldnamelist(:) => null() - integer :: fieldcount - real(r8), pointer :: fldptr(:) - integer :: n - integer :: imask - real(r8) :: rmask - character(CL) :: cvalue + type(ESMF_VM) :: vm + type(ESMF_Time) :: currTime + integer :: current_ymd ! model date + integer :: current_year ! model year + integer :: current_mon ! model month + integer :: current_day ! model day + integer :: current_tod ! model sec into model date + integer :: localpet + integer :: n, ns + character(CL) :: cvalue + character(CS) :: cns + logical :: ispresent, isset + logical :: read_restart + logical :: exists character(len=*), parameter :: subname=trim(module_name)//':(InitializeRealize) ' !------------------------------------------------------------------------------- @@ -339,6 +344,7 @@ subroutine InitializeRealize(gcomp, clock, rc) ! Loop over ice sheets do ns = 1,num_icesheets + write(cns,'(i0)') ns ! Initialize pio subsystem @@ -352,20 +358,23 @@ subroutine InitializeRealize(gcomp, clock, rc) ! Check that model_meshfile exists if (my_task == main_task) then - inquire(file=trim(model_meshfile(ns)), exist=exists) + inquire(file=trim(model_meshfiles(ns)), exist=exists) if (.not.exists) then - write(logunit, *)' ERROR: model_meshfile '//trim(model_meshfile)//' does not exist' - call shr_sys_abort(trim(subname)//' ERROR: model_meshfile '//trim(model_meshfile)//' does not exist') + write(logunit,'(a)')' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist' + call shr_sys_abort(trim(subname)//' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist') end if endif ! Read in model mesh - model_mesh(ns) = ESMF_MeshCreate(trim(model_meshfile(ns)), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + model_meshes(ns) = ESMF_MeshCreate(trim(model_meshfiles(ns)), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Initialize stream data type - call shr_strdata_init_from_config(sdat(ns), streamfilename, model_mesh(ns), clock, 'GLC', logunit, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (trim(datamode) /= 'noevolve') then + call shr_strdata_init_from_config(sdat(ns), streamfilename, model_meshes(ns), clock, 'GLC', logunit, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call ESMF_TraceRegionExit('dglc_strdata_init') ! Realize the actively coupled fields, now that a mesh is established and @@ -482,7 +491,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) call ESMF_TraceRegionEnter('DGLC_RUN') ! Loop over ice sheets - do ns = 1,size(NStateImp) + do ns = 1,size(NStateExp) !-------------------- ! First time initialization @@ -490,8 +499,10 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) if (first_time) then ! Initialize dfields for given ice sheet - call dglc_init_dfields(NStateImp(ns), NStateExp(ns), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (trim(datamode) /= 'noevolve') then + call dglc_init_dfields(ns, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if ! Initialize datamode module ponters select case (trim(datamode)) @@ -501,12 +512,11 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) end select ! Read restart if needed - ! if (restart_read .and. .not. skip_restart_read) then - ! select case (trim(datamode)) - ! case('noevolve') - ! call dglc_datamode_copyall_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat(ns)) - ! end select - ! end if + if (trim(datamode) /= 'noevolve') then + if (restart_read .and. .not. skip_restart_read) then + ! placeholder for future datamodes + end if + end if ! Reset first_time first_time = .false. @@ -516,18 +526,20 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) ! Update export (and possibly import data model states) !-------------------- - ! Advance data model streams - time and spatially interpolate to model time and grid - call ESMF_TraceRegionEnter('dglc_strdata_advance') - call shr_strdata_advance(sdat(ns), target_ymd, target_tod, logunit, 'dglc', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TraceRegionExit('dglc_strdata_advance') + if (trim(datamode) /= 'noevolve') then + ! Advance data model streams - time and spatially interpolate to model time and grid + call ESMF_TraceRegionEnter('dglc_strdata_advance') + call shr_strdata_advance(sdat(ns), target_ymd, target_tod, logunit, 'dglc', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit('dglc_strdata_advance') - ! Copy all fields from streams to export state as default - ! This automatically will update the fields in the export state - call ESMF_TraceRegionEnter('dglc_dfield_copy') - call dshr_dfield_copy(dfields_icesheets(ns)%dfields, sdat(ns), rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TraceRegionExit('dglc_dfield_copy') + ! Copy all fields from streams to export state as default + ! This automatically will update the fields in the export state + call ESMF_TraceRegionEnter('dglc_dfield_copy') + call dshr_dfield_copy(dfields_icesheets(ns)%dfields, sdat(ns), rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit('dglc_dfield_copy') + end if ! Perform data mode specific calculations select case (trim(datamode)) @@ -538,11 +550,9 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) ! Write restarts if needed if (restart_write) then - select case (trim(datamode)) - case('noevolve') - call dglc_datamode_noevolve_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat(ns)) - end select + if (trim(datamode) /= 'evolve') then + ! this is a place holder for future datamode + end if end if ! Write diagnostics @@ -572,7 +582,7 @@ subroutine dglc_init_dfields(ns, rc) integer :: fieldcount type(ESMF_Field) :: lfield character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - character(*), parameter :: subName = "(dglc_init_dfields) " + character(*), parameter :: subName = "(dglc_init_dfields) " !------------------------------------------------------------------------------- rc = ESMF_SUCCESS From 1f42d9c8c3e16a1699d1bc8d75792d9610673848 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 20 Mar 2024 12:26:41 +0100 Subject: [PATCH 046/170] more compilation fixes --- dglc/cime_config/buildlib | 54 -- dglc/cime_config/namelist_definition_dglc.xml | 18 +- dglc/dglc_datamode_noevolve_mod.F90 | 135 ++--- dglc/glc_comp_nuopc.F90 | 465 +++++++++--------- 4 files changed, 333 insertions(+), 339 deletions(-) delete mode 100755 dglc/cime_config/buildlib diff --git a/dglc/cime_config/buildlib b/dglc/cime_config/buildlib deleted file mode 100755 index 281f0d4e9..000000000 --- a/dglc/cime_config/buildlib +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 - -""" -build cime component model library. This buildlib script is used by all CDEPS components. -""" - -import sys, os - -_CIMEROOT = os.environ.get("CIMEROOT") -if _CIMEROOT is None: - raise SystemExit("ERROR: must set CIMEROOT environment variable") -sys.path.append(os.path.join(_CIMEROOT, "CIME", "Tools")) - -_LIBDIR = os.path.join(_CIMEROOT, "CIME") -sys.path.append(_LIBDIR) - -from standard_script_setup import * -from CIME.buildlib import parse_input -from CIME.case import Case -from CIME.utils import run_cmd, symlink_force, expect - -# pragma pylint: disable=unused-argument,undefined-variable - -logger = logging.getLogger(__name__) - - -def buildlib(bldroot, libroot, case, compname=None): - if not compname: - expect( - bldroot.endswith("obj"), - "It appears that buildlib_comps is being called for the main CDEPS build\n" - "(the main CDEPS build should use buildlib, not buildlib_comps)", - ) - compname = os.path.basename(os.path.abspath(os.path.join(bldroot, os.pardir))) - - _, o, e = run_cmd("make d{}".format(compname), from_dir=bldroot, verbose=True) - libname = "lib{}.a".format(compname) - dlibname = "libd{}.a".format(compname) - dlibpath = os.path.join(bldroot, dlibname) - if os.path.exists(dlibpath): - symlink_force(os.path.join(bldroot, dlibname), os.path.join(libroot, libname)) - else: - expect(False, "ERROR in {} build {} {}".format(compname, o, e)) - logger.info(f"build successful for comp={compname}") - - -def _main_func(args): - caseroot, libroot, bldroot = parse_input(args) - with Case(caseroot) as case: - buildlib(bldroot, libroot, case) - - -if __name__ == "__main__": - _main_func(sys.argv) diff --git a/dglc/cime_config/namelist_definition_dglc.xml b/dglc/cime_config/namelist_definition_dglc.xml index 2fabb50a8..0041e88af 100644 --- a/dglc/cime_config/namelist_definition_dglc.xml +++ b/dglc/cime_config/namelist_definition_dglc.xml @@ -35,6 +35,22 @@ + + char + streams + abs + dglc_nml + + $DIN_LOC_ROOT/glc/cism/Antarctica/ISMIP6_Antarctica_8km.init.c210908.nc:$DIN_LOC_ROOT/glc/cism/Greenland/greenland_4km_epsg3413_c171126.nc + $DIN_LOC_ROOT/glc/cism/Greenland/gland20.input_c150415.nc + $DIN_LOC_ROOT/glc/cism/Greenland/greenland_4km_epsg3413_c171126.nc + $DIN_LOC_ROOT/glc/cism/Antarctica/ISMIP6_Antarctica_8km.init.c210908.nc + + + colon deliminted string of inputdata files + + + char streams @@ -44,7 +60,7 @@ $GLC_DOMAIN_MESH - file(s) specifying model mesh + colon deliminted string of file(s) specifying model mesh for more than one ice sheets this will contain an array of mesh file names diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 3e06254fc..03ba9d4b3 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -10,10 +10,10 @@ module dglc_datamode_noevolve_mod use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add use dshr_strdata_mod , only : shr_strdata_type - use pio , only : file_desc_t, io_desc_t, var_desc_t, PIO_BCAST_ERROR, PIO_NOWRITE + use pio , only : file_desc_t, io_desc_t, var_desc_t, iosystem_desc_t use pio , only : pio_openfile, pio_inq_varid, pio_inq_varndims, pio_inq_vardimid use pio , only : pio_inq_dimlen, pio_initdecomp, pio_read_darray, pio_double - use pio , only : pio_closefile, pio_freedecomp, pio_subsystem_t + use pio , only : pio_closefile, pio_freedecomp, PIO_BCAST_ERROR, PIO_NOWRITE implicit none private ! except @@ -136,26 +136,26 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, rc) end subroutine dglc_datamode_noevolve_init_pointers !=============================================================================== - subroutine dglc_datamode_noevolve_advance(ns, pio_subsystem, io_type, io_format, & - model_mesh, input_file, rc) + subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & + model_meshes, input_files, rc) ! Assume that the model mesh is the same as the input data mesh ! input/output variables - integer , intent(in) :: ns ! ice sheet index - type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info - integer , intent(in) :: io_type ! pio info - integer , intent(in) :: io_format ! pio info - type(ESMF_Mesh) , intent(in) :: model_mesh ! mesh read in from fileName_mesh - character(len=*) , intent(in) :: input_file ! file name string + type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info + integer , intent(in) :: io_type ! pio info + integer , intent(in) :: io_format ! pio info + type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes + character(len=*) , intent(in) :: input_files(:) ! input file names integer , intent(out) :: rc ! local variables type(ESMF_FieldBundle) :: fldbun_noevolve - type(file_desc_t) :: pioid - type(io_desc_t) :: pio_iodesc type(ESMF_DistGrid) :: distgrid type(ESMF_Field) :: field_noevolve + type(file_desc_t) :: pioid + type(io_desc_t) :: pio_iodesc + integer :: ns ! ice sheet index integer :: lsize integer, pointer :: gindex(:) ! domain decomposition of data integer :: ndims ! number of dims @@ -169,57 +169,66 @@ subroutine dglc_datamode_noevolve_advance(ns, pio_subsystem, io_type, io_format, rc = ESMF_SUCCESS - ! Create module level field bundle - fldbun_noevolve = ESMF_FieldBundleCreate(rc=rc) ! input field bundle - - ! "ice thickness" ; - field_noevolve = ESMF_FieldCreate(model_mesh, ESMF_TYPEKIND_R8, name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! "bed topography" ; - field_noevolve = ESMF_FieldCreate(model_mesh, ESMF_TYPEKIND_R8, name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Get mesh info - call ESMF_MeshGet(model_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(gindex(lsize)) - call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Create pioid and pio_iodesc at the module level - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) - rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(input_file), pio_nowrite) - rcode = pio_inq_varid(pioid, 'thk', varid) - rcode = pio_inq_varndims(pioid, varid, ndims) - allocate(dimid(ndims)) - rcode = pio_inq_vardimid(pioid, varid, dimid(1:ndims)) - rcode = pio_inq_dimlen(pioid, dimid(1), nxg) - rcode = pio_inq_dimlen(pioid, dimid(2), nyg) - call pio_initdecomp(pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) - deallocate(gindex) - - ! Read in the data into the appropriate field bundle pointers - call dshr_fldbun_getFldPtr(fldbun_noevolve, 'thk', data, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - rcode = pio_inq_varid(pioid, 'thk', varid) - call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) - Sg_ice_covered(ns)%ptr(:) = data(:) - - call dshr_fldbun_getFldPtr(fldbun_noevolve, 'topg', data, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - rcode = pio_inq_varid(pioid, 'topg', varid) - call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) - Sg_topo(ns)%ptr(:) = data(:) - - call pio_closefile(pioid) - call pio_freedecomp(pio_subsystem, pio_iodesc) + do ns = 1,num_icesheets + + ! Create module level field bundle + fldbun_noevolve = ESMF_FieldBundleCreate(rc=rc) ! input field bundle + + ! "ice thickness" ; + field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! "bed topography" ; + field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Get mesh info + call ESMF_MeshGet(model_meshes(ns), 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(gindex(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Create pioid and pio_iodesc at the module level + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(input_files(ns)), pio_nowrite) + rcode = pio_inq_varid(pioid, 'thk', varid) + rcode = pio_inq_varndims(pioid, varid, ndims) + allocate(dimid(ndims)) + rcode = pio_inq_vardimid(pioid, varid, dimid(1:ndims)) + rcode = pio_inq_dimlen(pioid, dimid(1), nxg) + rcode = pio_inq_dimlen(pioid, dimid(2), nyg) + call pio_initdecomp(pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) + deallocate(gindex) + + ! Read in the data into the appropriate field bundle pointers + ! Note that Sg_ice_covered(ns)%ptr points into the data for + ! the Sg_ice_covered field in NStateExp(ns) + ! Note that Sg_topo(ns)%ptr points into the data for + ! the Sg_topon NStateExp(ns) + + call dshr_fldbun_getFldPtr(fldbun_noevolve, 'thk', data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + rcode = pio_inq_varid(pioid, 'thk', varid) + call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) + Sg_ice_covered(ns)%ptr(:) = data(:) + + call dshr_fldbun_getFldPtr(fldbun_noevolve, 'topg', data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + rcode = pio_inq_varid(pioid, 'topg', varid) + call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) + Sg_topo(ns)%ptr(:) = data(:) + + call pio_closefile(pioid) + call pio_freedecomp(pio_subsystem, pio_iodesc) + + end do ! end loop over ice sheets end subroutine dglc_datamode_noevolve_advance diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 586404a35..428c77086 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -29,7 +29,7 @@ module cdeps_dglc_comp use shr_sys_mod , only : shr_sys_abort use shr_cal_mod , only : shr_cal_ymd2date use shr_log_mod , only : shr_log_setLogUnit - use shr_string_mod , only : shr_string_listgetnum + use shr_string_mod , only : shr_string_listGetNum, shr_string_listGetName use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_init_from_config @@ -58,33 +58,38 @@ module cdeps_dglc_comp ! Private module data !-------------------------------------------------------------------------- + integer, parameter :: max_icesheets = 10 ! maximum number of ice sheets for namelist input + integer :: num_icesheets = 0 ! actual number of ice sheets + + ! namelist input + character(CS) :: icesheet_names(max_icesheets) + character(CL) :: model_meshfiles(max_icesheets) + character(CL) :: model_datafiles(max_icesheets) + integer :: nx_global(max_icesheets) + integer :: ny_global(max_icesheets) + ! module variables for multiple ice sheets type(shr_strdata_type) , allocatable :: sdat(:) type(ESMF_State) , allocatable :: NStateImp(:) type(ESMF_State) , allocatable :: NStateExp(:) type(ESMF_Mesh) , allocatable :: model_meshes(:) - character(CL) , allocatable :: model_meshfiles(:) - character(CS) , allocatable :: icesheet_names(:) - integer , allocatable :: nx_global(:) - integer , allocatable :: ny_global(:) ! module variables common to all data models - character(CS) :: flds_scalar_name = '' - integer :: flds_scalar_num = 0 - integer :: flds_scalar_index_nx = 0 - integer :: flds_scalar_index_ny = 0 - integer :: mpicom ! mpi communicator - integer :: my_task ! my task in mpi communicator mpicom - logical :: mainproc ! true of my_task == main_task - character(len=16) :: inst_suffix = "" ! char string associated with instance (ie. "_0001" or "") - integer :: logunit ! logging unit number - logical :: restart_read ! start from restart - character(CL) :: case_name - character(*) , parameter :: nullstr = 'null' + character(CS) :: flds_scalar_name = '' + integer :: flds_scalar_num = 0 + integer :: flds_scalar_index_nx = 0 + integer :: flds_scalar_index_ny = 0 + integer :: mpicom ! mpi communicator + integer :: my_task ! my task in mpi communicator mpicom + logical :: mainproc ! true of my_task == main_task + character(len=16) :: inst_suffix = "" ! char string associated with instance (ie. "_0001" or "") + integer :: logunit ! logging unit number + logical :: restart_read ! start from restart + character(CL) :: case_name + character(*) , parameter :: nullstr = 'null' ! dglc_in namelist input - integer :: num_icesheets = 0 - character(ESMF_MAXSTR) :: model_meshfiles_list ! colon separated string containing model meshfiles + character(CL) :: streamfilename = nullstr ! filename to obtain stream info from character(CL) :: nlfilename = nullstr ! filename to obtain namelist info from character(CL) :: datamode = nullstr ! flags physics options wrt input data @@ -180,14 +185,18 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: bcasttmp(1) integer :: ns, n character(len=CS) :: cnum + character(len=CL) :: icesheets_list + character(len=ESMF_MAXSTR) :: model_datafiles_list ! colon separated string containing input datafiles + character(len=ESMF_MAXSTR) :: model_meshfiles_list ! colon separated string containing model meshfiles character(len=*),parameter :: subname=trim(module_name)//':(InitializeAdvertise) ' !------------------------------------------------------------------------------- !icesheet_names = "ais", "gris" !num_icesheets = 2 + ! Note that the suffix '-list' refers to a colon delimited string of names namelist / dglc_nml / datamode, & - ice_sheet_names, model_meshfiles_list, nx_global, ny_global, & + icesheets_list, model_meshfiles_list, model_datafiles_list, nx_global, ny_global, & restfilm, skip_restart_read rc = ESMF_SUCCESS @@ -206,36 +215,44 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Read dglc_nml from nlfilename if (my_task == main_task) then - nlfilename = "dglc_in"//trim(inst_suffix) - open (newunit=nu,file=trim(nlfilename),status="old",action="read") - call shr_nl_find_group_name(nu, 'dglc_nml', status=ierr) - read (nu,nml=dglc_nml,iostat=ierr) - close(nu) - if (ierr > 0) then - write(logunit,'(a,i8)') 'ERROR: reading input namelist, '//trim(nlfilename)//' iostat=',ierr - call shr_sys_abort(subName//': namelist read error '//trim(nlfilename)) - end if - - ! write namelist input to standard out - write(logunit,'(a,a)')' case_name = ',trim(case_name) - write(logunit,'(a,a)')' datamode = ',trim(datamode) - - num_icesheets = shr_string_listGetNum(model_meshfiles_list) - do ns = 1,num_icesheets - ! determine mesh filename - call shr_string_listGetName(model_meshfiles_list, ns, model_meshfile(ns)) - write(logunit,'(a,i4 )')' ice_sheet index = ',ns - write(logunit,'(a,a )')' model_meshfile = ',trim(model_meshfiles(ns)) - write(logunit,'(a,i10)')' nx_global = ',nx_global(ns) - write(logunit,'(a,i10)')' ny_global = ',ny_global(ns) - end do - write(logunit,'(a,a )')' restfilm = ',trim(restfilm) - write(logunit,'(a,l6)')' skip_restart_read = ',skip_restart_read - if (skip_restart_read) then - bcasttmp = 1 - else - bcasttmp = 0 - end if + nlfilename = "dglc_in"//trim(inst_suffix) + open (newunit=nu,file=trim(nlfilename),status="old",action="read") + call shr_nl_find_group_name(nu, 'dglc_nml', status=ierr) + read (nu,nml=dglc_nml,iostat=ierr) + close(nu) + if (ierr > 0) then + write(logunit,'(a,i8)') 'ERROR: reading input namelist, '//trim(nlfilename)//' iostat=',ierr + call shr_sys_abort(subName//': namelist read error '//trim(nlfilename)) + end if + + ! Determine number of ice sheets + num_icesheets = shr_string_listGetNum(model_meshfiles_list) + + ! Determine array of model meshfile(s) and model input datafile(s) + do ns = 1,num_icesheets + ! determine mesh filename(s) + call shr_string_listGetName(model_meshfiles_list, ns, model_meshfiles(ns)) + ! determine input datafile name(s) + call shr_string_listGetName(model_datafiles_list, ns, model_datafiles(ns)) + end do + if (skip_restart_read) then + bcasttmp = 1 + else + bcasttmp = 0 + end if + + ! Write diagnostics + write(logunit,'(a,a)')' case_name = ',trim(case_name) + write(logunit,'(a,a)')' datamode = ',trim(datamode) + do ns = 1,num_icesheets + write(logunit,'(a,i4 )')' ice_sheet index = ',ns + write(logunit,'(a,a )')' model_meshfile = ',trim(model_meshfiles(ns)) + write(logunit,'(a,a )')' model_datafile = ',trim(model_datafiles(ns)) + write(logunit,'(a,i10)')' nx_global = ',nx_global(ns) + write(logunit,'(a,i10)')' ny_global = ',ny_global(ns) + end do + write(logunit,'(a,a )')' restfilm = ',trim(restfilm) + write(logunit,'(a,l6)')' skip_restart_read = ',skip_restart_read endif ! Broadcast namelist input @@ -246,52 +263,54 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call ESMF_VMBroadcast(vm, restfilm, CL, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do ns = 1,num_icesheets - call ESMF_VMBroadcast(vm, model_meshfiles(ns), CL, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMBroadcast(vm, nx_global(ns), 1, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMBroadcast(vm, ny_global(ns), 1, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, model_meshfiles(ns), CL, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + bcasttmp(1) = nx_global(ns) + call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + bcasttmp(1) = ny_global(ns) + call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end do call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Validate datamode if ( trim(datamode) == 'noevolve') then ! read stream, no import data - ! do nothing + ! do nothing else - call shr_sys_abort(' ERROR illegal dglc datamode = '//trim(datamode)) + call shr_sys_abort(' ERROR illegal dglc datamode = '//trim(datamode)) endif ! Allocate module variables + allocate(sdat(num_icesheets)) allocate(NStateImp(num_icesheets)) allocate(NStateExp(num_icesheets)) - allocate(sdat(num_icesheets)) allocate(model_meshes(num_icesheets)) - allocate(dfields_icesheets(num_icesheets)) ! Create nested states do ns = 1,num_icesheets - write(cnum,'(i0)') ns - call NUOPC_AddNestedState(importState, CplSet="GLC"//trim(cnum), nestedState=NStateImp(ns), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_AddNestedState(exportState, CplSet="GLC"//trim(cnum), nestedState=NStateExp(ns), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(cnum,'(i0)') ns + call NUOPC_AddNestedState(importState, CplSet="GLC"//trim(cnum), nestedState=NStateImp(ns), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_AddNestedState(exportState, CplSet="GLC"//trim(cnum), nestedState=NStateExp(ns), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end do ! Advertise dglc fields if (trim(datamode)=='noevolve') then - call dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_name, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_name, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end subroutine InitializeAdvertise !=============================================================================== - subroutine InitializeRealize(gcomp, clock, rc) + subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! input/output variables type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: importState, exportState type(ESMF_Clock) :: clock integer, intent(out) :: rc @@ -337,60 +356,11 @@ subroutine InitializeRealize(gcomp, clock, rc) call NUOPC_CompAttributeGet(gcomp, name='read_restart', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then - read(cvalue,*) read_restart + read(cvalue,*) read_restart else - call shr_sys_abort(subname//' ERROR: read restart flag must be present') + call shr_sys_abort(subname//' ERROR: read restart flag must be present') end if - ! Loop over ice sheets - do ns = 1,num_icesheets - - write(cns,'(i0)') ns - - ! Initialize pio subsystem -#ifdef CESMCOUPLED - sdat(ns)%pio_subsystem => shr_pio_getiosys('GLC') - sdat(ns)%io_type = shr_pio_getiotype('GLC') - sdat(ns)%io_format = shr_pio_getioformat('GLC') -#else - call dshr_pio_init(gcomp, sdat(ns), logunit, rc) -#endif - - ! Check that model_meshfile exists - if (my_task == main_task) then - inquire(file=trim(model_meshfiles(ns)), exist=exists) - if (.not.exists) then - write(logunit,'(a)')' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist' - call shr_sys_abort(trim(subname)//' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist') - end if - endif - - ! Read in model mesh - model_meshes(ns) = ESMF_MeshCreate(trim(model_meshfiles(ns)), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Initialize stream data type - if (trim(datamode) /= 'noevolve') then - call shr_strdata_init_from_config(sdat(ns), streamfilename, model_meshes(ns), clock, 'GLC', logunit, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - call ESMF_TraceRegionExit('dglc_strdata_init') - - ! Realize the actively coupled fields, now that a mesh is established and - ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState - ! by replacing the advertised fields with the newly created fields of the same name. - - call dshr_fldlist_realize( NStateExp(ns), fldsExport, flds_scalar_name, flds_scalar_num, model_mesh(ns), & - subname//trim(modelname)//':Export', export_all, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call dshr_fldlist_realize( NStateImp(ns), fldsImport, flds_scalar_name, flds_scalar_num, model_mesh(ns), & - subname//trim(modelname)//':Import', .false., rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - end do ! loop over ice sheets - ! Get the time to interpolate the stream data to call ESMF_ClockGet(clock, currTime=currTime, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -398,24 +368,68 @@ subroutine InitializeRealize(gcomp, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call shr_cal_ymd2date(current_year, current_mon, current_day, current_ymd) - ! loop over ice sheets + ! Loop over ice sheets do ns = 1,num_icesheets - ! Run dglc - call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Add scalars to export state - call dshr_state_SetScalar(dble(nx_global(ns)),flds_scalar_index_nx, & - NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call dshr_state_SetScalar(dble(ny_global(ns)),flds_scalar_index_ny,& - NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(cns,'(i0)') ns + + ! Initialize pio subsystem +#ifdef CESMCOUPLED + sdat(ns)%pio_subsystem => shr_pio_getiosys('GLC') + sdat(ns)%io_type = shr_pio_getiotype('GLC') + sdat(ns)%io_format = shr_pio_getioformat('GLC') +#else + call dshr_pio_init(gcomp, sdat(ns), logunit, rc) +#endif + + ! Check that model_meshfile exists + if (my_task == main_task) then + inquire(file=trim(model_meshfiles(ns)), exist=exists) + if (.not.exists) then + write(logunit,'(a)')' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist' + call shr_sys_abort(trim(subname)//' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist') + end if + endif + + ! Read in model mesh for given ice sheet + model_meshes(ns) = ESMF_MeshCreate(trim(model_meshfiles(ns)), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Initialize stream data type + if (trim(datamode) /= 'noevolve') then + call shr_strdata_init_from_config(sdat(ns), streamfilename, model_meshes(ns), clock, 'GLC', logunit, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + call ESMF_TraceRegionExit('dglc_strdata_init') + + ! Realize the actively coupled fields, now that a mesh is established and + ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState + ! by replacing the advertised fields with the newly created fields of the same name. + + call dshr_fldlist_realize( NStateExp(ns), fldsExport, flds_scalar_name, flds_scalar_num, model_meshes(ns), & + subname//trim(modelname)//':Export', export_all, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call dshr_fldlist_realize( NStateImp(ns), fldsImport, flds_scalar_name, flds_scalar_num, model_meshes(ns), & + subname//trim(modelname)//':Import', .false., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Run dglc + call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Add scalars to export state + call dshr_state_SetScalar(dble(nx_global(ns)),flds_scalar_index_nx, & + NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_SetScalar(dble(ny_global(ns)),flds_scalar_index_ny,& + NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end do call ESMF_VMLogMemInfo("Leaving "//trim(subname)) - end subroutine InitializeRealize + end subroutine InitializeRealize !=============================================================================== subroutine ModelAdvance(gcomp, rc) @@ -490,95 +504,100 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) call ESMF_TraceRegionEnter('DGLC_RUN') - ! Loop over ice sheets - do ns = 1,size(NStateExp) - - !-------------------- - ! First time initialization - !-------------------- - - if (first_time) then - ! Initialize dfields for given ice sheet - if (trim(datamode) /= 'noevolve') then - call dglc_init_dfields(ns, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! Initialize datamode module ponters - select case (trim(datamode)) - case('noevolve') - call dglc_datamode_copyall_init_pointers(NStateExp(ns), rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end select - - ! Read restart if needed - if (trim(datamode) /= 'noevolve') then - if (restart_read .and. .not. skip_restart_read) then - ! placeholder for future datamodes - end if - end if + !-------------------- + ! First time initialization + !-------------------- + + if (first_time) then + ! Initialize dfields for all ice sheets + if (trim(datamode) /= 'noevolve') then + call dglc_init_dfields(rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! Initialize datamode module ponters + select case (trim(datamode)) + case('noevolve') + call dglc_datamode_copyall_init_pointers(NStateExp(ns), rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end select + + ! Read restart if needed + if (trim(datamode) /= 'noevolve') then + if (restart_read .and. .not. skip_restart_read) then + ! placeholder for future datamodes + end if + end if + + ! Reset first_time + first_time = .false. + end if - ! Reset first_time - first_time = .false. - end if - - !-------------------- - ! Update export (and possibly import data model states) - !-------------------- - - if (trim(datamode) /= 'noevolve') then - ! Advance data model streams - time and spatially interpolate to model time and grid - call ESMF_TraceRegionEnter('dglc_strdata_advance') - call shr_strdata_advance(sdat(ns), target_ymd, target_tod, logunit, 'dglc', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TraceRegionExit('dglc_strdata_advance') - - ! Copy all fields from streams to export state as default - ! This automatically will update the fields in the export state - call ESMF_TraceRegionEnter('dglc_dfield_copy') - call dshr_dfield_copy(dfields_icesheets(ns)%dfields, sdat(ns), rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TraceRegionExit('dglc_dfield_copy') - end if - - ! Perform data mode specific calculations - select case (trim(datamode)) - case('noevolve') - call dglc_datamode_noevolve_advance(rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end select - - ! Write restarts if needed - if (restart_write) then - if (trim(datamode) /= 'evolve') then - ! this is a place holder for future datamode - end if - end if + !-------------------- + ! Update export (and possibly import data model states) + !-------------------- + + if (trim(datamode) /= 'noevolve') then + if (.not. allocated(dfields_icesheets)) then + allocate(dfields_icesheets(num_icesheets)) + end if + + ! Loop over ice sheets + do ns = 1,num_icesheets + ! Advance data model streams - time and spatially interpolate to model time and grid + ! Note that loop over ice sheets is done inside shr_strdata_advance + call ESMF_TraceRegionEnter('dglc_strdata_advance') + call shr_strdata_advance(sdat(ns), target_ymd, target_tod, logunit, 'dglc', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit('dglc_strdata_advance') + + ! Copy all fields from streams to export state as default + ! This automatically will update the fields in the export state + call ESMF_TraceRegionEnter('dglc_dfield_copy') + call dshr_dfield_copy(dfields_icesheets(ns)%dfields, sdat(ns), rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit('dglc_dfield_copy') + end do + end if - ! Write diagnostics - if (diagnose_data) then - write(cnum,'(i0)') ns - call dshr_state_diagnose(NStateExp, flds_scalar_name, trim(subname)//':ES_'//trim(cnum), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + ! Perform data mode specific calculations + select case (trim(datamode)) + case('noevolve') + call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, & + model_meshes, model_datafiles, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end select + + ! Write restarts if needed + if (restart_write) then + if (trim(datamode) /= 'evolve') then + ! this is a place holder for future datamode + end if + end if - end do ! end of loop over ice sheets + ! Write diagnostics + if (diagnose_data) then + do ns = 1,num_icesheets + write(cnum,'(i0)') ns + call dshr_state_diagnose(NStateExp(ns), flds_scalar_name, trim(subname)//':ES_'//trim(cnum), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + end if call ESMF_TraceRegionExit('DGLC_RUN') contains - subroutine dglc_init_dfields(ns, rc) + subroutine dglc_init_dfields(rc) ! ----------------------------- ! Initialize dfields arrays ! ----------------------------- ! input/output variables - integer , intent(in) :: ns ! ice sheet index - integer , intent(out) :: rc + integer, intent(out) :: rc ! local variables - integer :: n + integer :: nf, ns integer :: fieldcount type(ESMF_Field) :: lfield character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) @@ -587,21 +606,25 @@ subroutine dglc_init_dfields(ns, rc) rc = ESMF_SUCCESS + ! Loop over ice sheets ! Initialize dfields data type (to map streams to export state fields) ! Create dfields linked list - used for copying stream fields to export state fields - call ESMF_StateGet(NStateExp(ns), itemCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(lfieldnamelist(fieldCount)) - call ESMF_StateGet(NStateExp(ns), itemNameList=lfieldnamelist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - call ESMF_StateGet(NStateExp(ns), itemName=trim(lfieldNameList(n)), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (trim(lfieldnamelist(n)) /= flds_scalar_name) then - call dshr_dfield_add( dfields, sdat(ns), trim(lfieldnamelist(n)), trim(lfieldnamelist(n)), NStateExp(ns), & - logunit, mainproc, rc) + do ns = 1,num_icesheets + call ESMF_StateGet(NStateExp(ns), itemCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(lfieldnamelist(fieldCount)) + call ESMF_StateGet(NStateExp(ns), itemNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nf = 1, fieldCount + call ESMF_StateGet(NStateExp(ns), itemName=trim(lfieldNameList(nf)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (trim(lfieldnamelist(nf)) /= flds_scalar_name) then + call dshr_dfield_add( dfields_icesheets(ns)%dfields, sdat(ns), & + trim(lfieldnamelist(nf)), trim(lfieldnamelist(nf)), NStateExp(ns), logunit, mainproc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + end if + end do + deallocate(lfieldnamelist) end do end subroutine dglc_init_dfields @@ -614,9 +637,9 @@ subroutine ModelFinalize(gcomp, rc) !------------------------------------------------------------------------------- rc = ESMF_SUCCESS if (my_task == main_task) then - write(logunit,*) - write(logunit,*) 'dglc : end of main integration loop' - write(logunit,*) + write(logunit,*) + write(logunit,*) 'dglc : end of main integration loop' + write(logunit,*) end if end subroutine ModelFinalize From d7e590d151b84c79a934547d936262a34846b370 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 20 Mar 2024 12:26:57 +0100 Subject: [PATCH 047/170] more compilation fixes --- cime_config/buildlib | 2 +- cime_config/buildlib_comps | 2 ++ dglc/dglc_datamode_noevolve_mod.F90 | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cime_config/buildlib b/cime_config/buildlib index a692a4e50..2da096a7a 100755 --- a/cime_config/buildlib +++ b/cime_config/buildlib @@ -184,7 +184,7 @@ def buildlib(bldroot, libroot, case): expect(False, nextline) # Link the CDEPS component directories to the location expected by cime - for comp in ("atm", "lnd", "ice", "ocn", "rof", "wav"): + for comp in ("atm", "glc", "lnd", "ice", "ocn", "rof", "wav"): compname = case.get_value("COMP_{}".format(comp.upper())) comppath = os.path.join(case.get_value("EXEROOT"), comp, "obj") if compname == "d" + comp: diff --git a/cime_config/buildlib_comps b/cime_config/buildlib_comps index 281f0d4e9..1366a4cfe 100755 --- a/cime_config/buildlib_comps +++ b/cime_config/buildlib_comps @@ -33,7 +33,9 @@ def buildlib(bldroot, libroot, case, compname=None): ) compname = os.path.basename(os.path.abspath(os.path.join(bldroot, os.pardir))) + print("DEBUG: here3") _, o, e = run_cmd("make d{}".format(compname), from_dir=bldroot, verbose=True) + print("DEBUG: here4") libname = "lib{}.a".format(compname) dlibname = "libd{}.a".format(compname) dlibpath = os.path.join(bldroot, dlibname) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 03ba9d4b3..b6cc8dcb6 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -14,6 +14,7 @@ module dglc_datamode_noevolve_mod use pio , only : pio_openfile, pio_inq_varid, pio_inq_varndims, pio_inq_vardimid use pio , only : pio_inq_dimlen, pio_initdecomp, pio_read_darray, pio_double use pio , only : pio_closefile, pio_freedecomp, PIO_BCAST_ERROR, PIO_NOWRITE + use pio , only : pio_seterrorhandling implicit none private ! except From f60351789350d2937821cec10e1976905f4e9e45 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 20 Mar 2024 15:16:14 +0100 Subject: [PATCH 048/170] fixes to for advertise and realize --- dglc/cime_config/buildlib | 1 + dglc/cime_config/namelist_definition_dglc.xml | 4 +- dglc/glc_comp_nuopc.F90 | 103 +++++++++--------- 3 files changed, 54 insertions(+), 54 deletions(-) create mode 120000 dglc/cime_config/buildlib diff --git a/dglc/cime_config/buildlib b/dglc/cime_config/buildlib new file mode 120000 index 000000000..0c5e984ac --- /dev/null +++ b/dglc/cime_config/buildlib @@ -0,0 +1 @@ +../../cime_config/buildlib_comps \ No newline at end of file diff --git a/dglc/cime_config/namelist_definition_dglc.xml b/dglc/cime_config/namelist_definition_dglc.xml index 0041e88af..b2ede04bc 100644 --- a/dglc/cime_config/namelist_definition_dglc.xml +++ b/dglc/cime_config/namelist_definition_dglc.xml @@ -35,7 +35,7 @@ - + char streams abs @@ -51,7 +51,7 @@ - + char streams abs diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 428c77086..31f249f8c 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -39,9 +39,9 @@ module cdeps_dglc_comp use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_realize ! Datamode specialized modules - use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_advertise - use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_init_pointers - use dglc_datamode_noevolve_mod , only : dglc_datamode_noevolve_advance + use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_advertise + use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_init_pointers + use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_advance implicit none private ! except @@ -58,15 +58,16 @@ module cdeps_dglc_comp ! Private module data !-------------------------------------------------------------------------- - integer, parameter :: max_icesheets = 10 ! maximum number of ice sheets for namelist input - integer :: num_icesheets = 0 ! actual number of ice sheets + character(*) , parameter :: nullstr = 'null' + integer , parameter :: max_icesheets = 10 ! maximum number of ice sheets for namelist input + integer :: num_icesheets ! actual number of ice sheets ! namelist input - character(CS) :: icesheet_names(max_icesheets) - character(CL) :: model_meshfiles(max_icesheets) - character(CL) :: model_datafiles(max_icesheets) - integer :: nx_global(max_icesheets) - integer :: ny_global(max_icesheets) + character(CS) :: icesheet_names(max_icesheets) = nullstr + character(CL) :: model_meshfiles(max_icesheets) = nullstr + character(CL) :: model_datafiles(max_icesheets) = nullstr + integer :: nx_global(max_icesheets) = 0 + integer :: ny_global(max_icesheets) = 0 ! module variables for multiple ice sheets type(shr_strdata_type) , allocatable :: sdat(:) @@ -75,27 +76,25 @@ module cdeps_dglc_comp type(ESMF_Mesh) , allocatable :: model_meshes(:) ! module variables common to all data models - character(CS) :: flds_scalar_name = '' - integer :: flds_scalar_num = 0 - integer :: flds_scalar_index_nx = 0 - integer :: flds_scalar_index_ny = 0 - integer :: mpicom ! mpi communicator - integer :: my_task ! my task in mpi communicator mpicom - logical :: mainproc ! true of my_task == main_task - character(len=16) :: inst_suffix = "" ! char string associated with instance (ie. "_0001" or "") - integer :: logunit ! logging unit number - logical :: restart_read ! start from restart - character(CL) :: case_name - character(*) , parameter :: nullstr = 'null' + character(CS) :: flds_scalar_name = '' + integer :: flds_scalar_num = 0 + integer :: flds_scalar_index_nx = 0 + integer :: flds_scalar_index_ny = 0 + integer :: mpicom ! mpi communicator + integer :: my_task ! my task in mpi communicator mpicom + logical :: mainproc ! true of my_task == main_task + character(len=16) :: inst_suffix = "" ! char string associated with instance (ie. "_0001" or "") + integer :: logunit ! logging unit number + logical :: restart_read ! start from restart + character(CL) :: case_name ! dglc_in namelist input - - character(CL) :: streamfilename = nullstr ! filename to obtain stream info from - character(CL) :: nlfilename = nullstr ! filename to obtain namelist info from - character(CL) :: datamode = nullstr ! flags physics options wrt input data - character(CL) :: restfilm = nullstr ! model restart file namelist - logical :: skip_restart_read = .false. ! true => skip restart read in continuation run - logical :: export_all = .false. ! true => export all fields, do not check connected or not + character(CL) :: streamfilename = nullstr ! filename to obtain stream info from + character(CL) :: nlfilename = nullstr ! filename to obtain namelist info from + character(CL) :: datamode = nullstr ! flags physics options wrt input data + character(CL) :: restfilm = nullstr ! model restart file namelist + logical :: skip_restart_read = .false. ! true => skip restart read in continuation run + logical :: export_all = .false. ! true => export all fields, do not check connected or not ! linked lists type(fldList_type) , pointer :: fldsImport => null() @@ -191,9 +190,6 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) character(len=*),parameter :: subname=trim(module_name)//':(InitializeAdvertise) ' !------------------------------------------------------------------------------- - !icesheet_names = "ais", "gris" - !num_icesheets = 2 - ! Note that the suffix '-list' refers to a colon delimited string of names namelist / dglc_nml / datamode, & icesheets_list, model_meshfiles_list, model_datafiles_list, nx_global, ny_global, & @@ -235,11 +231,6 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! determine input datafile name(s) call shr_string_listGetName(model_datafiles_list, ns, model_datafiles(ns)) end do - if (skip_restart_read) then - bcasttmp = 1 - else - bcasttmp = 0 - end if ! Write diagnostics write(logunit,'(a,a)')' case_name = ',trim(case_name) @@ -253,6 +244,9 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) end do write(logunit,'(a,a )')' restfilm = ',trim(restfilm) write(logunit,'(a,l6)')' skip_restart_read = ',skip_restart_read + + bcasttmp(1) = 0 + if(skip_restart_read) bcasttmp(1) = 1 endif ! Broadcast namelist input @@ -262,18 +256,23 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, restfilm, CL, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do ns = 1,num_icesheets - call ESMF_VMBroadcast(vm, model_meshfiles(ns), CL, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - bcasttmp(1) = nx_global(ns) - call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - bcasttmp(1) = ny_global(ns) - call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end do + call ESMF_VMBroadcast(vm, model_meshfiles, CL*max_icesheets, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, nx_global, max_icesheets, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, ny_global, max_icesheets, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Set number of ice sheets for all mpi tasks + bcasttmp(1) = num_icesheets + call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + num_icesheets = bcasttmp(1) + + ! Determine if will skip restart read for all mpi tasks call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + skip_restart_read = (bcasttmp(1) == 1) ! Validate datamode if ( trim(datamode) == 'noevolve') then ! read stream, no import data @@ -333,9 +332,9 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) !------------------------------------------------------------------------------- rc = ESMF_SUCCESS - call ESMF_VMLogMemInfo("Entering "//trim(subname)) ! Initialize model mesh, restart flag, logunit, model_mask and model_frac + call ESMF_VMLogMemInfo("Entering "//trim(subname)) call ESMF_TraceRegionEnter('dglc_strdata_init') ! Determine stream filename @@ -400,8 +399,6 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - call ESMF_TraceRegionExit('dglc_strdata_init') - ! Realize the actively coupled fields, now that a mesh is established and ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState ! by replacing the advertised fields with the newly created fields of the same name. @@ -425,8 +422,10 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) call dshr_state_SetScalar(dble(ny_global(ns)),flds_scalar_index_ny,& NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - end do + end do ! end loop over ice sheets + + call ESMF_TraceRegionExit('dglc_strdata_init') call ESMF_VMLogMemInfo("Leaving "//trim(subname)) end subroutine InitializeRealize @@ -518,7 +517,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) ! Initialize datamode module ponters select case (trim(datamode)) case('noevolve') - call dglc_datamode_copyall_init_pointers(NStateExp(ns), rc) + call dglc_datamode_noevolve_init_pointers(NStateExp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select From ececaaa7bc7c927e58a291ebad63a57056991bb7 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 20 Mar 2024 16:25:27 +0100 Subject: [PATCH 049/170] finished advertise and realize phases --- dglc/dglc_datamode_noevolve_mod.F90 | 20 ++++++++++---------- dglc/glc_comp_nuopc.F90 | 2 +- dshr/dshr_fldlist_mod.F90 | 3 +++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index b6cc8dcb6..10a2cbb38 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -69,6 +69,7 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_n ! local variables integer :: ns logical :: isPresent, isSet + character(len=CS) :: cnum type(fldlist_type), pointer :: fldList !------------------------------------------------------------------------------- @@ -86,18 +87,17 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_n call dshr_fldList_add(fldsExport, field_out_ice_covered) call dshr_fldList_add(fldsExport, field_out_topo) call dshr_fldList_add(fldsExport, field_out_icemask) - Call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) + call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) do ns = 1,num_icesheets - fldlist => fldsExport ! the head of the linked list - do while (associated(fldlist)) - call NUOPC_Advertise(NStateExp(ns), standardName=fldlist%stdname, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (ns == 1) then - call ESMF_LogWrite('(dglc_comp_advertise): Fr_glc'//trim(fldList%stdname), ESMF_LOGMSG_INFO) - end if - fldList => fldList%next - end do + write(cnum,'(i0)') ns + fldlist => fldsExport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(NStateExp(ns), standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite('(dglc_comp_advertise): Fr_glc'//trim(cnum)//"_"//trim(fldList%stdname), ESMF_LOGMSG_INFO) + fldList => fldList%next + end do enddo end subroutine dglc_datamode_noevolve_advertise diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 31f249f8c..fca0f92eb 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -19,7 +19,7 @@ module cdeps_dglc_comp use ESMF , only : ESMF_MeshCreate, ESMF_FILEFORMAT_ESMFMESH use NUOPC , only : NUOPC_CompDerive, NUOPC_CompSetEntryPoint, NUOPC_CompSpecialize use NUOPC , only : NUOPC_Advertise, NUOPC_CompAttributeGet, NUOPC_CompAttributeSet - use NUOPC , only : NUOPC_AddNestedState + use NUOPC , only : NUOPC_AddNestedState, NUOPC_IsConnected use NUOPC_Model , only : model_routine_SS => SetServices use NUOPC_Model , only : model_label_Advance => label_Advance use NUOPC_Model , only : model_label_SetRunClock => label_SetRunClock diff --git a/dshr/dshr_fldlist_mod.F90 b/dshr/dshr_fldlist_mod.F90 index 398e1ce61..d35a6d073 100644 --- a/dshr/dshr_fldlist_mod.F90 +++ b/dshr/dshr_fldlist_mod.F90 @@ -77,8 +77,11 @@ subroutine dshr_fldlist_realize(state, fldLists, flds_scalar_name, flds_scalar_n fldList => fldLists ! note that fldlists is the head of the linked list do while (associated(fldList)) stdname = fldList%stdname + write(6,*)'DEBUG: stdname is ',trim(stdname) if (NUOPC_IsConnected(state, fieldName=stdname) .or. export_all) then + write(6,*)'DEBUG: field '//trim(stdname)//' is connected ' + ! Check field name since linked list might have empty string if (trim(stdname) == '') then fldList => fldList%next From aa6a9e934357a8f69f2b4ed2ef24e14d674150b3 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 20 Mar 2024 19:12:58 +0100 Subject: [PATCH 050/170] now in run phase --- cime_config/buildlib_comps | 2 - dglc/dglc_datamode_noevolve_mod.F90 | 4 +- dglc/glc_comp_nuopc.F90 | 103 ++++++++++++++-------------- dshr/dshr_fldlist_mod.F90 | 2 - streams/dshr_methods_mod.F90 | 5 +- 5 files changed, 60 insertions(+), 56 deletions(-) diff --git a/cime_config/buildlib_comps b/cime_config/buildlib_comps index 1366a4cfe..281f0d4e9 100755 --- a/cime_config/buildlib_comps +++ b/cime_config/buildlib_comps @@ -33,9 +33,7 @@ def buildlib(bldroot, libroot, case, compname=None): ) compname = os.path.basename(os.path.abspath(os.path.join(bldroot, os.pardir))) - print("DEBUG: here3") _, o, e = run_cmd("make d{}".format(compname), from_dir=bldroot, verbose=True) - print("DEBUG: here4") libname = "lib{}.a".format(compname) dlibname = "libd{}.a".format(compname) dlibpath = os.path.join(bldroot, dlibname) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 10a2cbb38..e3843536a 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -128,8 +128,10 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, rc) do ns = 1,num_icesheets call dshr_state_getfldptr(NStateExp(ns), 'Sg_topo' , fldptr1=Sg_topo(ns)%ptr , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(NStateExp(ns), 'Sg_ice_covered' , fldptr1=Sg_ice_covered(ns)%ptr , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(NStateExp(ns), 'Sg_icemask' , fldptr1=Sg_icemask(ns)%ptr , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end do @@ -197,8 +199,8 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Create pioid and pio_iodesc at the module level - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(input_files(ns)), pio_nowrite) + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) rcode = pio_inq_varid(pioid, 'thk', varid) rcode = pio_inq_varndims(pioid, varid, ndims) allocate(dimid(ndims)) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index fca0f92eb..9bc423f28 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -355,9 +355,9 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) call NUOPC_CompAttributeGet(gcomp, name='read_restart', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then - read(cvalue,*) read_restart + read(cvalue,*) read_restart else - call shr_sys_abort(subname//' ERROR: read restart flag must be present') + call shr_sys_abort(subname//' ERROR: read restart flag must be present') end if ! Get the time to interpolate the stream data to @@ -369,62 +369,65 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! Loop over ice sheets do ns = 1,num_icesheets - write(cns,'(i0)') ns - ! Initialize pio subsystem + write(cns,'(i0)') ns + + ! Initialize pio subsystem #ifdef CESMCOUPLED - sdat(ns)%pio_subsystem => shr_pio_getiosys('GLC') - sdat(ns)%io_type = shr_pio_getiotype('GLC') - sdat(ns)%io_format = shr_pio_getioformat('GLC') + sdat(ns)%pio_subsystem => shr_pio_getiosys('GLC') + sdat(ns)%io_type = shr_pio_getiotype('GLC') + sdat(ns)%io_format = shr_pio_getioformat('GLC') #else - call dshr_pio_init(gcomp, sdat(ns), logunit, rc) + call dshr_pio_init(gcomp, sdat(ns), logunit, rc) #endif - ! Check that model_meshfile exists - if (my_task == main_task) then - inquire(file=trim(model_meshfiles(ns)), exist=exists) - if (.not.exists) then - write(logunit,'(a)')' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist' - call shr_sys_abort(trim(subname)//' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist') - end if - endif - - ! Read in model mesh for given ice sheet - model_meshes(ns) = ESMF_MeshCreate(trim(model_meshfiles(ns)), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Initialize stream data type - if (trim(datamode) /= 'noevolve') then - call shr_strdata_init_from_config(sdat(ns), streamfilename, model_meshes(ns), clock, 'GLC', logunit, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! Realize the actively coupled fields, now that a mesh is established and - ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState - ! by replacing the advertised fields with the newly created fields of the same name. - - call dshr_fldlist_realize( NStateExp(ns), fldsExport, flds_scalar_name, flds_scalar_num, model_meshes(ns), & - subname//trim(modelname)//':Export', export_all, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call dshr_fldlist_realize( NStateImp(ns), fldsImport, flds_scalar_name, flds_scalar_num, model_meshes(ns), & - subname//trim(modelname)//':Import', .false., rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Run dglc - call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Add scalars to export state - call dshr_state_SetScalar(dble(nx_global(ns)),flds_scalar_index_nx, & - NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call dshr_state_SetScalar(dble(ny_global(ns)),flds_scalar_index_ny,& - NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Check that model_meshfile exists + if (my_task == main_task) then + inquire(file=trim(model_meshfiles(ns)), exist=exists) + if (.not.exists) then + write(logunit,'(a)')' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist' + call shr_sys_abort(trim(subname)//' ERROR: model_meshfile '//trim(model_meshfiles(ns))//' does not exist') + end if + endif + + ! Read in model mesh for given ice sheet + model_meshes(ns) = ESMF_MeshCreate(trim(model_meshfiles(ns)), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Initialize stream data type + if (trim(datamode) /= 'noevolve') then + call shr_strdata_init_from_config(sdat(ns), streamfilename, model_meshes(ns), clock, 'GLC', logunit, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! Realize the actively coupled fields, now that a mesh is established and + ! NUOPC_Realize "realizes" a previously advertised field in the importState and exportState + ! by replacing the advertised fields with the newly created fields of the same name. + + call ESMF_LogWrite(subname//' calling dshr_fldlist_realize export for ice sheet '//trim(cns), ESMF_LOGMSG_INFO) + call dshr_fldlist_realize( NStateExp(ns), fldsExport, flds_scalar_name, flds_scalar_num, model_meshes(ns), & + subname//trim(modelname)//':Export', export_all, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_LogWrite(subname//' calling dshr_fldlist_realize importfor ice sheet '//trim(cns), ESMF_LOGMSG_INFO) + call dshr_fldlist_realize( NStateImp(ns), fldsImport, flds_scalar_name, flds_scalar_num, model_meshes(ns), & + subname//trim(modelname)//':Import', .false., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Add scalars to export state + call dshr_state_SetScalar(dble(nx_global(ns)),flds_scalar_index_nx, & + NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_SetScalar(dble(ny_global(ns)),flds_scalar_index_ny,& + NStateExp(ns), flds_scalar_name, flds_scalar_num, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end do ! end loop over ice sheets + ! Run dglc + call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit('dglc_strdata_init') call ESMF_VMLogMemInfo("Leaving "//trim(subname)) diff --git a/dshr/dshr_fldlist_mod.F90 b/dshr/dshr_fldlist_mod.F90 index d35a6d073..a06912fc1 100644 --- a/dshr/dshr_fldlist_mod.F90 +++ b/dshr/dshr_fldlist_mod.F90 @@ -77,10 +77,8 @@ subroutine dshr_fldlist_realize(state, fldLists, flds_scalar_name, flds_scalar_n fldList => fldLists ! note that fldlists is the head of the linked list do while (associated(fldList)) stdname = fldList%stdname - write(6,*)'DEBUG: stdname is ',trim(stdname) if (NUOPC_IsConnected(state, fieldName=stdname) .or. export_all) then - write(6,*)'DEBUG: field '//trim(stdname)//' is connected ' ! Check field name since linked list might have empty string if (trim(stdname) == '') then diff --git a/streams/dshr_methods_mod.F90 b/streams/dshr_methods_mod.F90 index b1972f7c8..8e721bed1 100644 --- a/streams/dshr_methods_mod.F90 +++ b/streams/dshr_methods_mod.F90 @@ -541,6 +541,7 @@ subroutine dshr_field_getfldptr(field, fldptr1, fldptr2, rank, abort, rc) integer :: ungriddedUBound(1) integer :: lrank logical :: labort + character(len=CS) :: name character(len=*), parameter :: subname='(field_getfldptr)' ! ---------------------------------------------- rc = ESMF_SUCCESS @@ -554,7 +555,9 @@ subroutine dshr_field_getfldptr(field, fldptr1, fldptr2, rank, abort, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (status /= ESMF_FIELDSTATUS_COMPLETE) then if (labort) then - call ESMF_LogWrite(trim(subname)//": ERROR data not allocated ", ESMF_LOGMSG_ERROR, rc=rc) + call ESMF_FieldGet(field, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(trim(subname)//": field "//trim(name)//" has no data not allocated ", ESMF_LOGMSG_ERROR, rc=rc) rc = ESMF_FAILURE return else From f09996397c0509fd92746c747c763986f3bb19c0 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 20 Mar 2024 20:58:09 +0100 Subject: [PATCH 051/170] dglc now runs and produces good values for topog --- dglc/dglc_datamode_noevolve_mod.F90 | 7 +++++++ dglc/glc_comp_nuopc.F90 | 2 ++ 2 files changed, 9 insertions(+) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index e3843536a..b0153e442 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -167,6 +167,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & integer :: rcode integer :: nxg, nyg real(r8), pointer :: data(:) + logical :: exists character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -199,6 +200,11 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Create pioid and pio_iodesc at the module level + inquire(file=trim(input_files(ns)), exist=exists) + if (.not.exists) then + write(6,'(a)')' ERROR: model input file '//trim(input_files(ns))//' does not exist' + call shr_sys_abort() + end if rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(input_files(ns)), pio_nowrite) call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) rcode = pio_inq_varid(pioid, 'thk', varid) @@ -208,6 +214,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & rcode = pio_inq_dimlen(pioid, dimid(1), nxg) rcode = pio_inq_dimlen(pioid, dimid(2), nyg) call pio_initdecomp(pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) + deallocate(dimid) deallocate(gindex) ! Read in the data into the appropriate field bundle pointers diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 9bc423f28..37ed7747b 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -258,6 +258,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, model_meshfiles, CL*max_icesheets, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, model_datafiles, CL*max_icesheets, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, nx_global, max_icesheets, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, ny_global, max_icesheets, main_task, rc=rc) From f724a787063d5ea7c47732ee5a42ed1577e9d7ba Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 21 Mar 2024 13:43:51 +0100 Subject: [PATCH 052/170] implemented correct export fields for noevolve mode --- dglc/dglc_datamode_noevolve_mod.F90 | 112 +++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 19 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index b0153e442..a64a75f0f 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -4,9 +4,10 @@ module dglc_datamode_noevolve_mod use ESMF , only : ESMF_Mesh, ESMF_DistGrid, ESMF_FieldBundle, ESMF_Field use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldCreate, ESMF_MeshLoc_Element use ESMF , only : ESMF_FieldBundleAdd, ESMF_MeshGet, ESMF_DistGridGet, ESMF_Typekind_R8 - use NUOPC , only : NUOPC_Advertise, NUOPC_AddNestedState + use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort + use shr_const_mod , only : SHR_CONST_RHOICE, SHR_CONST_RHOSW use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add use dshr_strdata_mod , only : shr_strdata_type @@ -23,9 +24,10 @@ module dglc_datamode_noevolve_mod public :: dglc_datamode_noevolve_init_pointers public :: dglc_datamode_noevolve_advance - integer :: num_icesheets + integer :: num_icesheets + real(r8) :: thk0 = 1._r8 - ! export fields + ! Export fields type icesheet_ptr_t real(r8), pointer :: ptr(:) => null() ! pointer to array endtype icesheet_ptr_t @@ -34,23 +36,20 @@ module dglc_datamode_noevolve_mod type(icesheet_ptr_t), allocatable :: Sg_ice_covered(:) type(icesheet_ptr_t), allocatable :: Sg_icemask(:) + ! Field names character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' character(len=*), parameter :: field_in_qice = 'Flgl_qice' - character(len=*), parameter :: field_out_area = 'Sg_area' character(len=*), parameter :: field_out_ice_covered = 'Sg_ice_covered' character(len=*), parameter :: field_out_topo = 'Sg_topo' character(len=*), parameter :: field_out_icemask = 'Sg_icemask' character(len=*), parameter :: field_out_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' - character(len=*), parameter :: field_out_hflx_to_lnd = 'Flgg_hflx' character(len=*), parameter :: field_out_rofi_to_ice = 'Figg_rofi' character(len=*), parameter :: field_out_rofi_to_ocn = 'Fogg_rofi' character(len=*), parameter :: field_out_rofl_to_ocn = 'Fogg_rofl' - character(*) , parameter :: nullstr = 'null' character(*) , parameter :: rpfile = 'rpointer.glc' - character(*) , parameter :: u_FILE_u = & __FILE__ @@ -87,7 +86,7 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_n call dshr_fldList_add(fldsExport, field_out_ice_covered) call dshr_fldList_add(fldsExport, field_out_topo) call dshr_fldList_add(fldsExport, field_out_icemask) - call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) + !call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) do ns = 1,num_icesheets write(cnum,'(i0)') ns @@ -128,10 +127,8 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, rc) do ns = 1,num_icesheets call dshr_state_getfldptr(NStateExp(ns), 'Sg_topo' , fldptr1=Sg_topo(ns)%ptr , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), 'Sg_ice_covered' , fldptr1=Sg_ice_covered(ns)%ptr , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), 'Sg_icemask' , fldptr1=Sg_icemask(ns)%ptr , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end do @@ -159,6 +156,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & type(file_desc_t) :: pioid type(io_desc_t) :: pio_iodesc integer :: ns ! ice sheet index + integer :: ng ! grid cell index integer :: lsize integer, pointer :: gindex(:) ! domain decomposition of data integer :: ndims ! number of dims @@ -166,8 +164,14 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & type(var_desc_t) :: varid integer :: rcode integer :: nxg, nyg - real(r8), pointer :: data(:) + real(r8), pointer :: topog(:) + real(r8), pointer :: thck(:) logical :: exists + real(r8) :: rhoi ! density of ice ~ kg/m^3 + real(r8) :: rhoo ! density of sea water ~ kg/m^3 + real(r8) :: eus ! eustatic sea level + real(r8), allocatable :: lsrf(:) + real(r8), allocatable :: usrf(:) character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -222,18 +226,58 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & ! the Sg_ice_covered field in NStateExp(ns) ! Note that Sg_topo(ns)%ptr points into the data for ! the Sg_topon NStateExp(ns) + ! Note that topog is bedrock topography - call dshr_fldbun_getFldPtr(fldbun_noevolve, 'thk', data, rc=rc) + call dshr_fldbun_getFldPtr(fldbun_noevolve, 'topg', topog, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - rcode = pio_inq_varid(pioid, 'thk', varid) - call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) - Sg_ice_covered(ns)%ptr(:) = data(:) + rcode = pio_inq_varid(pioid, 'topg', varid) + call pio_read_darray(pioid, varid, pio_iodesc, topog, rcode) - call dshr_fldbun_getFldPtr(fldbun_noevolve, 'topg', data, rc=rc) + call dshr_fldbun_getFldPtr(fldbun_noevolve, 'thk', thck, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - rcode = pio_inq_varid(pioid, 'topg', varid) - call pio_read_darray(pioid, varid, pio_iodesc, data, rcode) - Sg_topo(ns)%ptr(:) = data(:) + rcode = pio_inq_varid(pioid, 'thk', varid) + call pio_read_darray(pioid, varid, pio_iodesc, thck, rcode) + + allocate(lsrf(lsize)) + allocate(usrf(lsize)) + + rhoi = SHR_CONST_RHOICE ! 0.917e3 + rhoo = SHR_CONST_RHOSW ! 1.026e3 + eus = 0 + do ng = 1,lsize + if (topog(ng) - eus < (-rhoi/rhoo) * thck(ng)) then + lsrf(ng) = (-rhoi/rhoo) * thck(ng) + else + lsrf(ng) = topog(ng) + end if + usrf(ng) = max(0.d0, thck(ng) + lsrf(ng)) + end do + + !Sg_ice_covered(ns)%ptr(:) = thk(:) + do ng = 1,lsize + if (is_in_active_grid(usrf(ng))) then + Sg_icemask(ns)%ptr(ng) = 1.d0 + if (is_ice_covered(thck(ng))) then + Sg_ice_covered(ns)%ptr(ng) = 1.d0 + else + Sg_ice_covered(ns)%ptr(ng) = 0.d0 + end if + ! Note that we use the same method for computing topo whether this point is + ! ice-covered or ice-free. This is in contrast to the method for computing + ! ice-free topo in glint_upscaling_gcm. + Sg_topo(ns)%ptr(ng) = thk0 * usrf(ng) + else + ! Note that this logic implies that if (in theory) we had an ice-covered + ! point outside the "active grid", it will get classified as ice-free for + ! these purposes. This mimics the logic currently in glint_upscaling_gcm. + Sg_icemask(ns)%ptr(ng) = 0.d0 + Sg_ice_covered(ns)%ptr(ng) = 0.d0 + Sg_topo(ns)%ptr(ng) = 0.d0 + end if + end do + + deallocate(lsrf) + deallocate(usrf) call pio_closefile(pioid) call pio_freedecomp(pio_subsystem, pio_iodesc) @@ -242,4 +286,34 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & end subroutine dglc_datamode_noevolve_advance + !=============================================================================== + logical function is_in_active_grid(usrf) + ! Return true if the given point is inside the "active grid". The active grid includes + ! any point that can receive a positive surface mass balance, which includes any + ! point classified as land or ice sheet. + + real(r8), intent(in) :: usrf ! surface elevation (m) + + if (thk0 * usrf > 0.d0) then + ! points not at sea level are assumed to be land or ice sheet + is_in_active_grid = .true. + else + is_in_active_grid = .false. + end if + end function is_in_active_grid + + !=============================================================================== + logical function is_ice_covered(thck) + ! Return true if the given point is ice-covered + + real(r8), intent(in) :: thck ! ice thickness (m) + real(r8), parameter :: min_thck = 0.d0 + + if (thk0 * thck > min_thck) then + is_ice_covered = .true. + else + is_ice_covered = .false. + end if + end function is_ice_covered + end module dglc_datamode_noevolve_mod From d24fac4022a7861f78847327e10b252661424c58 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 22 Mar 2024 14:16:40 +0100 Subject: [PATCH 053/170] more fixes for having import data sent back --- dglc/dglc_datamode_noevolve_mod.F90 | 110 +++++++++++++++++++++------- dglc/glc_comp_nuopc.F90 | 4 +- 2 files changed, 86 insertions(+), 28 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index a64a75f0f..1943cf1dd 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -4,7 +4,7 @@ module dglc_datamode_noevolve_mod use ESMF , only : ESMF_Mesh, ESMF_DistGrid, ESMF_FieldBundle, ESMF_Field use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldCreate, ESMF_MeshLoc_Element use ESMF , only : ESMF_FieldBundleAdd, ESMF_MeshGet, ESMF_DistGridGet, ESMF_Typekind_R8 - use NUOPC , only : NUOPC_Advertise + use NUOPC , only : NUOPC_Advertise, NUOPC_IsConnected use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort use shr_const_mod , only : SHR_CONST_RHOICE, SHR_CONST_RHOSW @@ -24,30 +24,36 @@ module dglc_datamode_noevolve_mod public :: dglc_datamode_noevolve_init_pointers public :: dglc_datamode_noevolve_advance + logical :: initialized_noevolve = .false. integer :: num_icesheets real(r8) :: thk0 = 1._r8 - ! Export fields + ! Data structure to enable multiple ice sheets type icesheet_ptr_t real(r8), pointer :: ptr(:) => null() ! pointer to array endtype icesheet_ptr_t + + ! Export fields type(icesheet_ptr_t), allocatable :: Sg_area(:) type(icesheet_ptr_t), allocatable :: Sg_topo(:) type(icesheet_ptr_t), allocatable :: Sg_ice_covered(:) type(icesheet_ptr_t), allocatable :: Sg_icemask(:) + type(icesheet_ptr_t), allocatable :: Sg_icemask_coupled_fluxes(:) - ! Field names - character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' - character(len=*), parameter :: field_in_qice = 'Flgl_qice' + ! Import fields + type(icesheet_ptr_t), allocatable :: Sl_tsrf(:) + type(icesheet_ptr_t), allocatable :: Flgl_qice(:) + + ! Export Field names character(len=*), parameter :: field_out_area = 'Sg_area' - character(len=*), parameter :: field_out_ice_covered = 'Sg_ice_covered' character(len=*), parameter :: field_out_topo = 'Sg_topo' + character(len=*), parameter :: field_out_ice_covered = 'Sg_ice_covered' character(len=*), parameter :: field_out_icemask = 'Sg_icemask' character(len=*), parameter :: field_out_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' - character(len=*), parameter :: field_out_hflx_to_lnd = 'Flgg_hflx' - character(len=*), parameter :: field_out_rofi_to_ice = 'Figg_rofi' - character(len=*), parameter :: field_out_rofi_to_ocn = 'Fogg_rofi' - character(len=*), parameter :: field_out_rofl_to_ocn = 'Fogg_rofl' + + ! Import Field names + character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' + character(len=*), parameter :: field_in_qice = 'Flgl_qice' character(*) , parameter :: rpfile = 'rpointer.glc' character(*) , parameter :: u_FILE_u = & @@ -57,18 +63,20 @@ module dglc_datamode_noevolve_mod contains !=============================================================================== - subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_name, rc) + subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fldsimport, flds_scalar_name, rc) ! input/output variables - type(ESMF_State) , intent(inout) :: NStateExp(:) - type(fldlist_type) , pointer :: fldsexport - character(len=*) , intent(in) :: flds_scalar_name - integer , intent(out) :: rc + type(ESMF_State) , intent(inout) :: NStateExp(:) + type(fldlist_type), pointer :: fldsexport + type(ESMF_State) , intent(inout) :: NStateImp(:) + type(fldlist_type), pointer :: fldsimport + character(len=*) , intent(in) :: flds_scalar_name + integer , intent(out) :: rc ! local variables - integer :: ns - logical :: isPresent, isSet - character(len=CS) :: cnum + integer :: ns + logical :: isPresent, isSet + character(len=CS) :: cnum type(fldlist_type), pointer :: fldList !------------------------------------------------------------------------------- @@ -83,10 +91,11 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_n ! Advertise export fields call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsExport, field_out_area) call dshr_fldList_add(fldsExport, field_out_ice_covered) call dshr_fldList_add(fldsExport, field_out_topo) call dshr_fldList_add(fldsExport, field_out_icemask) - !call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) + call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) do ns = 1,num_icesheets write(cnum,'(i0)') ns @@ -99,13 +108,30 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_n end do enddo + ! Advertise import fields + call dshr_fldList_add(fldsImport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsImport, field_in_tsrf) + call dshr_fldList_add(fldsImport, field_in_qice) + + do ns = 1,num_icesheets + write(cnum,'(i0)') ns + fldlist => fldsImport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(NStateImp(ns), standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite('(dglc_comp_advertise): To_glc'//trim(cnum)//"_"//trim(fldList%stdname), ESMF_LOGMSG_INFO) + fldList => fldList%next + end do + enddo + end subroutine dglc_datamode_noevolve_advertise !=============================================================================== - subroutine dglc_datamode_noevolve_init_pointers(NStateExp, rc) + subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) ! input/output variables type(ESMF_State) , intent(inout) :: NStateExp(:) + type(ESMF_State) , intent(inout) :: NStateImp(:) integer , intent(out) :: rc ! local variables @@ -123,14 +149,34 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, rc) allocate(Sg_topo(num_icesheets)) allocate(Sg_ice_covered(num_icesheets)) allocate(Sg_icemask(num_icesheets)) + allocate(Sg_icemask_coupled_fluxes(num_icesheets)) do ns = 1,num_icesheets - call dshr_state_getfldptr(NStateExp(ns), 'Sg_topo' , fldptr1=Sg_topo(ns)%ptr , rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_topo, fldptr1=Sg_topo(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), 'Sg_ice_covered' , fldptr1=Sg_ice_covered(ns)%ptr , rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_ice_covered, fldptr1=Sg_ice_covered(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), 'Sg_icemask' , fldptr1=Sg_icemask(ns)%ptr , rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_icemask, fldptr1=Sg_icemask(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(NStateExp(ns), field_out_icemask_coupled_fluxes, fldptr1=Sg_icemask_coupled_fluxes(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do + + ! initialize pointers to import fields + allocate(Sl_tsrf(num_icesheets)) + allocate(Flgl_qice(num_icesheets)) + + do ns = 1,num_icesheets + ! NOTE: the field is connected ONLY if the MED->GLC entry is in the nuopc.runconfig file + ! This restriction occurs even if the field was advertised + if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_tsrf)) then + call dshr_state_getfldptr(NStateImp(ns), field_in_tsrf, fldptr1=Sl_tsrf(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_qice)) then + call dshr_state_getfldptr(NStateImp(ns), field_in_qice, fldptr1=Flgl_qice(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if end do end subroutine dglc_datamode_noevolve_init_pointers @@ -177,6 +223,17 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & rc = ESMF_SUCCESS + if (initialized_noevolve) then + RETURN + end if + + real(r8), allocatable :: glc_areas(:,:) + glc_areas(:,:) = get_dns(params%instances(instance_index)%model) * & + get_dew(params%instances(instance_index)%model) + call get_areas(ice_sheet, instance_index = ns, areas=glc_areas) + glc_areas(:,:) = glc_areas(:,:)/(radius*radius) ! convert from m^2 to radians^2 + + do ns = 1,num_icesheets ! Create module level field bundle @@ -251,12 +308,10 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & lsrf(ng) = topog(ng) end if usrf(ng) = max(0.d0, thck(ng) + lsrf(ng)) - end do - !Sg_ice_covered(ns)%ptr(:) = thk(:) - do ng = 1,lsize if (is_in_active_grid(usrf(ng))) then Sg_icemask(ns)%ptr(ng) = 1.d0 + Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 1.d0 if (is_ice_covered(thck(ng))) then Sg_ice_covered(ns)%ptr(ng) = 1.d0 else @@ -271,6 +326,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & ! point outside the "active grid", it will get classified as ice-free for ! these purposes. This mimics the logic currently in glint_upscaling_gcm. Sg_icemask(ns)%ptr(ng) = 0.d0 + Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 0.d0 Sg_ice_covered(ns)%ptr(ng) = 0.d0 Sg_topo(ns)%ptr(ng) = 0.d0 end if @@ -284,6 +340,8 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & end do ! end loop over ice sheets + initialized_noevolve = .true. + end subroutine dglc_datamode_noevolve_advance !=============================================================================== diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 37ed7747b..c5d20fd7b 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -300,7 +300,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Advertise dglc fields if (trim(datamode)=='noevolve') then - call dglc_datamode_noevolve_advertise(NStateExp, fldsexport, flds_scalar_name, rc) + call dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fldsimport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -522,7 +522,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) ! Initialize datamode module ponters select case (trim(datamode)) case('noevolve') - call dglc_datamode_noevolve_init_pointers(NStateExp, rc) + call dglc_datamode_noevolve_init_pointers(NStateExp, NStateImp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select From e5c7386eba53c3826717992f6a0ae23f06734226 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 24 Mar 2024 10:42:55 +0100 Subject: [PATCH 054/170] hard-wired greenland area as a prototype test --- dglc/dglc_datamode_noevolve_mod.F90 | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 1943cf1dd..c9cb25d41 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -152,6 +152,8 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) allocate(Sg_icemask_coupled_fluxes(num_icesheets)) do ns = 1,num_icesheets + call dshr_state_getfldptr(NStateExp(ns), field_out_area, fldptr1=Sg_area(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(NStateExp(ns), field_out_topo, fldptr1=Sg_topo(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(NStateExp(ns), field_out_ice_covered, fldptr1=Sg_ice_covered(ns)%ptr, rc=rc) @@ -218,6 +220,8 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & real(r8) :: eus ! eustatic sea level real(r8), allocatable :: lsrf(:) real(r8), allocatable :: usrf(:) + ! TODO: make this a namelist variable + real(r8) :: glc_areas(num_icesheets) ! internal ice sheet area radians**2 character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -227,15 +231,22 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & RETURN end if - real(r8), allocatable :: glc_areas(:,:) - glc_areas(:,:) = get_dns(params%instances(instance_index)%model) * & - get_dew(params%instances(instance_index)%model) - call get_areas(ice_sheet, instance_index = ns, areas=glc_areas) - glc_areas(:,:) = glc_areas(:,:)/(radius*radius) ! convert from m^2 to radians^2 + ! real(r8), allocatable :: glc_areas(:,:) + ! glc_areas(:,:) = get_dns(params%instances(instance_index)%model) * & + ! get_dew(params%instances(instance_index)%model) + ! call get_areas(ice_sheet, instance_index = ns, areas=glc_areas) + ! glc_areas(:,:) = glc_areas(:,:)/(radius*radius) ! convert from m^2 to radians^2 + ! glc_areas(:,:) = + glc_areas(1) = 3.94162024004361e-07 do ns = 1,num_icesheets + ! "area" ; + do ng = 1,lsize + Sg_area(ns)%ptr(ng) = glc_areas(ns) + end do + ! Create module level field bundle fldbun_noevolve = ESMF_FieldBundleCreate(rc=rc) ! input field bundle From 862df107ff060212b677ed66b5b3cfbf31aa4da0 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 27 Mar 2024 04:43:55 -0600 Subject: [PATCH 055/170] more changes to get dglc working with CLM --- dglc/cime_config/buildnml | 17 ++- dglc/cime_config/config_component.xml | 41 +++++++ dglc/cime_config/namelist_definition_dglc.xml | 30 +++++ dglc/dglc_datamode_noevolve_mod.F90 | 112 +++++++++--------- dglc/glc_comp_nuopc.F90 | 40 ++++--- 5 files changed, 157 insertions(+), 83 deletions(-) diff --git a/dglc/cime_config/buildnml b/dglc/cime_config/buildnml index 6994b7051..4dfef53b8 100755 --- a/dglc/cime_config/buildnml +++ b/dglc/cime_config/buildnml @@ -51,15 +51,6 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path expect(glc_grid != "null", "DGLC_GRID cannot be null") - # Log some settings. - logger.debug("DGLC mode is {}".format(dglc_mode)) - - # Initialize namelist defaults - # Note: always use model mesh file to set mask for drof - config = {} - config['dglc_mode'] = dglc_mode - config['glc_grid'] = glc_grid - # Do not allow single column mode for dglc if case.get_value('PTS_LON'): scol_lon = float(case.get_value('PTS_LON')) @@ -73,6 +64,14 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path expect(False, "single column mode for DGLC is not currently allowed") + # Log some settings. + logger.debug("DGLC mode is {}".format(dglc_mode)) + + # Initialize namelist defaults + config = {} + config['dglc_mode'] = dglc_mode + config['glc_grid'] = glc_grid + # Initialize nmlgen nmlgen.init_defaults(infile, config) diff --git a/dglc/cime_config/config_component.xml b/dglc/cime_config/config_component.xml index ae4a0549a..27cc4af61 100644 --- a/dglc/cime_config/config_component.xml +++ b/dglc/cime_config/config_component.xml @@ -40,6 +40,47 @@ + + logical + FALSE + run_component_dglc + env_run.xml + + If true, have the mediator calculate import values that are sent back to + GLC even in GLC is in NOEVOLVE mode + + + + + logical + FALSE + run_component_dglc + env_run.xml + + TRUE + + Whether to include the Greenland Ice Sheet in this DGLC simulation + This should generally be set at create_newcase time (via the compset). In principle it + can be changed later, but great care is needed to change a number of other variables + to be consistent (GLC_GRID, GLC_DOMAIN_MESH and possibly others). + + + + + logical + FALSE + run_component_dglc + env_run.xml + + TRUE + + Whether to include the Antarctica Ice Sheet in this DGLC simulation + This should generally be set at create_newcase time (via the compset). In principle it + can be changed later, but great care is needed to change a number of other variables + to be consistent (GLC_GRID, GLC_DOMAIN_MESH and possibly others). + + + logical TRUE,FALSE diff --git a/dglc/cime_config/namelist_definition_dglc.xml b/dglc/cime_config/namelist_definition_dglc.xml index b2ede04bc..20dd0bde1 100644 --- a/dglc/cime_config/namelist_definition_dglc.xml +++ b/dglc/cime_config/namelist_definition_dglc.xml @@ -65,6 +65,21 @@ + + real(20) + streams + dglc_nml + + 3.94162024004361e-07,1.57664809601744e-06 + 1. + 3.94162024004361e-07 + 1.57664809601744e-06 + + + colon deliminted string of inputdata files + + + integer(20) streams @@ -109,6 +124,21 @@ + + logical + dglc + dglc_nml + + If set to true, than dglc will advertise and realize import + fields even if it does not do anything with them. This + capability is used, for example, in generating coupler history + data for GLC spinup runs. + + + $DGLC_GET_IMPORT_DATA + + + logical dglc diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index c9cb25d41..7b6427497 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -27,6 +27,7 @@ module dglc_datamode_noevolve_mod logical :: initialized_noevolve = .false. integer :: num_icesheets real(r8) :: thk0 = 1._r8 + logical :: get_import_data ! Data structure to enable multiple ice sheets type icesheet_ptr_t @@ -63,12 +64,14 @@ module dglc_datamode_noevolve_mod contains !=============================================================================== - subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fldsimport, flds_scalar_name, rc) + subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fldsimport, & + get_import_data_in, flds_scalar_name, rc) ! input/output variables type(ESMF_State) , intent(inout) :: NStateExp(:) type(fldlist_type), pointer :: fldsexport type(ESMF_State) , intent(inout) :: NStateImp(:) + logical , intent(in) :: get_import_data_in type(fldlist_type), pointer :: fldsimport character(len=*) , intent(in) :: flds_scalar_name integer , intent(out) :: rc @@ -82,6 +85,9 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fl rc = ESMF_SUCCESS + ! Set module vraiable + get_import_data = get_import_data_in + !-------------------------------- ! Create nested state for active ice sheets only !-------------------------------- @@ -108,21 +114,23 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fl end do enddo - ! Advertise import fields - call dshr_fldList_add(fldsImport, trim(flds_scalar_name)) - call dshr_fldList_add(fldsImport, field_in_tsrf) - call dshr_fldList_add(fldsImport, field_in_qice) - - do ns = 1,num_icesheets - write(cnum,'(i0)') ns - fldlist => fldsImport ! the head of the linked list - do while (associated(fldlist)) - call NUOPC_Advertise(NStateImp(ns), standardName=fldlist%stdname, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite('(dglc_comp_advertise): To_glc'//trim(cnum)//"_"//trim(fldList%stdname), ESMF_LOGMSG_INFO) - fldList => fldList%next - end do - enddo + ! Advertise import fields if appropriate + if (get_import_data) then + call dshr_fldList_add(fldsImport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsImport, field_in_tsrf) + call dshr_fldList_add(fldsImport, field_in_qice) + + do ns = 1,num_icesheets + write(cnum,'(i0)') ns + fldlist => fldsImport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(NStateImp(ns), standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite('(dglc_comp_advertise): To_glc'//trim(cnum)//"_"//trim(fldList%stdname), ESMF_LOGMSG_INFO) + fldList => fldList%next + end do + enddo + end if end subroutine dglc_datamode_noevolve_advertise @@ -164,28 +172,30 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end do - ! initialize pointers to import fields - allocate(Sl_tsrf(num_icesheets)) - allocate(Flgl_qice(num_icesheets)) - - do ns = 1,num_icesheets - ! NOTE: the field is connected ONLY if the MED->GLC entry is in the nuopc.runconfig file - ! This restriction occurs even if the field was advertised - if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_tsrf)) then - call dshr_state_getfldptr(NStateImp(ns), field_in_tsrf, fldptr1=Sl_tsrf(ns)%ptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_qice)) then - call dshr_state_getfldptr(NStateImp(ns), field_in_qice, fldptr1=Flgl_qice(ns)%ptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - end do + ! initialize pointers to import fields if appropriate + if (get_import_data) then + allocate(Sl_tsrf(num_icesheets)) + allocate(Flgl_qice(num_icesheets)) + + do ns = 1,num_icesheets + ! NOTE: the field is connected ONLY if the MED->GLC entry is in the nuopc.runconfig file + ! This restriction occurs even if the field was advertised + if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_tsrf)) then + call dshr_state_getfldptr(NStateImp(ns), field_in_tsrf, fldptr1=Sl_tsrf(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_qice)) then + call dshr_state_getfldptr(NStateImp(ns), field_in_qice, fldptr1=Flgl_qice(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + end do + end if end subroutine dglc_datamode_noevolve_init_pointers !=============================================================================== subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & - model_meshes, input_files, rc) + model_meshes, model_areas, input_files, rc) ! Assume that the model mesh is the same as the input data mesh @@ -194,6 +204,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & integer , intent(in) :: io_type ! pio info integer , intent(in) :: io_format ! pio info type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes + real(r8) , intent(in) :: model_areas(:) ! internal model ice sheets areas (radians**2) character(len=*) , intent(in) :: input_files(:) ! input file names integer , intent(out) :: rc @@ -220,8 +231,6 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & real(r8) :: eus ! eustatic sea level real(r8), allocatable :: lsrf(:) real(r8), allocatable :: usrf(:) - ! TODO: make this a namelist variable - real(r8) :: glc_areas(num_icesheets) ! internal ice sheet area radians**2 character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -231,20 +240,20 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & RETURN end if - ! real(r8), allocatable :: glc_areas(:,:) - ! glc_areas(:,:) = get_dns(params%instances(instance_index)%model) * & - ! get_dew(params%instances(instance_index)%model) - ! call get_areas(ice_sheet, instance_index = ns, areas=glc_areas) - ! glc_areas(:,:) = glc_areas(:,:)/(radius*radius) ! convert from m^2 to radians^2 - ! glc_areas(:,:) = - - glc_areas(1) = 3.94162024004361e-07 - do ns = 1,num_icesheets - ! "area" ; + ! Get mesh info + call ESMF_MeshGet(model_meshes(ns), 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(gindex(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine "glc_area" ; do ng = 1,lsize - Sg_area(ns)%ptr(ng) = glc_areas(ns) + Sg_area(ns)%ptr(ng) = model_areas(ns) end do ! Create module level field bundle @@ -262,15 +271,6 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Get mesh info - call ESMF_MeshGet(model_meshes(ns), 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(gindex(lsize)) - call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Create pioid and pio_iodesc at the module level inquire(file=trim(input_files(ns)), exist=exists) if (.not.exists) then @@ -322,7 +322,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (is_in_active_grid(usrf(ng))) then Sg_icemask(ns)%ptr(ng) = 1.d0 - Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 1.d0 + Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 0.d0 if (is_ice_covered(thck(ng))) then Sg_ice_covered(ns)%ptr(ng) = 1.d0 else diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index c5d20fd7b..6d160bdc3 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -61,6 +61,7 @@ module cdeps_dglc_comp character(*) , parameter :: nullstr = 'null' integer , parameter :: max_icesheets = 10 ! maximum number of ice sheets for namelist input integer :: num_icesheets ! actual number of ice sheets + logical :: get_import_data = .false. ! namelist input character(CS) :: icesheet_names(max_icesheets) = nullstr @@ -68,6 +69,7 @@ module cdeps_dglc_comp character(CL) :: model_datafiles(max_icesheets) = nullstr integer :: nx_global(max_icesheets) = 0 integer :: ny_global(max_icesheets) = 0 + real(r8) :: model_areas(max_icesheets) = 1.e36 ! module variables for multiple ice sheets type(shr_strdata_type) , allocatable :: sdat(:) @@ -181,7 +183,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: inst_index ! number of current instance (ie. 1) integer :: nu ! unit number integer :: ierr ! error code - integer :: bcasttmp(1) + integer :: bcasttmp(3) integer :: ns, n character(len=CS) :: cnum character(len=CL) :: icesheets_list @@ -192,8 +194,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Note that the suffix '-list' refers to a colon delimited string of names namelist / dglc_nml / datamode, & - icesheets_list, model_meshfiles_list, model_datafiles_list, nx_global, ny_global, & - restfilm, skip_restart_read + icesheets_list, model_meshfiles_list, model_datafiles_list, model_areas, nx_global, ny_global, & + get_import_data, restfilm, skip_restart_read rc = ESMF_SUCCESS @@ -236,17 +238,22 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,'(a,a)')' case_name = ',trim(case_name) write(logunit,'(a,a)')' datamode = ',trim(datamode) do ns = 1,num_icesheets - write(logunit,'(a,i4 )')' ice_sheet index = ',ns - write(logunit,'(a,a )')' model_meshfile = ',trim(model_meshfiles(ns)) - write(logunit,'(a,a )')' model_datafile = ',trim(model_datafiles(ns)) - write(logunit,'(a,i10)')' nx_global = ',nx_global(ns) - write(logunit,'(a,i10)')' ny_global = ',ny_global(ns) + write(logunit,'(a,i4 )') ' ice_sheet index = ',ns + write(logunit,'(a,a )') ' model_meshfile = ',trim(model_meshfiles(ns)) + write(logunit,'(a,a )') ' model_datafile = ',trim(model_datafiles(ns)) + write(logunit,'(a,i10)') ' nx_global = ',nx_global(ns) + write(logunit,'(a,i10)') ' ny_global = ',ny_global(ns) + write(logunit,'(a,d13.5)')' model_areas = ',model_areas(ns) end do write(logunit,'(a,a )')' restfilm = ',trim(restfilm) + write(logunit,'(a,l6)')' get_import_data = ',get_import_data write(logunit,'(a,l6)')' skip_restart_read = ',skip_restart_read bcasttmp(1) = 0 if(skip_restart_read) bcasttmp(1) = 1 + bcasttmp(2) = 0 + if(get_import_data) bcasttmp(2) = 1 + bcasttmp(3) = num_icesheets endif ! Broadcast namelist input @@ -264,17 +271,13 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, ny_global, max_icesheets, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Set number of ice sheets for all mpi tasks - bcasttmp(1) = num_icesheets - call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) + call ESMF_VMBroadcast(vm, model_areas, max_icesheets, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - num_icesheets = bcasttmp(1) - - ! Determine if will skip restart read for all mpi tasks - call ESMF_VMBroadcast(vm, bcasttmp, 1, main_task, rc=rc) + call ESMF_VMBroadcast(vm, bcasttmp, 3, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return skip_restart_read = (bcasttmp(1) == 1) + get_import_data = (bcasttmp(2) == 1) + num_icesheets = bcasttmp(3) ! Validate datamode if ( trim(datamode) == 'noevolve') then ! read stream, no import data @@ -300,7 +303,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Advertise dglc fields if (trim(datamode)=='noevolve') then - call dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fldsimport, flds_scalar_name, rc) + call dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fldsimport, & + get_import_data, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -568,7 +572,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) select case (trim(datamode)) case('noevolve') call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, & - model_meshes, model_datafiles, rc) + model_meshes, model_areas, model_datafiles, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select From 63ed71f4067e73d9009c65d78a253e1dcb915b18 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 27 Mar 2024 06:30:01 -0600 Subject: [PATCH 056/170] first addition of documentation for dglc --- dglc/glc_comp_nuopc.F90 | 3 +- doc/source/dglc.rst | 113 ++++++++++++++++++++++++++++++++++++++++ doc/source/index.rst | 1 + 3 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 doc/source/dglc.rst diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 6d160bdc3..26b3d15d0 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -186,7 +186,6 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: bcasttmp(3) integer :: ns, n character(len=CS) :: cnum - character(len=CL) :: icesheets_list character(len=ESMF_MAXSTR) :: model_datafiles_list ! colon separated string containing input datafiles character(len=ESMF_MAXSTR) :: model_meshfiles_list ! colon separated string containing model meshfiles character(len=*),parameter :: subname=trim(module_name)//':(InitializeAdvertise) ' @@ -194,7 +193,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Note that the suffix '-list' refers to a colon delimited string of names namelist / dglc_nml / datamode, & - icesheets_list, model_meshfiles_list, model_datafiles_list, model_areas, nx_global, ny_global, & + model_meshfiles_list, model_datafiles_list, model_areas, nx_global, ny_global, & get_import_data, restfilm, skip_restart_read rc = ESMF_SUCCESS diff --git a/doc/source/dglc.rst b/doc/source/dglc.rst new file mode 100644 index 000000000..56e35d191 --- /dev/null +++ b/doc/source/dglc.rst @@ -0,0 +1,113 @@ +.. _dglc: + +Data Ocean (DGLC) +================= + +DGLC is normally used as a substitute for CESM/CISM running in NOEVOLVE mode. +The various ways of running DGLC is referred to as its mode. + +NOEVOLVE mode is used in CESM as follows. +In typical runs, CISM is not evolving; CLM computes the surface mass +balance (SMB) and sends it to CISM, but CISM’s ice sheet geometry +remains fixed over the course of the run. In these runs, CISM serves +two roles in the system: + - Over the CISM domain (typically Greenland in + CESM2), CISM dictates glacier areas and topographic elevations, + overriding the values on CLM’s surface dataset. CISM also dictates the + elevation of non-glacier land units in its domain, and only in this + domain are atmospheric fields downscaled to non-glacier land + units. (So if you run with a stub glacier model - SGLC - then glacier + areas and elevations will be taken entirely from CLM’s surface + dataset, and no downscaling will be done over non-glacier land units.) + - CISM provides the grid onto which SMB is downscaled. (If you run with + SGLC then SMB will still be computed in CLM, but it won’t be + downscaled to a high-resolution ice sheet grid.) + +DGLC has the capability of supporting multiple ice sheets (as is the +case with CISM/CMEPS coupling). This is configured via the following +namelist settings: + + - ``model_meshfiles_list`` is a colon separated string containing model + meshfiles describing the different ice sheets. + + - ``model_datafiles_list`` is colon separated string containing + input datafiles that are used by CISM. Each datafile corresponds to a different + ice sheet mesh and should have the same order as those in the ``model_meshfiles_list``. + +.. _dglc-datamodes: + +-------------------- +Supported Data Modes +-------------------- + +DGLC has its own set of supported ``datamode`` values that appears in +the ``dglc_in`` namelist input. The datamode specifies what additional +operations need to be done by DGLC on *ALL* of the streams in the +``dglc.streams.xml`` file. Each datamode value is also associated with +a DGLC source file that carries out these operations and these are +listed in parentheses next to the mode name. Currently, the only +supported ``datamode`` is ``noevolve``. + +noevolve (``dglc_datamode_noevolve_mod.F90``) + - This mode is an analytic mode that has no associated stream files. + This mode uses ``dglc_in`` namelist variables as follows: + +.. _dglc-cime-vars: + +--------------------------------------- +Configuring DGLC using CIME-CCS +--------------------------------------- + +If CDEPS is coupled to the CIME-CCS then the CIME ``$CASEROOT`` xml +variable ``DGLC_MODE`` will be generated based on the compset +specification ``DGLC%{DGLC_MODE}``. ``DGLC_MODE`` will in term be +used in the ``namelist_definition_dglc.xml`` file to determine the +collection of streams that are associated with DGLC and also sets the +dglc namelist variable ``datamode`` in the file ``dglc_in``. + +The following list describes the valid values of ``DGLC_MODE`` +(defined in the ``config_component.xml`` file for DGLC), and how they +relate to the associated input streams and the ``datamode`` namelist +variable. + +DGLC%DOM + - SST data provided by a file + - dglc_mode: prescribed + - streams: prescribed + - datamode: sstdata + +DGLC%IAF + - SST data provided by a file + - dglc_mode: interannual + - streams: interannual + - datamode: iaf + +DGLC%SOM + - Slab Ocean Model is used to calculate sea surface temperature. + - dglc_mode: som + - streams: som + - datamode: som + +DGLC%SOMAQP + - Slab Ocean Model is used to calculate sea surface temperature. + - dglc_mode: som_aquap + - streams: N/A + - datamode: som_aquap + +DGLC%AQP[1-10] + - Lattitude varying analytical sea surface data + - dglc_mode: sst_aquap[1-10] + - streams: N/A + - datamode: sst_aquap[1-10] + +DGLC%AQPFILE + - SST data provided by a file + - dglc_mode: sst_aquap_file + - streams: aquapfile + - datamode: sst_aquapfile + +DGLC%AQPCONST + - Constant sea surface data from aquaplanet + - dglc_mode: sst_aquap_constant + - streams: N/A + - datamode: sst_aquap_constant diff --git a/doc/source/index.rst b/doc/source/index.rst index 3990258c3..f1a826f07 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -29,4 +29,5 @@ Table of contents dlnd.rst drof.rst dwav.rst + dglc.rst extending.rst From dbec7c93af394a339a4ae029e75ed924a58f577e Mon Sep 17 00:00:00 2001 From: mvertens Date: Wed, 27 Mar 2024 14:41:11 +0100 Subject: [PATCH 057/170] udpates for documentation for dglc --- dglc/cime_config/config_component.xml | 15 +-- doc/source/dglc.rst | 132 ++++++++++++++------------ 2 files changed, 79 insertions(+), 68 deletions(-) diff --git a/dglc/cime_config/config_component.xml b/dglc/cime_config/config_component.xml index 27cc4af61..d8ef6469f 100644 --- a/dglc/cime_config/config_component.xml +++ b/dglc/cime_config/config_component.xml @@ -27,16 +27,19 @@ char - NOEVOLVE - NOEVOLVE + noevolve + noevolve - noevolve + noevolve run_component_dglc env_run.xml - - model mode. - TODO: fill in what noevolve mode does + + NOEVOLVE mode is used in CESM as follows. + In typical runs, CISM is not evolving; CLM computes the surface mass + balance (SMB) and sends it to CISM, but CISM’s ice sheet geometry + remains fixed over the course of the run. In these runs, CISM serves + two roles in the system: diff --git a/doc/source/dglc.rst b/doc/source/dglc.rst index 56e35d191..9aa1ad6b9 100644 --- a/doc/source/dglc.rst +++ b/doc/source/dglc.rst @@ -1,6 +1,6 @@ .. _dglc: -Data Ocean (DGLC) +Data Land-Ice (DGLC) ================= DGLC is normally used as a substitute for CESM/CISM running in NOEVOLVE mode. @@ -11,34 +11,55 @@ In typical runs, CISM is not evolving; CLM computes the surface mass balance (SMB) and sends it to CISM, but CISM’s ice sheet geometry remains fixed over the course of the run. In these runs, CISM serves two roles in the system: - - Over the CISM domain (typically Greenland in - CESM2), CISM dictates glacier areas and topographic elevations, - overriding the values on CLM’s surface dataset. CISM also dictates the - elevation of non-glacier land units in its domain, and only in this - domain are atmospheric fields downscaled to non-glacier land - units. (So if you run with a stub glacier model - SGLC - then glacier - areas and elevations will be taken entirely from CLM’s surface - dataset, and no downscaling will be done over non-glacier land units.) - - CISM provides the grid onto which SMB is downscaled. (If you run with - SGLC then SMB will still be computed in CLM, but it won’t be - downscaled to a high-resolution ice sheet grid.) + + - Over the CISM domain (typically Greenland in + CESM2), CISM dictates glacier areas and topographic elevations, + overriding the values on CLM’s surface dataset. CISM also dictates the + elevation of non-glacier land units in its domain, and only in this + domain are atmospheric fields downscaled to non-glacier land + units. (So if you run with a stub glacier model - SGLC - then glacier + areas and elevations will be taken entirely from CLM’s surface + dataset, and no downscaling will be done over non-glacier land units.) + + - CISM provides the grid onto which SMB is downscaled. (If you run with + SGLC then SMB will still be computed in CLM, but it won’t be + downscaled to a high-resolution ice sheet grid.) + +-------------------- +Supported Data Modes +-------------------- DGLC has the capability of supporting multiple ice sheets (as is the case with CISM/CMEPS coupling). This is configured via the following -namelist settings: +``dglc_in`` namelist settings: - ``model_meshfiles_list`` is a colon separated string containing model meshfiles describing the different ice sheets. - ``model_datafiles_list`` is colon separated string containing - input datafiles that are used by CISM. Each datafile corresponds to a different - ice sheet mesh and should have the same order as those in the ``model_meshfiles_list``. - -.. _dglc-datamodes: - --------------------- -Supported Data Modes --------------------- + input datafiles that specify are used to obtain data for bedrock + topography and the ice thickness. + + - ``model_areas`` is an array that is the size of the number of ice + sheets and that specifies the gridcell areas that corresponds to + what internal gridcell areas the prognostic land-ice component + uses internally (in this case CISM). Specifying this at the + namelist level eliminates the need to duplicate the code that is + used in CISM to derive this quantity. + + - ``nx_global`` is an array that is the size of the number of ice + sheets and that specifies the global longitude dimension of the + each ice sheet. + + - ``ny_global`` is an array that is the size of the number of ice + sheets and that specifies the global latitude dimension of the + each ice sheet. + +.. note:: + Each element of ``model_data_filelist``, ``model_areas``, + ``nx_global`` and ``ny_global`` corresponds to a different ice + sheet mesh and should have the **same order** as those in the + ``model_meshfiles_list``. DGLC has its own set of supported ``datamode`` values that appears in the ``dglc_in`` namelist input. The datamode specifies what additional @@ -70,44 +91,31 @@ The following list describes the valid values of ``DGLC_MODE`` relate to the associated input streams and the ``datamode`` namelist variable. -DGLC%DOM - - SST data provided by a file - - dglc_mode: prescribed - - streams: prescribed - - datamode: sstdata - -DGLC%IAF - - SST data provided by a file - - dglc_mode: interannual - - streams: interannual - - datamode: iaf - -DGLC%SOM - - Slab Ocean Model is used to calculate sea surface temperature. - - dglc_mode: som - - streams: som - - datamode: som - -DGLC%SOMAQP - - Slab Ocean Model is used to calculate sea surface temperature. - - dglc_mode: som_aquap - - streams: N/A - - datamode: som_aquap - -DGLC%AQP[1-10] - - Lattitude varying analytical sea surface data - - dglc_mode: sst_aquap[1-10] - - streams: N/A - - datamode: sst_aquap[1-10] - -DGLC%AQPFILE - - SST data provided by a file - - dglc_mode: sst_aquap_file - - streams: aquapfile - - datamode: sst_aquapfile - -DGLC%AQPCONST - - Constant sea surface data from aquaplanet - - dglc_mode: sst_aquap_constant - - streams: N/A - - datamode: sst_aquap_constant +DGLC%NOEVOLVE + - fields sent to mediator are created analytically without stream + input + - dglc_mode: NOEVOLVE + - streams: none + - datamode: noevolve + +In addition, the following DGLC specific CIME-CCS xml variables will appear in ``$CASEROOT/env_run.xml``: + +DGLC_GET_IMPORT_DATA + - If true, have the mediator calculate import values that are sent back to + GLC even in GLC is in NOEVOLVE mode. The default value is FALSE. + +DGLC_USE_GREENLAND + - Whether to include the Greenland Ice Sheet in this DGLC simulation + This should generally be set at create_newcase time (via the compset). In principle it + can be changed later, but great care is needed to change a number of other variables + to be consistent (GLC_GRID, GLC_DOMAIN_MESH and possibly others). + +DGLC_USE_ANTARCTICA + - Whether to include the Antarctic Ice Sheet in this DGLC simulation + This should generally be set at create_newcase time (via the compset). In principle it + can be changed later, but great care is needed to change a number of other variables + to be consistent (GLC_GRID, GLC_DOMAIN_MESH and possibly others). + +DGLC_SKIP_RESTART_READ + - If set to true, than dglc restarts will not be read on a continuation run. + From 8f32440646ade064102e2362353ae91bb7a00eb2 Mon Sep 17 00:00:00 2001 From: mvertens Date: Wed, 27 Mar 2024 19:18:05 +0100 Subject: [PATCH 058/170] more additions for dglc --- doc/source/introduction.rst | 3 ++- doc/source/streams.rst | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/source/introduction.rst b/doc/source/introduction.rst index b34a67419..dcdf2ef1b 100644 --- a/doc/source/introduction.rst +++ b/doc/source/introduction.rst @@ -59,6 +59,7 @@ cime_config CIME Case Control System cmake Build (can be used with or without CIME) datm Data atmosphere component dice Data sea-ice component +dglc Data land-ice component dlnd Data land component docn Data ocean component drof Data river component @@ -132,7 +133,7 @@ CDEPS and CIME Control System (CCS) If the CDEPS data models are used in conjunction with the CIME Case Control System (CCS) then the following will also hold: Each data model has an xml variable in ``env_run.xml`` that specifies the data model mode. -These are: ``DATM_MODE``, ``DICE_MODE``, ``DLND_MODE``, ``DOCN_MODE``, ``DROF_MODE``, ``DWAV_MODE``. +These are: ``DATM_MODE``, ``DICE_MODE``, ``DGLC_MODE``, ``DLND_MODE``, ``DOCN_MODE``, ``DROF_MODE``, ``DWAV_MODE``. Each data model mode specifies the streams that are associated with that data model. More details of the data model design are covered in :ref:`design details`. diff --git a/doc/source/streams.rst b/doc/source/streams.rst index 3ce4d8023..0b6fa7235 100644 --- a/doc/source/streams.rst +++ b/doc/source/streams.rst @@ -365,7 +365,7 @@ Data Model Namelist Input ------------------------- Each data model has an associated input namelist file, ``d{model_name}_in``, -where ``model_name=[datm,dlnd,dice,docn,drof,dwav]``. +where ``model_name=[datm,dlnd,dglc,dice,docn,drof,dwav]``. The following namelist variables appear in each data model namelist: @@ -381,6 +381,8 @@ The following namelist variables appear in each data model namelist: :ref:`Data Land ` + :ref:`Data Land-Ice ` + :ref:`Data Ocean ` :ref:`Data Runoff ` From 6e04eeacad34e032ac8df3f093bf5893fe40daaa Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 28 Mar 2024 08:00:14 -0600 Subject: [PATCH 059/170] update the testlist to work on derecho --- cime_config/testdefs/testlist_cdeps.xml | 68 ++++++++++++------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/cime_config/testdefs/testlist_cdeps.xml b/cime_config/testdefs/testlist_cdeps.xml index 03cbfb0c7..2147b04d3 100644 --- a/cime_config/testdefs/testlist_cdeps.xml +++ b/cime_config/testdefs/testlist_cdeps.xml @@ -1,97 +1,97 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -100,25 +100,25 @@ - + - + - + - + - + - + @@ -127,9 +127,9 @@ - + - + @@ -138,9 +138,9 @@ - + - + From 368ea9568731e5210d601b01a207fb417fa08792 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 28 Mar 2024 08:00:14 -0600 Subject: [PATCH 060/170] update the testlist to work on derecho --- cime_config/testdefs/testlist_cdeps.xml | 68 ++++++++++++------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/cime_config/testdefs/testlist_cdeps.xml b/cime_config/testdefs/testlist_cdeps.xml index 03cbfb0c7..2147b04d3 100644 --- a/cime_config/testdefs/testlist_cdeps.xml +++ b/cime_config/testdefs/testlist_cdeps.xml @@ -1,97 +1,97 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -100,25 +100,25 @@ - + - + - + - + - + - + @@ -127,9 +127,9 @@ - + - + @@ -138,9 +138,9 @@ - + - + From a700dd1fba4993a2c1b88ec8de96c23e4c55228c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 28 Mar 2024 13:17:08 -0600 Subject: [PATCH 061/170] added new derecho tests across the system including in dglc --- datm/cime_config/testdefs/testlist_datm.xml | 58 +++++++++------------ dglc/cime_config/buildnml | 11 ++-- dglc/cime_config/stream_definition_dglc.xml | 33 ++++++++++++ dglc/cime_config/testdefs/testlist_dglc.xml | 29 +++++++++++ dice/cime_config/testdefs/testlist_dice.xml | 8 +-- dlnd/cime_config/testdefs/testlist_dlnd.xml | 4 +- docn/cime_config/testdefs/testlist_docn.xml | 14 ++--- dwav/cime_config/testdefs/testlist_dwav.xml | 4 +- 8 files changed, 107 insertions(+), 54 deletions(-) create mode 100644 dglc/cime_config/testdefs/testlist_dglc.xml diff --git a/datm/cime_config/testdefs/testlist_datm.xml b/datm/cime_config/testdefs/testlist_datm.xml index ce9efb45a..0669f0518 100644 --- a/datm/cime_config/testdefs/testlist_datm.xml +++ b/datm/cime_config/testdefs/testlist_datm.xml @@ -3,108 +3,100 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - + diff --git a/dglc/cime_config/buildnml b/dglc/cime_config/buildnml index 4dfef53b8..78dc9446f 100755 --- a/dglc/cime_config/buildnml +++ b/dglc/cime_config/buildnml @@ -79,19 +79,18 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path namelist_file = os.path.join(confdir, "dglc_in") nmlgen.write_output_file(namelist_file, data_list_path, groups=['dglc_nml']) - # Determine streams - streamlist = nmlgen.get_streams() - if type(streamlist) == type(str()): - streamlist = [] - # Generate dglc.streams.xml print("dglc_mode is {}".format(dglc_mode)) - if 'NOEVOLVE' in dglc_mode: + if 'noevolve' in dglc_mode: generate_stream_file = False else: generate_stream_file = True #endif if generate_stream_file: + # Determine streams + streamlist = nmlgen.get_streams() + if type(streamlist) == type(str()): + streamlist = [] outfile = os.path.join(confdir, "dglc.streams"+inst_string+".xml" ) schema_file = os.path.join(_CDEPS_CONFIG,"stream_definition_v2.0.xsd") stream_file = os.path.join(_CDEPS_CONFIG,os.pardir, "dglc","cime_config","stream_definition_dglc.xml") diff --git a/dglc/cime_config/stream_definition_dglc.xml b/dglc/cime_config/stream_definition_dglc.xml index 2811e8806..80ba75c5b 100644 --- a/dglc/cime_config/stream_definition_dglc.xml +++ b/dglc/cime_config/stream_definition_dglc.xml @@ -13,4 +13,37 @@ + + + + + unset + + + unset + + + unset unset + + null + + bilinear + + null + 0 + 0 + 0 + 0 + + lower + + + cycle + + + 1.5 + + single + + diff --git a/dglc/cime_config/testdefs/testlist_dglc.xml b/dglc/cime_config/testdefs/testlist_dglc.xml new file mode 100644 index 000000000..6557dec24 --- /dev/null +++ b/dglc/cime_config/testdefs/testlist_dglc.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dice/cime_config/testdefs/testlist_dice.xml b/dice/cime_config/testdefs/testlist_dice.xml index eac359d4e..7ef974fd4 100644 --- a/dice/cime_config/testdefs/testlist_dice.xml +++ b/dice/cime_config/testdefs/testlist_dice.xml @@ -1,17 +1,17 @@ - + - + - + - + diff --git a/dlnd/cime_config/testdefs/testlist_dlnd.xml b/dlnd/cime_config/testdefs/testlist_dlnd.xml index de52bac4a..a18c070de 100644 --- a/dlnd/cime_config/testdefs/testlist_dlnd.xml +++ b/dlnd/cime_config/testdefs/testlist_dlnd.xml @@ -1,9 +1,9 @@ - + - + diff --git a/docn/cime_config/testdefs/testlist_docn.xml b/docn/cime_config/testdefs/testlist_docn.xml index 5dea00d48..1fb29d5ba 100644 --- a/docn/cime_config/testdefs/testlist_docn.xml +++ b/docn/cime_config/testdefs/testlist_docn.xml @@ -1,29 +1,29 @@ - + - + - + - + - + - + - + diff --git a/dwav/cime_config/testdefs/testlist_dwav.xml b/dwav/cime_config/testdefs/testlist_dwav.xml index 0fed61eb2..65dd63d9e 100644 --- a/dwav/cime_config/testdefs/testlist_dwav.xml +++ b/dwav/cime_config/testdefs/testlist_dwav.xml @@ -1,9 +1,9 @@ - + - + From 0fdefdfb9323d6f318781e66e39d17146c457188 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 28 Mar 2024 13:18:00 -0600 Subject: [PATCH 062/170] removed cdeps/cime_config/testdefs - tests are already defined in cdeps/dxxx/cime_config/testdefs --- cime_config/testdefs/testlist_cdeps.xml | 150 ------------------------ 1 file changed, 150 deletions(-) delete mode 100644 cime_config/testdefs/testlist_cdeps.xml diff --git a/cime_config/testdefs/testlist_cdeps.xml b/cime_config/testdefs/testlist_cdeps.xml deleted file mode 100644 index 2147b04d3..000000000 --- a/cime_config/testdefs/testlist_cdeps.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From c6522b22c6c7f9c15cce730b0c36ae7f01318b2a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 29 Mar 2024 07:36:11 -0600 Subject: [PATCH 063/170] fixed regression testing failures and also added aux_cdeps_noresm test category --- datm/cime_config/testdefs/testlist_datm.xml | 15 ++++++++++++++- dglc/cime_config/buildnml | 1 + dglc/cime_config/testdefs/testlist_dglc.xml | 3 +++ dice/cime_config/testdefs/testlist_dice.xml | 2 ++ dlnd/cime_config/testdefs/testlist_dlnd.xml | 1 + docn/cime_config/testdefs/testlist_docn.xml | 3 +++ drof/cime_config/testdefs/testlist_drof.xml | 1 + dwav/cime_config/testdefs/testlist_dwav.xml | 1 + 8 files changed, 26 insertions(+), 1 deletion(-) diff --git a/datm/cime_config/testdefs/testlist_datm.xml b/datm/cime_config/testdefs/testlist_datm.xml index 0669f0518..a20e56305 100644 --- a/datm/cime_config/testdefs/testlist_datm.xml +++ b/datm/cime_config/testdefs/testlist_datm.xml @@ -1,14 +1,16 @@ - + + + @@ -17,6 +19,7 @@ + @@ -25,6 +28,7 @@ + @@ -33,6 +37,7 @@ + @@ -41,6 +46,7 @@ + @@ -49,6 +55,7 @@ + @@ -57,6 +64,7 @@ + @@ -65,6 +73,7 @@ + @@ -73,6 +82,7 @@ + @@ -81,6 +91,7 @@ + @@ -89,6 +100,7 @@ + @@ -97,6 +109,7 @@ + diff --git a/dglc/cime_config/buildnml b/dglc/cime_config/buildnml index 78dc9446f..a18295e6e 100755 --- a/dglc/cime_config/buildnml +++ b/dglc/cime_config/buildnml @@ -81,6 +81,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path # Generate dglc.streams.xml print("dglc_mode is {}".format(dglc_mode)) + if 'noevolve' in dglc_mode: generate_stream_file = False else: diff --git a/dglc/cime_config/testdefs/testlist_dglc.xml b/dglc/cime_config/testdefs/testlist_dglc.xml index 6557dec24..194773fa7 100644 --- a/dglc/cime_config/testdefs/testlist_dglc.xml +++ b/dglc/cime_config/testdefs/testlist_dglc.xml @@ -4,6 +4,7 @@ + @@ -12,6 +13,7 @@ + @@ -20,6 +22,7 @@ + diff --git a/dice/cime_config/testdefs/testlist_dice.xml b/dice/cime_config/testdefs/testlist_dice.xml index 7ef974fd4..909980ce6 100644 --- a/dice/cime_config/testdefs/testlist_dice.xml +++ b/dice/cime_config/testdefs/testlist_dice.xml @@ -4,6 +4,7 @@ + @@ -12,6 +13,7 @@ + diff --git a/dlnd/cime_config/testdefs/testlist_dlnd.xml b/dlnd/cime_config/testdefs/testlist_dlnd.xml index a18c070de..59026878c 100644 --- a/dlnd/cime_config/testdefs/testlist_dlnd.xml +++ b/dlnd/cime_config/testdefs/testlist_dlnd.xml @@ -4,6 +4,7 @@ + diff --git a/docn/cime_config/testdefs/testlist_docn.xml b/docn/cime_config/testdefs/testlist_docn.xml index 1fb29d5ba..5c279cabf 100644 --- a/docn/cime_config/testdefs/testlist_docn.xml +++ b/docn/cime_config/testdefs/testlist_docn.xml @@ -4,6 +4,7 @@ + @@ -12,6 +13,7 @@ + @@ -20,6 +22,7 @@ + diff --git a/drof/cime_config/testdefs/testlist_drof.xml b/drof/cime_config/testdefs/testlist_drof.xml index 0515f0fc6..38b5fb142 100644 --- a/drof/cime_config/testdefs/testlist_drof.xml +++ b/drof/cime_config/testdefs/testlist_drof.xml @@ -4,6 +4,7 @@ + diff --git a/dwav/cime_config/testdefs/testlist_dwav.xml b/dwav/cime_config/testdefs/testlist_dwav.xml index 65dd63d9e..1864398ad 100644 --- a/dwav/cime_config/testdefs/testlist_dwav.xml +++ b/dwav/cime_config/testdefs/testlist_dwav.xml @@ -4,6 +4,7 @@ + From 4ee74e87db78ca00b9660b32561ec28a399bdb88 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 29 Mar 2024 09:36:55 -0600 Subject: [PATCH 064/170] removed unused variable declaration --- dglc/dglc_datamode_noevolve_mod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 7b6427497..8e681b34e 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -78,7 +78,6 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fl ! local variables integer :: ns - logical :: isPresent, isSet character(len=CS) :: cnum type(fldlist_type), pointer :: fldList !------------------------------------------------------------------------------- From 24613eb03c8b3a19edea71344b9143aa1da7b088 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 29 Mar 2024 10:31:36 -0600 Subject: [PATCH 065/170] need CESMCOUPLED cpp here --- dglc/glc_comp_nuopc.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 26b3d15d0..b78bb3537 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -30,7 +30,9 @@ module cdeps_dglc_comp use shr_cal_mod , only : shr_cal_ymd2date use shr_log_mod , only : shr_log_setLogUnit use shr_string_mod , only : shr_string_listGetNum, shr_string_listGetName +#ifdef CESMCOUPLED use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat +#endif use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_init_from_config use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init From f7d6739925bbb25e136b253ff742209457b1ff05 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 29 Mar 2024 10:47:22 -0600 Subject: [PATCH 066/170] clean up --- dglc/glc_comp_nuopc.F90 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index b78bb3537..ad521bf9b 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -66,7 +66,6 @@ module cdeps_dglc_comp logical :: get_import_data = .false. ! namelist input - character(CS) :: icesheet_names(max_icesheets) = nullstr character(CL) :: model_meshfiles(max_icesheets) = nullstr character(CL) :: model_datafiles(max_icesheets) = nullstr integer :: nx_global(max_icesheets) = 0 @@ -186,7 +185,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: nu ! unit number integer :: ierr ! error code integer :: bcasttmp(3) - integer :: ns, n + integer :: ns character(len=CS) :: cnum character(len=ESMF_MAXSTR) :: model_datafiles_list ! colon separated string containing input datafiles character(len=ESMF_MAXSTR) :: model_meshfiles_list ! colon separated string containing model meshfiles @@ -328,8 +327,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) integer :: current_mon ! model month integer :: current_day ! model day integer :: current_tod ! model sec into model date - integer :: localpet - integer :: n, ns + integer :: ns character(CL) :: cvalue character(CS) :: cns logical :: ispresent, isset From a5f6ecb88ba20d26e2e21f5f10cf92f6f9a3d74d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 29 Mar 2024 11:36:47 -0600 Subject: [PATCH 067/170] fixed indentation --- datm/atm_comp_nuopc.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 233e4c2b5..7a2a41c7b 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -29,7 +29,7 @@ module cdeps_datm_comp use shr_const_mod , only : shr_const_cday use shr_sys_mod , only : shr_sys_abort use shr_cal_mod , only : shr_cal_ymd2date - use shr_log_mod , only : shr_log_setLogUnit + use shr_log_mod , only : shr_log_setLogUnit use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_init_from_config, shr_strdata_advance use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_setOrbs From 9b92a2bfba11229fe8dfa36d16fa3abdc0b7ca75 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 30 Mar 2024 10:05:08 -0600 Subject: [PATCH 068/170] Increase stream filename length to CX (512) from CL (256) (#265) * Increase stream filename length to CX (512) from CL (256) * Move testlist from cheyenne to derecho resolving #265 * Change more references of Cheyenne to Derecho in test lists and in datm document * Remove _Vnuopc in testlists since NUOPC is the default and this is unneeded --- datm/cime_config/testdefs/testlist_datm.xml | 54 ++++++++++----------- dice/cime_config/testdefs/testlist_dice.xml | 8 +-- dlnd/cime_config/testdefs/testlist_dlnd.xml | 4 +- doc/source/datm.rst | 2 +- docn/cime_config/testdefs/testlist_docn.xml | 12 ++--- drof/cime_config/testdefs/testlist_drof.xml | 4 +- dwav/cime_config/testdefs/testlist_dwav.xml | 4 +- streams/dshr_strdata_mod.F90 | 22 ++++----- streams/dshr_stream_mod.F90 | 16 +++--- 9 files changed, 63 insertions(+), 63 deletions(-) diff --git a/datm/cime_config/testdefs/testlist_datm.xml b/datm/cime_config/testdefs/testlist_datm.xml index ce9efb45a..eab4c646e 100644 --- a/datm/cime_config/testdefs/testlist_datm.xml +++ b/datm/cime_config/testdefs/testlist_datm.xml @@ -3,108 +3,108 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/dice/cime_config/testdefs/testlist_dice.xml b/dice/cime_config/testdefs/testlist_dice.xml index eac359d4e..2a05956e0 100644 --- a/dice/cime_config/testdefs/testlist_dice.xml +++ b/dice/cime_config/testdefs/testlist_dice.xml @@ -1,17 +1,17 @@ - + - + - + - + diff --git a/dlnd/cime_config/testdefs/testlist_dlnd.xml b/dlnd/cime_config/testdefs/testlist_dlnd.xml index de52bac4a..9ace7ec7d 100644 --- a/dlnd/cime_config/testdefs/testlist_dlnd.xml +++ b/dlnd/cime_config/testdefs/testlist_dlnd.xml @@ -1,9 +1,9 @@ - + - + diff --git a/doc/source/datm.rst b/doc/source/datm.rst index ff067209c..e70c703da 100644 --- a/doc/source/datm.rst +++ b/doc/source/datm.rst @@ -60,7 +60,7 @@ ERA5 (``datm_datamode_era5_mod.F90``) .. note:: Due to the high temporal and spatial resoultion of ERA5 dataset, only 2019 - data is staged on NCAR's Cheyenne platform under + data is staged on NCAR's Derecho platform under `$CESMDATAROOT/inputdata/atm/datm7/ERA5` .. note:: diff --git a/docn/cime_config/testdefs/testlist_docn.xml b/docn/cime_config/testdefs/testlist_docn.xml index 5dea00d48..2549b1233 100644 --- a/docn/cime_config/testdefs/testlist_docn.xml +++ b/docn/cime_config/testdefs/testlist_docn.xml @@ -1,25 +1,25 @@ - + - + - + - + - + - + diff --git a/drof/cime_config/testdefs/testlist_drof.xml b/drof/cime_config/testdefs/testlist_drof.xml index 0515f0fc6..0fa691baf 100644 --- a/drof/cime_config/testdefs/testlist_drof.xml +++ b/drof/cime_config/testdefs/testlist_drof.xml @@ -1,9 +1,9 @@ - + - + diff --git a/dwav/cime_config/testdefs/testlist_dwav.xml b/dwav/cime_config/testdefs/testlist_dwav.xml index 0fed61eb2..b0e93a65d 100644 --- a/dwav/cime_config/testdefs/testlist_dwav.xml +++ b/dwav/cime_config/testdefs/testlist_dwav.xml @@ -1,9 +1,9 @@ - + - + diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index c056639d3..e9159f69b 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -21,7 +21,7 @@ module dshr_strdata_mod use ESMF , only : ESMF_REGION_TOTAL, ESMF_FieldGet, ESMF_TraceRegionExit, ESMF_TraceRegionEnter use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite use shr_kind_mod , only : r8=>shr_kind_r8, r4=>shr_kind_r4, i2=>shr_kind_I2 - use shr_kind_mod , only : cs=>shr_kind_cs, cl=>shr_kind_cl, cxx=>shr_kind_cxx + use shr_kind_mod , only : cs=>shr_kind_cs, cl=>shr_kind_cl, cxx=>shr_kind_cxx, cx=>shr_kind_cx use shr_sys_mod , only : shr_sys_abort use shr_const_mod , only : shr_const_pi, shr_const_cDay, shr_const_spval use shr_cal_mod , only : shr_cal_calendarname, shr_cal_timeSet @@ -389,7 +389,7 @@ subroutine shr_strdata_init(sdat, model_clock, stream_name, rc) character(CS) :: calendar ! calendar name integer :: ns ! stream index integer :: m ! generic index - character(CL) :: fileName ! generic file name + character(CX) :: fileName ! generic file name integer :: nfld ! loop stream field index type(ESMF_Field) :: lfield ! temporary type(ESMF_Field) :: lfield_dst ! temporary @@ -677,7 +677,7 @@ subroutine shr_strdata_get_stream_nlev(sdat, stream_index, rc) type(ESMF_VM) :: vm type(file_desc_t) :: pioid integer :: rcode - character(CL) :: filename + character(CX) :: filename integer :: dimid integer :: stream_nlev character(*), parameter :: subname = '(shr_strdata_set_stream_domain) ' @@ -694,7 +694,7 @@ subroutine shr_strdata_get_stream_nlev(sdat, stream_index, rc) if (sdat%mainproc) then call shr_stream_getData(sdat%stream(stream_index), 1, filename) end if - call ESMF_VMBroadCast(vm, filename, CL, 0, rc=rc) + call ESMF_VMBroadCast(vm, filename, CX, 0, rc=rc) rcode = pio_openfile(sdat%pio_subsystem, pioid, sdat%io_type, trim(filename), pio_nowrite) rcode = pio_inq_dimid(pioid, trim(sdat%stream(stream_index)%lev_dimname), dimid) rcode = pio_inq_dimlen(pioid, dimid, stream_nlev) @@ -726,7 +726,7 @@ subroutine shr_strdata_get_stream_domain(sdat, stream_index, fldname, flddata, r type(var_desc_t) :: varid type(file_desc_t) :: pioid integer :: rcode - character(CL) :: filename + character(CX) :: filename type(io_desc_t) :: pio_iodesc real(r4), allocatable :: data_real(:) real(r8), allocatable :: data_double(:) @@ -743,7 +743,7 @@ subroutine shr_strdata_get_stream_domain(sdat, stream_index, fldname, flddata, r if (sdat%mainproc) then call shr_stream_getData(sdat%stream(stream_index), 1, filename) end if - call ESMF_VMBroadCast(vm, filename, CL, 0, rc=rc) + call ESMF_VMBroadCast(vm, filename, CX, 0, rc=rc) ! Open the file rcode = pio_openfile(sdat%pio_subsystem, pioid, sdat%io_type, trim(filename), pio_nowrite) @@ -1305,10 +1305,10 @@ subroutine shr_strdata_readLBUB(sdat, ns, mDate, mSec, newData, istr, rc) real(r8) :: rDateM,rDateLB,rDateUB ! model,LB,UB dates with fractional days integer :: n_lb, n_ub integer :: i - character(CL) :: filename_lb - character(CL) :: filename_ub - character(CL) :: filename_next - character(CL) :: filename_prev + character(CX) :: filename_lb + character(CX) :: filename_ub + character(CX) :: filename_next + character(CX) :: filename_prev logical :: find_bounds character(*), parameter :: subname = '(shr_strdata_readLBUB) ' character(*), parameter :: F00 = "('(shr_strdata_readLBUB) ',8a)" @@ -1432,7 +1432,7 @@ subroutine shr_strdata_readstrm(sdat, per_stream, stream, fldbun_data, & ! local variables integer :: stream_nlev type(ESMF_Field) :: field_dst, field_vector_dst - character(CL) :: currfile + character(CX) :: currfile logical :: fileexists logical :: fileopen type(file_desc_t) :: pioid diff --git a/streams/dshr_stream_mod.F90 b/streams/dshr_stream_mod.F90 index ac16d18d6..e73fb19ca 100644 --- a/streams/dshr_stream_mod.F90 +++ b/streams/dshr_stream_mod.F90 @@ -15,7 +15,7 @@ module dshr_stream_mod ! containing those dates. ! ------------------------------------------------------------------------------- - use shr_kind_mod , only : r8=>shr_kind_r8, cs=>shr_kind_cs, cl=>shr_kind_cl, cxx=>shr_kind_cxx + use shr_kind_mod , only : r8=>shr_kind_r8, cs=>shr_kind_cs, cl=>shr_kind_cl, cxx=>shr_kind_cxx, cx=>shr_kind_cx use shr_sys_mod , only : shr_sys_abort use shr_const_mod , only : shr_const_cday use shr_string_mod , only : shr_string_leftalign_and_convert_tabs, shr_string_parseCFtunit @@ -85,7 +85,7 @@ module dshr_stream_mod ! a useful derived type to use inside shr_streamType --- type shr_stream_file_type - character(CL) :: name = shr_stream_file_null ! the file name (full pathname) + character(CX) :: name = shr_stream_file_null ! the file name (full pathname) logical :: haveData = .false. ! has t-coord data been read in? integer :: nt = 0 ! size of time dimension integer ,allocatable :: date(:) ! t-coord date: yyyymmdd @@ -125,7 +125,7 @@ module dshr_stream_mod integer :: n_gvd = -1 ! file/sample of greatest valid date logical :: found_gvd = .false. ! T <=> k_gvd,n_gvd have been set logical :: fileopen = .false. ! is current file open - character(CL) :: currfile = ' ' ! current filename + character(CX) :: currfile = ' ' ! current filename integer :: nvars ! number of stream variables character(CL) :: stream_vectors = 'null' ! stream vectors names type(file_desc_t) :: currpioid ! current pio file desc @@ -379,7 +379,7 @@ subroutine shr_stream_init_from_xml(streamfilename, streamdat, isroot_task, logu allocate(streamdat(i)%varlist(streamdat(i)%nvars)) endif do n=1,streamdat(i)%nfiles - call ESMF_VMBroadCast(vm, streamdat(i)%file(n)%name, CL, 0, rc=rc) + call ESMF_VMBroadCast(vm, streamdat(i)%file(n)%name, CX, 0, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return enddo do n=1,streamdat(i)%nvars @@ -1219,7 +1219,7 @@ subroutine shr_stream_readTCoord(strm, k, isroot_task, rc) integer,optional ,intent(out) :: rc ! return code ! local variables - character(CL) :: fileName ! filename to read + character(CX) :: fileName ! filename to read integer :: nt integer :: num,n integer :: din,dout @@ -1513,7 +1513,7 @@ subroutine shr_stream_getCalendar(strm, k, calendar) type(ESMF_VM) :: vm integer :: myid integer :: vid, n - character(CL) :: fileName + character(CX) :: fileName character(CL) :: lcal integer(PIO_OFFSET_KIND) :: attlen integer :: old_handle @@ -1745,13 +1745,13 @@ subroutine shr_stream_restIO(pioid, streams, mode) integer :: maxnt = 0 integer, allocatable :: tmp(:) integer :: logunit - character(len=CL) :: fname, rfname, rsfname + character(len=CX) :: fname, rfname, rsfname !------------------------------------------------------------------------------- if (mode .eq. 'define') then - rcode = pio_def_dim(pioid, 'strlen', CL, dimid_str) + rcode = pio_def_dim(pioid, 'strlen', CX, dimid_str) do k=1,size(streams) ! maxnfiles is the maximum number of files across all streams logunit = streams(k)%logunit From e88f40c03cf5a3b9d531baba08de5b99d33f82f3 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 30 Mar 2024 10:06:55 -0600 Subject: [PATCH 069/170] updates for dglc features required --- dglc/cime_config/buildnml | 4 +- dglc/cime_config/config_component.xml | 13 +-- dglc/cime_config/namelist_definition_dglc.xml | 37 +++---- dglc/dglc_datamode_noevolve_mod.F90 | 96 +++++++++---------- dglc/glc_comp_nuopc.F90 | 37 ++++--- 5 files changed, 75 insertions(+), 112 deletions(-) diff --git a/dglc/cime_config/buildnml b/dglc/cime_config/buildnml index a18295e6e..b68516429 100755 --- a/dglc/cime_config/buildnml +++ b/dglc/cime_config/buildnml @@ -60,7 +60,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path scol_lat = float(case.get_value('PTS_LAT')) else: scol_lat = -999. - if (scol_lon > -999. and scol_lat > 999.): + if (scol_lon > -999. or scol_lat > -999.): expect(False, "single column mode for DGLC is not currently allowed") @@ -80,7 +80,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path nmlgen.write_output_file(namelist_file, data_list_path, groups=['dglc_nml']) # Generate dglc.streams.xml - print("dglc_mode is {}".format(dglc_mode)) + logger.debug("dglc_mode is {}".format(dglc_mode)) if 'noevolve' in dglc_mode: generate_stream_file = False diff --git a/dglc/cime_config/config_component.xml b/dglc/cime_config/config_component.xml index d8ef6469f..15271a5b8 100644 --- a/dglc/cime_config/config_component.xml +++ b/dglc/cime_config/config_component.xml @@ -34,7 +34,7 @@ run_component_dglc env_run.xml - + NOEVOLVE mode is used in CESM as follows. In typical runs, CISM is not evolving; CLM computes the surface mass balance (SMB) and sends it to CISM, but CISM’s ice sheet geometry @@ -43,17 +43,6 @@ - - logical - FALSE - run_component_dglc - env_run.xml - - If true, have the mediator calculate import values that are sent back to - GLC even in GLC is in NOEVOLVE mode - - - logical FALSE diff --git a/dglc/cime_config/namelist_definition_dglc.xml b/dglc/cime_config/namelist_definition_dglc.xml index 20dd0bde1..8bc4e0c0e 100644 --- a/dglc/cime_config/namelist_definition_dglc.xml +++ b/dglc/cime_config/namelist_definition_dglc.xml @@ -42,7 +42,6 @@ dglc_nml $DIN_LOC_ROOT/glc/cism/Antarctica/ISMIP6_Antarctica_8km.init.c210908.nc:$DIN_LOC_ROOT/glc/cism/Greenland/greenland_4km_epsg3413_c171126.nc - $DIN_LOC_ROOT/glc/cism/Greenland/gland20.input_c150415.nc $DIN_LOC_ROOT/glc/cism/Greenland/greenland_4km_epsg3413_c171126.nc $DIN_LOC_ROOT/glc/cism/Antarctica/ISMIP6_Antarctica_8km.init.c210908.nc @@ -65,18 +64,19 @@ - + real(20) streams dglc_nml - 3.94162024004361e-07,1.57664809601744e-06 - 1. - 3.94162024004361e-07 - 1.57664809601744e-06 + 8000,4000 + 4000 + 8000 - colon deliminted string of inputdata files + model internal grid size(s) in m which is used to compute the internal model + model area in radians**2 using the formula (model_internal_gridsize/shr_const_rearth)**2 - + for more than one ice sheet this will contain an array of model_internal_gridsize values. @@ -91,8 +91,8 @@ 76 - global size(s) of nx - for more than one ice sheets this will contain an array of nx values + global size(s) of nx where for more than one ice sheet this + will contain an array of nx values @@ -107,8 +107,8 @@ 141 - global size(s) of ny - for more than one ice sheets this will contain an array of ny values + global size(s) of ny where for more than one ice sheet this + will contain an array of ny values @@ -124,21 +124,6 @@ - - logical - dglc - dglc_nml - - If set to true, than dglc will advertise and realize import - fields even if it does not do anything with them. This - capability is used, for example, in generating coupler history - data for GLC spinup runs. - - - $DGLC_GET_IMPORT_DATA - - - logical dglc diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 8e681b34e..9a5431e62 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -7,7 +7,7 @@ module dglc_datamode_noevolve_mod use NUOPC , only : NUOPC_Advertise, NUOPC_IsConnected use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort - use shr_const_mod , only : SHR_CONST_RHOICE, SHR_CONST_RHOSW + use shr_const_mod , only : SHR_CONST_RHOICE, SHR_CONST_RHOSW, SHR_CONST_REARTH use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add use dshr_strdata_mod , only : shr_strdata_type @@ -27,7 +27,6 @@ module dglc_datamode_noevolve_mod logical :: initialized_noevolve = .false. integer :: num_icesheets real(r8) :: thk0 = 1._r8 - logical :: get_import_data ! Data structure to enable multiple ice sheets type icesheet_ptr_t @@ -65,13 +64,12 @@ module dglc_datamode_noevolve_mod !=============================================================================== subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fldsimport, & - get_import_data_in, flds_scalar_name, rc) + flds_scalar_name, rc) ! input/output variables type(ESMF_State) , intent(inout) :: NStateExp(:) type(fldlist_type), pointer :: fldsexport type(ESMF_State) , intent(inout) :: NStateImp(:) - logical , intent(in) :: get_import_data_in type(fldlist_type), pointer :: fldsimport character(len=*) , intent(in) :: flds_scalar_name integer , intent(out) :: rc @@ -84,9 +82,6 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fl rc = ESMF_SUCCESS - ! Set module vraiable - get_import_data = get_import_data_in - !-------------------------------- ! Create nested state for active ice sheets only !-------------------------------- @@ -114,22 +109,20 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fl enddo ! Advertise import fields if appropriate - if (get_import_data) then - call dshr_fldList_add(fldsImport, trim(flds_scalar_name)) - call dshr_fldList_add(fldsImport, field_in_tsrf) - call dshr_fldList_add(fldsImport, field_in_qice) - - do ns = 1,num_icesheets - write(cnum,'(i0)') ns - fldlist => fldsImport ! the head of the linked list - do while (associated(fldlist)) - call NUOPC_Advertise(NStateImp(ns), standardName=fldlist%stdname, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite('(dglc_comp_advertise): To_glc'//trim(cnum)//"_"//trim(fldList%stdname), ESMF_LOGMSG_INFO) - fldList => fldList%next - end do - enddo - end if + call dshr_fldList_add(fldsImport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsImport, field_in_tsrf) + call dshr_fldList_add(fldsImport, field_in_qice) + + do ns = 1,num_icesheets + write(cnum,'(i0)') ns + fldlist => fldsImport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(NStateImp(ns), standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite('(dglc_comp_advertise): To_glc'//trim(cnum)//"_"//trim(fldList%stdname), ESMF_LOGMSG_INFO) + fldList => fldList%next + end do + enddo end subroutine dglc_datamode_noevolve_advertise @@ -172,39 +165,37 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) end do ! initialize pointers to import fields if appropriate - if (get_import_data) then - allocate(Sl_tsrf(num_icesheets)) - allocate(Flgl_qice(num_icesheets)) - - do ns = 1,num_icesheets - ! NOTE: the field is connected ONLY if the MED->GLC entry is in the nuopc.runconfig file - ! This restriction occurs even if the field was advertised - if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_tsrf)) then - call dshr_state_getfldptr(NStateImp(ns), field_in_tsrf, fldptr1=Sl_tsrf(ns)%ptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_qice)) then - call dshr_state_getfldptr(NStateImp(ns), field_in_qice, fldptr1=Flgl_qice(ns)%ptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - end do - end if + allocate(Sl_tsrf(num_icesheets)) + allocate(Flgl_qice(num_icesheets)) + + do ns = 1,num_icesheets + ! NOTE: the field is connected ONLY if the MED->GLC entry is in the nuopc.runconfig file + ! This restriction occurs even if the field was advertised + if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_tsrf)) then + call dshr_state_getfldptr(NStateImp(ns), field_in_tsrf, fldptr1=Sl_tsrf(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_qice)) then + call dshr_state_getfldptr(NStateImp(ns), field_in_qice, fldptr1=Flgl_qice(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + end do end subroutine dglc_datamode_noevolve_init_pointers !=============================================================================== subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & - model_meshes, model_areas, input_files, rc) + model_meshes, model_internal_gridsize, model_datafiles, rc) ! Assume that the model mesh is the same as the input data mesh ! input/output variables - type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info - integer , intent(in) :: io_type ! pio info - integer , intent(in) :: io_format ! pio info - type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes - real(r8) , intent(in) :: model_areas(:) ! internal model ice sheets areas (radians**2) - character(len=*) , intent(in) :: input_files(:) ! input file names + type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info + integer , intent(in) :: io_type ! pio info + integer , intent(in) :: io_format ! pio info + type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes + real(r8) , intent(in) :: model_internal_gridsize(:) ! internal model gridsizes (m) + character(len=*) , intent(in) :: model_datafiles(:) ! input file names integer , intent(out) :: rc ! local variables @@ -251,8 +242,11 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Determine "glc_area" ; + ! Sg_areas is in radians + ! SHR_CONST_REARTH is the radius of earth in m + ! model_internal_gridsize is the internal model gridsize in m do ng = 1,lsize - Sg_area(ns)%ptr(ng) = model_areas(ns) + Sg_area(ns)%ptr(ng) = (model_internal_gridsize(ns)/SHR_CONST_REARTH)**2 end do ! Create module level field bundle @@ -271,12 +265,12 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create pioid and pio_iodesc at the module level - inquire(file=trim(input_files(ns)), exist=exists) + inquire(file=trim(model_datafiles(ns)), exist=exists) if (.not.exists) then - write(6,'(a)')' ERROR: model input file '//trim(input_files(ns))//' does not exist' + write(6,'(a)')' ERROR: model input file '//trim(model_datafiles(ns))//' does not exist' call shr_sys_abort() end if - rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(input_files(ns)), pio_nowrite) + rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(model_datafiles(ns)), pio_nowrite) call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) rcode = pio_inq_varid(pioid, 'thk', varid) rcode = pio_inq_varndims(pioid, varid, ndims) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index ad521bf9b..233794fd3 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -63,14 +63,13 @@ module cdeps_dglc_comp character(*) , parameter :: nullstr = 'null' integer , parameter :: max_icesheets = 10 ! maximum number of ice sheets for namelist input integer :: num_icesheets ! actual number of ice sheets - logical :: get_import_data = .false. ! namelist input character(CL) :: model_meshfiles(max_icesheets) = nullstr character(CL) :: model_datafiles(max_icesheets) = nullstr integer :: nx_global(max_icesheets) = 0 integer :: ny_global(max_icesheets) = 0 - real(r8) :: model_areas(max_icesheets) = 1.e36 + real(r8) :: model_internal_gridsize(max_icesheets) = 1.e36 ! module variables for multiple ice sheets type(shr_strdata_type) , allocatable :: sdat(:) @@ -184,7 +183,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: inst_index ! number of current instance (ie. 1) integer :: nu ! unit number integer :: ierr ! error code - integer :: bcasttmp(3) + integer :: bcasttmp(2) integer :: ns character(len=CS) :: cnum character(len=ESMF_MAXSTR) :: model_datafiles_list ! colon separated string containing input datafiles @@ -194,8 +193,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Note that the suffix '-list' refers to a colon delimited string of names namelist / dglc_nml / datamode, & - model_meshfiles_list, model_datafiles_list, model_areas, nx_global, ny_global, & - get_import_data, restfilm, skip_restart_read + model_meshfiles_list, model_datafiles_list, model_internal_gridsize, nx_global, ny_global, & + restfilm, skip_restart_read rc = ESMF_SUCCESS @@ -238,22 +237,19 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,'(a,a)')' case_name = ',trim(case_name) write(logunit,'(a,a)')' datamode = ',trim(datamode) do ns = 1,num_icesheets - write(logunit,'(a,i4 )') ' ice_sheet index = ',ns - write(logunit,'(a,a )') ' model_meshfile = ',trim(model_meshfiles(ns)) - write(logunit,'(a,a )') ' model_datafile = ',trim(model_datafiles(ns)) - write(logunit,'(a,i10)') ' nx_global = ',nx_global(ns) - write(logunit,'(a,i10)') ' ny_global = ',ny_global(ns) - write(logunit,'(a,d13.5)')' model_areas = ',model_areas(ns) + write(logunit,'(a,i4 )') ' ice_sheet index = ',ns + write(logunit,'(a,a )') ' model_meshfile = ',trim(model_meshfiles(ns)) + write(logunit,'(a,a )') ' model_datafile = ',trim(model_datafiles(ns)) + write(logunit,'(a,d13.5)')' model_internal_gridsize = ',model_internal_gridsize(ns) + write(logunit,'(a,i10)') ' nx_global = ',nx_global(ns) + write(logunit,'(a,i10)') ' ny_global = ',ny_global(ns) end do write(logunit,'(a,a )')' restfilm = ',trim(restfilm) - write(logunit,'(a,l6)')' get_import_data = ',get_import_data write(logunit,'(a,l6)')' skip_restart_read = ',skip_restart_read bcasttmp(1) = 0 if(skip_restart_read) bcasttmp(1) = 1 - bcasttmp(2) = 0 - if(get_import_data) bcasttmp(2) = 1 - bcasttmp(3) = num_icesheets + bcasttmp(2) = num_icesheets endif ! Broadcast namelist input @@ -267,17 +263,16 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, model_datafiles, CL*max_icesheets, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, model_internal_gridsize, max_icesheets, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, nx_global, max_icesheets, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, ny_global, max_icesheets, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMBroadcast(vm, model_areas, max_icesheets, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, bcasttmp, 3, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return skip_restart_read = (bcasttmp(1) == 1) - get_import_data = (bcasttmp(2) == 1) - num_icesheets = bcasttmp(3) + num_icesheets = bcasttmp(2) ! Validate datamode if ( trim(datamode) == 'noevolve') then ! read stream, no import data @@ -304,7 +299,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! Advertise dglc fields if (trim(datamode)=='noevolve') then call dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fldsimport, & - get_import_data, flds_scalar_name, rc) + flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -571,7 +566,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) select case (trim(datamode)) case('noevolve') call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, & - model_meshes, model_areas, model_datafiles, rc) + model_meshes, model_internal_gridsize, model_datafiles, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select From 68918090ddb39e7b0cc13f6c600e26649d7a4fe5 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 30 Mar 2024 10:17:45 -0600 Subject: [PATCH 070/170] updated documentation --- doc/source/dglc.rst | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/doc/source/dglc.rst b/doc/source/dglc.rst index 9aa1ad6b9..51175681e 100644 --- a/doc/source/dglc.rst +++ b/doc/source/dglc.rst @@ -38,14 +38,15 @@ case with CISM/CMEPS coupling). This is configured via the following - ``model_datafiles_list`` is colon separated string containing input datafiles that specify are used to obtain data for bedrock - topography and the ice thickness. + topography and the ice thickness. - - ``model_areas`` is an array that is the size of the number of ice - sheets and that specifies the gridcell areas that corresponds to + - ``model_internal_gridsize`` is an array that is the size of the number of ice + sheets and that specifies the internal gridcell size that corresponds what internal gridcell areas the prognostic land-ice component - uses internally (in this case CISM). Specifying this at the - namelist level eliminates the need to duplicate the code that is - used in CISM to derive this quantity. + uses internally (in this case CISM). From this value the internal grid areas in + radians squared are given by (model_internal_gridsize/radius_earth)**2. + Both model_internal_gridsize and radius_earth have units of meters. + - ``nx_global`` is an array that is the size of the number of ice sheets and that specifies the global longitude dimension of the @@ -53,7 +54,7 @@ case with CISM/CMEPS coupling). This is configured via the following - ``ny_global`` is an array that is the size of the number of ice sheets and that specifies the global latitude dimension of the - each ice sheet. + each ice sheet. .. note:: Each element of ``model_data_filelist``, ``model_areas``, @@ -100,10 +101,6 @@ DGLC%NOEVOLVE In addition, the following DGLC specific CIME-CCS xml variables will appear in ``$CASEROOT/env_run.xml``: -DGLC_GET_IMPORT_DATA - - If true, have the mediator calculate import values that are sent back to - GLC even in GLC is in NOEVOLVE mode. The default value is FALSE. - DGLC_USE_GREENLAND - Whether to include the Greenland Ice Sheet in this DGLC simulation This should generally be set at create_newcase time (via the compset). In principle it @@ -118,4 +115,3 @@ DGLC_USE_ANTARCTICA DGLC_SKIP_RESTART_READ - If set to true, than dglc restarts will not be read on a continuation run. - From 3a4435be1daa77f4e15f4243df22e6d4dbd39a0b Mon Sep 17 00:00:00 2001 From: James Edwards Date: Tue, 2 Apr 2024 14:45:06 -0500 Subject: [PATCH 071/170] make the amount of data required to download minimal for testing --- cime_config/stream_cdeps.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index 1f702a13c..28db8a905 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -204,6 +204,9 @@ def create_stream_xml( data_year_first, data_year_last = self._get_stream_first_and_last_dates( self.stream_nodes, case ) + # If this is a test we don't need the full extent of the data + if case.get_value("TEST"): + data_year_first = max(data_year_last-2, data_year_first) # now write the data model streams xml file stream_vars = {} From c12a8d0c347e66e056c5f01f068fa563a05852ee Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 17 Apr 2024 11:04:49 -0600 Subject: [PATCH 072/170] add Fogg_rofi to dglc --- dglc/dglc_datamode_noevolve_mod.F90 | 261 +++++++++++++++------------- dglc/glc_comp_nuopc.F90 | 201 +++++++++++++++++++-- dshr/dshr_mod.F90 | 2 +- 3 files changed, 328 insertions(+), 136 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 9a5431e62..95a6d8469 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -39,6 +39,7 @@ module dglc_datamode_noevolve_mod type(icesheet_ptr_t), allocatable :: Sg_ice_covered(:) type(icesheet_ptr_t), allocatable :: Sg_icemask(:) type(icesheet_ptr_t), allocatable :: Sg_icemask_coupled_fluxes(:) + type(icesheet_ptr_t), allocatable :: Fogg_rofi(:) ! Import fields type(icesheet_ptr_t), allocatable :: Sl_tsrf(:) @@ -50,6 +51,7 @@ module dglc_datamode_noevolve_mod character(len=*), parameter :: field_out_ice_covered = 'Sg_ice_covered' character(len=*), parameter :: field_out_icemask = 'Sg_icemask' character(len=*), parameter :: field_out_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' + character(len=*), parameter :: field_out_rofi = 'Fogg_rofi' ! Import Field names character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' @@ -96,6 +98,7 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fl call dshr_fldList_add(fldsExport, field_out_topo) call dshr_fldList_add(fldsExport, field_out_icemask) call dshr_fldList_add(fldsExport, field_out_icemask_coupled_fluxes) + call dshr_fldList_add(fldsExport, field_out_rofi) do ns = 1,num_icesheets write(cnum,'(i0)') ns @@ -150,6 +153,7 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) allocate(Sg_ice_covered(num_icesheets)) allocate(Sg_icemask(num_icesheets)) allocate(Sg_icemask_coupled_fluxes(num_icesheets)) + allocate(Fogg_rofi(num_icesheets)) do ns = 1,num_icesheets call dshr_state_getfldptr(NStateExp(ns), field_out_area, fldptr1=Sg_area(ns)%ptr, rc=rc) @@ -162,6 +166,8 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(NStateExp(ns), field_out_icemask_coupled_fluxes, fldptr1=Sg_icemask_coupled_fluxes(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(NStateExp(ns), field_out_rofi, fldptr1=Fogg_rofi(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end do ! initialize pointers to import fields if appropriate @@ -169,16 +175,15 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) allocate(Flgl_qice(num_icesheets)) do ns = 1,num_icesheets - ! NOTE: the field is connected ONLY if the MED->GLC entry is in the nuopc.runconfig file - ! This restriction occurs even if the field was advertised - if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_tsrf)) then - call dshr_state_getfldptr(NStateImp(ns), field_in_tsrf, fldptr1=Sl_tsrf(ns)%ptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - if (NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_qice)) then - call dshr_state_getfldptr(NStateImp(ns), field_in_qice, fldptr1=Flgl_qice(ns)%ptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (.not. NUOPC_IsConnected(NStateImp(ns), fieldName=field_in_tsrf)) then + ! NOTE: the field is connected ONLY if the MED->GLC entry is in the nuopc.runconfig file + ! This restriction occurs even if the field was advertised + call shr_sys_abort(trim(subname)//": MED->GLC must appear in run sequence") end if + call dshr_state_getfldptr(NStateImp(ns), field_in_tsrf, fldptr1=Sl_tsrf(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(NStateImp(ns), field_in_qice, fldptr1=Flgl_qice(ns)%ptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end do end subroutine dglc_datamode_noevolve_init_pointers @@ -226,124 +231,140 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & rc = ESMF_SUCCESS - if (initialized_noevolve) then - RETURN - end if + if (.not. initialized_noevolve) then - do ns = 1,num_icesheets + do ns = 1,num_icesheets - ! Get mesh info - call ESMF_MeshGet(model_meshes(ns), 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(gindex(lsize)) - call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Determine "glc_area" ; - ! Sg_areas is in radians - ! SHR_CONST_REARTH is the radius of earth in m - ! model_internal_gridsize is the internal model gridsize in m - do ng = 1,lsize - Sg_area(ns)%ptr(ng) = (model_internal_gridsize(ns)/SHR_CONST_REARTH)**2 - end do + ! Get mesh info + call ESMF_MeshGet(model_meshes(ns), 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(gindex(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Create module level field bundle - fldbun_noevolve = ESMF_FieldBundleCreate(rc=rc) ! input field bundle - - ! "ice thickness" ; - field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! "bed topography" ; - field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create pioid and pio_iodesc at the module level - inquire(file=trim(model_datafiles(ns)), exist=exists) - if (.not.exists) then - write(6,'(a)')' ERROR: model input file '//trim(model_datafiles(ns))//' does not exist' - call shr_sys_abort() - end if - rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(model_datafiles(ns)), pio_nowrite) - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) - rcode = pio_inq_varid(pioid, 'thk', varid) - rcode = pio_inq_varndims(pioid, varid, ndims) - allocate(dimid(ndims)) - rcode = pio_inq_vardimid(pioid, varid, dimid(1:ndims)) - rcode = pio_inq_dimlen(pioid, dimid(1), nxg) - rcode = pio_inq_dimlen(pioid, dimid(2), nyg) - call pio_initdecomp(pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) - deallocate(dimid) - deallocate(gindex) - - ! Read in the data into the appropriate field bundle pointers - ! Note that Sg_ice_covered(ns)%ptr points into the data for - ! the Sg_ice_covered field in NStateExp(ns) - ! Note that Sg_topo(ns)%ptr points into the data for - ! the Sg_topon NStateExp(ns) - ! Note that topog is bedrock topography - - call dshr_fldbun_getFldPtr(fldbun_noevolve, 'topg', topog, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - rcode = pio_inq_varid(pioid, 'topg', varid) - call pio_read_darray(pioid, varid, pio_iodesc, topog, rcode) - - call dshr_fldbun_getFldPtr(fldbun_noevolve, 'thk', thck, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - rcode = pio_inq_varid(pioid, 'thk', varid) - call pio_read_darray(pioid, varid, pio_iodesc, thck, rcode) - - allocate(lsrf(lsize)) - allocate(usrf(lsize)) - - rhoi = SHR_CONST_RHOICE ! 0.917e3 - rhoo = SHR_CONST_RHOSW ! 1.026e3 - eus = 0 - do ng = 1,lsize - if (topog(ng) - eus < (-rhoi/rhoo) * thck(ng)) then - lsrf(ng) = (-rhoi/rhoo) * thck(ng) - else - lsrf(ng) = topog(ng) - end if - usrf(ng) = max(0.d0, thck(ng) + lsrf(ng)) - - if (is_in_active_grid(usrf(ng))) then - Sg_icemask(ns)%ptr(ng) = 1.d0 - Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 0.d0 - if (is_ice_covered(thck(ng))) then - Sg_ice_covered(ns)%ptr(ng) = 1.d0 - else - Sg_ice_covered(ns)%ptr(ng) = 0.d0 - end if - ! Note that we use the same method for computing topo whether this point is - ! ice-covered or ice-free. This is in contrast to the method for computing - ! ice-free topo in glint_upscaling_gcm. - Sg_topo(ns)%ptr(ng) = thk0 * usrf(ng) - else - ! Note that this logic implies that if (in theory) we had an ice-covered - ! point outside the "active grid", it will get classified as ice-free for - ! these purposes. This mimics the logic currently in glint_upscaling_gcm. - Sg_icemask(ns)%ptr(ng) = 0.d0 - Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 0.d0 - Sg_ice_covered(ns)%ptr(ng) = 0.d0 - Sg_topo(ns)%ptr(ng) = 0.d0 - end if - end do + ! Determine "glc_area" ; + ! Sg_areas is in radians + ! SHR_CONST_REARTH is the radius of earth in m + ! model_internal_gridsize is the internal model gridsize in m + do ng = 1,lsize + Sg_area(ns)%ptr(ng) = (model_internal_gridsize(ns)/SHR_CONST_REARTH)**2 + end do - deallocate(lsrf) - deallocate(usrf) + ! Create module level field bundle + fldbun_noevolve = ESMF_FieldBundleCreate(rc=rc) ! input field bundle - call pio_closefile(pioid) - call pio_freedecomp(pio_subsystem, pio_iodesc) + ! "ice thickness" ; + field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! "bed topography" ; + field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create pioid and pio_iodesc at the module level + inquire(file=trim(model_datafiles(ns)), exist=exists) + if (.not.exists) then + write(6,'(a)')' ERROR: model input file '//trim(model_datafiles(ns))//' does not exist' + call shr_sys_abort() + end if + rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(model_datafiles(ns)), pio_nowrite) + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + rcode = pio_inq_varid(pioid, 'thk', varid) + rcode = pio_inq_varndims(pioid, varid, ndims) + allocate(dimid(ndims)) + rcode = pio_inq_vardimid(pioid, varid, dimid(1:ndims)) + rcode = pio_inq_dimlen(pioid, dimid(1), nxg) + rcode = pio_inq_dimlen(pioid, dimid(2), nyg) + call pio_initdecomp(pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) + deallocate(dimid) + deallocate(gindex) + + ! Read in the data into the appropriate field bundle pointers + ! Note that Sg_ice_covered(ns)%ptr points into the data for + ! the Sg_ice_covered field in NStateExp(ns) + ! Note that Sg_topo(ns)%ptr points into the data for + ! the Sg_topon NStateExp(ns) + ! Note that topog is bedrock topography + + call dshr_fldbun_getFldPtr(fldbun_noevolve, 'topg', topog, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + rcode = pio_inq_varid(pioid, 'topg', varid) + call pio_read_darray(pioid, varid, pio_iodesc, topog, rcode) - end do ! end loop over ice sheets + call dshr_fldbun_getFldPtr(fldbun_noevolve, 'thk', thck, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + rcode = pio_inq_varid(pioid, 'thk', varid) + call pio_read_darray(pioid, varid, pio_iodesc, thck, rcode) + + allocate(lsrf(lsize)) + allocate(usrf(lsize)) + + rhoi = SHR_CONST_RHOICE ! 0.917e3 + rhoo = SHR_CONST_RHOSW ! 1.026e3 + eus = 0 + do ng = 1,lsize + if (topog(ng) - eus < (-rhoi/rhoo) * thck(ng)) then + lsrf(ng) = (-rhoi/rhoo) * thck(ng) + else + lsrf(ng) = topog(ng) + end if + usrf(ng) = max(0.d0, thck(ng) + lsrf(ng)) + + ! The export field 'ice_mask_coupled_fluxes' determines who is handling the + ! runoff associated with the surface mass balance + ! If its 0 -then ctsm needs to handle it. + ! Since we want dglc to handle it no evolve mode - then + ! ice_mask_coupled_fluxes to be identical to the mask + + if (is_in_active_grid(usrf(ng))) then + Sg_icemask(ns)%ptr(ng) = 1.d0 + Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 1.d0 + if (is_ice_covered(thck(ng))) then + Sg_ice_covered(ns)%ptr(ng) = 1.d0 + else + Sg_ice_covered(ns)%ptr(ng) = 0.d0 + end if + ! Note that we use the same method for computing topo whether this point is + ! ice-covered or ice-free. This is in contrast to the method for computing + ! ice-free topo in glint_upscaling_gcm. + Sg_topo(ns)%ptr(ng) = thk0 * usrf(ng) + else + ! Note that this logic implies that if (in theory) we had an ice-covered + ! point outside the "active grid", it will get classified as ice-free for + ! these purposes. This mimics the logic currently in glint_upscaling_gcm. + Sg_icemask(ns)%ptr(ng) = 0.d0 + Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 0.d0 + Sg_ice_covered(ns)%ptr(ng) = 0.d0 + Sg_topo(ns)%ptr(ng) = 0.d0 + end if + end do + + deallocate(lsrf) + deallocate(usrf) + + call pio_closefile(pioid) + call pio_freedecomp(pio_subsystem, pio_iodesc) + + end do ! end loop over ice sheets + + end if + + if (initialized_noevolve) then + ! Compute Fogg_rofi + do ns = 1,num_icesheets + do ng = 1,size(Fogg_rofi(ns)%ptr) + Fogg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + end do + end do + end if + ! Set initialized flag initialized_noevolve = .true. end subroutine dglc_datamode_noevolve_advance diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 233794fd3..4597c4065 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -9,11 +9,13 @@ module cdeps_dglc_comp !---------------------------------------------------------------------------- use ESMF , only : ESMF_VM, ESMF_VmGet, ESMF_VMBroadcast, ESMF_GridCompGet use ESMF , only : ESMF_Mesh, ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_Time - use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_METHOD_INITIALIZE - use ESMF , only : ESMF_TraceRegionEnter, ESMF_TraceRegionExit, ESMF_ClockGet - use ESMF , only : ESMF_TimeGet, ESMF_TimeInterval, ESMF_Field, ESMF_MAXSTR - use ESMF , only : ESMF_Alarm, ESMF_MethodRemove, ESMF_MethodAdd - use ESMF , only : ESMF_GridCompSetEntryPoint, ESMF_ClockGetAlarm, ESMF_AlarmIsRinging + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_METHOD_INITIALIZE + use ESMF , only : ESMF_TraceRegionEnter, ESMF_TraceRegionExit + use ESMF , only : ESMF_TimeGet, ESMF_TimeInterval, ESMF_TimeIntervalGet, ESMF_Field, ESMF_MAXSTR + use ESMF , only : ESMF_MethodRemove, ESMF_MethodAdd + use ESMF , only : ESMF_GridCompSetEntryPoint + use ESMF , only : ESMF_Alarm, ESMF_AlarmSet, ESMF_AlarmIsRinging, ESMF_ALARMLIST_ALL + use ESMF , only : ESMF_ClockGet, ESMF_ClockSet, ESMF_ClockAdvance, ESMF_ClockGetAlarm, ESMF_ClockGetAlarmList use ESMF , only : ESMF_StateGet, operator(+), ESMF_AlarmRingerOff, ESMF_LogWrite use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_VmLogMemInfo use ESMF , only : ESMF_MeshCreate, ESMF_FILEFORMAT_ESMFMESH @@ -35,7 +37,7 @@ module cdeps_dglc_comp #endif use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_init_from_config - use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init + use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init, dshr_alarm_init use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_check_restart_alarm use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_realize @@ -52,6 +54,7 @@ module cdeps_dglc_comp public :: SetVM private :: InitializeAdvertise private :: InitializeRealize + private :: ModelSetRunClock private :: ModelAdvance private :: dglc_comp_run private :: ModelFinalize @@ -157,7 +160,9 @@ subroutine SetServices(gcomp, rc) call ESMF_MethodRemove(gcomp, label=model_label_SetRunClock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompSpecialize(gcomp, specLabel=model_label_SetRunClock, specRoutine=dshr_set_runclock, rc=rc) + ! The following specialization does not use dshr_set_runclock since we also need to add an alarm + ! to determine if the model inputs are valid + call NUOPC_CompSpecialize(gcomp, specLabel=model_label_SetRunClock, specRoutine=ModelSetRunClock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSpecialize(gcomp, specLabel=model_label_Finalize, specRoutine=ModelFinalize, rc=rc) @@ -425,7 +430,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) end do ! end loop over ice sheets ! Run dglc - call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., rc=rc) + call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., valid_inputs=.true., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('dglc_strdata_init') @@ -449,11 +454,14 @@ subroutine ModelAdvance(gcomp, rc) integer :: yr ! year integer :: mon ! month integer :: day ! day in month + integer :: tod ! seconds in day logical :: restart_write + type(ESMF_Alarm) :: valid_alarm + logical :: valid_inputs ! if true, inputs from mediator are valid + character(len=CS) :: timestring character(len=*),parameter :: subname=trim(module_name)//':(ModelAdvance) ' !------------------------------------------------------------------------------- - rc = ESMF_SUCCESS call shr_log_setLogUnit(logunit) @@ -463,7 +471,17 @@ subroutine ModelAdvance(gcomp, rc) call NUOPC_ModelGet(gcomp, modelClock=clock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! For nuopc - the component clock is advanced at the end of the time interval + ! Determine if inputs from mediator are valid + call ESMF_ClockGetAlarm(clock, alarmname='alarm_valid_inputs', alarm=valid_alarm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (ESMF_AlarmIsRinging(valid_alarm, rc=rc)) then + valid_inputs = .true. + call ESMF_AlarmRingerOff( valid_alarm, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + valid_inputs = .false. + endif + ! Need to advance nuopc one timestep ahead for shr_strdata time interpolation call ESMF_ClockGet( clock, currTime=currTime, timeStep=timeStep, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -471,18 +489,23 @@ subroutine ModelAdvance(gcomp, rc) call ESMF_TimeGet( nextTime, yy=yr, mm=mon, dd=day, s=next_tod, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return call shr_cal_ymd2date(yr, mon, day, next_ymd) + if (my_task == main_task) then + call ESMF_TimeGet(currTime, timestring=timestring, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(logunit,'(a,l)') trim(timestring)//': valid_input for dglc is ',valid_inputs + end if ! determine if will write restart restart_write = dshr_check_restart_alarm(clock, rc=rc) ! run dglc - call dglc_comp_run(clock, next_ymd, next_tod, restart_write, rc=rc) + call dglc_comp_run(clock, next_ymd, next_tod, restart_write, valid_inputs, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine ModelAdvance !=============================================================================== - subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) + subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inputs, rc) ! -------------------------- ! advance dglc @@ -493,6 +516,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) integer , intent(in) :: target_ymd ! model date integer , intent(in) :: target_tod ! model sec into model date logical , intent(in) :: restart_write + logical , intent(in) :: valid_inputs integer , intent(out) :: rc ! local variables @@ -565,9 +589,11 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc) ! Perform data mode specific calculations select case (trim(datamode)) case('noevolve') - call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, & - model_meshes, model_internal_gridsize, model_datafiles, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (valid_inputs) then + call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, & + model_meshes, model_internal_gridsize, model_datafiles, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end select ! Write restarts if needed @@ -632,6 +658,151 @@ end subroutine dglc_init_dfields end subroutine dglc_comp_run + !=============================================================================== + + subroutine ModelSetRunClock(gcomp, rc) + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(ESMF_Clock) :: mclock, dclock + type(ESMF_Time) :: mcurrtime, dcurrtime + type(ESMF_Time) :: mstoptime + type(ESMF_TimeInterval) :: mtimestep, dtimestep + character(len=256) :: cvalue + character(len=256) :: restart_option ! Restart option units + integer :: restart_n ! Number until restart interval + integer :: restart_ymd ! Restart date (YYYYMMDD) + type(ESMF_ALARM) :: restart_alarm + character(len=256) :: stop_option ! Stop option units + integer :: stop_n ! Number until stop interval + integer :: stop_ymd ! Stop date (YYYYMMDD) + type(ESMF_ALARM) :: stop_alarm + character(len=128) :: name + integer :: alarmcount + character(len=CS) :: glc_avg_period ! averaging period in mediator + type(ESMF_ALARM) :: valid_alarm ! model alarm + integer :: dtime + character(len=*),parameter :: subname='glc_comp_nuopc:(dglc_set_runclock) ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! query the Component for its clocks + call NUOPC_ModelGet(gcomp, driverClock=dclock, modelClock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ClockGet(dclock, currTime=dcurrtime, timeStep=dtimestep, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGet(mclock, currTime=mcurrtime, timeStep=mtimestep, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! force model clock currtime and timestep to match driver and set stoptime + mstoptime = mcurrtime + dtimestep + call ESMF_ClockSet(mclock, currTime=dcurrtime, timeStep=dtimestep, stopTime=mstoptime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! determine number of alarms + call ESMF_ClockGetAlarmList(mclock, alarmlistflag=ESMF_ALARMLIST_ALL, alarmCount=alarmCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (alarmCount == 0) then + + !---------------- + ! glc valid input alarm + !---------------- + call NUOPC_CompAttributeGet(gcomp, name="glc_avg_period", value=glc_avg_period, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (trim(glc_avg_period) == 'hour') then + call dshr_alarm_init(mclock, valid_alarm, 'nhours', opt_n=1, alarmname='alarm_valid_inputs', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(glc_avg_period) == 'day') then + call dshr_alarm_init(mclock, valid_alarm, 'ndays' , opt_n=1, alarmname='alarm_valid_inputs', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(glc_avg_period) == 'yearly') then + call dshr_alarm_init(mclock, valid_alarm, 'yearly', alarmname='alarm_valid_inputs', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(glc_avg_period) == 'glc_coupling_period') then + call ESMF_TimeIntervalGet(mtimestep, s=dtime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_alarm_init(mclock, valid_alarm, 'nseconds', opt_n=dtime, alarmname='alarm_valid_inputs', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_LogWrite(trim(subname)// ": ERROR glc_avg_period = "//trim(glc_avg_period)//" not supported", & + ESMF_LOGMSG_INFO, rc=rc) + rc = ESMF_FAILURE + RETURN + end if + + call ESMF_AlarmSet(valid_alarm, clock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !---------------- + ! Restart alarm + !---------------- + call ESMF_LogWrite(subname//'setting restart alarm for dglc' , ESMF_LOGMSG_INFO) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call NUOPC_CompAttributeGet(gcomp, name="restart_option", value=restart_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call NUOPC_CompAttributeGet(gcomp, name="restart_n", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) restart_n + + call NUOPC_CompAttributeGet(gcomp, name="restart_ymd", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) restart_ymd + + call dshr_alarm_init(mclock, restart_alarm, restart_option, & + opt_n = restart_n, & + opt_ymd = restart_ymd, & + RefTime = mcurrTime, & + alarmname = 'alarm_restart', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_AlarmSet(restart_alarm, clock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !---------------- + ! Stop alarm + !---------------- + call ESMF_LogWrite(subname//'setting stop alarm for dglc' , ESMF_LOGMSG_INFO) + call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call NUOPC_CompAttributeGet(gcomp, name="stop_n", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_n + + call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_ymd + + call dshr_alarm_init(mclock, stop_alarm, stop_option, & + opt_n = stop_n, & + opt_ymd = stop_ymd, & + RefTime = mcurrTime, & + alarmname = 'alarm_stop', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_AlarmSet(stop_alarm, clock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end if + + ! Advance model clock to trigger alarms then reset model clock back to currtime + call ESMF_ClockAdvance(mclock,rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ClockSet(mclock, currTime=dcurrtime, timeStep=dtimestep, stopTime=mstoptime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine ModelSetRunClock + !=============================================================================== subroutine ModelFinalize(gcomp, rc) type(ESMF_GridComp) :: gcomp diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index 977b9d439..faa346b68 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -60,9 +60,9 @@ module dshr_mod public :: dshr_state_setscalar public :: dshr_orbital_update public :: dshr_orbital_init + public :: dshr_alarm_init ! initialize alarms private :: dshr_mesh_create_scol ! create mesh for single column mode - private :: dshr_alarm_init ! initialize alarms private :: dshr_time_init ! initialize time ! Note that gridTofieldMap = 2, therefore the ungridded dimension is innermost From 6673b85419b09b7926ec35160189ba004ed12f44 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 17 Apr 2024 14:12:54 -0600 Subject: [PATCH 073/170] update to have antarctica work with clm --- dglc/cime_config/config_component.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dglc/cime_config/config_component.xml b/dglc/cime_config/config_component.xml index 15271a5b8..a47b9d5e9 100644 --- a/dglc/cime_config/config_component.xml +++ b/dglc/cime_config/config_component.xml @@ -43,7 +43,7 @@ - + logical FALSE run_component_dglc @@ -58,7 +58,7 @@ - + logical FALSE run_component_dglc From 1e9220b746984380e791490f3609c55b2a0628c6 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 19 Apr 2024 08:07:47 -0600 Subject: [PATCH 074/170] added ability to read in multi-level docn data --- docn/CMakeLists.txt | 1 + docn/cime_config/config_component.xml | 6 +- docn/cime_config/namelist_definition_docn.xml | 4 +- docn/cime_config/stream_definition_docn.xml | 65 ++++++++++++++++++- docn/ocn_comp_nuopc.F90 | 35 ++++++++-- dshr/dshr_dfield_mod.F90 | 7 +- streams/dshr_methods_mod.F90 | 4 +- 7 files changed, 109 insertions(+), 13 deletions(-) diff --git a/docn/CMakeLists.txt b/docn/CMakeLists.txt index 007d595ca..256dc304d 100644 --- a/docn/CMakeLists.txt +++ b/docn/CMakeLists.txt @@ -5,6 +5,7 @@ set(SRCFILES ocn_comp_nuopc.F90 docn_datamode_aquaplanet_mod.F90 docn_datamode_iaf_mod.F90 docn_datamode_cplhist_mod.F90 + docn_datamode_multilev_mod.F90 docn_import_data_mod.F90) foreach(FILE ${SRCFILES}) diff --git a/docn/cime_config/config_component.xml b/docn/cime_config/config_component.xml index 3a98b7878..ab88c6fed 100644 --- a/docn/cime_config/config_component.xml +++ b/docn/cime_config/config_component.xml @@ -13,7 +13,7 @@ This file may have ocn desc entries. --> - DOCN + DOCN prescribed ocean mode slab ocean mode aquaplanet slab ocean mode @@ -32,6 +32,7 @@ file input aquaplanet sst globally constant SST for idealized experiments, such as RCE mediator history output for ocean fields imported to mediator + input stream files have multi level data @@ -45,7 +46,7 @@ char - prescribed,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,som,som_aquap,sst_aquap_constant,interannual,cplhist + prescribed,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,som,som_aquap,sst_aquap_constant,interannual,cplhist,multilev prescribed prescribed @@ -65,6 +66,7 @@ sst_aquapfile sst_aquap_constant cplhist + multilev run_component_docn env_run.xml diff --git a/docn/cime_config/namelist_definition_docn.xml b/docn/cime_config/namelist_definition_docn.xml index a44ae344d..71109b1c7 100644 --- a/docn/cime_config/namelist_definition_docn.xml +++ b/docn/cime_config/namelist_definition_docn.xml @@ -32,6 +32,7 @@ '' '' '' + sst_depth,salinity_depth @@ -39,7 +40,7 @@ char docn docn_nml - sstdata,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,sst_aquap_constant,som,som_aquap,iaf,cplhist + sstdata,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,sst_aquap_constant,som,som_aquap,iaf,cplhist,multilev General method that operates on the data for a given docn_mode. ==> dataMode = "sstdata" @@ -107,6 +108,7 @@ sst_aquap_file sst_aquap_constant cplhist + multilev diff --git a/docn/cime_config/stream_definition_docn.xml b/docn/cime_config/stream_definition_docn.xml index 0dd4baf54..4144e0e53 100644 --- a/docn/cime_config/stream_definition_docn.xml +++ b/docn/cime_config/stream_definition_docn.xml @@ -206,6 +206,69 @@ 1.e30 - single + single + + + + + $DIN_LOC_ROOT/share/meshes/gx1v7_151008_ESMFmesh.nc + + + /glade/collections/cmip/CMIP6/OMIP/NCAR/CESM2/omip2/r1i1p1f1/Omon/thetao/gn/v20190802/thetao_Omon_CESM2_omip2_r1i1p1f1_gn_024501-030512.nc + + + thetao So_t_depth + + lev + + bilinear + + null + 1 + 245 + 245 + 0 + + linear + + + cycle + + + 1.5 + + single + + + + + $DIN_LOC_ROOT/share/meshes/gx1v7_151008_ESMFmesh.nc + + + /glade/collections/cmip/CMIP6/OMIP/NCAR/CESM2/omip2/r1i1p1f1/Omon/so/gn/v20190802/so_Omon_CESM2_omip2_r1i1p1f1_gn_024501-030512.nc + + + so So_s_depth + + lev + + bilinear + + null + 1 + 245 + 245 + 0 + + linear + + + cycle + + + 1.5 + + single + diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index 4bdeb81f6..3a9c12a83 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -26,7 +26,7 @@ module cdeps_docn_comp use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort use shr_cal_mod , only : shr_cal_ymd2date - use shr_log_mod , only : shr_log_setLogUnit + use shr_log_mod , only : shr_log_setLogUnit use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_init_from_config use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init @@ -58,6 +58,11 @@ module cdeps_docn_comp use docn_datamode_cplhist_mod , only : docn_datamode_cplhist_advance use docn_datamode_cplhist_mod , only : docn_datamode_cplhist_restart_read use docn_datamode_cplhist_mod , only : docn_datamode_cplhist_restart_write + use docn_datamode_multilev_mod , only : docn_datamode_multilev_advertise + use docn_datamode_multilev_mod , only : docn_datamode_multilev_init_pointers + use docn_datamode_multilev_mod , only : docn_datamode_multilev_advance + use docn_datamode_multilev_mod , only : docn_datamode_multilev_restart_read + use docn_datamode_multilev_mod , only : docn_datamode_multilev_restart_write use docn_import_data_mod , only : docn_import_data_advertise implicit none @@ -193,6 +198,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: bcasttmp(4) real(r8) :: rtmp(1) type(ESMF_VM) :: vm + integer :: nlev = 60 !DEBUG - remove this and put into namelist character(len=*),parameter :: subname=trim(module_name)//':(InitializeAdvertise) ' character(*) ,parameter :: F00 = "('(" // trim(module_name) // ") ',8a)" character(*) ,parameter :: F01 = "('(" // trim(module_name) // ") ',a,2x,i8)" @@ -300,7 +306,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) trim(datamode) == 'som_aquap' .or. & ! read stream, needs import data trim(datamode) == 'cplhist' .or. & ! read stream, needs import data trim(datamode) == 'sst_aquap_analytic' .or. & ! analytic, no streams, import or export data - trim(datamode) == 'sst_aquap_constant' ) then ! analytic, no streams, import or export data + trim(datamode) == 'sst_aquap_constant' .or. & ! analytic, no streams, import or export data + trim(datamode) == 'multilev') then ! multilevel ocean input ! success do nothing else call shr_sys_abort(' ERROR illegal docn datamode = '//trim(datamode)) @@ -323,6 +330,9 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) else if (trim(datamode) == 'cplhist') then call docn_datamode_cplhist_advertise(exportState, fldsExport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(datamode) == 'multilev') then + call docn_datamode_multilev_advertise(exportState, fldsExport, flds_scalar_name, nlev, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if if (trim(import_data_fields) /= 'none') then @@ -550,6 +560,9 @@ subroutine docn_comp_run(importState, exportState, clock, target_ymd, target_tod case('cplhist') call docn_datamode_cplhist_init_pointers(exportState, model_frac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('multilev') + call docn_datamode_multilev_init_pointers(exportState, model_frac, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Read restart if needed @@ -607,6 +620,9 @@ subroutine docn_comp_run(importState, exportState, clock, target_ymd, target_tod case('cplhist') call docn_datamode_cplhist_advance(rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('multilev') + call docn_datamode_multilev_advance(rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Write restarts if needed (no restarts for aquaplanet analytic or aquaplanet input file) @@ -650,8 +666,10 @@ subroutine docn_init_dfields(importState, exportState, rc) ! local variables integer :: n integer :: fieldcount + integer :: dimcount type(ESMF_Field) :: lfield character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR) :: fieldname(1) character(*), parameter :: subName = "(docn_init_dfields) " !------------------------------------------------------------------------------- @@ -668,9 +686,18 @@ subroutine docn_init_dfields(importState, exportState, rc) call ESMF_StateGet(exportState, itemName=trim(lfieldNameList(n)), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (trim(lfieldnamelist(n)) /= flds_scalar_name) then - call dshr_dfield_add( dfields, sdat, trim(lfieldnamelist(n)), trim(lfieldnamelist(n)), exportState, & - logunit, mainproc, rc) + call ESMF_FieldGet(lfield, dimcount=dimCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dimcount == 2) then + fieldname(1) = trim(lfieldnamelist(n)) + call dshr_dfield_add( dfields, sdat, trim(lfieldnamelist(n)), fieldname, exportState, & + logunit, mainproc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call dshr_dfield_add( dfields, sdat, trim(lfieldnamelist(n)), trim(lfieldnamelist(n)), exportState, & + logunit, mainproc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif end if end do end subroutine docn_init_dfields diff --git a/dshr/dshr_dfield_mod.F90 b/dshr/dshr_dfield_mod.F90 index 2c2862042..bfd5cdc1a 100644 --- a/dshr/dshr_dfield_mod.F90 +++ b/dshr/dshr_dfield_mod.F90 @@ -438,6 +438,7 @@ subroutine dshr_dfield_copy(dfields, sdat, rc) type(ESMF_field) :: lfield type(dfield_type), pointer :: dfield real(r8), pointer :: data1d(:) + real(r8), pointer :: data2d(:,:) integer :: nf integer :: fldbun_index integer :: stream_index @@ -464,13 +465,13 @@ subroutine dshr_dfield_copy(dfields, sdat, rc) do nf = 1,size(dfield%stream_indices) stream_index = dfield%stream_indices(nf) fldbun_index = dfield%fldbun_indices(nf) - if(stream_index > 0) then + if (stream_index > 0) then fldbun_model = shr_strdata_get_stream_fieldbundle(sdat, stream_index, 'model') call dshr_fldbun_getfieldn(fldbun_model, fldbun_index, lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_field_getfldptr(lfield, fldptr1=data1d, rc=rc) + call dshr_field_getfldptr(lfield, fldptr2=data2d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - dfield%state_data2d(nf,:) = data1d(:) + dfield%state_data2d(:,:) = data2d(:,:) endif end do end if diff --git a/streams/dshr_methods_mod.F90 b/streams/dshr_methods_mod.F90 index 8e721bed1..0ce787596 100644 --- a/streams/dshr_methods_mod.F90 +++ b/streams/dshr_methods_mod.F90 @@ -568,7 +568,7 @@ subroutine dshr_field_getfldptr(field, fldptr1, fldptr2, rank, abort, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (ungriddedUBound(1) > 0) then if (.not.present(fldptr2)) then - call ESMF_LogWrite(trim(subname)//": ERROR missing rank=2 array ", & + call ESMF_LogWrite(trim(subname)//": ERROR missing rank=2 array for "//trim(name), & ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) rc = ESMF_FAILURE return @@ -578,7 +578,7 @@ subroutine dshr_field_getfldptr(field, fldptr1, fldptr2, rank, abort, rc) lrank = 2 else if (.not.present(fldptr1)) then - call ESMF_LogWrite(trim(subname)//": ERROR missing rank=1 array ", & + call ESMF_LogWrite(trim(subname)//": ERROR missing rank=1 array for "//trim(name), & ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) rc = ESMF_FAILURE return From 40d63eb1d271f52553f525a43e0d420c01527fa9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 19 Apr 2024 08:45:12 -0600 Subject: [PATCH 075/170] added new multilevel mode to docn --- docn/docn_datamode_multilev_mod.F90 | 159 ++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 docn/docn_datamode_multilev_mod.F90 diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 new file mode 100644 index 000000000..fa02eb263 --- /dev/null +++ b/docn/docn_datamode_multilev_mod.F90 @@ -0,0 +1,159 @@ +module docn_datamode_multilev_mod + use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS + use NUOPC , only : NUOPC_Advertise + use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs + use shr_const_mod , only : shr_const_TkFrz, shr_const_pi, shr_const_ocn_ref_sal + use shr_sys_mod , only : shr_sys_abort + use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr + use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add + use dshr_mod , only : dshr_restart_read, dshr_restart_write + use dshr_strdata_mod , only : shr_strdata_type + + implicit none + private ! except + + public :: docn_datamode_multilev_advertise + public :: docn_datamode_multilev_init_pointers + public :: docn_datamode_multilev_advance + public :: docn_datamode_multilev_restart_read + public :: docn_datamode_multilev_restart_write + + ! export fields + real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator + real(r8), pointer :: So_t_depth(:,:) => null() + real(r8), pointer :: So_s_depth(:,:) => null() + + ! constants + character(*) , parameter :: nullstr = 'null' + character(*) , parameter :: rpfile = 'rpointer.ocn' + character(*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine docn_datamode_multilev_advertise(exportState, fldsexport, flds_scalar_name, nlev, rc) + + ! input/output variables + type(esmf_State) , intent(inout) :: exportState + type(fldlist_type) , pointer :: fldsexport + character(len=*) , intent(in) :: flds_scalar_name + integer , intent(in) :: nlev + integer , intent(out) :: rc + + ! local variables + type(fldlist_type), pointer :: fldList + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Advertise export fields + call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsExport, 'So_omask') + call dshr_fldList_add(fldsExport, 'So_t_depth', ungridded_lbound=1, ungridded_ubound=nlev) + call dshr_fldList_add(fldsExport, 'So_s_depth', ungridded_lbound=1, ungridded_ubound=nlev) + + fldlist => fldsExport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(exportState, standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite('(docn_comp_advertise): Fr_ocn'//trim(fldList%stdname), ESMF_LOGMSG_INFO) + fldList => fldList%next + enddo + + end subroutine docn_datamode_multilev_advertise + + !=============================================================================== + subroutine docn_datamode_multilev_init_pointers(exportState, ocn_fraction, rc) + + ! input/output variables + type(ESMF_State) , intent(inout) :: exportState + real(r8) , intent(in) :: ocn_fraction(:) + integer , intent(out) :: rc + + ! local variables + character(len=*), parameter :: subname='(docn_init_pointers): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! initialize pointers to export fields + call dshr_state_getfldptr(exportState, 'So_omask' , fldptr1=So_omask , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'So_t_depth' , fldptr2=So_t_depth , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'So_s_depth' , fldptr2=So_s_depth , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Initialize export state pointers to non-zero + So_t_depth(:,:) = shr_const_TkFrz + So_s_depth(:,:) = shr_const_ocn_ref_sal + + ! Set export state ocean fraction (So_omask) + So_omask(:) = ocn_fraction(:) + + end subroutine docn_datamode_multilev_init_pointers + + !=============================================================================== + subroutine docn_datamode_multilev_advance(rc) + + ! input/output variables + integer, intent(out) :: rc + + ! local variables + integer :: i + character(len=*), parameter :: subname='(docn_datamode_multilev): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + do i = 1,size(So_omask) + if (So_omask(i) == 0.) then + So_t_depth(:,i) = 1.e30 + So_s_depth(:,i) = 1.e30 + end if + end do + + end subroutine docn_datamode_multilev_advance + + !=============================================================================== + subroutine docn_datamode_multilev_restart_write(case_name, inst_suffix, ymd, tod, & + logunit, my_task, sdat) + + ! write restart file + + ! input/output variables + character(len=*) , intent(in) :: case_name + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: ymd ! model date + integer , intent(in) :: tod ! model sec into model date + integer , intent(in) :: logunit + integer , intent(in) :: my_task + type(shr_strdata_type) , intent(inout) :: sdat + !------------------------------------------------------------------------------- + + call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, ymd, tod, & + logunit, my_task, sdat) + + end subroutine docn_datamode_multilev_restart_write + + !=============================================================================== + subroutine docn_datamode_multilev_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + + ! read restart file + + ! input/output arguments + character(len=*) , intent(inout) :: rest_filem + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: logunit + integer , intent(in) :: my_task + integer , intent(in) :: mpicom + type(shr_strdata_type) , intent(inout) :: sdat + !------------------------------------------------------------------------------- + + call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + + end subroutine docn_datamode_multilev_restart_read + +end module docn_datamode_multilev_mod From a6f0eb0be476d11692bc8c147c8ba64a557d1d32 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 23 Apr 2024 05:34:52 -0600 Subject: [PATCH 076/170] changes to get multilevel ocean input read --- docn/docn_datamode_multilev_mod.F90 | 103 +++++++++++++++++++++++----- docn/ocn_comp_nuopc.F90 | 8 +-- streams/dshr_strdata_mod.F90 | 9 +++ 3 files changed, 97 insertions(+), 23 deletions(-) diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index fa02eb263..c43f6b35e 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -2,12 +2,12 @@ module docn_datamode_multilev_mod use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs - use shr_const_mod , only : shr_const_TkFrz, shr_const_pi, shr_const_ocn_ref_sal + use shr_const_mod , only : shr_const_TkFrz, shr_const_pi, shr_const_ocn_ref_sal, shr_const_spval use shr_sys_mod , only : shr_sys_abort use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add use dshr_mod , only : dshr_restart_read, dshr_restart_write - use dshr_strdata_mod , only : shr_strdata_type + use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type implicit none private ! except @@ -18,11 +18,23 @@ module docn_datamode_multilev_mod public :: docn_datamode_multilev_restart_read public :: docn_datamode_multilev_restart_write - ! export fields - real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator + ! pointers to export fields + real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator real(r8), pointer :: So_t_depth(:,:) => null() real(r8), pointer :: So_s_depth(:,:) => null() + ! pointers to stream fields + real(r8), pointer :: stream_So_t_depth(:,:) => null() + real(r8), pointer :: stream_So_s_depth(:,:) => null() + + integer, parameter :: nlev_export = 30 + real(r8) :: vertical_levels(nlev_export) = (/ & + 60. , 120. , 180. , 240. , 300. , 360. , & + 420. , 480. , 540. , 600. , 660. , 720. , & + 780. , 840. , 900. , 960. , 1020., 1080., & + 1140., 1200., 1260., 1320., 1380., 1440., & + 1500., 1560., 1620., 1680., 1740., 1800. /) + ! constants character(*) , parameter :: nullstr = 'null' character(*) , parameter :: rpfile = 'rpointer.ocn' @@ -33,13 +45,12 @@ module docn_datamode_multilev_mod contains !=============================================================================== - subroutine docn_datamode_multilev_advertise(exportState, fldsexport, flds_scalar_name, nlev, rc) + subroutine docn_datamode_multilev_advertise(exportState, fldsexport, flds_scalar_name, rc) ! input/output variables type(esmf_State) , intent(inout) :: exportState type(fldlist_type) , pointer :: fldsexport character(len=*) , intent(in) :: flds_scalar_name - integer , intent(in) :: nlev integer , intent(out) :: rc ! local variables @@ -51,8 +62,8 @@ subroutine docn_datamode_multilev_advertise(exportState, fldsexport, flds_scalar ! Advertise export fields call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) call dshr_fldList_add(fldsExport, 'So_omask') - call dshr_fldList_add(fldsExport, 'So_t_depth', ungridded_lbound=1, ungridded_ubound=nlev) - call dshr_fldList_add(fldsExport, 'So_s_depth', ungridded_lbound=1, ungridded_ubound=nlev) + call dshr_fldList_add(fldsExport, 'So_t_depth', ungridded_lbound=1, ungridded_ubound=nlev_export) + call dshr_fldList_add(fldsExport, 'So_s_depth', ungridded_lbound=1, ungridded_ubound=nlev_export) fldlist => fldsExport ! the head of the linked list do while (associated(fldlist)) @@ -65,12 +76,13 @@ subroutine docn_datamode_multilev_advertise(exportState, fldsexport, flds_scalar end subroutine docn_datamode_multilev_advertise !=============================================================================== - subroutine docn_datamode_multilev_init_pointers(exportState, ocn_fraction, rc) + subroutine docn_datamode_multilev_init_pointers(exportState, sdat, ocn_fraction, rc) ! input/output variables - type(ESMF_State) , intent(inout) :: exportState - real(r8) , intent(in) :: ocn_fraction(:) - integer , intent(out) :: rc + type(ESMF_State) , intent(inout) :: exportState + type(shr_strdata_type) , intent(in) :: sdat + real(r8) , intent(in) :: ocn_fraction(:) + integer , intent(out) :: rc ! local variables character(len=*), parameter :: subname='(docn_init_pointers): ' @@ -78,7 +90,15 @@ subroutine docn_datamode_multilev_init_pointers(exportState, ocn_fraction, rc) rc = ESMF_SUCCESS + ! initialize pointers to stream fields + ! this has the full set of leveles in the stream data + call shr_strdata_get_stream_pointer( sdat, 'So_t_depth', stream_So_t_depth, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call shr_strdata_get_stream_pointer( sdat, 'So_s_depth', stream_So_s_depth, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! initialize pointers to export fields + ! the export state has only nlev_export levels call dshr_state_getfldptr(exportState, 'So_omask' , fldptr1=So_omask , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'So_t_depth' , fldptr2=So_t_depth , rc=rc) @@ -96,25 +116,70 @@ subroutine docn_datamode_multilev_init_pointers(exportState, ocn_fraction, rc) end subroutine docn_datamode_multilev_init_pointers !=============================================================================== - subroutine docn_datamode_multilev_advance(rc) + subroutine docn_datamode_multilev_advance(sdat, logunit, mainproc, rc) ! input/output variables - integer, intent(out) :: rc + type(shr_strdata_type) , intent(in) :: sdat + integer , intent(in) :: logunit + logical , intent(in) :: mainproc + integer , intent(out) :: rc ! local variables - integer :: i + integer :: i,ki,ko + integer :: nlev_stream + integer :: stream_index + logical :: level_found + real(r8) :: factor + real(r8), allocatable :: stream_vlevs(:) + logical :: first_time = .true. character(len=*), parameter :: subname='(docn_datamode_multilev): ' !------------------------------------------------------------------------------- rc = ESMF_SUCCESS - do i = 1,size(So_omask) - if (So_omask(i) == 0.) then - So_t_depth(:,i) = 1.e30 - So_s_depth(:,i) = 1.e30 + ! For now assume that all the streams have the same vertical levels + stream_index = 1 + + nlev_stream = sdat%pstrm(stream_index)%stream_nlev + allocate(stream_vlevs(nlev_stream)) + stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) + + do ko = 1,nlev_export + level_found = .false. + do ki = 1,nlev_stream-1 + if (vertical_levels(ko) > stream_vlevs(ki) .and. vertical_levels(ko) <= stream_vlevs(ki+1)) then + if (mainproc .and. first_time) then + write(logunit,'(a,3(i5,2x),3(f13.5,2x))') & + 'vertical interpolation: ki,ko,ki+1,lev(ki),lev(ko),lev(ki+1) = ',& + ki,ko,ki+1,stream_vlevs(ki), vertical_levels(ko), stream_vlevs(ki+1) + end if + level_found = .true. + do i = 1,size(So_omask) + if (So_omask(i) == 0.) then + So_t_depth(ko,i) = 1.e30 + So_s_depth(ko,i) = 1.e30 + else + if (stream_So_t_depth(ki+1,i) == shr_const_spval) then + So_t_depth(ko,i) = stream_So_t_depth(ki,i) + So_s_depth(ko,i) = stream_So_s_depth(ki,i) + else + factor = (stream_So_t_depth(ki+1,i)-stream_So_t_depth(ki,i))/(stream_vlevs(ki+1)-stream_vlevs(ki)) + So_t_depth(ko,i) = stream_So_t_depth(ki,i) + (vertical_levels(ko)-stream_vlevs(ki))*factor + + factor = (stream_So_s_depth(ki+1,i)-stream_So_s_depth(ki,i))/(stream_vlevs(ki+1)-stream_vlevs(ki)) + So_s_depth(ko,i) = stream_So_s_depth(ki,i) + (vertical_levels(ko)-stream_vlevs(ki))*factor + end if + end if + end do + end if + end do + if (.not. level_found) then + call shr_sys_abort("ERROR: could not find level bounds for vertical interpolation") end if end do + first_time = .false. + end subroutine docn_datamode_multilev_advance !=============================================================================== diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index 3a9c12a83..ced8cb86d 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -184,6 +184,7 @@ end subroutine SetServices !=============================================================================== subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) use shr_nl_mod, only: shr_nl_find_group_name + ! input/output variables type(ESMF_GridComp) :: gcomp type(ESMF_State) :: importState, exportState @@ -198,7 +199,6 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: bcasttmp(4) real(r8) :: rtmp(1) type(ESMF_VM) :: vm - integer :: nlev = 60 !DEBUG - remove this and put into namelist character(len=*),parameter :: subname=trim(module_name)//':(InitializeAdvertise) ' character(*) ,parameter :: F00 = "('(" // trim(module_name) // ") ',8a)" character(*) ,parameter :: F01 = "('(" // trim(module_name) // ") ',a,2x,i8)" @@ -331,7 +331,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call docn_datamode_cplhist_advertise(exportState, fldsExport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return else if (trim(datamode) == 'multilev') then - call docn_datamode_multilev_advertise(exportState, fldsExport, flds_scalar_name, nlev, rc) + call docn_datamode_multilev_advertise(exportState, fldsExport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -561,7 +561,7 @@ subroutine docn_comp_run(importState, exportState, clock, target_ymd, target_tod call docn_datamode_cplhist_init_pointers(exportState, model_frac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case('multilev') - call docn_datamode_multilev_init_pointers(exportState, model_frac, rc) + call docn_datamode_multilev_init_pointers(exportState, sdat, model_frac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select @@ -621,7 +621,7 @@ subroutine docn_comp_run(importState, exportState, clock, target_ymd, target_tod call docn_datamode_cplhist_advance(rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case('multilev') - call docn_datamode_multilev_advance(rc=rc) + call docn_datamode_multilev_advance(sdat, logunit, mainproc, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index e9159f69b..5830f5e98 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -94,6 +94,7 @@ module dshr_strdata_mod character(CL), allocatable :: fldlist_stream(:) ! names of stream file fields character(CL), allocatable :: fldlist_model(:) ! names of stream model fields integer :: stream_nlev ! number of vertical levels in stream + real(r8), allocatable :: stream_vlevs(:) ! values of vertical levels in stream integer :: stream_lb ! index of the Lowerbound (LB) in fldlist_stream integer :: stream_ub ! index of the Upperbound (UB) in fldlist_stream type(ESMF_Field) :: field_stream ! a field on the stream data domain @@ -679,6 +680,7 @@ subroutine shr_strdata_get_stream_nlev(sdat, stream_index, rc) integer :: rcode character(CX) :: filename integer :: dimid + type(var_desc_t) :: varid integer :: stream_nlev character(*), parameter :: subname = '(shr_strdata_set_stream_domain) ' ! ---------------------------------------------- @@ -698,10 +700,17 @@ subroutine shr_strdata_get_stream_nlev(sdat, stream_index, rc) rcode = pio_openfile(sdat%pio_subsystem, pioid, sdat%io_type, trim(filename), pio_nowrite) rcode = pio_inq_dimid(pioid, trim(sdat%stream(stream_index)%lev_dimname), dimid) rcode = pio_inq_dimlen(pioid, dimid, stream_nlev) + allocate(sdat%pstrm(stream_index)%stream_vlevs(stream_nlev)) + rcode = pio_inq_varid(pioid, trim(sdat%stream(stream_index)%lev_dimname), varid) + rcode = pio_get_var(pioid, varid, sdat%pstrm(stream_index)%stream_vlevs) + ! DEBUG: input is in cm + sdat%pstrm(stream_index)%stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) / 100. + ! DEBUG call pio_closefile(pioid) end if if (sdat%mainproc) then write(sdat%stream(1)%logunit,*) trim(subname)//' stream_nlev = ',stream_nlev + write(sdat%stream(1)%logunit,*)' stream vertical levels = ',sdat%pstrm(stream_index)%stream_vlevs end if ! Set stream_nlev in the per-stream sdat info From 458f0df591a569ccbc5b1505ea8fed85d1013144 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 23 Apr 2024 05:53:49 -0600 Subject: [PATCH 077/170] added query for units of ocean depth layers --- docn/docn_datamode_multilev_mod.F90 | 3 ++- streams/dshr_strdata_mod.F90 | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index c43f6b35e..bb528a584 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -142,7 +142,8 @@ subroutine docn_datamode_multilev_advance(sdat, logunit, mainproc, rc) nlev_stream = sdat%pstrm(stream_index)%stream_nlev allocate(stream_vlevs(nlev_stream)) - stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) + ! TODO: for now hard-wired input in cm + stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) / 100. do ko = 1,nlev_export level_found = .false. diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index 5830f5e98..60e3d0ddc 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -51,7 +51,7 @@ module dshr_strdata_mod use pio , only : pio_inquire, pio_inq_varid, pio_inq_varndims, pio_inq_vardimid use pio , only : pio_inq_dimlen, pio_inq_vartype, pio_inq_dimname, pio_inq_dimid 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 : pio_read_darray, pio_setframe, pio_fill_double, pio_get_att, pio_inq_att use pio , only : PIO_BCAST_ERROR, PIO_RETURN_ERROR, PIO_NOERR, PIO_INTERNAL_ERROR, PIO_SHORT implicit none @@ -682,6 +682,8 @@ subroutine shr_strdata_get_stream_nlev(sdat, stream_index, rc) integer :: dimid type(var_desc_t) :: varid integer :: stream_nlev + integer :: old_handle ! previous setting of pio error handling + character(CS) :: units character(*), parameter :: subname = '(shr_strdata_set_stream_domain) ' ! ---------------------------------------------- @@ -703,9 +705,17 @@ subroutine shr_strdata_get_stream_nlev(sdat, stream_index, rc) allocate(sdat%pstrm(stream_index)%stream_vlevs(stream_nlev)) rcode = pio_inq_varid(pioid, trim(sdat%stream(stream_index)%lev_dimname), varid) rcode = pio_get_var(pioid, varid, sdat%pstrm(stream_index)%stream_vlevs) - ! DEBUG: input is in cm - sdat%pstrm(stream_index)%stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) / 100. - ! DEBUG + + ! Determine vertical coordinates units - assume that default is m + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR, old_handle) + rcode = pio_inq_att(pioid, varid, 'units') + call pio_seterrorhandling(pioid, old_handle) + if (rcode == PIO_NOERR) then + rcode = pio_get_att(pioid, varid, 'units', units) + if (trim(units) == 'centimeters' .or. trim(units) == 'cm') then + sdat%pstrm(stream_index)%stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) / 100. + end if + end if call pio_closefile(pioid) end if if (sdat%mainproc) then From 38ce4fbca00f964d75cbc9cfa03331cbdf8727bc Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 24 Apr 2024 09:37:48 -0600 Subject: [PATCH 078/170] updates needed for multi-level ocean input --- dglc/dglc_datamode_noevolve_mod.F90 | 11 ++++++++++- docn/docn_datamode_multilev_mod.F90 | 10 +++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 95a6d8469..084531477 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -30,7 +30,8 @@ module dglc_datamode_noevolve_mod ! Data structure to enable multiple ice sheets type icesheet_ptr_t - real(r8), pointer :: ptr(:) => null() ! pointer to array + real(r8), pointer :: ptr(:) => null() ! pointer to array + real(r8), pointer :: ptr2d(:,:) => null() ! pointer to 2d array endtype icesheet_ptr_t ! Export fields @@ -42,8 +43,11 @@ module dglc_datamode_noevolve_mod type(icesheet_ptr_t), allocatable :: Fogg_rofi(:) ! Import fields + integer, parameter :: nlev_import = 30 type(icesheet_ptr_t), allocatable :: Sl_tsrf(:) type(icesheet_ptr_t), allocatable :: Flgl_qice(:) + type(icesheet_ptr_t), allocatable :: So_t(:) + type(icesheet_ptr_t), allocatable :: So_q(:) ! Export Field names character(len=*), parameter :: field_out_area = 'Sg_area' @@ -56,6 +60,8 @@ module dglc_datamode_noevolve_mod ! Import Field names character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' character(len=*), parameter :: field_in_qice = 'Flgl_qice' + character(len=*), parameter :: field_in_so_t_depth = 'So_t_depth' + character(len=*), parameter :: field_in_so_s_depth = 'So_s_depth' character(*) , parameter :: rpfile = 'rpointer.glc' character(*) , parameter :: u_FILE_u = & @@ -115,6 +121,9 @@ subroutine dglc_datamode_noevolve_advertise(NStateExp, fldsexport, NStateImp, fl call dshr_fldList_add(fldsImport, trim(flds_scalar_name)) call dshr_fldList_add(fldsImport, field_in_tsrf) call dshr_fldList_add(fldsImport, field_in_qice) + ! TODO: Add namelist for this + call dshr_fldList_add(fldsImport, field_in_so_t_depth, ungridded_lbound=1, ungridded_ubound=nlev_import) + call dshr_fldList_add(fldsImport, field_in_so_s_depth, ungridded_lbound=1, ungridded_ubound=nlev_import) do ns = 1,num_icesheets write(cnum,'(i0)') ns diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index bb528a584..6a1ec7605 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -142,8 +142,7 @@ subroutine docn_datamode_multilev_advance(sdat, logunit, mainproc, rc) nlev_stream = sdat%pstrm(stream_index)%stream_nlev allocate(stream_vlevs(nlev_stream)) - ! TODO: for now hard-wired input in cm - stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) / 100. + stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) do ko = 1,nlev_export level_found = .false. @@ -157,15 +156,16 @@ subroutine docn_datamode_multilev_advance(sdat, logunit, mainproc, rc) level_found = .true. do i = 1,size(So_omask) if (So_omask(i) == 0.) then - So_t_depth(ko,i) = 1.e30 - So_s_depth(ko,i) = 1.e30 + So_t_depth(ko,i) = shr_const_spval + So_s_depth(ko,i) = shr_const_spval else if (stream_So_t_depth(ki+1,i) == shr_const_spval) then - So_t_depth(ko,i) = stream_So_t_depth(ki,i) + So_t_depth(ko,i) = stream_So_t_depth(ki,i) + shr_const_tkfrz So_s_depth(ko,i) = stream_So_s_depth(ki,i) else factor = (stream_So_t_depth(ki+1,i)-stream_So_t_depth(ki,i))/(stream_vlevs(ki+1)-stream_vlevs(ki)) So_t_depth(ko,i) = stream_So_t_depth(ki,i) + (vertical_levels(ko)-stream_vlevs(ki))*factor + So_t_depth(ko,i) = So_t_depth(ko,i) + shr_const_tkfrz factor = (stream_So_s_depth(ki+1,i)-stream_So_s_depth(ki,i))/(stream_vlevs(ki+1)-stream_vlevs(ki)) So_s_depth(ko,i) = stream_So_s_depth(ki,i) + (vertical_levels(ko)-stream_vlevs(ki))*factor From 2121f2b88109415554cfa68022faa1e35c60f8c9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 24 Apr 2024 09:46:06 -0600 Subject: [PATCH 079/170] update comment --- docn/docn_datamode_multilev_mod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index 6a1ec7605..6a9828667 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -159,6 +159,7 @@ subroutine docn_datamode_multilev_advance(sdat, logunit, mainproc, rc) So_t_depth(ko,i) = shr_const_spval So_s_depth(ko,i) = shr_const_spval else + ! Assume input T forcing is in degrees C if (stream_So_t_depth(ki+1,i) == shr_const_spval) then So_t_depth(ko,i) = stream_So_t_depth(ki,i) + shr_const_tkfrz So_s_depth(ko,i) = stream_So_s_depth(ki,i) From 423829fff04bfcff9fc3b5c6068eec6ec924620a Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Sun, 28 Apr 2024 15:21:55 -0600 Subject: [PATCH 080/170] Revert "make the amount of data required to download minimal for testing" --- cime_config/stream_cdeps.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index 28db8a905..1f702a13c 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -204,9 +204,6 @@ def create_stream_xml( data_year_first, data_year_last = self._get_stream_first_and_last_dates( self.stream_nodes, case ) - # If this is a test we don't need the full extent of the data - if case.get_value("TEST"): - data_year_first = max(data_year_last-2, data_year_first) # now write the data model streams xml file stream_vars = {} From 7e1096f4a1630210d3fca454d6f9a08563333381 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 29 Apr 2024 04:22:41 -0600 Subject: [PATCH 081/170] fixes to permit stream field with ungridded dimensions --- dshr/dshr_dfield_mod.F90 | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dshr/dshr_dfield_mod.F90 b/dshr/dshr_dfield_mod.F90 index bfd5cdc1a..2f3b33d69 100644 --- a/dshr/dshr_dfield_mod.F90 +++ b/dshr/dshr_dfield_mod.F90 @@ -1,7 +1,7 @@ module dshr_dfield_mod use ESMF , only : ESMF_State, ESMF_FieldBundle, ESMF_MAXSTR, ESMF_SUCCESS - use ESMF , only : ESMF_FieldBundleGet, ESMF_ITEMORDER_ADDORDER, ESMF_Field + use ESMF , only : ESMF_FieldBundleGet, ESMF_ITEMORDER_ADDORDER, ESMF_Field, ESMF_FieldGet use shr_kind_mod , only : r8=>shr_kind_r8, cs=>shr_kind_cs, cl=>shr_kind_cl, cxx=>shr_kind_cxx use shr_sys_mod , only : shr_sys_abort use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_get_stream_count, shr_strdata_get_stream_fieldbundle @@ -442,6 +442,8 @@ subroutine dshr_dfield_copy(dfields, sdat, rc) integer :: nf integer :: fldbun_index integer :: stream_index + integer :: ungriddedUBound_output(1) + integer :: ungriddedCount !------------------------------------------------------------------------------- rc = ESMF_SUCCESS @@ -469,9 +471,18 @@ subroutine dshr_dfield_copy(dfields, sdat, rc) fldbun_model = shr_strdata_get_stream_fieldbundle(sdat, stream_index, 'model') call dshr_fldbun_getfieldn(fldbun_model, fldbun_index, lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_field_getfldptr(lfield, fldptr2=data2d, rc=rc) + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound_output, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - dfield%state_data2d(:,:) = data2d(:,:) + ungriddedCount = ungriddedUBound_output(1) + if (ungriddedCount > 0) then + call dshr_field_getfldptr(lfield, fldptr2=data2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dfield%state_data2d(:,:) = data2d(:,:) + else + call dshr_field_getfldptr(lfield, fldptr1=data1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dfield%state_data2d(nf,:) = data1d(:) + end if endif end do end if From 1ba9b8f1716255b20469b2d0de93a563454d310f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 29 Apr 2024 08:30:04 -0600 Subject: [PATCH 082/170] updated testlist so that DGLC%NOEVOLVE passes --- dglc/cime_config/testdefs/testlist_dglc.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dglc/cime_config/testdefs/testlist_dglc.xml b/dglc/cime_config/testdefs/testlist_dglc.xml index 194773fa7..8383469c7 100644 --- a/dglc/cime_config/testdefs/testlist_dglc.xml +++ b/dglc/cime_config/testdefs/testlist_dglc.xml @@ -1,7 +1,7 @@ - + @@ -10,7 +10,7 @@ - + @@ -19,7 +19,7 @@ - + From dc6923e09a0959c7b3ec05ba0e07e2501d81e906 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 1 May 2024 14:29:38 -0600 Subject: [PATCH 083/170] fixes for vertical interpolation --- docn/docn_datamode_multilev_mod.F90 | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index 6a9828667..0c6ea681b 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -29,10 +29,8 @@ module docn_datamode_multilev_mod integer, parameter :: nlev_export = 30 real(r8) :: vertical_levels(nlev_export) = (/ & - 60. , 120. , 180. , 240. , 300. , 360. , & - 420. , 480. , 540. , 600. , 660. , 720. , & - 780. , 840. , 900. , 960. , 1020., 1080., & - 1140., 1200., 1260., 1320., 1380., 1440., & + 60. , 120. , 180. , 240. , 300. , 360. , 420. , 480. , 540. , 600. , 660. , 720. , & + 780. , 840. , 900. , 960. , 1020., 1080., 1140., 1200., 1260., 1320., 1380., 1440., & 1500., 1560., 1620., 1680., 1740., 1800. /) ! constants @@ -160,9 +158,14 @@ subroutine docn_datamode_multilev_advance(sdat, logunit, mainproc, rc) So_s_depth(ko,i) = shr_const_spval else ! Assume input T forcing is in degrees C - if (stream_So_t_depth(ki+1,i) == shr_const_spval) then - So_t_depth(ko,i) = stream_So_t_depth(ki,i) + shr_const_tkfrz - So_s_depth(ko,i) = stream_So_s_depth(ki,i) + if (stream_So_t_depth(ki+1,i) > 1.e10) then + if (stream_So_t_depth(ki,i) > 1.e10) then + So_t_depth(ko,i) = shr_const_spval + So_s_depth(ko,i) = shr_const_spval + else + So_t_depth(ko,i) = stream_So_t_depth(ki,i) + shr_const_tkfrz + So_s_depth(ko,i) = stream_So_s_depth(ki,i) + end if else factor = (stream_So_t_depth(ki+1,i)-stream_So_t_depth(ki,i))/(stream_vlevs(ki+1)-stream_vlevs(ki)) So_t_depth(ko,i) = stream_So_t_depth(ki,i) + (vertical_levels(ko)-stream_vlevs(ki))*factor From 27726a1cab6aa0a3d863797fefb47e8d5a66671e Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 2 May 2024 19:34:21 +0200 Subject: [PATCH 084/170] update for blom output stream --- docn/cime_config/namelist_definition_docn.xml | 2 +- docn/cime_config/stream_definition_docn.xml | 45 ++++++++++++++++--- docn/docn_datamode_multilev_mod.F90 | 6 +-- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/docn/cime_config/namelist_definition_docn.xml b/docn/cime_config/namelist_definition_docn.xml index 71109b1c7..b2f788113 100644 --- a/docn/cime_config/namelist_definition_docn.xml +++ b/docn/cime_config/namelist_definition_docn.xml @@ -32,7 +32,7 @@ '' '' '' - sst_depth,salinity_depth + sst_salinity_depth_blom diff --git a/docn/cime_config/stream_definition_docn.xml b/docn/cime_config/stream_definition_docn.xml index 4144e0e53..4e4dd6655 100644 --- a/docn/cime_config/stream_definition_docn.xml +++ b/docn/cime_config/stream_definition_docn.xml @@ -209,12 +209,12 @@ single - + - $DIN_LOC_ROOT/share/meshes/gx1v7_151008_ESMFmesh.nc + $DIN_LOC_ROOT/share/meshes/gx1v7_151008_ESMFmesh.nc - /glade/collections/cmip/CMIP6/OMIP/NCAR/CESM2/omip2/r1i1p1f1/Omon/thetao/gn/v20190802/thetao_Omon_CESM2_omip2_r1i1p1f1_gn_024501-030512.nc + /glade/collections/cmip/CMIP6/OMIP/NCAR/CESM2/omip2/r1i1p1f1/Omon/thetao/gn/v20190802/thetao_Omon_CESM2_omip2_r1i1p1f1_gn_024501-030512.nc thetao So_t_depth @@ -242,10 +242,10 @@ - $DIN_LOC_ROOT/share/meshes/gx1v7_151008_ESMFmesh.nc + $DIN_LOC_ROOT/share/meshes/gx1v7_151008_ESMFmesh.nc - /glade/collections/cmip/CMIP6/OMIP/NCAR/CESM2/omip2/r1i1p1f1/Omon/so/gn/v20190802/so_Omon_CESM2_omip2_r1i1p1f1_gn_024501-030512.nc + /glade/collections/cmip/CMIP6/OMIP/NCAR/CESM2/omip2/r1i1p1f1/Omon/so/gn/v20190802/so_Omon_CESM2_omip2_r1i1p1f1_gn_024501-030512.nc so So_s_depth @@ -271,4 +271,39 @@ single + + + $DIN_LOC_ROOT/share/meshes/tnx1v4_20170601_cdf5_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/docn7/MULTILEV/N1850frc2G_f09_tn14_gl4_SMB1_celo.blom.hm.2300.nc + $DIN_LOC_ROOT/ocn/docn7/MULTILEV/N1850frc2G_f09_tn14_gl4_SMB1_celo.blom.hm.2301.nc + $DIN_LOC_ROOT/ocn/docn7/MULTILEV/N1850frc2G_f09_tn14_gl4_SMB1_celo.blom.hm.2302.nc + $DIN_LOC_ROOT/ocn/docn7/MULTILEV/N1850frc2G_f09_tn14_gl4_SMB1_celo.blom.hm.2303.nc + + + templvl So_t_depth + salnlvl So_s_depth + + depth + + bilinear + + null + 1 + 2300 + 2303 + 0 + + linear + + + cycle + + + 1.5 + + single + + diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index 0c6ea681b..897797f3f 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -29,9 +29,9 @@ module docn_datamode_multilev_mod integer, parameter :: nlev_export = 30 real(r8) :: vertical_levels(nlev_export) = (/ & - 60. , 120. , 180. , 240. , 300. , 360. , 420. , 480. , 540. , 600. , 660. , 720. , & - 780. , 840. , 900. , 960. , 1020., 1080., 1140., 1200., 1260., 1320., 1380., 1440., & - 1500., 1560., 1620., 1680., 1740., 1800. /) + 30., 90., 150., 210., 270., 330., 390., 450., 510., 570., & + 630., 690., 750., 810., 870., 930., 990., 1050., 1110., 1170., & + 1230., 1290., 1350., 1410., 1470., 1530., 1590., 1650., 1710., 1770. /) ! constants character(*) , parameter :: nullstr = 'null' From 4070e0a8c1a7b70968b9672ce44b53eea47f982d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 5 May 2024 11:07:31 -0600 Subject: [PATCH 085/170] fix for CTSM issue Issue #2518 --- streams/dshr_strdata_mod.F90 | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index e9159f69b..877b781ff 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -1933,6 +1933,7 @@ subroutine shr_strdata_set_stream_iodesc(sdat, per_stream, fldname, pioid, rc) character(*), parameter :: F00 = "('(shr_strdata_set_stream_iodesc) ',a,i8,2x,i8,2x,a)" character(*), parameter :: F01 = "('(shr_strdata_set_stream_iodesc) ',a,i8,2x,i8,2x,a)" character(*), parameter :: F02 = "('(shr_strdata_set_stream_iodesc) ',a,i8,2x,i8,2x,i8,2x,a)" + character(*), parameter :: F03 = "('(shr_strdata_set_stream_iodesc) ',a,i8,2x,a)" !------------------------------------------------------------------------------- rc = ESMF_SUCCESS @@ -1982,13 +1983,23 @@ subroutine shr_strdata_set_stream_iodesc(sdat, per_stream, fldname, pioid, rc) ! determine io descriptor if (ndims == 2) then - if (sdat%mainproc) then - write(sdat%stream(1)%logunit,F00) 'setting iodesc for : '//trim(fldname)// & - ' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2),& - ' variable has no time dimension ' + rcode = pio_inq_dimname(pioid, dimids(ndims), dimname) + if (trim(dimname) == 'time' .or. trim(dimname) == 'nt') then + if (sdat%mainproc) then + write(sdat%stream(1)%logunit,F03) 'setting iodesc for : '//trim(fldname)// & + ' with dimlens(1) = ',dimlens(1),' and the variable has a time dimension ' + end if + call pio_initdecomp(sdat%pio_subsystem, pio_iovartype, (/dimlens(1)/), compdof, & + per_stream%stream_pio_iodesc) + else + if (sdat%mainproc) then + write(sdat%stream(1)%logunit,F00) 'setting iodesc for : '//trim(fldname)// & + ' with dimlens(1), dimlens(2) = ',dimlens(1),dimlens(2),& + ' variable has no time dimension ' + end if + call pio_initdecomp(sdat%pio_subsystem, pio_iovartype, (/dimlens(1),dimlens(2)/), compdof, & + per_stream%stream_pio_iodesc) end if - call pio_initdecomp(sdat%pio_subsystem, pio_iovartype, (/dimlens(1),dimlens(2)/), compdof, & - per_stream%stream_pio_iodesc) else if (ndims == 3) then rcode = pio_inq_dimname(pioid, dimids(ndims), dimname) From 47a0d2ba27c529f8d0a011afe25ff1225b3438d8 Mon Sep 17 00:00:00 2001 From: Teagan King Date: Wed, 8 May 2024 10:44:33 -0600 Subject: [PATCH 086/170] updates to PLUMBER stream --- cime_config/stream_cdeps.py | 9 ++++++++- datm/cime_config/stream_definition_datm.xml | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index bf3e6e788..7c6118f7a 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -76,6 +76,7 @@ def create_stream_xml( data_list_file, user_mods_file, available_neon_data=None, + available_plumber_data=None ): """ Create the stream xml file and append the required stream input data to the input data list file @@ -245,12 +246,18 @@ def create_stream_xml( and ("PRISM" not in stream_name) ): rundir = case.get_value("RUNDIR") - #TODO: may need to add a similar PLUMBER line for neon in available_neon_data: stream_datafiles += ( os.path.join(rundir, "inputdata", "atm", neon) + "\n" ) + elif available_plumber_data and stream_name.startswith("PLUMBER"): + rundir = case.get_value("RUNDIR") + for plumber in available_plumber_data: + stream_datafiles += ( + os.path.join(rundir, "inputdata", "atm", plumber) + + "\n" + ) else: stream_datafiles = child.xml_element.text stream_datafiles = self._resolve_values( diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 4936eb0a0..ffb7ec71b 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -351,7 +351,7 @@ none - $DIN_LOC_ROOT/atm/cdeps/PLUMBER2/${NEONSITE}_%y.nc + $DIN_LOC_ROOT/atm/cdeps/PLUMBER2/${PLUMBER2SITE}_%y.nc PRECIP Faxa_precn # this will probably need updating From c2ac6765b8ad56a81c778f16affc0828759a636a Mon Sep 17 00:00:00 2001 From: Teagan King Date: Thu, 9 May 2024 13:34:30 -0600 Subject: [PATCH 087/170] include correct variables in stream --- datm/cime_config/stream_definition_datm.xml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index ffb7ec71b..764ea7629 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -350,11 +350,18 @@ none - + #TODO: also include data files form here? https://github.com/ESCOMP/CTSM/pull/2155/files#diff-1f787dc228c6e41e2e3e2a82101d6ea4980ee2535ecbcb06e5d6e5d6bda8f167 $DIN_LOC_ROOT/atm/cdeps/PLUMBER2/${PLUMBER2SITE}_%y.nc - PRECIP Faxa_precn # this will probably need updating + ZBOT Sa_z + TBOT Sa_tbot + QBOT Sa_shum + WIND Sa_wind + PRECTmms Faxa_precn + FSDS Faxa_swdn + PSRF Sa_pbot + FLDS Faxa_lwdn null @@ -363,7 +370,7 @@ null $DATM_YR_ALIGN $DATM_YR_START - $DATM_YR_END + $DATM_YR_END # TODO: not sure if we need month info, etc here? 0 linear From 13f4594c00088645c49b79fe9cba43494868b6f3 Mon Sep 17 00:00:00 2001 From: Teagan King Date: Thu, 9 May 2024 14:58:41 -0600 Subject: [PATCH 088/170] temporary plumber change for dtlimit --- datm/cime_config/stream_definition_datm.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 764ea7629..e274c4c82 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -350,7 +350,7 @@ none - #TODO: also include data files form here? https://github.com/ESCOMP/CTSM/pull/2155/files#diff-1f787dc228c6e41e2e3e2a82101d6ea4980ee2535ecbcb06e5d6e5d6bda8f167 + $DIN_LOC_ROOT/atm/cdeps/PLUMBER2/${PLUMBER2SITE}_%y.nc @@ -370,7 +370,7 @@ null $DATM_YR_ALIGN $DATM_YR_START - $DATM_YR_END # TODO: not sure if we need month info, etc here? + $DATM_YR_END 0 linear @@ -4080,6 +4080,7 @@ 1.5 + CLM_USRDAT_NAME=="PLUMBER" 30 single @@ -4619,6 +4620,7 @@ 1.5 + CLM_USRDAT_NAME="PLUMBER" 30 single From cf975ab4fd7afd99b3912334e45799cc0d51fba7 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Thu, 9 May 2024 15:13:25 -0600 Subject: [PATCH 089/170] Update stream_definition_datm.xml to include longer files --- datm/cime_config/stream_definition_datm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 310c5097e..7f38bedad 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -3578,7 +3578,7 @@ none - $DIN_LOC_ROOT/atm/datm7/CO2/fco2_datm_globalSSP3-7.0__simyr_2014-2501_CMIP6_c190506.nc + $DIN_LOC_ROOT/atm/datm7/CO2/fco2_datm_globalSSP3-7.0_simyr_1750-2501_CMIP6_c201101.nc CO2 Sa_co2diag @@ -4001,7 +4001,7 @@ $DIN_LOC_ROOT/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc - $DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/aero/aerodep_clm_SSP370_b.e21.BWSSP370cmip6.f09_g17.CMIP6-SSP3-7.0-WACCM.001_2014-2101_monthly_0.9x1.25_c190402.nc + $DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/aero/aerodep_clm_SSP370_b.e21.BWSSP370cmip6.f09_g17.CMIP6-SSP3-7.0-WACCM.001_1849-2101_monthly_0.9x1.25_c201103.nc BCDEPWET Faxa_bcphiwet From 72b8e24a2d33a97ec5c83ca23b8832880c8143e8 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 13 May 2024 12:51:32 -0600 Subject: [PATCH 090/170] remove manage externals, replace with git-fleximod --- .gitignore | 4 ---- .gitmodules | 16 ++++++++++++++++ fox | 1 + share/genf90 | 1 + 4 files changed, 18 insertions(+), 4 deletions(-) create mode 160000 fox create mode 160000 share/genf90 diff --git a/.gitignore b/.gitignore index 625692541..34b286f3e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,9 +31,5 @@ *.out *.app -# Externals -fox -share/genf90 - # ignore pycache __pycache__ diff --git a/.gitmodules b/.gitmodules index e69de29bb..4d1a64693 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,16 @@ +# This is a git-fleximod adapted .gitmodules file. Any field with a name starting in fx is a git-fleximod +# specific field. See https://github.com/ESMCI/git-fleximod for details. + +[submodule "fox"] +path = fox +url = https://github.com/ESMCI/fox.git +fxtag = 4.1.2.1 +fxrequired = AlwaysRequired +fxDONOTUSEurl = https://github.com/ESMCI/fox.git + +[submodule "genf90"] +path = share/genf90 +url = https://github.com/PARALLELIO/genf9 +fxtag = 4816965 +fxrequired = AlwaysRequired +fxDONOTUSEurl = https://github.com/PARALLELIO/genf9 diff --git a/fox b/fox new file mode 160000 index 000000000..4ff17b4a1 --- /dev/null +++ b/fox @@ -0,0 +1 @@ +Subproject commit 4ff17b4a1a66b4ae0fbe9a2067503cb4b4c292c0 diff --git a/share/genf90 b/share/genf90 new file mode 160000 index 000000000..4816965ba --- /dev/null +++ b/share/genf90 @@ -0,0 +1 @@ +Subproject commit 4816965ba946731352bad195b7d946a5fe682ff5 From 89a713f9cbe3e9a4a084a74200438892f1ed486f Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 13 May 2024 12:53:34 -0600 Subject: [PATCH 091/170] update github workflow --- .github/workflows/extbuild.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 52afb7b81..185f6d85d 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -19,11 +19,11 @@ jobs: CPPFLAGS: "-I/usr/include -I/usr/local/include " LDFLAGS: "-L/usr/lib/x86_64-linux-gnu " # Versions of all dependencies can be updated here - these match tag names in the github repo - ESMF_VERSION: v8.5.0 - ParallelIO_VERSION: pio2_6_0 + ESMF_VERSION: v8.6.1 + ParallelIO_VERSION: pio2_6_2 steps: - id: checkout-CDEPS - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive - id: load-env @@ -37,7 +37,7 @@ jobs: sudo apt-get install autotools-dev autoconf - name: Cache PARALLELIO id: cache-PARALLELIO - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${GITHUB_WORKSPACE}/pio key: ${{ runner.os }}-${{ env.ParallelIO_VERSION }}-parallelio2 From 023f198cb3e099a93ccbf9ce53efa7b37f019de7 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 13 May 2024 12:59:11 -0600 Subject: [PATCH 092/170] fix typo in .gitmodules --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 4d1a64693..4e98d1b69 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,7 +10,7 @@ fxDONOTUSEurl = https://github.com/ESMCI/fox.git [submodule "genf90"] path = share/genf90 -url = https://github.com/PARALLELIO/genf9 +url = https://github.com/PARALLELIO/genf90 fxtag = 4816965 fxrequired = AlwaysRequired -fxDONOTUSEurl = https://github.com/PARALLELIO/genf9 +fxDONOTUSEurl = https://github.com/PARALLELIO/genf90 From 017e6a992b61488347ff64dc616035506bd405c1 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 14 May 2024 07:40:34 -0600 Subject: [PATCH 093/170] update workflow versions --- .github/workflows/extbuild.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 52afb7b81..185f6d85d 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -19,11 +19,11 @@ jobs: CPPFLAGS: "-I/usr/include -I/usr/local/include " LDFLAGS: "-L/usr/lib/x86_64-linux-gnu " # Versions of all dependencies can be updated here - these match tag names in the github repo - ESMF_VERSION: v8.5.0 - ParallelIO_VERSION: pio2_6_0 + ESMF_VERSION: v8.6.1 + ParallelIO_VERSION: pio2_6_2 steps: - id: checkout-CDEPS - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive - id: load-env @@ -37,7 +37,7 @@ jobs: sudo apt-get install autotools-dev autoconf - name: Cache PARALLELIO id: cache-PARALLELIO - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${GITHUB_WORKSPACE}/pio key: ${{ runner.os }}-${{ env.ParallelIO_VERSION }}-parallelio2 From 472b568fadfcfb744ea4cdaf805af7b635238d06 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 14 May 2024 07:50:55 -0600 Subject: [PATCH 094/170] comment out unused vars --- dglc/dglc_datamode_noevolve_mod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 084531477..e4392105e 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -46,8 +46,8 @@ module dglc_datamode_noevolve_mod integer, parameter :: nlev_import = 30 type(icesheet_ptr_t), allocatable :: Sl_tsrf(:) type(icesheet_ptr_t), allocatable :: Flgl_qice(:) - type(icesheet_ptr_t), allocatable :: So_t(:) - type(icesheet_ptr_t), allocatable :: So_q(:) +! type(icesheet_ptr_t), allocatable :: So_t(:) +! type(icesheet_ptr_t), allocatable :: So_q(:) ! Export Field names character(len=*), parameter :: field_out_area = 'Sg_area' From a8baf6644e46ceaeb47fbf03ef47c4a4e61b9753 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 14 May 2024 07:54:57 -0600 Subject: [PATCH 095/170] remove more unused vars --- dglc/glc_comp_nuopc.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 4597c4065..09c858ff1 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -454,7 +454,6 @@ subroutine ModelAdvance(gcomp, rc) integer :: yr ! year integer :: mon ! month integer :: day ! day in month - integer :: tod ! seconds in day logical :: restart_write type(ESMF_Alarm) :: valid_alarm logical :: valid_inputs ! if true, inputs from mediator are valid @@ -680,7 +679,6 @@ subroutine ModelSetRunClock(gcomp, rc) integer :: stop_n ! Number until stop interval integer :: stop_ymd ! Stop date (YYYYMMDD) type(ESMF_ALARM) :: stop_alarm - character(len=128) :: name integer :: alarmcount character(len=CS) :: glc_avg_period ! averaging period in mediator type(ESMF_ALARM) :: valid_alarm ! model alarm From ee01687ae1a8bf1c160a0a40fe3728d30a39c691 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 15 May 2024 11:23:15 -0600 Subject: [PATCH 096/170] bug fix for single level --- streams/dshr_strdata_mod.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index 60e3d0ddc..724ea7d36 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -720,7 +720,9 @@ subroutine shr_strdata_get_stream_nlev(sdat, stream_index, rc) end if if (sdat%mainproc) then write(sdat%stream(1)%logunit,*) trim(subname)//' stream_nlev = ',stream_nlev - write(sdat%stream(1)%logunit,*)' stream vertical levels = ',sdat%pstrm(stream_index)%stream_vlevs + if (stream_nlev /= 1) then + write(sdat%stream(1)%logunit,*)' stream vertical levels = ',sdat%pstrm(stream_index)%stream_vlevs + end if end if ! Set stream_nlev in the per-stream sdat info From d0016108eb709a4c55b099e8e5b27e9f35289c4e Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Wed, 15 May 2024 11:52:22 -0600 Subject: [PATCH 097/170] Update if statements for dtlimit in stream_definition_datm.xml --- datm/cime_config/stream_definition_datm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index e274c4c82..71883a107 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -4080,7 +4080,7 @@ 1.5 - CLM_USRDAT_NAME=="PLUMBER" 30 + 30 single @@ -4620,7 +4620,7 @@ 1.5 - CLM_USRDAT_NAME="PLUMBER" 30 + 30 single From bb18dea762b17105dc6215fe50ee3fce31cd7616 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 17 May 2024 07:16:06 -0600 Subject: [PATCH 098/170] updates the fox build since the directory now always exists (but may be empty) --- CMakeLists.txt | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc7cce6df..ff7046ebd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,23 +71,18 @@ add_subdirectory(streams) add_subdirectory(dshr) if(NOT DISABLE_FoX) - if(IS_DIRECTORY "${FOX_ROOT}") - message(STATUS "FoX library is already checked out!") - message(STATUS "FoX source dir: ${FOX_ROOT}") - else() - FetchContent_Declare(fox - GIT_REPOSITORY https://github.com/ESMCI/fox.git - GIT_TAG 4.1.2.1 - SOURCE_DIR ${FOX_ROOT} - BINARY_DIR ${FOX_ROOT}/.. - ) - FetchContent_GetProperties(fox) - if(NOT fox_POPULATED) - FetchContent_Populate(fox) - message(STATUS "FoX source dir: ${fox_SOURCE_DIR}") - message(STATUS "FoX binary dir: ${fox_BINARY_DIR}") - endif() - endif() + FetchContent_Declare(fox + GIT_REPOSITORY https://github.com/ESMCI/fox.git + GIT_TAG 4.1.2.1 + SOURCE_DIR ${FOX_ROOT} + BINARY_DIR ${FOX_ROOT}/.. + ) + FetchContent_GetProperties(fox) + if(NOT fox_POPULATED) + FetchContent_Populate(fox) + message(STATUS "FoX source dir: ${fox_SOURCE_DIR}") + message(STATUS "FoX binary dir: ${fox_BINARY_DIR}") + endif() add_subdirectory(fox) target_include_directories(streams PUBLIC $ From 493b38e1ab61e03a8fd26e0195c88b3621845dd0 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Fri, 31 May 2024 17:26:49 -0600 Subject: [PATCH 099/170] Add changes to exchange between SOM and WW3DEV --- docn/docn_datamode_som_mod.F90 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docn/docn_datamode_som_mod.F90 b/docn/docn_datamode_som_mod.F90 index b91ce134d..672c58d4d 100644 --- a/docn/docn_datamode_som_mod.F90 +++ b/docn/docn_datamode_som_mod.F90 @@ -34,6 +34,7 @@ module docn_datamode_som_mod real(r8), pointer :: So_v(:) => null() real(r8), pointer :: So_dhdx(:) => null() real(r8), pointer :: So_dhdy(:) => null() + real(r8), pointer :: So_bldepth(:) => null() real(r8), pointer :: Fioo_q(:) => null() real(r8), pointer :: So_fswpen(:) => null() @@ -98,6 +99,7 @@ subroutine docn_datamode_som_advertise(importState, exportState, fldsimport, fld call dshr_fldList_add(fldsExport, 'So_v' ) call dshr_fldList_add(fldsExport, 'So_dhdx' ) call dshr_fldList_add(fldsExport, 'So_dhdy' ) + call dshr_fldList_add(fldsExport, 'So_bldepth' ) call dshr_fldList_add(fldsExport, 'Fioo_q' ) call dshr_fldList_add(fldsExport, 'So_fswpen' ) @@ -189,6 +191,8 @@ subroutine docn_datamode_som_init_pointers(importState, exportState, sdat, ocn_f if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'So_dhdy' , fldptr1=So_dhdy , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'So_bldepth' , fldptr1=So_bldepth , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(exportState, 'Fioo_q' , fldptr1=Fioo_q , rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -289,6 +293,7 @@ subroutine docn_datamode_som_advance(importState, exportState, clock, restart_re ! save somtp to restart file somtp(n) = So_t(n) + So_bldepth(n) = strm_h(n) endif end do deallocate(tfreeze) From 0acd3c738d9b4fe561d259fd4aa7e4c2e9d6b766 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 14 Jun 2024 02:56:24 -0600 Subject: [PATCH 100/170] fix initialization of dglc import/export pointers --- dglc/dglc_datamode_noevolve_mod.F90 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index e4392105e..0d9686094 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -7,7 +7,7 @@ module dglc_datamode_noevolve_mod use NUOPC , only : NUOPC_Advertise, NUOPC_IsConnected use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort - use shr_const_mod , only : SHR_CONST_RHOICE, SHR_CONST_RHOSW, SHR_CONST_REARTH + use shr_const_mod , only : SHR_CONST_RHOICE, SHR_CONST_RHOSW, SHR_CONST_REARTH, SHR_CONST_TKFRZ use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add use dshr_strdata_mod , only : shr_strdata_type @@ -46,8 +46,8 @@ module dglc_datamode_noevolve_mod integer, parameter :: nlev_import = 30 type(icesheet_ptr_t), allocatable :: Sl_tsrf(:) type(icesheet_ptr_t), allocatable :: Flgl_qice(:) -! type(icesheet_ptr_t), allocatable :: So_t(:) -! type(icesheet_ptr_t), allocatable :: So_q(:) + ! type(icesheet_ptr_t), allocatable :: So_t(:) + ! type(icesheet_ptr_t), allocatable :: So_q(:) ! Export Field names character(len=*), parameter :: field_out_area = 'Sg_area' @@ -177,6 +177,8 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(NStateExp(ns), field_out_rofi, fldptr1=Fogg_rofi(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + + Fogg_rofi(ns)%ptr(:) = 0._r8 end do ! initialize pointers to import fields if appropriate @@ -193,6 +195,9 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(NStateImp(ns), field_in_qice, fldptr1=Flgl_qice(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + + Sl_tsrf(ns)%ptr(:) = SHR_CONST_TKFRZ + Flgl_qice(ns)%ptr(:) = 0._r8 end do end subroutine dglc_datamode_noevolve_init_pointers @@ -368,7 +373,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & ! Compute Fogg_rofi do ns = 1,num_icesheets do ng = 1,size(Fogg_rofi(ns)%ptr) - Fogg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + Fogg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) end do end do end if From 096ff6adce342c7059cadfc8a4c641c6f0f0aec8 Mon Sep 17 00:00:00 2001 From: Chris Fischer Date: Fri, 14 Jun 2024 12:47:01 -0600 Subject: [PATCH 101/170] Fix missing field width for L edit descriptor for NAG --- dglc/glc_comp_nuopc.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 09c858ff1..f5b6c2a36 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -491,7 +491,7 @@ subroutine ModelAdvance(gcomp, rc) if (my_task == main_task) then call ESMF_TimeGet(currTime, timestring=timestring, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(logunit,'(a,l)') trim(timestring)//': valid_input for dglc is ',valid_inputs + write(logunit,'(a,l6)') trim(timestring)//': valid_input for dglc is ',valid_inputs end if ! determine if will write restart From 6d4ce9ead6ec92334eebf7376708f1751992b224 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:17:45 -0600 Subject: [PATCH 102/170] Update stream_definition_datm.xml: PLUMBER to PLUMBER2 --- datm/cime_config/stream_definition_datm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index e3058642a..c9fd0004a 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -4080,7 +4080,7 @@ 1.5 - 30 + 30 single @@ -4620,7 +4620,7 @@ 1.5 - 30 + 30 single From b81072a49db6625a40a88a58ace96b41ddf8b92f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 28 Jun 2024 03:40:22 -0600 Subject: [PATCH 103/170] renamed Fogg_rofi to Fgrg_rofi --- dglc/dglc_datamode_noevolve_mod.F90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index e4392105e..806373e50 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -40,7 +40,7 @@ module dglc_datamode_noevolve_mod type(icesheet_ptr_t), allocatable :: Sg_ice_covered(:) type(icesheet_ptr_t), allocatable :: Sg_icemask(:) type(icesheet_ptr_t), allocatable :: Sg_icemask_coupled_fluxes(:) - type(icesheet_ptr_t), allocatable :: Fogg_rofi(:) + type(icesheet_ptr_t), allocatable :: Fgrg_rofi(:) ! Import fields integer, parameter :: nlev_import = 30 @@ -55,7 +55,7 @@ module dglc_datamode_noevolve_mod character(len=*), parameter :: field_out_ice_covered = 'Sg_ice_covered' character(len=*), parameter :: field_out_icemask = 'Sg_icemask' character(len=*), parameter :: field_out_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' - character(len=*), parameter :: field_out_rofi = 'Fogg_rofi' + character(len=*), parameter :: field_out_rofi = 'Fgrg_rofi' ! Import Field names character(len=*), parameter :: field_in_tsrf = 'Sl_tsrf' @@ -162,7 +162,7 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) allocate(Sg_ice_covered(num_icesheets)) allocate(Sg_icemask(num_icesheets)) allocate(Sg_icemask_coupled_fluxes(num_icesheets)) - allocate(Fogg_rofi(num_icesheets)) + allocate(Fgrg_rofi(num_icesheets)) do ns = 1,num_icesheets call dshr_state_getfldptr(NStateExp(ns), field_out_area, fldptr1=Sg_area(ns)%ptr, rc=rc) @@ -175,7 +175,7 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call dshr_state_getfldptr(NStateExp(ns), field_out_icemask_coupled_fluxes, fldptr1=Sg_icemask_coupled_fluxes(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), field_out_rofi, fldptr1=Fogg_rofi(ns)%ptr, rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_rofi, fldptr1=Fgrg_rofi(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end do @@ -365,10 +365,10 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & end if if (initialized_noevolve) then - ! Compute Fogg_rofi + ! Compute Fgrg_rofi do ns = 1,num_icesheets - do ng = 1,size(Fogg_rofi(ns)%ptr) - Fogg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + do ng = 1,size(Fgrg_rofi(ns)%ptr) + Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) end do end do end if From 305114787e97215832c2e7497b5b6076227c2198 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 28 Jun 2024 03:44:21 -0600 Subject: [PATCH 104/170] merge to main --- dglc/dglc_datamode_noevolve_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 0bddb4808..975f8971f 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -178,7 +178,7 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) call dshr_state_getfldptr(NStateExp(ns), field_out_rofi, fldptr1=Fgrg_rofi(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - Fogg_rofi(ns)%ptr(:) = 0._r8 + Fgrg_rofi(ns)%ptr(:) = 0._r8 end do ! initialize pointers to import fields if appropriate From b7a608820480ee9a79f11e37e88bf740350f51b5 Mon Sep 17 00:00:00 2001 From: mvertens Date: Fri, 12 Jul 2024 20:29:07 +0200 Subject: [PATCH 105/170] Add capability to send both prescribed SST and multi-level ocean SST/SALN to mediator (#289) * new data ocn mode to send both multi-level ocn and sst to mediator * moved cheyenne to derecho in testlist * added new mode code Co-authored-by: Mariana Vertenstein --- docn/CMakeLists.txt | 1 + docn/cime_config/config_component.xml | 6 +- docn/cime_config/namelist_definition_docn.xml | 4 +- docn/docn_datamode_multilev_dom_mod.F90 | 264 ++++++++++++++++++ docn/ocn_comp_nuopc.F90 | 19 +- drof/cime_config/testdefs/testlist_drof.xml | 2 +- 6 files changed, 290 insertions(+), 6 deletions(-) create mode 100644 docn/docn_datamode_multilev_dom_mod.F90 diff --git a/docn/CMakeLists.txt b/docn/CMakeLists.txt index 256dc304d..46e51007f 100644 --- a/docn/CMakeLists.txt +++ b/docn/CMakeLists.txt @@ -6,6 +6,7 @@ set(SRCFILES ocn_comp_nuopc.F90 docn_datamode_iaf_mod.F90 docn_datamode_cplhist_mod.F90 docn_datamode_multilev_mod.F90 + docn_datamode_multilev_dom_mod.F90 docn_import_data_mod.F90) foreach(FILE ${SRCFILES}) diff --git a/docn/cime_config/config_component.xml b/docn/cime_config/config_component.xml index ab88c6fed..c5461d900 100644 --- a/docn/cime_config/config_component.xml +++ b/docn/cime_config/config_component.xml @@ -13,7 +13,7 @@ This file may have ocn desc entries. --> - DOCN + DOCN prescribed ocean mode slab ocean mode aquaplanet slab ocean mode @@ -33,6 +33,7 @@ globally constant SST for idealized experiments, such as RCE mediator history output for ocean fields imported to mediator input stream files have multi level data + input stream files have multi level data and prescribed ocean SST @@ -46,7 +47,7 @@ char - prescribed,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,som,som_aquap,sst_aquap_constant,interannual,cplhist,multilev + prescribed,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,som,som_aquap,sst_aquap_constant,interannual,cplhist,multilev,multilev_dom prescribed prescribed @@ -67,6 +68,7 @@ sst_aquap_constant cplhist multilev + multilev_dom run_component_docn env_run.xml diff --git a/docn/cime_config/namelist_definition_docn.xml b/docn/cime_config/namelist_definition_docn.xml index b2f788113..3e6d12558 100644 --- a/docn/cime_config/namelist_definition_docn.xml +++ b/docn/cime_config/namelist_definition_docn.xml @@ -32,6 +32,7 @@ '' '' '' + sst_salinity_depth_blom,prescribed sst_salinity_depth_blom @@ -40,7 +41,7 @@ char docn docn_nml - sstdata,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,sst_aquap_constant,som,som_aquap,iaf,cplhist,multilev + sstdata,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,sst_aquap_constant,som,som_aquap,iaf,cplhist,multilev,multilev_dom General method that operates on the data for a given docn_mode. ==> dataMode = "sstdata" @@ -108,6 +109,7 @@ sst_aquap_file sst_aquap_constant cplhist + multilev_dom multilev diff --git a/docn/docn_datamode_multilev_dom_mod.F90 b/docn/docn_datamode_multilev_dom_mod.F90 new file mode 100644 index 000000000..7cd7fd9eb --- /dev/null +++ b/docn/docn_datamode_multilev_dom_mod.F90 @@ -0,0 +1,264 @@ +module docn_datamode_multilev_dom_mod + + use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS + use NUOPC , only : NUOPC_Advertise + use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs + use shr_const_mod , only : shr_const_TkFrz, shr_const_pi, shr_const_ocn_ref_sal, shr_const_spval + use shr_sys_mod , only : shr_sys_abort + use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr + use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add + use dshr_mod , only : dshr_restart_read, dshr_restart_write + use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type, shr_strdata_get_stream_count + + implicit none + private ! except + + public :: docn_datamode_multilev_dom_advertise + public :: docn_datamode_multilev_dom_init_pointers + public :: docn_datamode_multilev_dom_advance + public :: docn_datamode_multilev_dom_restart_read + public :: docn_datamode_multilev_dom_restart_write + + ! pointers to export fields + real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator + real(r8), pointer :: So_t_depth(:,:) => null() + real(r8), pointer :: So_s_depth(:,:) => null() + real(r8), pointer :: So_t(:) => null() + real(r8), pointer :: So_u(:) => null() + real(r8), pointer :: So_v(:) => null() + real(r8), pointer :: So_s(:) => null() + + ! pointers to stream fields + real(r8), pointer :: stream_So_t_depth(:,:) => null() + real(r8), pointer :: stream_So_s_depth(:,:) => null() + + integer, parameter :: nlev_export = 30 + real(r8) :: vertical_levels(nlev_export) = (/ & + 30., 90., 150., 210., 270., 330., 390., 450., 510., 570., & + 630., 690., 750., 810., 870., 930., 990., 1050., 1110., 1170., & + 1230., 1290., 1350., 1410., 1470., 1530., 1590., 1650., 1710., 1770. /) + + real(r8) , parameter :: tkfrz = shr_const_tkfrz ! freezing point, fresh water (kelvin) + real(r8) , parameter :: ocnsalt = shr_const_ocn_ref_sal ! ocean reference salinity + + ! constants + character(*) , parameter :: nullstr = 'null' + character(*) , parameter :: rpfile = 'rpointer.ocn' + character(*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine docn_datamode_multilev_dom_advertise(exportState, fldsexport, flds_scalar_name, rc) + + ! input/output variables + type(esmf_State) , intent(inout) :: exportState + type(fldlist_type) , pointer :: fldsexport + character(len=*) , intent(in) :: flds_scalar_name + integer , intent(out) :: rc + + ! local variables + type(fldlist_type), pointer :: fldList + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Advertise export fields + call dshr_fldList_add(fldsExport, trim(flds_scalar_name)) + call dshr_fldList_add(fldsExport, 'So_omask') + call dshr_fldList_add(fldsExport, 'So_t_depth', ungridded_lbound=1, ungridded_ubound=nlev_export) + call dshr_fldList_add(fldsExport, 'So_s_depth', ungridded_lbound=1, ungridded_ubound=nlev_export) + call dshr_fldList_add(fldsExport, 'So_t' ) + call dshr_fldList_add(fldsExport, 'So_s' ) + call dshr_fldList_add(fldsExport, 'So_u' ) + call dshr_fldList_add(fldsExport, 'So_v' ) + + fldlist => fldsExport ! the head of the linked list + do while (associated(fldlist)) + call NUOPC_Advertise(exportState, standardName=fldlist%stdname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite('(docn_comp_advertise): Fr_ocn'//trim(fldList%stdname), ESMF_LOGMSG_INFO) + fldList => fldList%next + enddo + + end subroutine docn_datamode_multilev_dom_advertise + + !=============================================================================== + subroutine docn_datamode_multilev_dom_init_pointers(exportState, sdat, ocn_fraction, rc) + + ! input/output variables + type(ESMF_State) , intent(inout) :: exportState + type(shr_strdata_type) , intent(in) :: sdat + real(r8) , intent(in) :: ocn_fraction(:) + integer , intent(out) :: rc + + ! local variables + character(len=*), parameter :: subname='(docn_init_pointers): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! initialize pointers to stream fields + ! this has the full set of leveles in the stream data + call shr_strdata_get_stream_pointer( sdat, 'So_t_depth', stream_So_t_depth, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call shr_strdata_get_stream_pointer( sdat, 'So_s_depth', stream_So_s_depth, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call dshr_state_getfldptr(exportState, 'So_t', fldptr1=So_t, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'So_s', fldptr1=So_s, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'So_u', fldptr1=So_u, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'So_v', fldptr1=So_v, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! initialize pointers to export fields + ! the export state has only nlev_export levels + call dshr_state_getfldptr(exportState, 'So_omask' , fldptr1=So_omask , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'So_t_depth' , fldptr2=So_t_depth , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'So_s_depth' , fldptr2=So_s_depth , rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Initialize export state pointers to non-zero + So_t_depth(:,:) = shr_const_TkFrz + So_s_depth(:,:) = shr_const_ocn_ref_sal + + So_u(:) = 0.0_r8 + So_v(:) = 0.0_r8 + So_s(:) = ocnsalt + So_t(:) = TkFrz + + ! Set export state ocean fraction (So_omask) + So_omask(:) = ocn_fraction(:) + + end subroutine docn_datamode_multilev_dom_init_pointers + + !=============================================================================== + subroutine docn_datamode_multilev_dom_advance(sdat, logunit, mainproc, rc) + + ! input/output variables + type(shr_strdata_type) , intent(in) :: sdat + integer , intent(in) :: logunit + logical , intent(in) :: mainproc + integer , intent(out) :: rc + + ! local variables + integer :: i,ki,ko + integer :: nstreams + integer :: nlev_stream + integer :: stream_index + logical :: level_found + real(r8) :: factor + real(r8), allocatable :: stream_vlevs(:) + logical :: first_time = .true. + character(len=*), parameter :: subname='(docn_datamode_multilev_dom): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + So_t(:) = So_t(:) + TkFrz + + ! Determine number of vertical levels for multi level stream + nstreams = shr_strdata_get_stream_count(sdat) + nlev_stream = 0 + do stream_index = 1,nstreams + nlev_stream = sdat%pstrm(stream_index)%stream_nlev + if (nlev_stream > 1) exit + end do + if (nlev_stream == 0) then + call shr_sys_abort(trim(subname)//" could not find vertical levels greater than 0") + end if + allocate(stream_vlevs(nlev_stream)) + stream_vlevs(:) = sdat%pstrm(stream_index)%stream_vlevs(:) + + do ko = 1,nlev_export + level_found = .false. + do ki = 1,nlev_stream-1 + if (vertical_levels(ko) > stream_vlevs(ki) .and. vertical_levels(ko) <= stream_vlevs(ki+1)) then + if (mainproc .and. first_time) then + write(logunit,'(a,3(i5,2x),3(f13.5,2x))') & + 'vertical interpolation: ki,ko,ki+1,lev(ki),lev(ko),lev(ki+1) = ',& + ki,ko,ki+1,stream_vlevs(ki), vertical_levels(ko), stream_vlevs(ki+1) + end if + level_found = .true. + do i = 1,size(So_omask) + if (So_omask(i) == 0.) then + So_t_depth(ko,i) = shr_const_spval + So_s_depth(ko,i) = shr_const_spval + else + ! Assume input T forcing is in degrees C + if (stream_So_t_depth(ki+1,i) > 1.e10) then + if (stream_So_t_depth(ki,i) > 1.e10) then + So_t_depth(ko,i) = shr_const_spval + So_s_depth(ko,i) = shr_const_spval + else + So_t_depth(ko,i) = stream_So_t_depth(ki,i) + shr_const_tkfrz + So_s_depth(ko,i) = stream_So_s_depth(ki,i) + end if + else + factor = (stream_So_t_depth(ki+1,i)-stream_So_t_depth(ki,i))/(stream_vlevs(ki+1)-stream_vlevs(ki)) + So_t_depth(ko,i) = stream_So_t_depth(ki,i) + (vertical_levels(ko)-stream_vlevs(ki))*factor + So_t_depth(ko,i) = So_t_depth(ko,i) + shr_const_tkfrz + + factor = (stream_So_s_depth(ki+1,i)-stream_So_s_depth(ki,i))/(stream_vlevs(ki+1)-stream_vlevs(ki)) + So_s_depth(ko,i) = stream_So_s_depth(ki,i) + (vertical_levels(ko)-stream_vlevs(ki))*factor + end if + end if + end do + end if + end do + if (.not. level_found) then + call shr_sys_abort(trim(subname)//" could not find level bounds for vertical interpolation") + end if + end do + + first_time = .false. + + end subroutine docn_datamode_multilev_dom_advance + + !=============================================================================== + subroutine docn_datamode_multilev_dom_restart_write(case_name, inst_suffix, ymd, tod, & + logunit, my_task, sdat) + + ! write restart file + + ! input/output variables + character(len=*) , intent(in) :: case_name + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: ymd ! model date + integer , intent(in) :: tod ! model sec into model date + integer , intent(in) :: logunit + integer , intent(in) :: my_task + type(shr_strdata_type) , intent(inout) :: sdat + !------------------------------------------------------------------------------- + + call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, ymd, tod, & + logunit, my_task, sdat) + + end subroutine docn_datamode_multilev_dom_restart_write + + !=============================================================================== + subroutine docn_datamode_multilev_dom_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + + ! read restart file + + ! input/output arguments + character(len=*) , intent(inout) :: rest_filem + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: logunit + integer , intent(in) :: my_task + integer , intent(in) :: mpicom + type(shr_strdata_type) , intent(inout) :: sdat + !------------------------------------------------------------------------------- + + call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + + end subroutine docn_datamode_multilev_dom_restart_read + +end module docn_datamode_multilev_dom_mod diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index ced8cb86d..f15ed9ec2 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -63,7 +63,12 @@ module cdeps_docn_comp use docn_datamode_multilev_mod , only : docn_datamode_multilev_advance use docn_datamode_multilev_mod , only : docn_datamode_multilev_restart_read use docn_datamode_multilev_mod , only : docn_datamode_multilev_restart_write - use docn_import_data_mod , only : docn_import_data_advertise + use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_advertise + use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_init_pointers + use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_advance + use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_restart_read + use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_restart_write + use docn_import_data_mod , only : docn_import_data_advertise implicit none private ! except @@ -307,7 +312,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) trim(datamode) == 'cplhist' .or. & ! read stream, needs import data trim(datamode) == 'sst_aquap_analytic' .or. & ! analytic, no streams, import or export data trim(datamode) == 'sst_aquap_constant' .or. & ! analytic, no streams, import or export data - trim(datamode) == 'multilev') then ! multilevel ocean input + trim(datamode) == 'multilev' .or. & ! multilevel ocean input + trim(datamode) == 'multilev_dom') then ! multilevel ocean input and sst export ! success do nothing else call shr_sys_abort(' ERROR illegal docn datamode = '//trim(datamode)) @@ -333,6 +339,9 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) else if (trim(datamode) == 'multilev') then call docn_datamode_multilev_advertise(exportState, fldsExport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(datamode) == 'multilev_dom') then + call docn_datamode_multilev_dom_advertise(exportState, fldsExport, flds_scalar_name, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if if (trim(import_data_fields) /= 'none') then @@ -563,6 +572,9 @@ subroutine docn_comp_run(importState, exportState, clock, target_ymd, target_tod case('multilev') call docn_datamode_multilev_init_pointers(exportState, sdat, model_frac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('multilev_dom') + call docn_datamode_multilev_dom_init_pointers(exportState, sdat, model_frac, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Read restart if needed @@ -623,6 +635,9 @@ subroutine docn_comp_run(importState, exportState, clock, target_ymd, target_tod case('multilev') call docn_datamode_multilev_advance(sdat, logunit, mainproc, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('multilev_dom') + call docn_datamode_multilev_dom_advance(sdat, logunit, mainproc, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Write restarts if needed (no restarts for aquaplanet analytic or aquaplanet input file) diff --git a/drof/cime_config/testdefs/testlist_drof.xml b/drof/cime_config/testdefs/testlist_drof.xml index e45c72a3e..6e423fabe 100644 --- a/drof/cime_config/testdefs/testlist_drof.xml +++ b/drof/cime_config/testdefs/testlist_drof.xml @@ -3,7 +3,7 @@ - + From b9c2964de34dadcb35959f8820faf1c0c17fd3bd Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:11:15 -0600 Subject: [PATCH 106/170] Update buildnml PLUMBER --> PLUMBER2 --- datm/cime_config/buildnml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml index 1fd77c642..6843b87c8 100755 --- a/datm/cime_config/buildnml +++ b/datm/cime_config/buildnml @@ -194,7 +194,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path streamlist.append(clm_usrdat_name+"_PRECIP."+neonsite) if clm_usrdat_name == 'NEON': streamlist.append(clm_usrdat_name+".NEON_PRECIP."+neonsite) - if clm_usrdat_name == 'PLUMBER': + if clm_usrdat_name == 'PLUMBER2': streamlist.append(clm_usrdat_name+plumber2site) bias_correct = nmlgen.get_value("bias_correct") From e3fb72a76895566bb335172d3098fe3baabfbeb9 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:13:25 -0600 Subject: [PATCH 107/170] Update namelist_definition_datm.xml PLUMBER --> PLUMBER2 --- datm/cime_config/namelist_definition_datm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index 4fa625935..3c2be3995 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -41,7 +41,7 @@ NEON.$NEONSITE - PLUMBER.$PLUMBER2SITE + PLUMBER2.$PLUMBER2SITE CLM_USRDAT.$CLM_USRDAT_NAME From 7e687d3bd98db60582b7b204307c774d1eb5b44b Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:14:55 -0600 Subject: [PATCH 108/170] Update stream_definition_datm.xml PLUMBER --> PLUMBER2 --- datm/cime_config/stream_definition_datm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index c9fd0004a..7899e85c4 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -343,10 +343,10 @@ - + - + none From fe1eece99d581610f114389bd4f3c40d58bbac93 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:18:22 -0600 Subject: [PATCH 109/170] Update stream_cdeps.py PLUMBER --> PLUMBER2 --- cime_config/stream_cdeps.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index 7c6118f7a..7f342ce9c 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -188,10 +188,10 @@ def create_stream_xml( {"name": "NEON.NEON_PRECIP.$NEONSITE"}, err_msg="No stream_entry {} found".format(stream_name), ) - elif stream_name.startswith("PLUMBER"): + elif stream_name.startswith("PLUMBER2"): self.stream_nodes = super(StreamCDEPS, self).get_child( "stream_entry", - {"name": "PLUMBER.$PLUMBER2SITE"}, + {"name": "PLUMBER2.$PLUMBER2SITE"}, err_msg="No stream_entry {} found".format(stream_name), ) elif stream_name.startswith("CLM_USRDAT."): @@ -251,7 +251,7 @@ def create_stream_xml( os.path.join(rundir, "inputdata", "atm", neon) + "\n" ) - elif available_plumber_data and stream_name.startswith("PLUMBER"): + elif available_plumber_data and stream_name.startswith("PLUMBER2"): rundir = case.get_value("RUNDIR") for plumber in available_plumber_data: stream_datafiles += ( From 1f4f5ca3e245c9c4df1aceaae5bef34f85257fbf Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:35:52 -0600 Subject: [PATCH 110/170] Update stream_definition_datm.xml documentation --- datm/cime_config/stream_definition_datm.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 7899e85c4..c3d36014c 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -41,6 +41,8 @@ CORE_RYF9091_JRA = JRA55 repeat year forcing, v1.3, 1990-1991 (for forcing POP and CICE) CORE_RYF0304_JRA = JRA55 repeat year forcing, v1.3, 2003-2004 (for forcing POP and CICE) ERA5 = ERA5 intra-annual year forcing + NEON = Run with forcing from NEON tower data + PLUMBER2 = Run with forcing from PLUMBER2 tower data SIMPLE = Namelist-configurable, constant datm forcing for simple experiments CPLHIST = Streams for lnd or ocn/ice forcing used for spinup From d101eda255aec8be3b9c262627e14356d97b64c7 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Aug 2024 05:28:18 -0600 Subject: [PATCH 111/170] a fix for cdeps build concurancy issues --- cime_config/buildlib | 66 ++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/cime_config/buildlib b/cime_config/buildlib index 2da096a7a..4c44d790b 100755 --- a/cime_config/buildlib +++ b/cime_config/buildlib @@ -73,8 +73,10 @@ def buildlib(bldroot, libroot, case): strthread = "nothreads" mpilib = case.get_value("MPILIB") compiler = case.get_value("COMPILER") - sharedpath = os.path.join(compiler, mpilib, strdebug, strthread, "nuopc") - + sharedpath = os.path.join(compiler, mpilib, strdebug, strthread) + sharedroot = case.get_value("SHAREDLIBROOT") + cdepsblddir = os.path.join(sharedroot, sharedpath, "CDEPS") + logger.info("Running cmake for CDEPS") srcpath = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) cmake_flags = get_standard_cmake_args(case, os.path.join(sharedpath, "cdeps")) @@ -147,31 +149,47 @@ def buildlib(bldroot, libroot, case): else: bld_time = src_time - 1 - # if any file in src is newer than CmakeFiles in the build directory, rerun cmake + # Make sure that no other process is currently trying to build this library, done with a simple lockfile + if os.path.exists(cdepsblddir): + logger.info("{} already exists, checking for lockfile".format(cdepsblddir)) + while os.path.exists(os.path.join(cdepsblddir,"lockfile")): + logger.info("Waiting for lockfile in {}".format(cdepsblddir)) + time.sleep(10) + else: + logger.info("{} does not exist, creating lockfile".format(cdepsblddir)) + os.makedirs(cdepsblddir) + with open(os.path.join(cdepsblddir,"lockfile"),"w") as fd: + fd.write(str(os.getpid())) + + try: + # if any file in src is newer than CmakeFiles in the build directory, rerun cmake + if src_time > bld_time: + logger.info("cmake_flags {}".format(cmake_flags)) + s, o, e = run_cmd( + "cmake {} ".format(cmake_flags), from_dir=bldroot, verbose=True + ) + expect(not s, "ERROR from cmake output={}, error={}".format(o, e)) + else: + # The dwav_lib is the last file built in cdeps, wait for it to be built + dwav_lib = os.path.join(bldroot, "dwav", "libdwav.a") + time_to_wait = 300 + time_counter = 0 + while not os.path.exists(dwav_lib): + time.sleep(1) + time_counter += 1 + if time_counter > time_to_wait: + break + expect(time_counter <= time_to_wait, " Timeout waiting for {}".format(dwav_lib)) - if src_time > bld_time: - logger.info("cmake_flags {}".format(cmake_flags)) s, o, e = run_cmd( - "cmake {} ".format(cmake_flags), from_dir=bldroot, verbose=True + "make install VERBOSE=1 DESTDIR={}".format(libroot), + from_dir=bldroot, + verbose=True, ) - expect(not s, "ERROR from cmake output={}, error={}".format(o, e)) - else: - # The dwav_lib is the last file built in cdeps, wait for it to be built - dwav_lib = os.path.join(bldroot, "dwav", "libdwav.a") - time_to_wait = 300 - time_counter = 0 - while not os.path.exists(dwav_lib): - time.sleep(1) - time_counter += 1 - if time_counter > time_to_wait: - break - expect(time_counter <= time_to_wait, " Timeout waiting for {}".format(dwav_lib)) - - s, o, e = run_cmd( - "make install VERBOSE=1 DESTDIR={}".format(libroot), - from_dir=bldroot, - verbose=True, - ) + finally: + if os.path.exists(os.path.join(cdepsblddir,"lockfile")): + os.remove(os.path.join(cdepsblddir,"lockfile")) + expect(not s, "ERROR from make output={}, error={}".format(o, e)) logger.info("make output={}\nerror={}".format(o, e)) if compiler == "gnu" and case.get_value("DEBUG"): From e98991f2e3e1794a896fb2da0df26040ecb6d2f1 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Thu, 1 Aug 2024 10:58:43 -0600 Subject: [PATCH 112/170] Update buildnml to include fix for PLUMBER2.PLUMBER2SITE (with period) --- datm/cime_config/buildnml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml index 6843b87c8..ce4a852de 100755 --- a/datm/cime_config/buildnml +++ b/datm/cime_config/buildnml @@ -195,7 +195,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path if clm_usrdat_name == 'NEON': streamlist.append(clm_usrdat_name+".NEON_PRECIP."+neonsite) if clm_usrdat_name == 'PLUMBER2': - streamlist.append(clm_usrdat_name+plumber2site) + streamlist.append(clm_usrdat_name+"."+plumber2site) bias_correct = nmlgen.get_value("bias_correct") if bias_correct is not None: From d564ec9f355ff808bac54e18c398e9042e995f64 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Thu, 1 Aug 2024 11:02:08 -0600 Subject: [PATCH 113/170] Update buildnml to separate plumber/neon cases --- datm/cime_config/buildnml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml index ce4a852de..4d988ce1a 100755 --- a/datm/cime_config/buildnml +++ b/datm/cime_config/buildnml @@ -141,11 +141,17 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path available_neon_data = None if 'CLM_USRDAT' in model_grid: config['model_grid'] = 'CLM_USRDAT' - neonsite = case.get_value("NEONSITE") - if neonsite: - config['neon'] = "True" - # download and use the listing.csv file to determine data availablity - available_neon_data = _get_neon_data_availability(case, neonsite) + if 'NEON' in clm_usrdat_name: + neonsite = case.get_value("NEONSITE") + if neonsite: + config['neon'] = "True" + # download and use the listing.csv file to determine data availablity + available_neon_data = _get_neon_data_availability(case, neonsite) + if 'PLUMBER' in clm_usrdat_name: + # TODO: not recognizing PLUBMER2SITE var in buildnml + plumber2site = case.get_value("PLUMBER2SITE") + if plumber2site: + config['plumber'] = "True" else: config['model_grid'] = model_grid From c4202b43b2df701da9a7df7e7a56f54a1e2c761e Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Aug 2024 14:11:29 -0600 Subject: [PATCH 114/170] increase timeout for cdeps build --- cime_config/buildlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/buildlib b/cime_config/buildlib index 4c44d790b..536bdae66 100755 --- a/cime_config/buildlib +++ b/cime_config/buildlib @@ -172,7 +172,7 @@ def buildlib(bldroot, libroot, case): else: # The dwav_lib is the last file built in cdeps, wait for it to be built dwav_lib = os.path.join(bldroot, "dwav", "libdwav.a") - time_to_wait = 300 + time_to_wait = 600 time_counter = 0 while not os.path.exists(dwav_lib): time.sleep(1) From b5395f433c74ecd6f43770aac7d7836401a32aad Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:34:21 -0600 Subject: [PATCH 115/170] Update buildnml to use caseroot to get plumber2 information because plumber2site var not recognized at time of buildnml --- datm/cime_config/buildnml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml index 4d988ce1a..026a14ef1 100755 --- a/datm/cime_config/buildnml +++ b/datm/cime_config/buildnml @@ -147,9 +147,8 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path config['neon'] = "True" # download and use the listing.csv file to determine data availablity available_neon_data = _get_neon_data_availability(case, neonsite) - if 'PLUMBER' in clm_usrdat_name: - # TODO: not recognizing PLUBMER2SITE var in buildnml - plumber2site = case.get_value("PLUMBER2SITE") + if 'PLUMBER2' in clm_usrdat_name: + plumber2site = case.get_value('CASEROOT').split('/')[-1] if plumber2site: config['plumber'] = "True" else: From c9b6e57dd4a52a47f5253d662db2550f43c2c513 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Fri, 2 Aug 2024 13:33:59 -0600 Subject: [PATCH 116/170] Update buildnml now that PLUMBER2SITE xmlchange is working --- datm/cime_config/buildnml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/cime_config/buildnml b/datm/cime_config/buildnml index 026a14ef1..28e341c02 100755 --- a/datm/cime_config/buildnml +++ b/datm/cime_config/buildnml @@ -148,7 +148,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path # download and use the listing.csv file to determine data availablity available_neon_data = _get_neon_data_availability(case, neonsite) if 'PLUMBER2' in clm_usrdat_name: - plumber2site = case.get_value('CASEROOT').split('/')[-1] + plumber2site = case.get_value('PLUMBER2SITE') if plumber2site: config['plumber'] = "True" else: From 734d38a8f6ef8987d8be839bc24bfd1e380466d3 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:53:29 -0600 Subject: [PATCH 117/170] example hard coded start year in stream_definition_datm.xml --- datm/cime_config/stream_definition_datm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index c3d36014c..0a018c896 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -353,7 +353,7 @@ none - $DIN_LOC_ROOT/atm/cdeps/PLUMBER2/${PLUMBER2SITE}_%y.nc + $DIN_LOC_ROOT/atm/datm7/CLM1PT_data/PLUMBER2/${PLUMBER2SITE}/CLM1PT_data/CTSM_DATM_${PLUMBER2SITE}_2010-${DATM_YR_END}.nc ZBOT Sa_z From 57256a273fab637fd29f15dd56a0c26c388800d2 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Thu, 8 Aug 2024 11:50:08 -0600 Subject: [PATCH 118/170] Update stream_cdeps.py to avoid CLM_USRDAT.PLUMBER2 stream --- cime_config/stream_cdeps.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index 7f342ce9c..a291250d7 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -195,6 +195,8 @@ def create_stream_xml( err_msg="No stream_entry {} found".format(stream_name), ) elif stream_name.startswith("CLM_USRDAT."): + if 'PLUMBER2' in stream_name: + continue self.stream_nodes = super(StreamCDEPS, self).get_child( "stream_entry", {"name": "CLM_USRDAT.$CLM_USRDAT_NAME"}, From c6d01f62245915f104d875d670800513e2cf094f Mon Sep 17 00:00:00 2001 From: Teagan King Date: Thu, 8 Aug 2024 11:54:55 -0600 Subject: [PATCH 119/170] include xml var for yr_start in filename for plumber2 --- datm/cime_config/config_component.xml | 9 +++++++++ doc/source/datm.rst | 3 +++ 2 files changed, 12 insertions(+) diff --git a/datm/cime_config/config_component.xml b/datm/cime_config/config_component.xml index e0a04797d..70a9e79f1 100644 --- a/datm/cime_config/config_component.xml +++ b/datm/cime_config/config_component.xml @@ -296,6 +296,15 @@ starting year to loop data over + + integer + + UNSET + run_component_datm + env_run.xml + Start year listed in PLUMBER2 filenames. Leave unset for other cases. + + integer diff --git a/doc/source/datm.rst b/doc/source/datm.rst index e70c703da..d731bc689 100644 --- a/doc/source/datm.rst +++ b/doc/source/datm.rst @@ -176,6 +176,9 @@ DATM_CPLHIST_CASE DATM_YR_START - Starting year to loop data over +DATM_YR_START_FILENAME + - Start year listed in PLUMBER2 filename + DATM_YR_END - Ending year to loop data over From 66ce97dc278899cf35cbf5dc7018c8f38a44e919 Mon Sep 17 00:00:00 2001 From: mvertens Date: Sun, 11 Aug 2024 19:51:43 +0200 Subject: [PATCH 120/170] bugfix for fgrg_rofi computation (#295) --- dglc/dglc_datamode_noevolve_mod.F90 | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 975f8971f..d654e6aac 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -49,6 +49,8 @@ module dglc_datamode_noevolve_mod ! type(icesheet_ptr_t), allocatable :: So_t(:) ! type(icesheet_ptr_t), allocatable :: So_q(:) + real(r8), allocatable :: usrf(:) ! upper surface elevation (m) on ice grid + ! Export Field names character(len=*), parameter :: field_out_area = 'Sg_area' character(len=*), parameter :: field_out_topo = 'Sg_topo' @@ -238,8 +240,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & real(r8) :: rhoi ! density of ice ~ kg/m^3 real(r8) :: rhoo ! density of sea water ~ kg/m^3 real(r8) :: eus ! eustatic sea level - real(r8), allocatable :: lsrf(:) - real(r8), allocatable :: usrf(:) + real(r8), allocatable :: lsrf(:) ! lower surface elevation (m) on ice grid character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -316,8 +317,8 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & rcode = pio_inq_varid(pioid, 'thk', varid) call pio_read_darray(pioid, varid, pio_iodesc, thck, rcode) - allocate(lsrf(lsize)) allocate(usrf(lsize)) + allocate(lsrf(lsize)) rhoi = SHR_CONST_RHOICE ! 0.917e3 rhoo = SHR_CONST_RHOSW ! 1.026e3 @@ -360,7 +361,6 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & end do deallocate(lsrf) - deallocate(usrf) call pio_closefile(pioid) call pio_freedecomp(pio_subsystem, pio_iodesc) @@ -372,8 +372,13 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (initialized_noevolve) then ! Compute Fgrg_rofi do ns = 1,num_icesheets - do ng = 1,size(Fgrg_rofi(ns)%ptr) - Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + lsize = size(Fgrg_rofi(ns)%ptr) + do ng = 1,lsize + if (is_in_active_grid(usrf(ng))) then + Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + else + Fgrg_rofi(ns)%ptr(ng) = 0._r8 + end if end do end do end if From e35cb72c74b5f007a80bb7995d5ba4a55c9dde4a Mon Sep 17 00:00:00 2001 From: Teagan King Date: Tue, 13 Aug 2024 11:39:59 -0600 Subject: [PATCH 121/170] implement xml var DATM_YR_START_FILENAME --- datm/cime_config/stream_definition_datm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 0a018c896..6ab079edb 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -353,7 +353,7 @@ none - $DIN_LOC_ROOT/atm/datm7/CLM1PT_data/PLUMBER2/${PLUMBER2SITE}/CLM1PT_data/CTSM_DATM_${PLUMBER2SITE}_2010-${DATM_YR_END}.nc + $DIN_LOC_ROOT/atm/datm7/CLM1PT_data/PLUMBER2/${PLUMBER2SITE}/CLM1PT_data/CTSM_DATM_${PLUMBER2SITE}_${DATM_YR_START_FILENAME}-${DATM_YR_END}.nc ZBOT Sa_z From 0a4386197be646391c7eb667e83f43c984ff132d Mon Sep 17 00:00:00 2001 From: Teagan King Date: Fri, 16 Aug 2024 10:36:40 -0600 Subject: [PATCH 122/170] updates for aux-cdeps tests now passing --- cime_config/stream_definition_v2.0.xsd | 3 ++- datm/cime_config/config_component.xml | 4 ++-- datm/cime_config/stream_definition_datm.xml | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cime_config/stream_definition_v2.0.xsd b/cime_config/stream_definition_v2.0.xsd index de3189e35..d6ec74768 100644 --- a/cime_config/stream_definition_v2.0.xsd +++ b/cime_config/stream_definition_v2.0.xsd @@ -93,7 +93,8 @@ - + + diff --git a/datm/cime_config/config_component.xml b/datm/cime_config/config_component.xml index 70a9e79f1..e6cfc0153 100644 --- a/datm/cime_config/config_component.xml +++ b/datm/cime_config/config_component.xml @@ -299,10 +299,10 @@ integer - UNSET + 9999 run_component_datm env_run.xml - Start year listed in PLUMBER2 filenames. Leave unset for other cases. + Start year listed in PLUMBER2 filenames. Leave as 9999 for other cases. diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 6ab079edb..bfe6fc4a0 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -4082,7 +4082,7 @@ 1.5 - 30 + 30 single @@ -4622,7 +4622,7 @@ 1.5 - 30 + 30 single From 1797342543e53bbb764529dac0efc76358107d79 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Fri, 16 Aug 2024 11:20:40 -0600 Subject: [PATCH 123/170] Update config_component.xml to address Erik's comment --- datm/cime_config/config_component.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datm/cime_config/config_component.xml b/datm/cime_config/config_component.xml index e6cfc0153..4f8c010bb 100644 --- a/datm/cime_config/config_component.xml +++ b/datm/cime_config/config_component.xml @@ -299,10 +299,10 @@ integer - 9999 + -9999 run_component_datm env_run.xml - Start year listed in PLUMBER2 filenames. Leave as 9999 for other cases. + Start year listed in PLUMBER2 filenames. Only used in PLUMBER2; leave as -9999 for other cases. From ffd4077919a17a987cb830f5a50a1072b9896ae7 Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Fri, 16 Aug 2024 11:33:32 -0600 Subject: [PATCH 124/170] Update config_component.xml to use positive 9999 --- datm/cime_config/config_component.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datm/cime_config/config_component.xml b/datm/cime_config/config_component.xml index 4f8c010bb..f2698e9d4 100644 --- a/datm/cime_config/config_component.xml +++ b/datm/cime_config/config_component.xml @@ -299,10 +299,10 @@ integer - -9999 + 9999 run_component_datm env_run.xml - Start year listed in PLUMBER2 filenames. Only used in PLUMBER2; leave as -9999 for other cases. + Start year listed in PLUMBER2 filenames for certain datm_modes. Currently only used in PLUMBER2; leave as the default value (9999) for other cases. From 7e363e7ca1975ba40ce33ec82c23325b6eca63aa Mon Sep 17 00:00:00 2001 From: Teagan King <98482480+TeaganKing@users.noreply.github.com> Date: Fri, 16 Aug 2024 11:51:20 -0600 Subject: [PATCH 125/170] Add comment to stream_cdeps.py --- cime_config/stream_cdeps.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index a291250d7..b7af2f28c 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -196,6 +196,8 @@ def create_stream_xml( ) elif stream_name.startswith("CLM_USRDAT."): if 'PLUMBER2' in stream_name: + # if PLUMBER2 is in the stream name + # we want to use PLUMBER2.PLUMBER2SITE instead of CLM_USRDAT.PLUMBER2 continue self.stream_nodes = super(StreamCDEPS, self).get_child( "stream_entry", From cce236ce8bb06d7c89ac6a5e07b25f78c0335a61 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 20 Aug 2024 15:46:06 -0600 Subject: [PATCH 126/170] revert the change to download fox --- CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff7046ebd..9e1ad9be5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,18 +71,18 @@ add_subdirectory(streams) add_subdirectory(dshr) if(NOT DISABLE_FoX) - FetchContent_Declare(fox - GIT_REPOSITORY https://github.com/ESMCI/fox.git - GIT_TAG 4.1.2.1 - SOURCE_DIR ${FOX_ROOT} - BINARY_DIR ${FOX_ROOT}/.. - ) - FetchContent_GetProperties(fox) - if(NOT fox_POPULATED) - FetchContent_Populate(fox) - message(STATUS "FoX source dir: ${fox_SOURCE_DIR}") - message(STATUS "FoX binary dir: ${fox_BINARY_DIR}") - endif() +# FetchContent_Declare(fox +# GIT_REPOSITORY https://github.com/ESMCI/fox.git +# GIT_TAG 4.1.2.1 +# SOURCE_DIR ${FOX_ROOT} +# BINARY_DIR ${FOX_ROOT}/.. +# ) +# FetchContent_GetProperties(fox) +# if(NOT fox_POPULATED) +# FetchContent_Populate(fox) +# message(STATUS "FoX source dir: ${fox_SOURCE_DIR}") +# message(STATUS "FoX binary dir: ${fox_BINARY_DIR}") +# endif() add_subdirectory(fox) target_include_directories(streams PUBLIC $ From 52657a4e36769c34674f40c164a433f33be9f1ab Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 21 Aug 2024 09:54:36 -0600 Subject: [PATCH 127/170] remove commented code --- CMakeLists.txt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e1ad9be5..a4e0aa82e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,18 +71,6 @@ add_subdirectory(streams) add_subdirectory(dshr) if(NOT DISABLE_FoX) -# FetchContent_Declare(fox -# GIT_REPOSITORY https://github.com/ESMCI/fox.git -# GIT_TAG 4.1.2.1 -# SOURCE_DIR ${FOX_ROOT} -# BINARY_DIR ${FOX_ROOT}/.. -# ) -# FetchContent_GetProperties(fox) -# if(NOT fox_POPULATED) -# FetchContent_Populate(fox) -# message(STATUS "FoX source dir: ${fox_SOURCE_DIR}") -# message(STATUS "FoX binary dir: ${fox_BINARY_DIR}") -# endif() add_subdirectory(fox) target_include_directories(streams PUBLIC $ From e3aeb54c7837665861b19dcbd4ec048fb65a8736 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 21 Aug 2024 14:21:59 -0600 Subject: [PATCH 128/170] add nuopc_shr_methods.F90 for UFS --- share/CMakeLists.txt | 3 +- share/nuopc_shr_methods.F90 | 895 ++++++++++++++++++++++++++++++++++++ 2 files changed, 897 insertions(+), 1 deletion(-) create mode 100644 share/nuopc_shr_methods.F90 diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 6d1c3607d..3a821304b 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -18,7 +18,8 @@ add_library(cdeps_share ${GenF90_SRCS} shr_log_mod.F90 shr_strconvert_mod.F90 shr_precip_mod.F90 - shr_string_mod.F90) + shr_string_mod.F90 + nuopc_shr_methods.F90) target_include_directories (cdeps_share PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${ESMF_F90COMPILEPATHS} ${PIO_Fortran_INCLUDE_DIRS}) diff --git a/share/nuopc_shr_methods.F90 b/share/nuopc_shr_methods.F90 new file mode 100644 index 000000000..eeac5405e --- /dev/null +++ b/share/nuopc_shr_methods.F90 @@ -0,0 +1,895 @@ +module nuopc_shr_methods + + use ESMF , only : operator(<), operator(/=), operator(+) + use ESMF , only : operator(-), operator(*) , operator(>=) + use ESMF , only : operator(<=), operator(>), operator(==), MOD + use ESMF , only : ESMF_LOGERR_PASSTHRU, ESMF_LogFoundError, ESMF_LOGMSG_ERROR, ESMF_MAXSTR + use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_FAILURE + use ESMF , only : ESMF_State, ESMF_StateGet + use ESMF , only : ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_GridCompSet + use ESMF , only : ESMF_GeomType_Flag, ESMF_FieldStatus_Flag + use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_AlarmSet + use ESMF , only : ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID, ESMF_FIELDSTATUS_COMPLETE + use ESMF , only : ESMF_Clock, ESMF_ClockCreate, ESMF_ClockGet, ESMF_ClockSet + use ESMF , only : ESMF_ClockPrint, ESMF_ClockAdvance + use ESMF , only : ESMF_Alarm, ESMF_AlarmCreate, ESMF_AlarmGet, ESMF_AlarmSet + use ESMF , only : ESMF_Calendar, ESMF_CALKIND_NOLEAP, ESMF_CALKIND_GREGORIAN + use ESMF , only : ESMF_Time, ESMF_TimeGet, ESMF_TimeSet, ESMF_ClockGetAlarm + use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalSet, ESMF_TimeIntervalGet + use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMBroadcast, ESMF_VMGetCurrent + use NUOPC , only : NUOPC_CompAttributeGet + use NUOPC_Model , only : NUOPC_ModelGet + 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 shr_log_mod , only : shr_log_setLogUnit + + implicit none + private + + public :: memcheck + public :: get_component_instance + public :: set_component_logging + public :: log_clock_advance + public :: state_getscalar + public :: state_setscalar + public :: state_diagnose + public :: alarmInit + public :: get_minimum_timestep + public :: chkerr + + private :: timeInit + private :: field_getfldptr + + ! Module data + + ! Clock and alarm options shared with esm_time_mod along with dtime_driver which is initialized there. + ! Dtime_driver is needed here for setting alarm options which use the nstep option and is a module variable + ! to avoid requiring a change in all model caps. + character(len=*), public, parameter :: & + optNONE = "none" , & + optNever = "never" , & + optNSteps = "nstep" , & + optNSeconds = "nsecond" , & + optNMinutes = "nminute" , & + optNHours = "nhour" , & + optNDays = "nday" , & + optNMonths = "nmonth" , & + optNYears = "nyear" , & + optMonthly = "monthly" , & + optYearly = "yearly" , & + optDate = "date" , & + optEnd = "end" , & + optGLCCouplingPeriod = "glc_coupling_period" + + integer, public :: dtime_drv ! initialized in esm_time_mod.F90 + + integer, parameter :: SecPerDay = 86400 ! Seconds per day + integer, parameter :: memdebug_level=1 + character(len=1024) :: msgString + character(len=*), parameter :: u_FILE_u = & + __FILE__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine memcheck(string, level, maintask) + + ! input/output variables + character(len=*) , intent(in) :: string + integer , intent(in) :: level + logical , intent(in) :: maintask + + ! local variables +#ifdef CESMCOUPLED + integer, external :: GPTLprint_memusage + integer :: ierr = 0 +#endif + !----------------------------------------------------------------------- + +#ifdef CESMCOUPLED + if ((maintask .and. memdebug_level > level) .or. memdebug_level > level+1) then + ierr = GPTLprint_memusage(string) + endif +#endif + + end subroutine memcheck + +!=============================================================================== + + subroutine get_component_instance(gcomp, inst_suffix, inst_index, rc) + + ! input/output variables + type(ESMF_GridComp) :: gcomp + character(len=*) , intent(out) :: inst_suffix + integer , intent(out) :: inst_index + integer , intent(out) :: rc + + ! local variables + logical :: isPresent + character(len=4) :: cvalue + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + call NUOPC_CompAttributeGet(gcomp, name="inst_suffix", isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (isPresent) then + call NUOPC_CompAttributeGet(gcomp, name="inst_suffix", value=inst_suffix, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + cvalue = inst_suffix(2:) + read(cvalue, *) inst_index + else + inst_suffix = "" + inst_index=1 + endif + + end subroutine get_component_instance + +!=============================================================================== + subroutine set_component_logging(gcomp, maintask, logunit, shrlogunit, rc) + use NUOPC, only: NUOPC_CompAttributeSet, NUOPC_CompAttributeAdd + ! input/output variables + type(ESMF_GridComp) :: gcomp + logical, intent(in) :: maintask + integer, intent(out) :: logunit + integer, intent(out) :: shrlogunit + integer, intent(out) :: rc + + ! local variables + character(len=CL) :: diro + character(len=CL) :: logfile + character(len=CL) :: inst_suffix + integer :: inst_index ! Not used here + integer :: n + character(len=CL) :: name + character(len=*), parameter :: subname = "("//__FILE__//": set_component_logging)" + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (maintask) then + call NUOPC_CompAttributeGet(gcomp, name="diro", value=diro, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name="logfile", value=logfile, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_component_instance(gcomp, inst_suffix, inst_index, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Multiinstance logfile name needs a correction + if(len_trim(inst_suffix) > 0) then + n = index(logfile, '.') + logfile = logfile(1:n-1)//trim(inst_suffix)//logfile(n:) + endif + + open(newunit=logunit,file=trim(diro)//"/"//trim(logfile)) + + else + logUnit = 6 + endif + + call ESMF_GridCompGet(gcomp, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_LogWrite(trim(subname)//": setting logunit for component: "//trim(name), ESMF_LOGMSG_INFO) + call NUOPC_CompAttributeAdd(gcomp, (/"logunit"/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeSet(gcomp, "logunit", logunit, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call shr_log_setLogUnit (logunit) + ! Still need to set this return value + shrlogunit = logunit + call ESMF_LogWrite(trim(subname)//": done for component "//trim(name), ESMF_LOGMSG_INFO) + end subroutine set_component_logging + +!=============================================================================== + + subroutine log_clock_advance(clock, component, logunit, rc) + + ! input/output variables + type(ESMF_Clock) :: clock + character(len=*) , intent(in) :: component + integer , intent(in) :: logunit + integer , intent(out) :: rc + + ! local variables + character(len=CL) :: cvalue, prestring + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + write(prestring, *) "------>Advancing ",trim(component)," from: " + call ESMF_ClockPrint(clock, options="currTime", unit=cvalue, preString=trim(prestring), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + write(logunit, *) trim(cvalue) + + call ESMF_ClockPrint(clock, options="stopTime", unit=cvalue, & + preString="--------------------------------> to: ", rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + write(logunit, *) trim(cvalue) + + end subroutine log_clock_advance + +!=============================================================================== + + subroutine state_getscalar(state, scalar_id, scalar_value, flds_scalar_name, flds_scalar_num, rc) + + ! ---------------------------------------------- + ! Get scalar data from State for a particular name and broadcast it to all other pets + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State), intent(in) :: state + integer, intent(in) :: scalar_id + real(r8), intent(out) :: scalar_value + character(len=*), intent(in) :: flds_scalar_name + integer, intent(in) :: flds_scalar_num + integer, intent(inout) :: rc + + ! local variables + integer :: mytask + type(ESMF_VM) :: vm + type(ESMF_Field) :: field + real(r8), pointer :: farrayptr(:,:) + real(r8) :: tmp(1) + character(len=*), parameter :: subname='(state_getscalar)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_VMGetCurrent(vm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_VMGet(vm, localPet=mytask, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_StateGet(State, itemName=trim(flds_scalar_name), field=field, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (mytask == 0) then + call ESMF_FieldGet(field, farrayPtr = farrayptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (scalar_id < 0 .or. scalar_id > flds_scalar_num) then + call ESMF_LogWrite(trim(subname)//": ERROR in scalar_id", ESMF_LOGMSG_INFO, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return + endif + tmp(:) = farrayptr(scalar_id,:) + endif + call ESMF_VMBroadCast(vm, tmp, 1, 0, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + scalar_value = tmp(1) + + end subroutine state_getscalar + +!================================================================================ + + subroutine state_setscalar(scalar_value, scalar_id, State, flds_scalar_name, flds_scalar_num, rc) + + ! ---------------------------------------------- + ! Set scalar data from State for a particular name + ! ---------------------------------------------- + + ! input/output arguments + real(r8), intent(in) :: scalar_value + integer, intent(in) :: scalar_id + type(ESMF_State), intent(inout) :: State + character(len=*), intent(in) :: flds_scalar_name + integer, intent(in) :: flds_scalar_num + integer, intent(inout) :: rc + + ! local variables + integer :: mytask + type(ESMF_Field) :: lfield + type(ESMF_VM) :: vm + real(r8), pointer :: farrayptr(:,:) + character(len=*), parameter :: subname='(state_setscalar)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_VMGetCurrent(vm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_VMGet(vm, localPet=mytask, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_StateGet(State, itemName=trim(flds_scalar_name), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (mytask == 0) then + call ESMF_FieldGet(lfield, farrayPtr = farrayptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (scalar_id < 0 .or. scalar_id > flds_scalar_num) then + call ESMF_LogWrite(trim(subname)//": ERROR in scalar_id", ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + endif + farrayptr(scalar_id,1) = scalar_value + endif + + end subroutine state_setscalar + +!=============================================================================== + + subroutine state_diagnose(State, string, rc) + + ! ---------------------------------------------- + ! Diagnose status of State + ! ---------------------------------------------- + + type(ESMF_State), intent(in) :: state + character(len=*), intent(in) :: string + integer , intent(out) :: rc + + ! local variables + integer :: n + type(ESMf_Field) :: lfield + integer :: fieldCount, lrank + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + real(r8), pointer :: dataPtr1d(:) + real(r8), pointer :: dataPtr2d(:,:) + character(len=*),parameter :: subname='(state_diagnose)' + ! ---------------------------------------------- + + call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(lfieldnamelist(fieldCount)) + + call ESMF_StateGet(state, itemNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + do n = 1, fieldCount + + call ESMF_StateGet(state, itemName=lfieldnamelist(n), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call field_getfldptr(lfield, fldptr1=dataPtr1d, fldptr2=dataPtr2d, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + if (size(dataPtr1d) > 0) then + write(msgString,'(A,a)') trim(string)//': for 1d field '//trim(lfieldnamelist(n)) + call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) + write(msgString,'(A,3g14.7,i8)') trim(string)//': 1d field '//trim(lfieldnamelist(n)), & + minval(dataPtr1d), maxval(dataPtr1d), sum(dataPtr1d), size(dataPtr1d) + call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) + else + write(msgString,'(A,a)') trim(string)//': '//trim(lfieldnamelist(n))," no data" + call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) + endif + elseif (lrank == 2) then + if (size(dataPtr2d) > 0) then + write(msgString,'(A,a)') trim(string)//': for 2d field '//trim(lfieldnamelist(n)) + call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) + write(msgString,'(A,3g14.7,i8)') trim(string)//': 2d field '//trim(lfieldnamelist(n)), & + minval(dataPtr2d), maxval(dataPtr2d), sum(dataPtr2d), size(dataPtr2d) + call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) + else + write(msgString,'(A,a)') trim(string)//': '//trim(lfieldnamelist(n))," no data" + call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) + endif + else + call ESMF_LogWrite(trim(subname)//": ERROR rank not supported ", ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + enddo + + deallocate(lfieldnamelist) + + end subroutine state_diagnose + +!=============================================================================== + + subroutine field_getfldptr(field, fldptr1, fldptr2, rank, abort, rc) + + ! ---------------------------------------------- + ! for a field, determine rank and return fldptr1 or fldptr2 + ! abort is true by default and will abort if fldptr is not yet allocated in field + ! rank returns 0, 1, or 2. 0 means fldptr not allocated and abort=false + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_Field) , intent(in) :: field + real(r8), pointer , intent(inout), optional :: fldptr1(:) + real(r8), pointer , intent(inout), optional :: fldptr2(:,:) + integer , intent(out) , optional :: rank + logical , intent(in) , optional :: abort + integer , intent(out) , optional :: rc + + ! local variables + type(ESMF_GeomType_Flag) :: geomtype + type(ESMF_FieldStatus_Flag) :: status + type(ESMF_Mesh) :: lmesh + integer :: lrank, nnodes, nelements + logical :: labort + character(len=*), parameter :: subname='(field_getfldptr)' + ! ---------------------------------------------- + + if (.not.present(rc)) then + call ESMF_LogWrite(trim(subname)//": ERROR rc not present ", & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + + rc = ESMF_SUCCESS + + labort = .true. + if (present(abort)) then + labort = abort + endif + lrank = -99 + + call ESMF_FieldGet(field, status=status, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (status /= ESMF_FIELDSTATUS_COMPLETE) then + lrank = 0 + if (labort) then + call ESMF_LogWrite(trim(subname)//": ERROR data not allocated ", ESMF_LOGMSG_INFO, rc=rc) + rc = ESMF_FAILURE + return + else + call ESMF_LogWrite(trim(subname)//": WARNING data not allocated ", ESMF_LOGMSG_INFO, rc=rc) + endif + else + + call ESMF_FieldGet(field, geomtype=geomtype, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (geomtype == ESMF_GEOMTYPE_GRID) then + call ESMF_FieldGet(field, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + elseif (geomtype == ESMF_GEOMTYPE_MESH) then + call ESMF_FieldGet(field, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field, mesh=lmesh, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(lmesh, numOwnedNodes=nnodes, numOwnedElements=nelements, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (nnodes == 0 .and. nelements == 0) lrank = 0 + else + call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", & + ESMF_LOGMSG_INFO, rc=rc) + rc = ESMF_FAILURE + return + endif ! geomtype + + if (lrank == 0) then + call ESMF_LogWrite(trim(subname)//": no local nodes or elements ", & + ESMF_LOGMSG_INFO) + elseif (lrank == 1) then + if (.not.present(fldptr1)) then + call ESMF_LogWrite(trim(subname)//": ERROR missing rank=1 array ", & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + call ESMF_FieldGet(field, farrayPtr=fldptr1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + elseif (lrank == 2) then + if (.not.present(fldptr2)) then + call ESMF_LogWrite(trim(subname)//": ERROR missing rank=2 array ", & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + call ESMF_FieldGet(field, farrayPtr=fldptr2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_LogWrite(trim(subname)//": ERROR in rank ", & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + + endif ! status + + if (present(rank)) then + rank = lrank + endif + + end subroutine field_getfldptr + +!=============================================================================== + + subroutine alarmInit( clock, alarm, option, & + opt_n, opt_ymd, opt_tod, RefTime, alarmname, advance_clock, rc) + use ESMF, only : ESMF_AlarmPrint + ! Setup an alarm in a clock + ! Notes: The ringtime sent to AlarmCreate MUST be the next alarm + ! time. If you send an arbitrary but proper ringtime from the + ! past and the ring interval, the alarm will always go off on the + ! next clock advance and this will cause serious problems. Even + ! if it makes sense to initialize an alarm with some reference + ! time and the alarm interval, that reference time has to be + ! advance forward to be >= the current time. In the logic below + ! we set an appropriate "NextAlarm" and then we make sure to + ! advance it properly based on the ring interval. + + ! input/output variables + type(ESMF_Clock) , intent(inout) :: clock ! clock + type(ESMF_Alarm) , intent(inout) :: alarm ! alarm + character(len=*) , intent(in) :: option ! alarm option + integer , optional , intent(in) :: opt_n ! alarm freq + integer , optional , intent(in) :: opt_ymd ! alarm ymd + integer , optional , intent(in) :: opt_tod ! alarm tod (sec) + type(ESMF_Time) , optional , intent(in) :: RefTime ! ref time + character(len=*) , optional , intent(in) :: alarmname ! alarm name + logical , optional , intent(in) :: advance_clock ! advance clock to trigger alarm + integer , intent(inout) :: rc ! Return code + + ! local variables + type(ESMF_Calendar) :: cal ! calendar + integer :: lymd ! local ymd + integer :: ltod ! local tod + integer :: cyy,cmm,cdd,csec ! time info + character(len=64) :: lalarmname ! local alarm name + logical :: update_nextalarm ! update next alarm + type(ESMF_Time) :: CurrTime ! Current Time + type(ESMF_Time) :: NextAlarm ! Next restart alarm time + type(ESMF_TimeInterval) :: AlarmInterval ! Alarm interval + type(ESMF_TimeInterval) :: TimeStepInterval ! Component timestep interval + character(len=*), parameter :: subname = '(alarmInit): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + lalarmname = 'alarm_unknown' + if (present(alarmname)) lalarmname = trim(alarmname) + ltod = 0 + if (present(opt_tod)) ltod = opt_tod + lymd = -1 + if (present(opt_ymd)) lymd = opt_ymd + + call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_TimeGet(CurrTime, yy=cyy, mm=cmm, dd=cdd, s=csec, rc=rc ) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! initial guess of next alarm, this will be updated below + if (present(RefTime)) then + NextAlarm = RefTime + else + NextAlarm = CurrTime + endif + + ! Determine calendar + call ESMF_ClockGet(clock, calendar=cal) + + ! Error checks + if (trim(option) == optdate) then + if (.not. present(opt_ymd)) then + call ESMF_LogWrite(trim(subname)//trim(option)//' requires opt_ymd', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + end if + if (lymd < 0 .or. ltod < 0) then + call ESMF_LogWrite(subname//trim(option)//'opt_ymd, opt_tod invalid', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + end if + else if (& + trim(option) == optNSteps .or. trim(option) == trim(optNSteps)//'s' .or. & + trim(option) == optNSeconds .or. trim(option) == trim(optNSeconds)//'s' .or. & + trim(option) == optNMinutes .or. trim(option) == trim(optNMinutes)//'s' .or. & + trim(option) == optNHours .or. trim(option) == trim(optNHours)//'s' .or. & + trim(option) == optNDays .or. trim(option) == trim(optNDays)//'s' .or. & + trim(option) == optNMonths .or. trim(option) == trim(optNMonths)//'s' .or. & + trim(option) == optNYears .or. trim(option) == trim(optNYears)//'s' ) then + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + end if + end if + + ! Determine inputs for call to create alarm + selectcase (trim(option)) + + case (optNONE) + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) + if (chkerr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .false. + + case (optNever) + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) + if (chkerr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .false. + + case (optDate) + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call timeInit(NextAlarm, lymd, cal, ltod, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .false. + + case (optNSteps,trim(optNSteps)//'s') + call ESMF_ClockGet(clock, TimeStep=TimestepInterval, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeIntervalSet(AlarmInterval, s=dtime_drv, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + ! timestepinterval*0 is 0 of kind ESMF_TimeStepInterval + if (mod(AlarmInterval, TimestepInterval) /= (timestepinterval*0)) then + call ESMF_LogWrite(subname//'illegal Alarm setting for '//trim(alarmname), ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + update_nextalarm = .true. + + case (optNSeconds,trim(optNSeconds)//'s') + call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNMinutes,trim(optNMinutes)//'s') + call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc) + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNHours,trim(optNHours)//'s') + call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNDays,trim(optNDays)//'s') + call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNMonths,trim(optNMonths)//'s') + call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optMonthly) + call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=1, s=0, calendar=cal, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .true. + + case (optNYears, trim(optNYears)//'s') + call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optYearly) + call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeSet( NextAlarm, yy=cyy, mm=1, dd=1, s=0, calendar=cal, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .true. + case default + call ESMF_LogWrite(subname//'unknown option '//trim(option), ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + + end select + + ! -------------------------------------------------------------------------------- + ! --- AlarmInterval and NextAlarm should be set --- + ! -------------------------------------------------------------------------------- + + ! --- advance Next Alarm so it won't ring on first timestep for + ! --- most options above. go back one alarminterval just to be careful + + if (update_nextalarm) then + NextAlarm = NextAlarm - AlarmInterval + do while (NextAlarm <= CurrTime) + NextAlarm = NextAlarm + AlarmInterval + enddo + endif + alarm = ESMF_AlarmCreate( name=lalarmname, clock=clock, ringTime=NextAlarm, & + ringInterval=AlarmInterval, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Advance model clock to trigger alarm then reset model clock back to currtime + if (present(advance_clock)) then + if (advance_clock) then + call ESMF_AlarmSet(alarm, clock=clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGet(clock, currTime=CurrTime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockAdvance(clock,rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockSet(clock, currTime=currtime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end if + + end subroutine alarmInit + +!=============================================================================== + + subroutine timeInit( Time, ymd, cal, tod, rc) + + ! Create the ESMF_Time object corresponding to the given input time, + ! given in YMD (Year Month Day) and TOD (Time-of-day) format. + ! Set the time by an integer as YYYYMMDD and integer seconds in the day + + ! input/output parameters: + type(ESMF_Time) , intent(inout) :: Time ! ESMF time + integer , intent(in) :: ymd ! year, month, day YYYYMMDD + type(ESMF_Calendar) , intent(in) :: cal ! ESMF calendar + integer , intent(in) :: tod ! time of day in seconds + integer , intent(out) :: rc + + ! local variables + integer :: year, mon, day ! year, month, day as integers + integer :: tdate ! temporary date + character(len=*), parameter :: subname='(timeInit)' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if ( (ymd < 0) .or. (tod < 0) .or. (tod > SecPerDay) )then + call shr_sys_abort( subname//'ERROR yymmdd is a negative number or time-of-day out of bounds' ) + end if + + tdate = abs(ymd) + year = int(tdate/10000) + if (ymd < 0) year = -year + mon = int( mod(tdate,10000)/ 100) + day = mod(tdate, 100) + + call ESMF_TimeSet( Time, yy=year, mm=mon, dd=day, s=tod, calendar=cal, rc=rc ) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + end subroutine timeInit + +!=============================================================================== + + integer function get_minimum_timestep(gcomp, rc) + ! Get the minimum timestep interval in seconds based on the nuopc.config variables *_cpl_dt, + ! if none of these variables are defined this routine will throw an error + type(ESMF_GridComp), intent(in) :: gcomp + integer, intent(out) :: rc + + character(len=CS) :: cvalue + integer :: atm_cpl_dt ! Atmosphere coupling interval + integer :: lnd_cpl_dt ! Land coupling interval + integer :: ice_cpl_dt ! Sea-Ice coupling interval + integer :: ocn_cpl_dt ! Ocean coupling interval + integer :: glc_cpl_dt ! Glc coupling interval + integer :: rof_cpl_dt ! Runoff coupling interval + integer :: wav_cpl_dt ! Wav coupling interval + logical :: is_present, is_set ! determine if these variables are used + integer :: esp_cpl_dt ! Esp coupling interval + + !--------------------------------------------------------------------------- + ! Determine driver clock timestep + !--------------------------------------------------------------------------- + get_minimum_timestep = huge(1) + + call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) atm_cpl_dt + get_minimum_timestep = min(atm_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) lnd_cpl_dt + get_minimum_timestep = min(lnd_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ice_cpl_dt + get_minimum_timestep = min(ice_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ocn_cpl_dt + get_minimum_timestep = min(ocn_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) glc_cpl_dt + get_minimum_timestep = min(glc_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) rof_cpl_dt + get_minimum_timestep = min(rof_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) wav_cpl_dt + get_minimum_timestep = min(wav_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="esp_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="esp_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) esp_cpl_dt + get_minimum_timestep = min(esp_cpl_dt, get_minimum_timestep) + endif + if(get_minimum_timestep == huge(1)) then + call ESMF_LogWrite('minimum_timestep_error: this option is not supported ', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + if(get_minimum_timestep <= 0) then + print *,__FILE__,__LINE__,atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt + call ESMF_LogWrite('minimum_timestep_error ERROR ', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + end function get_minimum_timestep + +!=============================================================================== + + logical function chkerr(rc, line, file) + + integer, intent(in) :: rc + integer, intent(in) :: line + character(len=*), intent(in) :: file + + 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 nuopc_shr_methods From d5ba65baae7905ddd41c8d9bbab8057fe8b4c5da Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 21 Aug 2024 14:48:53 -0600 Subject: [PATCH 129/170] remove unused function --- share/nuopc_shr_methods.F90 | 117 ------------------------------------ 1 file changed, 117 deletions(-) diff --git a/share/nuopc_shr_methods.F90 b/share/nuopc_shr_methods.F90 index eeac5405e..d65a9cc69 100644 --- a/share/nuopc_shr_methods.F90 +++ b/share/nuopc_shr_methods.F90 @@ -35,7 +35,6 @@ module nuopc_shr_methods public :: state_setscalar public :: state_diagnose public :: alarmInit - public :: get_minimum_timestep public :: chkerr private :: timeInit @@ -759,122 +758,6 @@ subroutine timeInit( Time, ymd, cal, tod, rc) end subroutine timeInit -!=============================================================================== - - integer function get_minimum_timestep(gcomp, rc) - ! Get the minimum timestep interval in seconds based on the nuopc.config variables *_cpl_dt, - ! if none of these variables are defined this routine will throw an error - type(ESMF_GridComp), intent(in) :: gcomp - integer, intent(out) :: rc - - character(len=CS) :: cvalue - integer :: atm_cpl_dt ! Atmosphere coupling interval - integer :: lnd_cpl_dt ! Land coupling interval - integer :: ice_cpl_dt ! Sea-Ice coupling interval - integer :: ocn_cpl_dt ! Ocean coupling interval - integer :: glc_cpl_dt ! Glc coupling interval - integer :: rof_cpl_dt ! Runoff coupling interval - integer :: wav_cpl_dt ! Wav coupling interval - logical :: is_present, is_set ! determine if these variables are used - integer :: esp_cpl_dt ! Esp coupling interval - - !--------------------------------------------------------------------------- - ! Determine driver clock timestep - !--------------------------------------------------------------------------- - get_minimum_timestep = huge(1) - - call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (is_present .and. is_set) then - call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) atm_cpl_dt - get_minimum_timestep = min(atm_cpl_dt, get_minimum_timestep) - endif - - call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (is_present .and. is_set) then - call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) lnd_cpl_dt - get_minimum_timestep = min(lnd_cpl_dt, get_minimum_timestep) - endif - - call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (is_present .and. is_set) then - call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) ice_cpl_dt - get_minimum_timestep = min(ice_cpl_dt, get_minimum_timestep) - endif - - call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (is_present .and. is_set) then - call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) ocn_cpl_dt - get_minimum_timestep = min(ocn_cpl_dt, get_minimum_timestep) - endif - - call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (is_present .and. is_set) then - call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) glc_cpl_dt - get_minimum_timestep = min(glc_cpl_dt, get_minimum_timestep) - endif - - call NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (is_present .and. is_set) then - call NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) rof_cpl_dt - get_minimum_timestep = min(rof_cpl_dt, get_minimum_timestep) - endif - - call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (is_present .and. is_set) then - call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) wav_cpl_dt - get_minimum_timestep = min(wav_cpl_dt, get_minimum_timestep) - endif - - call NUOPC_CompAttributeGet(gcomp, name="esp_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (is_present .and. is_set) then - call NUOPC_CompAttributeGet(gcomp, name="esp_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) esp_cpl_dt - get_minimum_timestep = min(esp_cpl_dt, get_minimum_timestep) - endif - if(get_minimum_timestep == huge(1)) then - call ESMF_LogWrite('minimum_timestep_error: this option is not supported ', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - if(get_minimum_timestep <= 0) then - print *,__FILE__,__LINE__,atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt - call ESMF_LogWrite('minimum_timestep_error ERROR ', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - end function get_minimum_timestep - !=============================================================================== logical function chkerr(rc, line, file) From 8e1f68d29f155b51b4b169a14bbeba65b8a913c2 Mon Sep 17 00:00:00 2001 From: Katetc Date: Thu, 29 Aug 2024 13:51:49 -0600 Subject: [PATCH 130/170] Fixed usrf bug and first draft simple hole filling for neg qice --- dglc/dglc_datamode_noevolve_mod.F90 | 58 ++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index d654e6aac..9d4d5cb73 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -49,8 +49,6 @@ module dglc_datamode_noevolve_mod ! type(icesheet_ptr_t), allocatable :: So_t(:) ! type(icesheet_ptr_t), allocatable :: So_q(:) - real(r8), allocatable :: usrf(:) ! upper surface elevation (m) on ice grid - ! Export Field names character(len=*), parameter :: field_out_area = 'Sg_area' character(len=*), parameter :: field_out_topo = 'Sg_topo' @@ -206,7 +204,7 @@ end subroutine dglc_datamode_noevolve_init_pointers !=============================================================================== subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & - model_meshes, model_internal_gridsize, model_datafiles, rc) + logunit, model_meshes, model_internal_gridsize, model_datafiles, rc) ! Assume that the model mesh is the same as the input data mesh @@ -214,6 +212,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info integer , intent(in) :: io_type ! pio info integer , intent(in) :: io_format ! pio info + integer , intent(in) :: logunit ! For writing logs type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes real(r8) , intent(in) :: model_internal_gridsize(:) ! internal model gridsizes (m) character(len=*) , intent(in) :: model_datafiles(:) ! input file names @@ -240,7 +239,11 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & real(r8) :: rhoi ! density of ice ~ kg/m^3 real(r8) :: rhoo ! density of sea water ~ kg/m^3 real(r8) :: eus ! eustatic sea level + real(r8), allocatable :: Tot_smb(:) ! Sum smb on each ice sheet to reduce neg fluxes + real(r8) :: num_Tot ! Number of active grid cells in total calculation + real(r8) :: ice_out ! Scaled value of ice mass balance sent to rof real(r8), allocatable :: lsrf(:) ! lower surface elevation (m) on ice grid + real(r8), allocatable :: usrf(:) ! upper surface elevation (m) on ice grid character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -361,7 +364,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & end do deallocate(lsrf) - + deallocate(usrf) call pio_closefile(pioid) call pio_freedecomp(pio_subsystem, pio_iodesc) @@ -369,23 +372,58 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & end if + ! Set initialized flag + initialized_noevolve = .true. + if (initialized_noevolve) then + ! Compute Fgrg_rofi do ns = 1,num_icesheets - lsize = size(Fgrg_rofi(ns)%ptr) + + ! Get mesh info + call ESMF_MeshGet(model_meshes(ns), 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(Tot_smb(lsize)) + Tot_smb(:) = 0.d0 + num_Tot = 0.d0 + ice_out = 0.d0 + + ! For No Evolve to reduce negative ice fluxes from DGLC, we will + ! Sum over all smb (Flgl_qice) for each ice sheet (not globally). + ! The output to the river model will be an equal division of the + ! final total (pos+Neg). do ng = 1,lsize - if (is_in_active_grid(usrf(ng))) then - Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then + Tot_smb(ns) = Tot_smb(ns)+Flgl_qice(ns)%ptr(ng) + num_Tot = num_Tot+1.d0 + end if + end do + ! Now redistribute the scaled values + if (num_Tot.gt.0.d0) then + ice_out = Tot_smb(ns)/num_Tot + else + ice_out = 0.d0 + end if + do ng = 1,lsize + if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then + Fgrg_rofi(ns)%ptr(ng) = ice_out else Fgrg_rofi(ns)%ptr(ng) = 0._r8 end if end do + + deallocate(Tot_smb) + !if (is_in_active_grid(usrf(ng))) then + ! Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + !else + ! Fgrg_rofi(ns)%ptr(ng) = 0._r8 + !end if end do end if - ! Set initialized flag - initialized_noevolve = .true. - end subroutine dglc_datamode_noevolve_advance !=============================================================================== From da714ce8a7c7da64c9523818f848df967a2299f4 Mon Sep 17 00:00:00 2001 From: Katetc Date: Thu, 29 Aug 2024 14:44:00 -0600 Subject: [PATCH 131/170] Passing logunit to run comp subroutine --- dglc/glc_comp_nuopc.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index f5b6c2a36..11e66bfd2 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -590,7 +590,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inp case('noevolve') if (valid_inputs) then call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, & - model_meshes, model_internal_gridsize, model_datafiles, rc) + logunit, model_meshes, model_internal_gridsize, model_datafiles, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end select From aedd7221d80c988adc8c61fb481520ad1f01fbb6 Mon Sep 17 00:00:00 2001 From: Katetc Date: Fri, 30 Aug 2024 10:07:25 -0600 Subject: [PATCH 132/170] Fix step 2, scaled removal by fraction of local positives --- dglc/dglc_datamode_noevolve_mod.F90 | 84 +++++++++++++++++++---------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 9d4d5cb73..8a8f96b9e 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -239,9 +239,11 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & real(r8) :: rhoi ! density of ice ~ kg/m^3 real(r8) :: rhoo ! density of sea water ~ kg/m^3 real(r8) :: eus ! eustatic sea level - real(r8), allocatable :: Tot_smb(:) ! Sum smb on each ice sheet to reduce neg fluxes + real(r8) :: Tot_pos_smb ! Sum of positive smb values on each ice sheet for hole-filling + real(r8) :: Tot_neg_smb ! Sum of negative smb values on each ice sheet for hole-filling real(r8) :: num_Tot ! Number of active grid cells in total calculation - real(r8) :: ice_out ! Scaled value of ice mass balance sent to rof + real(r8) :: rat ! Ratio of hole-filling flux to apply + real(r8), allocatable :: ice_runoff_out(:) ! Scaled ice runoff output after holes filled real(r8), allocatable :: lsrf(:) ! lower surface elevation (m) on ice grid real(r8), allocatable :: usrf(:) ! upper surface elevation (m) on ice grid character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' @@ -386,41 +388,67 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(Tot_smb(lsize)) - Tot_smb(:) = 0.d0 + allocate(ice_runoff_out(lsize)) + ice_runoff_out(:) = 0.d0 + Tot_pos_smb = 0.d0 + Tot_neg_smb = 0.d0 num_Tot = 0.d0 - ice_out = 0.d0 + rat = 0.d0 ! For No Evolve to reduce negative ice fluxes from DGLC, we will - ! Sum over all smb (Flgl_qice) for each ice sheet (not globally). - ! The output to the river model will be an equal division of the - ! final total (pos+Neg). + ! Calculate the total positive and total negative fluxes on each + ! processor for each ice sheet. do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then - Tot_smb(ns) = Tot_smb(ns)+Flgl_qice(ns)%ptr(ng) - num_Tot = num_Tot+1.d0 + if(Flgl_qice(ns)%ptr(ng) > 0.d0) then + Tot_pos_smb = Tot_pos_smb+Flgl_qice(ns)%ptr(ng) + end if + ! Ignore places that are exactly 0.d0 + if(Flgl_qice(ns)%ptr(ng) < 0.d0) then + Tot_neg_smb = Tot_neg_smb+Flgl_qice(ns)%ptr(ng) + end if end if end do - ! Now redistribute the scaled values - if (num_Tot.gt.0.d0) then - ice_out = Tot_smb(ns)/num_Tot + ! If there's more positive than negative, then set all + ! negative to zero and destribute the negative flux amount + ! across the positive values, scaled by the size of the + ! positive value. This section also applies to any chunks + ! where there is no negative smb. In that case the ice + ! runoff is exactly equal to the input smb. + if(abs(Tot_pos_smb) >= abs(Tot_neg_smb)) then + do ng = 1,lsize + if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then + if(Flgl_qice(ns)%ptr(ng) > 0.d0) then + rat = Flgl_qice(ns)%ptr(ng)/Tot_pos_smb + Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_neg_smb + else if (Flgl_qice(ns)%ptr(ng) < 0.d0) then + Fgrg_rofi(ns)%ptr(ng) = 0.d0 + end if + else + Fgrg_rofi(ns)%ptr(ng) = 0._r8 + end if + end do else - ice_out = 0.d0 - end if - do ng = 1,lsize - if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then - Fgrg_rofi(ns)%ptr(ng) = ice_out - else - Fgrg_rofi(ns)%ptr(ng) = 0._r8 - end if - end do + ! If there's more negative than positive, set the positive to zero + ! and distribute the positive amount to the negative spaces to + ! reduce their negativity a bit. This shouldn't happen often. + ! This section of code also applies if Tot_pos_smb is zero. + do ng = 1,lsize + if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then + if(Flgl_qice(ns)%ptr(ng) < 0.d0) then + rat = Flgl_qice(ns)%ptr(ng)/Tot_neg_smb + Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_pos_smb + else if (Flgl_qice(ns)%ptr(ng) > 0.d0) then + Fgrg_rofi(ns)%ptr(ng) = 0.d0 + end if + else + Fgrg_rofi(ns)%ptr(ng) = 0._r8 + end if + end do + + end if ! More neg or pos smb - deallocate(Tot_smb) - !if (is_in_active_grid(usrf(ng))) then - ! Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) - !else - ! Fgrg_rofi(ns)%ptr(ng) = 0._r8 - !end if + deallocate(ice_runoff_out) end do end if From b73abc38b1e41e80a9e553be080f025fb69be66c Mon Sep 17 00:00:00 2001 From: Katetc Date: Fri, 30 Aug 2024 12:49:27 -0600 Subject: [PATCH 133/170] Third step complete, added global sums to spread calculation out over the entire ice sheet --- dglc/dglc_datamode_noevolve_mod.F90 | 49 +++++++++++++++++++---------- dglc/glc_comp_nuopc.F90 | 9 +++--- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 8a8f96b9e..068e1b81e 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -4,6 +4,8 @@ module dglc_datamode_noevolve_mod use ESMF , only : ESMF_Mesh, ESMF_DistGrid, ESMF_FieldBundle, ESMF_Field use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldCreate, ESMF_MeshLoc_Element use ESMF , only : ESMF_FieldBundleAdd, ESMF_MeshGet, ESMF_DistGridGet, ESMF_Typekind_R8 + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_VM, ESMF_VMAllreduce, ESMF_REDUCE_SUM use NUOPC , only : NUOPC_Advertise, NUOPC_IsConnected use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort @@ -203,12 +205,13 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) end subroutine dglc_datamode_noevolve_init_pointers !=============================================================================== - subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & + subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_format, & logunit, model_meshes, model_internal_gridsize, model_datafiles, rc) ! Assume that the model mesh is the same as the input data mesh - ! input/output variables + ! input/output variables + type(ESMF_GridComp) :: gcomp type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info integer , intent(in) :: io_type ! pio info integer , intent(in) :: io_format ! pio info @@ -222,6 +225,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & type(ESMF_FieldBundle) :: fldbun_noevolve type(ESMF_DistGrid) :: distgrid type(ESMF_Field) :: field_noevolve + type(ESMF_VM) :: vm type(file_desc_t) :: pioid type(io_desc_t) :: pio_iodesc integer :: ns ! ice sheet index @@ -239,8 +243,8 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & real(r8) :: rhoi ! density of ice ~ kg/m^3 real(r8) :: rhoo ! density of sea water ~ kg/m^3 real(r8) :: eus ! eustatic sea level - real(r8) :: Tot_pos_smb ! Sum of positive smb values on each ice sheet for hole-filling - real(r8) :: Tot_neg_smb ! Sum of negative smb values on each ice sheet for hole-filling + real(r8) :: loc_pos_smb(1), Tot_pos_smb(1) ! Sum of positive smb values on each ice sheet for hole-filling + real(r8) :: loc_neg_smb(1), Tot_neg_smb(1) ! Sum of negative smb values on each ice sheet for hole-filling real(r8) :: num_Tot ! Number of active grid cells in total calculation real(r8) :: rat ! Ratio of hole-filling flux to apply real(r8), allocatable :: ice_runoff_out(:) ! Scaled ice runoff output after holes filled @@ -390,42 +394,55 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & allocate(ice_runoff_out(lsize)) ice_runoff_out(:) = 0.d0 - Tot_pos_smb = 0.d0 - Tot_neg_smb = 0.d0 + loc_pos_smb(1) = 0.d0 + Tot_pos_smb(1) = 0.d0 + loc_neg_smb(1) = 0.d0 + Tot_neg_smb(1) = 0.d0 num_Tot = 0.d0 rat = 0.d0 ! For No Evolve to reduce negative ice fluxes from DGLC, we will ! Calculate the total positive and total negative fluxes on each - ! processor for each ice sheet. + ! processor first (local totals). do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then if(Flgl_qice(ns)%ptr(ng) > 0.d0) then - Tot_pos_smb = Tot_pos_smb+Flgl_qice(ns)%ptr(ng) + loc_pos_smb(1) = loc_pos_smb(1)+Flgl_qice(ns)%ptr(ng)*Sg_area(ns)%ptr(ng) end if ! Ignore places that are exactly 0.d0 if(Flgl_qice(ns)%ptr(ng) < 0.d0) then - Tot_neg_smb = Tot_neg_smb+Flgl_qice(ns)%ptr(ng) + loc_neg_smb(1) = loc_neg_smb(1)+Flgl_qice(ns)%ptr(ng)*Sg_area(ns)%ptr(ng) end if end if end do + ! Now do two global sums to get the ice sheet total positive + ! and negative ice fluxes + call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMAllreduce(vm, senddata=loc_pos_smb, recvdata=Tot_pos_smb, count=1, & + reduceflag=ESMF_REDUCE_SUM, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMAllreduce(vm, senddata=loc_neg_smb, recvdata=Tot_neg_smb, count=1, & + reduceflag=ESMF_REDUCE_SUM, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! If there's more positive than negative, then set all ! negative to zero and destribute the negative flux amount ! across the positive values, scaled by the size of the ! positive value. This section also applies to any chunks ! where there is no negative smb. In that case the ice ! runoff is exactly equal to the input smb. - if(abs(Tot_pos_smb) >= abs(Tot_neg_smb)) then + if(abs(Tot_pos_smb(1)) >= abs(Tot_neg_smb(1))) then do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then if(Flgl_qice(ns)%ptr(ng) > 0.d0) then - rat = Flgl_qice(ns)%ptr(ng)/Tot_pos_smb - Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_neg_smb + rat = Flgl_qice(ns)%ptr(ng)/Tot_pos_smb(1) + Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_neg_smb(1)/Sg_area(ns)%ptr(ng) else if (Flgl_qice(ns)%ptr(ng) < 0.d0) then Fgrg_rofi(ns)%ptr(ng) = 0.d0 end if else - Fgrg_rofi(ns)%ptr(ng) = 0._r8 + Fgrg_rofi(ns)%ptr(ng) = 0.d0 end if end do else @@ -436,13 +453,13 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then if(Flgl_qice(ns)%ptr(ng) < 0.d0) then - rat = Flgl_qice(ns)%ptr(ng)/Tot_neg_smb - Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_pos_smb + rat = Flgl_qice(ns)%ptr(ng)/Tot_neg_smb(1) + Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_pos_smb(1)/Sg_area(ns)%ptr(ng) else if (Flgl_qice(ns)%ptr(ng) > 0.d0) then Fgrg_rofi(ns)%ptr(ng) = 0.d0 end if else - Fgrg_rofi(ns)%ptr(ng) = 0._r8 + Fgrg_rofi(ns)%ptr(ng) = 0.d0 end if end do diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 11e66bfd2..ab797bbd2 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -430,7 +430,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) end do ! end loop over ice sheets ! Run dglc - call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., valid_inputs=.true., rc=rc) + call dglc_comp_run(gcomp, clock, current_ymd, current_tod, restart_write=.false., valid_inputs=.true., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('dglc_strdata_init') @@ -498,19 +498,20 @@ subroutine ModelAdvance(gcomp, rc) restart_write = dshr_check_restart_alarm(clock, rc=rc) ! run dglc - call dglc_comp_run(clock, next_ymd, next_tod, restart_write, valid_inputs, rc=rc) + call dglc_comp_run(gcomp, clock, next_ymd, next_tod, restart_write, valid_inputs, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine ModelAdvance !=============================================================================== - subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inputs, rc) + subroutine dglc_comp_run(gcomp, clock, target_ymd, target_tod, restart_write, valid_inputs, rc) ! -------------------------- ! advance dglc ! -------------------------- ! input/output variables: + type(ESMF_GridComp) :: gcomp type(ESMF_Clock) , intent(in) :: clock integer , intent(in) :: target_ymd ! model date integer , intent(in) :: target_tod ! model sec into model date @@ -589,7 +590,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inp select case (trim(datamode)) case('noevolve') if (valid_inputs) then - call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, & + call dglc_datamode_noevolve_advance(gcomp, sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, & logunit, model_meshes, model_internal_gridsize, model_datafiles, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if From 9a8afbc4fc61d334f6c06890ea3ebabd293f9def Mon Sep 17 00:00:00 2001 From: Katetc Date: Fri, 30 Aug 2024 13:44:42 -0600 Subject: [PATCH 134/170] Fixed area weighting on application --- dglc/dglc_datamode_noevolve_mod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 068e1b81e..d544ac8ac 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -436,8 +436,8 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then if(Flgl_qice(ns)%ptr(ng) > 0.d0) then - rat = Flgl_qice(ns)%ptr(ng)/Tot_pos_smb(1) - Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_neg_smb(1)/Sg_area(ns)%ptr(ng) + rat = Flgl_qice(ns)%ptr(ng)*Sg_area(ns)%ptr(ng)/Tot_pos_smb(1) + Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_neg_smb(1) else if (Flgl_qice(ns)%ptr(ng) < 0.d0) then Fgrg_rofi(ns)%ptr(ng) = 0.d0 end if @@ -453,8 +453,8 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then if(Flgl_qice(ns)%ptr(ng) < 0.d0) then - rat = Flgl_qice(ns)%ptr(ng)/Tot_neg_smb(1) - Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_pos_smb(1)/Sg_area(ns)%ptr(ng) + rat = Flgl_qice(ns)%ptr(ng)*Sg_area(ns)%ptr(ng)/Tot_neg_smb(1) + Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_pos_smb(1) else if (Flgl_qice(ns)%ptr(ng) > 0.d0) then Fgrg_rofi(ns)%ptr(ng) = 0.d0 end if From 1f7234f38ccaba880c5c1650ff3c587dfc87f295 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 30 Aug 2024 17:11:19 -0600 Subject: [PATCH 135/170] starting the translation --- datm/atm_comp_nuopc.F90 | 23 ++++++++++++----------- datm/datm_datamode_cfsr_mod.F90 | 8 ++++---- datm/datm_datamode_clmncep_mod.F90 | 8 ++++---- datm/datm_datamode_core2_mod.F90 | 8 ++++---- datm/datm_datamode_cplhist_mod.F90 | 8 ++++---- datm/datm_datamode_era5_mod.F90 | 8 ++++---- datm/datm_datamode_gefs_mod.F90 | 8 ++++---- datm/datm_datamode_jra_mod.F90 | 8 ++++---- datm/datm_datamode_simple_mod.F90 | 8 ++++---- dice/dice_datamode_ssmi_mod.F90 | 9 +++++---- dice/ice_comp_nuopc.F90 | 7 ++++--- dshr/dshr_mod.F90 | 19 ++++++++++--------- 12 files changed, 63 insertions(+), 59 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 7a2a41c7b..9fd846f98 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -479,7 +479,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Run datm - call datm_comp_run(importstate, exportstate, current_ymd, current_tod, current_mon, & + call datm_comp_run(gcomp, importstate, exportstate, current_ymd, current_tod, current_mon, & orbEccen, orbMvelpp, orbLambm0, orbObliqr, restart_write=.false., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -561,7 +561,7 @@ subroutine ModelAdvance(gcomp, rc) ! Run datm call ESMF_TraceRegionEnter('datm_run') - call datm_comp_run(importstate, exportstate, next_ymd, next_tod, mon, & + call datm_comp_run(gcomp, importstate, exportstate, next_ymd, next_tod, mon, & orbEccen, orbMvelpp, orbLambm0, orbObliqr, restart_write, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('datm_run') @@ -579,7 +579,7 @@ subroutine ModelAdvance(gcomp, rc) end subroutine ModelAdvance !=============================================================================== - subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, target_mon, & + subroutine datm_comp_run(gcomp, importState, exportState, target_ymd, target_tod, target_mon, & orbEccen, orbMvelpp, orbLambm0, orbObliqr, restart_write, rc) ! ---------------------------------- @@ -587,6 +587,7 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe ! ---------------------------------- ! input/output variables + type(ESMF_GridComp) , intent(in) :: gcomp type(ESMF_State) , intent(inout) :: importState type(ESMF_State) , intent(inout) :: exportState integer , intent(in) :: target_ymd ! model date @@ -650,21 +651,21 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe if (restart_read .and. .not. skip_restart_read) then select case (trim(datamode)) case('CORE2_NYF','CORE2_IAF') - call datm_datamode_core2_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call datm_datamode_core2_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('CORE_IAF_JRA') - call datm_datamode_jra_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call datm_datamode_jra_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('CLMNCEP') - call datm_datamode_clmncep_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call datm_datamode_clmncep_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('CPLHIST') - call datm_datamode_cplhist_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call datm_datamode_cplhist_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('ERA5') - call datm_datamode_era5_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call datm_datamode_era5_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('GEFS') - call datm_datamode_gefs_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call datm_datamode_gefs_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('CFSR') - call datm_datamode_cfsr_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call datm_datamode_cfsr_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('SIMPLE') - call datm_datamode_simple_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call datm_datamode_simple_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) end select end if diff --git a/datm/datm_datamode_cfsr_mod.F90 b/datm/datm_datamode_cfsr_mod.F90 index 8ad8cd3d6..c3aa60203 100644 --- a/datm/datm_datamode_cfsr_mod.F90 +++ b/datm/datm_datamode_cfsr_mod.F90 @@ -238,18 +238,18 @@ subroutine datm_datamode_cfsr_restart_write(case_name, inst_suffix, ymd, tod, & end subroutine datm_datamode_cfsr_restart_write !=============================================================================== - subroutine datm_datamode_cfsr_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - + subroutine datm_datamode_cfsr_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) + use ESMF, only : ESMF_GridComp ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) end subroutine datm_datamode_cfsr_restart_read diff --git a/datm/datm_datamode_clmncep_mod.F90 b/datm/datm_datamode_clmncep_mod.F90 index 41a9725c0..e9c982af2 100644 --- a/datm/datm_datamode_clmncep_mod.F90 +++ b/datm/datm_datamode_clmncep_mod.F90 @@ -610,18 +610,18 @@ subroutine datm_datamode_clmncep_restart_write(case_name, inst_suffix, ymd, tod, end subroutine datm_datamode_clmncep_restart_write !=============================================================================== - subroutine datm_datamode_clmncep_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - + subroutine datm_datamode_clmncep_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) + use ESMF, only : ESMF_GridComp ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) end subroutine datm_datamode_clmncep_restart_read diff --git a/datm/datm_datamode_core2_mod.F90 b/datm/datm_datamode_core2_mod.F90 index 41d2caae8..7e68893a2 100644 --- a/datm/datm_datamode_core2_mod.F90 +++ b/datm/datm_datamode_core2_mod.F90 @@ -429,18 +429,18 @@ subroutine datm_datamode_core2_restart_write(case_name, inst_suffix, ymd, tod, & end subroutine datm_datamode_core2_restart_write !=============================================================================== - subroutine datm_datamode_core2_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - + subroutine datm_datamode_core2_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) + use ESMF, only : ESMF_GridComp ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) end subroutine datm_datamode_core2_restart_read diff --git a/datm/datm_datamode_cplhist_mod.F90 b/datm/datm_datamode_cplhist_mod.F90 index 482bb7a04..c13ccef9d 100644 --- a/datm/datm_datamode_cplhist_mod.F90 +++ b/datm/datm_datamode_cplhist_mod.F90 @@ -220,18 +220,18 @@ subroutine datm_datamode_cplhist_restart_write(case_name, inst_suffix, ymd, tod, end subroutine datm_datamode_cplhist_restart_write !=============================================================================== - subroutine datm_datamode_cplhist_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - + subroutine datm_datamode_cplhist_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) + use ESMF, only : ESMF_GridComp ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) end subroutine datm_datamode_cplhist_restart_read diff --git a/datm/datm_datamode_era5_mod.F90 b/datm/datm_datamode_era5_mod.F90 index e10fe3028..84224a037 100644 --- a/datm/datm_datamode_era5_mod.F90 +++ b/datm/datm_datamode_era5_mod.F90 @@ -337,18 +337,18 @@ subroutine datm_datamode_era5_restart_write(case_name, inst_suffix, ymd, tod, & end subroutine datm_datamode_era5_restart_write !=============================================================================== - subroutine datm_datamode_era5_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - + subroutine datm_datamode_era5_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) + use ESMF, only : ESMF_GridComp ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) end subroutine datm_datamode_era5_restart_read diff --git a/datm/datm_datamode_gefs_mod.F90 b/datm/datm_datamode_gefs_mod.F90 index 86e6939a3..16c97990f 100644 --- a/datm/datm_datamode_gefs_mod.F90 +++ b/datm/datm_datamode_gefs_mod.F90 @@ -240,18 +240,18 @@ subroutine datm_datamode_gefs_restart_write(case_name, inst_suffix, ymd, tod, & end subroutine datm_datamode_gefs_restart_write !=============================================================================== - subroutine datm_datamode_gefs_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - + subroutine datm_datamode_gefs_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) + use ESMF, only : ESMF_GridComp ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) end subroutine datm_datamode_gefs_restart_read diff --git a/datm/datm_datamode_jra_mod.F90 b/datm/datm_datamode_jra_mod.F90 index 9eb815150..43bc3c2f9 100644 --- a/datm/datm_datamode_jra_mod.F90 +++ b/datm/datm_datamode_jra_mod.F90 @@ -1,7 +1,7 @@ module datm_datamode_jra_mod use ESMF , only : ESMF_State, ESMF_StateGet, ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO - use ESMF , only : ESMF_MeshGet + use ESMF , only : ESMF_MeshGet, ESMF_GridComp use ESMF , only : ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND, operator(/=) use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -323,18 +323,18 @@ subroutine datm_datamode_jra_restart_write(case_name, inst_suffix, ymd, tod, & end subroutine datm_datamode_jra_restart_write !=============================================================================== - subroutine datm_datamode_jra_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + subroutine datm_datamode_jra_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) end subroutine datm_datamode_jra_restart_read diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 index ca978c153..c614f0465 100644 --- a/datm/datm_datamode_simple_mod.F90 +++ b/datm/datm_datamode_simple_mod.F90 @@ -361,18 +361,18 @@ subroutine datm_datamode_simple_restart_write(case_name, inst_suffix, ymd, tod, end subroutine datm_datamode_simple_restart_write !=============================================================================== - subroutine datm_datamode_simple_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - + subroutine datm_datamode_simple_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) + use ESMF, only : ESMF_GridComp ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) end subroutine datm_datamode_simple_restart_read diff --git a/dice/dice_datamode_ssmi_mod.F90 b/dice/dice_datamode_ssmi_mod.F90 index 6f15fc9c7..1196c8316 100644 --- a/dice/dice_datamode_ssmi_mod.F90 +++ b/dice/dice_datamode_ssmi_mod.F90 @@ -2,7 +2,7 @@ module dice_datamode_ssmi_mod use ESMF , only : ESMF_State, ESMF_LogWrite, ESMF_Array, ESMF_MeshGet use ESMF , only : ESMF_SUCCESS, ESMF_LOGMSG_INFO, ESMF_DistGrid - use ESMF , only : ESMF_ArrayCreate, ESMF_ArrayDestroy + use ESMF , only : ESMF_ArrayCreate, ESMF_ArrayDestroy, ESMF_GridComp use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort @@ -586,9 +586,10 @@ subroutine dice_datamode_ssmi_restart_write(case_name, inst_suffix, ymd, tod, & end subroutine dice_datamode_ssmi_restart_write !=============================================================================== - subroutine dice_datamode_ssmi_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - + subroutine dice_datamode_ssmi_restart_read(gcomp, rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + use nuopc_shr_methods, only : shr_get_rpointer_name ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit @@ -601,7 +602,7 @@ subroutine dice_datamode_ssmi_restart_read(rest_filem, inst_suffix, logunit, my_ allocate(water(sdat%model_lsize)) ! read restart - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat, & + call dshr_restart_read(gcomp, rest_filem, 'ice', nullstr, logunit, my_task, mpicom, sdat, & fld=water, fldname='water') end subroutine dice_datamode_ssmi_restart_read diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index 63539e812..c5a44a48c 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -450,7 +450,7 @@ subroutine ModelAdvance(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Run dice - call dice_comp_run(importState, exportState, next_ymd, next_tod, cosarg, restart_write, rc) + call dice_comp_run(gcomp, importState, exportState, next_ymd, next_tod, cosarg, restart_write, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit(subname) @@ -458,13 +458,14 @@ subroutine ModelAdvance(gcomp, rc) end subroutine ModelAdvance !=============================================================================== - subroutine dice_comp_run(importstate, exportstate, target_ymd, target_tod, cosarg, restart_write, rc) + subroutine dice_comp_run(gcomp, importstate, exportstate, target_ymd, target_tod, cosarg, restart_write, rc) ! -------------------------- ! advance dice ! -------------------------- ! input/output variables: + type(ESMF_GridComp), intent(in) :: gcomp type(ESMF_State) , intent(inout) :: exportState type(ESMF_State) , intent(inout) :: importState integer , intent(in) :: target_ymd ! model date @@ -504,7 +505,7 @@ subroutine dice_comp_run(importstate, exportstate, target_ymd, target_tod, cosar if (restart_read) then select case (trim(datamode)) case('ssmi', 'ssmi_iaf') - call dice_datamode_ssmi_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call dice_datamode_ssmi_restart_read(gcomp, restfilm, inst_suffix, logunit, my_task, mpicom, sdat) end select end if diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index faa346b68..bfd337039 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -950,17 +950,19 @@ subroutine dshr_time_init( Time, ymd, cal, tod, rc) end subroutine dshr_time_init !=============================================================================== - subroutine dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, & + subroutine dshr_restart_read(gcomp, rest_filem, compname, nullstr, & logunit, my_task, mpicom, sdat, fld, fldname) ! Read restart file use dshr_stream_mod, only : shr_stream_restIO use ESMF, only : ESMF_VMGetCurrent + use nuopc_shr_methods, only: shr_get_rpointer_name + ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: rpfile - character(len=*) , intent(in) :: inst_suffix + character(len=*) , intent(in) :: compname character(len=*) , intent(in) :: nullstr integer , intent(in) :: logunit integer , intent(in) :: my_task @@ -970,6 +972,7 @@ subroutine dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, & character(len=*) , optional , intent(in) :: fldname ! local variables + character(len=ESMF_MAXSTR) :: rpfile type(ESMF_VM) :: vm integer :: nu logical :: exists ! file existance @@ -990,13 +993,11 @@ subroutine dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, & exists = .false. if (trim(rest_filem) == trim(nullstr)) then if (my_task == main_task) then + call shr_get_rpointer_name(gcomp, compname, rpfile, 'read', rc) + write(logunit,F00) ' restart filename from rpointer' - inquire(file=trim(rpfile)//trim(inst_suffix), exist=exists) - if (.not.exists) then - write(logunit, F00) ' ERROR: rpointer file does not exist' - call shr_sys_abort(trim(subname)//' ERROR: rpointer file missing') - endif - open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') + + open(newunit=nu, file=trim(rpfile), form='formatted') read(nu, '(a)') rest_filem close(nu) inquire(file=trim(rest_filem), exist=exists) From 78f7c21ad145d3169fb6a5672d32368d24e756f8 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Sat, 31 Aug 2024 14:50:41 -0600 Subject: [PATCH 136/170] add new JRA 1.5 streams for datm and drof --- datm/cime_config/config_component.xml | 6 +- datm/cime_config/namelist_definition_datm.xml | 3 + datm/cime_config/stream_definition_datm.xml | 267 +++++++++++++++++- drof/cime_config/config_component.xml | 6 +- drof/cime_config/namelist_definition_drof.xml | 1 + drof/cime_config/stream_definition_drof.xml | 32 +++ 6 files changed, 304 insertions(+), 11 deletions(-) diff --git a/datm/cime_config/config_component.xml b/datm/cime_config/config_component.xml index e0a04797d..bf02b6c71 100644 --- a/datm/cime_config/config_component.xml +++ b/datm/cime_config/config_component.xml @@ -10,7 +10,7 @@ This file may have atm desc entries. --> - Data driven ATM + Data driven ATM QIAN data set QIAN with water isotopes CRUNCEP data set @@ -23,6 +23,7 @@ COREv2 interannual forcing interannual JRA55 forcing interannual JRA55 forcing, v1.4, through 2018 + interannual JRA55 forcing, v1.5, through 2018 JRA55 Repeat Year Forcing v1.3 1984-1985 JRA55 Repeat Year Forcing v1.3 1990-1991 JRA55 Repeat Year Forcing v1.3 2003-2004 @@ -41,7 +42,7 @@ char - CORE2_NYF,CORE2_IAF,CLM_QIAN,CLM_QIAN_WISO,1PT,CLMCRUNCEP,CLMCRUNCEPv7,CLMGSWP3v1,CLMNLDAS2,CPLHIST,CORE_IAF_JRA,CORE_IAF_JRA_1p4_2018,ERA5,SIMPLE + CORE2_NYF,CORE2_IAF,CLM_QIAN,CLM_QIAN_WISO,1PT,CLMCRUNCEP,CLMCRUNCEPv7,CLMGSWP3v1,CLMNLDAS2,CPLHIST,CORE_IAF_JRA,CORE_IAF_JRA_1p4_2018,CORE_IAF_JRA_1p5_2018,CORE_IAF_JRA_1p5_2018,ERA5,SIMPLE CORE2_NYF run_component_datm env_run.xml @@ -54,6 +55,7 @@ CORE2_IAF CORE_IAF_JRA CORE_IAF_JRA_1p4_2018 + CORE_IAF_JRA_1p5_2018 CLM_QIAN CLM_QIAN_WISO CLMCRUNCEPv7 diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index 491b6f6d1..70ed9b0af 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -52,6 +52,9 @@ CORE_IAF_JRA_1p4_2018.GCGCS.PREC,CORE_IAF_JRA_1p4_2018.GISS.LWDN,CORE_IAF_JRA_1p4_2018.GISS.SWDN,CORE_IAF_JRA_1p4_2018.NCEP.Q_10,CORE_IAF_JRA_1p4_2018.NCEP.SLP_,CORE_IAF_JRA_1p4_2018.NCEP.T_10,CORE_IAF_JRA_1p4_2018.NCEP.U_10,CORE_IAF_JRA_1p4_2018.NCEP.V_10 + + CORE_IAF_JRA_1p5_2018.GCGCS.PREC,CORE_IAF_JRA_1p5_2018.GISS.LWDN,CORE_IAF_JRA_1p5_2018.GISS.SWDN,CORE_IAF_JRA_1p5_2018.NCEP.Q_10,CORE_IAF_JRA_1p5_2018.NCEP.SLP_,CORE_IAF_JRA_1p5_2018.NCEP.T_10,CORE_IAF_JRA_1p5_2018.NCEP.U_10,CORE_IAF_JRA_1p5_2018.NCEP.V_10 + CORE_RYF8485_JRA.GISS.LWDN,CORE_RYF8485_JRA.GISS.SWDN,CORE_RYF8485_JRA.GCGCS,CORE_RYF8485_JRA.NCEP diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 7f38bedad..01bc87419 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -33,13 +33,14 @@ CLMGSWP3v1 = Run with the CLM GSWP3 V1 forcing (force CLM) CLMNLDAS2 = Run with the CLM NLDAS2 regional forcing valid from 1980 to 2018 (force CLM) 1PT = Run with supplied single point data (force CLM) - CORE2_NYF = CORE2 normal year forcing (for forcing POP and CICE) - CORE2_IAF = CORE2 intra-annual year forcing (for forcing POP and CICE) - CORE_IAF_JRA = JRA55 intra-annual year forcing (for forcing POP and CICE) - CORE_IAF_JRA_1p4_2018 = JRA55 intra-annual year forcing, v1.4, through 2018 (for forcing POP and CICE) - CORE_RYF8485_JRA = JRA55 repeat year forcing, v1.3, 1984-1985 (for forcing POP and CICE) - CORE_RYF9091_JRA = JRA55 repeat year forcing, v1.3, 1990-1991 (for forcing POP and CICE) - CORE_RYF0304_JRA = JRA55 repeat year forcing, v1.3, 2003-2004 (for forcing POP and CICE) + CORE2_NYF = CORE2 normal year forcing (for forcing MOM6 and CICE) + CORE2_IAF = CORE2 intra-annual year forcing (for forcing MOM6 and CICE) + CORE_IAF_JRA = JRA55 intra-annual year forcing (for forcing MOM6 and CICE) + CORE_IAF_JRA_1p4_2018 = JRA55 intra-annual year forcing, v1.4, through 2018 (for forcing MOM6 and CICE) + CORE_IAF_JRA_1p5_2018 = JRA55 intra-annual year forcing, v1.5, through 2018 (for forcing MOM6 and CICE + CORE_RYF8485_JRA = JRA55 repeat year forcing, v1.3, 1984-1985 (for forcing MOM6 and CICE) + CORE_RYF9091_JRA = JRA55 repeat year forcing, v1.3, 1990-1991 (for forcing MOM6 and CICE) + CORE_RYF0304_JRA = JRA55 repeat year forcing, v1.3, 2003-2004 (for forcing MOM6 and CICE) ERA5 = ERA5 intra-annual year forcing SIMPLE = Namelist-configurable, constant datm forcing for simple experiments CPLHIST = Streams for lnd or ocn/ice forcing used for spinup @@ -2416,6 +2417,258 @@ single + + + + + + + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.prec.TL319.%y.210504.nc + + + prec Faxa_prec + + null + + bilinear + + null + 1 + 1958 + 2018 + 0 + + linear + + + cycle + + + 1.5 + + single + + + + + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.lwdn.TL319.%y.210504.nc + + + lwdn Faxa_lwdn + + null + + bilinear + + null + 1 + 1958 + 2018 + 0 + + linear + + + cycle + + + 1.5 + + single + + + + + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.swdn.TL319.%y.210504.nc + + + swdn Faxa_swdn + + null + + bilinear + + null + 1 + 1958 + 2018 + -5400 + + coszen + + + cycle + + + 1.5 + + single + + + + + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.q_10.TL319.%y.210504.nc + + + q_10 Sa_shum + + null + + bilinear + + null + 1 + 1958 + 2018 + 0 + + linear + + + cycle + + + 1.5 + + single + + + + + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.slp.TL319.%y.210504.nc + + + slp Sa_pslv + + null + + bilinear + + null + 1 + 1958 + 2018 + 0 + + linear + + + cycle + + + 1.5 + + single + + + + + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.t_10.TL319.%y.210504.nc + + + t_10 Sa_tbot + + null + + bilinear + + null + 1 + 1958 + 2018 + 0 + + linear + + + cycle + + + 1.5 + + single + + + + + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.u_10.TL319.%y.210504.nc + + + u_10 Sa_u + + null + + bilinear + + null + 1 + 1958 + 2018 + 0 + + linear + + + cycle + + + 1.5 + + single + + + + + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc + + + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.v_10.TL319.%y.210504.nc + + + v_10 Sa_v + + null + + bilinear + + null + 1 + 1958 + 2018 + 0 + + linear + + + cycle + + + 1.5 + + single + + diff --git a/drof/cime_config/config_component.xml b/drof/cime_config/config_component.xml index c87e1f1c6..c37e71e7e 100644 --- a/drof/cime_config/config_component.xml +++ b/drof/cime_config/config_component.xml @@ -13,7 +13,7 @@ --> - Data runoff model + Data runoff model NULL mode COREv2 normal year forcing: COREv2 interannual year forcing: @@ -25,6 +25,7 @@ JRA55 interannual forcing, v1.4, through 2018, no rofi around AIS JRA55 interannual forcing, v1.4, through 2018, no rofl around AIS JRA55 interannual forcing, v1.4, through 2018, no rofi or rofl around AIS + JRA55 interannual forcing, v1.5, through 2018 JRA55 interannual forcing JRA55 Repeat Year Forcing v1.3 1984-1985 JRA55 Repeat Year Forcing v1.3 1990-1991 @@ -42,7 +43,7 @@ char - CPLHIST,DIATREN_ANN_RX1,DIATREN_IAF_RX1,DIATREN_IAF_AIS00_RX1,DIATREN_IAF_AIS45_RX1,DIATREN_IAF_AIS55_RX1,IAF_JRA,IAF_JRA_1p4_2018,IAF_JRA_1p4_2018_AIS0ICE,IAF_JRA_1p4_2018_AIS0LIQ,IAF_JRA_1p4_2018_AIS0ROF,RYF8485_JRA,RYF9091_JRA,RYF0304_JRA,NULL + CPLHIST,DIATREN_ANN_RX1,DIATREN_IAF_RX1,DIATREN_IAF_AIS00_RX1,DIATREN_IAF_AIS45_RX1,DIATREN_IAF_AIS55_RX1,IAF_JRA,IAF_JRA_1p4_2018,IAF_JRA_1p4_2018_AIS0ICE,IAF_JRA_1p4_2018_AIS0LIQ,IAF_JRA_1p4_2018_AIS0ROF,IAF_JRA_1p5_2018,RYF8485_JRA,RYF9091_JRA,RYF0304_JRA,NULL DIATREN_ANN_RX1 NULL @@ -60,6 +61,7 @@ IAF_JRA_1p4_2018_AIS0ICE IAF_JRA_1p4_2018_AIS0LIQ IAF_JRA_1p4_2018_AIS0ROF + IAF_JRA_1p5_2018 RYF8485_JRA RYF9091_JRA RYF0304_JRA diff --git a/drof/cime_config/namelist_definition_drof.xml b/drof/cime_config/namelist_definition_drof.xml index 88a3493bb..71021636e 100644 --- a/drof/cime_config/namelist_definition_drof.xml +++ b/drof/cime_config/namelist_definition_drof.xml @@ -21,6 +21,7 @@ rof.diatren_iaf_ais55_rx1 rof.iaf_jra rof.iaf_jra_1p4_2018 + rof.iaf_jra_1p5_2018 rof.ryf8485_jra rof.ryf9091_jra rof.ryf0304_jra diff --git a/drof/cime_config/stream_definition_drof.xml b/drof/cime_config/stream_definition_drof.xml index d14e5cbbe..9f8b20ff5 100644 --- a/drof/cime_config/stream_definition_drof.xml +++ b/drof/cime_config/stream_definition_drof.xml @@ -475,6 +475,38 @@ single + + + $DIN_LOC_ROOT/lnd/dlnd7/JRA55/JRA.v1.4.runoff.1958_ESMFmesh_cdf5_20201020.nc + + + $DIN_LOC_ROOT/lnd/dlnd7/JRA55/JRA.v1.5.runoff.%y.240411.nc + + + rofl Forr_rofl + rofi Forr_rofi + + null + + bilinear + + null + 1 + 1958 + 2018 + 0 + + upper + + + cycle + + + 3.0 + + single + + $DIN_LOC_ROOT/lnd/dlnd7/JRA55/JRA.v1.4.runoff.1958_ESMFmesh_cdf5_20201020.nc From 99ae4e6b59151f04d240c668b0345ce5fd0fa215 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 2 Sep 2024 16:03:27 +0200 Subject: [PATCH 137/170] add restart functionality for dglc%noevolve --- dglc/dglc_datamode_noevolve_mod.F90 | 259 +++++++++++++++++++++++++--- dglc/glc_comp_nuopc.F90 | 30 +++- 2 files changed, 259 insertions(+), 30 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index d654e6aac..165b1b4c3 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -4,17 +4,22 @@ module dglc_datamode_noevolve_mod use ESMF , only : ESMF_Mesh, ESMF_DistGrid, ESMF_FieldBundle, ESMF_Field use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldCreate, ESMF_MeshLoc_Element use ESMF , only : ESMF_FieldBundleAdd, ESMF_MeshGet, ESMF_DistGridGet, ESMF_Typekind_R8 + use ESMF , only : ESMF_VMGetCurrent, ESMF_VMBroadCast, ESMF_VM use NUOPC , only : NUOPC_Advertise, NUOPC_IsConnected use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort use shr_const_mod , only : SHR_CONST_RHOICE, SHR_CONST_RHOSW, SHR_CONST_REARTH, SHR_CONST_TKFRZ + use shr_const_mod , only : SHR_CONST_SPVAL + use shr_cal_mod , only : shr_cal_datetod2string use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add use dshr_strdata_mod , only : shr_strdata_type use pio , only : file_desc_t, io_desc_t, var_desc_t, iosystem_desc_t use pio , only : pio_openfile, pio_inq_varid, pio_inq_varndims, pio_inq_vardimid use pio , only : pio_inq_dimlen, pio_initdecomp, pio_read_darray, pio_double - use pio , only : pio_closefile, pio_freedecomp, PIO_BCAST_ERROR, PIO_NOWRITE + use pio , only : pio_closefile, pio_freedecomp, PIO_BCAST_ERROR, PIO_NOWRITE, PIO_CLOBBER + use pio , only : pio_createfile, pio_def_dim, pio_def_var, pio_put_att, pio_fill + use pio , only : pio_set_fill, pio_put_att, pio_enddef, pio_write_darray, PIO_GLOBAL use pio , only : pio_seterrorhandling implicit none @@ -23,9 +28,13 @@ module dglc_datamode_noevolve_mod public :: dglc_datamode_noevolve_advertise public :: dglc_datamode_noevolve_init_pointers public :: dglc_datamode_noevolve_advance + public :: dglc_datamode_noevolve_restart_write + public :: dglc_datamode_noevolve_restart_read logical :: initialized_noevolve = .false. integer :: num_icesheets + integer, allocatable :: lsize(:) ! local size for ice sheet + integer, allocatable :: gsize(:) ! global size for ice sheet real(r8) :: thk0 = 1._r8 ! Data structure to enable multiple ice sheets @@ -49,8 +58,6 @@ module dglc_datamode_noevolve_mod ! type(icesheet_ptr_t), allocatable :: So_t(:) ! type(icesheet_ptr_t), allocatable :: So_q(:) - real(r8), allocatable :: usrf(:) ! upper surface elevation (m) on ice grid - ! Export Field names character(len=*), parameter :: field_out_area = 'Sg_area' character(len=*), parameter :: field_out_topo = 'Sg_topo' @@ -65,6 +72,7 @@ module dglc_datamode_noevolve_mod character(len=*), parameter :: field_in_so_t_depth = 'So_t_depth' character(len=*), parameter :: field_in_so_s_depth = 'So_s_depth' + character(*) , parameter :: nullstr = 'null' character(*) , parameter :: rpfile = 'rpointer.glc' character(*) , parameter :: u_FILE_u = & __FILE__ @@ -225,9 +233,9 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & type(ESMF_Field) :: field_noevolve type(file_desc_t) :: pioid type(io_desc_t) :: pio_iodesc - integer :: ns ! ice sheet index - integer :: ng ! grid cell index - integer :: lsize + integer :: ns ! ice sheet index + integer :: ng ! grid cell index + integer :: nelem ! element counter integer, pointer :: gindex(:) ! domain decomposition of data integer :: ndims ! number of dims integer, allocatable :: dimid(:) @@ -237,10 +245,13 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & real(r8), pointer :: topog(:) real(r8), pointer :: thck(:) logical :: exists - real(r8) :: rhoi ! density of ice ~ kg/m^3 - real(r8) :: rhoo ! density of sea water ~ kg/m^3 - real(r8) :: eus ! eustatic sea level - real(r8), allocatable :: lsrf(:) ! lower surface elevation (m) on ice grid + real(r8) :: rhoi ! density of ice ~ kg/m^3 + real(r8) :: rhoo ! density of sea water ~ kg/m^3 + real(r8) :: eus ! eustatic sea level + real(r8), allocatable :: lsrf(:) ! lower surface elevation (m) on ice grid + real(r8), allocatable :: usrf(:) ! upper surface elevation (m) on ice grid + integer :: tileCount + integer, allocatable :: elementCountPTile(:) character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -248,22 +259,39 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (.not. initialized_noevolve) then + ! Allocate module variables + allocate(gsize(num_icesheets)) + allocate(lsize(num_icesheets)) + + ! Loop over ice sheets do ns = 1,num_icesheets - ! Get mesh info + ! Determine lsize(ns) and gindex call ESMF_MeshGet(model_meshes(ns), elementdistGrid=distGrid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) + call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize(ns), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(gindex(lsize)) + allocate(gindex(lsize(ns))) call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Determine gsize(ns) + call ESMF_DistGridGet(distGrid, tileCount=tileCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(elementCountPTile(tileCount)) + call ESMF_distGridGet(distGrid, elementCountPTile=elementCountPTile, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + gsize(ns) = 0 + do nelem = 1,size(elementCountPTile) + gsize(ns) = gsize(ns) + elementCountPTile(nelem) + end do + deallocate(elementCountPTile) + ! Determine "glc_area" ; ! Sg_areas is in radians ! SHR_CONST_REARTH is the radius of earth in m ! model_internal_gridsize is the internal model gridsize in m - do ng = 1,lsize + do ng = 1,lsize(ns) Sg_area(ns)%ptr(ng) = (model_internal_gridsize(ns)/SHR_CONST_REARTH)**2 end do @@ -271,13 +299,15 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & fldbun_noevolve = ESMF_FieldBundleCreate(rc=rc) ! input field bundle ! "ice thickness" ; - field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, & + name='thk', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! "bed topography" ; - field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_noevolve = ESMF_FieldCreate(model_meshes(ns), ESMF_TYPEKIND_R8, & + name='topg', meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldBundleAdd(fldbun_noevolve, (/field_noevolve/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -298,7 +328,6 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & rcode = pio_inq_dimlen(pioid, dimid(2), nyg) call pio_initdecomp(pio_subsystem, pio_double, (/nxg,nyg/), gindex, pio_iodesc) deallocate(dimid) - deallocate(gindex) ! Read in the data into the appropriate field bundle pointers ! Note that Sg_ice_covered(ns)%ptr points into the data for @@ -317,13 +346,13 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & rcode = pio_inq_varid(pioid, 'thk', varid) call pio_read_darray(pioid, varid, pio_iodesc, thck, rcode) - allocate(usrf(lsize)) - allocate(lsrf(lsize)) + allocate(usrf(lsize(ns))) + allocate(lsrf(lsize(ns))) rhoi = SHR_CONST_RHOICE ! 0.917e3 rhoo = SHR_CONST_RHOSW ! 1.026e3 eus = 0 - do ng = 1,lsize + do ng = 1,lsize(ns) if (topog(ng) - eus < (-rhoi/rhoo) * thck(ng)) then lsrf(ng) = (-rhoi/rhoo) * thck(ng) else @@ -361,7 +390,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & end do deallocate(lsrf) - + deallocate(usrf) call pio_closefile(pioid) call pio_freedecomp(pio_subsystem, pio_iodesc) @@ -372,9 +401,8 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (initialized_noevolve) then ! Compute Fgrg_rofi do ns = 1,num_icesheets - lsize = size(Fgrg_rofi(ns)%ptr) - do ng = 1,lsize - if (is_in_active_grid(usrf(ng))) then + do ng = 1,lsize(ns) + if (Sg_icemask_coupled_fluxes(ns)%ptr(ng) > 0.d0) then Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) else Fgrg_rofi(ns)%ptr(ng) = 0._r8 @@ -418,4 +446,187 @@ logical function is_ice_covered(thck) end if end function is_ice_covered + !=============================================================================== + subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & + inst_suffix, ymd, tod, logunit, my_task, main_task, & + pio_subsystem, io_type, nx_global, ny_global, rc) + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes + character(len=*) , intent(in) :: case_name + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: ymd ! model date + integer , intent(in) :: tod ! model sec into model date + integer , intent(in) :: logunit + integer , intent(in) :: my_task + integer , intent(in) :: main_task + type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info + integer , intent(in) :: io_type ! pio info + integer , intent(in) :: nx_global(:) + integer , intent(in) :: ny_global(:) + integer , intent(out) :: rc + + ! local variables + type(ESMF_DistGrid) :: distgrid + integer :: ns + character(len=CS) :: cnum + integer, pointer :: gindex(:) ! domain decomposition of data + integer :: nu + character(len=CL) :: rest_file_model + character(len=CS) :: date_str + type(file_desc_t) :: pioid + integer :: dimid_fld + integer :: dimid2(2) + type(var_desc_t) :: varid + type(io_desc_t) :: pio_iodesc + integer :: oldmode + integer :: rcode + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + do ns = 1,num_icesheets + ! Determine gindex for this ice sheet + call ESMF_MeshGet(model_meshes(ns), elementdistGrid=distGrid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(gindex(lsize(ns))) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Need to explicitly write restart since noevolve mode does not read a stream + write(cnum,'(i0)') ns + + call shr_cal_datetod2string(date_str, ymd, tod) + write(rest_file_model ,"(7a)") trim(case_name),'.','dglc',trim(inst_suffix),'.r.',trim(date_str),'.nc' + + ! write restart info to rpointer file + if (my_task == main_task) then + open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') + write(nu,'(a)') rest_file_model + close(nu) + write(logunit,'(a,2x,i0,2x,i0)')' writing with no streams '//trim(rest_file_model), ymd, tod + endif + + ! write data model restart data + rcode = pio_createfile(pio_subsystem, pioid, io_type, trim(rest_file_model), pio_clobber) + rcode = pio_def_dim(pioid, '_nx'//trim(cnum), nx_global(ns), dimid2(1)) + rcode = pio_def_dim(pioid, '_ny'//trim(cnum), ny_global(ns), dimid2(2)) + rcode = pio_def_var(pioid, 'flgl_rofi'//cnum, PIO_DOUBLE, (/dimid2/), varid) + rcode = pio_put_att(pioid, varid, "_FillValue", shr_const_spval) + rcode = pio_set_fill(pioid, PIO_FILL, oldmode) + rcode = pio_put_att(pioid, pio_global, "version", "nuopc_data_models_v0") + rcode = pio_enddef(pioid) + + call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) + call pio_write_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode, fillval=shr_const_spval) + call pio_closefile(pioid) + call pio_freedecomp(pio_subsystem, pio_iodesc) + + ! Deallocate gindex + deallocate (gindex) + end do + end subroutine dglc_datamode_noevolve_restart_write + + !=============================================================================== + subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & + inst_suffix, logunit, my_task, main_task, mpicom, & + pio_subsystem, io_type, nx_global, ny_global, rc) + + ! input/output arguments + type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes + character(len=*) , intent(inout) :: restfilem + character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: logunit + integer , intent(in) :: my_task + integer , intent(in) :: main_task + integer , intent(in) :: mpicom + type(iosystem_desc_t) , pointer :: pio_subsystem ! pio info + integer , intent(in) :: io_type ! pio info + integer , intent(in) :: nx_global(:) + integer , intent(in) :: ny_global(:) + integer , intent(out) :: rc + + ! local variables + type(ESMF_DistGrid) :: distgrid + integer :: ns + character(len=CS) :: cnum + integer, pointer :: gindex(:) ! domain decomposition of data + type(ESMF_VM) :: vm + integer :: nu + logical :: exists ! file existance + type(file_desc_t) :: pioid + type(var_desc_t) :: varid + type(io_desc_t) :: pio_iodesc + integer :: rcode + integer :: tmp(1) + character(*), parameter :: subName = "(dglc_datamode_noevolve_restart_read) " + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + do ns = 1,num_icesheets + + write(cnum,'(i0)') ns + + ! Determine gindex for this ice sheet + call ESMF_MeshGet(model_meshes(ns), elementdistGrid=distGrid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(gindex(lsize(ns))) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_VMGetCurrent(vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine restart file + exists = .false. + if (trim(restfilem) == trim(nullstr)) then + if (my_task == main_task) then + write(logunit,'(a)') trim(subname)//' restart filename from rpointer' + inquire(file=trim(rpfile)//trim(inst_suffix), exist=exists) + if (.not.exists) then + write(logunit, '(a)') trim(subname)//' ERROR: rpointer file does not exist' + call shr_sys_abort(trim(subname)//' ERROR: rpointer file missing') + endif + open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') + read(nu,'(a)') restfilem + close(nu) + inquire(file=trim(restfilem), exist=exists) + endif + call ESMF_VMBroadCast(vm, restfilem, CL, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + ! use namelist already read + if (my_task == main_task) then + write(logunit, '(a)') trim(subname)//' restart filenames from namelist ' + inquire(file=trim(restfilem), exist=exists) + endif + endif + tmp = 0 + if(exists) tmp=1 + call ESMF_VMBroadCast(vm, tmp, 1, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + exists = (tmp(1) == 1) + + ! Read restart file + if (exists) then + if (my_task == main_task) then + write(logunit, '(a)') trim(subname)//' reading data model restart '//trim(restfilem) + end if + rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(restfilem), pio_nowrite) + call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) + rcode = pio_inq_varid(pioid, 'flgl_rofi'//cnum, varid) + call pio_read_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode) + call pio_closefile(pioid) + call pio_freedecomp(pio_subsystem, pio_iodesc) + else + if (my_task == main_task) then + write(logunit, '(a)') trim(subname)//' file not found, skipping '//trim(restfilem) + end if + endif + + end do ! loop over ice sheets + + end subroutine dglc_datamode_noevolve_restart_read + end module dglc_datamode_noevolve_mod diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index f5b6c2a36..d67b6e58b 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -46,6 +46,8 @@ module cdeps_dglc_comp use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_advertise use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_init_pointers use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_advance + use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_restart_read + use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_restart_write implicit none private ! except @@ -251,7 +253,6 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) end do write(logunit,'(a,a )')' restfilm = ',trim(restfilm) write(logunit,'(a,l6)')' skip_restart_read = ',skip_restart_read - bcasttmp(1) = 0 if(skip_restart_read) bcasttmp(1) = 1 bcasttmp(2) = num_icesheets @@ -464,6 +465,7 @@ subroutine ModelAdvance(gcomp, rc) rc = ESMF_SUCCESS call shr_log_setLogUnit(logunit) + call ESMF_TraceRegionEnter(subname) call memcheck(subname, 5, my_task == main_task) ! query the Component for its clock @@ -496,11 +498,17 @@ subroutine ModelAdvance(gcomp, rc) ! determine if will write restart restart_write = dshr_check_restart_alarm(clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (my_task == main_task) then + write(logunit,'(a,l6)') trim(timestring)//': restart write is ',restart_write + end if ! run dglc call dglc_comp_run(clock, next_ymd, next_tod, restart_write, valid_inputs, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TraceRegionExit(subname) + end subroutine ModelAdvance !=============================================================================== @@ -548,9 +556,12 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inp end select ! Read restart if needed - if (trim(datamode) /= 'noevolve') then - if (restart_read .and. .not. skip_restart_read) then - ! placeholder for future datamodes + if (restart_read .and. .not. skip_restart_read) then + if (restart_read) then + call dglc_datamode_noevolve_restart_read(model_meshes, restfilm, & + inst_suffix, logunit, my_task, main_task, mpicom, & + sdat(1)%pio_subsystem, sdat(1)%io_type, nx_global, ny_global, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if @@ -596,9 +607,16 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inp end select ! Write restarts if needed + if (restart_write) then - if (trim(datamode) /= 'evolve') then - ! this is a place holder for future datamode + if (trim(datamode) == 'noevolve') then + if (my_task == main_task) then + write(logunit,'(a)') 'calling dglc_datamode_noevolve_restart_write' + end if + call dglc_datamode_noevolve_restart_write(model_meshes, case_name, & + inst_suffix, target_ymd, target_tod, logunit, my_task, main_task, & + sdat(1)%pio_subsystem, sdat(1)%io_type, nx_global, ny_global, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if From 7b78b8f5068c4ccc3884af02a029daa82e46dfef Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 2 Sep 2024 19:39:17 +0200 Subject: [PATCH 138/170] got both write and read restarts working --- dglc/dglc_datamode_noevolve_mod.F90 | 87 ++++++++++++++--------------- dglc/glc_comp_nuopc.F90 | 16 +++--- 2 files changed, 48 insertions(+), 55 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 165b1b4c3..65fe3e59a 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -33,8 +33,6 @@ module dglc_datamode_noevolve_mod logical :: initialized_noevolve = .false. integer :: num_icesheets - integer, allocatable :: lsize(:) ! local size for ice sheet - integer, allocatable :: gsize(:) ! global size for ice sheet real(r8) :: thk0 = 1._r8 ! Data structure to enable multiple ice sheets @@ -175,17 +173,23 @@ subroutine dglc_datamode_noevolve_init_pointers(NStateExp, NstateImp, rc) allocate(Fgrg_rofi(num_icesheets)) do ns = 1,num_icesheets - call dshr_state_getfldptr(NStateExp(ns), field_out_area, fldptr1=Sg_area(ns)%ptr, rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_area, & + fldptr1=Sg_area(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), field_out_topo, fldptr1=Sg_topo(ns)%ptr, rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_topo, & + fldptr1=Sg_topo(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), field_out_ice_covered, fldptr1=Sg_ice_covered(ns)%ptr, rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_ice_covered, & + fldptr1=Sg_ice_covered(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), field_out_icemask, fldptr1=Sg_icemask(ns)%ptr, rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_icemask, & + fldptr1=Sg_icemask(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), field_out_icemask_coupled_fluxes, fldptr1=Sg_icemask_coupled_fluxes(ns)%ptr, rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_icemask_coupled_fluxes, & + fldptr1=Sg_icemask_coupled_fluxes(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call dshr_state_getfldptr(NStateExp(ns), field_out_rofi, fldptr1=Fgrg_rofi(ns)%ptr, rc=rc) + call dshr_state_getfldptr(NStateExp(ns), field_out_rofi, & + fldptr1=Fgrg_rofi(ns)%ptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return Fgrg_rofi(ns)%ptr(:) = 0._r8 @@ -236,6 +240,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & integer :: ns ! ice sheet index integer :: ng ! grid cell index integer :: nelem ! element counter + integer :: lsize ! local size integer, pointer :: gindex(:) ! domain decomposition of data integer :: ndims ! number of dims integer, allocatable :: dimid(:) @@ -248,10 +253,8 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & real(r8) :: rhoi ! density of ice ~ kg/m^3 real(r8) :: rhoo ! density of sea water ~ kg/m^3 real(r8) :: eus ! eustatic sea level - real(r8), allocatable :: lsrf(:) ! lower surface elevation (m) on ice grid - real(r8), allocatable :: usrf(:) ! upper surface elevation (m) on ice grid - integer :: tileCount - integer, allocatable :: elementCountPTile(:) + real(r8) :: lsrf ! lower surface elevation (m) on ice grid + real(r8) :: usrf ! upper surface elevation (m) on ice grid character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -259,39 +262,23 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (.not. initialized_noevolve) then - ! Allocate module variables - allocate(gsize(num_icesheets)) - allocate(lsize(num_icesheets)) - ! Loop over ice sheets do ns = 1,num_icesheets - ! Determine lsize(ns) and gindex + ! Determine lsize and gindex call ESMF_MeshGet(model_meshes(ns), elementdistGrid=distGrid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize(ns), rc=rc) + call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(gindex(lsize(ns))) + allocate(gindex(lsize)) call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine gsize(ns) - call ESMF_DistGridGet(distGrid, tileCount=tileCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(elementCountPTile(tileCount)) - call ESMF_distGridGet(distGrid, elementCountPTile=elementCountPTile, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - gsize(ns) = 0 - do nelem = 1,size(elementCountPTile) - gsize(ns) = gsize(ns) + elementCountPTile(nelem) - end do - deallocate(elementCountPTile) - ! Determine "glc_area" ; ! Sg_areas is in radians ! SHR_CONST_REARTH is the radius of earth in m ! model_internal_gridsize is the internal model gridsize in m - do ng = 1,lsize(ns) + do ng = 1,lsize Sg_area(ns)%ptr(ng) = (model_internal_gridsize(ns)/SHR_CONST_REARTH)**2 end do @@ -346,19 +333,16 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & rcode = pio_inq_varid(pioid, 'thk', varid) call pio_read_darray(pioid, varid, pio_iodesc, thck, rcode) - allocate(usrf(lsize(ns))) - allocate(lsrf(lsize(ns))) - rhoi = SHR_CONST_RHOICE ! 0.917e3 rhoo = SHR_CONST_RHOSW ! 1.026e3 eus = 0 - do ng = 1,lsize(ns) + do ng = 1,lsize if (topog(ng) - eus < (-rhoi/rhoo) * thck(ng)) then - lsrf(ng) = (-rhoi/rhoo) * thck(ng) + lsrf = (-rhoi/rhoo) * thck(ng) else - lsrf(ng) = topog(ng) + lsrf = topog(ng) end if - usrf(ng) = max(0.d0, thck(ng) + lsrf(ng)) + usrf = max(0.d0, thck(ng) + lsrf) ! The export field 'ice_mask_coupled_fluxes' determines who is handling the ! runoff associated with the surface mass balance @@ -366,7 +350,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & ! Since we want dglc to handle it no evolve mode - then ! ice_mask_coupled_fluxes to be identical to the mask - if (is_in_active_grid(usrf(ng))) then + if (is_in_active_grid(usrf)) then Sg_icemask(ns)%ptr(ng) = 1.d0 Sg_icemask_coupled_fluxes(ns)%ptr(ng) = 1.d0 if (is_ice_covered(thck(ng))) then @@ -377,7 +361,7 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & ! Note that we use the same method for computing topo whether this point is ! ice-covered or ice-free. This is in contrast to the method for computing ! ice-free topo in glint_upscaling_gcm. - Sg_topo(ns)%ptr(ng) = thk0 * usrf(ng) + Sg_topo(ns)%ptr(ng) = thk0 * usrf else ! Note that this logic implies that if (in theory) we had an ice-covered ! point outside the "active grid", it will get classified as ice-free for @@ -389,8 +373,6 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & end if end do - deallocate(lsrf) - deallocate(usrf) call pio_closefile(pioid) call pio_freedecomp(pio_subsystem, pio_iodesc) @@ -401,7 +383,11 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & if (initialized_noevolve) then ! Compute Fgrg_rofi do ns = 1,num_icesheets - do ng = 1,lsize(ns) + call ESMF_MeshGet(model_meshes(ns), 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 + do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng) > 0.d0) then Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) else @@ -470,6 +456,7 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & type(ESMF_DistGrid) :: distgrid integer :: ns character(len=CS) :: cnum + integer :: lsize integer, pointer :: gindex(:) ! domain decomposition of data integer :: nu character(len=CL) :: rest_file_model @@ -489,7 +476,9 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & ! Determine gindex for this ice sheet call ESMF_MeshGet(model_meshes(ns), elementdistGrid=distGrid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(gindex(lsize(ns))) + call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(gindex(lsize)) call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -550,6 +539,7 @@ subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & type(ESMF_DistGrid) :: distgrid integer :: ns character(len=CS) :: cnum + integer :: lsize integer, pointer :: gindex(:) ! domain decomposition of data type(ESMF_VM) :: vm integer :: nu @@ -571,7 +561,9 @@ subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & ! Determine gindex for this ice sheet call ESMF_MeshGet(model_meshes(ns), elementdistGrid=distGrid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(gindex(lsize(ns))) + call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(gindex(lsize)) call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -625,6 +617,9 @@ subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & end if endif + ! Deallocate gindex + deallocate(gindex) + end do ! loop over ice sheets end subroutine dglc_datamode_noevolve_restart_read diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index d67b6e58b..b74e56f7c 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -332,7 +332,6 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) character(CL) :: cvalue character(CS) :: cns logical :: ispresent, isset - logical :: read_restart logical :: exists character(len=*), parameter :: subname=trim(module_name)//':(InitializeRealize) ' !------------------------------------------------------------------------------- @@ -357,11 +356,11 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) mainproc = (my_task == main_task) call shr_log_setLogUnit(logunit) - ! Set restart flag + ! Set restart flag (sets module variable restart_read) call NUOPC_CompAttributeGet(gcomp, name='read_restart', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then - read(cvalue,*) read_restart + read(cvalue,*) restart_read else call shr_sys_abort(subname//' ERROR: read restart flag must be present') end if @@ -557,12 +556,11 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inp ! Read restart if needed if (restart_read .and. .not. skip_restart_read) then - if (restart_read) then - call dglc_datamode_noevolve_restart_read(model_meshes, restfilm, & - inst_suffix, logunit, my_task, main_task, mpicom, & - sdat(1)%pio_subsystem, sdat(1)%io_type, nx_global, ny_global, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + write(logunit,'(a)')' DEBUG: calling dglc_datamode_noevolve_restart_read' + call dglc_datamode_noevolve_restart_read(model_meshes, restfilm, & + inst_suffix, logunit, my_task, main_task, mpicom, & + sdat(1)%pio_subsystem, sdat(1)%io_type, nx_global, ny_global, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if ! Reset first_time From b2ded394ff199af4b8a760b30f49b55eeeffc72b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 3 Sep 2024 14:15:20 +0200 Subject: [PATCH 139/170] fixed problems in github CI --- dglc/dglc_datamode_noevolve_mod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 65fe3e59a..0c5dd8bda 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -239,7 +239,6 @@ subroutine dglc_datamode_noevolve_advance(pio_subsystem, io_type, io_format, & type(io_desc_t) :: pio_iodesc integer :: ns ! ice sheet index integer :: ng ! grid cell index - integer :: nelem ! element counter integer :: lsize ! local size integer, pointer :: gindex(:) ! domain decomposition of data integer :: ndims ! number of dims @@ -462,7 +461,6 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & character(len=CL) :: rest_file_model character(len=CS) :: date_str type(file_desc_t) :: pioid - integer :: dimid_fld integer :: dimid2(2) type(var_desc_t) :: varid type(io_desc_t) :: pio_iodesc From 5251638b4d8b9d290b97b282b064f59f1fc7f42d Mon Sep 17 00:00:00 2001 From: Katetc Date: Tue, 3 Sep 2024 17:02:51 -0600 Subject: [PATCH 140/170] Removed second area weighting and second if clause to make sure the 0-0 case is handled correctly --- dglc/dglc_datamode_noevolve_mod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index d544ac8ac..3c18f36cd 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -436,9 +436,9 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then if(Flgl_qice(ns)%ptr(ng) > 0.d0) then - rat = Flgl_qice(ns)%ptr(ng)*Sg_area(ns)%ptr(ng)/Tot_pos_smb(1) + rat = Flgl_qice(ns)%ptr(ng)/Tot_pos_smb(1) Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_neg_smb(1) - else if (Flgl_qice(ns)%ptr(ng) < 0.d0) then + else Fgrg_rofi(ns)%ptr(ng) = 0.d0 end if else @@ -453,9 +453,9 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form do ng = 1,lsize if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then if(Flgl_qice(ns)%ptr(ng) < 0.d0) then - rat = Flgl_qice(ns)%ptr(ng)*Sg_area(ns)%ptr(ng)/Tot_neg_smb(1) + rat = Flgl_qice(ns)%ptr(ng)/Tot_neg_smb(1) Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_pos_smb(1) - else if (Flgl_qice(ns)%ptr(ng) > 0.d0) then + else Fgrg_rofi(ns)%ptr(ng) = 0.d0 end if else From 9d057d7878a75cc48aa0fe77e642543fa615330f Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 3 Sep 2024 21:45:48 -0600 Subject: [PATCH 141/170] fix issues in refactor --- dglc/dglc_datamode_noevolve_mod.F90 | 146 ++++++++++++++-------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 0c5dd8bda..75d3b4669 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -469,49 +469,51 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & !------------------------------------------------------------------------------- rc = ESMF_SUCCESS - + call shr_cal_datetod2string(date_str, ymd, tod) + write(rest_file_model ,"(7a)") trim(case_name),'.','dglc',trim(inst_suffix),'.r.',trim(date_str),'.nc' + ! write restart info to rpointer file + if (my_task == main_task) then + open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') + write(nu,'(a)') rest_file_model + close(nu) + write(logunit,'(a,2x,i0,2x,i0)')' writing with no streams '//trim(rest_file_model), ymd, tod + endif + + ! write data model restart data + rcode = pio_createfile(pio_subsystem, pioid, io_type, trim(rest_file_model), pio_clobber) + do ns = 1,num_icesheets - ! Determine gindex for this ice sheet - call ESMF_MeshGet(model_meshes(ns), 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(gindex(lsize)) - call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Need to explicitly write restart since noevolve mode does not read a stream write(cnum,'(i0)') ns - call shr_cal_datetod2string(date_str, ymd, tod) - write(rest_file_model ,"(7a)") trim(case_name),'.','dglc',trim(inst_suffix),'.r.',trim(date_str),'.nc' - - ! write restart info to rpointer file - if (my_task == main_task) then - open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') - write(nu,'(a)') rest_file_model - close(nu) - write(logunit,'(a,2x,i0,2x,i0)')' writing with no streams '//trim(rest_file_model), ymd, tod - endif - - ! write data model restart data - rcode = pio_createfile(pio_subsystem, pioid, io_type, trim(rest_file_model), pio_clobber) rcode = pio_def_dim(pioid, '_nx'//trim(cnum), nx_global(ns), dimid2(1)) rcode = pio_def_dim(pioid, '_ny'//trim(cnum), ny_global(ns), dimid2(2)) rcode = pio_def_var(pioid, 'flgl_rofi'//cnum, PIO_DOUBLE, (/dimid2/), varid) rcode = pio_put_att(pioid, varid, "_FillValue", shr_const_spval) rcode = pio_set_fill(pioid, PIO_FILL, oldmode) rcode = pio_put_att(pioid, pio_global, "version", "nuopc_data_models_v0") - rcode = pio_enddef(pioid) + enddo + rcode = pio_enddef(pioid) + do ns = 1,num_icesheets + + ! Determine gindex for this ice sheet + call ESMF_MeshGet(model_meshes(ns), 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(gindex(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) call pio_write_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode, fillval=shr_const_spval) - call pio_closefile(pioid) call pio_freedecomp(pio_subsystem, pio_iodesc) ! Deallocate gindex deallocate (gindex) end do + call pio_closefile(pioid) end subroutine dglc_datamode_noevolve_restart_write !=============================================================================== @@ -551,7 +553,48 @@ subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & !------------------------------------------------------------------------------- rc = ESMF_SUCCESS + ! Determine restart file + + if (trim(restfilem) == trim(nullstr)) then + exists = .false. + call ESMF_VMGetCurrent(vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (my_task == main_task) then + write(logunit,'(a)') trim(subname)//' restart filename from rpointer' + inquire(file=trim(rpfile)//trim(inst_suffix), exist=exists) + if (.not.exists) then + write(logunit, '(a)') trim(subname)//' ERROR: rpointer file does not exist' + call shr_sys_abort(trim(subname)//' ERROR: rpointer file missing') + endif + open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') + read(nu,'(a)') restfilem + close(nu) + inquire(file=trim(restfilem), exist=exists) + endif + call ESMF_VMBroadCast(vm, restfilem, CL, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + ! use namelist already read + if (my_task == main_task) then + write(logunit, '(a)') trim(subname)//' restart filenames from namelist ' + inquire(file=trim(restfilem), exist=exists) + endif + endif + tmp = 0 + if(exists) tmp=1 + exists = (tmp(1) == 1) + if (.not. exists .and. my_task == main_task) then + write(logunit, '(a)') trim(subname)//' file not found, skipping '//trim(restfilem) + return + end if + + ! Read restart file + if (my_task == main_task) then + write(logunit, '(a)') trim(subname)//' reading data model restart '//trim(restfilem) + end if + + rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(restfilem), pio_nowrite) do ns = 1,num_icesheets write(cnum,'(i0)') ns @@ -565,60 +608,17 @@ subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMGetCurrent(vm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine restart file - exists = .false. - if (trim(restfilem) == trim(nullstr)) then - if (my_task == main_task) then - write(logunit,'(a)') trim(subname)//' restart filename from rpointer' - inquire(file=trim(rpfile)//trim(inst_suffix), exist=exists) - if (.not.exists) then - write(logunit, '(a)') trim(subname)//' ERROR: rpointer file does not exist' - call shr_sys_abort(trim(subname)//' ERROR: rpointer file missing') - endif - open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') - read(nu,'(a)') restfilem - close(nu) - inquire(file=trim(restfilem), exist=exists) - endif - call ESMF_VMBroadCast(vm, restfilem, CL, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - ! use namelist already read - if (my_task == main_task) then - write(logunit, '(a)') trim(subname)//' restart filenames from namelist ' - inquire(file=trim(restfilem), exist=exists) - endif - endif - tmp = 0 - if(exists) tmp=1 - call ESMF_VMBroadCast(vm, tmp, 1, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - exists = (tmp(1) == 1) - - ! Read restart file - if (exists) then - if (my_task == main_task) then - write(logunit, '(a)') trim(subname)//' reading data model restart '//trim(restfilem) - end if - rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(restfilem), pio_nowrite) - call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) - rcode = pio_inq_varid(pioid, 'flgl_rofi'//cnum, varid) - call pio_read_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode) - call pio_closefile(pioid) - call pio_freedecomp(pio_subsystem, pio_iodesc) - else - if (my_task == main_task) then - write(logunit, '(a)') trim(subname)//' file not found, skipping '//trim(restfilem) - end if - endif + call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) + rcode = pio_inq_varid(pioid, 'flgl_rofi'//cnum, varid) + call pio_read_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode) + call pio_freedecomp(pio_subsystem, pio_iodesc) ! Deallocate gindex deallocate(gindex) end do ! loop over ice sheets + call pio_closefile(pioid) end subroutine dglc_datamode_noevolve_restart_read From e982ef215b10159256bcbbcc6c93cdaafdab191a Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 4 Sep 2024 06:57:57 -0600 Subject: [PATCH 142/170] fix varid in write --- dglc/dglc_datamode_noevolve_mod.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 75d3b4669..c083a911b 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -462,7 +462,7 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & character(len=CS) :: date_str type(file_desc_t) :: pioid integer :: dimid2(2) - type(var_desc_t) :: varid + type(var_desc_t), allocatable :: varid(:) type(io_desc_t) :: pio_iodesc integer :: oldmode integer :: rcode @@ -481,15 +481,15 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & ! write data model restart data rcode = pio_createfile(pio_subsystem, pioid, io_type, trim(rest_file_model), pio_clobber) - + allocate(varid(num_icesheets)) do ns = 1,num_icesheets ! Need to explicitly write restart since noevolve mode does not read a stream write(cnum,'(i0)') ns rcode = pio_def_dim(pioid, '_nx'//trim(cnum), nx_global(ns), dimid2(1)) rcode = pio_def_dim(pioid, '_ny'//trim(cnum), ny_global(ns), dimid2(2)) - rcode = pio_def_var(pioid, 'flgl_rofi'//cnum, PIO_DOUBLE, (/dimid2/), varid) - rcode = pio_put_att(pioid, varid, "_FillValue", shr_const_spval) + rcode = pio_def_var(pioid, 'flgl_rofi'//cnum, PIO_DOUBLE, (/dimid2/), varid(ns)) + rcode = pio_put_att(pioid, varid(ns), "_FillValue", shr_const_spval) rcode = pio_set_fill(pioid, PIO_FILL, oldmode) rcode = pio_put_att(pioid, pio_global, "version", "nuopc_data_models_v0") enddo @@ -507,7 +507,7 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & if (ChkErr(rc,__LINE__,u_FILE_u)) return call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) - call pio_write_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode, fillval=shr_const_spval) + call pio_write_darray(pioid, varid(ns), pio_iodesc, Fgrg_rofi(ns)%ptr, rcode, fillval=shr_const_spval) call pio_freedecomp(pio_subsystem, pio_iodesc) ! Deallocate gindex From 276e2a1617d1867087e85f6429522beba05be44d Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 4 Sep 2024 07:36:53 -0600 Subject: [PATCH 143/170] reorder iodesc destroy --- dglc/dglc_datamode_noevolve_mod.F90 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index c083a911b..3393ea215 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -463,7 +463,7 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & type(file_desc_t) :: pioid integer :: dimid2(2) type(var_desc_t), allocatable :: varid(:) - type(io_desc_t) :: pio_iodesc + type(io_desc_t), allocatable :: pio_iodesc(:) integer :: oldmode integer :: rcode !------------------------------------------------------------------------------- @@ -494,7 +494,7 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & rcode = pio_put_att(pioid, pio_global, "version", "nuopc_data_models_v0") enddo rcode = pio_enddef(pioid) - + allocate(pio_iodesc(num_icesheets)) do ns = 1,num_icesheets ! Determine gindex for this ice sheet @@ -505,16 +505,18 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & allocate(gindex(lsize)) call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc(ns)) + call pio_write_darray(pioid, varid(ns), pio_iodesc(ns), Fgrg_rofi(ns)%ptr, rcode, fillval=shr_const_spval) - call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) - call pio_write_darray(pioid, varid(ns), pio_iodesc, Fgrg_rofi(ns)%ptr, rcode, fillval=shr_const_spval) - call pio_freedecomp(pio_subsystem, pio_iodesc) - ! Deallocate gindex deallocate (gindex) end do call pio_closefile(pioid) - end subroutine dglc_datamode_noevolve_restart_write + do ns = 1,num_icesheets + call pio_freedecomp(pio_subsystem, pio_iodesc(ns)) + enddo + + end subroutine dglc_datamode_noevolve_restart_write !=============================================================================== subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & From 7cdf9a54fa75388d04a02bb5b5a237aae4ed5030 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 4 Sep 2024 09:29:59 -0600 Subject: [PATCH 144/170] modify restart read --- dglc/dglc_datamode_noevolve_mod.F90 | 102 ++++++++++++------------ dglc/glc_comp_nuopc.F90 | 11 +-- dice/ice_comp_nuopc.F90 | 2 +- dlnd/lnd_comp_nuopc.F90 | 2 +- docn/docn_datamode_copyall_mod.F90 | 7 +- docn/docn_datamode_cplhist_mod.F90 | 7 +- docn/docn_datamode_iaf_mod.F90 | 8 +- docn/docn_datamode_multilev_dom_mod.F90 | 8 +- docn/docn_datamode_multilev_mod.F90 | 7 +- docn/docn_datamode_som_mod.F90 | 10 +-- docn/ocn_comp_nuopc.F90 | 13 +-- drof/rof_comp_nuopc.F90 | 9 ++- dshr/dshr_mod.F90 | 1 + dwav/wav_comp_nuopc.F90 | 2 +- 14 files changed, 97 insertions(+), 92 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 0c5dd8bda..566a01018 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -4,7 +4,7 @@ module dglc_datamode_noevolve_mod use ESMF , only : ESMF_Mesh, ESMF_DistGrid, ESMF_FieldBundle, ESMF_Field use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldCreate, ESMF_MeshLoc_Element use ESMF , only : ESMF_FieldBundleAdd, ESMF_MeshGet, ESMF_DistGridGet, ESMF_Typekind_R8 - use ESMF , only : ESMF_VMGetCurrent, ESMF_VMBroadCast, ESMF_VM + use ESMF , only : ESMF_VMGetCurrent, ESMF_VMBroadCast, ESMF_VM, ESMF_GridComp use NUOPC , only : NUOPC_Advertise, NUOPC_IsConnected use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort @@ -515,14 +515,14 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & end subroutine dglc_datamode_noevolve_restart_write !=============================================================================== - subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & - inst_suffix, logunit, my_task, main_task, mpicom, & + subroutine dglc_datamode_noevolve_restart_read(gcomp, model_meshes, restfilem, & + logunit, my_task, main_task, mpicom, & pio_subsystem, io_type, nx_global, ny_global, rc) - + use nuopc_shr_methods, only : shr_get_rpointer_name ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes character(len=*) , intent(inout) :: restfilem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: main_task @@ -537,6 +537,7 @@ subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & type(ESMF_DistGrid) :: distgrid integer :: ns character(len=CS) :: cnum + character(len=CS) :: rpfile integer :: lsize integer, pointer :: gindex(:) ! domain decomposition of data type(ESMF_VM) :: vm @@ -551,6 +552,41 @@ subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & !------------------------------------------------------------------------------- rc = ESMF_SUCCESS + ! Determine restart file + exists = .false. + if (trim(restfilem) == trim(nullstr)) then + if (my_task == main_task) then + call shr_get_rpointer_name(gcomp, 'glc', rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + write(logunit,'(a)') trim(subname)//' restart filename from rpointer' + open(newunit=nu, file=trim(rpfile), form='formatted') + read(nu,'(a)') restfilem + close(nu) + inquire(file=trim(restfilem), exist=exists) + endif + call ESMF_VMBroadCast(vm, restfilem, CL, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + ! use namelist already read + if (my_task == main_task) then + write(logunit, '(a)') trim(subname)//' restart filenames from namelist ' + inquire(file=trim(restfilem), exist=exists) + endif + endif + call ESMF_VMGetCurrent(vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + tmp = 0 + if(exists) tmp=1 + call ESMF_VMBroadCast(vm, tmp, 1, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + exists = (tmp(1) == 1) + if (.not. exists .and. my_task == main_task) then + write(logunit, '(a)') trim(subname)//' file not found, skipping '//trim(restfilem) + ! Should we return here or just abort? + return + end if + do ns = 1,num_icesheets @@ -565,55 +601,17 @@ subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, & call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMGetCurrent(vm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Determine restart file - exists = .false. - if (trim(restfilem) == trim(nullstr)) then - if (my_task == main_task) then - write(logunit,'(a)') trim(subname)//' restart filename from rpointer' - inquire(file=trim(rpfile)//trim(inst_suffix), exist=exists) - if (.not.exists) then - write(logunit, '(a)') trim(subname)//' ERROR: rpointer file does not exist' - call shr_sys_abort(trim(subname)//' ERROR: rpointer file missing') - endif - open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') - read(nu,'(a)') restfilem - close(nu) - inquire(file=trim(restfilem), exist=exists) - endif - call ESMF_VMBroadCast(vm, restfilem, CL, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - ! use namelist already read - if (my_task == main_task) then - write(logunit, '(a)') trim(subname)//' restart filenames from namelist ' - inquire(file=trim(restfilem), exist=exists) - endif - endif - tmp = 0 - if(exists) tmp=1 - call ESMF_VMBroadCast(vm, tmp, 1, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - exists = (tmp(1) == 1) ! Read restart file - if (exists) then - if (my_task == main_task) then - write(logunit, '(a)') trim(subname)//' reading data model restart '//trim(restfilem) - end if - rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(restfilem), pio_nowrite) - call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) - rcode = pio_inq_varid(pioid, 'flgl_rofi'//cnum, varid) - call pio_read_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode) - call pio_closefile(pioid) - call pio_freedecomp(pio_subsystem, pio_iodesc) - else - if (my_task == main_task) then - write(logunit, '(a)') trim(subname)//' file not found, skipping '//trim(restfilem) - end if - endif + if (my_task == main_task) then + write(logunit, '(a)') trim(subname)//' reading data model restart '//trim(restfilem) + end if + rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(restfilem), pio_nowrite) + call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) + rcode = pio_inq_varid(pioid, 'flgl_rofi'//cnum, varid) + call pio_read_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode) + call pio_closefile(pioid) + call pio_freedecomp(pio_subsystem, pio_iodesc) ! Deallocate gindex deallocate(gindex) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index b74e56f7c..3099ee9d2 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -430,7 +430,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) end do ! end loop over ice sheets ! Run dglc - call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., valid_inputs=.true., rc=rc) + call dglc_comp_run(gcomp, clock, current_ymd, current_tod, restart_write=.false., valid_inputs=.true., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('dglc_strdata_init') @@ -503,7 +503,7 @@ subroutine ModelAdvance(gcomp, rc) end if ! run dglc - call dglc_comp_run(clock, next_ymd, next_tod, restart_write, valid_inputs, rc=rc) + call dglc_comp_run(gcomp, clock, next_ymd, next_tod, restart_write, valid_inputs, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit(subname) @@ -511,13 +511,14 @@ subroutine ModelAdvance(gcomp, rc) end subroutine ModelAdvance !=============================================================================== - subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inputs, rc) + subroutine dglc_comp_run(gcomp, clock, target_ymd, target_tod, restart_write, valid_inputs, rc) ! -------------------------- ! advance dglc ! -------------------------- ! input/output variables: + type(ESMF_GridComp) ,intent(in) :: gcomp type(ESMF_Clock) , intent(in) :: clock integer , intent(in) :: target_ymd ! model date integer , intent(in) :: target_tod ! model sec into model date @@ -557,8 +558,8 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inp ! Read restart if needed if (restart_read .and. .not. skip_restart_read) then write(logunit,'(a)')' DEBUG: calling dglc_datamode_noevolve_restart_read' - call dglc_datamode_noevolve_restart_read(model_meshes, restfilm, & - inst_suffix, logunit, my_task, main_task, mpicom, & + call dglc_datamode_noevolve_restart_read(gcomp, model_meshes, restfilm, & + logunit, my_task, main_task, mpicom, & sdat(1)%pio_subsystem, sdat(1)%io_type, nx_global, ny_global, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index c5a44a48c..39a7c7f2a 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -382,7 +382,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) cosArg = 2.0_R8*shr_const_pi*(jday - jday0)/365.0_R8 ! Run dice - call dice_comp_run(importState, exportState, current_ymd, current_tod, cosarg, restart_write=.false., rc=rc) + call dice_comp_run(gcomp, importState, exportState, current_ymd, current_tod, cosarg, restart_write=.false., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Add scalars to export state diff --git a/dlnd/lnd_comp_nuopc.F90 b/dlnd/lnd_comp_nuopc.F90 index 56a360c83..bea64c5aa 100644 --- a/dlnd/lnd_comp_nuopc.F90 +++ b/dlnd/lnd_comp_nuopc.F90 @@ -303,7 +303,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! Read restart if necessary if (restart_read .and. .not. skip_restart_read) then - call dshr_restart_read(restfilm, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, restfilm, 'lnd', nullstr, logunit, my_task, mpicom, sdat) end if ! get the time to interpolate the stream data to diff --git a/docn/docn_datamode_copyall_mod.F90 b/docn/docn_datamode_copyall_mod.F90 index 95d4b7642..a6fa3e73d 100644 --- a/docn/docn_datamode_copyall_mod.F90 +++ b/docn/docn_datamode_copyall_mod.F90 @@ -1,6 +1,7 @@ module docn_datamode_copyall_mod use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_const_mod , only : shr_const_TkFrz, shr_const_pi, shr_const_ocn_ref_sal @@ -148,18 +149,18 @@ subroutine docn_datamode_copyall_restart_write(case_name, inst_suffix, ymd, tod, end subroutine docn_datamode_copyall_restart_write !=============================================================================== - subroutine docn_datamode_copyall_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + subroutine docn_datamode_copyall_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) end subroutine docn_datamode_copyall_restart_read diff --git a/docn/docn_datamode_cplhist_mod.F90 b/docn/docn_datamode_cplhist_mod.F90 index 3ff9e65c5..81fead617 100644 --- a/docn/docn_datamode_cplhist_mod.F90 +++ b/docn/docn_datamode_cplhist_mod.F90 @@ -1,6 +1,7 @@ module docn_datamode_cplhist_mod use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_const_mod , only : shr_const_TkFrz, shr_const_pi, shr_const_ocn_ref_sal @@ -142,18 +143,18 @@ subroutine docn_datamode_cplhist_restart_write(case_name, inst_suffix, ymd, tod, end subroutine docn_datamode_cplhist_restart_write !=============================================================================== - subroutine docn_datamode_cplhist_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + subroutine docn_datamode_cplhist_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) end subroutine docn_datamode_cplhist_restart_read diff --git a/docn/docn_datamode_iaf_mod.F90 b/docn/docn_datamode_iaf_mod.F90 index 032467f35..23b939a29 100644 --- a/docn/docn_datamode_iaf_mod.F90 +++ b/docn/docn_datamode_iaf_mod.F90 @@ -1,5 +1,5 @@ module docn_datamode_iaf_mod - + use ESMF , only : ESMF_GridComp use ESMF , only : ESMF_SUCCESS, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_State use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -198,20 +198,20 @@ subroutine docn_datamode_iaf_restart_write(case_name, inst_suffix, ymd, tod, & end subroutine docn_datamode_iaf_restart_write !=============================================================================== - subroutine docn_datamode_iaf_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + subroutine docn_datamode_iaf_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) ! read restart file ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) end subroutine docn_datamode_iaf_restart_read diff --git a/docn/docn_datamode_multilev_dom_mod.F90 b/docn/docn_datamode_multilev_dom_mod.F90 index 7cd7fd9eb..578e2b9ba 100644 --- a/docn/docn_datamode_multilev_dom_mod.F90 +++ b/docn/docn_datamode_multilev_dom_mod.F90 @@ -1,5 +1,5 @@ module docn_datamode_multilev_dom_mod - + use ESMF , only : ESMF_GridComp use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -244,20 +244,20 @@ subroutine docn_datamode_multilev_dom_restart_write(case_name, inst_suffix, ymd, end subroutine docn_datamode_multilev_dom_restart_write !=============================================================================== - subroutine docn_datamode_multilev_dom_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + subroutine docn_datamode_multilev_dom_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) ! read restart file ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) end subroutine docn_datamode_multilev_dom_restart_read diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index 897797f3f..b522862e6 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -1,4 +1,5 @@ module docn_datamode_multilev_mod + use ESMF , only : ESMF_GridComp use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -209,20 +210,20 @@ subroutine docn_datamode_multilev_restart_write(case_name, inst_suffix, ymd, tod end subroutine docn_datamode_multilev_restart_write !=============================================================================== - subroutine docn_datamode_multilev_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + subroutine docn_datamode_multilev_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) ! read restart file ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) end subroutine docn_datamode_multilev_restart_read diff --git a/docn/docn_datamode_som_mod.F90 b/docn/docn_datamode_som_mod.F90 index 672c58d4d..76b6bde95 100644 --- a/docn/docn_datamode_som_mod.F90 +++ b/docn/docn_datamode_som_mod.F90 @@ -1,9 +1,9 @@ module docn_datamode_som_mod - + use ESMF , only : ESMF_SUCCESS, ESMF_State, ESMF_Clock, ESMF_StateGet, ESMF_StateItem_Flag use ESMF , only : ESMF_TimeInterval, ESMF_ClockGet, ESMF_TimeIntervalGet use ESMF , only : ESMF_LOGMSG_INFO, ESMF_STATEITEM_NOTFOUND, operator(/=) - use ESMF , only : ESMF_LogWrite + use ESMF , only : ESMF_LogWrite, ESMF_GridComp use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort @@ -326,13 +326,13 @@ subroutine docn_datamode_som_restart_write(case_name, inst_suffix, ymd, tod, & end subroutine docn_datamode_som_restart_write !=============================================================================== - subroutine docn_datamode_som_restart_read(rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) + subroutine docn_datamode_som_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) ! read restart file ! input/output arguments + type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom @@ -343,7 +343,7 @@ subroutine docn_datamode_som_restart_read(rest_filem, inst_suffix, logunit, my_t allocate(somtp(sdat%model_lsize)) ! read restart - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat, & + call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat, & fld=somtp, fldname='somtp') end subroutine docn_datamode_som_restart_read diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index f15ed9ec2..1d7366a3f 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -453,7 +453,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) call shr_cal_ymd2date(current_year, current_mon, current_day, current_ymd) ! Run docn - call docn_comp_run(importState, exportState, clock, current_ymd, current_tod, restart_write=.false., rc=rc) + call docn_comp_run(gcomp, importState, exportState, clock, current_ymd, current_tod, restart_write=.false., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Add scalars to export state @@ -512,19 +512,20 @@ subroutine ModelAdvance(gcomp, rc) restart_write = dshr_check_restart_alarm(clock, rc=rc) ! run docn - call docn_comp_run(importState, exportState, clock, next_ymd, next_tod, restart_write, rc=rc) + call docn_comp_run(gcomp, importState, exportState, clock, next_ymd, next_tod, restart_write, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine ModelAdvance !=============================================================================== - subroutine docn_comp_run(importState, exportState, clock, target_ymd, target_tod, restart_write, rc) + subroutine docn_comp_run(gcomp, importState, exportState, clock, target_ymd, target_tod, restart_write, rc) ! -------------------------- ! advance docn ! -------------------------- ! input/output variables: + type(ESMF_GridComp) , intent(in) :: gcomp type(ESMF_Clock) , intent(in) :: clock type(ESMF_State) , intent(inout) :: importState type(ESMF_State) , intent(inout) :: exportState @@ -581,11 +582,11 @@ subroutine docn_comp_run(importState, exportState, clock, target_ymd, target_tod if (restart_read .and. .not. skip_restart_read) then select case (trim(datamode)) case('sstdata', 'sst_aquap_file') - call docn_datamode_copyall_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call docn_datamode_copyall_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('iaf') - call docn_datamode_iaf_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call docn_datamode_iaf_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) case('som', 'som_aquap') - call docn_datamode_som_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call docn_datamode_som_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) end select end if diff --git a/drof/rof_comp_nuopc.F90 b/drof/rof_comp_nuopc.F90 index 959421a70..5b9e5ef1f 100644 --- a/drof/rof_comp_nuopc.F90 +++ b/drof/rof_comp_nuopc.F90 @@ -310,7 +310,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) call shr_cal_ymd2date(current_year, current_mon, current_day, current_ymd) ! Run drof - call drof_comp_run(exportstate, current_ymd, current_tod, restart_write=.false., rc=rc) + call drof_comp_run(gcomp, exportstate, current_ymd, current_tod, restart_write=.false., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Add scalars to export state @@ -365,19 +365,20 @@ subroutine ModelAdvance(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! run drof - call drof_comp_run(exportState, next_ymd, next_tod, restart_write, rc=rc) + call drof_comp_run(gcomp, exportState, next_ymd, next_tod, restart_write, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine ModelAdvance !=============================================================================== - subroutine drof_comp_run(exportState, target_ymd, target_tod, restart_write, rc) + subroutine drof_comp_run(gcomp, exportState, target_ymd, target_tod, restart_write, rc) ! -------------------------- ! advance drof ! -------------------------- ! input/output variables: + type(ESMF_GridComp), intent(in) :: gcomp type(ESMF_State) , intent(inout) :: exportState integer , intent(in) :: target_ymd ! model date integer , intent(in) :: target_tod ! model sec into model date @@ -411,7 +412,7 @@ subroutine drof_comp_run(exportState, target_ymd, target_tod, restart_write, rc) ! Read restart if needed if (restart_read .and. .not. skip_restart_read) then - call dshr_restart_read(restfilm, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, restfilm, 'rof', nullstr, logunit, my_task, mpicom, sdat) end if first_time = .false. diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index bfd337039..e16b44c3a 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -994,6 +994,7 @@ subroutine dshr_restart_read(gcomp, rest_filem, compname, nullstr, & if (trim(rest_filem) == trim(nullstr)) then if (my_task == main_task) then call shr_get_rpointer_name(gcomp, compname, rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return write(logunit,F00) ' restart filename from rpointer' diff --git a/dwav/wav_comp_nuopc.F90 b/dwav/wav_comp_nuopc.F90 index 13728738a..cb850e5da 100644 --- a/dwav/wav_comp_nuopc.F90 +++ b/dwav/wav_comp_nuopc.F90 @@ -290,7 +290,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! Read restart if necessary if (restart_read .and. .not. skip_restart_read) then - call dshr_restart_read(restfilm, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat) + call dshr_restart_read(gcomp, restfilm, 'wav', nullstr, logunit, my_task, mpicom, sdat) end if ! Get the time to interpolate the stream data to From e65d8d9832311faf19ec474b71cba833e99b5d6d Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 4 Sep 2024 15:27:02 -0600 Subject: [PATCH 145/170] save before reverting to main --- dshr/dshr_mod.F90 | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index d323ccf1b..faa346b68 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -950,19 +950,17 @@ subroutine dshr_time_init( Time, ymd, cal, tod, rc) end subroutine dshr_time_init !=============================================================================== - subroutine dshr_restart_read(gcomp, rest_filem, compname, nullstr, & - logunit, my_task, mpicom, sdat, rc, fld, fldname) + subroutine dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, & + logunit, my_task, mpicom, sdat, fld, fldname) ! Read restart file use dshr_stream_mod, only : shr_stream_restIO use ESMF, only : ESMF_VMGetCurrent - use nuopc_shr_methods, only: shr_get_rpointer_name - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: compname + character(len=*) , intent(in) :: rpfile + character(len=*) , intent(in) :: inst_suffix character(len=*) , intent(in) :: nullstr integer , intent(in) :: logunit integer , intent(in) :: my_task @@ -970,10 +968,8 @@ subroutine dshr_restart_read(gcomp, rest_filem, compname, nullstr, & type(shr_strdata_type) , intent(inout) :: sdat real(r8) , optional , pointer :: fld(:) character(len=*) , optional , intent(in) :: fldname - integer , intent(out) :: rc - + ! local variables - character(len=ESMF_MAXSTR) :: rpfile type(ESMF_VM) :: vm integer :: nu logical :: exists ! file existance @@ -981,11 +977,12 @@ subroutine dshr_restart_read(gcomp, rest_filem, compname, nullstr, & type(var_desc_t) :: varid type(io_desc_t) :: pio_iodesc integer :: rcode + integer :: rc integer :: tmp(1) character(*), parameter :: F00 = "('(dshr_restart_read) ',8a)" character(*), parameter :: subName = "(dshr_restart_read) " !------------------------------------------------------------------------------- - + ! no streams means no restart file is read. if(shr_strdata_get_stream_count(sdat) <= 0) return call ESMF_VMGetCurrent(vm, rc=rc) @@ -993,12 +990,13 @@ subroutine dshr_restart_read(gcomp, rest_filem, compname, nullstr, & exists = .false. if (trim(rest_filem) == trim(nullstr)) then if (my_task == main_task) then - call shr_get_rpointer_name(gcomp, compname, rpfile, 'read', rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - write(logunit,F00) ' restart filename from rpointer '//trim(rpfile) - - open(newunit=nu, file=trim(rpfile), form='formatted') + write(logunit,F00) ' restart filename from rpointer' + inquire(file=trim(rpfile)//trim(inst_suffix), exist=exists) + if (.not.exists) then + write(logunit, F00) ' ERROR: rpointer file does not exist' + call shr_sys_abort(trim(subname)//' ERROR: rpointer file missing') + endif + open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') read(nu, '(a)') rest_filem close(nu) inquire(file=trim(rest_filem), exist=exists) From 34838d24dcd29ff00b74bdc0edf60db132c42254 Mon Sep 17 00:00:00 2001 From: Katetc Date: Thu, 5 Sep 2024 10:43:24 -0600 Subject: [PATCH 146/170] One more review comment addressed --- dglc/dglc_datamode_noevolve_mod.F90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index fef1201bd..3b64c884f 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -398,9 +398,8 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form ! Get mesh info call ESMF_MeshGet(model_meshes(ns), 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 - + lsize = size(Fgrg_rofi(ns)%ptr) + allocate(ice_runoff_out(lsize)) ice_runoff_out(:) = 0.d0 loc_pos_smb(1) = 0.d0 From 863def0c8a6295dbbb4b44b1055845d980cd5978 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 5 Sep 2024 13:58:15 -0600 Subject: [PATCH 147/170] restart ERS.f19_g17.2000_DATM%NYF_SLND_DICE%SSMI_DOCN%DOM_DROF%NYF_DGLC%NOEVOLVE_DWAV%CLIMO.derecho_intel passing --- datm/atm_comp_nuopc.F90 | 84 +++++++------------------ datm/datm_datamode_cfsr_mod.F90 | 40 ------------ datm/datm_datamode_clmncep_mod.F90 | 37 ----------- datm/datm_datamode_core2_mod.F90 | 39 ------------ datm/datm_datamode_cplhist_mod.F90 | 42 +------------ datm/datm_datamode_era5_mod.F90 | 41 +----------- datm/datm_datamode_gefs_mod.F90 | 38 ----------- datm/datm_datamode_jra_mod.F90 | 40 +----------- datm/datm_datamode_simple_mod.F90 | 38 ----------- dglc/dglc_datamode_noevolve_mod.F90 | 39 ++++-------- dglc/glc_comp_nuopc.F90 | 12 ++-- dice/dice_datamode_ssmi_mod.F90 | 20 +++--- dice/ice_comp_nuopc.F90 | 11 +++- dlnd/lnd_comp_nuopc.F90 | 24 ++++--- docn/docn_datamode_copyall_mod.F90 | 39 ------------ docn/docn_datamode_cplhist_mod.F90 | 39 ------------ docn/docn_datamode_iaf_mod.F90 | 46 +------------- docn/docn_datamode_multilev_dom_mod.F90 | 44 +------------ docn/docn_datamode_multilev_mod.F90 | 43 ------------- docn/docn_datamode_som_mod.F90 | 23 +++---- docn/ocn_comp_nuopc.F90 | 58 ++++++++--------- drof/rof_comp_nuopc.F90 | 17 +++-- dshr/dshr_mod.F90 | 29 ++++----- dwav/wav_comp_nuopc.F90 | 23 ++++--- 24 files changed, 163 insertions(+), 703 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 9fd846f98..9d7de76f8 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -33,9 +33,9 @@ module cdeps_datm_comp use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_init_from_config, shr_strdata_advance use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_setOrbs - use dshr_mod , only : dshr_model_initphase, dshr_init + use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_restart_write use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_log_clock_advance - use dshr_mod , only : dshr_mesh_init, dshr_check_restart_alarm + use dshr_mod , only : dshr_mesh_init, dshr_check_restart_alarm, dshr_restart_read use dshr_mod , only : dshr_orbital_init, dshr_orbital_update use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add, dshr_fldlist_realize @@ -43,50 +43,34 @@ module cdeps_datm_comp use datm_datamode_core2_mod , only : datm_datamode_core2_advertise use datm_datamode_core2_mod , only : datm_datamode_core2_init_pointers use datm_datamode_core2_mod , only : datm_datamode_core2_advance - use datm_datamode_core2_mod , only : datm_datamode_core2_restart_write - use datm_datamode_core2_mod , only : datm_datamode_core2_restart_read use datm_datamode_jra_mod , only : datm_datamode_jra_advertise use datm_datamode_jra_mod , only : datm_datamode_jra_init_pointers use datm_datamode_jra_mod , only : datm_datamode_jra_advance - use datm_datamode_jra_mod , only : datm_datamode_jra_restart_write - use datm_datamode_jra_mod , only : datm_datamode_jra_restart_read use datm_datamode_clmncep_mod , only : datm_datamode_clmncep_advertise use datm_datamode_clmncep_mod , only : datm_datamode_clmncep_init_pointers use datm_datamode_clmncep_mod , only : datm_datamode_clmncep_advance - use datm_datamode_clmncep_mod , only : datm_datamode_clmncep_restart_write - use datm_datamode_clmncep_mod , only : datm_datamode_clmncep_restart_read use datm_datamode_cplhist_mod , only : datm_datamode_cplhist_advertise use datm_datamode_cplhist_mod , only : datm_datamode_cplhist_init_pointers use datm_datamode_cplhist_mod , only : datm_datamode_cplhist_advance - use datm_datamode_cplhist_mod , only : datm_datamode_cplhist_restart_write - use datm_datamode_cplhist_mod , only : datm_datamode_cplhist_restart_read use datm_datamode_era5_mod , only : datm_datamode_era5_advertise use datm_datamode_era5_mod , only : datm_datamode_era5_init_pointers use datm_datamode_era5_mod , only : datm_datamode_era5_advance - use datm_datamode_era5_mod , only : datm_datamode_era5_restart_write - use datm_datamode_era5_mod , only : datm_datamode_era5_restart_read use datm_datamode_gefs_mod , only : datm_datamode_gefs_advertise use datm_datamode_gefs_mod , only : datm_datamode_gefs_init_pointers use datm_datamode_gefs_mod , only : datm_datamode_gefs_advance - use datm_datamode_gefs_mod , only : datm_datamode_gefs_restart_write - use datm_datamode_gefs_mod , only : datm_datamode_gefs_restart_read use datm_datamode_cfsr_mod , only : datm_datamode_cfsr_advertise use datm_datamode_cfsr_mod , only : datm_datamode_cfsr_init_pointers use datm_datamode_cfsr_mod , only : datm_datamode_cfsr_advance - use datm_datamode_cfsr_mod , only : datm_datamode_cfsr_restart_write - use datm_datamode_cfsr_mod , only : datm_datamode_cfsr_restart_read use datm_datamode_simple_mod , only : datm_datamode_simple_advertise use datm_datamode_simple_mod , only : datm_datamode_simple_init_pointers use datm_datamode_simple_mod , only : datm_datamode_simple_advance - use datm_datamode_simple_mod , only : datm_datamode_simple_restart_write - use datm_datamode_simple_mod , only : datm_datamode_simple_restart_read implicit none private ! except @@ -157,7 +141,6 @@ module cdeps_datm_comp integer :: idt ! integer model timestep logical :: diagnose_data = .true. integer , parameter :: main_task = 0 ! task number of main task - character(len=*) , parameter :: rpfile = 'rpointer.atm' #ifdef CESMCOUPLED character(*) , parameter :: modName = "(atm_comp_nuopc)" #else @@ -581,13 +564,13 @@ end subroutine ModelAdvance !=============================================================================== subroutine datm_comp_run(gcomp, importState, exportState, target_ymd, target_tod, target_mon, & orbEccen, orbMvelpp, orbLambm0, orbObliqr, restart_write, rc) - + use nuopc_shr_methods, only : shr_get_rpointer_name ! ---------------------------------- ! run method for datm model ! ---------------------------------- ! input/output variables - type(ESMF_GridComp) , intent(in) :: gcomp + type(ESMF_GridComp) , intent(inout) :: gcomp type(ESMF_State) , intent(inout) :: importState type(ESMF_State) , intent(inout) :: exportState integer , intent(in) :: target_ymd ! model date @@ -602,7 +585,10 @@ subroutine datm_comp_run(gcomp, importState, exportState, target_ymd, target_tod ! local variables logical :: first_time = .true. + character(len=CL) :: rpfile + character(len=16) :: timestr character(*), parameter :: subName = '(datm_comp_run) ' + integer :: yr, mon, day !------------------------------------------------------------------------------- rc = ESMF_SUCCESS @@ -614,7 +600,6 @@ subroutine datm_comp_run(gcomp, importState, exportState, target_ymd, target_tod !-------------------- if (first_time) then - ! Initialize dfields call datm_init_dfields(rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -649,23 +634,14 @@ subroutine datm_comp_run(gcomp, importState, exportState, target_ymd, target_tod ! Read restart if needed if (restart_read .and. .not. skip_restart_read) then + call shr_get_rpointer_name(gcomp, 'atm', target_ymd, target_tod, rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return select case (trim(datamode)) - case('CORE2_NYF','CORE2_IAF') - call datm_datamode_core2_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) - case('CORE_IAF_JRA') - call datm_datamode_jra_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) - case('CLMNCEP') - call datm_datamode_clmncep_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) - case('CPLHIST') - call datm_datamode_cplhist_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) - case('ERA5') - call datm_datamode_era5_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) - case('GEFS') - call datm_datamode_gefs_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) - case('CFSR') - call datm_datamode_cfsr_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) - case('SIMPLE') - call datm_datamode_simple_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) + case('CORE2_NYF','CORE2_IAF','CORE_IAF_JRA','CLMNCEP','CPLHIST','ERA5','GEFS','CFSR','SIMPLE') + call dshr_restart_read(restfilm, rpfile, logunit, my_task, mpicom, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + case default + call shr_sys_abort(subName//'datamode '//trim(datamode)//' not recognized') end select end if @@ -728,33 +704,15 @@ subroutine datm_comp_run(gcomp, importState, exportState, target_ymd, target_tod ! Write restarts if needed if (restart_write) then + call shr_get_rpointer_name(gcomp, 'atm', target_ymd, target_tod, rpfile, 'write', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return select case (trim(datamode)) - case('CORE2_NYF','CORE2_IAF') - call datm_datamode_core2_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - case('CORE_IAF_JRA') - call datm_datamode_jra_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - case('CLMNCEP') - call datm_datamode_clmncep_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - case('CPLHIST') - call datm_datamode_cplhist_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - case('ERA5') - call datm_datamode_era5_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - case('GEFS') - call datm_datamode_gefs_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) + case('CORE2_NYF','CORE2_IAF','CORE_IAF_JRA','CLMNCEP','CPLHIST','ERA5','GEFS','CFSR','SIMPLE') + call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, target_ymd, target_tod, logunit, & + my_task, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - case('CFSR') - call datm_datamode_cfsr_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - case('SIMPLE') - call datm_datamode_simple_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) + case default + call shr_sys_abort(subName//'datamode '//trim(datamode)//' not recognized') end select end if diff --git a/datm/datm_datamode_cfsr_mod.F90 b/datm/datm_datamode_cfsr_mod.F90 index c3aa60203..ec1ab7a89 100644 --- a/datm/datm_datamode_cfsr_mod.F90 +++ b/datm/datm_datamode_cfsr_mod.F90 @@ -8,7 +8,6 @@ module datm_datamode_cfsr_mod use shr_const_mod , only : shr_const_tkfrz, shr_const_rhofw, shr_const_rdair use dshr_methods_mod , only : dshr_state_getfldptr, chkerr use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_get_stream_pointer - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add @@ -18,8 +17,6 @@ module datm_datamode_cfsr_mod public :: datm_datamode_cfsr_advertise public :: datm_datamode_cfsr_init_pointers public :: datm_datamode_cfsr_advance - public :: datm_datamode_cfsr_restart_write - public :: datm_datamode_cfsr_restart_read ! export state data real(r8), pointer :: Sa_z(:) => null() @@ -51,8 +48,6 @@ module datm_datamode_cfsr_mod real(r8) , parameter :: rdair = SHR_CONST_RDAIR ! dry air gas constant ~ J/K/kg real(r8) , parameter :: rhofw = SHR_CONST_RHOFW ! density of fresh water ~ kg/m^3 - character(*), parameter :: nullstr = 'undefined' - character(*), parameter :: rpfile = 'rpointer.atm' character(*), parameter :: u_FILE_u = & __FILE__ @@ -218,39 +213,4 @@ subroutine datm_datamode_cfsr_advance(exportstate, mainproc, logunit, mpicom, ta end subroutine datm_datamode_cfsr_advance - !=============================================================================== - subroutine datm_datamode_cfsr_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine datm_datamode_cfsr_restart_write - - !=============================================================================== - subroutine datm_datamode_cfsr_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - use ESMF, only : ESMF_GridComp - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine datm_datamode_cfsr_restart_read - end module datm_datamode_cfsr_mod diff --git a/datm/datm_datamode_clmncep_mod.F90 b/datm/datm_datamode_clmncep_mod.F90 index e9c982af2..f11aa167c 100644 --- a/datm/datm_datamode_clmncep_mod.F90 +++ b/datm/datm_datamode_clmncep_mod.F90 @@ -10,7 +10,6 @@ module datm_datamode_clmncep_mod use shr_const_mod , only : shr_const_pstd, shr_const_stebol, shr_const_rdair use dshr_methods_mod , only : dshr_state_getfldptr, chkerr use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_get_stream_pointer - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add @@ -20,8 +19,6 @@ module datm_datamode_clmncep_mod public :: datm_datamode_clmncep_advertise public :: datm_datamode_clmncep_init_pointers public :: datm_datamode_clmncep_advance - public :: datm_datamode_clmncep_restart_write - public :: datm_datamode_clmncep_restart_read private :: datm_esat ! determine saturation vapor pressure ! export state data @@ -591,41 +588,7 @@ subroutine datm_datamode_clmncep_advance(mainproc, logunit, mpicom, rc) end subroutine datm_datamode_clmncep_advance !=============================================================================== - subroutine datm_datamode_clmncep_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine datm_datamode_clmncep_restart_write - - !=============================================================================== - subroutine datm_datamode_clmncep_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - use ESMF, only : ESMF_GridComp - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine datm_datamode_clmncep_restart_read - - !=============================================================================== real(r8) function datm_eSat(tK,tKbot) !---------------------------------------------------------------------------- diff --git a/datm/datm_datamode_core2_mod.F90 b/datm/datm_datamode_core2_mod.F90 index 7e68893a2..8b041f084 100644 --- a/datm/datm_datamode_core2_mod.F90 +++ b/datm/datm_datamode_core2_mod.F90 @@ -22,7 +22,6 @@ module datm_datamode_core2_mod use shr_const_mod , only : shr_const_tkfrz, shr_const_pi use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, dshr_fldbun_regrid, chkerr - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add @@ -32,8 +31,6 @@ module datm_datamode_core2_mod public :: datm_datamode_core2_advertise public :: datm_datamode_core2_init_pointers public :: datm_datamode_core2_advance - public :: datm_datamode_core2_restart_write - public :: datm_datamode_core2_restart_read private :: datm_get_adjustment_factors @@ -86,7 +83,6 @@ module datm_datamode_core2_mod -1.99_R8,-0.91_R8, 1.72_R8, 2.30_R8, 1.81_R8, 1.06_R8/ character(*), parameter :: nullstr = 'null' - character(*), parameter :: rpfile = 'rpointer.atm' character(*), parameter :: u_FILE_u = & __FILE__ @@ -409,41 +405,6 @@ subroutine datm_datamode_core2_advance(datamode, target_ymd, target_tod, target_ end subroutine datm_datamode_core2_advance - !=============================================================================== - subroutine datm_datamode_core2_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine datm_datamode_core2_restart_write - - !=============================================================================== - subroutine datm_datamode_core2_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - use ESMF, only : ESMF_GridComp - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine datm_datamode_core2_restart_read - !=============================================================================== subroutine datm_get_adjustment_factors(sdat, fileName_mesh, fileName_data, windF, winddF, qsatF, rc) diff --git a/datm/datm_datamode_cplhist_mod.F90 b/datm/datm_datamode_cplhist_mod.F90 index c13ccef9d..2765bc157 100644 --- a/datm/datm_datamode_cplhist_mod.F90 +++ b/datm/datm_datamode_cplhist_mod.F90 @@ -7,7 +7,6 @@ module datm_datamode_cplhist_mod use shr_sys_mod , only : shr_sys_abort use dshr_methods_mod , only : dshr_state_getfldptr, chkerr use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_get_stream_pointer - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add @@ -17,8 +16,6 @@ module datm_datamode_cplhist_mod public :: datm_datamode_cplhist_advertise public :: datm_datamode_cplhist_init_pointers public :: datm_datamode_cplhist_advance - public :: datm_datamode_cplhist_restart_write - public :: datm_datamode_cplhist_restart_read ! export state data real(r8), pointer :: Sa_z(:) => null() @@ -27,8 +24,8 @@ module datm_datamode_cplhist_mod real(r8), pointer :: Sa_tbot(:) => null() real(r8), pointer :: Sa_ptem(:) => null() real(r8), pointer :: Sa_shum(:) => null() -! TODO: water isotope support -! real(r8), pointer :: Sa_shum_wiso(:,:) => null() ! water isotopes + ! TODO: water isotope support + ! real(r8), pointer :: Sa_shum_wiso(:,:) => null() ! water isotopes real(r8), pointer :: Sa_dens(:) => null() real(r8), pointer :: Sa_pbot(:) => null() real(r8), pointer :: Sa_pslv(:) => null() @@ -200,39 +197,4 @@ subroutine datm_datamode_cplhist_advance(mainproc, logunit, mpicom, rc) end subroutine datm_datamode_cplhist_advance - !=============================================================================== - subroutine datm_datamode_cplhist_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine datm_datamode_cplhist_restart_write - - !=============================================================================== - subroutine datm_datamode_cplhist_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - use ESMF, only : ESMF_GridComp - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine datm_datamode_cplhist_restart_read - end module datm_datamode_cplhist_mod diff --git a/datm/datm_datamode_era5_mod.F90 b/datm/datm_datamode_era5_mod.F90 index 84224a037..2ba91cc78 100644 --- a/datm/datm_datamode_era5_mod.F90 +++ b/datm/datm_datamode_era5_mod.F90 @@ -8,7 +8,6 @@ module datm_datamode_era5_mod use shr_const_mod , only : shr_const_tkfrz, shr_const_rhofw, shr_const_rdair use dshr_methods_mod , only : dshr_state_getfldptr, chkerr use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_get_stream_pointer - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add @@ -18,8 +17,6 @@ module datm_datamode_era5_mod public :: datm_datamode_era5_advertise public :: datm_datamode_era5_init_pointers public :: datm_datamode_era5_advance - public :: datm_datamode_era5_restart_write - public :: datm_datamode_era5_restart_read private :: datm_eSat ! determine saturation vapor pressure ! export state data @@ -194,7 +191,7 @@ subroutine datm_datamode_era5_init_pointers(exportState, sdat, rc) end subroutine datm_datamode_era5_init_pointers - !=============================================================================== + !=============================================================================== subroutine datm_datamode_era5_advance(exportstate, mainproc, logunit, mpicom, target_ymd, target_tod, model_calendar, rc) use ESMF, only: ESMF_VMGetCurrent, ESMF_VMAllReduce, ESMF_REDUCE_MAX, ESMF_VM @@ -317,41 +314,7 @@ subroutine datm_datamode_era5_advance(exportstate, mainproc, logunit, mpicom, ta end subroutine datm_datamode_era5_advance - !=============================================================================== - subroutine datm_datamode_era5_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine datm_datamode_era5_restart_write - - !=============================================================================== - subroutine datm_datamode_era5_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - use ESMF, only : ESMF_GridComp - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine datm_datamode_era5_restart_read - + !=============================================================================== real(r8) function datm_eSat(tK,tKbot) !---------------------------------------------------------------------------- diff --git a/datm/datm_datamode_gefs_mod.F90 b/datm/datm_datamode_gefs_mod.F90 index 16c97990f..66b991d89 100644 --- a/datm/datm_datamode_gefs_mod.F90 +++ b/datm/datm_datamode_gefs_mod.F90 @@ -8,7 +8,6 @@ module datm_datamode_gefs_mod use shr_const_mod , only : shr_const_tkfrz, shr_const_rhofw, shr_const_rdair use dshr_methods_mod , only : dshr_state_getfldptr, chkerr use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_get_stream_pointer - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add @@ -18,8 +17,6 @@ module datm_datamode_gefs_mod public :: datm_datamode_gefs_advertise public :: datm_datamode_gefs_init_pointers public :: datm_datamode_gefs_advance - public :: datm_datamode_gefs_restart_write - public :: datm_datamode_gefs_restart_read ! export state data real(r8), pointer :: Sa_z(:) => null() @@ -220,39 +217,4 @@ subroutine datm_datamode_gefs_advance(exportstate, mainproc, logunit, mpicom, ta end subroutine datm_datamode_gefs_advance - !=============================================================================== - subroutine datm_datamode_gefs_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine datm_datamode_gefs_restart_write - - !=============================================================================== - subroutine datm_datamode_gefs_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - use ESMF, only : ESMF_GridComp - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine datm_datamode_gefs_restart_read - end module datm_datamode_gefs_mod diff --git a/datm/datm_datamode_jra_mod.F90 b/datm/datm_datamode_jra_mod.F90 index 43bc3c2f9..e09844ace 100644 --- a/datm/datm_datamode_jra_mod.F90 +++ b/datm/datm_datamode_jra_mod.F90 @@ -1,7 +1,7 @@ module datm_datamode_jra_mod use ESMF , only : ESMF_State, ESMF_StateGet, ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO - use ESMF , only : ESMF_MeshGet, ESMF_GridComp + use ESMF , only : ESMF_MeshGet use ESMF , only : ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND, operator(/=) use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -10,7 +10,6 @@ module datm_datamode_jra_mod use shr_const_mod , only : shr_const_tkfrz, shr_const_pi, shr_const_rdair use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, dshr_fldbun_regrid, chkerr - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add @@ -20,8 +19,6 @@ module datm_datamode_jra_mod public :: datm_datamode_jra_advertise public :: datm_datamode_jra_init_pointers public :: datm_datamode_jra_advance - public :: datm_datamode_jra_restart_write - public :: datm_datamode_jra_restart_read ! export state pointers real(r8), pointer :: Sa_z(:) => null() @@ -303,39 +300,4 @@ subroutine datm_datamode_jra_advance(exportstate, target_ymd, target_tod, model_ end subroutine datm_datamode_jra_advance - !=============================================================================== - subroutine datm_datamode_jra_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine datm_datamode_jra_restart_write - - !=============================================================================== - subroutine datm_datamode_jra_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine datm_datamode_jra_restart_read - end module datm_datamode_jra_mod diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 index c614f0465..da88fc640 100644 --- a/datm/datm_datamode_simple_mod.F90 +++ b/datm/datm_datamode_simple_mod.F90 @@ -23,7 +23,6 @@ module datm_datamode_simple_mod use shr_const_mod , only : shr_const_tkfrz, shr_const_pi use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, dshr_fldbun_regrid, chkerr - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add @@ -33,8 +32,6 @@ module datm_datamode_simple_mod public :: datm_datamode_simple_advertise public :: datm_datamode_simple_init_pointers public :: datm_datamode_simple_advance - public :: datm_datamode_simple_restart_write - public :: datm_datamode_simple_restart_read ! export state pointers real(r8), pointer :: Sa_u(:) => null() @@ -341,39 +338,4 @@ subroutine datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & end subroutine datm_datamode_simple_advance - !=============================================================================== - subroutine datm_datamode_simple_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'datm', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine datm_datamode_simple_restart_write - - !=============================================================================== - subroutine datm_datamode_simple_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - use ESMF, only : ESMF_GridComp - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'atm', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine datm_datamode_simple_restart_read - end module datm_datamode_simple_mod diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index d41b739fd..7467a98ae 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -4,7 +4,7 @@ module dglc_datamode_noevolve_mod use ESMF , only : ESMF_Mesh, ESMF_DistGrid, ESMF_FieldBundle, ESMF_Field use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldCreate, ESMF_MeshLoc_Element use ESMF , only : ESMF_FieldBundleAdd, ESMF_MeshGet, ESMF_DistGridGet, ESMF_Typekind_R8 - use ESMF , only : ESMF_VMGetCurrent, ESMF_VMBroadCast, ESMF_VM, ESMF_GridComp + use ESMF , only : ESMF_VMGetCurrent, ESMF_VMBroadCast, ESMF_VM use NUOPC , only : NUOPC_Advertise, NUOPC_IsConnected use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort @@ -71,7 +71,6 @@ module dglc_datamode_noevolve_mod character(len=*), parameter :: field_in_so_s_depth = 'So_s_depth' character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.glc' character(*) , parameter :: u_FILE_u = & __FILE__ @@ -433,12 +432,13 @@ end function is_ice_covered !=============================================================================== subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & - inst_suffix, ymd, tod, logunit, my_task, main_task, & + rpfile, inst_suffix, ymd, tod, logunit, my_task, main_task, & pio_subsystem, io_type, nx_global, ny_global, rc) ! input/output variables type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes character(len=*) , intent(in) :: case_name + character(len=*) , intent(in) :: rpfile character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: ymd ! model date integer , intent(in) :: tod ! model sec into model date @@ -519,14 +519,14 @@ subroutine dglc_datamode_noevolve_restart_write(model_meshes, case_name, & end subroutine dglc_datamode_noevolve_restart_write !=============================================================================== - subroutine dglc_datamode_noevolve_restart_read(gcomp, model_meshes, restfilem, & + subroutine dglc_datamode_noevolve_restart_read(model_meshes, restfilem, rpfile, & logunit, my_task, main_task, mpicom, & pio_subsystem, io_type, nx_global, ny_global, rc) - use nuopc_shr_methods, only : shr_get_rpointer_name + ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp type(ESMF_Mesh) , intent(in) :: model_meshes(:) ! ice sheets meshes character(len=*) , intent(inout) :: restfilem + character(len=*) , intent(in) :: rpfile integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: main_task @@ -541,7 +541,6 @@ subroutine dglc_datamode_noevolve_restart_read(gcomp, model_meshes, restfilem, & type(ESMF_DistGrid) :: distgrid integer :: ns character(len=CS) :: cnum - character(len=CS) :: rpfile integer :: lsize integer, pointer :: gindex(:) ! domain decomposition of data type(ESMF_VM) :: vm @@ -557,14 +556,14 @@ subroutine dglc_datamode_noevolve_restart_read(gcomp, model_meshes, restfilem, & rc = ESMF_SUCCESS ! Determine restart file - exists = .false. - call ESMF_VMGetCurrent(vm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (trim(restfilem) == trim(nullstr)) then + exists = .false. + call ESMF_VMGetCurrent(vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (my_task == main_task) then - call shr_get_rpointer_name(gcomp, 'glc', rpfile, 'read', rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(logunit,'(a)') trim(subname)//' restart filename from rpointer' + write(logunit,'(a)') trim(subname)//' restart filename from rpointer '//trim(rpfile) open(newunit=nu, file=trim(rpfile), form='formatted') read(nu,'(a)') restfilem close(nu) @@ -581,16 +580,12 @@ subroutine dglc_datamode_noevolve_restart_read(gcomp, model_meshes, restfilem, & endif tmp = 0 if(exists) tmp=1 - call ESMF_VMBroadCast(vm, tmp, 1, main_task, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return exists = (tmp(1) == 1) - if (.not. exists .and. my_task == main_task) then write(logunit, '(a)') trim(subname)//' file not found, skipping '//trim(restfilem) - ! Should we return here or just abort? return end if - + ! Read restart file if (my_task == main_task) then write(logunit, '(a)') trim(subname)//' reading data model restart '//trim(restfilem) @@ -610,14 +605,6 @@ subroutine dglc_datamode_noevolve_restart_read(gcomp, model_meshes, restfilem, & call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=gindex, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Read restart file - if (my_task == main_task) then - write(logunit, '(a)') trim(subname)//' reading data model restart '//trim(restfilem) - end if - rcode = pio_openfile(pio_subsystem, pioid, io_type, trim(restfilem), pio_nowrite) - call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) - rcode = pio_inq_varid(pioid, 'flgl_rofi'//cnum, varid) - call pio_read_darray(pioid, varid, pio_iodesc, Fgrg_rofi(ns)%ptr, rcode) call pio_initdecomp(pio_subsystem, pio_double, (/nx_global(ns),ny_global(ns)/), gindex, pio_iodesc) rcode = pio_inq_varid(pioid, 'flgl_rofi'//cnum, varid) diff --git a/dglc/glc_comp_nuopc.F90 b/dglc/glc_comp_nuopc.F90 index 3099ee9d2..a20be438b 100644 --- a/dglc/glc_comp_nuopc.F90 +++ b/dglc/glc_comp_nuopc.F90 @@ -41,7 +41,7 @@ module cdeps_dglc_comp use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_check_restart_alarm use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_realize - + use nuopc_shr_methods, only : shr_get_rpointer_name ! Datamode specialized modules use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_advertise use dglc_datamode_noevolve_mod, only : dglc_datamode_noevolve_init_pointers @@ -530,6 +530,7 @@ subroutine dglc_comp_run(gcomp, clock, target_ymd, target_tod, restart_write, va character(len=CS) :: cnum integer :: ns ! ice sheet index logical :: first_time = .true. + character(len=CS) :: rpfile character(*), parameter :: subName = "(dglc_comp_run) " !------------------------------------------------------------------------------- @@ -557,8 +558,9 @@ subroutine dglc_comp_run(gcomp, clock, target_ymd, target_tod, restart_write, va ! Read restart if needed if (restart_read .and. .not. skip_restart_read) then - write(logunit,'(a)')' DEBUG: calling dglc_datamode_noevolve_restart_read' - call dglc_datamode_noevolve_restart_read(gcomp, model_meshes, restfilm, & + call shr_get_rpointer_name(gcomp, 'glc', target_ymd, target_tod, rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dglc_datamode_noevolve_restart_read(model_meshes, restfilm, rpfile, & logunit, my_task, main_task, mpicom, & sdat(1)%pio_subsystem, sdat(1)%io_type, nx_global, ny_global, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -612,7 +614,9 @@ subroutine dglc_comp_run(gcomp, clock, target_ymd, target_tod, restart_write, va if (my_task == main_task) then write(logunit,'(a)') 'calling dglc_datamode_noevolve_restart_write' end if - call dglc_datamode_noevolve_restart_write(model_meshes, case_name, & + call shr_get_rpointer_name(gcomp, 'glc', target_ymd, target_tod, rpfile, 'write', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dglc_datamode_noevolve_restart_write(model_meshes, case_name, rpfile, & inst_suffix, target_ymd, target_tod, logunit, my_task, main_task, & sdat(1)%pio_subsystem, sdat(1)%io_type, nx_global, ny_global, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/dice/dice_datamode_ssmi_mod.F90 b/dice/dice_datamode_ssmi_mod.F90 index 1196c8316..79c4ac372 100644 --- a/dice/dice_datamode_ssmi_mod.F90 +++ b/dice/dice_datamode_ssmi_mod.F90 @@ -102,7 +102,6 @@ module dice_datamode_ssmi_mod real(r8) , parameter :: waterMax = 1000.0_r8 ! wrt iFrac comp & frazil ice (kg/m^2) character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.ice' character(*) , parameter :: u_FILE_u = & __FILE__ @@ -567,10 +566,11 @@ subroutine dice_datamode_ssmi_advance(exportState, importState, cosarg, flds_i2o end subroutine dice_datamode_ssmi_advance !=============================================================================== - subroutine dice_datamode_ssmi_restart_write(case_name, inst_suffix, ymd, tod, & + subroutine dice_datamode_ssmi_restart_write(rpfile, case_name, inst_suffix, ymd, tod, & logunit, my_task, sdat) ! input/output variables + character(len=*) , intent(in) :: rpfile character(len=*) , intent(in) :: case_name character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: ymd ! model date @@ -579,31 +579,33 @@ subroutine dice_datamode_ssmi_restart_write(case_name, inst_suffix, ymd, tod, & integer , intent(in) :: my_task type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - + integer :: rc call dshr_restart_write(rpfile, case_name, 'dice', inst_suffix, ymd, tod, & - logunit, my_task, sdat, fld=water, fldname='water') + logunit, my_task, sdat, rc, fld=water, fldname='water') + if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine dice_datamode_ssmi_restart_write !=============================================================================== - subroutine dice_datamode_ssmi_restart_read(gcomp, rest_filem, inst_suffix, logunit, my_task, mpicom, sdat) - use nuopc_shr_methods, only : shr_get_rpointer_name + subroutine dice_datamode_ssmi_restart_read(gcomp, rest_filem, rpfile, logunit, my_task, mpicom, sdat) + ! input/output arguments type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem - character(len=*) , intent(in) :: inst_suffix + character(len=*) , intent(in) :: rpfile integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - + integer :: rc ! allocate module memory for restart fields that are read in allocate(water(sdat%model_lsize)) ! read restart - call dshr_restart_read(gcomp, rest_filem, 'ice', nullstr, logunit, my_task, mpicom, sdat, & + call dshr_restart_read(rest_filem, rpfile, logunit, my_task, mpicom, sdat, rc,& fld=water, fldname='water') + if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine dice_datamode_ssmi_restart_read diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index 39a7c7f2a..ad01ffdd0 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -395,7 +395,6 @@ end subroutine InitializeRealize !=============================================================================== subroutine ModelAdvance(gcomp, rc) - ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -459,6 +458,7 @@ end subroutine ModelAdvance !=============================================================================== subroutine dice_comp_run(gcomp, importstate, exportstate, target_ymd, target_tod, cosarg, restart_write, rc) + use nuopc_shr_methods, only : shr_get_rpointer_name ! -------------------------- ! advance dice @@ -476,6 +476,7 @@ subroutine dice_comp_run(gcomp, importstate, exportstate, target_ymd, target_tod ! local variables logical :: first_time = .true. + character(len=CL) :: rpfile character(*), parameter :: subName = "(dice_comp_run) " !------------------------------------------------------------------------------- @@ -503,9 +504,11 @@ subroutine dice_comp_run(gcomp, importstate, exportstate, target_ymd, target_tod ! read restart if needed if (restart_read) then + call shr_get_rpointer_name(gcomp, 'ice', target_ymd, target_tod, rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return select case (trim(datamode)) case('ssmi', 'ssmi_iaf') - call dice_datamode_ssmi_restart_read(gcomp, restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call dice_datamode_ssmi_restart_read(gcomp, restfilm, rpfile, logunit, my_task, mpicom, sdat) end select end if @@ -550,9 +553,11 @@ subroutine dice_comp_run(gcomp, importstate, exportstate, target_ymd, target_tod ! Write restarts if needed if (restart_write) then + call shr_get_rpointer_name(gcomp, 'ice', target_ymd, target_tod, rpfile, 'write', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return select case (trim(datamode)) case('ssmi', 'ssmi_iaf') - call dice_datamode_ssmi_restart_write(case_name, inst_suffix, target_ymd, target_tod, & + call dice_datamode_ssmi_restart_write(rpfile, case_name, inst_suffix, target_ymd, target_tod, & logunit, my_task, sdat) if (ChkErr(rc,__LINE__,u_FILE_u)) return end select diff --git a/dlnd/lnd_comp_nuopc.F90 b/dlnd/lnd_comp_nuopc.F90 index bea64c5aa..f7527da65 100644 --- a/dlnd/lnd_comp_nuopc.F90 +++ b/dlnd/lnd_comp_nuopc.F90 @@ -98,7 +98,6 @@ module cdeps_dlnd_comp integer :: glc_nec logical :: diagnose_data = .true. integer , parameter :: main_task=0 ! task number of main task - character(*) , parameter :: rpfile = 'rpointer.lnd' #ifdef CESMCOUPLED character(*) , parameter :: modName = "(lnd_comp_nuopc)" #else @@ -277,6 +276,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) integer :: current_mon ! model month integer :: current_day ! model day integer :: current_tod ! model sec into model date + character(len=cl) :: rpfile ! restart pointer file name character(len=*),parameter :: subname=trim(modName)//':(InitializeRealize) ' !------------------------------------------------------------------------------- @@ -301,11 +301,6 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) call dlnd_comp_realize(importState, exportState, export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Read restart if necessary - if (restart_read .and. .not. skip_restart_read) then - call dshr_restart_read(gcomp, restfilm, 'lnd', nullstr, logunit, my_task, mpicom, sdat) - end if - ! get the time to interpolate the stream data to call ESMF_ClockGet(clock, currTime=currTime, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -313,6 +308,15 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call shr_cal_ymd2date(current_year, current_mon, current_day, current_ymd) + ! Read restart if necessary + if (restart_read .and. .not. skip_restart_read) then + call shr_get_rpointer_name(gcomp, 'lnd', current_ymd, current_tod, rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_restart_read(restfilm, rpfile, logunit, my_task, mpicom, sdat, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + + ! Run dlnd to create export state call dlnd_comp_run(importState, exportState, current_ymd, current_tod, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -333,7 +337,7 @@ end subroutine InitializeRealize !=============================================================================== subroutine ModelAdvance(gcomp, rc) - + use nuopc_shr_methods, only : shr_get_rpointer_name ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -349,6 +353,7 @@ subroutine ModelAdvance(gcomp, rc) integer :: mon ! month integer :: day ! day in month logical :: write_restart + character(len=CL) :: rpfile character(len=*),parameter :: subname=trim(modName)//':(ModelAdvance) ' !------------------------------------------------------------------------------- @@ -379,8 +384,11 @@ subroutine ModelAdvance(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (write_restart) then call ESMF_TraceRegionEnter('dlnd_restart') + call shr_get_rpointer_name(gcomp, 'lnd', next_ymd, next_tod, rpfile, 'write', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_restart_write(rpfile, case_name, 'dlnd', inst_suffix, next_ymd, next_tod, & - logunit, my_task, sdat) + logunit, my_task, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('dlnd_restart') endif diff --git a/docn/docn_datamode_copyall_mod.F90 b/docn/docn_datamode_copyall_mod.F90 index a6fa3e73d..85d625fee 100644 --- a/docn/docn_datamode_copyall_mod.F90 +++ b/docn/docn_datamode_copyall_mod.F90 @@ -1,14 +1,12 @@ module docn_datamode_copyall_mod use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS - use ESMF , only : ESMF_GridComp use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_const_mod , only : shr_const_TkFrz, shr_const_pi, shr_const_ocn_ref_sal use shr_sys_mod , only : shr_sys_abort use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type implicit none @@ -17,8 +15,6 @@ module docn_datamode_copyall_mod public :: docn_datamode_copyall_advertise public :: docn_datamode_copyall_init_pointers public :: docn_datamode_copyall_advance - public :: docn_datamode_copyall_restart_read - public :: docn_datamode_copyall_restart_write ! export fields real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator @@ -129,39 +125,4 @@ subroutine docn_datamode_copyall_advance(rc) end subroutine docn_datamode_copyall_advance - !=============================================================================== - subroutine docn_datamode_copyall_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine docn_datamode_copyall_restart_write - - !=============================================================================== - subroutine docn_datamode_copyall_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine docn_datamode_copyall_restart_read - end module docn_datamode_copyall_mod diff --git a/docn/docn_datamode_cplhist_mod.F90 b/docn/docn_datamode_cplhist_mod.F90 index 81fead617..81ac40224 100644 --- a/docn/docn_datamode_cplhist_mod.F90 +++ b/docn/docn_datamode_cplhist_mod.F90 @@ -1,14 +1,12 @@ module docn_datamode_cplhist_mod use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS - use ESMF , only : ESMF_GridComp use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_const_mod , only : shr_const_TkFrz, shr_const_pi, shr_const_ocn_ref_sal use shr_sys_mod , only : shr_sys_abort use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_type implicit none @@ -17,8 +15,6 @@ module docn_datamode_cplhist_mod public :: docn_datamode_cplhist_advertise public :: docn_datamode_cplhist_init_pointers public :: docn_datamode_cplhist_advance - public :: docn_datamode_cplhist_restart_read - public :: docn_datamode_cplhist_restart_write ! export fields real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator @@ -123,39 +119,4 @@ subroutine docn_datamode_cplhist_advance(rc) end subroutine docn_datamode_cplhist_advance - !=============================================================================== - subroutine docn_datamode_cplhist_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine docn_datamode_cplhist_restart_write - - !=============================================================================== - subroutine docn_datamode_cplhist_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine docn_datamode_cplhist_restart_read - end module docn_datamode_cplhist_mod diff --git a/docn/docn_datamode_iaf_mod.F90 b/docn/docn_datamode_iaf_mod.F90 index 23b939a29..7e56afd47 100644 --- a/docn/docn_datamode_iaf_mod.F90 +++ b/docn/docn_datamode_iaf_mod.F90 @@ -1,5 +1,5 @@ module docn_datamode_iaf_mod - use ESMF , only : ESMF_GridComp + use ESMF , only : ESMF_SUCCESS, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_State use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -8,7 +8,6 @@ module docn_datamode_iaf_mod use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_strdata_mod , only : shr_strdata_type - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add use pio @@ -18,8 +17,6 @@ module docn_datamode_iaf_mod public :: docn_datamode_iaf_advertise public :: docn_datamode_iaf_init_pointers public :: docn_datamode_iaf_advance - public :: docn_datamode_iaf_restart_read - public :: docn_datamode_iaf_restart_write ! export fields real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator @@ -41,8 +38,6 @@ module docn_datamode_iaf_mod real(r8) , parameter :: tkfrz = shr_const_tkfrz ! freezing point, fresh water (kelvin) real(r8) , parameter :: ocnsalt = shr_const_ocn_ref_sal ! ocean reference salinity - character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.ocn' character(*) , parameter :: u_FILE_u = & __FILE__ @@ -176,43 +171,4 @@ subroutine docn_datamode_iaf_advance(rc) end subroutine docn_datamode_iaf_advance - !=============================================================================== - subroutine docn_datamode_iaf_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! write restart file - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine docn_datamode_iaf_restart_write - - !=============================================================================== - subroutine docn_datamode_iaf_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - - ! read restart file - - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine docn_datamode_iaf_restart_read - end module docn_datamode_iaf_mod diff --git a/docn/docn_datamode_multilev_dom_mod.F90 b/docn/docn_datamode_multilev_dom_mod.F90 index 578e2b9ba..9c8c35be9 100644 --- a/docn/docn_datamode_multilev_dom_mod.F90 +++ b/docn/docn_datamode_multilev_dom_mod.F90 @@ -1,5 +1,5 @@ module docn_datamode_multilev_dom_mod - use ESMF , only : ESMF_GridComp + use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -7,7 +7,6 @@ module docn_datamode_multilev_dom_mod use shr_sys_mod , only : shr_sys_abort use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type, shr_strdata_get_stream_count implicit none @@ -16,8 +15,6 @@ module docn_datamode_multilev_dom_mod public :: docn_datamode_multilev_dom_advertise public :: docn_datamode_multilev_dom_init_pointers public :: docn_datamode_multilev_dom_advance - public :: docn_datamode_multilev_dom_restart_read - public :: docn_datamode_multilev_dom_restart_write ! pointers to export fields real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator @@ -222,43 +219,4 @@ subroutine docn_datamode_multilev_dom_advance(sdat, logunit, mainproc, rc) end subroutine docn_datamode_multilev_dom_advance - !=============================================================================== - subroutine docn_datamode_multilev_dom_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! write restart file - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine docn_datamode_multilev_dom_restart_write - - !=============================================================================== - subroutine docn_datamode_multilev_dom_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - - ! read restart file - - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine docn_datamode_multilev_dom_restart_read - end module docn_datamode_multilev_dom_mod diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index b522862e6..aaa24258f 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -1,5 +1,4 @@ module docn_datamode_multilev_mod - use ESMF , only : ESMF_GridComp use ESMF , only : ESMF_State, ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_SUCCESS use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -7,7 +6,6 @@ module docn_datamode_multilev_mod use shr_sys_mod , only : shr_sys_abort use dshr_methods_mod , only : dshr_state_getfldptr, dshr_fldbun_getfldptr, chkerr use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add - use dshr_mod , only : dshr_restart_read, dshr_restart_write use dshr_strdata_mod , only : shr_strdata_get_stream_pointer, shr_strdata_type implicit none @@ -16,8 +14,6 @@ module docn_datamode_multilev_mod public :: docn_datamode_multilev_advertise public :: docn_datamode_multilev_init_pointers public :: docn_datamode_multilev_advance - public :: docn_datamode_multilev_restart_read - public :: docn_datamode_multilev_restart_write ! pointers to export fields real(r8), pointer :: So_omask(:) => null() ! real ocean fraction sent to mediator @@ -188,43 +184,4 @@ subroutine docn_datamode_multilev_advance(sdat, logunit, mainproc, rc) end subroutine docn_datamode_multilev_advance - !=============================================================================== - subroutine docn_datamode_multilev_restart_write(case_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - ! write restart file - - ! input/output variables - character(len=*) , intent(in) :: case_name - character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: ymd ! model date - integer , intent(in) :: tod ! model sec into model date - integer , intent(in) :: logunit - integer , intent(in) :: my_task - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, ymd, tod, & - logunit, my_task, sdat) - - end subroutine docn_datamode_multilev_restart_write - - !=============================================================================== - subroutine docn_datamode_multilev_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) - - ! read restart file - - ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp - character(len=*) , intent(inout) :: rest_filem - integer , intent(in) :: logunit - integer , intent(in) :: my_task - integer , intent(in) :: mpicom - type(shr_strdata_type) , intent(inout) :: sdat - !------------------------------------------------------------------------------- - - call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat) - - end subroutine docn_datamode_multilev_restart_read - end module docn_datamode_multilev_mod diff --git a/docn/docn_datamode_som_mod.F90 b/docn/docn_datamode_som_mod.F90 index 76b6bde95..92e51c0f8 100644 --- a/docn/docn_datamode_som_mod.F90 +++ b/docn/docn_datamode_som_mod.F90 @@ -1,9 +1,9 @@ module docn_datamode_som_mod - + use ESMF , only : ESMF_SUCCESS, ESMF_State, ESMF_Clock, ESMF_StateGet, ESMF_StateItem_Flag use ESMF , only : ESMF_TimeInterval, ESMF_ClockGet, ESMF_TimeIntervalGet use ESMF , only : ESMF_LOGMSG_INFO, ESMF_STATEITEM_NOTFOUND, operator(/=) - use ESMF , only : ESMF_LogWrite, ESMF_GridComp + use ESMF , only : ESMF_LogWrite use NUOPC , only : NUOPC_Advertise use shr_kind_mod , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs use shr_sys_mod , only : shr_sys_abort @@ -66,7 +66,6 @@ module docn_datamode_som_mod real(r8) , parameter :: ocnsalt = shr_const_ocn_ref_sal ! ocean reference salinity character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.ocn' character(*) , parameter :: u_FILE_u = & __FILE__ @@ -305,12 +304,13 @@ subroutine docn_datamode_som_advance(importState, exportState, clock, restart_re end subroutine docn_datamode_som_advance !=============================================================================== - subroutine docn_datamode_som_restart_write(case_name, inst_suffix, ymd, tod, & + subroutine docn_datamode_som_restart_write(rpfile, case_name, inst_suffix, ymd, tod, & logunit, my_task, sdat) ! write restart file ! input/output variables + character(len=*) , intent(in) :: rpfile character(len=*) , intent(in) :: case_name character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: ymd ! model date @@ -319,32 +319,33 @@ subroutine docn_datamode_som_restart_write(case_name, inst_suffix, ymd, tod, & integer , intent(in) :: my_task type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - + integer :: rc call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, ymd, tod, & - logunit, my_task, sdat, fld=somtp, fldname='somtp') + logunit, my_task, sdat, rc, fld=somtp, fldname='somtp') + if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine docn_datamode_som_restart_write !=============================================================================== - subroutine docn_datamode_som_restart_read(gcomp, rest_filem, logunit, my_task, mpicom, sdat) + subroutine docn_datamode_som_restart_read(rest_filem, rpfile, logunit, my_task, mpicom, sdat) ! read restart file ! input/output arguments - type(ESMF_GridComp) , intent(in) :: gcomp character(len=*) , intent(inout) :: rest_filem + character(len=*) , intent(in) :: rpfile integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat !------------------------------------------------------------------------------- - + integer :: rc ! allocate module memory for restart fields that are read in allocate(somtp(sdat%model_lsize)) - ! read restart - call dshr_restart_read(gcomp, rest_filem, 'ocn', nullstr, logunit, my_task, mpicom, sdat, & + call dshr_restart_read(rest_filem, rpfile, logunit, my_task, mpicom, sdat, rc,& fld=somtp, fldname='somtp') + if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine docn_datamode_som_restart_read diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index 1d7366a3f..ce57ed8ee 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -29,22 +29,20 @@ module cdeps_docn_comp use shr_log_mod , only : shr_log_setLogUnit use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_init_from_config - use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init + use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init, dshr_restart_read use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_check_restart_alarm + use dshr_mod , only : dshr_restart_write use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_realize + use nuopc_shr_methods, only : shr_get_rpointer_name ! Datamode specialized modules use docn_datamode_copyall_mod , only : docn_datamode_copyall_advertise use docn_datamode_copyall_mod , only : docn_datamode_copyall_init_pointers use docn_datamode_copyall_mod , only : docn_datamode_copyall_advance - use docn_datamode_copyall_mod , only : docn_datamode_copyall_restart_read - use docn_datamode_copyall_mod , only : docn_datamode_copyall_restart_write use docn_datamode_iaf_mod , only : docn_datamode_iaf_advertise use docn_datamode_iaf_mod , only : docn_datamode_iaf_init_pointers use docn_datamode_iaf_mod , only : docn_datamode_iaf_advance - use docn_datamode_iaf_mod , only : docn_datamode_iaf_restart_read - use docn_datamode_iaf_mod , only : docn_datamode_iaf_restart_write use docn_datamode_som_mod , only : docn_datamode_som_advertise use docn_datamode_som_mod , only : docn_datamode_som_init_pointers use docn_datamode_som_mod , only : docn_datamode_som_advance @@ -56,18 +54,12 @@ module cdeps_docn_comp use docn_datamode_cplhist_mod , only : docn_datamode_cplhist_advertise use docn_datamode_cplhist_mod , only : docn_datamode_cplhist_init_pointers use docn_datamode_cplhist_mod , only : docn_datamode_cplhist_advance - use docn_datamode_cplhist_mod , only : docn_datamode_cplhist_restart_read - use docn_datamode_cplhist_mod , only : docn_datamode_cplhist_restart_write use docn_datamode_multilev_mod , only : docn_datamode_multilev_advertise use docn_datamode_multilev_mod , only : docn_datamode_multilev_init_pointers use docn_datamode_multilev_mod , only : docn_datamode_multilev_advance - use docn_datamode_multilev_mod , only : docn_datamode_multilev_restart_read - use docn_datamode_multilev_mod , only : docn_datamode_multilev_restart_write use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_advertise use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_init_pointers use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_advance - use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_restart_read - use docn_datamode_multilev_dom_mod, only : docn_datamode_multilev_dom_restart_write use docn_import_data_mod , only : docn_import_data_advertise implicit none @@ -525,7 +517,7 @@ subroutine docn_comp_run(gcomp, importState, exportState, clock, target_ymd, tar ! -------------------------- ! input/output variables: - type(ESMF_GridComp) , intent(in) :: gcomp + type(ESMF_GridComp), intent(in) :: gcomp type(ESMF_Clock) , intent(in) :: clock type(ESMF_State) , intent(inout) :: importState type(ESMF_State) , intent(inout) :: exportState @@ -536,6 +528,7 @@ subroutine docn_comp_run(gcomp, importState, exportState, clock, target_ymd, tar ! local variables logical :: first_time = .true. + character(len=CL) :: rpfile ! restart pointer file name character(*), parameter :: subName = "(docn_comp_run) " !------------------------------------------------------------------------------- @@ -580,13 +573,15 @@ subroutine docn_comp_run(gcomp, importState, exportState, clock, target_ymd, tar ! Read restart if needed if (restart_read .and. .not. skip_restart_read) then + call shr_get_rpointer_name(gcomp, 'ocn', target_ymd, target_tod, rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + select case (trim(datamode)) - case('sstdata', 'sst_aquap_file') - call docn_datamode_copyall_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) - case('iaf') - call docn_datamode_iaf_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) + case('sstdata', 'sst_aquap_file', 'iaf', 'cplhist', 'multilev', 'mulitilev_dom') + call dshr_restart_read(restfilm, rpfile, logunit, my_task, mpicom, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return case('som', 'som_aquap') - call docn_datamode_som_restart_read(gcomp, restfilm, logunit, my_task, mpicom, sdat) + call docn_datamode_som_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) end select end if @@ -643,21 +638,22 @@ subroutine docn_comp_run(gcomp, importState, exportState, clock, target_ymd, tar ! Write restarts if needed (no restarts for aquaplanet analytic or aquaplanet input file) if (restart_write) then - select case (trim(datamode)) - case('sstdata','sst_aquap_file') - call docn_datamode_copyall_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - case('iaf') - call docn_datamode_iaf_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - case('som','som_aquap') - call docn_datamode_som_restart_write(case_name, inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - case('cplhist') - call docn_datamode_cplhist_restart_write(case_name, inst_suffix, target_ymd, target_tod, & + call shr_get_rpointer_name(gcomp, 'ocn', target_ymd, target_tod, rpfile, 'write', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + select case (trim(datamode)) + case('sstdata', 'sst_aquap_file', 'iaf', 'cplhist', 'multilev', 'mulitilev_dom') + call dshr_restart_write(rpfile, case_name, 'docn', inst_suffix, target_ymd, target_tod, logunit, & + my_task, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('som', 'som_aquap') + call docn_datamode_som_restart_write(rpfile, case_name, inst_suffix, target_ymd, target_tod, & logunit, my_task, sdat) - end select - end if + case default + call shr_sys_abort(subName//'datamode '//trim(datamode)//' not recognized') + end select + + endif call ESMF_TraceRegionExit('DOCN_RUN') diff --git a/drof/rof_comp_nuopc.F90 b/drof/rof_comp_nuopc.F90 index 5b9e5ef1f..e35f78fd0 100644 --- a/drof/rof_comp_nuopc.F90 +++ b/drof/rof_comp_nuopc.F90 @@ -36,6 +36,7 @@ module cdeps_drof_comp use dshr_mod , only : dshr_restart_read, dshr_restart_write, dshr_mesh_init use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add, dshr_fldlist_realize + use nuopc_shr_methods, only : shr_get_rpointer_name implicit none private ! except @@ -388,6 +389,7 @@ subroutine drof_comp_run(gcomp, exportState, target_ymd, target_tod, restart_wri ! local variables logical :: first_time = .true. integer :: n + character(len=CL) :: rpfile character(*), parameter :: subName = "(drof_comp_run) " !------------------------------------------------------------------------------- @@ -412,7 +414,10 @@ subroutine drof_comp_run(gcomp, exportState, target_ymd, target_tod, restart_wri ! Read restart if needed if (restart_read .and. .not. skip_restart_read) then - call dshr_restart_read(gcomp, restfilm, 'rof', nullstr, logunit, my_task, mpicom, sdat) + call shr_get_rpointer_name(gcomp, 'rof', target_ymd, target_tod, rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_restart_read(restfilm, rpfile, logunit, my_task, mpicom, sdat, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end if first_time = .false. @@ -447,11 +452,13 @@ subroutine drof_comp_run(gcomp, exportState, target_ymd, target_tod, restart_wri ! write restarts if needed if (restart_write) then - select case (trim(datamode)) - case('copyall') + if(trim(datamode) .eq. 'copyall') then + call shr_get_rpointer_name(gcomp, 'rof', target_ymd, target_tod, rpfile, 'write', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_restart_write(rpfile, case_name, 'drof', inst_suffix, target_ymd, target_tod, & - logunit, my_task, sdat) - end select + logunit, my_task, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + endif end if ! write diagnostics diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index faa346b68..8ea10dca3 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -950,8 +950,8 @@ subroutine dshr_time_init( Time, ymd, cal, tod, rc) end subroutine dshr_time_init !=============================================================================== - subroutine dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, & - logunit, my_task, mpicom, sdat, fld, fldname) + subroutine dshr_restart_read(rest_filem, rpfile, & + logunit, my_task, mpicom, sdat, rc, fld, fldname) ! Read restart file @@ -960,12 +960,11 @@ subroutine dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, & ! input/output arguments character(len=*) , intent(inout) :: rest_filem character(len=*) , intent(in) :: rpfile - character(len=*) , intent(in) :: inst_suffix - character(len=*) , intent(in) :: nullstr integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom type(shr_strdata_type) , intent(inout) :: sdat + integer , intent(out) :: rc real(r8) , optional , pointer :: fld(:) character(len=*) , optional , intent(in) :: fldname @@ -977,26 +976,20 @@ subroutine dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, & type(var_desc_t) :: varid type(io_desc_t) :: pio_iodesc integer :: rcode - integer :: rc integer :: tmp(1) character(*), parameter :: F00 = "('(dshr_restart_read) ',8a)" character(*), parameter :: subName = "(dshr_restart_read) " !------------------------------------------------------------------------------- - + rc = ESMF_SUCCESS ! no streams means no restart file is read. if(shr_strdata_get_stream_count(sdat) <= 0) return call ESMF_VMGetCurrent(vm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return exists = .false. - if (trim(rest_filem) == trim(nullstr)) then + if (trim(rest_filem) == 'none') then if (my_task == main_task) then - write(logunit,F00) ' restart filename from rpointer' - inquire(file=trim(rpfile)//trim(inst_suffix), exist=exists) - if (.not.exists) then - write(logunit, F00) ' ERROR: rpointer file does not exist' - call shr_sys_abort(trim(subname)//' ERROR: rpointer file missing') - endif - open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') + write(logunit,F00) ' restart filename from rpointer '//trim(rpfile) + open(newunit=nu, file=trim(rpfile), form='formatted') read(nu, '(a)') rest_filem close(nu) inquire(file=trim(rest_filem), exist=exists) @@ -1035,7 +1028,7 @@ end subroutine dshr_restart_read !=============================================================================== subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, tod, & - logunit, my_task, sdat, fld, fldname) + logunit, my_task, sdat, rc, fld, fldname) ! Write restart file @@ -1051,6 +1044,7 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t integer , intent(in) :: logunit integer , intent(in) :: my_task type(shr_strdata_type) , intent(inout) :: sdat + integer , intent(out) :: rc real(r8) , optional , pointer :: fld(:) character(len=*) , optional , intent(in) :: fldname @@ -1067,6 +1061,7 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t character(*), parameter :: F00 = "('(dshr_restart_write) ',2a,2(i0,2x))" !------------------------------------------------------------------------------- + rc = ESMF_SUCCESS ! no streams means no restart file is written. if (shr_strdata_get_stream_count(sdat) <= 0) return @@ -1075,10 +1070,10 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t ! write restart info to rpointer file if (my_task == main_task) then - open(newunit=nu, file=trim(rpfile)//trim(inst_suffix), form='formatted') + open(newunit=nu, file=trim(rpfile), form='formatted') write(nu,'(a)') rest_file_model close(nu) - write(logunit,F00)' writing ',trim(rest_file_model), ymd, tod + write(logunit,F00)' writing ',trim(rest_file_model) endif ! write data model restart data diff --git a/dwav/wav_comp_nuopc.F90 b/dwav/wav_comp_nuopc.F90 index cb850e5da..0a5a25d02 100644 --- a/dwav/wav_comp_nuopc.F90 +++ b/dwav/wav_comp_nuopc.F90 @@ -34,6 +34,7 @@ module cdeps_dwav_comp use dshr_mod , only : dshr_restart_read, dshr_restart_write, dshr_mesh_init use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add, dshr_fldlist_realize + use nuopc_shr_methods, only : shr_get_rpointer_name implicit none private ! except @@ -249,7 +250,6 @@ end subroutine InitializeAdvertise !=============================================================================== subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) - ! input/output variables type(ESMF_GridComp) :: gcomp type(ESMF_State) :: importState, exportState @@ -263,6 +263,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) integer :: current_mon ! model month integer :: current_day ! model day integer :: current_tod ! model sec into model date + character(len=CL):: rpfile character(len=*), parameter :: subname=trim(modName)//':(InitializeRealize) ' !------------------------------------------------------------------------------- @@ -288,11 +289,6 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) call dwav_comp_realize(importState, exportState, export_all, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Read restart if necessary - if (restart_read .and. .not. skip_restart_read) then - call dshr_restart_read(gcomp, restfilm, 'wav', nullstr, logunit, my_task, mpicom, sdat) - end if - ! Get the time to interpolate the stream data to call ESMF_ClockGet(clock, currTime=currTime, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -300,6 +296,15 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call shr_cal_ymd2date(current_year, current_mon, current_day, current_ymd) + + ! Read restart if necessary + if (restart_read .and. .not. skip_restart_read) then + call shr_get_rpointer_name(gcomp, 'wav', current_ymd, current_tod, rpfile, 'read', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_restart_read(restfilm, rpfile, logunit, my_task, mpicom, sdat, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + ! Run dwav to create export state call dwav_comp_run(logunit, current_ymd, current_tod, sdat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -330,6 +335,7 @@ subroutine ModelAdvance(gcomp, rc) integer :: next_ymd ! model date integer :: next_tod ! model sec into model date logical :: write_restart + character(len=CL):: rpfile character(len=*),parameter :: subname=trim(modName)//':(ModelAdvance) ' !------------------------------------------------------------------------------- @@ -364,9 +370,12 @@ subroutine ModelAdvance(gcomp, rc) call ESMF_TraceRegionEnter('dwav_restart') call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call shr_get_rpointer_name(gcomp, 'wav', next_ymd, next_tod, rpfile, 'write', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call dshr_restart_write(rpfile, case_name, 'dwav', inst_suffix, next_ymd, next_tod, & - logunit, my_task, sdat) + logunit, my_task, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('dwav_restart') endif From 328d94a4b3e54d485d45e2ecac25a566470d6e32 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 5 Sep 2024 14:40:16 -0600 Subject: [PATCH 148/170] update aux_cdeps tests for cesm3 --- datm/cime_config/testdefs/testlist_datm.xml | 8 ++++---- dice/cime_config/testdefs/testlist_dice.xml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/datm/cime_config/testdefs/testlist_datm.xml b/datm/cime_config/testdefs/testlist_datm.xml index a20e56305..34bbe3fcf 100644 --- a/datm/cime_config/testdefs/testlist_datm.xml +++ b/datm/cime_config/testdefs/testlist_datm.xml @@ -70,7 +70,7 @@ - + @@ -79,7 +79,7 @@ - + @@ -88,7 +88,7 @@ - + @@ -97,7 +97,7 @@ - + diff --git a/dice/cime_config/testdefs/testlist_dice.xml b/dice/cime_config/testdefs/testlist_dice.xml index 909980ce6..948dc092d 100644 --- a/dice/cime_config/testdefs/testlist_dice.xml +++ b/dice/cime_config/testdefs/testlist_dice.xml @@ -1,7 +1,7 @@ - + @@ -10,7 +10,7 @@ - + From 9b22a506d661f50f71d03e1d73170c2b2d4b3663 Mon Sep 17 00:00:00 2001 From: Katetc Date: Thu, 5 Sep 2024 15:17:48 -0600 Subject: [PATCH 149/170] Final code cleanup and review comments --- dglc/dglc_datamode_noevolve_mod.F90 | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/dglc/dglc_datamode_noevolve_mod.F90 b/dglc/dglc_datamode_noevolve_mod.F90 index 3b64c884f..6a7caa58a 100644 --- a/dglc/dglc_datamode_noevolve_mod.F90 +++ b/dglc/dglc_datamode_noevolve_mod.F90 @@ -261,9 +261,7 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form real(r8) :: usrf ! upper surface elevation (m) on ice grid real(r8) :: loc_pos_smb(1), Tot_pos_smb(1) ! Sum of positive smb values on each ice sheet for hole-filling real(r8) :: loc_neg_smb(1), Tot_neg_smb(1) ! Sum of negative smb values on each ice sheet for hole-filling - real(r8) :: num_Tot ! Number of active grid cells in total calculation real(r8) :: rat ! Ratio of hole-filling flux to apply - real(r8), allocatable :: ice_runoff_out(:) ! Scaled ice runoff output after holes filled character(len=*), parameter :: subname='(dglc_datamode_noevolve_advance): ' !------------------------------------------------------------------------------- @@ -395,25 +393,22 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form ! Compute Fgrg_rofi do ns = 1,num_icesheets - ! Get mesh info - call ESMF_MeshGet(model_meshes(ns), elementdistGrid=distGrid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Get number of grid cells per ice sheet lsize = size(Fgrg_rofi(ns)%ptr) - - allocate(ice_runoff_out(lsize)) - ice_runoff_out(:) = 0.d0 + + ! reset output variables to zero + Fgrg_rofi(ns)%ptr(:) = 0.d0 loc_pos_smb(1) = 0.d0 Tot_pos_smb(1) = 0.d0 loc_neg_smb(1) = 0.d0 Tot_neg_smb(1) = 0.d0 - num_Tot = 0.d0 rat = 0.d0 ! For No Evolve to reduce negative ice fluxes from DGLC, we will ! Calculate the total positive and total negative fluxes on each ! processor first (local totals). do ng = 1,lsize - if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then + if (Sg_icemask_coupled_fluxes(ns)%ptr(ng) > 0.d0) then if(Flgl_qice(ns)%ptr(ng) > 0.d0) then loc_pos_smb(1) = loc_pos_smb(1)+Flgl_qice(ns)%ptr(ng)*Sg_area(ns)%ptr(ng) end if @@ -433,7 +428,7 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form call ESMF_VMAllreduce(vm, senddata=loc_neg_smb, recvdata=Tot_neg_smb, count=1, & reduceflag=ESMF_REDUCE_SUM, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + ! If there's more positive than negative, then set all ! negative to zero and destribute the negative flux amount ! across the positive values, scaled by the size of the @@ -442,7 +437,7 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form ! runoff is exactly equal to the input smb. if(abs(Tot_pos_smb(1)) >= abs(Tot_neg_smb(1))) then do ng = 1,lsize - if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then + if (Sg_icemask_coupled_fluxes(ns)%ptr(ng) > 0.d0) then if(Flgl_qice(ns)%ptr(ng) > 0.d0) then rat = Flgl_qice(ns)%ptr(ng)/Tot_pos_smb(1) Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_neg_smb(1) @@ -459,7 +454,7 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form ! reduce their negativity a bit. This shouldn't happen often. ! This section of code also applies if Tot_pos_smb is zero. do ng = 1,lsize - if (Sg_icemask_coupled_fluxes(ns)%ptr(ng).gt.0.d0) then + if (Sg_icemask_coupled_fluxes(ns)%ptr(ng) > 0.d0) then if(Flgl_qice(ns)%ptr(ng) < 0.d0) then rat = Flgl_qice(ns)%ptr(ng)/Tot_neg_smb(1) Fgrg_rofi(ns)%ptr(ng) = Flgl_qice(ns)%ptr(ng) + rat*Tot_pos_smb(1) @@ -473,9 +468,8 @@ subroutine dglc_datamode_noevolve_advance(gcomp, pio_subsystem, io_type, io_form end if ! More neg or pos smb - deallocate(ice_runoff_out) - end do - end if + end do ! Each ice sheet + end if ! if initialized ! Set initialized flag initialized_noevolve = .true. From 03057bd91d9a0e06dc92c4e9a7dea13916e1dc59 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 6 Sep 2024 09:59:57 -0600 Subject: [PATCH 150/170] add use statement in lnd and change to restart test for dglc --- dglc/cime_config/testdefs/testlist_dglc.xml | 2 +- dlnd/lnd_comp_nuopc.F90 | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dglc/cime_config/testdefs/testlist_dglc.xml b/dglc/cime_config/testdefs/testlist_dglc.xml index 8383469c7..2ab88bccb 100644 --- a/dglc/cime_config/testdefs/testlist_dglc.xml +++ b/dglc/cime_config/testdefs/testlist_dglc.xml @@ -1,7 +1,7 @@ - + diff --git a/dlnd/lnd_comp_nuopc.F90 b/dlnd/lnd_comp_nuopc.F90 index f7527da65..a40685bc7 100644 --- a/dlnd/lnd_comp_nuopc.F90 +++ b/dlnd/lnd_comp_nuopc.F90 @@ -35,7 +35,8 @@ module cdeps_dlnd_comp use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_add, dshr_fldlist_realize use glc_elevclass_mod , only : glc_elevclass_as_string, glc_elevclass_init - + use nuopc_shr_methods , only : shr_get_rpointer_name + implicit none private ! except From 93cc684b1196d505ba35cacd8160783b0f10a25e Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 6 Sep 2024 10:43:10 -0600 Subject: [PATCH 151/170] revert change to test, update nuopc_shr_methods --- dglc/cime_config/testdefs/testlist_dglc.xml | 2 +- share/nuopc_shr_methods.F90 | 169 +++++++++++++++++++- 2 files changed, 168 insertions(+), 3 deletions(-) diff --git a/dglc/cime_config/testdefs/testlist_dglc.xml b/dglc/cime_config/testdefs/testlist_dglc.xml index 2ab88bccb..8383469c7 100644 --- a/dglc/cime_config/testdefs/testlist_dglc.xml +++ b/dglc/cime_config/testdefs/testlist_dglc.xml @@ -1,7 +1,7 @@ - + diff --git a/share/nuopc_shr_methods.F90 b/share/nuopc_shr_methods.F90 index d65a9cc69..e6bcfba5f 100644 --- a/share/nuopc_shr_methods.F90 +++ b/share/nuopc_shr_methods.F90 @@ -18,6 +18,7 @@ module nuopc_shr_methods use ESMF , only : ESMF_Time, ESMF_TimeGet, ESMF_TimeSet, ESMF_ClockGetAlarm use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalSet, ESMF_TimeIntervalGet use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMBroadcast, ESMF_VMGetCurrent + use ESMF , only : ESMF_ClockGetNextTime use NUOPC , only : NUOPC_CompAttributeGet use NUOPC_Model , only : NUOPC_ModelGet use shr_kind_mod , only : r8 => shr_kind_r8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -35,11 +36,12 @@ module nuopc_shr_methods public :: state_setscalar public :: state_diagnose public :: alarmInit + public :: get_minimum_timestep public :: chkerr - + public :: shr_get_rpointer_name private :: timeInit private :: field_getfldptr - + ! Module data ! Clock and alarm options shared with esm_time_mod along with dtime_driver which is initialized there. @@ -760,6 +762,169 @@ end subroutine timeInit !=============================================================================== + integer function get_minimum_timestep(gcomp, rc) + ! Get the minimum timestep interval in seconds based on the nuopc.config variables *_cpl_dt, + ! if none of these variables are defined this routine will throw an error + type(ESMF_GridComp), intent(in) :: gcomp + integer, intent(out) :: rc + + character(len=CS) :: cvalue + integer :: atm_cpl_dt ! Atmosphere coupling interval + integer :: lnd_cpl_dt ! Land coupling interval + integer :: ice_cpl_dt ! Sea-Ice coupling interval + integer :: ocn_cpl_dt ! Ocean coupling interval + integer :: glc_cpl_dt ! Glc coupling interval + integer :: rof_cpl_dt ! Runoff coupling interval + integer :: wav_cpl_dt ! Wav coupling interval + logical :: is_present, is_set ! determine if these variables are used + integer :: esp_cpl_dt ! Esp coupling interval + + !--------------------------------------------------------------------------- + ! Determine driver clock timestep + !--------------------------------------------------------------------------- + get_minimum_timestep = huge(1) + + call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) atm_cpl_dt + get_minimum_timestep = min(atm_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) lnd_cpl_dt + get_minimum_timestep = min(lnd_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ice_cpl_dt + get_minimum_timestep = min(ice_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ocn_cpl_dt + get_minimum_timestep = min(ocn_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) glc_cpl_dt + get_minimum_timestep = min(glc_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) rof_cpl_dt + get_minimum_timestep = min(rof_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) wav_cpl_dt + get_minimum_timestep = min(wav_cpl_dt, get_minimum_timestep) + endif + + call NUOPC_CompAttributeGet(gcomp, name="esp_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (is_present .and. is_set) then + call NUOPC_CompAttributeGet(gcomp, name="esp_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) esp_cpl_dt + get_minimum_timestep = min(esp_cpl_dt, get_minimum_timestep) + endif + if(get_minimum_timestep == huge(1)) then + call ESMF_LogWrite('minimum_timestep_error: this option is not supported ', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + if(get_minimum_timestep <= 0) then + print *,__FILE__,__LINE__,atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt + call ESMF_LogWrite('minimum_timestep_error ERROR ', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + end function get_minimum_timestep + + subroutine shr_get_rpointer_name(gcomp, compname, ymd, time, rpfile, mode, rc) + type(ESMF_GRIDCOMP), intent(in) :: gcomp + character(len=3), intent(in) :: compname + integer, intent(in) :: ymd + integer, intent(in) :: time + character(len=*), intent(out) :: rpfile + character(len=*), intent(in) :: mode + integer, intent(out) :: rc + + ! local vars + integer :: yr, mon, day + character(len=16) timestr + logical :: isPresent + character(len=ESMF_MAXSTR) :: inst_suffix + + character(len=*), parameter :: subname='shr_get_rpointer_name' + + rc = ESMF_SUCCESS + + inst_suffix = "" + call NUOPC_CompAttributeGet(gcomp, name='inst_suffix', isPresent=isPresent, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if(ispresent) call NUOPC_CompAttributeGet(gcomp, name='inst_suffix', value=inst_suffix, rc=rc) + + yr = ymd/10000 + mon = (ymd - yr*10000)/100 + day = (ymd - yr*10000 - mon*100) + write(timestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',time + + rpfile = "rpointer."//compname + if (trim(inst_suffix) .ne. "") then + write(rpfile,*) trim(rpfile),".",trim(inst_suffix) + endif + write(rpfile,*) trim(rpfile),".",timestr + if (mode.eq.'read') then + inquire(file=trim(rpfile), exist=isPresent) + if(.not. isPresent) then + rpfile = "rpointer."//compname + if (inst_suffix .ne. "") then + rpfile = trim(rpfile)//"."//trim(inst_suffix) + endif + inquire(file=trim(rpfile), exist=isPresent) + if(.not. isPresent) then + call shr_sys_abort( subname//'ERROR no rpointer file found in '//rpfile//' or in '//rpfile//'.'//timestr ) + endif + endif + endif + end subroutine shr_get_rpointer_name + logical function chkerr(rc, line, file) integer, intent(in) :: rc From f90b42e5d8358ecd9e65c43344c2072aa3085402 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 6 Sep 2024 12:53:09 -0600 Subject: [PATCH 152/170] add DATAMODELTEST compset alias --- cime_config/config_compsets.xml | 57 +++++++++++++++++++++ datm/atm_comp_nuopc.F90 | 2 - dglc/cime_config/testdefs/testlist_dglc.xml | 14 +++-- 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 cime_config/config_compsets.xml diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml new file mode 100644 index 000000000..7c92d45f9 --- /dev/null +++ b/cime_config/config_compsets.xml @@ -0,0 +1,57 @@ + + + + + + ========================================= + compset naming convention + ========================================= + The compset longname below has the specified order + atm, lnd, ice, ocn, river, glc wave cesm-options + + The notation for the compset longname is + TIME_ATM[%phys]_LND[%phys]_ICE[%phys]_OCN[%phys]_ROF[%phys]_GLC[%phys]_WAV[%phys][_ESP%phys][_BGC%phys] + Where for the specific compsets below the following is supported + TIME = Time period (e.g. 2000, HIST, RCP8...) + ATM = [CAM40, CAM50, CAM60] + LND = [CLM45, CLM50, SLND] + ICE = [CICE, DICE, SICE] + OCN = [MOM6, DOCN, SOCN] + ROF = [RTM, MOSART, SROF] + GLC = [CISM2, DGLC, SGLC] + WAV = [WW3, DWAV, XWAV, SWAV] + ESP = [SESP] + BGC = optional BGC scenario + + The OPTIONAL %phys attributes specify submodes of the given system + For example DOCN%DOM is the data ocean model for DOCN + ALL the possible %phys choices for each component are listed. + ALL data models must have a %phys option that corresponds to the data model mode + + Each compset node is associated with the following elements + - lname + - alias + - support (optional description of the support level for this compset) + Each compset node can also have the following attributes + - grid (optional regular expression match for grid to work with the compset) + + + DATAMODELTEST + HIST_DATM%JRA_DLND%SCPL_DICE%SSMI_DOCN%DOM_DGLC%NOEVOLVE_DWAV%CLIMO + + + + + + + 0001-01-01 + 2000-01-01 + 1850-01-01 + 1955-01-01 + 2005-01-01 + 2013-01-01 + + + + + diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 9d7de76f8..12b462af4 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -586,9 +586,7 @@ subroutine datm_comp_run(gcomp, importState, exportState, target_ymd, target_tod ! local variables logical :: first_time = .true. character(len=CL) :: rpfile - character(len=16) :: timestr character(*), parameter :: subName = '(datm_comp_run) ' - integer :: yr, mon, day !------------------------------------------------------------------------------- rc = ESMF_SUCCESS diff --git a/dglc/cime_config/testdefs/testlist_dglc.xml b/dglc/cime_config/testdefs/testlist_dglc.xml index 8383469c7..352530660 100644 --- a/dglc/cime_config/testdefs/testlist_dglc.xml +++ b/dglc/cime_config/testdefs/testlist_dglc.xml @@ -1,7 +1,7 @@ - + @@ -10,7 +10,7 @@ - + @@ -19,7 +19,7 @@ - + @@ -29,4 +29,12 @@ + + + + + + + + From 743120d74c8c365da178a6d9359e8223491eabc8 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 11 Sep 2024 10:31:36 -0600 Subject: [PATCH 153/170] fix ocn_aquap analytic cases --- docn/ocn_comp_nuopc.F90 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index ce57ed8ee..4bf9e5acd 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -558,6 +558,7 @@ subroutine docn_comp_run(gcomp, importState, exportState, clock, target_ymd, tar call docn_datamode_som_init_pointers(importState, exportState, sdat, model_frac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case('sst_aquap_analytic', 'sst_aquap_constant') + skip_restart_read=.true. call docn_datamode_aquaplanet_init_pointers(exportState, model_frac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case('cplhist') @@ -649,6 +650,8 @@ subroutine docn_comp_run(gcomp, importState, exportState, clock, target_ymd, tar case('som', 'som_aquap') call docn_datamode_som_restart_write(rpfile, case_name, inst_suffix, target_ymd, target_tod, & logunit, my_task, sdat) + case('sst_aquap_analytic', 'sst_aquap_constant') + ! Do nothing case default call shr_sys_abort(subName//'datamode '//trim(datamode)//' not recognized') end select From 4fecfe394aaf1998c8aeb40fb668279ecc44899a Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 30 Sep 2024 09:49:52 -0600 Subject: [PATCH 154/170] fix testlist_dglc formating --- dglc/cime_config/testdefs/testlist_dglc.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dglc/cime_config/testdefs/testlist_dglc.xml b/dglc/cime_config/testdefs/testlist_dglc.xml index 352530660..f87182fba 100644 --- a/dglc/cime_config/testdefs/testlist_dglc.xml +++ b/dglc/cime_config/testdefs/testlist_dglc.xml @@ -30,7 +30,9 @@ - + + + From 302c33fa1da5cf2b725fdefd0781a8b3b8a03c6f Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 1 Oct 2024 08:07:17 -0600 Subject: [PATCH 155/170] remove the config_compsets file --- cime_config/config_compsets.xml | 57 --------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 cime_config/config_compsets.xml diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml deleted file mode 100644 index 7c92d45f9..000000000 --- a/cime_config/config_compsets.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - ========================================= - compset naming convention - ========================================= - The compset longname below has the specified order - atm, lnd, ice, ocn, river, glc wave cesm-options - - The notation for the compset longname is - TIME_ATM[%phys]_LND[%phys]_ICE[%phys]_OCN[%phys]_ROF[%phys]_GLC[%phys]_WAV[%phys][_ESP%phys][_BGC%phys] - Where for the specific compsets below the following is supported - TIME = Time period (e.g. 2000, HIST, RCP8...) - ATM = [CAM40, CAM50, CAM60] - LND = [CLM45, CLM50, SLND] - ICE = [CICE, DICE, SICE] - OCN = [MOM6, DOCN, SOCN] - ROF = [RTM, MOSART, SROF] - GLC = [CISM2, DGLC, SGLC] - WAV = [WW3, DWAV, XWAV, SWAV] - ESP = [SESP] - BGC = optional BGC scenario - - The OPTIONAL %phys attributes specify submodes of the given system - For example DOCN%DOM is the data ocean model for DOCN - ALL the possible %phys choices for each component are listed. - ALL data models must have a %phys option that corresponds to the data model mode - - Each compset node is associated with the following elements - - lname - - alias - - support (optional description of the support level for this compset) - Each compset node can also have the following attributes - - grid (optional regular expression match for grid to work with the compset) - - - DATAMODELTEST - HIST_DATM%JRA_DLND%SCPL_DICE%SSMI_DOCN%DOM_DGLC%NOEVOLVE_DWAV%CLIMO - - - - - - - 0001-01-01 - 2000-01-01 - 1850-01-01 - 1955-01-01 - 2005-01-01 - 2013-01-01 - - - - - From d5da82e88995b42451bfbd2abbf26d1f9e163433 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 1 Oct 2024 11:19:18 -0600 Subject: [PATCH 156/170] update nuopc_shr_methods to share1.1.3 --- share/nuopc_shr_methods.F90 | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/share/nuopc_shr_methods.F90 b/share/nuopc_shr_methods.F90 index e6bcfba5f..02de842f9 100644 --- a/share/nuopc_shr_methods.F90 +++ b/share/nuopc_shr_methods.F90 @@ -905,18 +905,11 @@ subroutine shr_get_rpointer_name(gcomp, compname, ymd, time, rpfile, mode, rc) day = (ymd - yr*10000 - mon*100) write(timestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',time - rpfile = "rpointer."//compname - if (trim(inst_suffix) .ne. "") then - write(rpfile,*) trim(rpfile),".",trim(inst_suffix) - endif - write(rpfile,*) trim(rpfile),".",timestr + write(rpfile,*) "rpointer."//compname//trim(inst_suffix)//'.'//trim(timestr) if (mode.eq.'read') then inquire(file=trim(rpfile), exist=isPresent) if(.not. isPresent) then - rpfile = "rpointer."//compname - if (inst_suffix .ne. "") then - rpfile = trim(rpfile)//"."//trim(inst_suffix) - endif + rpfile = "rpointer."//compname//trim(inst_suffix) inquire(file=trim(rpfile), exist=isPresent) if(.not. isPresent) then call shr_sys_abort( subname//'ERROR no rpointer file found in '//rpfile//' or in '//rpfile//'.'//timestr ) From c2c4274e1ca4923c5b4963b035cff0e22c634615 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 3 Oct 2024 15:34:50 -0600 Subject: [PATCH 157/170] fix issue in docn --- docn/ocn_comp_nuopc.F90 | 2 +- dshr/dshr_mod.F90 | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index 4bf9e5acd..bb0d3e78b 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -582,7 +582,7 @@ subroutine docn_comp_run(gcomp, importState, exportState, clock, target_ymd, tar call dshr_restart_read(restfilm, rpfile, logunit, my_task, mpicom, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case('som', 'som_aquap') - call docn_datamode_som_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + call docn_datamode_som_restart_read(restfilm, rpfile, logunit, my_task, mpicom, sdat) end select end if diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index 8ea10dca3..7d6bd71f8 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -985,10 +985,10 @@ subroutine dshr_restart_read(rest_filem, rpfile, & if(shr_strdata_get_stream_count(sdat) <= 0) return call ESMF_VMGetCurrent(vm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - exists = .false. - if (trim(rest_filem) == 'none') then + inquire(file=trim(rest_filem), exist=exists) + if (trim(rest_filem) == 'none' .or. trim(rest_filem) == 'null') then if (my_task == main_task) then - write(logunit,F00) ' restart filename from rpointer '//trim(rpfile) + write(logunit,F00) ' restart filename from rpointer: '//trim(rpfile) open(newunit=nu, file=trim(rpfile), form='formatted') read(nu, '(a)') rest_filem close(nu) From 7a181896f16fd9f1bbdaf556248395fa5ae716ad Mon Sep 17 00:00:00 2001 From: Nick Szapiro Date: Mon, 7 Oct 2024 18:16:53 +0000 Subject: [PATCH 158/170] Remove duplicate SIMPLE case statements (from merge) --- datm/atm_comp_nuopc.F90 | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 6259dbc4d..5180164d7 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -401,10 +401,6 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call datm_datamode_simple_advertise(exportState, fldsExport, flds_scalar_name, & nlfilename, my_task, vm, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - case ('SIMPLE') - call datm_datamode_simple_advertise(exportState, fldsExport, flds_scalar_name, & - nlfilename, my_task, vm, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return end select end subroutine InitializeAdvertise @@ -648,9 +644,6 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe case('SIMPLE') call datm_datamode_simple_init_pointers(exportState, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - case('SIMPLE') - call datm_datamode_simple_init_pointers(exportState, sdat, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Read restart if needed @@ -725,10 +718,6 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe call datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & sdat%model_calendar, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - case('SIMPLE') - call datm_datamode_simple_advance(target_ymd, target_tod, target_mon, & - sdat%model_calendar, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Write restarts if needed From 395f9dd6f8c6870cdb4592dba07c3f6f484aac69 Mon Sep 17 00:00:00 2001 From: Nicholas Szapiro <149816583+NickSzapiro-NOAA@users.noreply.github.com> Date: Tue, 8 Oct 2024 03:35:39 -0400 Subject: [PATCH 159/170] Remove duplicate use datm_datamode_simple_mod in atm_comp_nuopc.F90 --- datm/atm_comp_nuopc.F90 | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 5180164d7..048501a20 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -82,18 +82,6 @@ module cdeps_datm_comp use datm_datamode_simple_mod , only : datm_datamode_simple_restart_write use datm_datamode_simple_mod , only : datm_datamode_simple_restart_read - use datm_datamode_simple_mod , only : datm_datamode_simple_advertise - use datm_datamode_simple_mod , only : datm_datamode_simple_init_pointers - use datm_datamode_simple_mod , only : datm_datamode_simple_advance - use datm_datamode_simple_mod , only : datm_datamode_simple_restart_write - use datm_datamode_simple_mod , only : datm_datamode_simple_restart_read - - use datm_datamode_simple_mod , only : datm_datamode_simple_advertise - use datm_datamode_simple_mod , only : datm_datamode_simple_init_pointers - use datm_datamode_simple_mod , only : datm_datamode_simple_advance - use datm_datamode_simple_mod , only : datm_datamode_simple_restart_write - use datm_datamode_simple_mod , only : datm_datamode_simple_restart_read - implicit none private ! except From 0c377449ea919e38f683cfb48ec1a6f8d1daab20 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Fri, 25 Oct 2024 13:44:17 -0600 Subject: [PATCH 160/170] fix input_data_list generation for when multiple stream_datafiles entries are present for a stream_entry --- cime_config/stream_cdeps.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index 1f702a13c..0c8ab5b50 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -245,10 +245,11 @@ def create_stream_xml( + "\n" ) else: - stream_datafiles = child.xml_element.text - stream_datafiles = self._resolve_values( - case, stream_datafiles + _stream_datafiles = child.xml_element.text + _stream_datafiles = self._resolve_values( + case, _stream_datafiles ) + stream_datafiles += '\n' + _stream_datafiles # endif neon if ( "first_year" in child.xml_element.attrib From 37b1a13b2228f7c5c25d9a82570a368f59466494 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Fri, 25 Oct 2024 14:01:07 -0600 Subject: [PATCH 161/170] extend jra v1.5 to 2023 --- datm/cime_config/config_component.xml | 8 +- datm/cime_config/namelist_definition_datm.xml | 4 +- datm/cime_config/stream_definition_datm.xml | 76 ++++++++++++------- drof/cime_config/config_component.xml | 8 +- drof/cime_config/namelist_definition_drof.xml | 4 +- drof/cime_config/stream_definition_drof.xml | 6 +- 6 files changed, 65 insertions(+), 41 deletions(-) diff --git a/datm/cime_config/config_component.xml b/datm/cime_config/config_component.xml index bf02b6c71..5eb54d9f5 100644 --- a/datm/cime_config/config_component.xml +++ b/datm/cime_config/config_component.xml @@ -10,7 +10,7 @@ This file may have atm desc entries. --> - Data driven ATM + Data driven ATM QIAN data set QIAN with water isotopes CRUNCEP data set @@ -23,7 +23,7 @@ COREv2 interannual forcing interannual JRA55 forcing interannual JRA55 forcing, v1.4, through 2018 - interannual JRA55 forcing, v1.5, through 2018 + interannual JRA55 forcing, v1.5, through 2023 JRA55 Repeat Year Forcing v1.3 1984-1985 JRA55 Repeat Year Forcing v1.3 1990-1991 JRA55 Repeat Year Forcing v1.3 2003-2004 @@ -42,7 +42,7 @@ char - CORE2_NYF,CORE2_IAF,CLM_QIAN,CLM_QIAN_WISO,1PT,CLMCRUNCEP,CLMCRUNCEPv7,CLMGSWP3v1,CLMNLDAS2,CPLHIST,CORE_IAF_JRA,CORE_IAF_JRA_1p4_2018,CORE_IAF_JRA_1p5_2018,CORE_IAF_JRA_1p5_2018,ERA5,SIMPLE + CORE2_NYF,CORE2_IAF,CLM_QIAN,CLM_QIAN_WISO,1PT,CLMCRUNCEP,CLMCRUNCEPv7,CLMGSWP3v1,CLMNLDAS2,CPLHIST,CORE_IAF_JRA,CORE_IAF_JRA_1p4_2018,CORE_IAF_JRA_1p5_2023,ERA5,SIMPLE CORE2_NYF run_component_datm env_run.xml @@ -55,7 +55,7 @@ CORE2_IAF CORE_IAF_JRA CORE_IAF_JRA_1p4_2018 - CORE_IAF_JRA_1p5_2018 + CORE_IAF_JRA_1p5_2023 CLM_QIAN CLM_QIAN_WISO CLMCRUNCEPv7 diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index 70ed9b0af..3fc7941e2 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -52,8 +52,8 @@ CORE_IAF_JRA_1p4_2018.GCGCS.PREC,CORE_IAF_JRA_1p4_2018.GISS.LWDN,CORE_IAF_JRA_1p4_2018.GISS.SWDN,CORE_IAF_JRA_1p4_2018.NCEP.Q_10,CORE_IAF_JRA_1p4_2018.NCEP.SLP_,CORE_IAF_JRA_1p4_2018.NCEP.T_10,CORE_IAF_JRA_1p4_2018.NCEP.U_10,CORE_IAF_JRA_1p4_2018.NCEP.V_10 - - CORE_IAF_JRA_1p5_2018.GCGCS.PREC,CORE_IAF_JRA_1p5_2018.GISS.LWDN,CORE_IAF_JRA_1p5_2018.GISS.SWDN,CORE_IAF_JRA_1p5_2018.NCEP.Q_10,CORE_IAF_JRA_1p5_2018.NCEP.SLP_,CORE_IAF_JRA_1p5_2018.NCEP.T_10,CORE_IAF_JRA_1p5_2018.NCEP.U_10,CORE_IAF_JRA_1p5_2018.NCEP.V_10 + + CORE_IAF_JRA_1p5_2023.GCGCS.PREC,CORE_IAF_JRA_1p5_2023.GISS.LWDN,CORE_IAF_JRA_1p5_2023.GISS.SWDN,CORE_IAF_JRA_1p5_2023.NCEP.Q_10,CORE_IAF_JRA_1p5_2023.NCEP.SLP_,CORE_IAF_JRA_1p5_2023.NCEP.T_10,CORE_IAF_JRA_1p5_2023.NCEP.U_10,CORE_IAF_JRA_1p5_2023.NCEP.V_10 CORE_RYF8485_JRA.GISS.LWDN,CORE_RYF8485_JRA.GISS.SWDN,CORE_RYF8485_JRA.GCGCS,CORE_RYF8485_JRA.NCEP diff --git a/datm/cime_config/stream_definition_datm.xml b/datm/cime_config/stream_definition_datm.xml index 01bc87419..ead974c2a 100644 --- a/datm/cime_config/stream_definition_datm.xml +++ b/datm/cime_config/stream_definition_datm.xml @@ -37,7 +37,7 @@ CORE2_IAF = CORE2 intra-annual year forcing (for forcing MOM6 and CICE) CORE_IAF_JRA = JRA55 intra-annual year forcing (for forcing MOM6 and CICE) CORE_IAF_JRA_1p4_2018 = JRA55 intra-annual year forcing, v1.4, through 2018 (for forcing MOM6 and CICE) - CORE_IAF_JRA_1p5_2018 = JRA55 intra-annual year forcing, v1.5, through 2018 (for forcing MOM6 and CICE + CORE_IAF_JRA_1p5_2023 = JRA55 intra-annual year forcing, v1.5, through 2023 (for forcing MOM6 and CICE) CORE_RYF8485_JRA = JRA55 repeat year forcing, v1.3, 1984-1985 (for forcing MOM6 and CICE) CORE_RYF9091_JRA = JRA55 repeat year forcing, v1.3, 1990-1991 (for forcing MOM6 and CICE) CORE_RYF0304_JRA = JRA55 repeat year forcing, v1.3, 2003-2004 (for forcing MOM6 and CICE) @@ -2418,15 +2418,18 @@ - + - + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc - $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.prec.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.prec.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.prec.TL319.%y.220505.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.prec.TL319.%y.230718.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.prec.TL319.%y.240531.nc prec Faxa_prec @@ -2438,7 +2441,7 @@ null 1 1958 - 2018 + 2023 0 linear @@ -2452,12 +2455,15 @@ single - + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc - $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.lwdn.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.lwdn.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.lwdn.TL319.%y.220505.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.lwdn.TL319.%y.230718.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.lwdn.TL319.%y.240531.nc lwdn Faxa_lwdn @@ -2469,7 +2475,7 @@ null 1 1958 - 2018 + 2023 0 linear @@ -2483,12 +2489,15 @@ single - + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc - $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.swdn.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.swdn.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.swdn.TL319.%y.220505.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.swdn.TL319.%y.230718.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.swdn.TL319.%y.240531.nc swdn Faxa_swdn @@ -2500,7 +2509,7 @@ null 1 1958 - 2018 + 2023 -5400 coszen @@ -2514,12 +2523,15 @@ single - + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc - $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.q_10.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.q_10.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.q_10.TL319.%y.220505.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.q_10.TL319.%y.230718.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.q_10.TL319.%y.240531.nc q_10 Sa_shum @@ -2531,7 +2543,7 @@ null 1 1958 - 2018 + 2023 0 linear @@ -2545,12 +2557,15 @@ single - + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc - $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.slp.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.slp.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.slp.TL319.%y.220505.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.slp.TL319.%y.230718.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.slp.TL319.%y.240531.nc slp Sa_pslv @@ -2562,7 +2577,7 @@ null 1 1958 - 2018 + 2023 0 linear @@ -2576,12 +2591,15 @@ single - + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc - $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.t_10.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.t_10.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.t_10.TL319.%y.220505.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.t_10.TL319.%y.230718.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.t_10.TL319.%y.240531.nc t_10 Sa_tbot @@ -2593,7 +2611,7 @@ null 1 1958 - 2018 + 2023 0 linear @@ -2607,12 +2625,15 @@ single - + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc - $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.u_10.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.u_10.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.u_10.TL319.%y.220505.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.u_10.TL319.%y.230718.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.u_10.TL319.%y.240531.nc u_10 Sa_u @@ -2624,7 +2645,7 @@ null 1 1958 - 2018 + 2023 0 linear @@ -2638,12 +2659,15 @@ single - + $DIN_LOC_ROOT/share/meshes/TL319_151007_ESMFmesh.nc - $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.v_10.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.v_10.TL319.%y.210504.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.v_10.TL319.%y.220505.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.v_10.TL319.%y.230718.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.v_10.TL319.%y.240531.nc v_10 Sa_v @@ -2655,7 +2679,7 @@ null 1 1958 - 2018 + 2023 0 linear diff --git a/drof/cime_config/config_component.xml b/drof/cime_config/config_component.xml index c37e71e7e..1db777be7 100644 --- a/drof/cime_config/config_component.xml +++ b/drof/cime_config/config_component.xml @@ -13,7 +13,7 @@ --> - Data runoff model + Data runoff model NULL mode COREv2 normal year forcing: COREv2 interannual year forcing: @@ -25,7 +25,7 @@ JRA55 interannual forcing, v1.4, through 2018, no rofi around AIS JRA55 interannual forcing, v1.4, through 2018, no rofl around AIS JRA55 interannual forcing, v1.4, through 2018, no rofi or rofl around AIS - JRA55 interannual forcing, v1.5, through 2018 + JRA55 interannual forcing, v1.5, through 2023 JRA55 interannual forcing JRA55 Repeat Year Forcing v1.3 1984-1985 JRA55 Repeat Year Forcing v1.3 1990-1991 @@ -43,7 +43,7 @@ char - CPLHIST,DIATREN_ANN_RX1,DIATREN_IAF_RX1,DIATREN_IAF_AIS00_RX1,DIATREN_IAF_AIS45_RX1,DIATREN_IAF_AIS55_RX1,IAF_JRA,IAF_JRA_1p4_2018,IAF_JRA_1p4_2018_AIS0ICE,IAF_JRA_1p4_2018_AIS0LIQ,IAF_JRA_1p4_2018_AIS0ROF,IAF_JRA_1p5_2018,RYF8485_JRA,RYF9091_JRA,RYF0304_JRA,NULL + CPLHIST,DIATREN_ANN_RX1,DIATREN_IAF_RX1,DIATREN_IAF_AIS00_RX1,DIATREN_IAF_AIS45_RX1,DIATREN_IAF_AIS55_RX1,IAF_JRA,IAF_JRA_1p4_2018,IAF_JRA_1p4_2018_AIS0ICE,IAF_JRA_1p4_2018_AIS0LIQ,IAF_JRA_1p4_2018_AIS0ROF,IAF_JRA_1p5_2023,RYF8485_JRA,RYF9091_JRA,RYF0304_JRA,NULL DIATREN_ANN_RX1 NULL @@ -61,7 +61,7 @@ IAF_JRA_1p4_2018_AIS0ICE IAF_JRA_1p4_2018_AIS0LIQ IAF_JRA_1p4_2018_AIS0ROF - IAF_JRA_1p5_2018 + IAF_JRA_1p5_2023 RYF8485_JRA RYF9091_JRA RYF0304_JRA diff --git a/drof/cime_config/namelist_definition_drof.xml b/drof/cime_config/namelist_definition_drof.xml index 71021636e..ff3d402bb 100644 --- a/drof/cime_config/namelist_definition_drof.xml +++ b/drof/cime_config/namelist_definition_drof.xml @@ -19,9 +19,9 @@ rof.diatren_iaf_ais00_rx1 rof.diatren_iaf_ais45_rx1 rof.diatren_iaf_ais55_rx1 - rof.iaf_jra rof.iaf_jra_1p4_2018 - rof.iaf_jra_1p5_2018 + rof.iaf_jra_1p5_2023 + rof.iaf_jra rof.ryf8485_jra rof.ryf9091_jra rof.ryf0304_jra diff --git a/drof/cime_config/stream_definition_drof.xml b/drof/cime_config/stream_definition_drof.xml index 9f8b20ff5..1c87e690b 100644 --- a/drof/cime_config/stream_definition_drof.xml +++ b/drof/cime_config/stream_definition_drof.xml @@ -475,12 +475,12 @@ single - + $DIN_LOC_ROOT/lnd/dlnd7/JRA55/JRA.v1.4.runoff.1958_ESMFmesh_cdf5_20201020.nc - $DIN_LOC_ROOT/lnd/dlnd7/JRA55/JRA.v1.5.runoff.%y.240411.nc + $DIN_LOC_ROOT/ocn/jra55/v1.5_noleap/JRA.v1.5.runoff.%y.240411.nc rofl Forr_rofl @@ -493,7 +493,7 @@ null 1 1958 - 2018 + 2023 0 upper From faa59db8f09e8f550bc53e0496097f75886ac721 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Fri, 25 Oct 2024 17:39:47 -0600 Subject: [PATCH 162/170] fix (for real) input_data_list generation for when multiple stream_datafiles entries are present for a stream_entry --- cime_config/stream_cdeps.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cime_config/stream_cdeps.py b/cime_config/stream_cdeps.py index 5a17da940..3d653745a 100644 --- a/cime_config/stream_cdeps.py +++ b/cime_config/stream_cdeps.py @@ -242,6 +242,7 @@ def create_stream_xml( elif node_name == "stream_datafiles": # Get the resolved stream data files stream_vars[node_name] = "" + stream_datafiles_list = [] # to join stream_datafiles if multiple entries are present stream_datafiles = "" for child in self.get_children(root=node): if ( @@ -263,11 +264,10 @@ def create_stream_xml( + "\n" ) else: - _stream_datafiles = child.xml_element.text - _stream_datafiles = self._resolve_values( - case, _stream_datafiles + stream_datafiles = child.xml_element.text + stream_datafiles = self._resolve_values( + case, stream_datafiles ) - stream_datafiles += '\n' + _stream_datafiles # endif neon if ( "first_year" in child.xml_element.attrib @@ -307,6 +307,8 @@ def create_stream_xml( stream_datafiles.split("\n"), "file" ) # endif + stream_datafiles_list.append(stream_datafiles) + stream_datafiles = "\n".join(stream_datafiles_list) elif node_name in xml_scalar_names: attributes["model_grid"] = case.get_value("GRID") attributes["compset"] = case.get_value("COMPSET") From 11d937e3c7db0bae9e6f61744186a006a4ad31b8 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Tue, 29 Oct 2024 18:30:20 -0600 Subject: [PATCH 163/170] Add a namelist flag controlling the nextsw_cday calculation --- datm/atm_comp_nuopc.F90 | 22 ++++++++++++++++++- datm/cime_config/namelist_definition_datm.xml | 20 +++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 2a86b7687..bdec303e4 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -127,6 +127,7 @@ module cdeps_datm_comp character(CL) :: model_meshfile = nullstr ! full pathname to model meshfile character(CL) :: model_maskfile = nullstr ! full pathname to obtain mask from integer :: iradsw = 0 ! radiation interval (input namelist) + logical :: nextsw_cday_calc_cam7 ! true => use logic appropriate to cam7 (and later) for calculating nextsw_cday character(CL) :: factorFn_mesh = 'null' ! file containing correction factors mesh character(CL) :: factorFn_data = 'null' ! file containing correction factors data logical :: flds_presaero = .false. ! true => send valid prescribed aero fields to mediator @@ -230,6 +231,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: nu ! unit number integer :: ierr ! error code integer :: bcasttmp(10) + character(CL) :: nextsw_cday_calc type(ESMF_VM) :: vm character(len=*),parameter :: subname=trim(modName) // ':(InitializeAdvertise) ' character(*) ,parameter :: F00 = "('(" // trim(modName) // ") ',8a)" @@ -245,6 +247,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ny_global, & restfilm, & iradsw, & + nextsw_cday_calc, & factorFn_data, & factorFn_mesh, & flds_presaero, & @@ -259,6 +262,9 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) rc = ESMF_SUCCESS + ! Initialize locally-declared namelist items to default values + nextsw_cday_calc = nullstr + call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -318,6 +324,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, restfilm, CL, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMBroadcast(vm, nextsw_cday_calc, CL, main_task, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMBroadcast(vm, bcasttmp, 10, main_task, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return nx_global = bcasttmp(1) @@ -331,6 +339,14 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) skip_restart_read = (bcasttmp(9) == 1) export_all = (bcasttmp(10) == 1) + if (nextsw_cday_calc == 'cam7') then + nextsw_cday_calc_cam7 = .true. + else if (nextsw_cday_calc == 'cam6') then + nextsw_cday_calc_cam7 = .false. + else + call shr_sys_abort(' ERROR illegal datm nextsw_cday_calc = '//trim(nextsw_cday_calc)) + end if + ! write namelist input to standard out if (my_task == main_task) then write(logunit,F00)' case_name = ',trim(case_name) @@ -341,6 +357,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,F01)' ny_global = ',ny_global write(logunit,F00)' restfilm = ',trim(restfilm) write(logunit,F01)' iradsw = ',iradsw + write(logunit,F00)' nextsw_cday_calc = ', trim(nextsw_cday_calc) write(logunit,F00)' factorFn_data = ',trim(factorFn_data) write(logunit,F00)' factorFn_mesh = ',trim(factorFn_mesh) write(logunit,F02)' flds_presaero = ',flds_presaero @@ -905,7 +922,10 @@ real(R8) function getNextRadCDay( julday, tod, stepno, dtime, iradsw ) if (liradsw > 1) then delta_radsw = liradsw * dtime - if (trim(cplhist_nextsw_cday_calc) == 'cam7' ) then + if (nextsw_cday_calc_cam7) then + ! The logic in this block is consistent with the driver ordering in CAM7 and + ! later. So this is appropriate when using cplhist forcings generated from CAM7 + ! or later. if (mod(tod,delta_radsw) == 0 .and. stepno > 0) then nextsw_cday = julday + 1*dtime/shr_const_cday else diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index 3c2be3995..afe3a40d7 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -346,6 +346,26 @@ + + char + datm + datm_nml + cam6,cam7 + + Logic to use for calculating nextsw_cday. For CPLHIST cases, this should agree with + the version of CAM (or other atmosphere model) used to generate the CPLHIST + forcings; the valid values for this variable are based on this: 'cam6' is + appropriate for cases generated with the driver ordering in CAM6 and earlier, and + 'cam7' is appropriate for cases generated with the driver ordering in CAM7 and + later. This variable also applies for non-CPLHIST cases, but we currently assume (by + default) that non-CPLHIST cases follow the logic that was used in CAM6 and earlier. + + + cam6 + cam7 + + + char datm From 1f317a3c03badd4e3e11ddd455cf5bd6d6e9c9d6 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 31 Oct 2024 15:10:10 -0600 Subject: [PATCH 164/170] Improve documentation of nextsw_cday_calc and iradsw --- datm/atm_comp_nuopc.F90 | 17 +++++---- datm/cime_config/namelist_definition_datm.xml | 35 +++++++++++-------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index bdec303e4..4ac13b744 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -885,15 +885,14 @@ end subroutine datm_comp_run real(R8) function getNextRadCDay( julday, tod, stepno, dtime, iradsw ) ! Return the calendar day of the next radiation time-step. - ! General Usage: nextswday = getNextRadCDay(curr_date) iradsw is - ! the frequency to update the next shortwave. in number of steps - ! (or hours if negative) Julian date. - ! -- values greater than 1 set - ! the next radiation to the present time plus 2 timesteps every iradsw - ! -- values less than 0 turn set the next radiation to the present time - ! plus two timesteps every -iradsw hours. - ! -- if iradsw is zero, the next radiation time is the - ! present time plus 1 timestep. + ! General Usage: nextswday = getNextRadCDay(curr_date). iradsw is + ! the frequency to update the next shortwave in number of steps + ! (or hours if negative). + ! -- values greater than 1 set the next radiation to the present time plus either 1 or + ! 2 timesteps (depending on the value of nextsw_cday_calc_cam7) every iradsw timesteps. + ! -- values less than 0 set the next radiation to the present time plus either 1 or 2 + ! timesteps (depending on the value of nextsw_cday_calc_cam7) every -iradsw hours. + ! -- if iradsw is either 0 or 1, the next radiation time is the present time plus 1 timestep. ! input/output variables real(r8) , intent(in) :: julday diff --git a/datm/cime_config/namelist_definition_datm.xml b/datm/cime_config/namelist_definition_datm.xml index afe3a40d7..40935cf86 100644 --- a/datm/cime_config/namelist_definition_datm.xml +++ b/datm/cime_config/namelist_definition_datm.xml @@ -332,13 +332,15 @@ datm datm_nml - Frequency to update radiation in number of steps (or hours if negative) - irdasw is the radiation setting used to compute the next shortwave - Julian date. values greater than 1 set the next radiation to the - present time plus 2 timesteps every iradsw. values less than 0 turn - set the next radiation to the present time plus two timesteps every - -iradsw hours. if iradsw is zero, the next radiation time is the - present time plus 1 timestep. (default=0.) + Frequency to update radiation in number of steps (or hours if negative). + + irdasw is the radiation setting used to compute the next shortwave Julian date. + Values greater than 1 set the next radiation to the present time plus either 1 or 2 + timesteps (depending on the value of nextsw_cday_calc) every iradsw timesteps. + Values less than 0 set the next radiation to the present time plus either 1 or 2 + timesteps (depending on the value of nextsw_cday_calc) every -iradsw hours. If + iradsw is either 0 or 1, the next radiation time is the present time plus 1 + timestep. (default=1 for non-CPLHIST cases, and -1 for CPLHIST cases.) 1 @@ -352,13 +354,18 @@ datm_nml cam6,cam7 - Logic to use for calculating nextsw_cday. For CPLHIST cases, this should agree with - the version of CAM (or other atmosphere model) used to generate the CPLHIST - forcings; the valid values for this variable are based on this: 'cam6' is - appropriate for cases generated with the driver ordering in CAM6 and earlier, and - 'cam7' is appropriate for cases generated with the driver ordering in CAM7 and - later. This variable also applies for non-CPLHIST cases, but we currently assume (by - default) that non-CPLHIST cases follow the logic that was used in CAM6 and earlier. + Logic to use for calculating nextsw_cday. This variable has no effect when iradsw is + 0 or 1, so by default this only applies in CPLHIST cases. + + For CPLHIST cases, this should agree with the version of CAM (or other atmosphere + model) used to generate the CPLHIST forcings; the valid values for this variable are + based on this: 'cam6' is appropriate for cases generated with the driver ordering in + CAM6 and earlier, and 'cam7' is appropriate for cases generated with the driver + ordering in CAM7 and later. + + For 'cam6', the next radiation timestep is set to the present time plus 2 timesteps + when mod(tod+dtime,delta_radsw)==0. For 'cam7', the next radiation timestep is set + to the present time plus 1 timestep when mod(tod,delta_radsw)==0. cam6 From 3e3ca1836705e6d15a0e5874567267a0accc4bec Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 6 Nov 2024 07:22:25 -0700 Subject: [PATCH 165/170] backout the timestamp on rpointer files until alpha05c, remove unused rpfile parameters --- datm/datm_datamode_clmncep_mod.F90 | 1 - datm/datm_datamode_cplhist_mod.F90 | 1 - datm/datm_datamode_era5_mod.F90 | 1 - datm/datm_datamode_gefs_mod.F90 | 1 - datm/datm_datamode_jra_mod.F90 | 1 - datm/datm_datamode_simple_mod.F90 | 1 - docn/docn_datamode_copyall_mod.F90 | 1 - docn/docn_datamode_cplhist_mod.F90 | 1 - docn/docn_datamode_multilev_dom_mod.F90 | 1 - docn/docn_datamode_multilev_mod.F90 | 1 - drof/rof_comp_nuopc.F90 | 1 - dshr/dshr_mod.F90 | 6 ++++-- dwav/wav_comp_nuopc.F90 | 1 - 13 files changed, 4 insertions(+), 14 deletions(-) diff --git a/datm/datm_datamode_clmncep_mod.F90 b/datm/datm_datamode_clmncep_mod.F90 index f11aa167c..78b3bf4db 100644 --- a/datm/datm_datamode_clmncep_mod.F90 +++ b/datm/datm_datamode_clmncep_mod.F90 @@ -102,7 +102,6 @@ module datm_datamode_clmncep_mod character(*), parameter :: nullstr = 'null' - character(*), parameter :: rpfile = 'rpointer.atm' character(*), parameter :: u_FILE_u = & __FILE__ diff --git a/datm/datm_datamode_cplhist_mod.F90 b/datm/datm_datamode_cplhist_mod.F90 index 2765bc157..ca53ed78d 100644 --- a/datm/datm_datamode_cplhist_mod.F90 +++ b/datm/datm_datamode_cplhist_mod.F90 @@ -41,7 +41,6 @@ module datm_datamode_cplhist_mod real(r8), pointer :: Faxa_swnet(:) => null() character(*), parameter :: nullstr = 'null' - character(*), parameter :: rpfile = 'rpointer.atm' character(*), parameter :: u_FILE_u = & __FILE__ diff --git a/datm/datm_datamode_era5_mod.F90 b/datm/datm_datamode_era5_mod.F90 index 2ba91cc78..187c3b5d7 100644 --- a/datm/datm_datamode_era5_mod.F90 +++ b/datm/datm_datamode_era5_mod.F90 @@ -59,7 +59,6 @@ module datm_datamode_era5_mod real(r8) , parameter :: rhofw = SHR_CONST_RHOFW ! density of fresh water ~ kg/m^3 character(*), parameter :: nullstr = 'undefined' - character(*), parameter :: rpfile = 'rpointer.atm' character(*), parameter :: u_FILE_u = & __FILE__ diff --git a/datm/datm_datamode_gefs_mod.F90 b/datm/datm_datamode_gefs_mod.F90 index 66b991d89..fb7a0b4dc 100644 --- a/datm/datm_datamode_gefs_mod.F90 +++ b/datm/datm_datamode_gefs_mod.F90 @@ -49,7 +49,6 @@ module datm_datamode_gefs_mod real(r8) , parameter :: rhofw = SHR_CONST_RHOFW ! density of fresh water ~ kg/m^3 character(*), parameter :: nullstr = 'undefined' - character(*), parameter :: rpfile = 'rpointer.atm' character(*), parameter :: u_FILE_u = & __FILE__ diff --git a/datm/datm_datamode_jra_mod.F90 b/datm/datm_datamode_jra_mod.F90 index e09844ace..2e0e5ee67 100644 --- a/datm/datm_datamode_jra_mod.F90 +++ b/datm/datm_datamode_jra_mod.F90 @@ -58,7 +58,6 @@ module datm_datamode_jra_mod real(R8) , parameter :: dLWarc = -5.000_R8 character(*), parameter :: nullstr = 'null' - character(*), parameter :: rpfile = 'rpointer.atm' character(*), parameter :: u_FILE_u = & __FILE__ diff --git a/datm/datm_datamode_simple_mod.F90 b/datm/datm_datamode_simple_mod.F90 index da88fc640..454bceeac 100644 --- a/datm/datm_datamode_simple_mod.F90 +++ b/datm/datm_datamode_simple_mod.F90 @@ -76,7 +76,6 @@ module datm_datamode_simple_mod real(R8) , parameter :: dLWarc = -5.000_R8 character(*), parameter :: nullstr = 'null' - character(*), parameter :: rpfile = 'rpointer.atm' character(*), parameter :: u_FILE_u = & __FILE__ diff --git a/docn/docn_datamode_copyall_mod.F90 b/docn/docn_datamode_copyall_mod.F90 index 85d625fee..1c447677d 100644 --- a/docn/docn_datamode_copyall_mod.F90 +++ b/docn/docn_datamode_copyall_mod.F90 @@ -27,7 +27,6 @@ module docn_datamode_copyall_mod real(r8) , parameter :: ocnsalt = shr_const_ocn_ref_sal ! ocean reference salinity character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.ocn' character(*) , parameter :: u_FILE_u = & __FILE__ diff --git a/docn/docn_datamode_cplhist_mod.F90 b/docn/docn_datamode_cplhist_mod.F90 index 81ac40224..f913ad467 100644 --- a/docn/docn_datamode_cplhist_mod.F90 +++ b/docn/docn_datamode_cplhist_mod.F90 @@ -27,7 +27,6 @@ module docn_datamode_cplhist_mod real(r8) , parameter :: ocnsalt = shr_const_ocn_ref_sal ! ocean reference salinity character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.ocn' character(*) , parameter :: u_FILE_u = & __FILE__ diff --git a/docn/docn_datamode_multilev_dom_mod.F90 b/docn/docn_datamode_multilev_dom_mod.F90 index 9c8c35be9..c6413f018 100644 --- a/docn/docn_datamode_multilev_dom_mod.F90 +++ b/docn/docn_datamode_multilev_dom_mod.F90 @@ -40,7 +40,6 @@ module docn_datamode_multilev_dom_mod ! constants character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.ocn' character(*) , parameter :: u_FILE_u = & __FILE__ diff --git a/docn/docn_datamode_multilev_mod.F90 b/docn/docn_datamode_multilev_mod.F90 index aaa24258f..11f9dc43f 100644 --- a/docn/docn_datamode_multilev_mod.F90 +++ b/docn/docn_datamode_multilev_mod.F90 @@ -32,7 +32,6 @@ module docn_datamode_multilev_mod ! constants character(*) , parameter :: nullstr = 'null' - character(*) , parameter :: rpfile = 'rpointer.ocn' character(*) , parameter :: u_FILE_u = & __FILE__ diff --git a/drof/rof_comp_nuopc.F90 b/drof/rof_comp_nuopc.F90 index e35f78fd0..520057d90 100644 --- a/drof/rof_comp_nuopc.F90 +++ b/drof/rof_comp_nuopc.F90 @@ -81,7 +81,6 @@ module cdeps_drof_comp logical :: diagnose_data = .true. integer , parameter :: main_task=0 ! task number of main task - character(*) , parameter :: rpfile = 'rpointer.rof' #ifdef CESMCOUPLED character(*) , parameter :: modName = "(rof_comp_nuopc)" #else diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index 7d6bd71f8..9acf60919 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -1058,6 +1058,7 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t type(io_desc_t) :: pio_iodesc integer :: oldmode integer :: rcode + character(len=CS) :: lrpfile character(*), parameter :: F00 = "('(dshr_restart_write) ',2a,2(i0,2x))" !------------------------------------------------------------------------------- @@ -1067,10 +1068,11 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t call shr_cal_datetod2string(date_str, ymd, tod) write(rest_file_model ,"(7a)") trim(case_name),'.', trim(model_name),trim(inst_suffix),'.r.', trim(date_str),'.nc' - + ! temporarily turn off timestamp, remove this code and comment in alpha05c + lrpfile = rpfile(:len_trim(rpfile)-17) ! write restart info to rpointer file if (my_task == main_task) then - open(newunit=nu, file=trim(rpfile), form='formatted') + open(newunit=nu, file=trim(lrpfile), form='formatted') write(nu,'(a)') rest_file_model close(nu) write(logunit,F00)' writing ',trim(rest_file_model) diff --git a/dwav/wav_comp_nuopc.F90 b/dwav/wav_comp_nuopc.F90 index 0a5a25d02..61150fedd 100644 --- a/dwav/wav_comp_nuopc.F90 +++ b/dwav/wav_comp_nuopc.F90 @@ -83,7 +83,6 @@ module cdeps_dwav_comp ! constants logical :: diagnose_data = .true. integer , parameter :: main_task=0 ! task number of main task - character(*) , parameter :: rpfile = 'rpointer.wav' #ifdef CESMCOUPLED character(*) , parameter :: modName = "(wav_comp_nuopc)" #else From 89df6c39a6e888af17bde167bdd3a0c93c8ba92e Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Fri, 8 Nov 2024 10:44:26 -0700 Subject: [PATCH 166/170] Change hard-coded default for nextsw_cday_calc This is needed for UFS, which doesn't add this to the namelist --- datm/atm_comp_nuopc.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index b74e0d34e..cfd25a782 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -246,7 +246,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) rc = ESMF_SUCCESS ! Initialize locally-declared namelist items to default values - nextsw_cday_calc = nullstr + nextsw_cday_calc = 'cam6' call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return From bfd038ff4363f6ab6349789dc60b95d2347f12a1 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 6 Dec 2024 06:48:48 -0700 Subject: [PATCH 167/170] add back rpointer timestamps --- dshr/dshr_mod.F90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index 9acf60919..ca87f2e9d 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -1068,8 +1068,7 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t call shr_cal_datetod2string(date_str, ymd, tod) write(rest_file_model ,"(7a)") trim(case_name),'.', trim(model_name),trim(inst_suffix),'.r.', trim(date_str),'.nc' - ! temporarily turn off timestamp, remove this code and comment in alpha05c - lrpfile = rpfile(:len_trim(rpfile)-17) + ! write restart info to rpointer file if (my_task == main_task) then open(newunit=nu, file=trim(lrpfile), form='formatted') From 775ec1d8b187acbfe169313e90484907bb40d3e9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 9 Dec 2024 13:59:57 -0700 Subject: [PATCH 168/170] Revert "add back rpointer timestamps" This reverts commit bfd038ff4363f6ab6349789dc60b95d2347f12a1. --- dshr/dshr_mod.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index ca87f2e9d..9acf60919 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -1068,7 +1068,8 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t call shr_cal_datetod2string(date_str, ymd, tod) write(rest_file_model ,"(7a)") trim(case_name),'.', trim(model_name),trim(inst_suffix),'.r.', trim(date_str),'.nc' - + ! temporarily turn off timestamp, remove this code and comment in alpha05c + lrpfile = rpfile(:len_trim(rpfile)-17) ! write restart info to rpointer file if (my_task == main_task) then open(newunit=nu, file=trim(lrpfile), form='formatted') From 1d9928256268f8493a2f2446d4610f1b2c39bb5b Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 9 Dec 2024 14:02:28 -0700 Subject: [PATCH 169/170] correct readd of rpointer timestamps --- dshr/dshr_mod.F90 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index 9acf60919..fb5010ace 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -1058,7 +1058,6 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t type(io_desc_t) :: pio_iodesc integer :: oldmode integer :: rcode - character(len=CS) :: lrpfile character(*), parameter :: F00 = "('(dshr_restart_write) ',2a,2(i0,2x))" !------------------------------------------------------------------------------- @@ -1068,11 +1067,9 @@ subroutine dshr_restart_write(rpfile, case_name, model_name, inst_suffix, ymd, t call shr_cal_datetod2string(date_str, ymd, tod) write(rest_file_model ,"(7a)") trim(case_name),'.', trim(model_name),trim(inst_suffix),'.r.', trim(date_str),'.nc' - ! temporarily turn off timestamp, remove this code and comment in alpha05c - lrpfile = rpfile(:len_trim(rpfile)-17) ! write restart info to rpointer file if (my_task == main_task) then - open(newunit=nu, file=trim(lrpfile), form='formatted') + open(newunit=nu, file=trim(rpfile), form='formatted') write(nu,'(a)') rest_file_model close(nu) write(logunit,F00)' writing ',trim(rest_file_model) From 51f8cd20c15fe39ef1168d59d5077812b6508544 Mon Sep 17 00:00:00 2001 From: Nick Szapiro Date: Tue, 10 Dec 2024 22:21:20 +0000 Subject: [PATCH 170/170] Compile fixes --- dice/dice_datamode_cplhist_mod.F90 | 5 ++--- dice/ice_comp_nuopc.F90 | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dice/dice_datamode_cplhist_mod.F90 b/dice/dice_datamode_cplhist_mod.F90 index 6f5494a1f..8b42feb2f 100644 --- a/dice/dice_datamode_cplhist_mod.F90 +++ b/dice/dice_datamode_cplhist_mod.F90 @@ -180,12 +180,11 @@ subroutine dice_datamode_cplhist_restart_write(rpfile, case_name, inst_suffix, y end subroutine dice_datamode_cplhist_restart_write !=============================================================================== - subroutine dice_datamode_cplhist_restart_read(rest_filem, rpfile, inst_suffix, logunit, my_task, mpicom, sdat) + subroutine dice_datamode_cplhist_restart_read(rest_filem, rpfile, logunit, my_task, mpicom, sdat) ! input/output arguments character(len=*) , intent(inout) :: rest_filem character(len=*) , intent(in) :: rpfile - character(len=*) , intent(in) :: inst_suffix integer , intent(in) :: logunit integer , intent(in) :: my_task integer , intent(in) :: mpicom @@ -194,7 +193,7 @@ subroutine dice_datamode_cplhist_restart_read(rest_filem, rpfile, inst_suffix, l integer :: rc - call dshr_restart_read(rest_filem, rpfile, inst_suffix, nullstr, logunit, my_task, mpicom, sdat, rc) + call dshr_restart_read(rest_filem, rpfile, logunit, my_task, mpicom, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end subroutine dice_datamode_cplhist_restart_read diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index 3a0ba86a8..62186f2c8 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -533,7 +533,7 @@ subroutine dice_comp_run(gcomp, importstate, exportstate, target_ymd, target_tod case('ssmi', 'ssmi_iaf') call dice_datamode_ssmi_restart_read(gcomp, restfilm, rpfile, logunit, my_task, mpicom, sdat) case('cplhist') - call dice_datamode_cplhist_restart_read(restfilm, rpfile, inst_suffix, logunit, my_task, mpicom, sdat) + call dice_datamode_cplhist_restart_read(restfilm, rpfile, logunit, my_task, mpicom, sdat) end select end if