Skip to content

Commit

Permalink
Add Wave slow loop coupling and Field Exchanges for waves in nems (#266)
Browse files Browse the repository at this point in the history
Adds the ability to optionally place waves in the slow coupling loop. Also updates esmFldsExchange_nems to advertise and initialize required fields for the UFS S2SW application.
Specific notes
A FBExpAccumWav and counter are added. The prep_wav phase is split into prep_wav_accum and prep_wav_avg, replicating what is done for the the ocean component.
For waves in the fast coupling loop, the current prep_wav phase in the run sequence should be replaced with prep_wav_accum followed by prep_wav_avg. Answers are B4B in UFS testing when compared to using the current prep_wav phase.
For waves in the UFS S2SW application, the required fields are added to esmFldsExchange_nems. This requires a temporary conditional around the relevant code so that the S2SW app can continue to use NUOPC connectors during the transition to CMEPS.
For the HAFS applications in UFS using both CMEPS and waves, the src and dst masking in med_map_mod are switched to conform with the usual interpretation of src and dst masking. Implementing this change for the HAFS wave coupled applications will ensure that no additional change to CMEPS will be required when HAFS is switched to the new WW3 cap. For continued use of the existing WW3 cap during the transition period, this requires the setting of these variables correctly for the wave model using nems.configure
    mask_value_water = 1
   mask_value_land = 0
An extraneous ice->atm mapping in post_ice has also been removed and additional control of the dststatus_print
is applied to prevent nonsensical files being produced.
  • Loading branch information
DeniseWorthen authored Feb 1, 2022
1 parent c03f5a4 commit 7419333
Show file tree
Hide file tree
Showing 12 changed files with 339 additions and 130 deletions.
3 changes: 2 additions & 1 deletion cime_config/runseq/runseq_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ def gen_runseq(case, coupling_times):
runseq.add_action("MED med_phases_prep_ice" , med_to_ice)
runseq.add_action("MED -> ICE :remapMethod=redist" , med_to_ice)

runseq.add_action("MED med_phases_prep_wav" , med_to_wav)
runseq.add_action("MED med_phases_prep_wav_accum" , med_to_wav)
runseq.add_action("MED med_phases_prep_wav_avg" , med_to_wav)
runseq.add_action("MED -> WAV :remapMethod=redist" , med_to_wav)

runseq.add_action("MED med_phases_prep_rof" , med_to_rof and not rof_outer_loop)
Expand Down
4 changes: 2 additions & 2 deletions mediator/esmFldsExchange_hafs_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ subroutine esmFldsExchange_hafs_advt(gcomp, phase, rc)
! ---------------------------------------------------------------------
if (hafs_attr%atm_present .and. hafs_attr%wav_present) then
allocate(S_flds(1))
S_flds = (/'Sw_zo'/) ! wave_z0_roughness_length
S_flds = (/'Sw_z0'/) ! wave_z0_roughness_length
do n = 1,size(S_flds)
fldname = trim(S_flds(n))
call addfld(fldListFr(compwav)%flds, trim(fldname))
Expand Down Expand Up @@ -385,7 +385,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc)
! ---------------------------------------------------------------------
if (hafs_attr%atm_present .and. hafs_attr%wav_present) then
allocate(S_flds(1))
S_flds = (/'Sw_zo'/) ! wave_z0_roughness_length
S_flds = (/'Sw_z0'/) ! wave_z0_roughness_length
do n = 1,size(S_flds)
fldname = trim(S_flds(n))
if (fldchk(is_local%wrap%FBExp(compatm),trim(fldname),rc=rc) .and. &
Expand Down
75 changes: 74 additions & 1 deletion mediator/esmFldsExchange_nems_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc)
use NUOPC
use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8
use med_utils_mod , only : chkerr => med_utils_chkerr
use med_internalstate_mod , only : InternalState
use med_internalstate_mod , only : mastertask, logunit
use med_internalstate_mod , only : compmed, compatm, compocn, compice, comprof, ncomps
use med_internalstate_mod , only : compmed, compatm, compocn, compice, comprof, compwav, ncomps
use med_internalstate_mod , only : mapbilnr, mapconsf, mapconsd, mappatch
use med_internalstate_mod , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf
use med_internalstate_mod , only : mapconsf_aofrac
Expand All @@ -42,6 +43,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc)
integer , intent(inout) :: rc

! local variables:
type(InternalState) :: is_local
integer :: i, n, maptype
character(len=CX) :: msgString
character(len=CL) :: cvalue
Expand All @@ -52,6 +54,10 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc)

rc = ESMF_SUCCESS

nullify(is_local%wrap)
call ESMF_GridCompGetInternalState(gcomp, is_local, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return

! Set maptype according to coupling_mode
if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then
maptype = mapnstod_consf
Expand Down Expand Up @@ -159,6 +165,16 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc)
call addmap(fldListFr(compocn)%flds, 'So_t', compatm, maptype, 'ofrac', 'unset')
call addmrg(fldListTo(compatm)%flds, 'So_t', mrg_from=compocn, mrg_fld='So_t', mrg_type='copy')

! temporary conditional to avoid conflicts of advertised fields
! when waves are passing through connectors
if (is_local%wrap%comp_present(compwav)) then
! to atm: surface roughness length from wav
call addfld(fldListFr(compwav)%flds, 'Sw_z0')
call addfld(fldListTo(compatm)%flds, 'Sw_z0')
call addmap(fldListFr(compwav)%flds, 'Sw_z0', compatm, mapnstod_consf, 'one', 'unset')
call addmrg(fldListTo(compatm)%flds, 'Sw_z0', mrg_from=compwav, mrg_fld='Sw_z0', mrg_type='copy')
end if

!=====================================================================
! FIELDS TO OCEAN (compocn)
!=====================================================================
Expand Down Expand Up @@ -291,6 +307,23 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc)
end do
deallocate(flds)

! temporary conditional to avoid conflicts of advertised fields
! when waves are passing through connectors
if (is_local%wrap%comp_present(compwav)) then
! to ocn: partitioned stokes drift from wav
allocate(flds(6))
flds = (/'Sw_ustokes1', 'Sw_ustokes2', 'Sw_ustokes3', &
'Sw_vstokes1', 'Sw_vstokes2', 'Sw_vstokes3'/)
do n = 1,size(flds)
fldname = trim(flds(n))
call addfld(fldListTo(compocn)%flds, trim(fldname))
call addfld(fldListFr(compwav)%flds, trim(fldname))
call addmap(fldListFr(compwav)%flds, trim(fldname), compocn, mapfcopy, 'unset', 'unset')
call addmrg(fldListTo(compocn)%flds, trim(fldname), mrg_from=compwav, mrg_fld=trim(fldname), mrg_type='copy')
end do
deallocate(flds)
end if

!=====================================================================
! FIELDS TO ICE (compice)
!=====================================================================
Expand Down Expand Up @@ -353,6 +386,46 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc)
end do
deallocate(flds)

!=====================================================================
! FIELDS TO WAV (compwav)
!=====================================================================

! temporary conditional to avoid conflicts of advertised fields
! when waves are passing through connectors
if (is_local%wrap%comp_present(compwav)) then
! to wav - 10m winds and bottom temperature from atm
allocate(flds(3))
flds = (/'Sa_u10m', 'Sa_v10m', 'Sa_tbot'/)
do n = 1,size(flds)
fldname = trim(flds(n))
call addfld(fldListFr(compatm)%flds, trim(fldname))
call addfld(fldListTo(compwav)%flds, trim(fldname))
call addmap(fldListFr(compatm)%flds, trim(fldname), compwav, mapnstod_consf, 'one', 'unset')
call addmrg(fldListTo(compwav)%flds, trim(fldname), mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy')
end do
deallocate(flds)

! to wav: sea ice fraction
call addfld(fldListTo(compwav)%flds, 'Si_ifrac')
call addfld(fldListFr(compice)%flds, 'Si_ifrac')
call addmap(fldListFr(compice)%flds, 'Si_ifrac', compwav, mapfcopy , 'unset', 'unset')
call addmrg(fldListTo(compwav)%flds, 'Si_ifrac', mrg_from=compice, mrg_fld='Si_ifrac', mrg_type='copy')

! to wav: zonal sea water velocity from ocn
! to wav: meridional sea water velocity from ocn
! to wav: surface temperature from ocn
allocate(flds(3))
flds = (/'So_u', 'So_v', 'So_t'/)
do n = 1,size(flds)
fldname = trim(flds(n))
call addfld(fldListTo(compwav)%flds, trim(fldname))
call addfld(fldListFr(compocn)%flds, trim(fldname))
call addmap(fldListFr(compocn)%flds, trim(fldname), compwav, mapfcopy , 'unset', 'unset')
call addmrg(fldListTo(compwav)%flds, trim(fldname), mrg_from=compocn, mrg_fld=trim(fldname), mrg_type='copy')
end do
deallocate(flds)
end if

end subroutine esmFldsExchange_nems

end module esmFldsExchange_nems_mod
38 changes: 30 additions & 8 deletions mediator/med.F90
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ subroutine SetServices(gcomp, rc)
use med_phases_prep_atm_mod , only: med_phases_prep_atm
use med_phases_prep_ice_mod , only: med_phases_prep_ice
use med_phases_prep_lnd_mod , only: med_phases_prep_lnd
use med_phases_prep_wav_mod , only: med_phases_prep_wav
use med_phases_prep_wav_mod , only: med_phases_prep_wav_accum
use med_phases_prep_wav_mod , only: med_phases_prep_wav_avg
use med_phases_prep_glc_mod , only: med_phases_prep_glc
use med_phases_prep_rof_mod , only: med_phases_prep_rof
use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_accum
Expand Down Expand Up @@ -343,10 +344,20 @@ subroutine SetServices(gcomp, rc)
!------------------

call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, &
phaseLabelList=(/"med_phases_prep_wav"/), userRoutine=mediator_routine_Run, rc=rc)
phaseLabelList=(/"med_phases_prep_wav_accum"/), userRoutine=mediator_routine_Run, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, &
specPhaseLabel="med_phases_prep_wav", specRoutine=med_phases_prep_wav, rc=rc)
specPhaseLabel="med_phases_prep_wav_accum", specRoutine=med_phases_prep_wav_accum, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, &
specPhaselabel="med_phases_prep_wav_accum", specRoutine=NUOPC_NoOp, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, &
phaseLabelList=(/"med_phases_prep_wav_avg"/), userRoutine=mediator_routine_Run, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, &
specPhaseLabel="med_phases_prep_wav_avg", specRoutine=med_phases_prep_wav_avg, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, &
Expand Down Expand Up @@ -638,7 +649,7 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc)
! TransferOfferGeomObject Attribute.

use ESMF , only : ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_SUCCESS, ESMF_LogFoundAllocError
use ESMF , only : ESMF_StateIsCreated
use ESMF , only : ESMF_StateIsCreated
use ESMF , only : ESMF_LogMsg_Info, ESMF_LogWrite
use ESMF , only : ESMF_END_ABORT, ESMF_Finalize, ESMF_MAXSTR
use NUOPC , only : NUOPC_AddNamespace, NUOPC_Advertise, NUOPC_AddNestedState
Expand Down Expand Up @@ -1498,6 +1509,7 @@ subroutine DataInitialize(gcomp, rc)
use med_fraction_mod , only : med_fraction_init, med_fraction_set
use med_phases_restart_mod , only : med_phases_restart_read
use med_phases_prep_ocn_mod , only : med_phases_prep_ocn_init
use med_phases_prep_wav_mod , only : med_phases_prep_wav_init
use med_phases_prep_rof_mod , only : med_phases_prep_rof_init
use med_phases_prep_glc_mod , only : med_phases_prep_glc_init
use med_phases_prep_atm_mod , only : med_phases_prep_atm
Expand Down Expand Up @@ -1784,6 +1796,16 @@ subroutine DataInitialize(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if

!---------------------------------------
! Initialize wav export accumulation field bundle
!---------------------------------------
if ( is_local%wrap%comp_present(compwav) .and. &
ESMF_StateIsCreated(is_local%wrap%NStateImp(compwav),rc=rc) .and. &
ESMF_StateIsCreated(is_local%wrap%NStateExp(compwav),rc=rc)) then
call med_phases_prep_wav_init(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if

!---------------------------------------
! Initialize glc module field bundles here if appropriate
!---------------------------------------
Expand Down Expand Up @@ -2059,12 +2081,12 @@ subroutine DataInitialize(gcomp, rc)
! Call post routines as part of initialization
!---------------------------------------
if (is_local%wrap%comp_present(compatm)) then
! map atm->ocn, atm->ice, atm->lnd
! map atm->ocn, atm->ice, atm->lnd, atm->wav
call med_phases_post_atm(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
if (is_local%wrap%comp_present(compice)) then
! call set ice_frac and map ice->atm and ice->ocn
! call set ice_frac and map ice->ocn and ice->wav
call med_phases_post_ice(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
Expand All @@ -2079,7 +2101,7 @@ subroutine DataInitialize(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
if (is_local%wrap%comp_present(compocn)) then
! map initial ocn->ice
! map initial ocn->ice, ocn->wav
call med_phases_post_ocn(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
Expand All @@ -2089,7 +2111,7 @@ subroutine DataInitialize(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
if (is_local%wrap%comp_present(compwav)) then
! map initial wav->ocn and wav->ice
! map initial wav->ocn, wav->ice, wav->atm
call med_phases_post_wav(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
Expand Down
6 changes: 4 additions & 2 deletions mediator/med_internalstate_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,10 @@ module med_internalstate_mod
type(ESMF_FieldBundle), pointer :: FBfrac(:) ! Fraction data for various components, on their grid

! Accumulators for export field bundles
type(ESMF_FieldBundle) :: FBExpAccumOcn ! Accumulator for various components export on their grid
integer :: ExpAccumOcnCnt = 0 ! Accumulator counter for each FBExpAccum
type(ESMF_FieldBundle) :: FBExpAccumOcn ! Accumulator for Ocn export on Ocn grid
integer :: ExpAccumOcnCnt = 0 ! Accumulator counter for FBExpAccumOcn
type(ESMF_FieldBundle) :: FBExpAccumWav ! Accumulator for Wav export on Wav grid
integer :: ExpAccumWavCnt = 0 ! Accumulator counter for FBExpAccumWav

! Component Mesh info
type(mesh_info_type) , pointer :: mesh_info(:)
Expand Down
Loading

0 comments on commit 7419333

Please sign in to comment.