Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create cplhist mode for dice #290

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dice/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
project(dice Fortran)
set(SRCFILES ice_comp_nuopc.F90
dice_datamode_ssmi_mod.F90
dice_datamode_cplhist_mod.F90
dice_flux_atmice_mod.F90)

foreach(FILE ${SRCFILES})
Expand Down
195 changes: 195 additions & 0 deletions dice/dice_datamode_cplhist_mod.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
module dice_datamode_cplhist_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_TkFrzsw
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 :: dice_datamode_cplhist_advertise
public :: dice_datamode_cplhist_init_pointers
public :: dice_datamode_cplhist_advance
public :: dice_datamode_cplhist_restart_read
public :: dice_datamode_cplhist_restart_write

! export fields
! ice to atm in CMEPS/mediator/esmFldsExchange_ufs_mod.F90
real(r8), pointer :: Si_ifrac(:) => null()
real(r8), pointer :: Si_imask(:) => null()
real(r8), pointer :: Faii_taux(:) => null()
real(r8), pointer :: Faii_tauy(:) => null()
real(r8), pointer :: Faii_lat(:) => null()
real(r8), pointer :: Faii_sen(:) => null()
real(r8), pointer :: Faii_lwup(:) => null()
real(r8), pointer :: Faii_evap(:) => null()
real(r8), pointer :: Si_vice(:) => null()
real(r8), pointer :: Si_vsno(:) => null()
real(r8), pointer :: Si_t(:) => null()
real(r8), pointer :: Si_avsdr(:) => null()
real(r8), pointer :: Si_avsdf(:) => null()
real(r8), pointer :: Si_anidr(:) => null()
real(r8), pointer :: Si_anidf(:) => null()

character(*) , parameter :: nullstr = 'null'
character(*) , parameter :: rpfile = 'rpointer.ice'
character(*) , parameter :: u_FILE_u = &
__FILE__

!===============================================================================
contains
!===============================================================================

subroutine dice_datamode_cplhist_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, 'Si_ifrac' )
call dshr_fldList_add(fldsExport, 'Si_imask' )
call dshr_fldList_add(fldsExport, 'Faii_taux' )
call dshr_fldList_add(fldsExport, 'Faii_tauy' )
call dshr_fldList_add(fldsExport, 'Faii_lat' )
call dshr_fldList_add(fldsExport, 'Faii_sen' )
call dshr_fldList_add(fldsExport, 'Faii_lwup' )
call dshr_fldList_add(fldsExport, 'Faii_evap' )
call dshr_fldList_add(fldsExport, 'Si_vice' )
call dshr_fldList_add(fldsExport, 'Si_vsno' )
call dshr_fldList_add(fldsExport, 'Si_t' )
call dshr_fldList_add(fldsExport, 'Si_avsdr' )
call dshr_fldList_add(fldsExport, 'Si_avsdf' )
call dshr_fldList_add(fldsExport, 'Si_anidr' )
call dshr_fldList_add(fldsExport, 'Si_anidf' )

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('(dice_comp_advertise): Fr_ice'//trim(fldList%stdname), ESMF_LOGMSG_INFO)
fldList => fldList%next
enddo

end subroutine dice_datamode_cplhist_advertise

!===============================================================================
subroutine dice_datamode_cplhist_init_pointers(importState, exportState,sdat,rc)

! input/output variables
type(ESMF_State) , intent(inout) :: importState
type(ESMF_State) , intent(inout) :: exportState
type(shr_strdata_type) , intent(in) :: sdat
integer , intent(out) :: rc

! local variables
character(len=*), parameter :: subname='(dice_init_pointers): '
!-------------------------------------------------------------------------------

rc = ESMF_SUCCESS

! initialize pointers to export fields
call dshr_state_getfldptr(exportState, 'Si_ifrac' , fldptr1=Si_ifrac , rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Si_imask' , fldptr1=Si_imask , rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Faii_taux' , fldptr1=Faii_taux , allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Faii_tauy' , fldptr1=Faii_tauy , allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Faii_lat' , fldptr1=Faii_lat , allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Faii_sen', fldptr1=Faii_sen, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Faii_lwup', fldptr1=Faii_lwup, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Faii_evap', fldptr1=Faii_evap, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Si_vice', fldptr1=Si_vice, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Si_vsno', fldptr1=Si_vsno, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Si_t', fldptr1=Si_t, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Si_avsdr', fldptr1=Si_avsdr, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Si_avsdf', fldptr1=Si_avsdf, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Si_anidr', fldptr1=Si_anidr, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call dshr_state_getfldptr(exportState, 'Si_anidf', fldptr1=Si_anidf, allowNullReturn=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return

!Initialize (e.g., =0)?

end subroutine dice_datamode_cplhist_init_pointers

!===============================================================================
subroutine dice_datamode_cplhist_advance(rc)

! input/output variables
integer, intent(out) :: rc

! local variables
character(len=*), parameter :: subname='(dice_datamode_cplhist_advance): '
!-------------------------------------------------------------------------------

rc = ESMF_SUCCESS

!Unit conversions, calculations,....
!Where aice=0, Si_t=0K (as missing value). Interpolation in time between ice that comes or goes then has issues
where(Si_t .LT. 10) Si_t = shr_const_TkFrzsw

end subroutine dice_datamode_cplhist_advance

!===============================================================================
subroutine dice_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, 'dice', inst_suffix, ymd, tod, &
logunit, my_task, sdat)

end subroutine dice_datamode_cplhist_restart_write

!===============================================================================
subroutine dice_datamode_cplhist_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 dice_datamode_cplhist_restart_read

end module dice_datamode_cplhist_mod
88 changes: 78 additions & 10 deletions dice/ice_comp_nuopc.F90
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module cdeps_dice_comp
use ESMF , only : ESMF_AlarmIsRinging, ESMF_METHOD_INITIALIZE
use ESMF , only : ESMF_ClockGet, ESMF_TimeGet, ESMF_MethodRemove, ESMF_MethodAdd
use ESMF , only : ESMF_GridCompSetEntryPoint, operator(+), ESMF_AlarmRingerOff
use ESMF , only : ESMF_ClockGetAlarm, ESMF_StateGet, ESMF_Field, ESMF_FieldGet
use ESMF , only : ESMF_ClockGetAlarm, ESMF_StateGet, ESMF_Field, ESMF_FieldGet, ESMF_MAXSTR
use NUOPC , only : NUOPC_CompDerive, NUOPC_CompSetEntryPoint, NUOPC_CompSpecialize
use NUOPC , only : NUOPC_CompAttributeGet, NUOPC_Advertise
use NUOPC_Model , only : model_routine_SS => SetServices
Expand All @@ -41,6 +41,12 @@ module cdeps_dice_comp
use dice_datamode_ssmi_mod , only : dice_datamode_ssmi_advance
use dice_datamode_ssmi_mod , only : dice_datamode_ssmi_restart_read
use dice_datamode_ssmi_mod , only : dice_datamode_ssmi_restart_write
!
use dice_datamode_cplhist_mod , only : dice_datamode_cplhist_advertise
use dice_datamode_cplhist_mod , only : dice_datamode_cplhist_init_pointers
use dice_datamode_cplhist_mod , only : dice_datamode_cplhist_advance
use dice_datamode_cplhist_mod , only : dice_datamode_cplhist_restart_read
use dice_datamode_cplhist_mod , only : dice_datamode_cplhist_restart_write

implicit none
private ! except
Expand Down Expand Up @@ -176,6 +182,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
integer :: bcasttmp(4)
real(r8) :: rbcasttmp(3)
type(ESMF_VM) :: vm
logical :: isPresent, isSet
character(len=*),parameter :: subname=trim(modName)//':(InitializeAdvertise) '
character(*) ,parameter :: F00 = "('(" // trim(modName) // ") ',8a)"
character(*) ,parameter :: F01 = "('(" // trim(modName) // ") ',a,2x,i8)"
Expand Down Expand Up @@ -265,22 +272,28 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
flux_Qacc0 = rbcasttmp(3)

! Validate datamode
if ( trim(datamode) == 'ssmi' .or. trim(datamode) == 'ssmi_iaf') then
if ( trim(datamode) == 'ssmi' .or. trim(datamode) == 'ssmi_iaf' .or. trim(datamode) == 'cplhist') then
if (my_task == main_task) write(logunit,*) ' dice datamode = ',trim(datamode)
else
call shr_sys_abort(' ERROR illegal dice datamode = '//trim(datamode))
endif

! Advertise import and export fields
call NUOPC_CompAttributeGet(gcomp, name='flds_i2o_per_cat', value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) flds_i2o_per_cat ! module variable
if ( trim(datamode) == 'ssmi' .or. trim(datamode) == 'ssmi_iaf') then
call NUOPC_CompAttributeGet(gcomp, name='flds_i2o_per_cat', value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (isPresent .and. isSet) read(cvalue,*) flds_i2o_per_cat ! module variable
endif

!datamode already validated
select case (trim(datamode))
case('ssmi', 'ssmi_iaf')
case('ssmi','ssmi_iaf')
call dice_datamode_ssmi_advertise(importState, exportState, fldsimport, fldsexport, &
flds_scalar_name, flds_i2o_per_cat, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
case('cplhist')
call dice_datamode_cplhist_advertise(exportState, fldsexport, flds_scalar_name, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end select

end subroutine InitializeAdvertise
Expand Down Expand Up @@ -488,23 +501,34 @@ subroutine dice_comp_run(importstate, exportstate, target_ymd, target_tod, cosar

if (first_time) then

! Initialize dfields with export state data that has corresponding stream field
call dshr_dfield_add(dfields, sdat, state_fld='Si_ifrac', strm_fld='Si_ifrac', &
! Initialize dfields with export state data that has corresponding stream fieldi
select case (trim(datamode))
case('ssmi','ssmi_iaf')
call dshr_dfield_add(dfields, sdat, state_fld='Si_ifrac', strm_fld='Si_ifrac', &
state=exportState, logunit=logunit, mainproc=mainproc, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
if (chkerr(rc,__LINE__,u_FILE_u)) return
case('cplhist')
call dice_init_dfields(importState, exportState, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
end select

! Initialize datamode module ponters
select case (trim(datamode))
case('ssmi', 'ssmi_iaf')
call dice_datamode_ssmi_init_pointers(importState, exportState, sdat, flds_i2o_per_cat, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
case('cplhist')
call dice_datamode_cplhist_init_pointers(importState,exportState,sdat,rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
end select

! read restart if needed
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)
case('cplhist')
call dice_datamode_cplhist_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat)
end select
end if

Expand Down Expand Up @@ -545,6 +569,9 @@ subroutine dice_comp_run(importstate, exportstate, target_ymd, target_tod, cosar
call dice_datamode_ssmi_advance(exportState, importState, cosarg, flds_i2o_per_cat, &
flux_swpf, flux_Qmin, flux_Qacc, flux_Qacc0, dt, logunit, restart_read, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
case ('cplhist')
call dice_datamode_cplhist_advance(rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end select

! Write restarts if needed
Expand All @@ -553,7 +580,8 @@ subroutine dice_comp_run(importstate, exportstate, target_ymd, target_tod, cosar
case('ssmi', 'ssmi_iaf')
call dice_datamode_ssmi_restart_write(case_name, inst_suffix, target_ymd, target_tod, &
logunit, my_task, sdat)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
case ('cplhist')
call dice_datamode_cplhist_restart_write(case_name, inst_suffix, target_ymd, target_tod, logunit, my_task, sdat)
end select
end if

Expand All @@ -566,6 +594,46 @@ subroutine dice_comp_run(importstate, exportstate, target_ymd, target_tod, cosar
call ESMF_TraceRegionExit('dice_datamode')
call ESMF_TraceRegionExit('DICE_RUN')

contains
subroutine dice_init_dfields(importState, exportState, rc)
! -----------------------------
! Initialize dfields arrays
! -----------------------------

! input/output variables
type(ESMF_State) , intent(inout) :: importState
type(ESMF_State) , intent(inout) :: exportState
integer , intent(out) :: rc

! local variables
integer :: n
integer :: fieldcount
type(ESMF_Field) :: lfield
character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:)
character(*), parameter :: subName = "(dice_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(exportState, itemCount=fieldCount, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
allocate(lfieldnamelist(fieldCount))
call ESMF_StateGet(exportState, itemNameList=lfieldnamelist, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
do n = 1, fieldCount
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)
if (chkerr(rc,__LINE__,u_FILE_u)) return
end if
end do
end subroutine dice_init_dfields

end subroutine dice_comp_run

!===============================================================================
Expand Down
3 changes: 3 additions & 0 deletions doc/source/dice.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ ssmi (``dice_datamode_ssmi_mod.F90``)
ssmi_iaf (``dice_datamode_ssmi_mod.F90``)
- `ssmi_iaf` is the interannually varying version of `ssmi`.

cplhist (``dice_datamode_cplhist_mod.F90``)
- It provides mediator history variables from ice component of previous simulation.

.. _dice-cime-vars:

---------------------------------------
Expand Down
Loading