Skip to content

Commit

Permalink
Merge branch 'jiandewang-main-candidate-EMC-2021-01-04' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
adcroft committed Jan 20, 2021
2 parents 0f664aa + ea5e245 commit fe5e605
Show file tree
Hide file tree
Showing 9 changed files with 881 additions and 1,081 deletions.
1,036 changes: 323 additions & 713 deletions config_src/nuopc_driver/mom_cap.F90

Large diffs are not rendered by default.

448 changes: 286 additions & 162 deletions config_src/nuopc_driver/mom_cap_methods.F90

Large diffs are not rendered by default.

116 changes: 24 additions & 92 deletions config_src/nuopc_driver/mom_cap_time.F90
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module MOM_cap_time
use ESMF , only : ESMF_RC_ARG_BAD
use ESMF , only : operator(<), operator(/=), operator(+), operator(-), operator(*) , operator(>=)
use ESMF , only : operator(<=), operator(>), operator(==)
use MOM_cap_methods , only : ChkErr

implicit none; private

Expand Down Expand Up @@ -125,22 +126,13 @@ subroutine AlarmInit( clock, alarm, option, &
endif

call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_TimeGet(CurrTime, yy=cyy, mm=cmm, dd=cdd, s=csec, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_TimeGet(CurrTime, yy=nyy, mm=nmm, dd=ndd, s=nsec, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! initial guess of next alarm, this will be updated below
if (present(RefTime)) then
Expand All @@ -151,25 +143,16 @@ subroutine AlarmInit( clock, alarm, option, &

! Determine calendar
call ESMF_ClockGet(clock, calendar=cal, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! Determine inputs for call to create alarm
selectcase (trim(option))

case (optNONE, optNever)
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case (optDate)
Expand All @@ -188,15 +171,9 @@ subroutine AlarmInit( clock, alarm, option, &
return
endif
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call TimeInit(NextAlarm, lymd, cal, tod=ltod, desc="optDate", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case (optIfdays0)
Expand All @@ -208,104 +185,65 @@ subroutine AlarmInit( clock, alarm, option, &
return
endif
call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=opt_n, s=0, calendar=cal, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .true.

case (optNSteps, optNStep)
call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNSeconds, optNSecond)
call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNMinutes, optNMinute)
call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNHours, optNHour)
call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNDays, optNDay)
call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNMonths, optNMonth)
call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optMonthly)
call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=1, s=0, calendar=cal, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .true.

case (optNYears, optNYear)
call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optYearly)
call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=cyy, mm=1, dd=1, s=0, calendar=cal, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .true.

case default
Expand All @@ -332,10 +270,7 @@ subroutine AlarmInit( clock, alarm, option, &
endif

alarm = ESMF_AlarmCreate( name=lalarmname, clock=clock, ringTime=NextAlarm, ringInterval=AlarmInterval, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

end subroutine AlarmInit

Expand Down Expand Up @@ -378,10 +313,7 @@ subroutine TimeInit( Time, ymd, cal, tod, desc, logunit, rc)
call date2ymd (ymd,yr,mon,day)

call ESMF_TimeSet( Time, yy=yr, mm=mon, dd=day, s=ltod, calendar=cal, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

end subroutine TimeInit

Expand Down
11 changes: 7 additions & 4 deletions config_src/nuopc_driver/mom_ocean_model_nuopc.F90
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ module MOM_ocean_model_nuopc

integer :: nstep = 0 !< The number of calls to update_ocean.
logical :: use_ice_shelf !< If true, the ice shelf model is enabled.
logical :: use_waves !< If true use wave coupling.
logical,public :: use_waves !< If true use wave coupling.

logical :: icebergs_alter_ocean !< If true, the icebergs can change ocean the
!! ocean dynamics and forcing fluxes.
Expand Down Expand Up @@ -204,7 +204,7 @@ module MOM_ocean_model_nuopc
type(marine_ice_CS), pointer :: &
marine_ice_CSp => NULL() !< A pointer to the control structure for the
!! marine ice effects module.
type(wave_parameters_cs), pointer :: &
type(wave_parameters_cs), pointer, public :: &
Waves !< A structure containing pointers to the surface wave fields
type(surface_forcing_CS), pointer :: &
forcing_CSp => NULL() !< A pointer to the MOM forcing control structure
Expand Down Expand Up @@ -388,6 +388,9 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn, i
"If true, enables surface wave modules.", default=.false.)
if (OS%use_waves) then
call MOM_wave_interface_init(OS%Time, OS%grid, OS%GV, OS%US, param_file, OS%Waves, OS%diag)
call get_param(param_file,mdl,"SURFBAND_WAVENUMBERS",OS%Waves%WaveNum_Cen, &
"Central wavenumbers for surface Stokes drift bands.",units='rad/m', &
default=0.12566)
else
call MOM_wave_interface_init_lite(param_file)
endif
Expand Down Expand Up @@ -572,7 +575,7 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, &
call set_net_mass_forcing(OS%fluxes, OS%forces, OS%grid, OS%US)

if (OS%use_waves) then
call Update_Surface_Waves(OS%grid, OS%GV, OS%US, OS%time, ocean_coupling_time_step, OS%waves)
call Update_Surface_Waves(OS%grid, OS%GV, OS%US, OS%time, ocean_coupling_time_step, OS%waves, OS%forces)
endif

if (OS%nstep==0) then
Expand Down Expand Up @@ -733,7 +736,7 @@ subroutine ocean_model_end(Ocean_sfc, Ocean_state, Time, write_restart)
type(time_type), intent(in) :: Time !< The model time, used for writing restarts.
logical, intent(in) :: write_restart !< true => write restart file

call ocean_model_save_restart(Ocean_state, Time)
if(write_restart)call ocean_model_save_restart(Ocean_state, Time)
call diag_mediator_end(Time, Ocean_state%diag, end_diag_manager=.true.)
call MOM_end(Ocean_state%MOM_CSp)
if (Ocean_state%use_ice_shelf) call ice_shelf_end(Ocean_state%Ice_shelf_CSp)
Expand Down
40 changes: 37 additions & 3 deletions config_src/nuopc_driver/mom_surface_forcing_nuopc.F90
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,16 @@ module MOM_surface_forcing_nuopc
!! ice-shelves, expressed as a coefficient
!! for divergence damping, as determined
!! outside of the ocean model in [m3/s]
real, pointer, dimension(:,:) :: ustk0 => NULL() !< Surface Stokes drift, zonal [m/s]
real, pointer, dimension(:,:) :: vstk0 => NULL() !< Surface Stokes drift, meridional [m/s]
real, pointer, dimension(:) :: stk_wavenumbers => NULL() !< The central wave number of Stokes bands [rad/m]
real, pointer, dimension(:,:,:) :: ustkb => NULL() !< Stokes Drift spectrum, zonal [m/s]
!! Horizontal - u points
!! 3rd dimension - wavenumber
real, pointer, dimension(:,:,:) :: vstkb => NULL() !< Stokes Drift spectrum, meridional [m/s]
!! Horizontal - v points
!! 3rd dimension - wavenumber
integer :: num_stk_bands !< Number of Stokes drift bands passed through the coupler
integer :: xtype !< The type of the exchange - REGRID, REDIST or DIRECT
type(coupler_2d_bc_type) :: fluxes !< A structure that may contain an array of
!! named fields used for passive tracer fluxes.
Expand Down Expand Up @@ -428,7 +438,10 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
call MOM_error(FATAL, "liquid runoff is being added via data_override but "// &
"there is no associated runoff in the IOB")
return
end if
endif
if (associated(IOB%lrunoff)) then
if(CS%liquid_runoff_from_data)call data_override('OCN', 'runoff', IOB%lrunoff, Time)
endif

! obtain fluxes from IOB; note the staggering of indices
i0 = is - isc_bnd ; j0 = js - jsc_bnd
Expand All @@ -445,7 +458,6 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,

! liquid runoff flux
if (associated(IOB%lrunoff)) then
if(CS%liquid_runoff_from_data)call data_override('OCN', 'runoff', IOB%lrunoff, Time)
fluxes%lrunoff(i,j) = kg_m2_s_conversion * IOB%lrunoff(i-i0,j-j0) * G%mask2dT(i,j)
endif

Expand Down Expand Up @@ -624,7 +636,7 @@ subroutine convert_IOB_to_forces(IOB, forces, index_bounds, Time, G, US, CS)
real :: mass_eff !< effective mass of sea ice for rigidity [R Z ~> kg m-2]

integer :: wind_stagger !< AGRID, BGRID_NE, or CGRID_NE (integers from MOM_domains)
integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq, i0, j0
integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq, i0, j0, istk
integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB, isr, ier, jsr, jer
integer :: isc_bnd, iec_bnd, jsc_bnd, jec_bnd

Expand Down Expand Up @@ -663,6 +675,7 @@ subroutine convert_IOB_to_forces(IOB, forces, index_bounds, Time, G, US, CS)
if ( (associated(IOB%area_berg) .and. (.not. associated(forces%area_berg))) .or. &
(associated(IOB%mass_berg) .and. (.not. associated(forces%mass_berg))) ) &
call allocate_mech_forcing(G, forces, iceberg=.true.)

if (associated(IOB%ice_rigidity)) then
rigidity_at_h(:,:) = 0.0
call safe_alloc_ptr(forces%rigidity_ice_u,IsdB,IedB,jsd,jed)
Expand All @@ -673,6 +686,9 @@ subroutine convert_IOB_to_forces(IOB, forces, index_bounds, Time, G, US, CS)
if (associated(forces%rigidity_ice_u)) forces%rigidity_ice_u(:,:) = 0.0
if (associated(forces%rigidity_ice_v)) forces%rigidity_ice_v(:,:) = 0.0

if ( associated(IOB%ustkb) ) &
call allocate_mech_forcing(G, forces, waves=.true., num_stk_bands=IOB%num_stk_bands)

! applied surface pressure from atmosphere and cryosphere
if (CS%use_limited_P_SSH) then
forces%p_surf_SSH => forces%p_surf
Expand Down Expand Up @@ -830,6 +846,24 @@ subroutine convert_IOB_to_forces(IOB, forces, index_bounds, Time, G, US, CS)

endif ! endif for wind related fields

! wave to ocean coupling
if ( associated(IOB%ustkb) ) then

forces%stk_wavenumbers(:) = IOB%stk_wavenumbers
do j=js,je; do i=is,ie
forces%ustk0(i,j) = IOB%ustk0(i-I0,j-J0) ! How to be careful here that the domains are right?
forces%vstk0(i,j) = IOB%vstk0(i-I0,j-J0)
enddo ; enddo
call pass_vector(forces%ustk0,forces%vstk0, G%domain )
do istk = 1,IOB%num_stk_bands
do j=js,je; do i=is,ie
forces%ustkb(i,j,istk) = IOB%ustkb(i-I0,j-J0,istk)
forces%vstkb(i,j,istk) = IOB%vstkb(i-I0,j-J0,istk)
enddo; enddo
call pass_vector(forces%ustkb(:,:,istk),forces%vstkb(:,:,istk), G%domain )
enddo
endif

! sea ice related dynamic fields
if (associated(IOB%ice_rigidity)) then
call pass_var(rigidity_at_h, G%Domain, halo=1)
Expand Down
Loading

0 comments on commit fe5e605

Please sign in to comment.