From 3a4435be1daa77f4e15f4243df22e6d4dbd39a0b Mon Sep 17 00:00:00 2001 From: James Edwards Date: Tue, 2 Apr 2024 14:45:06 -0500 Subject: [PATCH 01/11] 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 1f702a13..28db8a90 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 40d63eb1d271f52553f525a43e0d420c01527fa9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 19 Apr 2024 08:45:12 -0600 Subject: [PATCH 02/11] 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 00000000..fa02eb26 --- /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 03/11] 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 fa02eb26..c43f6b35 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 3a9c12a8..ced8cb86 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 e9159f69..5830f5e9 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 04/11] 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 c43f6b35..bb528a58 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 5830f5e9..60e3d0dd 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 05/11] 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 95a6d846..08453147 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 bb528a58..6a1ec760 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 06/11] 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 6a1ec760..6a982866 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 07/11] 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 28db8a90..1f702a13 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 08/11] 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 bfd5cdc1..2f3b33d6 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 09/11] 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 194773fa..8383469c 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 10/11] 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 6a982866..0c6ea681 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 11/11] 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 71109b1c..b2f78811 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 4144e0e5..4e4dd665 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 0c6ea681..897797f3 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'