Skip to content

Commit

Permalink
FSD fixes for conservation (CICE-Consortium#495)
Browse files Browse the repository at this point in the history
This is a bug fix plus some rearranging for conservation in CICE. This impacts FSD cases as well as non-FSD cases.

There are two main aspects to the bug fix:

    Initial ice and snow volume values at the beginning of the lateral melt routine are now used for updating the snow and ice enthalpy as well other tracers for lateral melting. This is answer changing in all cases!

    The other fix is to move the computation of vi0new_lat (lateral growth from FSD) outside of the subroutine fsd_lateral_growth and a check to make sure the category vi0new (vin0new) does not exceed the total vi0new. This is a warning and it recomputes to ensure conservation. This is only answer changing in FSD cases.

    There is also a change in definition of floe_area_c, so that it is precisely half way between floe_area_l and floe_area_h. The original computation of floe_area_c based on floe_rad_c biases the area towards the lower value.

Update the fsd subroutine arguments (floe_rad_c, floe_rad_l, floe_binwidth, c_fsd_range) to store static data inside Icepack when computed in Icepack rather than pass them back and forth. Provide an ability to pass out the values from Icepack as optional arguments.

Move the computation of rsiden and get rid of fside which is no longer needed.

Clean up some comments and indentation

Update swccsm3 test, set ktherm=1

Update interface documentation

There is an associated CICE tag to go with this.
  • Loading branch information
dabail10 committed Nov 4, 2024
1 parent f20010d commit 46fdc73
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 70 deletions.
13 changes: 3 additions & 10 deletions configuration/driver/icedrv_InitMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,15 @@ module icedrv_InitMod

subroutine icedrv_initialize

use icedrv_arrays_column, only: hin_max, c_hi_range
use icedrv_arrays_column, only: floe_rad_l, floe_rad_c, &
floe_binwidth, c_fsd_range
use icedrv_arrays_column, only: hin_max, c_hi_range, floe_rad_c
use icedrv_calendar, only: dt, time, istep, istep1, &
init_calendar, calendar
use icepack_intfc, only: icepack_init_itd, icepack_init_itd_hist
use icepack_intfc, only: icepack_init_fsd_bounds
use icepack_intfc, only: icepack_init_snow
use icepack_intfc, only: icepack_init_sealvlpnd
use icepack_intfc, only: icepack_warnings_flush
use icedrv_domain_size, only: ncat, nfsd
use icedrv_domain_size, only: ncat
! use icedrv_diagnostics, only: icedrv_diagnostics_debug
use icedrv_flux, only: init_coupler_flux, init_history_therm, &
init_flux_atm_ocn
Expand Down Expand Up @@ -100,12 +98,7 @@ subroutine icedrv_initialize
endif

if (tr_fsd) then
call icepack_init_fsd_bounds( &
floe_rad_l=floe_rad_l, & ! fsd size lower bound in m (radius)
floe_rad_c=floe_rad_c, & ! fsd size bin centre in m (radius)
floe_binwidth=floe_binwidth, & ! fsd size bin width in m (radius)
c_fsd_range=c_fsd_range , & ! string for history output
write_diags=.true.)
call icepack_init_fsd_bounds(floe_rad_c_out=floe_rad_c, write_diags=.true. )
call icepack_warnings_flush(nu_diag)
if (icepack_warnings_aborted(subname)) then
call icedrv_system_abort(file=__FILE__,line=__LINE__)
Expand Down
17 changes: 5 additions & 12 deletions configuration/driver/icedrv_arrays_column.F90
Original file line number Diff line number Diff line change
Expand Up @@ -221,29 +221,22 @@ module icedrv_arrays_column

! floe size distribution
real(kind=dbl_kind), dimension(nfsd), public :: &
floe_rad_l, & ! fsd size lower bound in m (radius)
floe_rad_c, & ! fsd size bin centre in m (radius)
floe_binwidth ! fsd size bin width in m (radius)
floe_rad_c ! fsd size bin centre in m (radius)

real (kind=dbl_kind), dimension (nx), public :: &
wave_sig_ht ! significant height of waves (m)
wave_sig_ht ! significant height of waves (m)

real (kind=dbl_kind), dimension (nfreq), public :: &
wavefreq, & ! wave frequencies
dwavefreq ! wave frequency bin widths
wavefreq, & ! wave frequencies
dwavefreq ! wave frequency bin widths

real (kind=dbl_kind), dimension (nx,nfreq), public :: &
wave_spectrum ! wave spectrum
wave_spectrum ! wave spectrum

real (kind=dbl_kind), dimension (nx,nfsd), public :: &
! change in floe size distribution due to processes
d_afsd_newi, d_afsd_latg, d_afsd_latm, d_afsd_wave, d_afsd_weld

character (len=35), public, dimension(nfsd) :: &
c_fsd_range ! fsd floe_rad bounds (m)



!=======================================================================

end module icedrv_arrays_column
Expand Down
3 changes: 1 addition & 2 deletions configuration/driver/icedrv_flux.F90
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ module icedrv_flux

real (kind=dbl_kind), &
dimension (nx,ncat), public :: &
rsiden, & ! fraction of ice that melts laterally
fsurfn, & ! category fsurf
fcondtopn,& ! category fcondtop
fcondbotn,& ! category fcondbot
Expand Down Expand Up @@ -285,8 +286,6 @@ module icedrv_flux
!-----------------------------------------------------------------

real (kind=dbl_kind), dimension (nx), public :: &
rside , & ! fraction of ice that melts laterally
fside , & ! lateral heat flux (W/m^2)
wlat , & ! lateral melt rate (m/s)
fsw , & ! incoming shortwave radiation (W/m^2)
coszen , & ! cosine solar zenith angle, < 0 for sun below horizon
Expand Down
1 change: 1 addition & 0 deletions configuration/driver/icedrv_forcing.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,7 @@ subroutine get_wave_spec

! wave spectrum and frequencies
! get hardwired frequency bin info and a dummy wave spectrum profile

call icepack_init_wave(nfreq=nfreq, &
wave_spectrum_profile=wave_spectrum_profile, &
wavefreq=wavefreq, dwavefreq=dwavefreq)
Expand Down
5 changes: 0 additions & 5 deletions configuration/driver/icedrv_init.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,6 @@ subroutine set_state_var (nx, &

use icedrv_arrays_column, only: hin_max
use icedrv_domain_size, only: nilyr, nslyr, max_ntrcr, ncat, nfsd
use icedrv_arrays_column, only: floe_rad_c, floe_binwidth

integer (kind=int_kind), intent(in) :: &
nx ! number of grid cells
Expand Down Expand Up @@ -1447,8 +1446,6 @@ subroutine set_state_var (nx, &

! floe size distribution
if (tr_fsd) call icepack_init_fsd(ice_ic=ice_ic, &
floe_rad_c=floe_rad_c, &
floe_binwidth=floe_binwidth, &
afsd=trcrn(i,nt_fsd:nt_fsd+nfsd-1,n))
! surface temperature
trcrn(i,nt_Tsfc,n) = Tsfc ! deg C
Expand Down Expand Up @@ -1517,8 +1514,6 @@ subroutine set_state_var (nx, &
qin=qin(:), qsn=qsn(:))
! floe size distribution
if (tr_fsd) call icepack_init_fsd(ice_ic=ice_ic, &
floe_rad_c=floe_rad_c, &
floe_binwidth=floe_binwidth, &
afsd=trcrn(i,nt_fsd:nt_fsd+nfsd-1,n))

! surface temperature
Expand Down
1 change: 1 addition & 0 deletions configuration/scripts/options/set_nml.swccsm3
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ktherm = 1
shortwave = 'ccsm3'
albedo_type = 'ccsm3'
calc_tsfc = .true.
Expand Down
66 changes: 25 additions & 41 deletions doc/source/user_guide/interfaces.include
Original file line number Diff line number Diff line change
Expand Up @@ -142,22 +142,22 @@ icepack_init_fsd_bounds
! authors: Lettie Roach, NIWA/VUW and C. M. Bitz, UW

subroutine icepack_init_fsd_bounds( &
floe_rad_l, & ! fsd size lower bound in m (radius)
floe_rad_c, & ! fsd size bin centre in m (radius)
floe_binwidth, & ! fsd size bin width in m (radius)
c_fsd_range, & ! string for history output
write_diags ) ! flag for writing diagnostics
floe_rad_l_out, & ! fsd size lower bound in m (radius)
floe_rad_c_out, & ! fsd size bin centre in m (radius)
floe_binwidth_out, & ! fsd size bin width in m (radius)
c_fsd_range_out, & ! string for history output
write_diags) ! flag for writing diagnostics

real(kind=dbl_kind), dimension(:), intent(inout) :: &
floe_rad_l, & ! fsd size lower bound in m (radius)
floe_rad_c, & ! fsd size bin centre in m (radius)
floe_binwidth ! fsd size bin width in m (radius)
real(kind=dbl_kind), dimension(:), intent(out), optional :: &
floe_rad_l_out, & ! fsd size lower bound in m (radius)
floe_rad_c_out, & ! fsd size bin centre in m (radius)
floe_binwidth_out ! fsd size bin width in m (radius)

character (len=35), intent(out) :: &
c_fsd_range(nfsd) ! string for history output
character (len=35), dimension(:), intent(out), optional :: &
c_fsd_range_out ! string for history output

logical (kind=log_kind), intent(in), optional :: &
write_diags ! write diags flag
write_diags ! write diags flag



Expand All @@ -172,18 +172,11 @@ icepack_init_fsd
!
! authors: Lettie Roach, NIWA/VUW

subroutine icepack_init_fsd(ice_ic, &
floe_rad_c, & ! fsd size bin centre in m (radius)
floe_binwidth, & ! fsd size bin width in m (radius)
afsd) ! floe size distribution tracer
subroutine icepack_init_fsd(ice_ic, afsd) ! floe size distribution tracer

character(len=char_len_long), intent(in) :: &
ice_ic ! method of ice cover initialization

real(kind=dbl_kind), dimension(:), intent(inout) :: &
floe_rad_c, & ! fsd size bin centre in m (radius)
floe_binwidth ! fsd size bin width in m (radius)

real (kind=dbl_kind), dimension (:), intent(inout) :: &
afsd ! floe size tracer: fraction distribution of floes

Expand Down Expand Up @@ -2253,8 +2246,8 @@ icepack_step_therm2
nt_strata, &
Tf, sss, &
salinz, &
rside, meltl, &
fside, wlat, &
rsiden, meltl, &
wlat, &
frzmlt, frazil, &
frain, fpond, &
fresh, fsalt, &
Expand All @@ -2271,8 +2264,7 @@ icepack_step_therm2
wavefreq, &
dwavefreq, &
d_afsd_latg, d_afsd_newi, &
d_afsd_latm, d_afsd_weld, &
floe_rad_c, floe_binwidth)
d_afsd_latm, d_afsd_weld)

use icepack_parameters, only: icepack_init_parameters

Expand All @@ -2286,7 +2278,6 @@ icepack_step_therm2
dt , & ! time step
Tf , & ! freezing temperature (C)
sss , & ! sea surface salinity (ppt)
rside , & ! fraction of ice that melts laterally
frzmlt ! freezing/melting potential (W/m^2)

integer (kind=int_kind), dimension (:), intent(in) :: &
Expand All @@ -2301,13 +2292,13 @@ icepack_step_therm2
nt_strata ! indices of underlying tracer layers

real (kind=dbl_kind), dimension(:), intent(in) :: &
rsiden , & ! fraction of ice that melts laterally
salinz , & ! initial salinity profile
ocean_bio ! ocean concentration of biological tracer

real (kind=dbl_kind), intent(inout) :: &
aice , & ! sea ice concentration
aice0 , & ! concentration of open water
fside , & ! lateral heat flux (W/m^2)
frain , & ! rainfall rate (kg/m^2 s)
fpond , & ! fresh water flux to ponds (kg/m^2/s)
fresh , & ! fresh water flux to ocean (kg/m^2/s)
Expand Down Expand Up @@ -2370,10 +2361,6 @@ icepack_step_therm2
d_afsd_latm, & ! lateral melt
d_afsd_weld ! welding

real (kind=dbl_kind), dimension (:), intent(in), optional :: &
floe_rad_c, & ! fsd size bin centre in m (radius)
floe_binwidth ! fsd size bin width in m (radius)



icepack_therm_shared.F90
Expand Down Expand Up @@ -2563,8 +2550,8 @@ icepack_step_therm1
strocnxT , strocnyT , &
fbot , &
Tbot , Tsnice , &
frzmlt , rside , &
fside , wlat , &
frzmlt , rsiden , &
wlat , &
fsnow , frain , &
fpond , fsloss , &
fsurf , fsurfn , &
Expand Down Expand Up @@ -2611,7 +2598,7 @@ icepack_step_therm1
lmask_n , lmask_s , &
mlt_onset , frz_onset , &
yday , prescribed_ice, &
zlvs)
zlvs , afsdn)

real (kind=dbl_kind), intent(in) :: &
dt , & ! time step
Expand Down Expand Up @@ -2687,8 +2674,6 @@ icepack_step_therm1
strocnyT , & ! ice-ocean stress, y-direction
fbot , & ! ice-ocean heat flux at bottom surface (W/m^2)
frzmlt , & ! freezing/melting potential (W/m^2)
rside , & ! fraction of ice that melts laterally
fside , & ! lateral heat flux (W/m^2)
sst , & ! sea surface temperature (C)
Tf , & ! freezing temperature (C)
Tbot , & ! ice bottom surface temperature (deg C)
Expand All @@ -2701,7 +2686,7 @@ icepack_step_therm1
frz_onset ! day of year that freezing begins (congel or frazil)

real (kind=dbl_kind), intent(out), optional :: &
wlat ! lateral melt rate (m/s)
wlat ! lateral melt rate (m/s)

real (kind=dbl_kind), intent(inout), optional :: &
fswthru_vdr , & ! vis dir shortwave penetrating to ocean (W/m^2)
Expand Down Expand Up @@ -2735,6 +2720,9 @@ icepack_step_therm1
H2_18O_ocn , & ! ocean concentration of H2_18O (kg/kg)
zlvs ! atm level height for scalars (if different than zlvl) (m)

real (kind=dbl_kind), dimension(:,:), intent(in), optional :: &
afsdn ! afsd tracer

real (kind=dbl_kind), dimension(:), intent(inout) :: &
aicen_init , & ! fractional area of ice
vicen_init , & ! volume per unit area of ice (m)
Expand All @@ -2750,6 +2738,7 @@ icepack_step_therm1
ipnd , & ! melt pond refrozen lid thickness (m)
iage , & ! volume-weighted ice age
FY , & ! area-weighted first-year ice area
rsiden , & ! fraction of ice that melts laterally
fsurfn , & ! net flux to top surface, excluding fcondtop
fcondtopn , & ! downward cond flux at top surface (W m-2)
fcondbotn , & ! downward cond flux at bottom surface (W m-2)
Expand Down Expand Up @@ -3380,7 +3369,6 @@ icepack_step_wavefracture
subroutine icepack_step_wavefracture(wave_spec_type, &
dt, nfreq, &
aice, vice, aicen, &
floe_rad_l, floe_rad_c, &
wave_spectrum, wavefreq, dwavefreq, &
trcrn, d_afsd_wave)

Expand All @@ -3399,10 +3387,6 @@ icepack_step_wavefracture
real (kind=dbl_kind), dimension(ncat), intent(in) :: &
aicen ! ice area fraction (categories)

real(kind=dbl_kind), dimension(:), intent(in) :: &
floe_rad_l, & ! fsd size lower bound in m (radius)
floe_rad_c ! fsd size bin centre in m (radius)

real (kind=dbl_kind), dimension (:), intent(in) :: &
wavefreq, & ! wave frequencies (s^-1)
dwavefreq ! wave frequency bin widths (s^-1)
Expand Down

0 comments on commit 46fdc73

Please sign in to comment.