diff --git a/datm/CMakeLists.txt b/datm/CMakeLists.txt index 398606c45..d96060ab2 100644 --- a/datm/CMakeLists.txt +++ b/datm/CMakeLists.txt @@ -4,6 +4,8 @@ set(SRCFILES atm_comp_nuopc.F90 datm_datamode_cplhist_mod.F90 datm_datamode_core2_mod.F90 datm_datamode_jra_mod.F90 + datm_datamode_gefs_mod.F90 + datm_datamode_cfsr_mod.F90 datm_datamode_era5_mod.F90) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index df0b810b7..0e7069bb0 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -26,7 +26,7 @@ module atm_comp_nuopc use shr_cal_mod , only : shr_cal_ymd2date use shr_mpi_mod , only : shr_mpi_bcast use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck - use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_init_from_xml, shr_strdata_advance + 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_state_setscalar, dshr_set_runclock, dshr_log_clock_advance @@ -65,6 +65,18 @@ module atm_comp_nuopc 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 + implicit none private ! except @@ -99,7 +111,7 @@ module atm_comp_nuopc ! datm_in namelist input character(CL) :: nlfilename = nullstr ! filename to obtain namelist info from - character(CL) :: xmlfilename = nullstr ! filename to obtain namelist info from + character(CL) :: streamfilename = nullstr ! filename to obtain stream info from character(CL) :: dataMode = nullstr ! flags physics options wrt input data character(CL) :: model_meshfile = nullstr ! full pathname to model meshfile character(CL) :: model_maskfile = nullstr ! full pathname to obtain mask from @@ -273,6 +285,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) trim(datamode) == 'CORE_IAF_JRA' .or. & trim(datamode) == 'CLMNCEP' .or. & trim(datamode) == 'CPLHIST' .or. & + trim(datamode) == 'GEFS' .or. & + trim(datamode) == 'CFSR' .or. & trim(datamode) == 'ERA5') then else call shr_sys_abort(' ERROR illegal datm datamode = '//trim(datamode)) @@ -298,6 +312,12 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) case ('ERA5') call datm_datamode_era5_advertise(exportState, fldsExport, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case ('GEFS') + call datm_datamode_gefs_advertise(exportState, fldsExport, flds_scalar_name, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + case ('CFSR') + call datm_datamode_cfsr_advertise(exportState, fldsExport, flds_scalar_name, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select end subroutine InitializeAdvertise @@ -342,8 +362,11 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Initialize stream data type - xmlfilename = 'datm.streams'//trim(inst_suffix)//'.xml' - call shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, 'ATM', logunit, rc=rc) + streamfilename = 'datm.streams'//trim(inst_suffix) +#ifndef DISABLE_FoX + streamfilename = trim(streamfilename)//'.xml' +#endif + call shr_strdata_init_from_config(sdat, streamfilename, model_mesh, clock, 'ATM', logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('datm_strdata_init') @@ -541,6 +564,12 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe case('ERA5') call datm_datamode_era5_init_pointers(exportState, sdat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('GEFS') + call datm_datamode_gefs_init_pointers(exportState, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('CFSR') + call datm_datamode_cfsr_init_pointers(exportState, sdat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Read restart if needed @@ -556,6 +585,10 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe call datm_datamode_cplhist_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) case('ERA5') call datm_datamode_era5_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) + case('GEFS') + 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) end select end if @@ -603,6 +636,13 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe call datm_datamode_era5_advance(exportstate, masterproc, logunit, mpicom, target_ymd, & target_tod, sdat%model_calendar, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('GEFS') + call datm_datamode_gefs_advance(exportstate, masterproc, logunit, mpicom, target_ymd, & + target_tod, sdat%model_calendar, rc) + case('CFSR') + call datm_datamode_cfsr_advance(exportstate, masterproc, logunit, mpicom, target_ymd, & + target_tod, sdat%model_calendar, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end select ! Write restarts if needed @@ -623,6 +663,14 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe 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) + 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 end select end if diff --git a/datm/datm_datamode_cfsr_mod.F90 b/datm/datm_datamode_cfsr_mod.F90 new file mode 100644 index 000000000..24b5b8dda --- /dev/null +++ b/datm/datm_datamode_cfsr_mod.F90 @@ -0,0 +1,252 @@ +module datm_datamode_cfsr_mod + + use ESMF , only : ESMF_State, ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO + 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_precip_mod , only : shr_precip_partition_rain_snow_ramp + use shr_mpi_mod , only : shr_mpi_max + 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 + + implicit none + private ! except + + 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() + real(r8), pointer :: Sa_u(:) => null() + real(r8), pointer :: Sa_v(:) => null() + real(r8), pointer :: Sa_tbot(:) => null() + real(r8), pointer :: Sa_shum(:) => null() + real(r8), pointer :: Sa_pbot(:) => null() + real(r8), pointer :: Sa_u10m(:) => null() + real(r8), pointer :: Sa_v10m(:) => null() + real(r8), pointer :: Sa_t2m(:) => null() + real(r8), pointer :: Sa_q2m(:) => null() + real(r8), pointer :: Sa_pslv(:) => null() + real(r8), pointer :: Faxa_lwdn(:) => null() + real(r8), pointer :: Faxa_rain(:) => null() + real(r8), pointer :: Faxa_snow(:) => 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() + + ! stream data + real(r8), pointer :: strm_mask(:) => null() + + real(r8) :: tbotmax ! units detector + real(r8) :: maskmax ! units detector + + real(r8) , parameter :: tKFrz = SHR_CONST_TKFRZ + 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__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine datm_datamode_cfsr_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_tbot' ) + call dshr_fldList_add(fldsExport, 'Sa_pbot' ) + call dshr_fldList_add(fldsExport, 'Sa_shum' ) + call dshr_fldList_add(fldsExport, 'Sa_u10m' ) + call dshr_fldList_add(fldsExport, 'Sa_v10m' ) + call dshr_fldList_add(fldsExport, 'Sa_t2m' ) + call dshr_fldList_add(fldsExport, 'Sa_q2m' ) + call dshr_fldList_add(fldsExport, 'Sa_pslv' ) + call dshr_fldList_add(fldsExport, 'Faxa_rain' ) + call dshr_fldList_add(fldsExport, 'Faxa_snow' ) + 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_lwdn' ) + + 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_cfsr_advertise + + !=============================================================================== + subroutine datm_datamode_cfsr_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 + character(len=*), parameter :: subname='(datm_init_pointers): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! initialize pointers for module level stream arrays + call shr_strdata_get_stream_pointer( sdat, 'Sa_mask' , strm_mask , 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_shum' , fldptr1=Sa_shum , 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_t2m' , fldptr1=Sa_t2m , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_q2m' , fldptr1=Sa_q2m , 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, 'Faxa_rain' , fldptr1=Faxa_rain , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_snow' , fldptr1=Faxa_snow, 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_lwdn' , fldptr1=Faxa_lwdn , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine datm_datamode_cfsr_init_pointers + + !=============================================================================== + subroutine datm_datamode_cfsr_advance(exportstate, masterproc, logunit, mpicom, target_ymd, target_tod, model_calendar, rc) + + ! input/output variables + type(ESMF_State) , intent(inout) :: exportState + logical , intent(in) :: masterproc + integer , intent(in) :: logunit + integer , intent(in) :: mpicom + integer , intent(in) :: target_ymd + integer , intent(in) :: target_tod + character(len=*) , intent(in) :: model_calendar + integer , intent(out) :: rc + + ! local variables + logical :: first_time = .true. + integer :: n ! indices + integer :: lsize ! size of attr vect + real(r8) :: rtmp + real(r8) :: tbot, pbot + character(len=*), parameter :: subname='(datm_datamode_cfsr_advance): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + lsize = size(strm_mask) + + if (first_time) then + ! determine tbotmax (see below for use) + rtmp = maxval(Sa_tbot(:)) + call shr_mpi_max(rtmp, tbotmax, mpicom, 'datm_tbot', all=.true.) + if (masterproc) write(logunit,*) trim(subname),' tbotmax = ',tbotmax + + ! determine maskmax (see below for use) + rtmp = maxval(strm_mask(:)) + call shr_mpi_max(rtmp, maskmax, mpicom, 'datm_mask', all=.true.) + if (masterproc) write(logunit,*) trim(subname),' maskmax = ',maskmax + + ! reset first_time + first_time = .false. + end if + + do n = 1, lsize + !--- temperature --- + if (tbotmax < 50.0_r8) Sa_tbot(n) = Sa_tbot(n) + tkFrz + ! Limit very cold forcing to 180K + Sa_tbot(n) = max(180._r8, Sa_tbot(n)) + end do + + 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(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_cfsr_restart_read + +end module datm_datamode_cfsr_mod diff --git a/datm/datm_datamode_gefs_mod.F90 b/datm/datm_datamode_gefs_mod.F90 new file mode 100644 index 000000000..0d7274c04 --- /dev/null +++ b/datm/datm_datamode_gefs_mod.F90 @@ -0,0 +1,252 @@ +module datm_datamode_gefs_mod + + use ESMF , only : ESMF_State, ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO + 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_precip_mod , only : shr_precip_partition_rain_snow_ramp + use shr_mpi_mod , only : shr_mpi_max + 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 + + implicit none + private ! except + + 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() + real(r8), pointer :: Sa_u(:) => null() + real(r8), pointer :: Sa_v(:) => null() + real(r8), pointer :: Sa_tbot(:) => null() + real(r8), pointer :: Sa_shum(:) => null() + real(r8), pointer :: Sa_pbot(:) => null() + real(r8), pointer :: Sa_u10m(:) => null() + real(r8), pointer :: Sa_v10m(:) => null() + real(r8), pointer :: Sa_t2m(:) => null() + real(r8), pointer :: Sa_q2m(:) => null() + real(r8), pointer :: Sa_pslv(:) => null() + real(r8), pointer :: Faxa_lwdn(:) => null() + real(r8), pointer :: Faxa_rain(:) => null() + real(r8), pointer :: Faxa_snow(:) => 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() + + ! stream data + real(r8), pointer :: strm_mask(:) => null() + + real(r8) :: tbotmax ! units detector + real(r8) :: maskmax ! units detector + + real(r8) , parameter :: tKFrz = SHR_CONST_TKFRZ + 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__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine datm_datamode_gefs_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_tbot' ) + call dshr_fldList_add(fldsExport, 'Sa_pbot' ) + call dshr_fldList_add(fldsExport, 'Sa_shum' ) + call dshr_fldList_add(fldsExport, 'Sa_u10m' ) + call dshr_fldList_add(fldsExport, 'Sa_v10m' ) + call dshr_fldList_add(fldsExport, 'Sa_t2m' ) + call dshr_fldList_add(fldsExport, 'Sa_q2m' ) + call dshr_fldList_add(fldsExport, 'Sa_pslv' ) + call dshr_fldList_add(fldsExport, 'Faxa_rain' ) + call dshr_fldList_add(fldsExport, 'Faxa_snow' ) + 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_lwdn' ) + + 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_gefs_advertise + + !=============================================================================== + subroutine datm_datamode_gefs_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 + character(len=*), parameter :: subname='(datm_init_pointers): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! initialize pointers for module level stream arrays + call shr_strdata_get_stream_pointer( sdat, 'Sa_mask' , strm_mask , 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_shum' , fldptr1=Sa_shum , 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_t2m' , fldptr1=Sa_t2m , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Sa_q2m' , fldptr1=Sa_q2m , 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, 'Faxa_rain' , fldptr1=Faxa_rain , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call dshr_state_getfldptr(exportState, 'Faxa_snow' , fldptr1=Faxa_snow, 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_lwdn' , fldptr1=Faxa_lwdn , rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine datm_datamode_gefs_init_pointers + + !=============================================================================== + subroutine datm_datamode_gefs_advance(exportstate, masterproc, logunit, mpicom, target_ymd, target_tod, model_calendar, rc) + + ! input/output variables + type(ESMF_State) , intent(inout) :: exportState + logical , intent(in) :: masterproc + integer , intent(in) :: logunit + integer , intent(in) :: mpicom + integer , intent(in) :: target_ymd + integer , intent(in) :: target_tod + character(len=*) , intent(in) :: model_calendar + integer , intent(out) :: rc + + ! local variables + logical :: first_time = .true. + integer :: n ! indices + integer :: lsize ! size of attr vect + real(r8) :: rtmp + real(r8) :: tbot, pbot + character(len=*), parameter :: subname='(datm_datamode_gefs_advance): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + lsize = size(strm_mask) + + if (first_time) then + ! determine tbotmax (see below for use) + rtmp = maxval(Sa_tbot(:)) + call shr_mpi_max(rtmp, tbotmax, mpicom, 'datm_tbot', all=.true.) + if (masterproc) write(logunit,*) trim(subname),' tbotmax = ',tbotmax + + ! determine maskmax (see below for use) + rtmp = maxval(strm_mask(:)) + call shr_mpi_max(rtmp, maskmax, mpicom, 'datm_mask', all=.true.) + if (masterproc) write(logunit,*) trim(subname),' maskmax = ',maskmax + + ! reset first_time + first_time = .false. + end if + + do n = 1, lsize + !--- temperature --- + if (tbotmax < 50.0_r8) Sa_tbot(n) = Sa_tbot(n) + tkFrz + ! Limit very cold forcing to 180K + Sa_tbot(n) = max(180._r8, Sa_tbot(n)) + end do + + 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(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_gefs_restart_read + +end module datm_datamode_gefs_mod diff --git a/dice/ice_comp_nuopc.F90 b/dice/ice_comp_nuopc.F90 index e9ec2b5b7..7eef7caf8 100644 --- a/dice/ice_comp_nuopc.F90 +++ b/dice/ice_comp_nuopc.F90 @@ -27,7 +27,7 @@ module ice_comp_nuopc use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_log_clock_advance use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck - use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_init_from_xml, shr_strdata_advance + use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_init_from_config, shr_strdata_advance 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 @@ -68,7 +68,7 @@ module ice_comp_nuopc character(*) , parameter :: nullstr = 'null' ! dice_in namelist input - character(CL) :: xmlfilename = nullstr ! filename to obtain namelist info from + character(CL) :: streamfilename = nullstr ! filename to obtain stream info from character(CL) :: nlfilename = nullstr ! filename to obtain namelist info from character(CL) :: dataMode ! flags physics options wrt input data character(CL) :: model_meshfile = nullstr ! full pathname to model meshfile @@ -284,8 +284,11 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Initialize stream data type - xmlfilename = 'dice.streams'//trim(inst_suffix)//'.xml' - call shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, 'ICE', logunit, rc=rc) + streamfilename = 'dice.streams'//trim(inst_suffix) +#ifndef DISABLE_FoX + streamfilename = trim(streamfilename)//'.xml' +#endif + call shr_strdata_init_from_config(sdat, streamfilename, model_mesh, clock, 'ICE', logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('dice_strdata_init') diff --git a/dlnd/lnd_comp_nuopc.F90 b/dlnd/lnd_comp_nuopc.F90 index 54237b734..8f8649d9e 100644 --- a/dlnd/lnd_comp_nuopc.F90 +++ b/dlnd/lnd_comp_nuopc.F90 @@ -24,7 +24,7 @@ module lnd_comp_nuopc use shr_mpi_mod , only : shr_mpi_bcast 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_xml + use dshr_strdata_mod , only : shr_strdata_init_from_config use dshr_mod , only : dshr_model_initphase, dshr_init use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_log_clock_advance use dshr_mod , only : dshr_restart_read, dshr_restart_write, dshr_mesh_init @@ -69,7 +69,7 @@ module lnd_comp_nuopc character(CL) :: dataMode = nullstr ! flags physics options wrt input data character(CL) :: model_meshfile = nullstr ! full pathname to model meshfile character(CL) :: model_maskfile = nullstr ! full pathname to obtain mask from - character(CL) :: xmlfilename ! filename to obtain stream info from + character(CL) :: streamfilename ! filename to obtain stream info from character(CL) :: nlfilename = nullstr ! filename to obtain namelist info from logical :: force_prognostic_true = .false. ! if true set prognostic true character(CL) :: restfilm = nullstr ! model restart file namelist @@ -256,8 +256,11 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) model_meshfile, model_maskfile, model_mesh, model_mask, model_frac, restart_read, rc=rc) ! Initialize stream data type - xmlfilename = 'dlnd.streams'//trim(inst_suffix)//'.xml' - call shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, 'LND', logunit, rc=rc) + streamfilename = 'dlnd.streams'//trim(inst_suffix) +#ifndef DISABLE_FoX + streamfilename = trim(streamfilename)//'.xml' +#endif + call shr_strdata_init_from_config(sdat, streamfilename, model_mesh, clock, 'LND', logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('dlnd_strdata_init') diff --git a/docn/ocn_comp_nuopc.F90 b/docn/ocn_comp_nuopc.F90 index ba7a55ea7..46391bd36 100644 --- a/docn/ocn_comp_nuopc.F90 +++ b/docn/ocn_comp_nuopc.F90 @@ -24,7 +24,7 @@ module ocn_comp_nuopc use shr_cal_mod , only : shr_cal_ymd2date use shr_mpi_mod , only : shr_mpi_bcast 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_xml + 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 use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy @@ -82,7 +82,7 @@ module ocn_comp_nuopc character(*) , parameter :: nullstr = 'null' ! docn_in namelist input - character(CL) :: xmlfilename = nullstr ! filename to obtain namelist info from + 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) :: model_meshfile = nullstr ! full pathname to model meshfile @@ -307,8 +307,11 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! Initialize stream data type if not aqua planet if (.not. aquaplanet) then - xmlfilename = trim(modelname)//'.streams'//trim(inst_suffix)//'.xml' - call shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, 'OCN', logunit, rc=rc) + streamfilename = trim(modelname)//'.streams'//trim(inst_suffix) +#ifndef DISABLE_FoX + streamfilename = trim(streamfilename)//'.xml' +#endif + call shr_strdata_init_from_config(sdat, streamfilename, model_mesh, clock, 'OCN', logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if call ESMF_TraceRegionExit('docn_strdata_init') diff --git a/drof/rof_comp_nuopc.F90 b/drof/rof_comp_nuopc.F90 index 709329cc2..5c901c5d0 100644 --- a/drof/rof_comp_nuopc.F90 +++ b/drof/rof_comp_nuopc.F90 @@ -25,7 +25,7 @@ module rof_comp_nuopc use shr_mpi_mod , only : shr_mpi_bcast 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_xml + use dshr_strdata_mod , only : shr_strdata_init_from_config use dshr_mod , only : dshr_model_initphase, dshr_init use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock use dshr_mod , only : dshr_restart_read, dshr_restart_write, dshr_mesh_init @@ -62,7 +62,7 @@ module rof_comp_nuopc character(CL) :: case_name ! case name character(*) , parameter :: nullstr = 'null' ! drof_in namelist input - character(CL) :: xmlfilename = nullstr ! filename to obtain namelist info from + 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) :: model_meshfile = nullstr ! full pathname to model meshfile @@ -257,8 +257,11 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Initialize stream data type - xmlfilename = 'drof.streams'//trim(inst_suffix)//'.xml' - call shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, 'ROF', logunit, rc=rc) + streamfilename = 'drof.streams'//trim(inst_suffix) +#ifndef DISABLE_FOX + streamfilename = trim(streamfilename)//'.xml' +#endif + call shr_strdata_init_from_config(sdat, streamfilename, model_mesh, clock, 'ROF', logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('drof_strdata_init') diff --git a/dshr/dshr_mod.F90 b/dshr/dshr_mod.F90 index 25e268f5a..d950dc331 100644 --- a/dshr/dshr_mod.F90 +++ b/dshr/dshr_mod.F90 @@ -41,7 +41,7 @@ module dshr_mod #ifdef CESMCOUPLED use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat #endif - use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_init_from_xml, SHR_STRDATA_GET_STREAM_COUNT + use dshr_strdata_mod , only : shr_strdata_type, SHR_STRDATA_GET_STREAM_COUNT use dshr_methods_mod , only : chkerr use pio diff --git a/dwav/wav_comp_nuopc.F90 b/dwav/wav_comp_nuopc.F90 index 924b9642a..8dc4978c1 100644 --- a/dwav/wav_comp_nuopc.F90 +++ b/dwav/wav_comp_nuopc.F90 @@ -24,7 +24,7 @@ module wav_comp_nuopc use shr_mpi_mod , only : shr_mpi_bcast use dshr_methods_mod , only : dshr_state_getfldptr, chkerr, memcheck, dshr_state_diagnose use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance - use dshr_strdata_mod , only : shr_strdata_init_from_xml + use dshr_strdata_mod , only : shr_strdata_init_from_config use dshr_mod , only : dshr_model_initphase, dshr_init use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_log_clock_advance use dshr_mod , only : dshr_restart_read, dshr_restart_write, dshr_mesh_init @@ -64,7 +64,7 @@ module wav_comp_nuopc character(*) , parameter :: nullstr = 'null' ! dwav_in namelist input - character(CL) :: xmlfilename = nullstr ! filename to obtain namelist info from + 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) :: model_meshfile = nullstr ! full pathname to model meshfile @@ -244,8 +244,11 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Initialize stream data type if not aqua planet - xmlfilename = 'dwav.streams'//trim(inst_suffix)//'.xml' - call shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, 'WAV', logunit, rc=rc) + streamfilename = 'dwav.streams'//trim(inst_suffix) +#ifndef DISABLE_FoX + streamfilename = trim(streamfilename)//'.xml' +#endif + call shr_strdata_init_from_config(sdat, streamfilename, model_mesh, clock, 'WAV', logunit, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TraceRegionExit('dwav_strdata_init') diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index d87d6844d..c735a896a 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -7,7 +7,7 @@ module dshr_strdata_mod use ESMF , only : ESMF_Clock, ESMF_VM, ESMF_VMGet, ESMF_VMGetCurrent use ESMF , only : ESMF_DistGrid, ESMF_SUCCESS, ESMF_MeshGet, ESMF_DistGridGet use ESMF , only : ESMF_VMBroadCast, ESMF_MeshIsCreated, ESMF_MeshCreate - use ESMF , only : ESMF_CALKIND_NOLEAP, ESMF_CALKIND_GREGORIAN + use ESMF , only : ESMF_Calendar, ESMF_CALKIND_NOLEAP, ESMF_CALKIND_GREGORIAN use ESMF , only : ESMF_CalKind_Flag, ESMF_Time, ESMF_TimeInterval use ESMF , only : ESMF_TimeIntervalGet, ESMF_TYPEKIND_R8, ESMF_FieldCreate use ESMF , only : ESMF_FILEFORMAT_ESMFMESH, ESMF_FieldCreate @@ -34,7 +34,10 @@ module dshr_strdata_mod use dshr_stream_mod , only : shr_stream_streamtype, shr_stream_getModelFieldList, shr_stream_getStreamFieldList use dshr_stream_mod , only : shr_stream_taxis_cycle, shr_stream_taxis_extend, shr_stream_findBounds use dshr_stream_mod , only : shr_stream_getCurrFile, shr_stream_setCurrFile, shr_stream_getMeshFilename - use dshr_stream_mod , only : shr_stream_init_from_xml, shr_stream_init_from_inline + use dshr_stream_mod , only : shr_stream_init_from_inline, shr_stream_init_from_esmfconfig +#ifndef DISABLE_FoX + use dshr_stream_mod , only : shr_stream_init_from_xml +#endif use dshr_stream_mod , only : shr_stream_getnextfilename, shr_stream_getprevfilename, shr_stream_getData use dshr_tinterp_mod , only : shr_tInterp_getCosz, shr_tInterp_getAvgCosz, shr_tInterp_getFactors use dshr_methods_mod , only : dshr_fldbun_getfldptr, dshr_fldbun_getfieldN, dshr_fldbun_fldchk, chkerr @@ -53,7 +56,7 @@ module dshr_strdata_mod private public :: shr_strdata_type - public :: shr_strdata_init_from_xml + public :: shr_strdata_init_from_config public :: shr_strdata_init_from_inline public :: shr_strdata_setOrbs public :: shr_strdata_advance @@ -177,11 +180,11 @@ type(ESMF_FieldBundle) function shr_strdata_get_stream_fieldbundle(sdat, ns, nam end function shr_strdata_get_stream_fieldbundle !=============================================================================== - subroutine shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, compname, logunit, rc) + subroutine shr_strdata_init_from_config(sdat, streamfilename, model_mesh, clock, compname, logunit, rc) ! input/output variables type(shr_strdata_type) , intent(inout) :: sdat - character(len=*) , intent(in) :: xmlfilename + character(len=*) , intent(in) :: streamfilename type(ESMF_Mesh) , intent(in) :: model_mesh type(ESMF_Clock) , intent(in) :: clock character(len=*) , intent(in) :: compname @@ -191,7 +194,7 @@ subroutine shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, compn ! local variables type(ESMF_VM) :: vm integer :: i, localPet - character(len=*), parameter :: subname='(shr_strdata_init_from_xml)' + character(len=*), parameter :: subname='(shr_strdata_init_from_config)' ! ---------------------------------------------- rc = ESMF_SUCCESS call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) @@ -214,8 +217,13 @@ subroutine shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, compn ! Initialize sdat streams (read xml file for streams) sdat%masterproc = (localPet == master_task) - call shr_stream_init_from_xml(xmlfilename, sdat%stream, sdat%masterproc, sdat%logunit, & +#ifdef DISABLE_FoX + call shr_stream_init_from_esmfconfig(streamfilename, sdat%stream, sdat%logunit, & + sdat%pio_subsystem, sdat%io_type, sdat%io_format, rc=rc) +#else + call shr_stream_init_from_xml(streamfilename, sdat%stream, sdat%masterproc, sdat%logunit, & sdat%pio_subsystem, sdat%io_type, sdat%io_format, trim(compname), rc=rc) +#endif allocate(sdat%pstrm(shr_strdata_get_stream_count(sdat))) @@ -228,7 +236,7 @@ subroutine shr_strdata_init_from_xml(sdat, xmlfilename, model_mesh, clock, compn call shr_strdata_init(sdat, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - end subroutine shr_strdata_init_from_xml + end subroutine shr_strdata_init_from_config !=============================================================================== subroutine shr_strdata_init_from_inline(sdat, my_task, logunit, compname, & @@ -370,6 +378,7 @@ subroutine shr_strdata_init(sdat, model_clock, rc) ! local variables type(ESMF_Mesh), pointer :: stream_mesh + type(ESMF_Calendar) :: esmf_calendar ! esmf calendar type(ESMF_CalKind_Flag) :: esmf_caltype ! esmf calendar type character(CS) :: calendar ! calendar name integer :: ns ! stream index diff --git a/streams/dshr_stream_mod.F90 b/streams/dshr_stream_mod.F90 index 4aeffaef5..9a69c84a7 100644 --- a/streams/dshr_stream_mod.F90 +++ b/streams/dshr_stream_mod.F90 @@ -41,7 +41,10 @@ module dshr_stream_mod public :: shr_stream_streamType ! stream data type with private components ! !PUBLIC MEMBER FUNCTIONS: + public :: shr_stream_init_from_esmfconfig +#ifndef DISABLE_FoX public :: shr_stream_init_from_xml +#endif public :: shr_stream_init_from_inline ! initial stream type public :: shr_stream_findBounds ! return lower/upper bounding date info public :: shr_stream_getMeshFileName ! return stream filename @@ -122,9 +125,9 @@ module dshr_stream_mod contains !=============================================================================== - subroutine shr_stream_init_from_xml(xmlfilename, streamdat, isroot_task, logunit, & +#ifndef DISABLE_FoX + subroutine shr_stream_init_from_xml(streamfilename, streamdat, isroot_task, logunit, & pio_subsystem, io_type, io_format, compname, rc) - use FoX_DOM, only : extractDataContent, destroy, Node, NodeList, parseFile, getElementsByTagname use FoX_DOM, only : getLength, item use ESMF, only : ESMF_VM, ESMF_VMGetCurrent, ESMF_VMBroadCast, ESMF_SUCCESS @@ -157,7 +160,7 @@ subroutine shr_stream_init_from_xml(xmlfilename, streamdat, isroot_task, logunit ! --------------------------------------------------------------------- ! input/output variables - character(len=*), optional , intent(in) :: xmlfilename + character(len=*), optional , intent(in) :: streamfilename type(shr_stream_streamType) , intent(inout), pointer :: streamdat(:) logical , intent(in) :: isroot_task integer , intent(in) :: logunit @@ -185,9 +188,9 @@ subroutine shr_stream_init_from_xml(xmlfilename, streamdat, isroot_task, logunit if (isroot_task) then - Sdoc => parseFile(xmlfilename, iostat=status) + Sdoc => parseFile(streamfilename, iostat=status) if (status /= 0) then - call shr_sys_abort("Could not parse file "//trim(xmlfilename)) + call shr_sys_abort("Could not parse file "//trim(streamfilename)) endif streamlist => getElementsByTagname(Sdoc, "stream_info") nstrms = getLength(streamlist) @@ -377,6 +380,8 @@ subroutine shr_stream_init_from_xml(xmlfilename, streamdat, isroot_task, logunit end subroutine shr_stream_init_from_xml +#endif + !=============================================================================== subroutine shr_stream_init_from_inline(streamdat, & @@ -480,6 +485,193 @@ subroutine shr_stream_init_from_inline(streamdat, & end subroutine shr_stream_init_from_inline + !=============================================================================== + subroutine shr_stream_init_from_esmfconfig(streamfilename, streamdat, logunit, & + pio_subsystem, io_type, io_format, rc) + + use esmf , only : ESMF_VM, ESMF_VMGetCurrent, ESMF_VMBroadCast + use esmf , only : ESMF_SUCCESS, ESMF_ConfigCreate, ESMF_ConfigLoadFile + use esmf , only : ESMF_ConfigGetLen, ESMF_ConfigGetAttribute + use esmf , only : ESMF_Config, ESMF_MAXSTR + + !!--------------------------------------------------------------------- + !! The configuration file is a text file that can have following entries + !! file_id: "stream" + !! file_version: 1.0 + !! stream_info: 1 + !! taxmode: + !! tInterpAlgo: + !! readMode: + !! mapalgo: + !! dtlimit: + !! yearFirst: + !! yearLast: + !! yearAlign: + !! stream_vectors: + !! stream_mesh_file: + !! stream_lev_dimname: + !! stream_data_files: + !! stream_data_variables: + !! stream_offset: + !!--------------------------------------------------------------------- + + ! input/output variables + character(len=*), optional , intent(in) :: streamfilename + type(shr_stream_streamType) , intent(inout), pointer :: streamdat(:) + integer , intent(in) :: logunit + type(iosystem_desc_t) , intent(in), pointer :: pio_subsystem + integer , intent(in) :: io_type + integer , intent(in) :: io_format + integer , intent(out) :: rc + + ! local variables + type(ESMF_VM) :: vm + type(ESMF_Config) :: cf + integer :: i, n, nstrms + character(2) :: mystrm + character(*),parameter :: subName = '(shr_stream_init_from_esmfconfig)' + character(len=ESMF_MAXSTR), allocatable :: strm_tmpstrings(:) + character(*) , parameter :: u_FILE_u = __FILE__ + + ! --------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + nstrms = 0 + + ! allocate streamdat instance on all tasks + call ESMF_VMGetCurrent(vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! set ESMF config + cf = ESMF_ConfigCreate(rc=RC) + 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 + + ! allocate an array of shr_stream_streamtype objects on just isroot_task + if( nstrms > 0 ) then + allocate(streamdat(nstrms)) + else + call shr_sys_abort("no stream_info in config file "//trim(streamfilename)) + endif + + ! fill in non-default values for the streamdat attributes + do i=1, nstrms + write(mystrm,"(I2.2)") i + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%taxmode,label="taxmode"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%mapalgo,label="mapalgo"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%tInterpAlgo,label="tInterpAlgo"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%readMode,label="readMode"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if( ESMF_ConfigGetLen(config=CF, label="yearFirst"//mystrm//':', rc=rc) > 0 ) then + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%yearFirst,label="yearFirst"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call shr_sys_abort("yearFirst must be provided") + endif + + if( ESMF_ConfigGetLen(config=CF, label="yearLast"//mystrm//':', rc=rc) > 0 ) then + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%yearLast,label="yearLast"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call shr_sys_abort("yearLast must be provided") + endif + + if( ESMF_ConfigGetLen(config=CF, label="yearAlign"//mystrm//':', rc=rc) > 0 ) then + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%yearAlign,label="yearAlign"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call shr_sys_abort("yearAlign must be provided") + endif + + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%dtlimit,label="dtlimit"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%offset,label="stream_offset"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if( ESMF_ConfigGetLen(config=CF, label="stream_mesh_file"//mystrm//':', rc=rc) > 0 ) then + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%meshfile,label="stream_mesh_file"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call shr_sys_abort("stream_mesh_file must be provided") + endif + + if( ESMF_ConfigGetLen(config=CF, label="stream_vectors"//mystrm//':', rc=rc) > 0 ) then + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%stream_vectors,label="stream_vectors"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call shr_sys_abort("stream_vectors must be provided") + endif + + if( ESMF_ConfigGetLen(config=CF, label="stream_lev_dimname"//mystrm//':', rc=rc) > 0 ) then + call ESMF_ConfigGetAttribute(CF,value=streamdat(i)%lev_dimname,label="stream_lev_dimname"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call shr_sys_abort("stream_lev_dimname must be provided") + endif + + ! Get a list of stream file names + streamdat(i)%nfiles = ESMF_ConfigGetLen(config=CF, label="stream_data_files"//mystrm//':', rc=rc) + if( streamdat(i)%nfiles > 0) then + allocate(streamdat(i)%file( streamdat(i)%nfiles)) + allocate(strm_tmpstrings(streamdat(i)%nfiles)) + call ESMF_ConfigGetAttribute(CF,valueList=strm_tmpstrings, label="stream_data_files"//mystrm//':', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n=1,streamdat(i)%nfiles + streamdat(i)%file(n)%name = trim(strm_tmpstrings(i)) + enddo + deallocate(strm_tmpstrings) + else + call shr_sys_abort("stream data files must be provided") + endif + + ! Get name of stream variables in file and model + streamdat(i)%nvars = ESMF_ConfigGetLen(config=CF, label="stream_data_variables"//mystrm//':', rc=rc) + if( streamdat(i)%nvars > 0) then + allocate(streamdat(i)%varlist(streamdat(i)%nvars)) + allocate(strm_tmpstrings(streamdat(i)%nvars)) + call ESMF_ConfigGetAttribute(CF,valueList=strm_tmpstrings,label="stream_data_variables"//mystrm//':', rc=rc) + do n=1, streamdat(i)%nvars + streamdat(i)%varlist(n)%nameinfile = strm_tmpstrings(n)(1:index(trim(strm_tmpstrings(n)), " ")) + streamdat(i)%varlist(n)%nameinmodel = strm_tmpstrings(n)(index(trim(strm_tmpstrings(n)), " ", .true.)+1:) + enddo + else + call shr_sys_abort("stream data variables must be provided") + endif + + ! Initialize stream pio + streamdat(i)%pio_subsystem => pio_subsystem + streamdat(i)%pio_iotype = io_type + streamdat(i)%pio_ioformat = io_format + call shr_stream_getCalendar(streamdat(i), 1, streamdat(i)%calendar) + + ! 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") + end if + + enddo ! end loop nstrm + + ! Set logunit + streamdat(:)%logunit = logunit + + ! initialize flag that stream has been set + streamdat(:)%init = .true. + + end subroutine shr_stream_init_from_esmfconfig !=============================================================================== subroutine shr_stream_findBounds(strm, mDateIn, secIn, isroot_task, & mDateLB, dDateLB, secLB, n_lb, fileLB, mDateUB, dDateUB, secUB, n_ub, fileUB)