From 11c446abb0de5a90f9d146d03a6878ca326292d3 Mon Sep 17 00:00:00 2001 From: SIobhan O'Farrell Date: Wed, 13 Nov 2024 18:34:22 +1100 Subject: [PATCH 01/80] fixes to evap_ice evap_snow --- source/ice_flux.F90 | 2 ++ source/ice_history.F90 | 37 +++++++++++++++++++++++++++++++++-- source/ice_therm_vertical.F90 | 4 ++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/source/ice_flux.F90 b/source/ice_flux.F90 index 5f92570b..f409765e 100755 --- a/source/ice_flux.F90 +++ b/source/ice_flux.F90 @@ -475,6 +475,8 @@ subroutine init_coupler_flux flwout (:,:,:) = -stefan_boltzmann*Tffresh**4 ! in case atm model diagnoses Tsfc from flwout evap (:,:,:) = c0 + evap_ice (:,:,:) = c0 + evap_snow (:,:,:) = c0 Tref (:,:,:) = c0 Qref (:,:,:) = c0 Uref (:,:,:) = c0 diff --git a/source/ice_history.F90 b/source/ice_history.F90 index d8d2a4db..609fa99f 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -341,6 +341,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_sidmassgrowthbot, master_task) call broadcast_scalar (f_sidmasssi, master_task) call broadcast_scalar (f_sidmassevapsubl, master_task) + call broadcast_scalar (f_sndmasssubl, master_task) call broadcast_scalar (f_sidmassmelttop, master_task) call broadcast_scalar (f_sidmassmeltbot, master_task) call broadcast_scalar (f_sidmasslat, master_task) @@ -1153,6 +1154,11 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sidmassevapsubl) + call define_hist_field(n_sndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & + "snow mass change from evaporation and sublimation", & + "none", c1, c0, & + ns1, f_sndmasssubl) + call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from top ice melt", & "none", c1, c0, & @@ -1543,7 +1549,8 @@ subroutine accum_hist (dt) use ice_dyn_shared, only: kdyn, principal_stress,a_min use ice_flux, only: fsw, flw, fsnow, frain, sst, sss, uocn, vocn, & frzmlt_init, fswfac, fswabs, fswthru, alvdr, alvdf, alidr, alidf, & - albice, albsno, albpnd, coszen, flat, fsens, flwout, evap, & + albice, albsno, albpnd, coszen, flat, fsens, flwout, evap, + evap_ice evap_snow, & Tair, Tref, Qref, congel, frazil, snoice, dsnow, & melts, meltb, meltt, meltl, fresh, fsalt, fresh_ai, fsalt_ai, & fhocn, fhocn_ai, uatm, vatm, & @@ -2341,13 +2348,25 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*evap(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk) endif enddo enddo call accum_hist_field(n_sidmassevapsubl, iblk, worka(:,:), a2D) endif + if (f_sndmasssubl(1:1) /= 'x') then + worka(:,:) = c0 + do j = jlo, jhi + do i = ilo, ihi + if (aice(i,j,iblk) > puny) then + worka(i,j) = rhos*evap_snow(i,j,iblk) + endif + enddo + enddo + call accum_hist_field(n_sidmasssubl, iblk, worka(:,:), a2D) + endif + if (f_sidmassmelttop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -3218,6 +3237,20 @@ subroutine accum_hist (dt) endif endif + if (index(avail_hist_fields(n)%vname,'sndmasssubl') /= 0) then + if (f_sndmasssubl(1:1) /= 'x' .and. n_sndmasssubl(ns) /= 0) then + do j = jlo, jhi + do i = ilo, ihi + if (tmask(i,j,iblk)) then + a2D(i,j,n_sndmasssubl(ns),iblk) = & + a2D(i,j,n_sndmasssubl(ns),iblk)*avgct(ns)*ravgip(i,j) + if (ravgip(i,j) == c0) a2D(i,j,n_sndmasssubl(ns),iblk) = spval_dbl + endif + enddo ! i + enddo ! j + endif + endif + if (index(avail_hist_fields(n)%vname,'sidmassmelttop') /= 0) then if (f_sidmassmelttop(1:1) /= 'x' .and. n_sidmassmelttop(ns) /= 0) then do j = jlo, jhi diff --git a/source/ice_therm_vertical.F90 b/source/ice_therm_vertical.F90 index 7a54934e..6977f3de 100755 --- a/source/ice_therm_vertical.F90 +++ b/source/ice_therm_vertical.F90 @@ -287,8 +287,8 @@ subroutine thermo_vertical (nx_block, ny_block, & fadvocn(i,j) = c0 fcondbotn(i,j) = c0 ice_freeboardn(i,j) = c0 - - + evapn_ice(i,j)= c0 + evapn_snow(i,j)=c0 meltt (i,j) = c0 meltb (i,j) = c0 From 63f7641b7ef45a0dd19e2d539953ba08d20bbb0d Mon Sep 17 00:00:00 2001 From: SIobhan O'Farrell Date: Mon, 2 Dec 2024 15:10:24 +1100 Subject: [PATCH 02/80] bug fix --- source/ice_history.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 609fa99f..ef3672fb 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1550,7 +1550,7 @@ subroutine accum_hist (dt) use ice_flux, only: fsw, flw, fsnow, frain, sst, sss, uocn, vocn, & frzmlt_init, fswfac, fswabs, fswthru, alvdr, alvdf, alidr, alidf, & albice, albsno, albpnd, coszen, flat, fsens, flwout, evap, - evap_ice evap_snow, & + evap_ice,evap_snow, & Tair, Tref, Qref, congel, frazil, snoice, dsnow, & melts, meltb, meltt, meltl, fresh, fsalt, fresh_ai, fsalt_ai, & fhocn, fhocn_ai, uatm, vatm, & @@ -2360,7 +2360,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = rhos*evap_snow(i,j,iblk) + worka(i,j) = rhos*aice(i,j,iblk)*evap_snow(i,j,iblk) endif enddo enddo From e146cffa4255e9efd40cc0b47d308fdaf2428813 Mon Sep 17 00:00:00 2001 From: SIobhan O'Farrell Date: Mon, 2 Dec 2024 18:07:36 +1100 Subject: [PATCH 03/80] added timestep, FLAGGED diff with CICE6 --- source/ice_history.F90 | 57 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index ef3672fb..e4681655 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2001,6 +2001,8 @@ subroutine accum_hist (dt) worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk) enddo enddo + !FLAG CICE6 added Tffresh to seitch to Kelvin we may need + !to alighn with them and any ACCESS-NRI post processing call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) endif @@ -2016,6 +2018,9 @@ subroutine accum_hist (dt) endif enddo enddo + + !FLAG CICE6 has added Tffresh to this term to switch to + !Kelvins for CESM we had Centigrade in our output. call accum_hist_field(n_sitempsnic, iblk, worka(:,:), a2D) endif @@ -2024,7 +2029,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) & - worka(i,j) = aice(i,j,iblk)*(Ti_bot(i,j,iblk)+Tffresh) + worka(i,j) = & + aice(i,j,iblk)*(Ti_bot(i,j,iblk)/aice_init(i,j,iblk)+Tffresh) enddo enddo call accum_hist_field(n_sitempbot, iblk, worka(:,:), a2D) @@ -2312,10 +2318,15 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*frazil(i,j,iblk)*rhoi / aice_init(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*frazil(i,j,iblk)*rhoi / & + (dt*aice_init(i,j,iblk)) endif enddo enddo + !FLAG revisit to see if frazil still needs aice/aice_init + !but data can be noisy. NOT still in CICE6. No aice weighting + !either + call accum_hist_field(n_sidmassgrowthwat, iblk, worka(:,:), a2D) endif @@ -2324,10 +2335,16 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*congel(i,j,iblk)*rhoi / aice_init(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*congel(i,j,iblk)*rhoi / & + (dt *aice_init(i,j,iblk)) endif enddo enddo + + ! FLAG similar to frazil aice/aice_init no longer there but + ! noisy field. aice_init is there as first flag, so on off + ! switch check there. + call accum_hist_field(n_sidmassgrowthbot, iblk, worka(:,:), a2D) endif @@ -2336,10 +2353,14 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi / aice_init(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi /& + (dt * aice_init(i,j,iblk)) endif enddo enddo + + !FLAG same as frazil/congel issue + call accum_hist_field(n_sidmasssi, iblk, worka(:,:), a2D) endif @@ -2352,6 +2373,8 @@ subroutine accum_hist (dt) endif enddo enddo + !FLAG CICE6 has dropped aice muliplier + call accum_hist_field(n_sidmassevapsubl, iblk, worka(:,:), a2D) endif @@ -2364,6 +2387,8 @@ subroutine accum_hist (dt) endif enddo enddo + + !FLAG CICE6 has dropped aice muliplier call accum_hist_field(n_sidmasssubl, iblk, worka(:,:), a2D) endif @@ -2372,10 +2397,14 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi / aice_init(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi /& + (dt * aice_init(i,j,iblk)) endif enddo enddo + + !FLAG as above aice/aice_init factor + call accum_hist_field(n_sidmassmelttop, iblk, worka(:,:), a2D) endif @@ -2384,10 +2413,12 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / aice_init(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & + (dt * aice_init(i,j,iblk)) endif enddo enddo + !FLAG as above call accum_hist_field(n_sidmassmeltbot, iblk, worka(:,:), a2D) endif @@ -2396,10 +2427,12 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / aice_init(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & + (dt * aice_init(i,j,iblk)) endif enddo enddo + !FLAG as above call accum_hist_field(n_sidmasslat, iblk, worka(:,:), a2D) endif @@ -2408,7 +2441,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk) * fsnow(i,j,iblk) * dt + worka(i,j) = aice(i,j,iblk) * fsnow(i,j,iblk) * rhos endif enddo enddo @@ -2420,11 +2453,14 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*melts(i,j,iblk)*rhoi / aice_init(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*melts(i,j,iblk)*rhos/ & + (dt *aice_init(i,j,iblk)) endif enddo enddo - call accum_hist_field(n_sndmassmelt, iblk, worka(:,:), a2D) + !FLAG as above aice/aice_init still here + + call accum_hist_field(n_sndmassmelt, iblk, worka(:,:), a2D) endif if (f_siflswdtop(1:1) /= 'x') then @@ -2545,6 +2581,7 @@ subroutine accum_hist (dt) endif enddo enddo + !FLAG aice/aice_init survived in CICE6 here!! call accum_hist_field(n_siflcondbot, iblk, worka(:,:), a2D) endif From b59601a15bbc4e3a399f2b4cb4b6c84b3df50315 Mon Sep 17 00:00:00 2001 From: SIobhan O'Farrell Date: Mon, 16 Dec 2024 18:02:00 +1100 Subject: [PATCH 04/80] add siflfwdrain, minor changes to FLAG comments --- source/ice_history.F90 | 55 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index e4681655..f30f7787 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -356,6 +356,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_siflsensupbot, master_task) call broadcast_scalar (f_sifllatstop, master_task) call broadcast_scalar (f_siflcondtop, master_task) + call broadcast_scalar (f_siflfwdrain, master_task) call broadcast_scalar (f_siflcondbot, master_task) call broadcast_scalar (f_sipr, master_task) call broadcast_scalar (f_siflsaltbot, master_task) @@ -1235,6 +1236,11 @@ subroutine init_hist (dt) "positive downward", c1, c0, & ns1, f_siflcondbot) + call define_hist_field(n_siflfwdrain,"siflfwdrain","kg m-2 s-1",tstr2D, tcstr, & + "freshwater drainage through sea ice", & + "positive downward", c1, c0, & + ns1, f_siflfwdrain) + call define_hist_field(n_sipr,"sipr","kg m^-2 s^-1",tstr2D, tcstr, & "rainfall over sea ice", & "none", c1, c0, & @@ -2001,8 +2007,13 @@ subroutine accum_hist (dt) worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk) enddo enddo - !FLAG CICE6 added Tffresh to seitch to Kelvin we may need - !to alighn with them and any ACCESS-NRI post processing + !FLAG CICE6 added Tffresh to switch to Kelvin we may need + !to align with them and any ACCESS-NRI post processing, + !discus with MED team. It was in deg C in the APP4 + ! Sensible data in CM2 not clear it will be IN ESM1.6 + ! not defined in ESM1.5 in APP4. I dont think it was in ACCESS + ! 1-0/1-3 zero-layer model set ups. + call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) endif @@ -2020,7 +2031,9 @@ subroutine accum_hist (dt) enddo !FLAG CICE6 has added Tffresh to this term to switch to - !Kelvins for CESM we had Centigrade in our output. + !Kelvins for CESM we had Centigrade in our CM2 output + ! also the field was not defined so will not be sensible in + ! ESM1.6 so not worth adjusting. call accum_hist_field(n_sitempsnic, iblk, worka(:,:), a2D) endif @@ -2369,11 +2382,13 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk)*rhoi endif enddo enddo !FLAG CICE6 has dropped aice muliplier + !check back after looking at data ouput with and without aice + ! frain also has aice weights in CICE6 so its not connsitent. call accum_hist_field(n_sidmassevapsubl, iblk, worka(:,:), a2D) endif @@ -2389,6 +2404,11 @@ subroutine accum_hist (dt) enddo !FLAG CICE6 has dropped aice muliplier + !check back after looking at data ouput with and without aice + ! here less clear as it could be wighted with snow area as + ! well ice area, so CICE6 may be correct all other fluxes do + ! retain the aice reighting in CICE6 including flat + call accum_hist_field(n_sidmasssubl, iblk, worka(:,:), a2D) endif @@ -2646,6 +2666,19 @@ subroutine accum_hist (dt) call accum_hist_field(n_siflsaltbot, iblk, worka(:,:), a2D) endif + + if (f_siflfwdrain(1:1) /= 'x') then + worka(:,:) = c0 + do j = jlo, jhi + do i = ilo, ihi + if (aice(i,j,iblk) > puny) then + worka(i,j) = aice(i,j,iblk)*(frain(i,j,iblk) & + + melts(i,j,iblk)+meltt(i,j,iblk)) + endif + enddo + enddo + call accum_hist_field(n_siflfwdrain, iblk, worka(:,:), a2D) + endif !3D category fields if (f_aicen (1:1) /= 'x') & @@ -3473,6 +3506,20 @@ subroutine accum_hist (dt) endif endif + if (index(avail_hist_fields(n)%vname,'siflfwdrain') /= 0) then + if (f_sifllatstop(1:1) /= 'x' .and. n_siflfwdrain(ns) /= 0) then + do j = jlo, jhi + do i = ilo, ihi + if (tmask(i,j,iblk)) then + a2D(i,j,n_siflfwdrain(ns),iblk) = & + a2D(i,j,n_siflfwdrain(ns),iblk)*avgct(ns)*ravgip(i,j) + if (ravgip(i,j) == c0) a2D(i,j,n_siflfwdrain(ns),iblk) = spval_dbl + endif + enddo ! i + enddo ! j + endif + endif + if (index(avail_hist_fields(n)%vname,'sipr') /= 0) then if (f_sipr(1:1) /= 'x' .and. n_sipr(ns) /= 0) then do j = jlo, jhi From 19e550d7165043dc6e990f6210c1d14927647e6e Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 1 May 2025 12:29:34 +1000 Subject: [PATCH 05/80] missing variable definitions --- source/ice_history.F90 | 4 ++-- source/ice_history_shared.F90 | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index f30f7787..ce8313e5 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -37,7 +37,7 @@ module ice_history private public :: init_hist, accum_hist save - + !======================================================================= contains @@ -1555,7 +1555,7 @@ subroutine accum_hist (dt) use ice_dyn_shared, only: kdyn, principal_stress,a_min use ice_flux, only: fsw, flw, fsnow, frain, sst, sss, uocn, vocn, & frzmlt_init, fswfac, fswabs, fswthru, alvdr, alvdf, alidr, alidf, & - albice, albsno, albpnd, coszen, flat, fsens, flwout, evap, + albice, albsno, albpnd, coszen, flat, fsens, flwout, evap, & evap_ice,evap_snow, & Tair, Tref, Qref, congel, frazil, snoice, dsnow, & melts, meltb, meltt, meltl, fresh, fsalt, fresh_ai, fsalt_ai, & diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 9773aeb2..4940745c 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -271,6 +271,7 @@ module ice_history_shared f_sidmasslat = 'x', & f_sndmasssnf = 'x', & f_sndmassmelt = 'x', & + f_sndmasssubl = 'x', & f_sidivvel = 'x', & f_siflswdtop = 'x', & f_siflswutop = 'x', & @@ -285,6 +286,7 @@ module ice_history_shared f_sipr = 'x', & f_siflsaltbot = 'x', & f_siflfwbot = 'x', & + f_siflfwdrain = 'x', & f_sisaltmass = 'x', & f_aicen = 'x', f_vicen = 'x', & f_vsnon = 'x', & @@ -400,6 +402,7 @@ module ice_history_shared f_sidmasslat, & f_sndmasssnf, & f_sndmassmelt, & + f_sndmasssubl, & f_siflswdtop, & f_siflswutop, & f_siflswdbot, & @@ -413,6 +416,7 @@ module ice_history_shared f_sipr, & f_siflsaltbot, & f_siflfwbot, & + f_siflfwdrain, & f_sisaltmass, & f_aicen, f_vicen , & f_vsnon, & @@ -521,12 +525,14 @@ module ice_history_shared n_sidmassgrowthwat, & n_sidmassgrowthbot, & n_sidmasssi, & + n_sidmasssubl, & n_sidmassevapsubl, & n_sidmassmelttop, & n_sidmassmeltbot, & n_sidmasslat, & n_sndmasssnf, & n_sndmassmelt, & + n_sndmasssubl, & n_siflswdtop, & n_siflswutop, & n_siflswdbot, & @@ -540,6 +546,7 @@ module ice_history_shared n_sipr, & n_siflsaltbot, & n_siflfwbot, & + n_siflfwdrain, & n_sisaltmass, & n_vsnon, & n_fhocn , n_fhocn_ai , & @@ -573,13 +580,13 @@ module ice_history_shared n_keffn_top , & n_Tinz , n_Sinz , & n_Tsnz, & - n_a11 , n_a12 , & - n_e11 , n_e12 , & - n_e22 , & - n_s11 , n_s12 , & - n_s22 , & - n_yieldstress11, n_yieldstress12, & - n_yieldstress22 + n_a11 , n_a12 , & + n_e11 , n_e12 , & + n_e22 , & + n_s11 , n_s12 , & + n_s22 , & + n_yieldstress11, n_yieldstress12, & + n_yieldstress22 interface accum_hist_field ! generic interface module procedure accum_hist_field_2D, & From e49e0eb9da388c00c9221984e1a1dcb37927496c Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 3 Jun 2025 15:48:12 +1000 Subject: [PATCH 06/80] use kelvin for sitemptop --- source/ice_history.F90 | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index ce8313e5..780333ea 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1114,12 +1114,11 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sisnhc) - - call define_hist_field(n_sidconcth,"sidconcth","1/s",tstr2D, tcstr, & "sea ice area change from thermodynamics", & "none", c1, c0, & ns1, f_sidconcth) + call define_hist_field(n_sidconcdyn,"sidconcdyn","1/s",tstr2D, tcstr, & "sea ice area change from dynamics", & "none", c1, c0, & @@ -2004,16 +2003,9 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk) + worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk)+Tffresh enddo enddo - !FLAG CICE6 added Tffresh to switch to Kelvin we may need - !to align with them and any ACCESS-NRI post processing, - !discus with MED team. It was in deg C in the APP4 - ! Sensible data in CM2 not clear it will be IN ESM1.6 - ! not defined in ESM1.5 in APP4. I dont think it was in ACCESS - ! 1-0/1-3 zero-layer model set ups. - call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) endif From 50ce81549361e220efdc02fb290964bc5b81d978 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 3 Jun 2025 15:53:38 +1000 Subject: [PATCH 07/80] use kelvin for sitempsnic --- source/ice_history.F90 | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 780333ea..0d669a65 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2014,18 +2014,13 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (vsno(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*Tsnic(i,j,iblk)/aice_init(i,j,iblk) - else - worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk) - endif + if (vsno(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then + worka(i,j) = aice(i,j,iblk)*Tsnic(i,j,iblk)/aice_init(i,j,iblk)+Tffresh + else + worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk)+Tffresh + endif enddo enddo - - !FLAG CICE6 has added Tffresh to this term to switch to - !Kelvins for CESM we had Centigrade in our CM2 output - ! also the field was not defined so will not be sensible in - ! ESM1.6 so not worth adjusting. call accum_hist_field(n_sitempsnic, iblk, worka(:,:), a2D) endif From bc4a51fb021af4040c5a01d21f5bee88a594a685 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 3 Jun 2025 16:17:21 +1000 Subject: [PATCH 08/80] tidy comments --- source/ice_history.F90 | 46 ++++++++++++------------------------------ 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 0d669a65..7ec26468 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2314,6 +2314,9 @@ subroutine accum_hist (dt) endif if (f_sidmassgrowthwat(1:1) /= 'x') then + !Sea-Ice Mass Change Through Growth in Supercooled Open Water (Frazil) + !To-do: revisit to see if frazil still needs aice/aice_init weighting + !Data can be noisy. Weigthing not used in CICE6. worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2323,14 +2326,11 @@ subroutine accum_hist (dt) endif enddo enddo - !FLAG revisit to see if frazil still needs aice/aice_init - !but data can be noisy. NOT still in CICE6. No aice weighting - !either - call accum_hist_field(n_sidmassgrowthwat, iblk, worka(:,:), a2D) endif if (f_sidmassgrowthbot(1:1) /= 'x') then + !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2340,15 +2340,11 @@ subroutine accum_hist (dt) endif enddo enddo - - ! FLAG similar to frazil aice/aice_init no longer there but - ! noisy field. aice_init is there as first flag, so on off - ! switch check there. - call accum_hist_field(n_sidmassgrowthbot, iblk, worka(:,:), a2D) endif if (f_sidmasssi(1:1) /= 'x') then + !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2358,13 +2354,11 @@ subroutine accum_hist (dt) endif enddo enddo - - !FLAG same as frazil/congel issue - call accum_hist_field(n_sidmasssi, iblk, worka(:,:), a2D) endif if (f_sidmassevapsubl(1:1) /= 'x') then + !To-do: revisit to see if aice weighting is correct, looks like evap_ice is already weighted worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2373,14 +2367,11 @@ subroutine accum_hist (dt) endif enddo enddo - !FLAG CICE6 has dropped aice muliplier - !check back after looking at data ouput with and without aice - ! frain also has aice weights in CICE6 so its not connsitent. - call accum_hist_field(n_sidmassevapsubl, iblk, worka(:,:), a2D) endif if (f_sndmasssubl(1:1) /= 'x') then + !To-do: revisit to see if aice weighting is correct, looks like evap_snow is already weighted worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2389,17 +2380,11 @@ subroutine accum_hist (dt) endif enddo enddo - - !FLAG CICE6 has dropped aice muliplier - !check back after looking at data ouput with and without aice - ! here less clear as it could be wighted with snow area as - ! well ice area, so CICE6 may be correct all other fluxes do - ! retain the aice reighting in CICE6 including flat - call accum_hist_field(n_sidmasssubl, iblk, worka(:,:), a2D) endif if (f_sidmassmelttop(1:1) /= 'x') then + !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2409,13 +2394,11 @@ subroutine accum_hist (dt) endif enddo enddo - - !FLAG as above aice/aice_init factor - call accum_hist_field(n_sidmassmelttop, iblk, worka(:,:), a2D) endif if (f_sidmassmeltbot(1:1) /= 'x') then + !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2425,11 +2408,11 @@ subroutine accum_hist (dt) endif enddo enddo - !FLAG as above call accum_hist_field(n_sidmassmeltbot, iblk, worka(:,:), a2D) endif if (f_sidmasslat(1:1) /= 'x') then + !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2439,7 +2422,6 @@ subroutine accum_hist (dt) endif enddo enddo - !FLAG as above call accum_hist_field(n_sidmasslat, iblk, worka(:,:), a2D) endif @@ -2456,6 +2438,7 @@ subroutine accum_hist (dt) endif if (f_sndmassmelt(1:1) /= 'x') then + !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2465,8 +2448,6 @@ subroutine accum_hist (dt) endif enddo enddo - !FLAG as above aice/aice_init still here - call accum_hist_field(n_sndmassmelt, iblk, worka(:,:), a2D) endif @@ -2580,6 +2561,7 @@ subroutine accum_hist (dt) endif if (f_siflcondbot(1:1) /= 'x') then + !to-do: check about aice_init, still in CICE6 but different to siflcondtop worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2588,7 +2570,6 @@ subroutine accum_hist (dt) endif enddo enddo - !FLAG aice/aice_init survived in CICE6 here!! call accum_hist_field(n_siflcondbot, iblk, worka(:,:), a2D) endif @@ -2640,7 +2621,6 @@ subroutine accum_hist (dt) call accum_hist_field(n_siflfwbot, iblk, worka(:,:), a2D) endif - if (f_siflsaltbot(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -2653,7 +2633,6 @@ subroutine accum_hist (dt) call accum_hist_field(n_siflsaltbot, iblk, worka(:,:), a2D) endif - if (f_siflfwdrain(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -2666,6 +2645,7 @@ subroutine accum_hist (dt) enddo call accum_hist_field(n_siflfwdrain, iblk, worka(:,:), a2D) endif + !3D category fields if (f_aicen (1:1) /= 'x') & From 86dd0e12d703721bd32cd215fb502b92d3a876df Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Fri, 4 Jul 2025 15:10:39 +1000 Subject: [PATCH 09/80] Update source/ice_history.F90 Co-authored-by: Spencer Wong <88933912+blimlim@users.noreply.github.com> --- source/ice_history.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 7ec26468..d6754549 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2316,7 +2316,7 @@ subroutine accum_hist (dt) if (f_sidmassgrowthwat(1:1) /= 'x') then !Sea-Ice Mass Change Through Growth in Supercooled Open Water (Frazil) !To-do: revisit to see if frazil still needs aice/aice_init weighting - !Data can be noisy. Weigthing not used in CICE6. + !Data can be noisy. Weighting not used in CICE6. worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi From 462a1bd3195ae53a4f56fe3c65a730fc6a695f4a Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Wed, 20 Aug 2025 16:15:01 +1000 Subject: [PATCH 10/80] port CICE6 history features for CMIP variables: avg_ice_present, mask_ice_free_points, sndmassdyn, fixe some time weigthings --- source/ice_fileunits.F90 | 50 +- source/ice_history.F90 | 1579 +++++++++++---------------------- source/ice_history_shared.F90 | 39 +- 3 files changed, 605 insertions(+), 1063 deletions(-) diff --git a/source/ice_fileunits.F90 b/source/ice_fileunits.F90 index aa2be15d..a3a07fe0 100755 --- a/source/ice_fileunits.F90 +++ b/source/ice_fileunits.F90 @@ -29,7 +29,7 @@ module ice_fileunits implicit none private public :: init_fileunits, get_fileunit, flush_fileunit, & - release_fileunit, release_all_fileunits + release_fileunit, release_all_fileunits, goto_nml save character (len=char_len), public :: & @@ -292,6 +292,54 @@ subroutine flush_fileunit(iunit) end subroutine flush_fileunit +!======================================================================= + + subroutine goto_nml(iunit, nml, status) + ! Search to namelist group within ice_in file. + ! for compilers that do not allow optional namelists + + ! passed variables + integer(kind=int_kind), intent(in) :: & + iunit ! namelist file unit + + character(len=*), intent(in) :: & + nml ! namelist to search for + + integer(kind=int_kind), intent(out) :: & + status ! status of subrouine + + ! local variables + character(len=char_len) :: & + file_str, & ! string in file + nml_str ! namelist string to test + + integer(kind=int_kind) :: & + i, n ! dummy integers + + + ! rewind file + rewind(iunit) + + ! define test string with ampersand + nml_str = '&' // trim(adjustl(nml)) + + ! search for the record containing the namelist group we're looking for + do + read(iunit, '(a)', iostat=status) file_str + if (status /= 0) then + exit ! e.g. end of file + else + if (index(adjustl(file_str), nml_str) == 1) then + exit ! i.e. found record we're looking for + end if + end if + end do + + ! backspace to namelist name in file + backspace(iunit) + + end subroutine goto_nml + !======================================================================= end module ice_fileunits diff --git a/source/ice_history.F90 b/source/ice_history.F90 index d6754549..dd9bb6ea 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -32,6 +32,9 @@ module ice_history use ice_kinds_mod + use ice_constants, only: p5 + use ice_exit, only: abort_ice + implicit none private @@ -64,7 +67,6 @@ subroutine init_hist (dt) histfreq_n, nstreams use ice_domain_size, only: max_blocks, max_nstrm use ice_dyn_shared, only: kdyn - use ice_exit, only: abort_ice use ice_fileunits, only: nu_nml, nml_filename, nu_diag, & get_fileunit, release_fileunit use ice_flux, only: mlt_onset, frz_onset, albcnt @@ -78,6 +80,7 @@ subroutine init_hist (dt) use ice_state, only: tr_iage, tr_FY, tr_lvl, tr_pond, tr_aero, tr_brine use ice_therm_shared, only: calc_Tsfc, heat_capacity use ice_zbgc_shared, only: skl_bgc + use ice_fileunits, only: goto_nml real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -88,30 +91,45 @@ subroutine init_hist (dt) integer (kind=int_kind), dimension(max_nstrm) :: & ntmp integer (kind=int_kind) :: nml_error ! namelist i/o error flag + character(len=char_len_long) :: tmpstr2 ! for namelist check + character(len=char_len) :: nml_name ! text namelist name !----------------------------------------------------------------- ! read namelist !----------------------------------------------------------------- - call get_fileunit(nu_nml) if (my_task == master_task) then - open (nu_nml, file=nml_filename, status='old',iostat=nml_error) + nml_name = 'icefields_nml' + write(nu_diag,*) 'ice: Reading ', trim(nml_name) + + ! open file + call get_fileunit(nu_nml) + open (nu_nml, file=trim(nml_filename), status='old',iostat=nml_error) + if (nml_error /= 0) then + call abort_ice('ice ERROR: '//trim(nml_name)//' open file ') + endif + + ! seek to this namelist + call goto_nml(nu_nml,trim(nml_name),nml_error) if (nml_error /= 0) then - nml_error = -1 - else - nml_error = 1 + call abort_ice('ice ERROR: searching for '// trim(nml_name)) endif + + ! read namelist + nml_error = 1 do while (nml_error > 0) read(nu_nml, nml=icefields_nml,iostat=nml_error) + ! check if error + if (nml_error /= 0) then + ! backspace and re-read erroneous line + backspace(nu_nml) + read(nu_nml,fmt='(A)') tmpstr2 + call abort_ice('ice ERROR: ' // trim(nml_name) // ' reading ') + endif end do - if (nml_error == 0) close(nu_nml) - endif - call release_fileunit(nu_nml) - call broadcast_scalar(nml_error, master_task) - if (nml_error /= 0) then - close (nu_nml) - call abort_ice('ice: error reading icefields_nml') + close(nu_nml) + call release_fileunit(nu_nml) endif ! histfreq options ('1','h','d','m','y') @@ -130,7 +148,7 @@ subroutine init_hist (dt) call abort_ice('ice: histfreq contains illegal element') endif enddo - if (nstreams == 0) write (nu_diag,*) 'WARNING: No history output' + if (nstreams == 0 .and. my_task == master_task) write (nu_diag,*) 'WARNING: No history output' do ns1 = 1, nstreams do ns2 = 1, nstreams if (histfreq(ns1) == histfreq(ns2) .and. ns1/=ns2 & @@ -220,8 +238,8 @@ subroutine init_hist (dt) call broadcast_scalar (f_uatm, master_task) call broadcast_scalar (f_vatm, master_task) call broadcast_scalar (f_sice, master_task) - call broadcast_scalar (f_fswdn, master_task) call broadcast_scalar (f_fswup, master_task) + call broadcast_scalar (f_fswdn, master_task) call broadcast_scalar (f_flwdn, master_task) call broadcast_scalar (f_snow, master_task) call broadcast_scalar (f_snow_ai, master_task) @@ -316,17 +334,11 @@ subroutine init_hist (dt) call broadcast_scalar (f_siv, master_task) call broadcast_scalar (f_sidmasstranx, master_task) call broadcast_scalar (f_sidmasstrany, master_task) - call broadcast_scalar (f_sifb, master_task) call broadcast_scalar (f_sistrxdtop, master_task) call broadcast_scalar (f_sistrydtop, master_task) call broadcast_scalar (f_sistrxubot, master_task) call broadcast_scalar (f_sistryubot, master_task) - call broadcast_scalar (f_siforcetiltx, master_task) - call broadcast_scalar (f_siforcetilty, master_task) - call broadcast_scalar (f_siforcecoriolx, master_task) - call broadcast_scalar (f_siforcecorioly, master_task) - call broadcast_scalar (f_siforceintstrx, master_task) - call broadcast_scalar (f_siforceintstry, master_task) + call broadcast_scalar (f_sicompstren, master_task) call broadcast_scalar (f_sispeed, master_task) call broadcast_scalar (f_sialb, master_task) @@ -347,6 +359,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_sidmasslat, master_task) call broadcast_scalar (f_sndmasssnf, master_task) call broadcast_scalar (f_sndmassmelt, master_task) + call broadcast_scalar (f_sndmassdyn, master_task) call broadcast_scalar (f_siflswdtop, master_task) call broadcast_scalar (f_siflswutop, master_task) call broadcast_scalar (f_siflswdbot, master_task) @@ -356,12 +369,19 @@ subroutine init_hist (dt) call broadcast_scalar (f_siflsensupbot, master_task) call broadcast_scalar (f_sifllatstop, master_task) call broadcast_scalar (f_siflcondtop, master_task) - call broadcast_scalar (f_siflfwdrain, master_task) call broadcast_scalar (f_siflcondbot, master_task) call broadcast_scalar (f_sipr, master_task) + call broadcast_scalar (f_sifb, master_task) call broadcast_scalar (f_siflsaltbot, master_task) call broadcast_scalar (f_siflfwbot, master_task) call broadcast_scalar (f_sisaltmass, master_task) + call broadcast_scalar (f_siflfwdrain, master_task) + call broadcast_scalar (f_siforcetiltx, master_task) + call broadcast_scalar (f_siforcetilty, master_task) + call broadcast_scalar (f_siforcecoriolx, master_task) + call broadcast_scalar (f_siforcecorioly, master_task) + call broadcast_scalar (f_siforceintstrx, master_task) + call broadcast_scalar (f_siforceintstry, master_task) call broadcast_scalar (f_aicen, master_task) call broadcast_scalar (f_vicen, master_task) call broadcast_scalar (f_vsnon, master_task) @@ -423,12 +443,11 @@ subroutine init_hist (dt) "snow fraction per unit grid cell area", c1, c0, & ns1, f_snowfrac) - call define_hist_field(n_Tsfc,"Tsfc","C",tstr2D, tcstr, & "snow/ice surface temperature", & "averaged with Tf if no ice is present", c1, c0, & ns1, f_Tsfc) - + call define_hist_field(n_aice,"aice","1",tstr2D, tcstr, & "ice area (aggregate)", & "none", c1, c0, & @@ -574,31 +593,31 @@ subroutine init_hist (dt) " ", c100, c0, & ns1, f_alidr_ai) - call define_hist_field(n_alvdf_ai,"alvdf_ai","%",tstr2D, tcstr, & - "visible diffuse albedo", & - " ", c100, c0, & - ns1, f_alvdf_ai) + call define_hist_field(n_alvdf_ai,"alvdf_ai","%",tstr2D, tcstr, & + "visible diffuse albedo", & + " ", c100, c0, & + ns1, f_alvdf_ai) - call define_hist_field(n_alidf_ai,"alidf_ai","%",tstr2D, tcstr, & - "near IR diffuse albedo", & - " ", c100, c0, & - ns1, f_alidf_ai) + call define_hist_field(n_alidf_ai,"alidf_ai","%",tstr2D, tcstr, & + "near IR diffuse albedo", & + " ", c100, c0, & + ns1, f_alidf_ai) call define_hist_field(n_albice,"albice","%",tstr2D, tcstr, & "bare ice albedo", & "averaged for coszen>0, weighted by aice", c100, c0, & ns1, f_albice) - + call define_hist_field(n_albsno,"albsno","%",tstr2D, tcstr, & "snow albedo", & "averaged for coszen>0, weighted by aice", c100, c0, & ns1, f_albsno) - + call define_hist_field(n_albpnd,"albpnd","%",tstr2D, tcstr, & "melt pond albedo", & "averaged for coszen>0, weighted by aice", c100, c0, & ns1, f_albpnd) - + call define_hist_field(n_coszen,"coszen","radian",tstr2D, tcstr, & "cosine of the zenith angle", & "negative below horizon", c1, c0, & @@ -608,42 +627,42 @@ subroutine init_hist (dt) "latent heat flux (cpl)", & "positive downward", c1, c0, & ns1, f_flat) - + call define_hist_field(n_flat_ai,"flat_ai","W/m^2",tstr2D, tcstr, & "latent heat flux", & "weighted by ice area", c1, c0, & ns1, f_flat_ai) - + call define_hist_field(n_fsens,"fsens","W/m^2",tstr2D, tcstr, & "sensible heat flux (cpl)", & "positive downward", c1, c0, & ns1, f_fsens) - + call define_hist_field(n_fsens_ai,"fsens_ai","W/m^2",tstr2D, tcstr, & "sensible heat flux", & "weighted by ice area", c1, c0, & ns1, f_fsens_ai) - + call define_hist_field(n_flwup,"flwup","W/m^2",tstr2D, tcstr, & "upward longwave flux (cpl)", & "positive downward", c1, c0, & ns1, f_flwup) - + call define_hist_field(n_flwup_ai,"flwup_ai","W/m^2",tstr2D, tcstr, & "upward longwave flux", & "weighted by ice area", c1, c0, & ns1, f_flwup_ai) - + call define_hist_field(n_evap,"evap","cm/day",tstr2D, tcstr, & "evaporative water flux (cpl)", & "none", mps_to_cmpdy/rhofresh, c0, & ns1, f_evap) - + call define_hist_field(n_evap_ai,"evap_ai","cm/day",tstr2D, tcstr, & "evaporative water flux", & "weighted by ice area", mps_to_cmpdy/rhofresh, c0, & ns1, f_evap_ai) - + call define_hist_field(n_evap_ice_ai,"evap_ice_ai","cm/day",tstr2D, tcstr, & "evaporative water flux over ice only", & "weighted by ice area", mps_to_cmpdy/rhofresh, c0, & @@ -658,156 +677,156 @@ subroutine init_hist (dt) "air temperature", & "none", c1, -Tffresh, & ns1, f_Tair) - + call define_hist_field(n_Tref,"Tref","degC",tstr2D, tcstr, & "2m reference temperature", & "none", c1, -Tffresh, & ns1, f_Tref) - + call define_hist_field(n_Qref,"Qref","g/kg",tstr2D, tcstr, & "2m reference specific humidity", & "none", kg_to_g, c0, & ns1, f_Qref) - + call define_hist_field(n_congel,"congel","cm/day",tstr2D, tcstr, & "congelation ice growth", & "none", mps_to_cmpdy/dt, c0, & ns1, f_congel) - + call define_hist_field(n_frazil,"frazil","cm/day",tstr2D, tcstr, & "frazil ice growth", & "none", mps_to_cmpdy/dt, c0, & ns1, f_frazil) - + call define_hist_field(n_snoice,"snoice","cm/day",tstr2D, tcstr, & "snow-ice formation", & "none", mps_to_cmpdy/dt, c0, & ns1, f_snoice) - + call define_hist_field(n_dsnow,"dsnow","cm/day",tstr2D, tcstr, & "snow formation", & "none", mps_to_cmpdy/dt, c0, & ns1, f_dsnow) - + call define_hist_field(n_meltt,"meltt","cm/day",tstr2D, tcstr, & "top ice melt", & "none", mps_to_cmpdy/dt, c0, & ns1, f_meltt) - + call define_hist_field(n_melts,"melts","cm/day",tstr2D, tcstr, & "top snow melt", & "none", mps_to_cmpdy/dt, c0, & ns1, f_melts) - + call define_hist_field(n_meltb,"meltb","cm/day",tstr2D, tcstr, & "basal ice melt", & "none", mps_to_cmpdy/dt, c0, & ns1, f_meltb) - + call define_hist_field(n_meltl,"meltl","cm/day",tstr2D, tcstr, & "lateral ice melt", & "none", mps_to_cmpdy/dt, c0, & ns1, f_meltl) - + call define_hist_field(n_fresh,"fresh","cm/day",tstr2D, tcstr, & "freshwtr flx ice to ocn (cpl)", & "if positive, ocean gains fresh water", & mps_to_cmpdy/rhofresh, c0, & ns1, f_fresh) - + call define_hist_field(n_fresh_ai,"fresh_ai","cm/day",tstr2D, tcstr, & "freshwtr flx ice to ocn", & "weighted by ice area", mps_to_cmpdy/rhofresh, c0, & ns1, f_fresh_ai) - + call define_hist_field(n_fsalt,"fsalt","kg/m^2/s",tstr2D, tcstr, & "salt flux ice to ocn (cpl)", & "if positive, ocean gains salt", c1, c0, & ns1, f_fsalt) - + call define_hist_field(n_fsalt_ai,"fsalt_ai","kg/m^2/s",tstr2D, tcstr, & "salt flux ice to ocean", & "weighted by ice area", c1, c0, & ns1, f_fsalt_ai) - + call define_hist_field(n_fhocn,"fhocn","W/m^2",tstr2D, tcstr, & "heat flux ice to ocn (cpl)", & "if positive, ocean gains heat", c1, c0, & ns1, f_fhocn) - + call define_hist_field(n_fhocn_ai,"fhocn_ai","W/m^2",tstr2D, tcstr, & "heat flux ice to ocean", & "weighted by ice area", c1, c0, & ns1, f_fhocn_ai) - + call define_hist_field(n_fswthru,"fswthru","W/m^2",tstr2D, tcstr, & "SW thru ice to ocean (cpl)", & "if positive, ocean gains heat", c1, c0, & ns1, f_fswthru) - + call define_hist_field(n_fswthru_ai,"fswthru_ai","W/m^2",tstr2D, tcstr,& "SW flux thru ice to ocean", & "weighted by ice area", c1, c0, & ns1, f_fswthru_ai) - + call define_hist_field(n_strairx,"strairx","N/m^2",ustr2D, ucstr, & "atm/ice stress (x)", & "positive is x direction on U grid", c1, c0, & ns1, f_strairx) - + call define_hist_field(n_strairy,"strairy","N/m^2",ustr2D, ucstr, & "atm/ice stress (y)", & "positive is y direction on U grid", c1, c0, & ns1, f_strairy) - + call define_hist_field(n_strtltx,"strtltx","N/m^2",ustr2D, ucstr, & "sea sfc tilt stress (x)", & "none", c1, c0, & ns1, f_strtltx) - + call define_hist_field(n_strtlty,"strtlty","N/m^2",ustr2D, ucstr, & "sea sfc tilt stress (y)", & "none", c1, c0, & ns1, f_strtlty) - + call define_hist_field(n_strcorx,"strcorx","N/m^2",ustr2D, ucstr, & "coriolis stress (x)", & "positive is x direction on U grid", c1, c0, & ns1, f_strcorx) - + call define_hist_field(n_strcory,"strcory","N/m^2",ustr2D, ucstr, & "coriolis stress (y)", & "positive is y direction on U grid", c1, c0, & ns1, f_strcory) - + call define_hist_field(n_strocnx,"strocnx","N/m^2",ustr2D, ucstr, & "ocean/ice stress (x)", & "positive is x direction on U grid", c1, c0, & ns1, f_strocnx) - + call define_hist_field(n_strocny,"strocny","N/m^2",ustr2D, ucstr, & "ocean/ice stress (y)", & "positive is y direction on U grid", c1, c0, & ns1, f_strocny) - + call define_hist_field(n_strintx,"strintx","N/m^2",ustr2D, ucstr, & "internal ice stress (x)", & "positive is x direction on U grid", c1, c0, & ns1, f_strintx) - + call define_hist_field(n_strinty,"strinty","N/m^2",ustr2D, ucstr, & "internal ice stress (y)", & "positive is y direction on U grid", c1, c0, & ns1, f_strinty) - + call define_hist_field(n_strength,"strength","N/m",tstr2D, tcstr, & "compressive ice strength", & "none", c1, c0, & ns1, f_strength) - + call define_hist_field(n_divu,"divu","%/day",tstr2D, tcstr, & "strain rate (divergence)", & - "none", secday*c100, c0, & + "divu is instantaneous, on T grid", secday*c100, c0, & ns1, f_divu) call define_hist_field(n_shear,"shear","%/day",tstr2D, tcstr, & @@ -829,37 +848,37 @@ subroutine init_hist (dt) "ice volume tendency thermo", & "none", mps_to_cmpdy, c0, & ns1, f_dvidtt) - + call define_hist_field(n_dvsdtt,"dvsdtt","cm/day",tstr2D, tcstr, & "snow volume tendency thermo", & "none", mps_to_cmpdy, c0, & ns1, f_dvsdtt) - + call define_hist_field(n_dvidtd,"dvidtd","cm/day",tstr2D, tcstr, & "ice volume tendency dynamics", & "none", mps_to_cmpdy, c0, & ns1, f_dvidtd) - + call define_hist_field(n_dvsdtd,"dvsdtd","cm/day",tstr2D, tcstr, & "snow volume tendency dynamics", & "none", mps_to_cmpdy, c0, & ns1, f_dvsdtd) - + call define_hist_field(n_daidtt,"daidtt","%/day",tstr2D, tcstr, & "area tendency thermo", & "none", secday*c100, c0, & ns1, f_daidtt) - + call define_hist_field(n_daidtd,"daidtd","%/day",tstr2D, tcstr, & "area tendency dynamics", & "none", secday*c100, c0, & ns1, f_daidtd) - + call define_hist_field(n_dagedtt,"dagedtt","day/day",tstr2D, tcstr, & "age tendency thermo", & "excludes time step increment", c1, c0, & ns1, f_dagedtt) - + call define_hist_field(n_dagedtd,"dagedtd","day/day",tstr2D, tcstr, & "age tendency dynamics", & "excludes time step increment", c1, c0, & @@ -879,22 +898,22 @@ subroutine init_hist (dt) "ice volume snapshot", & "none", c1, c0, & ns1, f_hisnap) - + call define_hist_field(n_aisnap,"aisnap","1",tstr2D, tcstr, & "ice area snapshot", & "none", c1, c0, & ns1, f_aisnap) - - call define_hist_field(n_trsig,"trsig","N/m^2",tstr2D, tcstr, & + + call define_hist_field(n_trsig,"trsig","N/m",tstr2D, tcstr, & "internal stress tensor trace", & "ice strength approximation", c1, c0, & ns1, f_trsig) - + call define_hist_field(n_icepresent,"ice_present","1",tstr2D, tcstr, & "fraction of time-avg interval that ice is present", & "ice extent flag", c1, c0, & ns1, f_icepresent) - + call define_hist_field(n_fsurf_ai,"fsurf_ai","W/m^2",tstr2D, tcstr, & "net surface heat flux", & "positive downward, excludes conductive flux, weighted by ice area", & @@ -983,45 +1002,53 @@ subroutine init_hist (dt) call define_hist_field(n_sithick,"sithick","m",tstr2D, tcstr, & "sea ice thickness", & - "volume divided by area", c1, c0, & - ns1, f_sithick) + "volume divided by area", c1, c0, & + ns1, f_sithick, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siage,"siage","s",tstr2D, tcstr, & "sea ice age", & "none", c1, c0, & - ns1, f_siage) + ns1, f_siage, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_sifb,"sifb","m",tstr2D, tcstr, & "sea ice freeboard", & "none", c1, c0, & - ns1, f_sifb) + ns1, f_sifb, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_sisnconc,"sisnconc","1",tstr2D, tcstr, & "snow area fraction", & - "none", c1, c0, & - ns1, f_sisnconc) - call define_hist_field(n_sisnthick,"sisnthick","m",tstr2D, tcstr, & - "sea ice snow thickness", & - "snow volume divided by area", c1, c0, & - ns1, f_sisnthick) - call define_hist_field(n_sitemptop,"sitemptop","degC",tstr2D, tcstr, & - "sea ice surface temperature", & - "none", c1, c0, & - ns1, f_sitemptop) - call define_hist_field(n_sitempsnic,"sitempsnic","degC",tstr2D, tcstr, & - "snow ice interface temperature", & - "surface temperature when no snow present", c1, c0, & - ns1, f_sitempsnic) - call define_hist_field(n_sitempbot,"sitempbot","degK",tstr2D, tcstr, & - "sea ice bottom temperature", & - "none", c1, c0, & - ns1, f_sitempbot) + "none", c1, c0, & + ns1, f_sisnconc, avg_ice_present=.true., mask_ice_free_points=.true.) + + call define_hist_field(n_sisnthick,"sisnthick","m",tstr2D, tcstr, & + "sea ice snow thickness", & + "snow volume divided by area", c1, c0, & + ns1, f_sisnthick, avg_ice_present=.true., mask_ice_free_points=.true.) + + call define_hist_field(n_sitemptop,"sitemptop","K",tstr2D, tcstr, & + "sea ice surface temperature", & + "none", c1, c0, & + ns1, f_sitemptop, avg_ice_present=.true., mask_ice_free_points=.true.) + + call define_hist_field(n_sitempsnic,"sitempsnic","K",tstr2D, tcstr, & + "snow ice interface temperature", & + "surface temperature when no snow present", c1, c0, & + ns1, f_sitempsnic, avg_ice_present=.true., mask_ice_free_points=.true.) + + call define_hist_field(n_sitempbot,"sitempbot","K",tstr2D, tcstr, & + "sea ice bottom temperature", & + "none", c1, c0, & + ns1, f_sitempbot, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_siu,"siu","m/s",ustr2D, ucstr, & - "ice x velocity component", & - "none", c1, c0, & - ns1, f_siu) + "ice x velocity component", & + "none", c1, c0, & + ns1, f_siu, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_siv,"siv","m/s",ustr2D, ucstr, & - "ice y velocity component", & - "none", c1, c0, & - ns1, f_siv) + "ice y velocity component", & + "none", c1, c0, & + ns1, f_siv, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidmasstranx,"sidmasstranx","kg/s",ustr2D, ucstr, & "x component of snow and sea ice mass transport", & @@ -1036,92 +1063,91 @@ subroutine init_hist (dt) call define_hist_field(n_sistrxdtop,"sistrxdtop","N m^-2",ustr2D, ucstr, & "x component of atmospheric stress on sea ice", & "none", c1, c0, & - ns1, f_sistrxdtop) + ns1, f_sistrxdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistrydtop,"sistrydtop","N m^-2",ustr2D, ucstr, & "y component of atmospheric stress on sea ice", & "none", c1, c0, & - ns1, f_sistrydtop) - + ns1, f_sistrydtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistrxubot,"sistrxubot","N m^-2",ustr2D, ucstr, & "x component of ocean stress on sea ice", & "none", c1, c0, & - ns1, f_sistrxubot) + ns1, f_sistrxubot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistryubot,"sistryubot","N m^-2",ustr2D, ucstr, & "y component of ocean stress on sea ice", & "none", c1, c0, & - ns1, f_sistryubot) + ns1, f_sistryubot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcetiltx,"siforcetiltx","N m^-2",ustr2D, ucstr, & "x component of sea surface tilt force", & "none", c1, c0, & - ns1, f_siforcetiltx) + ns1, f_siforcetiltx, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcetilty,"siforcetilty","N m^-2",ustr2D, ucstr, & "y component of sea surface tilt force", & - "none", c1, c0, & - ns1, f_siforcetilty) + "none", c1, c0, & + ns1, f_siforcetilty, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siforcecoriolx,"siforcecoriolx","N m^-2",ustr2D, ucstr, & - "x component of Coriolis force", & - "none", c1, c0, & - ns1, f_siforcecoriolx) + call define_hist_field(n_siforcecoriolx,"siforcecoriolx","N m^-2",ustr2D, ucstr, & + "x component of Coriolis force", & + "none", c1, c0, & + ns1, f_siforcecoriolx, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siforcecorioly,"siforcecorioly","N m^-2",ustr2D, ucstr, & - "y component of Coriolis force", & - "none", c1, c0, & - ns1, f_siforcecorioly) + call define_hist_field(n_siforcecorioly,"siforcecorioly","N m^-2",ustr2D, ucstr, & + "y component of Coriolis force", & + "none", c1, c0, & + ns1, f_siforcecorioly, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siforceintstrx,"siforceintstrx","N m^-2",ustr2D, ucstr, & - "x component of internal ice stress force", & - "none", c1, c0, & - ns1, f_siforceintstrx) + call define_hist_field(n_siforceintstrx,"siforceintstrx","N m^-2",ustr2D, ucstr, & + "x component of internal ice stress force", & + "none", c1, c0, & + ns1, f_siforceintstrx, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siforceintstry,"siforceintstry","N m^-2",ustr2D, ucstr, & - "y component of internal ice stress force", & - "none", c1, c0, & - ns1, f_siforceintstry) + call define_hist_field(n_siforceintstry,"siforceintstry","N m^-2",ustr2D, ucstr, & + "y component of internal ice stress force", & + "none", c1, c0, & + ns1, f_siforceintstry, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sicompstren,"sicompstren","N/m",ustr2D, ucstr, & - "compressive sea ice strength", & - "none", c1, c0, & - ns1, f_sicompstren) + "compressive sea ice strength", & + "none", c1, c0, & + ns1, f_sicompstren, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidivvel,"sidivvel","1/s",ustr2D, ucstr, & - "divergence of the sea ice velocity field (ice area weighted)", & + "divergence of the sea ice velocity field (ice area weighted)", & "none", c1, c0, & - ns1, f_sidivvel) + ns1, f_sidivvel, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sispeed,"sispeed","m/s",ustr2D, ucstr, & "ice speed", & "none", c1, c0, & - ns1, f_sispeed) + ns1, f_sispeed, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sialb,"sialb","1",tstr2D, tcstr, & "sea ice albedo", & "none", c1, c0, & - ns1, f_sialb) + ns1, f_sialb, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sihc,"sihc","J m^-2",tstr2D, tcstr, & - "sea ice heat content", & + "sea ice heat content", & "none", c1, c0, & ns1, f_sihc) - call define_hist_field(n_sisnhc,"sisnhc","J m^-2",tstr2D, tcstr, & - "snow heat content", & + call define_hist_field(n_sisnhc,"sisnhc","J m^-2",tstr2D, tcstr, & + "snow heat content", & "none", c1, c0, & ns1, f_sisnhc) - call define_hist_field(n_sidconcth,"sidconcth","1/s",tstr2D, tcstr, & - "sea ice area change from thermodynamics", & - "none", c1, c0, & - ns1, f_sidconcth) + call define_hist_field(n_sidconcth,"sidconcth","1/s",tstr2D, tcstr, & + "sea ice area change from thermodynamics", & + "none", c1, c0, & + ns1, f_sidconcth) - call define_hist_field(n_sidconcdyn,"sidconcdyn","1/s",tstr2D, tcstr, & - "sea ice area change from dynamics", & - "none", c1, c0, & + call define_hist_field(n_sidconcdyn,"sidconcdyn","1/s",tstr2D, tcstr, & + "sea ice area change from dynamics", & + "none", c1, c0, & ns1, f_sidconcdyn) call define_hist_field(n_sidmassth,"sidmassth","kg m^-2 s^-1",tstr2D, tcstr, & @@ -1130,138 +1156,140 @@ subroutine init_hist (dt) ns1, f_sidmassth) call define_hist_field(n_sidmassdyn,"sidmassdyn","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from dynamics", & - "none", c1, c0, & - ns1, f_sidmassdyn) + "sea ice mass change from dynamics", & + "none", c1, c0, & + ns1, f_sidmassdyn) call define_hist_field(n_sidmassgrowthwat,"sidmassgrowthwat","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from frazil growth", & - "none", c1, c0, & - ns1, f_sidmassgrowthwat) + "none", c1, c0, & + ns1, f_sidmassgrowthwat) call define_hist_field(n_sidmassgrowthbot,"sidmassgrowthbot","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from bottom growth", & - "none", c1, c0, & - ns1, f_sidmassgrowthbot) + "sea ice mass change from basal growth", & + "none", c1, c0, & + ns1, f_sidmassgrowthbot) - call define_hist_field(n_sidmasssi,"sidmasssi","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from snow ice conversion", & - "none", c1, c0, & + call define_hist_field(n_sidmasssi,"sidmasssi","kg m^-2 s^-1",tstr2D, tcstr, & + "sea ice mass change from snow-ice formation", & + "none", c1, c0, & ns1, f_sidmasssi) - call define_hist_field(n_sidmassevapsubl,"sidmassevapsubl","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from evaporation and sublimation", & - "none", c1, c0, & - ns1, f_sidmassevapsubl) + call define_hist_field(n_sidmassevapsubl,"sidmassevapsubl","kg m^-2 s^-1",tstr2D, tcstr, & + "sea ice mass change from evaporation and sublimation", & + "none", c1, c0, & + ns1, f_sidmassevapsubl) - call define_hist_field(n_sndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & - "snow mass change from evaporation and sublimation", & - "none", c1, c0, & - ns1, f_sndmasssubl) + call define_hist_field(n_sndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & + "snow mass change from evaporation and sublimation", & + "none", c1, c0, & + ns1, f_sndmasssubl) - call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from top ice melt", & - "none", c1, c0, & + "none", c1, c0, & ns1, f_sidmassmelttop) call define_hist_field(n_sidmassmeltbot,"sidmassmeltbot","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from bottom ice melt", & - "none", c1, c0, & - ns1, f_sidmassmeltbot) + "none", c1, c0, & + ns1, f_sidmassmeltbot) call define_hist_field(n_sidmasslat,"sidmasslat","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from lateral ice melt", & - "none", c1, c0, & - ns1, f_sidmasslat) + "none", c1, c0, & + ns1, f_sidmasslat) call define_hist_field(n_sndmasssnf,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from snow fall", & - "none", c1, c0, & - ns1, f_sndmasssnf) + "none", c1, c0, & + ns1, f_sndmasssnf) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from melt", & "none", c1, c0, & ns1, f_sndmassmelt) - call define_hist_field(n_siflswdtop,"siflswdtop","W/m^2",tstr2D, tcstr, & - "down shortwave flux over sea ice", & - "positive downward", c1, c0, & - ns1, f_siflswdtop) + call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & + "snow mass change from dynamics ridging", & + "none", c1, c0, & + ns1, f_sndmassdyn) + + call define_hist_field(n_siflswdtop,"siflswdtop","W/m2",tstr2D, tcstr, & + "down shortwave flux over sea ice", & + "positive downward", c1, c0, & + ns1, f_siflswdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswutop,"siflswutop","W/m^2",tstr2D, tcstr, & - "upward shortwave flux over sea ice", & + "upward shortwave flux over sea ice", & "positive downward", c1, c0, & - ns1, f_siflswutop) + ns1, f_siflswutop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdbot,"siflswdbot","W/m^2",tstr2D, tcstr, & - "down shortwave flux at bottom of ice", & - "positive downward", c1, c0, & - ns1, f_siflswdbot) + "down shortwave flux at bottom of ice", & + "positive downward", c1, c0, & + ns1, f_siflswdbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllwdtop,"sifllwdtop","W/m^2",tstr2D, tcstr, & - "down longwave flux over sea ice", & - "positive downward", c1, c0, & - ns1, f_sifllwdtop) + "down longwave flux over sea ice", & + "positive downward", c1, c0, & + ns1, f_sifllwdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllwutop,"sifllwutop","W/m^2",tstr2D, tcstr, & - "upward longwave flux over sea ice", & - "positive downward", c1, c0, & - ns1, f_sifllwutop) + "upward longwave flux over sea ice", & + "positive downward", c1, c0, & + ns1, f_sifllwutop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsenstop,"siflsenstop","W/m^2",tstr2D, tcstr, & - "sensible heat flux over sea ice", & - "positive downward", c1, c0, & - ns1, f_siflsenstop) - - call define_hist_field(n_siflsensupbot,"siflsensupbot","W/m^2",tstr2D, tcstr, & - "sensible heat flux at bottom of sea ice", & + "sensible heat flux over sea ice", & "positive downward", c1, c0, & - ns1, f_siflsensupbot) + ns1, f_siflsenstop, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_siflsensupbot,"siflsensupbot","W/m^2",tstr2D, tcstr, & + "sensible heat flux at bottom of sea ice", & + "positive downward", c1, c0, & + ns1, f_siflsensupbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllatstop,"sifllatstop","W/m^2",tstr2D, tcstr, & - "latent heat flux over sea ice", & + "latent heat flux over sea ice", & "positive downward", c1, c0, & - ns1, f_sifllatstop) + ns1, f_sifllatstop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflcondtop,"siflcondtop","W/m^2",tstr2D, tcstr, & - "conductive heat flux at top of sea ice", & - "positive downward", c1, c0, & - ns1, f_siflcondtop) + "conductive heat flux at top of sea ice", & + "positive downward", c1, c0, & + ns1, f_siflcondtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflcondbot,"siflcondbot","W/m^2",tstr2D, tcstr, & - "conductive heat flux at bottom of sea ice", & - "positive downward", c1, c0, & - ns1, f_siflcondbot) + "conductive heat flux at bottom of sea ice", & + "positive downward", c1, c0, & + ns1, f_siflcondbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflfwdrain,"siflfwdrain","kg m-2 s-1",tstr2D, tcstr, & - "freshwater drainage through sea ice", & - "positive downward", c1, c0, & - ns1, f_siflfwdrain) + "freshwater drainage through sea ice", & + "positive downward", c1, c0, & + ns1, f_siflfwdrain, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sipr,"sipr","kg m^-2 s^-1",tstr2D, tcstr, & - "rainfall over sea ice", & + call define_hist_field(n_sipr,"sipr","kg m^-2 s^-1",tstr2D, tcstr, & + "rainfall over sea ice", & "none", c1, c0, & - ns1, f_sipr) - - - call define_hist_field(n_siflsaltbot,"siflsaltbot","kg m^-2 s^-1",tstr2D, tcstr, & - "salt flux from sea ice", & - "positive downward", c1, c0, & - ns1, f_siflsaltbot) + ns1, f_sipr, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflfwbot,"siflfwbot","kg m^-2 s^-1",tstr2D, tcstr, & - "fresh water flux from sea ice", & - "positive downward", c1, c0, & - ns1, f_siflfwbot) + call define_hist_field(n_siflsaltbot,"siflsaltbot","kg m^-2 s^-1",tstr2D, tcstr, & + "salt flux from sea ice", & + "positive downward", c1, c0, & + ns1, f_siflsaltbot, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sisaltmass,"sisaltmass","kg m^-2",tstr2D,& - tcstr, "mass of salt in sea ice (for ocean fluxes)",& + call define_hist_field(n_siflfwbot,"siflfwbot","kg m^-2 s^-1",tstr2D, tcstr, & + "fresh water flux from sea ice", & + "positive downward", c1, c0, & + ns1, f_siflfwbot, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_sisaltmass,"sisaltmass","kg m^-2",tstr2D, tcstr, & + "mass of salt in sea ice (for ocean fluxes)",& "none", c1, c0, & - ns1, f_sisaltmass) + ns1, f_sisaltmass, avg_ice_present=.true., mask_ice_free_points=.true.) !To-do : check this ! endif ! if (histfreq(ns1) /= 'x') then enddo ! ns1 @@ -1286,16 +1314,16 @@ subroutine init_hist (dt) do ns1 = 1, nstreams if (histfreq(ns1) /= 'x') then - call define_hist_field(n_aicen,"aicen","1",tstr3Dc, tcstr, & - "ice area, categories","none", c1, c0, & + call define_hist_field(n_aicen,"aicen","1",tstr3Dc, tcstr, & + "ice area, categories","none", c1, c0, & ns1, f_aicen) - call define_hist_field(n_vicen,"vicen","m",tstr3Dc, tcstr, & - "ice volume, categories","none", c1, c0, & + call define_hist_field(n_vicen,"vicen","m",tstr3Dc, tcstr, & + "ice volume, categories","none", c1, c0, & ns1, f_vicen) call define_hist_field(n_vsnon,"vsnon","m",tstr3Dc, tcstr, & - "snow depth on ice, categories","volume per unit area of snow", c1, c0, & + "snow depth on ice, categories","volume per unit area of snow", c1, c0, & ns1, f_vsnon) call define_hist_field(n_snowfracn,"snowfracn","1",tstr3Dc, tcstr, & @@ -1303,34 +1331,34 @@ subroutine init_hist (dt) "snow fraction per unit grid cell area", c1, c0, & ns1, f_snowfracn) - - call define_hist_field(n_fsurfn_ai,"fsurfn_ai","W/m^2",tstr3Dc, tcstr, & - "net surface heat flux, categories","weighted by ice area", c1, c0, & + call define_hist_field(n_fsurfn_ai,"fsurfn_ai","W/m^2",tstr3Dc, tcstr, & + "net surface heat flux, categories","weighted by ice area", c1, c0, & ns1, f_fsurfn_ai) - + call define_hist_field(n_fcondtopn_ai,"fcondtopn_ai","W/m^2",tstr3Dc, tcstr, & "top sfc conductive heat flux, cat","weighted by ice area", c1, c0, & ns1, f_fcondtopn_ai) - call define_hist_field(n_fmelttn_ai,"fmelttn_ai","W/m^2",tstr3Dc, tcstr, & - "net sfc heat flux causing melt, cat","weighted by ice area", c1, c0, & + call define_hist_field(n_fmelttn_ai,"fmelttn_ai","W/m^2",tstr3Dc, tcstr, & + "net sfc heat flux causing melt, cat","weighted by ice area", c1, c0, & ns1, f_fmelttn_ai) - call define_hist_field(n_flatn_ai,"flatn_ai","W/m^2",tstr3Dc, tcstr, & - "latent heat flux, category","weighted by ice area", c1, c0, & + call define_hist_field(n_flatn_ai,"flatn_ai","W/m^2",tstr3Dc, tcstr, & + "latent heat flux, category","weighted by ice area", c1, c0, & ns1, f_flatn_ai) - call define_hist_field(n_fsensn_ai,"fsensn_ai","W/m^2",tstr3Dc, tcstr, & - "sensible heat flux, category","weighted by ice area", c1, c0, & + call define_hist_field(n_fsensn_ai,"fsensn_ai","W/m^2",tstr3Dc, tcstr, & + "sensible heat flux, category","weighted by ice area", c1, c0, & ns1, f_fsensn_ai) - call define_hist_field(n_Tn_top,"Tn_top","K",tstr3Dc, tcstr, & - "temperature of the top layer (snow or ice), categories","multilayer scheme", c1, c0, & - ns1, f_Tn_top) + ! to-do: add if zero-layer? + call define_hist_field(n_Tn_top,"Tn_top","K",tstr3Dc, tcstr, & + "temperature of the top layer (snow or ice), categories", "multilayer scheme", c1, c0, & + ns1, f_Tn_top) call define_hist_field(n_keffn_top,"keffn_top","W/m^2/K",tstr3Dc, tcstr, & "effective thermal conductivity of the top ice layer, categories", & - "multilayer scheme", c1, c0, & + "multilayer scheme", c1, c0, & ns1, f_keffn_top) endif ! if (histfreq(ns1) /= 'x') then @@ -1397,14 +1425,15 @@ subroutine init_hist (dt) if (allocated(Tinz4d)) deallocate(Tinz4d) allocate(Tinz4d(nx_block,ny_block,nzilyr,ncat_hist)) endif + if (f_Sinz (1:1) /= 'x') then + if (allocated(Sinz4d)) deallocate(Sinz4d) + allocate(Sinz4d(nx_block,ny_block,nzilyr,ncat_hist)) + endif if (f_Tsnz (1:1) /= 'x') then if (allocated(Tsnz4d)) deallocate(Tsnz4d) allocate(Tsnz4d(nx_block,ny_block,nzslyr,ncat_hist)) endif - if (f_Sinz (1:1) /= 'x') then - if (allocated(Sinz4d)) deallocate(Sinz4d) - allocate(Sinz4d(nx_block,ny_block,nzilyr,ncat_hist)) - endif + ! other 4D history variables @@ -1443,9 +1472,13 @@ subroutine init_hist (dt) ntmp(:) = 0 if (my_task == master_task) then write(nu_diag,*) ' ' + write(nu_diag,*) 'total number of history fields = ',num_avail_hist_fields_tot + write(nu_diag,*) 'max number of history fields = ',max_avail_hist_fields write(nu_diag,*) 'The following variables will be ', & 'written to the history tape: ' write(nu_diag,101) 'description','units','variable','frequency','x' + if (num_avail_hist_fields_tot == 0) & + write(nu_diag,*) '*** WARNING: NO HISTORY FIELDS WILL BE WRITTEN ***' do n=1,num_avail_hist_fields_tot if (avail_hist_fields(n)%vhistfreq_n /= 0) & write(nu_diag,100) avail_hist_fields(n)%vdesc, & @@ -1491,9 +1524,11 @@ subroutine init_hist (dt) if (allocated(a4Di)) deallocate(a4Di) if (num_avail_hist_fields_4Di > 0) & allocate(a4Di(nx_block,ny_block,nzilyr,ncat_hist,num_avail_hist_fields_4Di,max_blocks)) + if (allocated(a4Ds)) deallocate(a4Ds) if (num_avail_hist_fields_4Ds > 0) & allocate(a4Ds(nx_block,ny_block,nzslyr,ncat_hist,num_avail_hist_fields_4Ds,max_blocks)) + if (allocated(a4Db)) deallocate(a4Db) if (num_avail_hist_fields_4Db > 0) & allocate(a4Db(nx_block,ny_block,nzblyr,ncat_hist,num_avail_hist_fields_4Db,max_blocks)) @@ -1510,8 +1545,8 @@ subroutine init_hist (dt) if (restart .and. yday >= c2) then ! restarting midyear gives erroneous onset dates - mlt_onset = 999._dbl_kind - frz_onset = 999._dbl_kind + mlt_onset = 999._dbl_kind + frz_onset = 999._dbl_kind else mlt_onset = c0 frz_onset = c0 @@ -1607,6 +1642,9 @@ subroutine accum_hist (dt) hs , & ! temporary variable for snow depth Tmlts ! temporary variable for melting temperature + real (kind=dbl_kind), dimension (nx_block,ny_block,ncat_hist) :: & + ravgipn + real (kind=dbl_kind) :: & area_threshold ! min time mean ice area allowed for dividing ! (maximum of a_min and aicenmin - @@ -1672,13 +1710,12 @@ subroutine accum_hist (dt) avgct(ns) = c1 else ! write averages over time histfreq avgct(ns) = avgct(ns) + c1 -! if (avgct(ns) == c1) time_beg(ns) = (time-dt)/int(secday) if (avgct(ns) == c1) then time_beg(ns) = (time-dt)/int(secday) time_beg(ns) = real(time_beg(ns),kind=real_kind) endif endif - enddo + enddo ! ns !--------------------------------------------------------------- ! increment field @@ -1689,7 +1726,7 @@ subroutine accum_hist (dt) do iblk = 1, nblocks - this_block = get_block(blocks_ice(iblk),iblk) + this_block = get_block(blocks_ice(iblk),iblk) ilo = this_block%ilo ihi = this_block%ihi jlo = this_block%jlo @@ -1702,9 +1739,9 @@ subroutine accum_hist (dt) call accum_hist_field(n_hi, iblk, vice(:,:,iblk), a2D) if (f_hs (1:1) /= 'x') & call accum_hist_field(n_hs, iblk, vsno(:,:,iblk), a2D) - if (f_sifb (1:1) /= 'x') & + if (f_sifb (1:1) /= 'x') & call accum_hist_field(n_sifb, iblk, ice_freeboard(:,:,iblk), a2D) - if (f_snowfrac(1:1) /= 'x') & + if (f_snowfrac(1:1) /= 'x') & call accum_hist_field(n_snowfrac, iblk, snowfrac(:,:,iblk), a2D) if (f_Tsfc (1:1) /= 'x') & call accum_hist_field(n_Tsfc, iblk, trcr(:,:,nt_Tsfc,iblk), a2D) @@ -1718,7 +1755,6 @@ subroutine accum_hist (dt) call accum_hist_field(n_uatm, iblk, uatm(:,:,iblk), a2D) if (f_vatm (1:1) /= 'x') & call accum_hist_field(n_vatm, iblk, vatm(:,:,iblk), a2D) - if (f_sice (1:1) /= 'x') then do j = jlo, jhi do i = ilo, ihi @@ -1799,14 +1835,13 @@ subroutine accum_hist (dt) call accum_hist_field(n_alvdf, iblk, alvdf(:,:,iblk), a2D) if (f_alidf (1:1) /= 'x') & call accum_hist_field(n_alidf, iblk, alidf(:,:,iblk), a2D) - if (f_alvdr_ai (1:1) /= 'x') & call accum_hist_field(n_alvdr_ai, iblk, alvdr_ai(:,:,iblk), a2D) if (f_alidr_ai (1:1) /= 'x') & call accum_hist_field(n_alidr_ai, iblk, alidr_ai(:,:,iblk), a2D) - if (f_alvdf_ai (1:1) /= 'x') & + if (f_alvdf_ai (1:1) /= 'x') & call accum_hist_field(n_alvdf_ai, iblk, alvdf_ai(:,:,iblk), a2D) - if (f_alidf_ai (1:1) /= 'x') & + if (f_alidf_ai (1:1) /= 'x') & call accum_hist_field(n_alidf_ai, iblk, alidf_ai(:,:,iblk), a2D) if (f_albice (1:1) /= 'x') & @@ -1837,16 +1872,14 @@ subroutine accum_hist (dt) if (f_evap_ice_ai(1:1) /= 'x') & call accum_hist_field(n_evap_ice_ai,iblk, evap_ice(:,:,iblk)*workb(:,:), a2D) if (f_evap_snow_ai(1:1) /= 'x') & - call accum_hist_field(n_evap_snow_ai,iblk, evap_snow(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_evap_snow_ai,iblk, evap_snow(:,:,iblk)*workb(:,:), a2D) if (f_Tair (1:1) /= 'x') & call accum_hist_field(n_Tair, iblk, Tair(:,:,iblk), a2D) if (f_Tref (1:1) /= 'x') & - call accum_hist_field(n_Tref, iblk, & - Tref(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_Tref, iblk, Tref(:,:,iblk)*workb(:,:), a2D) if (f_Qref (1:1) /= 'x') & - call accum_hist_field(n_Qref, iblk, & - Qref(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_Qref, iblk, Qref(:,:,iblk)*workb(:,:), a2D) if (f_congel (1:1) /= 'x') & call accum_hist_field(n_congel, iblk, congel(:,:,iblk), a2D) if (f_frazil (1:1) /= 'x') & @@ -1881,7 +1914,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_fswthru, iblk, fswthru(:,:,iblk), a2D) if (f_fswthru_ai(1:1)/= 'x') & call accum_hist_field(n_fswthru_ai,iblk, fswthru_ai(:,:,iblk), a2D) - + if (f_strairx(1:1) /= 'x') & call accum_hist_field(n_strairx, iblk, strairx(:,:,iblk), a2D) if (f_strairy(1:1) /= 'x') & @@ -1969,8 +2002,8 @@ subroutine accum_hist (dt) if (f_siage(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_iage,iblk) + do i = ilo, ihi + if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_iage,iblk) enddo enddo call accum_hist_field(n_siage, iblk, worka(:,:), a2D) @@ -1983,7 +2016,7 @@ subroutine accum_hist (dt) do i = ilo, ihi if (aice(i,j,iblk) > puny) worka(i,j) = snowfrac(i,j,iblk) enddo - enddo + enddo call accum_hist_field(n_sisnconc, iblk, worka(:,:), a2D) endif @@ -1994,8 +2027,8 @@ subroutine accum_hist (dt) if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & worka(i,j) = vsno(i,j,iblk) enddo - enddo - call accum_hist_field(n_sisnthick, iblk, worka(:,:), a2D) + enddo + call accum_hist_field(n_sisnthick, iblk, worka(:,:), a2D) endif @@ -2003,44 +2036,43 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk)+Tffresh + if (aice(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk)*(trcr(i,j,nt_Tsfc,iblk)+Tffresh) enddo enddo call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) endif - if (f_sitempsnic(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi - do i = ilo, ihi - if (vsno(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then + do i = ilo, ihi + if (vsno(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then worka(i,j) = aice(i,j,iblk)*Tsnic(i,j,iblk)/aice_init(i,j,iblk)+Tffresh - else + else worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk)+Tffresh endif enddo - enddo + enddo call accum_hist_field(n_sitempsnic, iblk, worka(:,:), a2D) endif - if (f_sitempbot(1:1) /= 'x') then + if (f_sitempbot(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) & - worka(i,j) = & - aice(i,j,iblk)*(Ti_bot(i,j,iblk)/aice_init(i,j,iblk)+Tffresh) - enddo - enddo - call accum_hist_field(n_sitempbot, iblk, worka(:,:), a2D) + worka(i,j) = aice(i,j,iblk)*(Ti_bot(i,j,iblk)/aice_init(i,j,iblk)+Tffresh) + enddo + enddo + call accum_hist_field(n_sitempbot, iblk, worka(:,:), a2D) endif if (f_siu(1:1) /= 'x') then - worka(:,:) = c0 + worka(:,:) = c0 do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*uvel(i,j,iblk) + do i = ilo, ihi + if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*uvel(i,j,iblk) enddo enddo call accum_hist_field(n_siu, iblk, worka(:,:), a2D) @@ -2049,63 +2081,63 @@ subroutine accum_hist (dt) if (f_siv(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*vvel(i,j,iblk) + do i = ilo, ihi + if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*vvel(i,j,iblk) enddo enddo call accum_hist_field(n_siv, iblk, worka(:,:), a2D) endif - - if (f_sispeed(1:1) /= 'x') then - worka(:,:) = c0 + if (f_sispeed(1:1) /= 'x') then + worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk) & - * sqrt(uvel(i,j,iblk)*uvel(i,j,iblk)+vvel(i,j,iblk)*vvel(i,j,iblk)) + if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk) & + * sqrt(uvel(i,j,iblk)*uvel(i,j,iblk)+vvel(i,j,iblk)*vvel(i,j,iblk)) + enddo enddo - enddo - call accum_hist_field(n_sispeed, iblk, worka(:,:), a2D) + call accum_hist_field(n_sispeed, iblk, worka(:,:), a2D) endif - if (f_sidmasstranx(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) & - worka(i,j) = (rhoi*0.5*(vice(i+1,j,iblk)+vice(i,j,iblk))*HTE(i,j,iblk) & - + rhos*0.5*(vsno(i+1,j,iblk)+vsno(i,j,iblk))*HTE(i,j,iblk)) & - * 0.5*(uvel(i,j-1,iblk)+uvel(i,j,iblk)) + if (aice(i,j,iblk) > puny) & + worka(i,j) = (rhoi*p5*(vice(i+1,j,iblk)+vice(i,j,iblk))*HTE(i,j,iblk) & + + rhos*p5*(vsno(i+1,j,iblk)+vsno(i,j,iblk))*HTE(i,j,iblk)) & + * p5*(uvel(i,j-1,iblk)+uvel(i,j,iblk)) enddo - enddo - call accum_hist_field(n_sidmasstranx, iblk, worka(:,:), a2D) - endif + enddo + call accum_hist_field(n_sidmasstranx, iblk, worka(:,:), a2D) + endif - if (f_sidmasstrany(1:1) /= 'x') then + if (f_sidmasstrany(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) & - worka(i,j) = (rhoi*0.5*(vice(i,j+1,iblk)+vice(i,j,iblk))*HTN(i,j,iblk) & - + rhos*0.5*(vsno(i,j+1,iblk)+vsno(i,j,iblk))*HTN(i,j,iblk)) & - * 0.5*(vvel(i-1,j,iblk)+vvel(i,j,iblk)) + if (aice(i,j,iblk) > puny) & + worka(i,j) = (rhoi*p5*(vice(i,j+1,iblk)+vice(i,j,iblk))*HTN(i,j,iblk) & + + rhos*p5*(vsno(i,j+1,iblk)+vsno(i,j,iblk))*HTN(i,j,iblk)) & + * p5*(vvel(i-1,j,iblk)+vvel(i,j,iblk)) + enddo enddo - enddo call accum_hist_field(n_sidmasstrany, iblk, worka(:,:), a2D) - endif + endif + !to-do: use aice_init if (f_sistrxdtop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk)*strairx(i,j,iblk) - enddo - enddo + enddo + enddo call accum_hist_field(n_sistrxdtop, iblk, worka(:,:), a2D) endif + !to-do: use aice_init if (f_sistrydtop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -2205,7 +2237,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_siforceintstry, iblk, worka(:,:), a2D) endif - if (f_sicompstren(1:1) /= 'x') then + if (f_sicompstren(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2289,7 +2321,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidconcdyn, iblk, worka(:,:), a2D) endif - if (f_sidmassth(1:1) /= 'x') then + if (f_sidmassth(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2317,12 +2349,14 @@ subroutine accum_hist (dt) !Sea-Ice Mass Change Through Growth in Supercooled Open Water (Frazil) !To-do: revisit to see if frazil still needs aice/aice_init weighting !Data can be noisy. Weighting not used in CICE6. + !Possibly if weighting is included, set avg_ice_present=.true., mask_ice_free_points=.true. worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*frazil(i,j,iblk)*rhoi / & - (dt*aice_init(i,j,iblk)) + worka(i,j) = frazil(i,j,iblk)*rhoi/dt + ! worka(i,j) = aice(i,j,iblk)*frazil(i,j,iblk)*rhoi / & + ! (dt*aice_init(i,j,iblk)) endif enddo enddo @@ -2335,8 +2369,9 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*congel(i,j,iblk)*rhoi / & - (dt *aice_init(i,j,iblk)) + worka(i,j) = congel(i,j,iblk)*rhoi/dt + ! worka(i,j) = aice(i,j,iblk)*congel(i,j,iblk)*rhoi / & + ! (dt *aice_init(i,j,iblk)) endif enddo enddo @@ -2345,12 +2380,14 @@ subroutine accum_hist (dt) if (f_sidmasssi(1:1) /= 'x') then !To-do: revisit to see if still needs aice/aice_init weighting + !to-do : divide by dt worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi /& - (dt * aice_init(i,j,iblk)) + worka(i,j) = snoice(i,j,iblk)*rhoi/dt + ! worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi /& + ! (dt * aice_init(i,j,iblk)) endif enddo enddo @@ -2363,7 +2400,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk)*rhoi + worka(i,j) = evap_ice(i,j,iblk)*rhoi + ! worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk)*rhoi endif enddo enddo @@ -2376,7 +2414,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = rhos*aice(i,j,iblk)*evap_snow(i,j,iblk) + worka(i,j) = rhos*evap_snow(i,j,iblk)/dt + ! worka(i,j) = rhos*aice(i,j,iblk)*evap_snow(i,j,iblk) endif enddo enddo @@ -2388,9 +2427,11 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi /& - (dt * aice_init(i,j,iblk)) + if (aice(i,j,iblk) > puny) then + worka(i,j) = meltt(i,j,iblk)*rhoi/dt + ! if (aice_init(i,j,iblk) > puny) then + ! worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi /& + ! (dt * aice_init(i,j,iblk)) endif enddo enddo @@ -2402,9 +2443,11 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & - (dt * aice_init(i,j,iblk)) + if (aice(i,j,iblk) > puny) then + worka(i,j) = meltb(i,j,iblk)*rhoi/dt + ! if (aice_init(i,j,iblk) > puny) then + ! worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & + ! (dt * aice_init(i,j,iblk)) endif enddo enddo @@ -2413,12 +2456,15 @@ subroutine accum_hist (dt) if (f_sidmasslat(1:1) /= 'x') then !To-do: revisit to see if still needs aice/aice_init weighting + !to-do : divide by dt worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & - (dt * aice_init(i,j,iblk)) + if (aice(i,j,iblk) > puny) then + worka(i,j) = meltl(i,j,iblk)*rhoi/dt + ! if (aice_init(i,j,iblk) > puny) then + ! worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & + ! (dt * aice_init(i,j,iblk)) endif enddo enddo @@ -2426,6 +2472,7 @@ subroutine accum_hist (dt) endif if (f_sndmasssnf(1:1) /= 'x') then + !to-do: CICE6 does not include rhos worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2442,13 +2489,27 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*melts(i,j,iblk)*rhos/ & - (dt *aice_init(i,j,iblk)) + if (aice(i,j,iblk) > puny) then + worka(i,j) = melts(i,j,iblk)*rhos/dt + ! if (aice_init(i,j,iblk) > puny) then + ! worka(i,j) = aice(i,j,iblk)*melts(i,j,iblk)*rhos/ & + ! (dt *aice_init(i,j,iblk)) + endif + enddo + enddo + call accum_hist_field(n_sndmassmelt, iblk, worka(:,:), a2D) + endif + + if (f_sndmassdyn(1:1) /= 'x') then + worka(:,:) = c0 + do j = jlo, jhi + do i = ilo, ihi + if (aice(i,j,iblk) > puny) then + worka(i,j) = dvsdtd(i,j,iblk)*rhos endif enddo enddo - call accum_hist_field(n_sndmassmelt, iblk, worka(:,:), a2D) + call accum_hist_field(n_sndmassdyn, iblk, worka(:,:), a2D) endif if (f_siflswdtop(1:1) /= 'x') then @@ -2488,7 +2549,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_siflswdbot, iblk, worka(:,:), a2D) endif - if (f_sifllwdtop(1:1) /= 'x') then + if (f_sifllwdtop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2500,7 +2561,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sifllwdtop, iblk, worka(:,:), a2D) endif - if (f_sifllwutop(1:1) /= 'x') then + if (f_sifllwutop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2585,6 +2646,38 @@ subroutine accum_hist (dt) call accum_hist_field(n_sipr, iblk, worka(:,:), a2D) endif +! to-do: Possibly fix for mushy ? +! if (f_sifb(1:1) /= 'x') then +! worka(:,:) = c0 +! rho_ice = rhoi +! rho_ocn = rhow +! do j = jlo, jhi +! do i = ilo, ihi +! if (aice(i,j,iblk) > puny) then +! if (ktherm == 2) then +! rho_ocn = icepack_mushy_density_brine(sss(i,j,iblk)) +! rho_ice = c0 +! do k = 1, nzilyr +! Tice = icepack_mushy_temperature_mush(trcr(i,j,nt_qice+k-1,iblk),trcr(i,j,nt_sice+k-1,iblk)) +! Sbr = trcr(i,j,nt_sice+k-1,iblk) +! phi = icepack_mushy_liquid_fraction(Tice,Sbr) +! rhob = icepack_mushy_density_brine(Sbr) +! rho_ice = rho_ice + min(phi*rhob+(c1-phi)*rhoi,rho_ocn) +! enddo +! rho_ice = rho_ice / real(nzilyr,kind=dbl_kind) +! endif +! worka(i,j) = ((rho_ocn-rho_ice)*vice(i,j,iblk) - rhos*vsno(i,j,iblk))/rho_ocn +! ! if (worka(i,j) < c0) then +! ! write(nu_diag,*) 'negative fb',rho_ocn,rho_ice,rhos +! ! write(nu_diag,*) vice(i,j,iblk),vsno(i,j,iblk) +! ! endif +! endif +! enddo +! enddo +! call accum_hist_field(n_sifb, iblk, worka(:,:), a2D) +! endif + +!to-do: fix for mushy? / frazil???? if (f_siflsaltbot(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -2609,6 +2702,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sisaltmass, iblk, worka(:,:), a2D) endif + !to-do : fix for frazil ???? if (f_siflfwbot(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -2638,8 +2732,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*(frain(i,j,iblk) & - + melts(i,j,iblk)+meltt(i,j,iblk)) + worka(i,j) = aice(i,j,iblk)*(frain(i,j,iblk) + melts(i,j,iblk)+meltt(i,j,iblk)) endif enddo enddo @@ -2657,11 +2750,12 @@ subroutine accum_hist (dt) if (f_vsnon (1:1) /= 'x') & call accum_hist_field(n_vsnon-n2D, iblk, ncat_hist, & vsnon(:,:,1:ncat_hist,iblk), a3Dc) - if (f_snowfracn(1:1) /= 'x') & + !to-do: check aicen ! + if (f_snowfracn(1:1) /= 'x') & call accum_hist_field(n_snowfracn-n2D, iblk, ncat_hist, & snowfracn(:,:,1:ncat_hist,iblk)*aicen(:,:,:,iblk), a3Dc) - if (f_Tn_top (1:1) /= 'x') & + if (f_Tn_top (1:1) /= 'x') & call accum_hist_field(n_Tn_top-n2D, iblk, ncat_hist, & Tn_top(:,:,1:ncat_hist,iblk), a3Dc) if (f_keffn_top (1:1) /= 'x') & @@ -2679,7 +2773,7 @@ subroutine accum_hist (dt) if (f_fsensn_ai (1:1) /= 'x') & call accum_hist_field(n_fsensn_ai-n2D, iblk, ncat_hist, & fsensn(:,:,1:ncat_hist,iblk)*aicen_init(:,:,1:ncat_hist,iblk), a3Dc) - ! Calculate surface heat flux that causes melt (calculated by the + ! Calculate surface heat flux that causes melt (calculated by the ! atmos in HadGEM3 so needed for checking purposes) if (f_fmelttn_ai (1:1) /= 'x') & call accum_hist_field(n_fmelttn_ai-n2D, iblk, ncat_hist, & @@ -2736,7 +2830,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_Sinz-n3Dbcum, iblk, nzilyr, ncat_hist, & Sinz4d(:,:,1:nzilyr,1:ncat_hist), a4Di) endif - + if (f_Tsnz (1:1) /= 'x') then Tsnz4d(:,:,:,:) = c0 if (ktherm == 2) then @@ -2822,12 +2916,13 @@ subroutine accum_hist (dt) !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block, & !$OMP n,nn,ravgctz,ravgip) do iblk = 1, nblocks - this_block = get_block(blocks_ice(iblk),iblk) + this_block = get_block(blocks_ice(iblk),iblk) ilo = this_block%ilo ihi = this_block%ihi jlo = this_block%jlo jhi = this_block%jhi + !to-do: figure out how to make sure n_aice actually exists do j = jlo, jhi do i = ilo, ihi ! Alex West - enforce time mean ice area threshold based @@ -2845,7 +2940,19 @@ subroutine accum_hist (dt) enddo ! i enddo ! j - + if (n_aicen(ns) > n2D) then + do k=1,ncat_hist + do j = jlo, jhi + do i = ilo, ihi + if (a3Dc(i,j,k,n_aicen(ns)-n2D,iblk) > puny) then + ravgipn(i,j,k) = c1/(a3Dc(i,j,k,n_aicen(ns)-n2D,iblk)) + else + ravgipn(i,j,k) = c0 + endif + enddo ! i + enddo ! j + enddo ! k + endif do n = 1, num_avail_hist_fields_2D if (avail_hist_fields(n)%vhistfreq == histfreq(ns)) then @@ -2853,716 +2960,62 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi #ifdef AusCOM - if (n_uocn(ns)==n.or.n_vocn(ns)==n) then - if (.not. umask(i,j,iblk)) then ! mask out land points - a2D(i,j,n,iblk) = spval_dbl - else ! convert units - a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & - * ravgct + avail_hist_fields(n)%conb - endif - else - if (.not. tmask(i,j,iblk)) then ! mask out land points - a2D(i,j,n,iblk) = spval_dbl - else ! convert units - a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & - * ravgct + avail_hist_fields(n)%conb - endif - endif + if (n_uocn(ns)==n.or.n_vocn(ns)==n) then + if (.not. umask(i,j,iblk)) then ! mask out land points + a2D(i,j,n,iblk) = spval_dbl + else ! convert units + a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & + * ravgct + avail_hist_fields(n)%conb + endif + else + if (.not. tmask(i,j,iblk)) then ! mask out land points + a2D(i,j,n,iblk) = spval_dbl + else ! convert units + a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & + * ravgct + avail_hist_fields(n)%conb + endif + endif #else - if (.not. tmask(i,j,iblk)) then ! mask out land points - a2D(i,j,n,iblk) = spval_dbl - else ! convert units - a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & - * ravgct + avail_hist_fields(n)%conb - endif + if (.not. tmask(i,j,iblk)) then ! mask out land points + a2D(i,j,n,iblk) = spval_dbl + else ! convert units + a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & + * ravgct + avail_hist_fields(n)%conb + endif #endif enddo ! i enddo ! j ! Only average for timesteps when ice present - if (index(avail_hist_fields(n)%vname,'sithick') /= 0) then - if (f_sithick(1:1) /= 'x' .and. n_sithick(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sithick(ns),iblk) = & - a2D(i,j,n_sithick(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sithick(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sifb') /= 0) then - if (f_sifb(1:1) /= 'x' .and. n_sifb(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sifb(ns),iblk) = & - a2D(i,j,n_sifb(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sifb(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siage') /= 0) then - if (f_siage(1:1) /= 'x' .and. n_siage(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siage(ns),iblk) = & - a2D(i,j,n_siage(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siage(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - - if (index(avail_hist_fields(n)%vname,'sisnconc') /= 0) then - if (f_sisnconc(1:1) /= 'x' .and. n_sisnconc(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sisnconc(ns),iblk) = & - a2D(i,j,n_sisnconc(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sisnconc(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sisnthick') /= 0) then - if (f_sisnthick(1:1) /= 'x' .and. n_sisnthick(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sisnthick(ns),iblk) = & - a2D(i,j,n_sisnthick(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sisnthick(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sitemptop') /= 0) then - if (f_sitemptop(1:1) /= 'x' .and. n_sitemptop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sitemptop(ns),iblk) = & - a2D(i,j,n_sitemptop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sitemptop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sitempsnic') /= 0) then - if (f_sitempsnic(1:1) /= 'x' .and. n_sitempsnic(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sitempsnic(ns),iblk) = & - a2D(i,j,n_sitempsnic(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sitempsnic(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sitempbot') /= 0) then - if (f_sitempbot(1:1) /= 'x' .and. n_sitempbot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sitempbot(ns),iblk) = & - a2D(i,j,n_sitempbot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sitempbot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siu') /= 0) then - if (f_siu(1:1) /= 'x' .and. n_siu(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siu(ns),iblk) = & - a2D(i,j,n_siu(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siu(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siv') /= 0) then - if (f_siv(1:1) /= 'x' .and. n_siv(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siv(ns),iblk) = & - a2D(i,j,n_siv(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siv(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sistrxdtop') /= 0) then - if (f_sistrxdtop(1:1) /= 'x' .and. n_sistrxdtop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sistrxdtop(ns),iblk) = & - a2D(i,j,n_sistrxdtop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sistrxdtop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sistrydtop') /= 0) then - if (f_sistrydtop(1:1) /= 'x' .and. n_sistrydtop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sistrydtop(ns),iblk) = & - a2D(i,j,n_sistrydtop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sistrydtop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sistrxubot') /= 0) then - if (f_sistrxubot(1:1) /= 'x' .and. n_sistrxubot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sistrxubot(ns),iblk) = & - a2D(i,j,n_sistrxubot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sistrxubot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sistryubot') /= 0) then - if (f_sistryubot(1:1) /= 'x' .and. n_sistryubot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sistryubot(ns),iblk) = & - a2D(i,j,n_sistryubot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sistryubot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siforcetiltx') /= 0) then - if (f_siforcetiltx(1:1) /= 'x' .and. n_siforcetiltx(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siforcetiltx(ns),iblk) = & - a2D(i,j,n_siforcetiltx(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siforcetiltx(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siforcetilty') /= 0) then - if (f_siforcetilty(1:1) /= 'x' .and. n_siforcetilty(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siforcetilty(ns),iblk) = & - a2D(i,j,n_siforcetilty(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siforcetilty(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siforcecoriolx') /= 0) then - if (f_siforcecoriolx(1:1) /= 'x' .and. n_siforcecoriolx(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siforcecoriolx(ns),iblk) = & - a2D(i,j,n_siforcecoriolx(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siforcecoriolx(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siforcecorioly') /= 0) then - if (f_siforcecorioly(1:1) /= 'x' .and. n_siforcecorioly(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siforcecorioly(ns),iblk) = & - a2D(i,j,n_siforcecorioly(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siforcecorioly(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siforceintstrx') /= 0) then - if (f_siforceintstrx(1:1) /= 'x' .and. n_siforceintstrx(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siforceintstrx(ns),iblk) = & - a2D(i,j,n_siforceintstrx(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siforceintstrx(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siforceintstry') /= 0) then - if (f_siforceintstry(1:1) /= 'x' .and. n_siforceintstry(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siforceintstry(ns),iblk) = & - a2D(i,j,n_siforceintstry(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siforceintstry(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sicompstren') /= 0) then - if (f_sicompstren(1:1) /= 'x' .and. n_sicompstren(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sicompstren(ns),iblk) = & - a2D(i,j,n_sicompstren(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sicompstren(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sidivvel') /= 0) then - if (f_sidivvel(1:1) /= 'x' .and. n_sidivvel(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sidivvel(ns),iblk) = & - a2D(i,j,n_sidivvel(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sidivvel(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sispeed') /= 0) then - if (f_sispeed(1:1) /= 'x' .and. n_sispeed(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sispeed(ns),iblk) = & - a2D(i,j,n_sispeed(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sispeed(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif + if (avail_hist_fields(n)%avg_ice_present) then + do j = jlo, jhi + do i = ilo, ihi + if (tmask(i,j,iblk)) then + a2D(i,j,n,iblk) = & + a2D(i,j,n,iblk)*avgct(ns)*ravgip(i,j) + endif + ! Mask ice-free points + if (avail_hist_fields(n)%mask_ice_free_points) then + if (ravgip(i,j) == c0) a2D(i,j,n,iblk) = spval_dbl + endif + enddo ! i + enddo ! j endif + ! CMIP albedo: also mask points below horizon if (index(avail_hist_fields(n)%vname,'sialb') /= 0) then - if (f_sialb(1:1) /= 'x' .and. n_sialb(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sialb(ns),iblk) = & - a2D(i,j,n_sialb(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sialb(ns),iblk) = spval_dbl - if (albcnt(i,j,iblk,ns) <= puny) a2D(i,j,n_sialb(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sidmassgrowthwat') /= 0) then - if (f_sidmassgrowthwat(1:1) /= 'x' .and. n_sidmassgrowthwat(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sidmassgrowthwat(ns),iblk) = & - a2D(i,j,n_sidmassgrowthwat(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sidmassgrowthwat(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sidmassgrowthbot') /= 0) then - if (f_sidmassgrowthbot(1:1) /= 'x' .and. n_sidmassgrowthbot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sidmassgrowthbot(ns),iblk) = & - a2D(i,j,n_sidmassgrowthbot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sidmassgrowthbot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sidmasssi') /= 0) then - if (f_sidmasssi(1:1) /= 'x' .and. n_sidmasssi(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sidmasssi(ns),iblk) = & - a2D(i,j,n_sidmasssi(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sidmasssi(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sidmassevapsubl') /= 0) then - if (f_sidmassevapsubl(1:1) /= 'x' .and. n_sidmassevapsubl(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sidmassevapsubl(ns),iblk) = & - a2D(i,j,n_sidmassevapsubl(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sidmassevapsubl(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sndmasssubl') /= 0) then - if (f_sndmasssubl(1:1) /= 'x' .and. n_sndmasssubl(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sndmasssubl(ns),iblk) = & - a2D(i,j,n_sndmasssubl(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sndmasssubl(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sidmassmelttop') /= 0) then - if (f_sidmassmelttop(1:1) /= 'x' .and. n_sidmassmelttop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sidmassmelttop(ns),iblk) = & - a2D(i,j,n_sidmassmelttop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sidmassmelttop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sidmassmeltbot') /= 0) then - if (f_sidmassmeltbot(1:1) /= 'x' .and. n_sidmassmeltbot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sidmassmeltbot(ns),iblk) = & - a2D(i,j,n_sidmassmeltbot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sidmassmeltbot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sidmasslat') /= 0) then - if (f_sidmasslat(1:1) /= 'x' .and. n_sidmasslat(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sidmasslat(ns),iblk) = & - a2D(i,j,n_sidmasslat(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sidmasslat(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - - - - if (index(avail_hist_fields(n)%vname,'sndmasssnf') /= 0) then - if (f_sndmasssnf(1:1) /= 'x' .and. n_sndmasssnf(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sndmasssnf(ns),iblk) = & - a2D(i,j,n_sndmasssnf(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sndmasssnf(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sndmassmelt') /= 0) then - if (f_sndmassmelt(1:1) /= 'x' .and. n_sndmassmelt(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sndmassmelt(ns),iblk) = & - a2D(i,j,n_sndmassmelt(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sndmassmelt(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflswdtop') /= 0) then - if (f_siflswdtop(1:1) /= 'x' .and. n_siflswdtop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflswdtop(ns),iblk) = & - a2D(i,j,n_siflswdtop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflswdtop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflswutop') /= 0) then - if (f_siflswutop(1:1) /= 'x' .and. n_siflswutop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflswutop(ns),iblk) = & - a2D(i,j,n_siflswutop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflswutop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if(index(avail_hist_fields(n)%vname,'siflswdbot') /= 0) then - if (f_siflswdbot(1:1) /= 'x' .and. n_siflswdbot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflswdbot(ns),iblk) = & - a2D(i,j,n_siflswdbot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflswdbot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sifllwdtop') /= 0) then - if (f_sifllwdtop(1:1) /= 'x' .and. n_sifllwdtop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sifllwdtop(ns),iblk) = & - a2D(i,j,n_sifllwdtop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sifllwdtop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sifllwutop') /= 0) then - if (f_sifllwutop(1:1) /= 'x' .and. n_sifllwutop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sifllwutop(ns),iblk) = & - a2D(i,j,n_sifllwutop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sifllwutop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflsenstop') /= 0) then - if (f_siflsenstop(1:1) /= 'x' .and. n_siflsenstop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflsenstop(ns),iblk) = & - a2D(i,j,n_siflsenstop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflsenstop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflsensupbot') /= 0) then - if (f_siflsensupbot(1:1) /= 'x' .and. n_siflsensupbot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflsensupbot(ns),iblk) = & - a2D(i,j,n_siflsensupbot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflsensupbot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sifllatstop') /= 0) then - if (f_sifllatstop(1:1) /= 'x' .and. n_sifllatstop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sifllatstop(ns),iblk) = & - a2D(i,j,n_sifllatstop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sifllatstop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflfwdrain') /= 0) then - if (f_sifllatstop(1:1) /= 'x' .and. n_siflfwdrain(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflfwdrain(ns),iblk) = & - a2D(i,j,n_siflfwdrain(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflfwdrain(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'sipr') /= 0) then - if (f_sipr(1:1) /= 'x' .and. n_sipr(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_sipr(ns),iblk) = & - a2D(i,j,n_sipr(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_sipr(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflcondtop') /= 0) then - if (f_siflcondtop(1:1) /= 'x' .and. n_siflcondtop(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflcondtop(ns),iblk) = & - a2D(i,j,n_siflcondtop(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflcondtop(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflcondbot') /= 0) then - if (f_siflcondbot(1:1) /= 'x' .and. n_siflcondbot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflcondbot(ns),iblk) = & - a2D(i,j,n_siflcondbot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflcondbot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflsaltbot') /= 0) then - if (f_siflsaltbot(1:1) /= 'x' .and. n_siflsaltbot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflsaltbot(ns),iblk) = & - a2D(i,j,n_siflsaltbot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflsaltbot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - - if (index(avail_hist_fields(n)%vname,'siflfwbot') /= 0) then - if (f_siflfwbot(1:1) /= 'x' .and. n_siflfwbot(ns) /= 0) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n_siflfwbot(ns),iblk) = & - a2D(i,j,n_siflfwbot(ns),iblk)*avgct(ns)*ravgip(i,j) - if (ravgip(i,j) == c0) a2D(i,j,n_siflfwbot(ns),iblk) = spval_dbl - endif - enddo ! i - enddo ! j - endif - endif - + do j = jlo, jhi + do i = ilo, ihi + if (albcnt(i,j,iblk,ns) <= puny) a2D(i,j,n,iblk) = spval_dbl + enddo ! i + enddo ! j + endif - !back out albedo/zenith angle dependence + ! back out albedo/zenith angle dependence if (avail_hist_fields(n)%vname(1:6) == 'albice') then do j = jlo, jhi do i = ilo, ihi - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk)) then ravgctz = c0 if (albcnt(i,j,iblk,ns) > puny) & ravgctz = c1/albcnt(i,j,iblk,ns) @@ -3582,7 +3035,7 @@ subroutine accum_hist (dt) if (avail_hist_fields(n)%vname(1:6) == 'albsni') then do j = jlo, jhi do i = ilo, ihi - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk)) then ravgctz = c0 if (albcnt(i,j,iblk,ns) > puny) & ravgctz = c1/albcnt(i,j,iblk,ns) @@ -3593,7 +3046,6 @@ subroutine accum_hist (dt) enddo ! i enddo ! j endif - if (avail_hist_fields(n)%vname(1:8) == 'alvdr_ai') then do j = jlo, jhi do i = ilo, ihi @@ -3623,7 +3075,8 @@ subroutine accum_hist (dt) do n = 1, num_avail_hist_fields_3Dc nn = n2D + n - if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then + if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then + do k = 1, ncat_hist do j = jlo, jhi do i = ilo, ihi @@ -3636,7 +3089,21 @@ subroutine accum_hist (dt) enddo ! i enddo ! j enddo ! k + if (avail_hist_fields(nn)%avg_ice_present) then + do k = 1, ncat_hist + do j = jlo, jhi + do i = ilo, ihi + if (tmask(i,j,iblk)) then + a3Dc(i,j,k,n,iblk) = & + a3Dc(i,j,k,n,iblk)*avgct(ns)*ravgipn(i,j,k) + endif + enddo ! i + enddo ! j + enddo ! k + endif + endif + enddo ! n do n = 1, num_avail_hist_fields_3Dz @@ -3658,7 +3125,7 @@ subroutine accum_hist (dt) enddo ! n do n = 1, num_avail_hist_fields_3Db nn = n3Dzcum + n - if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then + if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then do k = 1, nzblyr do j = jlo, jhi do i = ilo, ihi @@ -3676,7 +3143,7 @@ subroutine accum_hist (dt) do n = 1, num_avail_hist_fields_4Di nn = n3Dbcum + n - if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then + if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then do k = 1, nzilyr do ic = 1, ncat_hist do j = jlo, jhi @@ -3696,7 +3163,7 @@ subroutine accum_hist (dt) do n = 1, num_avail_hist_fields_4Ds nn = n4Dicum + n - if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then + if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then do k = 1, nzslyr do ic = 1, ncat_hist do j = jlo, jhi @@ -3715,7 +3182,7 @@ subroutine accum_hist (dt) enddo ! n do n = 1, num_avail_hist_fields_4Db nn = n4Dscum + n - if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then + if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then do k = 1, nzblyr do ic = 1, ncat_hist do j = jlo, jhi @@ -3738,7 +3205,7 @@ subroutine accum_hist (dt) !--------------------------------------------------------------- ! compute sig1 and sig2 - + call principal_stress (nx_block, ny_block, & stressp_1 (:,:,iblk), & stressm_1 (:,:,iblk), & diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 4940745c..aa478d73 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -83,6 +83,8 @@ module ice_history_shared real (kind=dbl_kind) :: conb ! additive conversion factor character (len=1) :: vhistfreq ! frequency of history output integer (kind=int_kind) :: vhistfreq_n ! number of vhistfreq intervals + logical (kind=log_kind) :: avg_ice_present ! only average where ice is present + logical (kind=log_kind) :: mask_ice_free_points ! mask ice-free points end type integer (kind=int_kind), parameter, public :: & @@ -271,6 +273,7 @@ module ice_history_shared f_sidmasslat = 'x', & f_sndmasssnf = 'x', & f_sndmassmelt = 'x', & + f_sndmassdyn = 'x', & f_sndmasssubl = 'x', & f_sidivvel = 'x', & f_siflswdtop = 'x', & @@ -397,12 +400,13 @@ module ice_history_shared f_sidmassgrowthbot, & f_sidmasssi, & f_sidmassevapsubl, & + f_sndmasssubl, & f_sidmassmelttop, & f_sidmassmeltbot, & f_sidmasslat, & f_sndmasssnf, & f_sndmassmelt, & - f_sndmasssubl, & + f_sndmassdyn, & f_siflswdtop, & f_siflswutop, & f_siflswdbot, & @@ -527,12 +531,13 @@ module ice_history_shared n_sidmasssi, & n_sidmasssubl, & n_sidmassevapsubl, & + n_sndmasssubl, & n_sidmassmelttop, & n_sidmassmeltbot, & n_sidmasslat, & n_sndmasssnf, & n_sndmassmelt, & - n_sndmasssubl, & + n_sndmassdyn, & n_siflswdtop, & n_siflswutop, & n_siflswdbot, & @@ -713,7 +718,7 @@ end subroutine construct_filename subroutine define_hist_field(id, vname, vunit, vcoord, vcellmeas, & vdesc, vcomment, cona, conb, & - ns, vhistfreq) + ns, vhistfreq, avg_ice_present, mask_ice_free_points) use ice_calendar, only: histfreq, histfreq_n, nstreams use ice_domain_size, only: max_nstrm @@ -741,12 +746,28 @@ subroutine define_hist_field(id, vname, vunit, vcoord, vcellmeas, & integer (kind=int_kind), intent(in) :: & ns ! history file stream index + logical (kind=log_kind), optional, intent(in) :: & + avg_ice_present , & ! compute average only when ice is present + mask_ice_free_points ! mask ice-free points + integer (kind=int_kind) :: & ns1 , & ! variable stream loop index lenf ! length of namelist string character (len=40) :: stmp + logical (kind=log_kind) :: & + l_avg_ice_present , & ! compute average only when ice is present + l_mask_ice_free_points ! mask ice-free points + + character(len=*), parameter :: subname = '(define_hist_field)' + + l_avg_ice_present = .false. + l_mask_ice_free_points = .false. + + if(present(avg_ice_present)) l_avg_ice_present = avg_ice_present + if(present(mask_ice_free_points)) l_mask_ice_free_points = mask_ice_free_points + if (histfreq(ns) == 'x') then call abort_ice("define_hist_fields has histfreq x") endif @@ -757,6 +778,10 @@ subroutine define_hist_field(id, vname, vunit, vcoord, vcellmeas, & do ns1 = 1, lenf if (vhistfreq(ns1:ns1) == histfreq(ns)) then + if (ns1 > 1 .and. index(vhistfreq(1:ns1-1),'x') /= 0) then + call abort_ice(subname//' ERROR: history frequency variable f_' // vname // ' can''t contain ''x'' along with active frequencies') + endif + num_avail_hist_fields_tot = num_avail_hist_fields_tot + 1 if (vcoord(11:14) == 'time') then @@ -805,6 +830,8 @@ subroutine define_hist_field(id, vname, vunit, vcoord, vcellmeas, & avail_hist_fields(id(ns))%conb = conb avail_hist_fields(id(ns))%vhistfreq = vhistfreq(ns1:ns1) avail_hist_fields(id(ns))%vhistfreq_n = histfreq_n(ns) + avail_hist_fields(id(ns))%avg_ice_present = l_avg_ice_present + avail_hist_fields(id(ns))%mask_ice_free_points = l_mask_ice_free_points endif enddo @@ -832,7 +859,7 @@ subroutine accum_hist_field_2D(id, iblk, field_accum, field) integer (int_kind), dimension(max_nstrm), intent(in) :: & id ! location in avail_fields array for use in ! later routines - + integer (kind=int_kind), intent(in) :: iblk real (kind=dbl_kind), intent(in) :: & @@ -903,7 +930,7 @@ subroutine accum_hist_field_3D(id, iblk, ndim, field_accum, field) integer (int_kind), dimension(max_nstrm), intent(in) :: & id ! location in avail_fields array for use in ! later routines - + integer (kind=int_kind), intent(in) :: iblk integer (kind=int_kind), intent(in) :: & @@ -967,7 +994,7 @@ subroutine accum_hist_field_4D(id, iblk, ndim3, ndim4, field_accum, field) integer (int_kind), dimension(max_nstrm), intent(in) :: & id ! location in avail_fields array for use in ! later routines - + integer (kind=int_kind), intent(in) :: iblk integer (kind=int_kind), intent(in) :: & From e26beb9181ed91ab35bc3a666f02c784772c1bad Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 21 Aug 2025 16:21:17 +1000 Subject: [PATCH 11/80] add sidmassgrowthsi (same as sidmasssi) --- source/ice_history.F90 | 23 +++++++++++++++++++++++ source/ice_history_shared.F90 | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index dd9bb6ea..b0df524c 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -352,6 +352,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_sidmassgrowthwat, master_task) call broadcast_scalar (f_sidmassgrowthbot, master_task) call broadcast_scalar (f_sidmasssi, master_task) + call broadcast_scalar (f_sidmassgrowthsi, master_task) call broadcast_scalar (f_sidmassevapsubl, master_task) call broadcast_scalar (f_sndmasssubl, master_task) call broadcast_scalar (f_sidmassmelttop, master_task) @@ -1150,6 +1151,7 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sidconcdyn) + !to-do: the next set of vars surely should be ice area weighted ? call define_hist_field(n_sidmassth,"sidmassth","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from thermodynamics", & "none", c1, c0, & @@ -1175,6 +1177,11 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sidmasssi) + call define_hist_field(n_sidmassgrowthsi,"sidmassgrowthsi","kg m^-2 s^-1",tstr2D, tcstr, & + "sea ice mass change from snow-ice formation", & + "none", c1, c0, & + ns1, f_sidmassgrowthsi) + call define_hist_field(n_sidmassevapsubl,"sidmassevapsubl","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from evaporation and sublimation", & "none", c1, c0, & @@ -2394,6 +2401,22 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmasssi, iblk, worka(:,:), a2D) endif + if (f_sidmassgrowthsi(1:1) /= 'x') then + !To-do: revisit to see if still needs aice/aice_init weighting + !to-do : divide by dt + worka(:,:) = c0 + do j = jlo, jhi + do i = ilo, ihi + if (aice_init(i,j,iblk) > puny) then + worka(i,j) = snoice(i,j,iblk)*rhoi/dt + ! worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi /& + ! (dt * aice_init(i,j,iblk)) + endif + enddo + enddo + call accum_hist_field(n_sidmassgrowthsi, iblk, worka(:,:), a2D) + endif + if (f_sidmassevapsubl(1:1) /= 'x') then !To-do: revisit to see if aice weighting is correct, looks like evap_ice is already weighted worka(:,:) = c0 diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index aa478d73..2d92363f 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -266,7 +266,7 @@ module ice_history_shared f_sidmassth = 'x', f_sidmassdyn = 'x', & f_sidmassgrowthwat = 'x', & f_sidmassgrowthbot = 'x', & - f_sidmasssi = 'x', & + f_sidmasssi = 'x', f_sidmassgrowthsi = 'x', & f_sidmassevapsubl = 'x', & f_sidmassmelttop = 'x', & f_sidmassmeltbot = 'x', & @@ -528,7 +528,7 @@ module ice_history_shared n_sidmassth , n_sidmassdyn, & n_sidmassgrowthwat, & n_sidmassgrowthbot, & - n_sidmasssi, & + n_sidmasssi, n_sidmassgrowthsi, & n_sidmasssubl, & n_sidmassevapsubl, & n_sndmasssubl, & From cb3bce8323b63eef6714030e005f3a48371e49af Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 21 Aug 2025 16:53:51 +1000 Subject: [PATCH 12/80] neaten formatting of history tape logging --- source/ice_history.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index b0df524c..d8bd6716 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1498,8 +1498,8 @@ subroutine init_hist (dt) enddo ! num_avail_hist_fields_tot write(nu_diag,*) ' ' endif - 100 format (1x,a40,2x,a16,2x,a12,1x,a1,2x,i6) - 101 format (2x,a19,10x,a16,9x,a12,2x,a,3x,a1) + 100 format (1x,a50,2x,a16,2x,a16,1x,a1,2x,i6) + 101 format (2x,a19,21x,a16,5x,a16,2x,a,3x,a1) call broadcast_array(ntmp, master_task) do ns = 1, nstreams From 8ae3a8bdcd353e7c8a4531ffa64b0a31a838b877 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 13:29:47 +1000 Subject: [PATCH 13/80] add sidmassmeltlat --- source/ice_history.F90 | 7 ++++++- source/ice_history_shared.F90 | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index d8bd6716..4067db87 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1207,6 +1207,11 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sidmasslat) + call define_hist_field(n_sidmasslat,"sidmasslat","kg m^-2 s^-1",tstr2D, tcstr, & + "sea ice mass change from lateral ice melt", & + "none", c1, c0, & + ns1, f_sidmassmeltlat) + call define_hist_field(n_sndmasssnf,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from snow fall", & "none", c1, c0, & @@ -2477,7 +2482,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmassmeltbot, iblk, worka(:,:), a2D) endif - if (f_sidmasslat(1:1) /= 'x') then + if (f_sidmasslat(1:1) /= 'x' .or. f_sidmassmeltlat(1:1) /= 'x') then !To-do: revisit to see if still needs aice/aice_init weighting !to-do : divide by dt worka(:,:) = c0 diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 2d92363f..23844c0a 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -266,11 +266,11 @@ module ice_history_shared f_sidmassth = 'x', f_sidmassdyn = 'x', & f_sidmassgrowthwat = 'x', & f_sidmassgrowthbot = 'x', & - f_sidmasssi = 'x', f_sidmassgrowthsi = 'x', & + f_sidmasssi = 'x', f_sidmassgrowthsi = 'x', & !same var, two names f_sidmassevapsubl = 'x', & f_sidmassmelttop = 'x', & f_sidmassmeltbot = 'x', & - f_sidmasslat = 'x', & + f_sidmasslat = 'x', f_sidmassmeltlat = 'x', & !same var, two names f_sndmasssnf = 'x', & f_sndmassmelt = 'x', & f_sndmassdyn = 'x', & @@ -403,7 +403,7 @@ module ice_history_shared f_sndmasssubl, & f_sidmassmelttop, & f_sidmassmeltbot, & - f_sidmasslat, & + f_sidmasslat, f_sidmassmeltlat,& f_sndmasssnf, & f_sndmassmelt, & f_sndmassdyn, & @@ -534,7 +534,7 @@ module ice_history_shared n_sndmasssubl, & n_sidmassmelttop, & n_sidmassmeltbot, & - n_sidmasslat, & + n_sidmasslat, & n_sndmasssnf, & n_sndmassmelt, & n_sndmassdyn, & From 4f24ad2520ed43ad467aa68bd8c52ab32a9f7336 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 13:33:41 +1000 Subject: [PATCH 14/80] fix namelist error handling --- source/ice_history.F90 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 4067db87..109c1a28 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -124,7 +124,8 @@ subroutine init_hist (dt) ! backspace and re-read erroneous line backspace(nu_nml) read(nu_nml,fmt='(A)') tmpstr2 - call abort_ice('ice ERROR: ' // trim(nml_name) // ' reading ') + call abort_ice('ice ERROR: ' // trim(nml_name) // ' reading '// & + trim(tmpstr2)) endif end do @@ -2116,8 +2117,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - worka(i,j) = (rhoi*p5*(vice(i+1,j,iblk)+vice(i,j,iblk))*HTE(i,j,iblk) & - + rhos*p5*(vsno(i+1,j,iblk)+vsno(i,j,iblk))*HTE(i,j,iblk)) & + worka(i,j) = p5*(rhoi*(vice(i+1,j,iblk)+vice(i,j,iblk))*HTE(i,j,iblk) & + + rhos*(vsno(i+1,j,iblk)+vsno(i,j,iblk))*HTE(i,j,iblk)) & * p5*(uvel(i,j-1,iblk)+uvel(i,j,iblk)) enddo enddo From 00dcd1571af10661f8c2ff95cba537136761534d Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 13:39:07 +1000 Subject: [PATCH 15/80] fix f_sidmassgrowthsi --- source/ice_history_shared.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 23844c0a..e8d2316f 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -398,7 +398,7 @@ module ice_history_shared f_sidmassth, f_sidmassdyn,& f_sidmassgrowthwat, & f_sidmassgrowthbot, & - f_sidmasssi, & + f_sidmasssi, f_sidmassgrowthsi & f_sidmassevapsubl, & f_sndmasssubl, & f_sidmassmelttop, & From 4f465459dc3019e916f87f1ce55f90887fc115d6 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 13:42:58 +1000 Subject: [PATCH 16/80] fix f_sidmassgrowthsi --- source/ice_history_shared.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index e8d2316f..170d9403 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -398,7 +398,7 @@ module ice_history_shared f_sidmassth, f_sidmassdyn,& f_sidmassgrowthwat, & f_sidmassgrowthbot, & - f_sidmasssi, f_sidmassgrowthsi & + f_sidmasssi, f_sidmassgrowthsi , & f_sidmassevapsubl, & f_sndmasssubl, & f_sidmassmelttop, & From b57d7ec43bc5414ed1b8a6b094c3ca78f07b4289 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 13:47:57 +1000 Subject: [PATCH 17/80] fix name for sidmassmeltlat and possible loop optimise of sidmasstran terms --- source/ice_history.F90 | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 109c1a28..8e40c1bf 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1208,7 +1208,7 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sidmasslat) - call define_hist_field(n_sidmasslat,"sidmasslat","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sidmasslat,"sidmassmeltlat","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from lateral ice melt", & "none", c1, c0, & ns1, f_sidmassmeltlat) @@ -2117,9 +2117,10 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - worka(i,j) = p5*(rhoi*(vice(i+1,j,iblk)+vice(i,j,iblk))*HTE(i,j,iblk) & - + rhos*(vsno(i+1,j,iblk)+vsno(i,j,iblk))*HTE(i,j,iblk)) & - * p5*(uvel(i,j-1,iblk)+uvel(i,j,iblk)) + worka(i,j) = p25*HTE(i,j,iblk)*( & + rhoi*(vice(i,j,iblk)+vice(i+1,j,iblk)) & + + rhos*(vsno(i,j,iblk)+vsno(i+1,j,iblk)) & + ) * (uvel(i,j-1,iblk)+uvel(i,j,iblk)) enddo enddo call accum_hist_field(n_sidmasstranx, iblk, worka(:,:), a2D) @@ -2130,12 +2131,13 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - worka(i,j) = (rhoi*p5*(vice(i,j+1,iblk)+vice(i,j,iblk))*HTN(i,j,iblk) & - + rhos*p5*(vsno(i,j+1,iblk)+vsno(i,j,iblk))*HTN(i,j,iblk)) & - * p5*(vvel(i-1,j,iblk)+vvel(i,j,iblk)) + worka(i,j) = p25*HTN(i,j,iblk)*( & + rhoi*(vice(i,j,iblk)+vice(i,j+1,iblk)) & + + rhos*(vsno(i,j,iblk)+vsno(i,j+1,iblk)) & + ) * (vvel(i-1,j,iblk)+vvel(i,j,iblk)) enddo enddo - call accum_hist_field(n_sidmasstrany, iblk, worka(:,:), a2D) + call accum_hist_field(n_sidmasstrany, iblk, worka(:,:), a2D) endif !to-do: use aice_init From a9cf7f72c33b13a302145be5ada5262bbc1ebe56 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 13:59:28 +1000 Subject: [PATCH 18/80] add siflsensbot --- source/ice_history.F90 | 8 +++++++- source/ice_history_shared.F90 | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 8e40c1bf..38c6d1c2 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -369,6 +369,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_sifllwutop, master_task) call broadcast_scalar (f_siflsenstop, master_task) call broadcast_scalar (f_siflsensupbot, master_task) + call broadcast_scalar (f_siflsensbot, master_task) call broadcast_scalar (f_sifllatstop, master_task) call broadcast_scalar (f_siflcondtop, master_task) call broadcast_scalar (f_siflcondbot, master_task) @@ -1263,6 +1264,11 @@ subroutine init_hist (dt) "positive downward", c1, c0, & ns1, f_siflsensupbot, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_siflsensupbot,"siflsensbot","W/m^2",tstr2D, tcstr, & + "sensible heat flux at bottom of sea ice", & + "positive downward", c1, c0, & + ns1, f_siflsensbot, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_sifllatstop,"sifllatstop","W/m^2",tstr2D, tcstr, & "latent heat flux over sea ice", & "positive downward", c1, c0, & @@ -2616,7 +2622,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_siflsenstop, iblk, worka(:,:), a2D) endif - if (f_siflsensupbot(1:1) /= 'x') then + if (f_siflsensupbot(1:1) /= 'x' .or. f_siflsensbot(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 170d9403..202a4660 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -282,7 +282,7 @@ module ice_history_shared f_sifllwdtop = 'x', & f_sifllwutop = 'x', & f_siflsenstop = 'x', & - f_siflsensupbot = 'x', & + f_siflsensupbot = 'x', f_siflsensbot = 'x', & !same var, two names f_sifllatstop = 'x', & f_siflcondtop = 'x', & f_siflcondbot = 'x', & @@ -413,7 +413,7 @@ module ice_history_shared f_sifllwdtop, & f_sifllwutop, & f_siflsenstop, & - f_siflsensupbot, & + f_siflsensupbot, f_siflsensbot, & f_sifllatstop, & f_siflcondtop, & f_siflcondbot, & From 003961c5cbbbeeba6eade391d829b0b781e62be4 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 14:23:45 +1000 Subject: [PATCH 19/80] simass and sisnmass --- source/ice_history.F90 | 35 +++++++++++++++++++++++++++++++++-- source/ice_history_shared.F90 | 3 +++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 38c6d1c2..b1c109ed 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -325,9 +325,11 @@ subroutine init_hist (dt) call broadcast_scalar (f_aisnap, master_task) call broadcast_scalar (f_hisnap, master_task) call broadcast_scalar (f_sithick, master_task) + call broadcast_scalar (f_simass, master_task) call broadcast_scalar (f_siage, master_task) call broadcast_scalar (f_sisnconc, master_task) call broadcast_scalar (f_sisnthick, master_task) + call broadcast_scalar (f_sisnmass, master_task) call broadcast_scalar (f_sitemptop, master_task) call broadcast_scalar (f_sitempsnic, master_task) call broadcast_scalar (f_sitempbot, master_task) @@ -339,7 +341,6 @@ subroutine init_hist (dt) call broadcast_scalar (f_sistrydtop, master_task) call broadcast_scalar (f_sistrxubot, master_task) call broadcast_scalar (f_sistryubot, master_task) - call broadcast_scalar (f_sicompstren, master_task) call broadcast_scalar (f_sispeed, master_task) call broadcast_scalar (f_sialb, master_task) @@ -1008,6 +1009,11 @@ subroutine init_hist (dt) "volume divided by area", c1, c0, & ns1, f_sithick, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_simass,"simass","kg m^-2",tstr2D, tcstr, & + "sea ice mass", & + "mass divided by area", c1, c0, & + ns1, f_simass, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_siage,"siage","s",tstr2D, tcstr, & "sea ice age", & "none", c1, c0, & @@ -1028,6 +1034,11 @@ subroutine init_hist (dt) "snow volume divided by area", c1, c0, & ns1, f_sisnthick, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_sisnmass,"sisnmass","m",tstr2D, tcstr, & + "snow mass per areas", & + "snow mass divided by area", c1, c0, & + ns1, f_sisnmass, avg_ice_present=.true., mask_ice_free_points=.true.) + call define_hist_field(n_sitemptop,"sitemptop","K",tstr2D, tcstr, & "sea ice surface temperature", & "none", c1, c0, & @@ -2018,6 +2029,16 @@ subroutine accum_hist (dt) call accum_hist_field(n_sithick, iblk, worka(:,:), a2D) endif + if (f_simass(1:1) /= 'x') then + worka(:,:) = c0 + do j = jlo, jhi + do i = ilo, ihi + if (aice(i,j,iblk) > puny) worka(i,j) = rhoi*vice(i,j,iblk) + enddo + enddo + call accum_hist_field(n_simass, iblk, worka(:,:), a2D) + endif + if (f_siage(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -2048,8 +2069,18 @@ subroutine accum_hist (dt) enddo enddo call accum_hist_field(n_sisnthick, iblk, worka(:,:), a2D) - endif + endif + if (f_sisnmass(1:1) /= 'x') then + worka(:,:) = c0 + do j = jlo, jhi + do i = ilo, ihi + if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & + worka(i,j) = vsno(i,j,iblk) * rhos + enddo + enddo + call accum_hist_field(n_sisnmass, iblk, worka(:,:), a2D) + endif if (f_sitemptop(1:1) /= 'x') then worka(:,:) = c0 diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 202a4660..e2176acc 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -248,6 +248,7 @@ module ice_history_shared f_iage = 'm', f_FY = 'm', & f_hisnap = 'm', f_aisnap = 'm', & f_sithick = 'x', f_sisnthick = 'x', & + f_simass = 'x', f_sisnmass = 'x', & f_sisnconc = 'x', f_siage = 'x', & f_sitemptop = 'x', f_sitempsnic = 'x', & f_sitempbot = 'x', f_sispeed = 'x', & @@ -379,6 +380,7 @@ module ice_history_shared f_iage, f_FY , & f_hisnap, f_aisnap , & f_sithick, f_sisnthick, & + f_simass, f_sisnmass, & f_sisnconc, f_siage, & f_sifb, & f_sitemptop, f_sitempsnic,& @@ -510,6 +512,7 @@ module ice_history_shared n_fsalt , n_fsalt_ai , & n_sidivvel, & n_sithick , n_sisnthick , & + n_simass , n_sisnmass , & n_sisnconc, n_siage, & n_sifb, & n_sitemptop , n_sitempsnic , & From 6daf21137d44c074caf44745703f7df09cf44de2 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 14:38:13 +1000 Subject: [PATCH 20/80] add siconc, fix sisnconc for aice weighting --- source/ice_history.F90 | 8 +++++++- source/ice_history_shared.F90 | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index b1c109ed..51a73b67 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -456,6 +456,11 @@ subroutine init_hist (dt) "ice area (aggregate)", & "none", c1, c0, & ns1, f_aice) + + call define_hist_field(n_aice,"siconc","1",tstr2D, tcstr, & + "sea ice area fraction", & + "none", c1, c0, & + ns1, f_siconc) call define_hist_field(n_uvel,"uvel","m/s",ustr2D, ucstr, & "ice velocity (x)", & @@ -1004,6 +1009,7 @@ subroutine init_hist (dt) ns1, f_FY) ! CMIP6 2D variables + ! check these definitions against the intensive/extensive/inst def in notz et al 2016 call define_hist_field(n_sithick,"sithick","m",tstr2D, tcstr, & "sea ice thickness", & "volume divided by area", c1, c0, & @@ -2054,7 +2060,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) worka(i,j) = snowfrac(i,j,iblk) + if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk) * snowfrac(i,j,iblk) enddo enddo call accum_hist_field(n_sisnconc, iblk, worka(:,:), a2D) diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index e2176acc..8c5db227 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -198,7 +198,8 @@ module ice_history_shared ! f_example = 'md', & f_hi = 'm', f_hs = 'm', & f_snowfrac = 'x', f_snowfracn = 'x', & - f_Tsfc = 'm', f_aice = 'm', & + f_Tsfc = 'm', & + f_aice = 'm', f_siconc = 'x' , & !same var, two names f_uvel = 'm', f_vvel = 'm', & f_uatm = 'm', f_vatm = 'm', & f_fswdn = 'm', f_flwdn = 'm', & @@ -380,6 +381,7 @@ module ice_history_shared f_iage, f_FY , & f_hisnap, f_aisnap , & f_sithick, f_sisnthick, & + f_siconc, & f_simass, f_sisnmass, & f_sisnconc, f_siage, & f_sifb, & From 2c26cfc6a3336560815ed9107799218e64e931c4 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 16:06:39 +1000 Subject: [PATCH 21/80] fix siconc --- source/ice_history.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 51a73b67..02bee039 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -234,6 +234,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_snowfracn, master_task) call broadcast_scalar (f_Tsfc, master_task) call broadcast_scalar (f_aice, master_task) + call broadcast_scalar (f_siconc, master_task) call broadcast_scalar (f_uvel, master_task) call broadcast_scalar (f_vvel, master_task) call broadcast_scalar (f_uatm, master_task) From aec5e8da210f8e6be2d03401a504d8ea6ce128c6 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 22 Aug 2025 16:07:10 +1000 Subject: [PATCH 22/80] sisndmassdyn --- source/ice_history.F90 | 15 +++++++++++---- source/ice_history_shared.F90 | 8 ++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 02bee039..17c1df7a 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -364,6 +364,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_sndmasssnf, master_task) call broadcast_scalar (f_sndmassmelt, master_task) call broadcast_scalar (f_sndmassdyn, master_task) + call broadcast_scalar (f_sisndmassdyn, master_task) call broadcast_scalar (f_siflswdtop, master_task) call broadcast_scalar (f_siflswutop, master_task) call broadcast_scalar (f_siflswdbot, master_task) @@ -1243,10 +1244,15 @@ subroutine init_hist (dt) ns1, f_sndmassmelt) call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & - "snow mass change from dynamics ridging", & + "snow mass change from dynamics (advection)", & "none", c1, c0, & ns1, f_sndmassdyn) + call define_hist_field(n_sndmassdyn,"sisndmassdyn","kg m-2 s-1",tstr2D, tcstr, & + "snow mass rate of change through advection by sea ice dynamics", & + "none", c1, c0, & + ns1, f_sisndmassdyn) + call define_hist_field(n_siflswdtop,"siflswdtop","W/m2",tstr2D, tcstr, & "down shortwave flux over sea ice", & "positive downward", c1, c0, & @@ -1782,7 +1788,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_snowfrac, iblk, snowfrac(:,:,iblk), a2D) if (f_Tsfc (1:1) /= 'x') & call accum_hist_field(n_Tsfc, iblk, trcr(:,:,nt_Tsfc,iblk), a2D) - if (f_aice (1:1) /= 'x') & + if (f_aice (1:1) /= 'x' .or. f_siconc (1:1) /= 'x') & call accum_hist_field(n_aice, iblk, aice(:,:,iblk), a2D) if (f_uvel (1:1) /= 'x') & call accum_hist_field(n_uvel, iblk, uvel(:,:,iblk), a2D) @@ -2061,7 +2067,8 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk) * snowfrac(i,j,iblk) + if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk) * snowfrac(i,j,iblk) enddo enddo call accum_hist_field(n_sisnconc, iblk, worka(:,:), a2D) @@ -2575,7 +2582,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sndmassmelt, iblk, worka(:,:), a2D) endif - if (f_sndmassdyn(1:1) /= 'x') then + if (f_sndmassdyn(1:1) /= 'x' .or. f_sisndmassdyn(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 8c5db227..649d77fb 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -275,7 +275,7 @@ module ice_history_shared f_sidmasslat = 'x', f_sidmassmeltlat = 'x', & !same var, two names f_sndmasssnf = 'x', & f_sndmassmelt = 'x', & - f_sndmassdyn = 'x', & + f_sndmassdyn = 'x', f_sisndmassdyn = 'x', & f_sndmasssubl = 'x', & f_sidivvel = 'x', & f_siflswdtop = 'x', & @@ -331,7 +331,8 @@ module ice_history_shared ! f_example , & f_hi, f_hs , & f_snowfrac, f_snowfracn, & - f_Tsfc, f_aice , & + f_Tsfc , & + f_aice , f_siconc , & f_uvel, f_vvel , & f_uatm, f_vatm , & f_fswdn, f_flwdn , & @@ -381,7 +382,6 @@ module ice_history_shared f_iage, f_FY , & f_hisnap, f_aisnap , & f_sithick, f_sisnthick, & - f_siconc, & f_simass, f_sisnmass, & f_sisnconc, f_siage, & f_sifb, & @@ -410,7 +410,7 @@ module ice_history_shared f_sidmasslat, f_sidmassmeltlat,& f_sndmasssnf, & f_sndmassmelt, & - f_sndmassdyn, & + f_sndmassdyn, f_sisndmassdyn, & f_siflswdtop, & f_siflswutop, & f_siflswdbot, & From 77622b30cd68ee4f74fc835559a922cd64ee7fca Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 5 Sep 2025 15:44:22 +1000 Subject: [PATCH 23/80] some fixes and add sisndmasssi --- source/ice_history.F90 | 35 ++++++++++++++++++++--------------- source/ice_history_shared.F90 | 11 +++++++---- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 17c1df7a..883f7194 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -363,6 +363,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_sidmasslat, master_task) call broadcast_scalar (f_sndmasssnf, master_task) call broadcast_scalar (f_sndmassmelt, master_task) + call broadcast_scalar (f_sisndmassmelt, master_task) call broadcast_scalar (f_sndmassdyn, master_task) call broadcast_scalar (f_sisndmassdyn, master_task) call broadcast_scalar (f_siflswdtop, master_task) @@ -1198,7 +1199,7 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sidmasssi) - call define_hist_field(n_sidmassgrowthsi,"sidmassgrowthsi","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sidmasssi,"sidmassgrowthsi","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from snow-ice formation", & "none", c1, c0, & ns1, f_sidmassgrowthsi) @@ -1241,17 +1242,27 @@ subroutine init_hist (dt) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from melt", & "none", c1, c0, & - ns1, f_sndmassmelt) + ns1, f_sndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) + + call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & + "snow mass change from melt", & + "none", c1, c0, & + ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) + + call define_hist_field(n_sndmassmelt,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & + "snow mass change through snow to ice conversion", & + "none", c1, c0, & + ns1, f_sisndmasssi, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & "snow mass change from dynamics (advection)", & "none", c1, c0, & - ns1, f_sndmassdyn) + ns1, f_sndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sisndmassdyn","kg m-2 s-1",tstr2D, tcstr, & "snow mass rate of change through advection by sea ice dynamics", & "none", c1, c0, & - ns1, f_sisndmassdyn) + ns1, f_sisndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdtop,"siflswdtop","W/m2",tstr2D, tcstr, & "down shortwave flux over sea ice", & @@ -1318,7 +1329,6 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sipr, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflsaltbot,"siflsaltbot","kg m^-2 s^-1",tstr2D, tcstr, & "salt flux from sea ice", & "positive downward", c1, c0, & @@ -2444,7 +2454,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmassgrowthbot, iblk, worka(:,:), a2D) endif - if (f_sidmasssi(1:1) /= 'x') then + if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') then !To-do: revisit to see if still needs aice/aice_init weighting !to-do : divide by dt worka(:,:) = c0 @@ -2460,20 +2470,16 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmasssi, iblk, worka(:,:), a2D) endif - if (f_sidmassgrowthsi(1:1) /= 'x') then - !To-do: revisit to see if still needs aice/aice_init weighting - !to-do : divide by dt + if (f_sisndmasssi(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then - worka(i,j) = snoice(i,j,iblk)*rhoi/dt - ! worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi /& - ! (dt * aice_init(i,j,iblk)) + worka(i,j) = -c1*snoice(i,j,iblk)*rhoi/dt endif enddo enddo - call accum_hist_field(n_sidmassgrowthsi, iblk, worka(:,:), a2D) + call accum_hist_field(n_sisndmasssi, iblk, worka(:,:), a2D) endif if (f_sidmassevapsubl(1:1) /= 'x') then @@ -2538,7 +2544,6 @@ subroutine accum_hist (dt) if (f_sidmasslat(1:1) /= 'x' .or. f_sidmassmeltlat(1:1) /= 'x') then !To-do: revisit to see if still needs aice/aice_init weighting - !to-do : divide by dt worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2566,7 +2571,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sndmasssnf, iblk, worka(:,:), a2D) endif - if (f_sndmassmelt(1:1) /= 'x') then + if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') then !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 649d77fb..dce24a40 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -274,8 +274,9 @@ module ice_history_shared f_sidmassmeltbot = 'x', & f_sidmasslat = 'x', f_sidmassmeltlat = 'x', & !same var, two names f_sndmasssnf = 'x', & - f_sndmassmelt = 'x', & - f_sndmassdyn = 'x', f_sisndmassdyn = 'x', & + f_sndmassmelt = 'x', f_sisndmassmelt = 'x', & !same var, two names + f_sndmassdyn = 'x', f_sisndmassdyn = 'x', & !same var, two names + f_sisndmasssi = 'x', & f_sndmasssubl = 'x', & f_sidivvel = 'x', & f_siflswdtop = 'x', & @@ -409,8 +410,9 @@ module ice_history_shared f_sidmassmeltbot, & f_sidmasslat, f_sidmassmeltlat,& f_sndmasssnf, & - f_sndmassmelt, & + f_sndmassmelt, f_sisndmassmelt, & f_sndmassdyn, f_sisndmassdyn, & + f_sisndmasssi, & f_siflswdtop, & f_siflswutop, & f_siflswdbot, & @@ -533,7 +535,7 @@ module ice_history_shared n_sidmassth , n_sidmassdyn, & n_sidmassgrowthwat, & n_sidmassgrowthbot, & - n_sidmasssi, n_sidmassgrowthsi, & + n_sidmasssi, & n_sidmasssubl, & n_sidmassevapsubl, & n_sndmasssubl, & @@ -543,6 +545,7 @@ module ice_history_shared n_sndmasssnf, & n_sndmassmelt, & n_sndmassdyn, & + n_sisndmasssi, & n_siflswdtop, & n_siflswutop, & n_siflswdbot, & From 6eb67cd9be1e1f2e534e97b5cd842a3bb75b8da4 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 5 Sep 2025 16:31:11 +1000 Subject: [PATCH 24/80] sisndmasssnf? --- source/ice_history.F90 | 19 ++++++++++++++----- source/ice_history_shared.F90 | 4 ++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 883f7194..b1158daa 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -362,6 +362,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_sidmassmeltbot, master_task) call broadcast_scalar (f_sidmasslat, master_task) call broadcast_scalar (f_sndmasssnf, master_task) + call broadcast_scalar (f_sisndmasssnf, master_task) call broadcast_scalar (f_sndmassmelt, master_task) call broadcast_scalar (f_sisndmassmelt, master_task) call broadcast_scalar (f_sndmassdyn, master_task) @@ -1237,7 +1238,12 @@ subroutine init_hist (dt) call define_hist_field(n_sndmasssnf,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from snow fall", & "none", c1, c0, & - ns1, f_sndmasssnf) + ns1, f_sndmasssnf, avg_ice_present=.true., mask_ice_free_points=.true.) + + call define_hist_field(n_sndmasssnf,"sisndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & + "snow mass change from snow fall", & + "none", c1, c0, & + ns1, f_sisndmasssnf, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from melt", & @@ -2471,6 +2477,8 @@ subroutine accum_hist (dt) endif if (f_sisndmasssi(1:1) /= 'x') then + !To-do: calculate a seperate icesno diag for change in snow thickness in ice_therm_vertical ? + ! Its equivalent though, so fairly moot worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2558,13 +2566,14 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmasslat, iblk, worka(:,:), a2D) endif - if (f_sndmasssnf(1:1) /= 'x') then - !to-do: CICE6 does not include rhos - worka(:,:) = c0 + if (f_sndmasssnf(1:1) /= 'x' .or. f_sisndmasssnf(1:1) /= 'x') then + !to-do: fsnow seems to already be multiplied by aice - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/drivers/access/cpl_forcing_handler.F90#L702-L703 + !and then unweighted again - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/source/ice_step_mod.F90#L331-L332 + !therefore i will weight again. in theory should weight by aice_init so it from the same time as the incoming flux ? do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk) * fsnow(i,j,iblk) * rhos + worka(i,j) = aice(i,j,iblk)*fsnow(i,j,iblk) endif enddo enddo diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index dce24a40..9ab50b5c 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -273,7 +273,7 @@ module ice_history_shared f_sidmassmelttop = 'x', & f_sidmassmeltbot = 'x', & f_sidmasslat = 'x', f_sidmassmeltlat = 'x', & !same var, two names - f_sndmasssnf = 'x', & + f_sndmasssnf = 'x', f_sisndmasssnf = 'x', & !same var, two names f_sndmassmelt = 'x', f_sisndmassmelt = 'x', & !same var, two names f_sndmassdyn = 'x', f_sisndmassdyn = 'x', & !same var, two names f_sisndmasssi = 'x', & @@ -409,7 +409,7 @@ module ice_history_shared f_sidmassmelttop, & f_sidmassmeltbot, & f_sidmasslat, f_sidmassmeltlat,& - f_sndmasssnf, & + f_sndmasssnf, f_sisndmasssnf, & f_sndmassmelt, f_sisndmassmelt, & f_sndmassdyn, f_sisndmassdyn, & f_sisndmasssi, & From 8e65dec025153c5c4f10cd122bdb91566e2ef05d Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 15 Sep 2025 13:30:14 +1000 Subject: [PATCH 25/80] add sisndmasssubl, although probably 0 for zero-layer thermodynamics? --- source/ice_history.F90 | 7 ++++++- source/ice_history_shared.F90 | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index b1158daa..bcbea31c 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1215,6 +1215,11 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sndmasssubl) + call define_hist_field(n_sndmasssubl,"sisndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & + "snow mass change from evaporation and sublimation", & + "none", c1, c0, & + ns1, f_sisndmasssubl) + call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from top ice melt", & "none", c1, c0, & @@ -2504,7 +2509,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmassevapsubl, iblk, worka(:,:), a2D) endif - if (f_sndmasssubl(1:1) /= 'x') then + if (f_sndmasssubl(1:1) /= 'x' .or. f_sisndmasssubl(1:1) /= 'x') then !To-do: revisit to see if aice weighting is correct, looks like evap_snow is already weighted worka(:,:) = c0 do j = jlo, jhi diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 9ab50b5c..b2455c5f 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -277,7 +277,7 @@ module ice_history_shared f_sndmassmelt = 'x', f_sisndmassmelt = 'x', & !same var, two names f_sndmassdyn = 'x', f_sisndmassdyn = 'x', & !same var, two names f_sisndmasssi = 'x', & - f_sndmasssubl = 'x', & + f_sndmasssubl = 'x', f_sisndmasssubl = 'x', & !same var, two names f_sidivvel = 'x', & f_siflswdtop = 'x', & f_siflswutop = 'x', & @@ -405,7 +405,7 @@ module ice_history_shared f_sidmassgrowthbot, & f_sidmasssi, f_sidmassgrowthsi , & f_sidmassevapsubl, & - f_sndmasssubl, & + f_sndmasssubl, f_sisndmasssubl, & f_sidmassmelttop, & f_sidmassmeltbot, & f_sidmasslat, f_sidmassmeltlat,& From 8f6f2061710eabc5435fb4a5f369819fb9290b25 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 15 Sep 2025 14:50:45 +1000 Subject: [PATCH 26/80] sitimefrac --- source/ice_history.F90 | 14 ++++++++++---- source/ice_history_shared.F90 | 6 ++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index bcbea31c..23ba9f0a 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -395,6 +395,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_vsnon, master_task) call broadcast_scalar (f_trsig, master_task) call broadcast_scalar (f_icepresent, master_task) + call broadcast_scalar (f_sitimefrac, master_task) call broadcast_scalar (f_fsurf_ai, master_task) call broadcast_scalar (f_fcondtop_ai, master_task) call broadcast_scalar (f_fmeltt_ai, master_task) @@ -927,6 +928,11 @@ subroutine init_hist (dt) "ice extent flag", c1, c0, & ns1, f_icepresent) + call define_hist_field(n_icepresent,"ice_present","1",tstr2D, tcstr, & + "fraction of time-avg interval that ice is present", & + "ice extent flag", c1, c0, & + ns1, f_sitimefrac) + call define_hist_field(n_fsurf_ai,"fsurf_ai","W/m^2",tstr2D, tcstr, & "net surface heat flux", & "positive downward, excludes conductive flux, weighted by ice area", & @@ -1013,7 +1019,7 @@ subroutine init_hist (dt) ns1, f_FY) ! CMIP6 2D variables - ! check these definitions against the intensive/extensive/inst def in notz et al 2016 + ! check these definitions against the intensive/extensive/inst def in notz et al 2016 call define_hist_field(n_sithick,"sithick","m",tstr2D, tcstr, & "sea ice thickness", & "volume divided by area", c1, c0, & @@ -2040,7 +2046,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_fcondtop_ai, iblk, & fcondtop(:,:,iblk)*workb(:,:), a2D) - if (f_icepresent(1:1) /= 'x') then + if (f_icepresent(1:1) /= 'x' .or. f_sitimefrac(1:1) /= 'x') then worka(:,:) = c0 area_threshold = max(a_min,aicenmin) do j = jlo, jhi @@ -2212,7 +2218,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmasstrany, iblk, worka(:,:), a2D) endif - !to-do: use aice_init + !to-do: scale by aice/aice_init as its a calculated based on initial state ? if (f_sistrxdtop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -2224,7 +2230,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sistrxdtop, iblk, worka(:,:), a2D) endif - !to-do: use aice_init + !to-do: scale by aice/aice_init ? if (f_sistrydtop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index b2455c5f..1d71d271 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -296,7 +296,8 @@ module ice_history_shared f_sisaltmass = 'x', & f_aicen = 'x', f_vicen = 'x', & f_vsnon = 'x', & - f_trsig = 'm', f_icepresent = 'm', & + f_trsig = 'm', & + f_icepresent = 'm', f_sitimefrac = 'x',& f_fsurf_ai = 'm', f_fcondtop_ai= 'm', & f_fmeltt_ai = 'm', & f_fsurfn_ai = 'x' ,f_fcondtopn_ai='x', & @@ -430,7 +431,8 @@ module ice_history_shared f_sisaltmass, & f_aicen, f_vicen , & f_vsnon, & - f_trsig, f_icepresent,& + f_trsig, & + f_icepresent, f_sitimefrac,& !same var, two names f_fsurf_ai, f_fcondtop_ai,& f_fmeltt_ai, & f_fsurfn_ai,f_fcondtopn_ai,& From fe5e7a0fe0d32fb6db5a8ad01063c835d2e8e5e1 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 15 Sep 2025 15:37:17 +1000 Subject: [PATCH 27/80] sivol --- source/ice_history.F90 | 7 ++++++- source/ice_history_shared.F90 | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 23ba9f0a..ea0b3b91 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -443,6 +443,11 @@ subroutine init_hist (dt) "ice volume per unit grid cell area", c1, c0, & ns1, f_hi) + call define_hist_field(n_hi,"hi","m",tstr2D, tcstr, & + "grid cell mean ice thickness", & + "ice volume per unit grid cell area", c1, c0, & + ns1, f_sivol) + call define_hist_field(n_hs,"hs","m",tstr2D, tcstr, & "grid cell mean snow thickness", & "snow volume per unit grid cell area", c1, c0, & @@ -1805,7 +1810,7 @@ subroutine accum_hist (dt) ! if (f_example(1:1) /= 'x') & ! call accum_hist_field(n_example,iblk, vice(:,:,iblk), a2D) - if (f_hi (1:1) /= 'x') & + if (f_hi (1:1) /= 'x' .or. f_sivol(1:1) /= 'x') & call accum_hist_field(n_hi, iblk, vice(:,:,iblk), a2D) if (f_hs (1:1) /= 'x') & call accum_hist_field(n_hs, iblk, vsno(:,:,iblk), a2D) diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 1d71d271..f73b908d 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -196,7 +196,8 @@ module ice_history_shared character (len=max_nstrm), public :: & ! f_example = 'md', & - f_hi = 'm', f_hs = 'm', & + f_hi = 'm', f_sivol = 'x', & + f_hs = 'm', & f_snowfrac = 'x', f_snowfracn = 'x', & f_Tsfc = 'm', & f_aice = 'm', f_siconc = 'x' , & !same var, two names @@ -331,7 +332,8 @@ module ice_history_shared f_VGRDi , f_VGRDs , & f_VGRDb , & ! f_example , & - f_hi, f_hs , & + f_hi , f_sivol , & + f_hs , & f_snowfrac, f_snowfracn, & f_Tsfc , & f_aice , f_siconc , & From 061fadad0aa19280d39d5c956ab501751e167a17 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 15 Sep 2025 16:59:46 +1000 Subject: [PATCH 28/80] notes --- source/ice_history.F90 | 13 +++---------- source/ice_history_shared.F90 | 2 +- source/ice_itd.F90 | 4 ++-- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index ea0b3b91..70551602 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2478,7 +2478,6 @@ subroutine accum_hist (dt) if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') then !To-do: revisit to see if still needs aice/aice_init weighting - !to-do : divide by dt worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2507,13 +2506,11 @@ subroutine accum_hist (dt) endif if (f_sidmassevapsubl(1:1) /= 'x') then - !To-do: revisit to see if aice weighting is correct, looks like evap_ice is already weighted worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = evap_ice(i,j,iblk)*rhoi - ! worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk)*rhoi + worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk)*rhoi endif enddo enddo @@ -2521,13 +2518,11 @@ subroutine accum_hist (dt) endif if (f_sndmasssubl(1:1) /= 'x' .or. f_sisndmasssubl(1:1) /= 'x') then - !To-do: revisit to see if aice weighting is correct, looks like evap_snow is already weighted worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = rhos*evap_snow(i,j,iblk)/dt - ! worka(i,j) = rhos*aice(i,j,iblk)*evap_snow(i,j,iblk) + worka(i,j) = rhos*aice(i,j,iblk)*evap_snow(i,j,iblk) endif enddo enddo @@ -2862,7 +2857,6 @@ subroutine accum_hist (dt) if (f_vsnon (1:1) /= 'x') & call accum_hist_field(n_vsnon-n2D, iblk, ncat_hist, & vsnon(:,:,1:ncat_hist,iblk), a3Dc) - !to-do: check aicen ! if (f_snowfracn(1:1) /= 'x') & call accum_hist_field(n_snowfracn-n2D, iblk, ncat_hist, & snowfracn(:,:,1:ncat_hist,iblk)*aicen(:,:,:,iblk), a3Dc) @@ -3037,8 +3031,7 @@ subroutine accum_hist (dt) !to-do: figure out how to make sure n_aice actually exists do j = jlo, jhi do i = ilo, ihi - ! Alex West - enforce time mean ice area threshold based - ! on + ! Alex West - enforce time mean ice area threshold based on ! the maximum of aicenmin (thermodynamic min ice fraction) ! and a_min (dynamic min ice fraction) so that intensive ! variables are reported only where both dynamics and diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index f73b908d..c0eee3a3 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -200,7 +200,7 @@ module ice_history_shared f_hs = 'm', & f_snowfrac = 'x', f_snowfracn = 'x', & f_Tsfc = 'm', & - f_aice = 'm', f_siconc = 'x' , & !same var, two names + f_aice = 'm', f_siconc = 'x' , & !same var, two names, !to-do: what happens if I try to save both ? f_uvel = 'm', f_vvel = 'm', & f_uatm = 'm', f_vatm = 'm', & f_fswdn = 'm', f_flwdn = 'm', & diff --git a/source/ice_itd.F90 b/source/ice_itd.F90 index 5d561029..e6a911c8 100755 --- a/source/ice_itd.F90 +++ b/source/ice_itd.F90 @@ -242,8 +242,8 @@ subroutine init_itd (calc_Tsfc, heat_capacity) ! Alex West: added these two ar hi_min = p2 ! 0.2m hs_min = p1 ! 0.1m else - ! aicenmin = puny ! Standard CICE setting - aicenmin = 2.0e-4_dbl_kind ! Same as setting in UM7.3 for ESM1.6 + aicenmin = puny ! Standard CICE setting + ! aicenmin = 2.0e-4_dbl_kind ! Same as setting in UM7.3 for ESM1.6 endif if (my_task == master_task) then From d0a7db6363635627315f0711ffd8b1a14d419362 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 22 Sep 2025 15:16:27 +1000 Subject: [PATCH 29/80] fix my bugs --- drivers/access/CICE_RunMod.F90 | 17 ++++----- drivers/access/cpl_forcing_handler.F90 | 4 +- drivers/access/cpl_interface.F90 | 53 +++++++++++++------------- source/ice_history.F90 | 39 ++++++++++++------- source/ice_history_shared.F90 | 3 +- source/ice_read_write.F90 | 27 +++++++++++++ 6 files changed, 90 insertions(+), 53 deletions(-) diff --git a/drivers/access/CICE_RunMod.F90 b/drivers/access/CICE_RunMod.F90 index adf71938..01e2ef72 100644 --- a/drivers/access/CICE_RunMod.F90 +++ b/drivers/access/CICE_RunMod.F90 @@ -62,14 +62,13 @@ subroutine CICE_Run use ice_timers, only: ice_timer_start, & ice_timer_stop, timer_couple, timer_step, & timer_from_atm, timer_into_atm, timer_from_ocn, timer_into_ocn - use ice_grid, only: t2ugrid_vector, u2tgrid_vector + use ice_grid, only: t2ugrid_vector integer (kind=int_kind) :: time_sec, itap, icpl_ai, tmp_time integer (kind=int_kind) :: rtimestamp_ai, stimestamp_ai integer (kind=int_kind) :: rtimestamp_io, stimestamp_io !receive and send timestamps (seconds) integer (kind=int_kind) :: imon - logical :: write_tmp_dump = .true. #endif !-------------------------------------------------------------------- @@ -88,13 +87,13 @@ subroutine CICE_Run write(il_out,*)' runtime, runtime0 = ',runtime, runtime0 time_sec = 0 - + DO icpl_ai = 1, num_cpl_ai !begin A <==> I coupling iterations !receive a2i fields rtimestamp_ai = time_sec !call ice_timer_start(timer_from_atm) ! atm/ice coupling - write(il_out,*)' calling from_atm at icpl_ai, time_sec = ', icpl_ai, time_sec + ! write(il_out,*)' calling from_atm at icpl_ai, time_sec = ', icpl_ai, time_sec !=========================== call from_atm(rtimestamp_ai) !=========================== @@ -116,8 +115,8 @@ subroutine CICE_Run call t2ugrid_vector(io_strsu) call t2ugrid_vector(io_strsv) - write(il_out,'(a,3i10)') & - ' calling into_ocn at icpl_ai, itap, time_sec = ', icpl_ai, itap, time_sec + ! write(il_out,'(a,3i10)') & + ! ' calling into_ocn at icpl_ai, itap, time_sec = ', icpl_ai, itap, time_sec !call ice_timer_start(timer_into_ocn) ! atm/ocn coupling !=========================== !call check_iceberg_fields('chk_iceberg_i2o.nc') @@ -142,7 +141,7 @@ subroutine CICE_Run if (dump_last .and. (itap == num_ice_ai) .and. (icpl_ai == num_cpl_ai)) then write_restart = 1 endif - + !*** ice "update" ***! call ice_step @@ -161,8 +160,8 @@ subroutine CICE_Run stimestamp_ai = time_sec - write(il_out,'(a,3i10)') & - ' calling into_atm at icpl_ai, itap, time_sec = ',icpl_ai, itap, time_sec + ! write(il_out,'(a,3i10)') & + ! ' calling into_atm at icpl_ai, itap, time_sec = ',icpl_ai, itap, time_sec !=========================== call into_atm(stimestamp_ai) !=========================== diff --git a/drivers/access/cpl_forcing_handler.F90 b/drivers/access/cpl_forcing_handler.F90 index 62a755c0..85660c6d 100644 --- a/drivers/access/cpl_forcing_handler.F90 +++ b/drivers/access/cpl_forcing_handler.F90 @@ -424,9 +424,9 @@ subroutine get_lice_discharge(fname) case (4); myvar = 'FICEBERG_GC3_AVE' end select write(il_out,*)'(get_lice_discharge), iceberg = ', iceberg - write(il_out,'(a,a)') '(get_lice_discharge) reading in iceberg data, myvar= ',trim(myvar) + ! write(il_out,'(a,a)') '(get_lice_discharge) reading in iceberg data, myvar= ',trim(myvar) do im = 1, 12 - write(il_out,*) '(get_lice_discharge) reading in data, month= ',im + ! write(il_out,*) '(get_lice_discharge) reading in data, month= ',im call ice_read_nc(ncid_i2o, im, trim(myvar), vwork, dbug) ! Restrict iceberg fluxes to ocean points diff --git a/drivers/access/cpl_interface.F90 b/drivers/access/cpl_interface.F90 index 34e324b5..0f2052a4 100644 --- a/drivers/access/cpl_interface.F90 +++ b/drivers/access/cpl_interface.F90 @@ -92,24 +92,23 @@ subroutine prism_init ! Initialise MPI mpiflag = .FALSE. call MPI_Initialized (mpiflag, ierror) - print *,'CICE: (prism_init) BF MPI_INIT, mpiflag = ',mpiflag + ! print *,'CICE: (prism_init) BF MPI_INIT, mpiflag = ',mpiflag if ( .not. mpiflag ) then call MPI_INIT(ierror) endif call MPI_Initialized (mpiflag, ierror) - print *, 'CICE: (prism_init) AF MPI_INIT, mpiflag = ',mpiflag + ! print *, 'CICE: (prism_init) AF MPI_INIT, mpiflag = ',mpiflag - print * - print *, 'CICE: (prism_init) calling prism_init_comp_proto...' + ! print *, 'CICE: (prism_init) calling prism_init_comp_proto...' call prism_init_comp_proto (il_comp_id, cp_modnam, ierror) if (ierror /= PRISM_Ok) then call prism_abort_proto(il_comp_id, 'cice prism_init','STOP 1') - else - print *, 'CICE: (prism_init) called prism_init_comp_proto !' + ! else + ! if ( my_task == master_task ) print *, 'CICE: (prism_init) called prism_init_comp_proto !' endif !B: the following part may not be really needed(?) @@ -132,8 +131,8 @@ subroutine prism_init if (ierror /= PRISM_Ok) then print *, 'CICE: (prism_init) Error in MPI_Buffer_Attach.' call prism_abort_proto(il_comp_id, 'cice prism_init','STOP 2') - else - print *, 'CICE: (prism_init) MPI_Buffer_Attach ok!' + ! else + ! print *, 'CICE: (prism_init) MPI_Buffer_Attach ok!' endif ! ! PSMILe attribution of local communicator. @@ -147,7 +146,7 @@ subroutine prism_init print *, 'CICE: Error in prism_get_localcomm_proto' call prism_abort_proto(il_comp_id, 'cice prism_init','STOP 3') else - print *, 'CICE: _get_localcomm_ OK! il_commlocal= ',il_commlocal + if ( my_task == master_task ) print *, 'CICE: _get_localcomm_ OK! il_commlocal= ',il_commlocal endif ! @@ -155,13 +154,13 @@ subroutine prism_init ! ! print *, '* CICE: Entering init_cpl.....' - print *, '* CICE (prism_init) calling MPI_Comm_Size ...' + !print *, '* CICE (prism_init) calling MPI_Comm_Size ...' call MPI_Comm_Size(il_commlocal, il_nbtotproc, ierror) - print *, '* CICE (prism_init) calling MPI_Comm_Rank ...' + !print *, '* CICE (prism_init) calling MPI_Comm_Rank ...' call MPI_Comm_Rank(il_commlocal, my_task, ierror) - print *, '* CICE (prism_init) il_commlocal, il_nbtotproc, my_task = ' - print *, '* CICE (prism_init) ', il_commlocal, il_nbtotproc, my_task + if ( my_task == master_task ) print *, '* CICE (prism_init) il_commlocal, il_nbtotproc, my_task = ' + if ( my_task == master_task ) print *, '* CICE (prism_init) ', il_commlocal, il_nbtotproc, my_task ! il_nbcplproc = il_nbtotproc !multi-process coupling (real parallel cpl)! !il_nbcplproc = 1 !mono process coupling @@ -258,18 +257,18 @@ subroutine init_cpl ! end do !!debug - if (my_task == 0) then - write(il_out,*) "all block info:" - do iblk=1,nblocks_tot - this_block = get_block(iblk,iblk) - ilo = this_block%ilo - ihi = this_block%ihi - jlo = this_block%jlo - jhi = this_block%jhi - write(il_out,*) ' this block: cpu, iblock, jblock=', distrb_info%blockLocation(iblk)-1, this_block%iblock, this_block%jblock - write(il_out,*) ' block:', iblk, "gilo, gjlo, gihi, gjhi=", this_block%i_glob(ilo), this_block%j_glob(jlo), this_block%i_glob(ihi), this_block%j_glob(jhi) - end do - end if + ! if (my_task == 0) then + ! write(il_out,*) "all block info:" + ! do iblk=1,nblocks_tot + ! this_block = get_block(iblk,iblk) + ! ilo = this_block%ilo + ! ihi = this_block%ihi + ! jlo = this_block%jlo + ! jhi = this_block%jhi + ! write(il_out,*) ' this block: cpu, iblock, jblock=', distrb_info%blockLocation(iblk)-1, this_block%iblock, this_block%jblock + ! write(il_out,*) ' block:', iblk, "gilo, gjlo, gihi, gjhi=", this_block%i_glob(ilo), this_block%j_glob(jlo), this_block%i_glob(ihi), this_block%j_glob(jhi) + ! end do + ! end if do iblk=1,nblocks_tot @@ -781,8 +780,8 @@ subroutine from_atm(isteps) call ncheck( nf_open('fields_a2i_in_ice.nc',nf_write,ncid) ) call write_nc_1Dtime(real(isteps),currstep,'time',ncid) endif - write(il_out,*) - write(il_out,*) '(from_atm) Total number of fields to be rcvd: ', nrecv_a2i + ! write(il_out,*) + ! write(il_out,*) '(from_atm) Total number of fields to be rcvd: ', nrecv_a2i endif if (debug) write(il_out,*) "prism_get from_atm at sec: ", isteps diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 70551602..70ccd8e5 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -160,7 +160,9 @@ subroutine init_hist (dt) enddo if (.not. tr_iage) then + !todo: abort here if trying to use these diagnostics and the tracer (and its restart) are not available f_iage = 'x' + f_siage = 'x' f_dagedtt = 'x' f_dagedtd = 'x' endif @@ -194,8 +196,9 @@ subroutine init_hist (dt) ! AEW: These are only calculated under certain circumstances ! (if using multilayers with UM-style coupling) if (calc_Tsfc .or. .not. heat_capacity) then + !to-do: abort here if trying to use these f_Tn_top = 'x' - f_keffn_top = 'x' + f_keffn_top = 'x' endif #ifndef ncdf @@ -358,13 +361,16 @@ subroutine init_hist (dt) call broadcast_scalar (f_sidmassgrowthsi, master_task) call broadcast_scalar (f_sidmassevapsubl, master_task) call broadcast_scalar (f_sndmasssubl, master_task) + call broadcast_scalar (f_sisndmasssubl, master_task) call broadcast_scalar (f_sidmassmelttop, master_task) call broadcast_scalar (f_sidmassmeltbot, master_task) call broadcast_scalar (f_sidmasslat, master_task) + call broadcast_scalar (f_sidmassmeltlat, master_task) call broadcast_scalar (f_sndmasssnf, master_task) call broadcast_scalar (f_sisndmasssnf, master_task) call broadcast_scalar (f_sndmassmelt, master_task) call broadcast_scalar (f_sisndmassmelt, master_task) + call broadcast_scalar (f_sisndmasssi, master_task) call broadcast_scalar (f_sndmassdyn, master_task) call broadcast_scalar (f_sisndmassdyn, master_task) call broadcast_scalar (f_siflswdtop, master_task) @@ -452,6 +458,7 @@ subroutine init_hist (dt) "grid cell mean snow thickness", & "snow volume per unit grid cell area", c1, c0, & ns1, f_hs) + call define_hist_field(n_snowfrac,"snowfrac","1",tstr2D, tcstr, & "grid cell mean snow fraction", & "snow fraction per unit grid cell area", c1, c0, & @@ -467,7 +474,7 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_aice) - call define_hist_field(n_aice,"siconc","1",tstr2D, tcstr, & + call define_hist_field(n_siconc,"siconc","1",tstr2D, tcstr, & "sea ice area fraction", & "none", c1, c0, & ns1, f_siconc) @@ -847,22 +854,22 @@ subroutine init_hist (dt) "strain rate (divergence)", & "divu is instantaneous, on T grid", secday*c100, c0, & ns1, f_divu) - + call define_hist_field(n_shear,"shear","%/day",tstr2D, tcstr, & "strain rate (shear)", & "none", secday*c100, c0, & ns1, f_shear) - + call define_hist_field(n_sig1,"sig1","1",ustr2D, ucstr, & "norm. principal stress 1", & "sig1 is instantaneous", c1, c0, & ns1, f_sig1) - + call define_hist_field(n_sig2,"sig2","1",ustr2D, ucstr, & "norm. principal stress 2", & "sig2 is instantaneous", c1, c0, & ns1, f_sig2) - + call define_hist_field(n_dvidtt,"dvidtt","cm/day",tstr2D, tcstr, & "ice volume tendency thermo", & "none", mps_to_cmpdy, c0, & @@ -933,7 +940,7 @@ subroutine init_hist (dt) "ice extent flag", c1, c0, & ns1, f_icepresent) - call define_hist_field(n_icepresent,"ice_present","1",tstr2D, tcstr, & + call define_hist_field(n_icepresent,"sitimefrac","1",tstr2D, tcstr, & "fraction of time-avg interval that ice is present", & "ice extent flag", c1, c0, & ns1, f_sitimefrac) @@ -1271,7 +1278,7 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sndmassmelt,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change through snow to ice conversion", & "none", c1, c0, & ns1, f_sisndmasssi, avg_ice_present=.true., mask_ice_free_points=.true.) @@ -1321,7 +1328,7 @@ subroutine init_hist (dt) "positive downward", c1, c0, & ns1, f_siflsensupbot, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflsensupbot,"siflsensbot","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_siflsensupbot,"siflsensbot","W/m^2",tstr2D, tcstr, & "sensible heat flux at bottom of sea ice", & "positive downward", c1, c0, & ns1, f_siflsensbot, avg_ice_present=.true., mask_ice_free_points=.true.) @@ -1820,8 +1827,10 @@ subroutine accum_hist (dt) call accum_hist_field(n_snowfrac, iblk, snowfrac(:,:,iblk), a2D) if (f_Tsfc (1:1) /= 'x') & call accum_hist_field(n_Tsfc, iblk, trcr(:,:,nt_Tsfc,iblk), a2D) - if (f_aice (1:1) /= 'x' .or. f_siconc (1:1) /= 'x') & + if (f_aice (1:1) /= 'x') & call accum_hist_field(n_aice, iblk, aice(:,:,iblk), a2D) + if (f_siconc (1:1) /= 'x') & + call accum_hist_field(n_siconc, iblk, aice(:,:,iblk), a2D) if (f_uvel (1:1) /= 'x') & call accum_hist_field(n_uvel, iblk, uvel(:,:,iblk), a2D) if (f_vvel (1:1) /= 'x') & @@ -2094,8 +2103,9 @@ subroutine accum_hist (dt) call accum_hist_field(n_siage, iblk, worka(:,:), a2D) endif - if (f_sisnconc(1:1) /= 'x') then + ! this is not prognostic in cice + ! could repeat this: https://github.com/ACCESS-NRI/cice5/blob/bce3629b7b11df704e2a632392ec139023e95ff1/source/ice_meltpond_topo.F90#L190C1-L195C56 worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2110,7 +2120,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & + if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & worka(i,j) = vsno(i,j,iblk) enddo enddo @@ -2121,7 +2131,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & + if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & worka(i,j) = vsno(i,j,iblk) * rhos enddo enddo @@ -2733,7 +2743,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then + if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then worka(i,j) = aice(i,j,iblk)*fcondbot(i,j,iblk)/aice_init(i,j,iblk) endif enddo @@ -2742,6 +2752,7 @@ subroutine accum_hist (dt) endif if (f_sipr(1:1) /= 'x') then + !to-do: check scaling ? worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index c0eee3a3..80cb5a8e 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -200,7 +200,7 @@ module ice_history_shared f_hs = 'm', & f_snowfrac = 'x', f_snowfracn = 'x', & f_Tsfc = 'm', & - f_aice = 'm', f_siconc = 'x' , & !same var, two names, !to-do: what happens if I try to save both ? + f_aice = 'm', f_siconc = 'x' , & !same var, two names, f_uvel = 'm', f_vvel = 'm', & f_uatm = 'm', f_vatm = 'm', & f_fswdn = 'm', f_flwdn = 'm', & @@ -486,6 +486,7 @@ module ice_history_shared n_hi , n_hs , & n_snowfrac, n_snowfracn, & n_Tsfc , n_aice , & + n_siconc, & n_uvel , n_vvel , & n_uatm , n_vatm , & n_sice , & diff --git a/source/ice_read_write.F90 b/source/ice_read_write.F90 index 8e973873..fb190bbf 100755 --- a/source/ice_read_write.F90 +++ b/source/ice_read_write.F90 @@ -1140,6 +1140,10 @@ subroutine ice_read_nc_xy(fid, nrec, varname, work, diag, & status = nf90_get_var( fid, varid, work_g1, & start=(/1,1,nrec/), & count=(/nx,ny,1/) ) + if (status /= nf90_noerr) then + call abort_ice ( & + 'ice_read_nc_xy: Cannot get variable '//trim(varname) ) + endif #else if (.not. present(restart_ext)) then status = nf90_get_var( fid, varid, work_g2, & @@ -1318,6 +1322,10 @@ subroutine ice_read_nc_xyz(fid, nrec, varname, work, diag, & status = nf90_get_var( fid, varid, work_g1, & start=(/1,1,1,nrec/), & count=(/nx,ny,ncat,1/) ) + if (status /= nf90_noerr) then + call abort_ice ( & + 'ice_read_nc_xyz: Cannot get variable '//trim(varname) ) + endif #else if (.not. present(restart_ext)) then status = nf90_get_var( fid, varid, work_g2, & @@ -1553,6 +1561,11 @@ subroutine ice_read_nc_z(fid, nrec, varname, work, diag, & start=(/1,nrec/), & count=(/nilyr,1/) ) + if (status /= nf90_noerr) then + call abort_ice ( & + 'ice_read_nc: Cannot get variable '//trim(varname) ) + endif + endif ! my_task = master_task !------------------------------------------------------------------- @@ -1661,6 +1674,11 @@ subroutine ice_write_nc_xy(fid, nrec, varid, work, diag, & start=(/1,1,nrec/), & count=(/nx,ny,1/) ) + if (status /= nf90_noerr) then + call abort_ice ( & + 'ice_write_nc_xy: Cannot put variable '//trim(nf90_strerror(status)) ) + endif + endif ! my_task = master_task !------------------------------------------------------------------- @@ -1777,6 +1795,11 @@ subroutine ice_write_nc_xyz(fid, nrec, varid, work, diag, & start=(/1,1,1,nrec/), & count=(/nx,ny,ncat,1/) ) + if (status /= nf90_noerr) then + call abort_ice ( & + 'ice_write_nc_xy: Cannot put variable '//trim(nf90_strerror(status)) ) + endif + endif ! my_task = master_task !------------------------------------------------------------------- @@ -1946,6 +1969,10 @@ subroutine ice_close_nc(fid) if (my_task == master_task) then status = nf90_close(fid) + if (status /= nf90_noerr) then + call abort_ice ( & + 'ice_close_nc: Error closing file '//trim(nf90_strerror(status)) ) + endif endif #endif From 1673cb2b6453461ebb54438d68d4d60a75671d8e Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 22 Sep 2025 16:44:33 +1000 Subject: [PATCH 30/80] fix my bugs --- drivers/access/CICE_RunMod.F90 | 25 ++++++++++++++++++++----- source/ice_history.F90 | 20 ++++++++------------ source/ice_history_shared.F90 | 1 - source/ice_step_mod.F90 | 1 + 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/drivers/access/CICE_RunMod.F90 b/drivers/access/CICE_RunMod.F90 index 01e2ef72..9d7cdae4 100644 --- a/drivers/access/CICE_RunMod.F90 +++ b/drivers/access/CICE_RunMod.F90 @@ -51,6 +51,8 @@ subroutine CICE_Run use ice_calendar, only: month, mday, istep, istep1, time, dt, stop_now, calendar, & write_restart, dump_last use ice_restart_driver, only: dumpfile !temporary debug + use ice_state, only: vsno, aice, tr_pond + use ice_flux, only: snowfrac #endif use ice_flux, only: init_flux_atm, init_flux_ocn use ice_state, only: tr_aero @@ -82,12 +84,15 @@ subroutine CICE_Run !-------------------------------------------------------------------- #ifdef ACCESS - write(il_out,*)'A <==> I coupling num_cpl_ai = ',num_cpl_ai - write(il_out,*)' ice steps per ai interval num_ice_ai = ',num_ice_ai - write(il_out,*)' runtime, runtime0 = ',runtime, runtime0 - time_sec = 0 + if (my_task == master_task) then + write(il_out,*)'A <==> I coupling num_cpl_ai = ',num_cpl_ai + write(il_out,*)' ice steps per ai interval num_ice_ai = ',num_ice_ai + write(il_out,*)' runtime, runtime0 = ',runtime, runtime0 + endif + time_sec = 0 + DO icpl_ai = 1, num_cpl_ai !begin A <==> I coupling iterations !receive a2i fields @@ -153,11 +158,21 @@ subroutine CICE_Run call time_average_fields_4_i2a !time averaging over ia cpl interval tmp_time = time_sec + dt - if ( mod(tmp_time, dt_cpl_ai) == 0 ) then !this happens at itap = num_ice_ai + if ( mod(tmp_time, dt_cpl_ai) == 0 ) then !this happens at itap = num_ice_ai !call ice_timer_start(timer_into_atm) !i2a fields ready to be sent for next IA cpl int in atm. call get_i2a_fields +#ifdef ACCESS + if ( .not. tr_pond) then + ! calculate a snowfrac diagnostic in the same way the UM does + ! set snow fraction using JULES empirical formula based + ! on snow volume + ! ref: https://github.com/ACCESS-NRI/UM7/blob/6602dadd15c190ee37c6644190f52d428bc66917/umbase_hg3/src/atmosphere/short_wave_radiation/ftsa.F90#L201-L202 + where (aice > puny) snowfrac(:,:,:) = c1 - exp(-p2*rhos*(vsno(:,:,:) / aice(:,:,:))) + endif +#endif + stimestamp_ai = time_sec ! write(il_out,'(a,3i10)') & diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 70ccd8e5..b1676925 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -474,7 +474,7 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_aice) - call define_hist_field(n_siconc,"siconc","1",tstr2D, tcstr, & + call define_hist_field(n_aice,"siconc","1",tstr2D, tcstr, & "sea ice area fraction", & "none", c1, c0, & ns1, f_siconc) @@ -1827,10 +1827,8 @@ subroutine accum_hist (dt) call accum_hist_field(n_snowfrac, iblk, snowfrac(:,:,iblk), a2D) if (f_Tsfc (1:1) /= 'x') & call accum_hist_field(n_Tsfc, iblk, trcr(:,:,nt_Tsfc,iblk), a2D) - if (f_aice (1:1) /= 'x') & + if (f_aice (1:1) /= 'x' .or. f_siconc (1:1) /= 'x') & call accum_hist_field(n_aice, iblk, aice(:,:,iblk), a2D) - if (f_siconc (1:1) /= 'x') & - call accum_hist_field(n_siconc, iblk, aice(:,:,iblk), a2D) if (f_uvel (1:1) /= 'x') & call accum_hist_field(n_uvel, iblk, uvel(:,:,iblk), a2D) if (f_vvel (1:1) /= 'x') & @@ -2104,15 +2102,13 @@ subroutine accum_hist (dt) endif if (f_sisnconc(1:1) /= 'x') then - ! this is not prognostic in cice - ! could repeat this: https://github.com/ACCESS-NRI/cice5/blob/bce3629b7b11df704e2a632392ec139023e95ff1/source/ice_meltpond_topo.F90#L190C1-L195C56 worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & - worka(i,j) = aice(i,j,iblk) * snowfrac(i,j,iblk) - enddo - enddo + do j = jlo, jhi + do i = ilo, ihi + if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk) * snowfrac(i,j,iblk) + enddo + enddo call accum_hist_field(n_sisnconc, iblk, worka(:,:), a2D) endif diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 80cb5a8e..59323a34 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -486,7 +486,6 @@ module ice_history_shared n_hi , n_hs , & n_snowfrac, n_snowfracn, & n_Tsfc , n_aice , & - n_siconc, & n_uvel , n_vvel , & n_uatm , n_vatm , & n_sice , & diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index 4afab596..acf1beb0 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -771,6 +771,7 @@ subroutine step_therm1 (dt, iblk) trcrn(:,:,nt_hpnd,:,iblk), & trcrn(:,:,nt_ipnd,:,iblk)) endif + call ice_timer_stop(timer_ponds,iblk) end subroutine step_therm1 From d518ff7f22aa1c304abda6b055efb6db4c9aa95a Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 22 Sep 2025 16:48:50 +1000 Subject: [PATCH 31/80] fix my bugs --- source/ice_flux.F90 | 1 + source/ice_history.F90 | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ice_flux.F90 b/source/ice_flux.F90 index f409765e..246d3738 100755 --- a/source/ice_flux.F90 +++ b/source/ice_flux.F90 @@ -789,6 +789,7 @@ subroutine merge_fluxes (nx_block, ny_block, & fsurf , & ! net heat flux to top surface (W/m**2) fcondtop, & ! downward cond flux at top sfc (W/m**2) fcondbot, & ! downward cond flux at bottom sfc (W/m**2) + fcondbot_init, & ! downward cond flux at bottom sfc, based on aicen_init (W/m**2) fsens , & ! sensible heat flx (W/m**2) flat , & ! latent heat flx (W/m**2) fswabs , & ! shortwave absorbed heat flx (W/m**2) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index b1676925..236c2129 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2740,7 +2740,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*fcondbot(i,j,iblk)/aice_init(i,j,iblk) + worka(i,j) = (aice(i,j,iblk)/aice_init(i,j,iblk))*fcondbot(i,j,iblk) endif enddo enddo From d3c1fa038cac91202eb39fe41cbbffbd78a66f77 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 23 Sep 2025 14:53:23 +1000 Subject: [PATCH 32/80] some corrections adn tidyup --- drivers/access/CICE_RunMod.F90 | 33 ++++++++++++++++++--------------- source/ice_flux.F90 | 1 - source/ice_history.F90 | 22 ++++++++++++++-------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/access/CICE_RunMod.F90 b/drivers/access/CICE_RunMod.F90 index 9d7cdae4..d9424d40 100644 --- a/drivers/access/CICE_RunMod.F90 +++ b/drivers/access/CICE_RunMod.F90 @@ -51,8 +51,6 @@ subroutine CICE_Run use ice_calendar, only: month, mday, istep, istep1, time, dt, stop_now, calendar, & write_restart, dump_last use ice_restart_driver, only: dumpfile !temporary debug - use ice_state, only: vsno, aice, tr_pond - use ice_flux, only: snowfrac #endif use ice_flux, only: init_flux_atm, init_flux_ocn use ice_state, only: tr_aero @@ -163,16 +161,6 @@ subroutine CICE_Run !i2a fields ready to be sent for next IA cpl int in atm. call get_i2a_fields -#ifdef ACCESS - if ( .not. tr_pond) then - ! calculate a snowfrac diagnostic in the same way the UM does - ! set snow fraction using JULES empirical formula based - ! on snow volume - ! ref: https://github.com/ACCESS-NRI/UM7/blob/6602dadd15c190ee37c6644190f52d428bc66917/umbase_hg3/src/atmosphere/short_wave_radiation/ftsa.F90#L201-L202 - where (aice > puny) snowfrac(:,:,:) = c1 - exp(-p2*rhos*(vsno(:,:,:) / aice(:,:,:))) - endif -#endif - stimestamp_ai = time_sec ! write(il_out,'(a,3i10)') & @@ -306,6 +294,10 @@ subroutine ice_step use ice_algae, only: bgc_diags, write_restart_bgc use ice_zbgc, only: init_history_bgc, biogeochemistry use ice_zbgc_shared, only: skl_bgc +#ifdef ACCESS + use ice_state, only: vsno, aice, tr_pond + use ice_flux, only: snowfrac +#endif integer (kind=int_kind) :: & iblk , & ! block index @@ -455,7 +447,7 @@ subroutine coupling_prep (iblk) use ice_ocean, only: oceanmixed_ice, ocean_mixed_layer use ice_shortwave, only: alvdfn, alidfn, alvdrn, alidrn, & albicen, albsnon, albpndn, apeffn - use ice_state, only: aicen, aice, aice_init, nbtrcr + use ice_state, only: aicen, aice, aice_init, nbtrcr, tr_pond, vsno use ice_therm_shared, only: calc_Tsfc, heat_capacity use ice_timers, only: timer_couple, ice_timer_start, ice_timer_stop use ice_zbgc_shared, only: flux_bio, flux_bio_ai @@ -541,8 +533,19 @@ subroutine coupling_prep (iblk) apeff_ai(i,j,iblk) = apeff_ai(i,j,iblk) & ! for history + apeffn(i,j,n,iblk)*aicen(i,j,n,iblk) - snowfrac(i,j,iblk) = snowfrac(i,j,iblk) & ! for history - + snowfracn(i,j,n,iblk)*aicen(i,j,n,iblk) + + if ( .not. tr_pond .and. .not. calc_Tsfc ) then + ! calculate a snowfrac diagnostic in the same way the UM does + ! set snow fraction using JULES empirical formula based + ! on snow volume + ! ref: https://github.com/ACCESS-NRI/UM7/blob/6602dadd15c190ee37c6644190f52d428bc66917/umbase_hg3/src/atmosphere/short_wave_radiation/ftsa.F90#L201-L202 + if (aice(i,j,iblk) > 2e-4) & + snowfrac(i,j,iblk) = c1 - exp(-p2*rhos*(vsno(i,j,iblk) / aice(i,j,iblk))) + else + snowfrac(i,j,iblk) = snowfrac(i,j,iblk) & ! for history + + snowfracn(i,j,n,iblk)*aicen(i,j,n,iblk) + endif + enddo enddo enddo diff --git a/source/ice_flux.F90 b/source/ice_flux.F90 index 246d3738..f409765e 100755 --- a/source/ice_flux.F90 +++ b/source/ice_flux.F90 @@ -789,7 +789,6 @@ subroutine merge_fluxes (nx_block, ny_block, & fsurf , & ! net heat flux to top surface (W/m**2) fcondtop, & ! downward cond flux at top sfc (W/m**2) fcondbot, & ! downward cond flux at bottom sfc (W/m**2) - fcondbot_init, & ! downward cond flux at bottom sfc, based on aicen_init (W/m**2) fsens , & ! sensible heat flx (W/m**2) flat , & ! latent heat flx (W/m**2) fswabs , & ! shortwave absorbed heat flx (W/m**2) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 236c2129..62e97aa3 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1031,7 +1031,11 @@ subroutine init_hist (dt) ns1, f_FY) ! CMIP6 2D variables - ! check these definitions against the intensive/extensive/inst def in notz et al 2016 + ! these definitions against the intensive/extensive/inst def + ! we use updated "mean where sea" or "mean where sea_ice" per CMIP7 data request + ! intensive means sea ice area weighted, and then averaged only when sea ice is present + ! extensive means a normal average (over all time and grid box area) + ! extensive vars tend to zero when aice is zero, intensive vars do not call define_hist_field(n_sithick,"sithick","m",tstr2D, tcstr, & "sea ice thickness", & "volume divided by area", c1, c0, & @@ -1040,7 +1044,7 @@ subroutine init_hist (dt) call define_hist_field(n_simass,"simass","kg m^-2",tstr2D, tcstr, & "sea ice mass", & "mass divided by area", c1, c0, & - ns1, f_simass, avg_ice_present=.true., mask_ice_free_points=.true.) + ns1, f_simass) call define_hist_field(n_siage,"siage","s",tstr2D, tcstr, & "sea ice age", & @@ -1159,7 +1163,7 @@ subroutine init_hist (dt) call define_hist_field(n_sidivvel,"sidivvel","1/s",ustr2D, ucstr, & "divergence of the sea ice velocity field (ice area weighted)", & - "none", c1, c0, & + "none", c1, c0, & ns1, f_sidivvel, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sispeed,"sispeed","m/s",ustr2D, ucstr, & @@ -1192,7 +1196,6 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sidconcdyn) - !to-do: the next set of vars surely should be ice area weighted ? call define_hist_field(n_sidmassth,"sidmassth","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from thermodynamics", & "none", c1, c0, & @@ -2740,7 +2743,12 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - worka(i,j) = (aice(i,j,iblk)/aice_init(i,j,iblk))*fcondbot(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*fcondbot(i,j,iblk) + ! CICE6 has this weighting, presumably an incorrent attempt to adjust + ! fcondbot so its consistent with aice ? + ! for ACCESS, fcondbot was caluclated in the UM, using aice from the timestep + ! before aice_init, so it doesn't really help + ! worka(i,j) = (aice(i,j,iblk)/aice_init(i,j,iblk))*fcondbot(i,j,iblk) endif enddo enddo @@ -2753,7 +2761,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*frain(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*frain(i,j,iblk) endif enddo enddo @@ -2791,7 +2799,6 @@ subroutine accum_hist (dt) ! call accum_hist_field(n_sifb, iblk, worka(:,:), a2D) ! endif -!to-do: fix for mushy? / frazil???? if (f_siflsaltbot(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -2816,7 +2823,6 @@ subroutine accum_hist (dt) call accum_hist_field(n_sisaltmass, iblk, worka(:,:), a2D) endif - !to-do : fix for frazil ???? if (f_siflfwbot(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi From 0f0df60e3f10ee639ed1ea0245f2e9741fa9e31d Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Tue, 23 Sep 2025 14:55:08 +1000 Subject: [PATCH 33/80] Update source/ice_history.F90 Co-authored-by: Spencer Wong <88933912+blimlim@users.noreply.github.com> --- source/ice_history.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 62e97aa3..8e8c33dc 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1351,7 +1351,7 @@ subroutine init_hist (dt) "positive downward", c1, c0, & ns1, f_siflcondbot, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflfwdrain,"siflfwdrain","kg m-2 s-1",tstr2D, tcstr, & + call define_hist_field(n_siflfwdrain,"siflfwdrain","kg m^-2 s^-1",tstr2D, tcstr, & "freshwater drainage through sea ice", & "positive downward", c1, c0, & ns1, f_siflfwdrain, avg_ice_present=.true., mask_ice_free_points=.true.) From db55587379287116e97e253c8417af8bbba713b6 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 23 Sep 2025 14:58:59 +1000 Subject: [PATCH 34/80] fix C->K conversion for sitempsnic --- source/ice_history.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 8e8c33dc..28aecb07 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2153,9 +2153,9 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (vsno(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*Tsnic(i,j,iblk)/aice_init(i,j,iblk)+Tffresh + worka(i,j) = aice(i,j,iblk)*(Tsnic(i,j,iblk)/aice_init(i,j,iblk)+Tffresh) else - worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk)+Tffresh + worka(i,j) = aice(i,j,iblk)*(trcr(i,j,nt_Tsfc,iblk)+Tffresh) endif enddo enddo From a8c2d2695dc5742594ace9ba9d37a2cf35734818 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Wed, 24 Sep 2025 10:23:30 +1000 Subject: [PATCH 35/80] Tsnice based on https://github.com/CICE-Consortium/Icepack/pull/542 --- source/ice_history.F90 | 10 ++++---- source/ice_step_mod.F90 | 7 ++--- source/ice_therm_shared.F90 | 3 ++- source/ice_therm_vertical.F90 | 48 ++++++++++++++++++++++------------- 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 28aecb07..20f44b83 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1702,7 +1702,7 @@ subroutine accum_hist (dt) use ice_meltpond_cesm, only: hs0 use ice_state ! almost everything use ice_therm_shared, only: calculate_Tin_from_qin, Tmlt, ktherm, & - Ti_bot, Tsnic + Ti_bot, Tsnice use ice_therm_mushy, only: temperature_mush, temperature_snow use ice_timers, only: ice_timer_start, ice_timer_stop, timer_readwrite use ice_zbgc_shared, only: skl_bgc @@ -2152,10 +2152,10 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (vsno(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*(Tsnic(i,j,iblk)/aice_init(i,j,iblk)+Tffresh) - else - worka(i,j) = aice(i,j,iblk)*(trcr(i,j,nt_Tsfc,iblk)+Tffresh) + if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then + ! Tsnice is aice_init weighted in thermo_vertical , so adjust that first + ! then convert C->K and weight by aice (as intrinsic CMIP diag) + worka(i,j) = aice(i,j,iblk)*(Tsnice(i,j,iblk)/aice_init(i,j,iblk)+Tffresh) endif enddo enddo diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index acf1beb0..575c5a6c 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -204,7 +204,7 @@ subroutine step_therm1 (dt, iblk) nt_apnd, nt_hpnd, nt_ipnd, nt_alvl, nt_vlvl, nt_Tsfc, & tr_iage, nt_iage, tr_FY, nt_FY, tr_aero, tr_pond, tr_pond_cesm, & tr_pond_lvl, nt_qice, nt_sice, tr_pond_topo, uvel, vvel - use ice_therm_shared, only: calc_Tsfc, Tsnic, Ti_bot + use ice_therm_shared, only: calc_Tsfc, Tsnice, Ti_bot use ice_therm_vertical, only: frzmlt_bottom_lateral, thermo_vertical use ice_timers, only: ice_timer_start, ice_timer_stop, timer_ponds !BBB: @@ -391,6 +391,8 @@ subroutine step_therm1 (dt, iblk) dfloe (:,:,iblk), ncat) endif + Tsnice(:,:,iblk) = c0 + do n = 1, ncat meltsn(:,:,n,iblk) = c0 @@ -571,7 +573,7 @@ subroutine step_therm1 (dt, iblk) mlt_onset(:,:,iblk), frz_onset(:,:,iblk), & yday, l_stop, & istop, jstop, & - dsnown(:,:,n,iblk)) + dsnown(:,:,n,iblk), Tsnice(:,:,iblk)) if (l_stop) then write (nu_diag,*) 'istep1, my_task, iblk =', & @@ -749,7 +751,6 @@ subroutine step_therm1 (dt, iblk) enddo ! ncat Ti_bot(:,:,iblk) = Tbot(:,:) * aice(:,:,iblk) - Tsnic(:,:,iblk) = c0 !----------------------------------------------------------------- ! Calculate ponds from the topographic scheme diff --git a/source/ice_therm_shared.F90 b/source/ice_therm_shared.F90 index 4d0a3f54..a23a91d1 100755 --- a/source/ice_therm_shared.F90 +++ b/source/ice_therm_shared.F90 @@ -44,7 +44,8 @@ module ice_therm_shared real (kind=dbl_kind), & dimension(nx_block,ny_block,max_blocks), & public :: & - Tsnic, Ti_bot + Tsnice, & ! snow ice interface temperature (deg C), (diagnostic) + Ti_bot logical (kind=log_kind), public :: & l_brine ! if true, treat brine pocket effects diff --git a/source/ice_therm_vertical.F90 b/source/ice_therm_vertical.F90 index 6977f3de..4c5d495b 100755 --- a/source/ice_therm_vertical.F90 +++ b/source/ice_therm_vertical.F90 @@ -29,8 +29,8 @@ module ice_therm_vertical nt_Tsfc, nt_iage, nt_sice, nt_qice, nt_qsno, & nt_apnd, nt_hpnd use ice_therm_shared, only: ktherm, ferrmax, heat_capacity, l_brine, & - calc_Tsfc, calculate_tin_from_qin, Tmin, & - cap_fluxes + calc_Tsfc, calculate_tin_from_qin, Tmin, Tsnice, & + cap_fluxes use ice_therm_bl99, only: temperature_changes use ice_therm_0layer, only: zerolayer_temperature use ice_flux, only: Tf @@ -101,7 +101,7 @@ subroutine thermo_vertical (nx_block, ny_block, & mlt_onset, frz_onset, & yday, l_stop, & istop, jstop, & - dsnow) + dsnow, Tsnice) use ice_communicate, only: my_task use ice_therm_mushy, only: temperature_changes_salinity @@ -221,6 +221,7 @@ subroutine thermo_vertical (nx_block, ny_block, & ! 2D state variables (thickness, temperature, enthalpy) real (kind=dbl_kind), dimension (icells) :: & + Tsnice , & ! snow ice interface temperature (deg C), (diagnostic) hilyr , & ! ice layer thickness hslyr , & ! snow layer thickness Tsf , & ! ice/snow top surface temp, same as Tsfcn (deg C) @@ -464,25 +465,38 @@ subroutine thermo_vertical (nx_block, ny_block, & endif ! heat_capacity - ! Alex West: Read 1D bottom conductive flux array into 2D array - ! for diagnostics (SIMIP)i + ! intermediate energy for error check + do ij = 1, icells + einter(ij) = c0 + do k = 1, nslyr + einter(ij) = einter(ij) + hslyr(ij) * zqsn(ij,k) + enddo ! k + do k = 1, nilyr + einter(ij) = einter(ij) + hilyr(ij) * zqin(ij,k) + enddo ! k + enddo ! ij + + ! Read 1D bottom conductive flux array into 2D array for diagnostics (SIMIP) do ij = 1, icells i = indxi(ij) j = indxj(ij) fcondbotn(i,j) = fcondbot(ij) - enddo - - ! intermediate energy for error check - do ij = 1, icells - einter(ij) = c0 - do k = 1, nslyr - einter(ij) = einter(ij) + hslyr(ij) * zqsn(ij,k) - enddo ! k - do k = 1, nilyr - einter(ij) = einter(ij) + hilyr(ij) * zqin(ij,k) - enddo ! k - enddo ! ij + ! Tsnice from https://github.com/CICE-Consortium/Icepack/blob/e9d626f0e5b743e143a2e87248a1aa22ee4f3751/columnphysics/icepack_therm_vertical.F90#L378C1-L385C12 + ! Tsnice is : + ! - the average of temperature of bottom snow layer and top ice layer, + ! - weighted by aicen across all thicknii categories + if ((hslyr(ij)+hilyr(ij)) > puny) then + if (hslyr(ij) > puny) then + Tsnice(ij) = Tsnice(ij) + aicen(i,j)*(& + (hslyr(ij)*zTsn(ij,nslyr) + hilyr(ij)*zTin(ij,1)) & + / (hslyr(ij)+hilyr(ij)) & + ) + else + Tsnice(ij) = Tsnice(ij) + aicen(i,j)*Tsf(ij) + endif + endif + enddo if (l_stop) return From e081c1426b2b0cfd798fa5222d5ab0d37ee0d0ee Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Wed, 24 Sep 2025 13:38:22 +1000 Subject: [PATCH 36/80] fix units on sisnmass --- source/ice_history.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 20f44b83..265d5456 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1066,7 +1066,7 @@ subroutine init_hist (dt) "snow volume divided by area", c1, c0, & ns1, f_sisnthick, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sisnmass,"sisnmass","m",tstr2D, tcstr, & + call define_hist_field(n_sisnmass,"sisnmass","kg m^-2",tstr2D, tcstr, & "snow mass per areas", & "snow mass divided by area", c1, c0, & ns1, f_sisnmass, avg_ice_present=.true., mask_ice_free_points=.true.) From 81f2080682037fcd922f6e8e88c23874beac4851 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 25 Sep 2025 13:30:22 +1000 Subject: [PATCH 37/80] reset evap_ice each timestep and adjust diagnostic --- source/ice_flux.F90 | 2 ++ source/ice_history.F90 | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/ice_flux.F90 b/source/ice_flux.F90 index f409765e..c348e652 100755 --- a/source/ice_flux.F90 +++ b/source/ice_flux.F90 @@ -537,6 +537,8 @@ subroutine init_flux_atm fswabs (:,:,:) = c0 flwout (:,:,:) = c0 evap (:,:,:) = c0 + evap_ice(:,:,:) = c0 + evap_snow(:,:,:) = c0 Tref (:,:,:) = c0 Qref (:,:,:) = c0 Uref (:,:,:) = c0 diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 265d5456..5bca5a93 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2519,7 +2519,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk)*rhoi + worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk) endif enddo enddo @@ -2531,7 +2531,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = rhos*aice(i,j,iblk)*evap_snow(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*evap_snow(i,j,iblk) endif enddo enddo From 60179c87f64a33c4daba7e440e1bd398979b2878 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 7 Oct 2025 11:36:59 +1100 Subject: [PATCH 38/80] use cice6 calc for freeboard --- source/ice_flux.F90 | 17 +-------- source/ice_history.F90 | 70 +++++++++++++++++------------------ source/ice_step_mod.F90 | 6 +-- source/ice_therm_vertical.F90 | 34 ++--------------- 4 files changed, 42 insertions(+), 85 deletions(-) diff --git a/source/ice_flux.F90 b/source/ice_flux.F90 index c348e652..1dff7836 100755 --- a/source/ice_flux.F90 +++ b/source/ice_flux.F90 @@ -74,10 +74,7 @@ module ice_flux dardg1dt, & ! rate of area loss by ridging ice (1/s) dardg2dt, & ! rate of area gain by new ridges (1/s) dvirdgdt, & ! rate of ice volume ridged (m/s) - opening , & ! rate of opening due to divergence/shear (1/s) - ice_freeboard ! height of ice surface (i.e. not snow surface) - ! above sea level (m) - + opening ! rate of opening due to divergence/shear (1/s) real (kind=dbl_kind), & dimension (nx_block,ny_block,ncat,max_blocks), public :: & @@ -92,10 +89,7 @@ module ice_flux araftn, & ! rafting ice area vraftn, & ! rafting ice volume aredistn, & ! redistribution function: fraction of new ridge area - vredistn , & ! redistribution function: fraction of new ridge volume - ice_freeboardn ! category height of ice surface (i.e. not snow - ! surface) above sea level (m) - + vredistn ! redistribution function: fraction of new ridge volume ! restart @@ -601,7 +595,6 @@ subroutine init_history_therm melts (:,:,:) = c0 meltb (:,:,:) = c0 meltl (:,:,:) = c0 - ice_freeboard (:,:,:) = c0 daidtt (:,:,:) = aice(:,:,:) ! temporary initial area dvidtt (:,:,:) = vice(:,:,:) ! temporary initial volume dvsdtt (:,:,:) = vsno(:,:,:) ! temporary initial volume @@ -716,7 +709,6 @@ subroutine merge_fluxes (nx_block, ny_block, & fswabsn, flwoutn, & evapn, & evapn_ice,evapn_snow, & - ice_freeboardn, & Trefn, Qrefn, & freshn, fsaltn, & fhocnn, fswthrun, & @@ -728,7 +720,6 @@ subroutine merge_fluxes (nx_block, ny_block, & fswabs, flwout, & evap, & evap_ice, evap_snow, & - ice_freeboard, & Tref, Qref, & fresh, fsalt, & fhocn, fswthru, & @@ -773,7 +764,6 @@ subroutine merge_fluxes (nx_block, ny_block, & meltsn , & ! snow melt (m) congeln , & ! congelation ice growth (m) snoicen , & ! snow-ice growth (m) - ice_freeboardn , & ! ice freeboard (m) evapn_ice, & ! evaporation over ice only (kg/m2/s) evapn_snow ! evaporation over snow only (kg/m2/s) @@ -807,7 +797,6 @@ subroutine merge_fluxes (nx_block, ny_block, & melts , & ! snow melt (m) congel , & ! congelation ice growth (m) snoice , & ! snow-ice growth (m) - ice_freeboard, & ! ice freeboard evap_ice, & ! evaporation over ice only evap_snow ! evaporation over snow only @@ -850,8 +839,6 @@ subroutine merge_fluxes (nx_block, ny_block, & evap (i,j) = evap (i,j) + evapn (i,j)*aicen(i,j) evap_ice (i,j) = evap_ice(i,j) + evapn_ice(i,j)*aicen(i,j) evap_snow (i,j) = evap_snow(i,j) + evapn_snow(i,j)*aicen(i,j) - ice_freeboard (i,j) = ice_freeboard(i,j) + & - ice_freeboardn(i,j)*aicen(i,j) Tref (i,j) = Tref (i,j) + Trefn (i,j)*aicen(i,j) Qref (i,j) = Qref (i,j) + Qrefn (i,j)*aicen(i,j) if (present(Urefn) .and. present(Uref)) then diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 5bca5a93..0d28d586 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1652,7 +1652,7 @@ subroutine accum_hist (dt) use ice_fileunits, only: nu_diag use ice_constants, only: c0, c1, p25, puny, secday, depressT, & - awtvdr, awtidr, awtvdf, awtidf, Lfresh, rhoi, rhos, cp_ice, & + awtvdr, awtidr, awtvdf, awtidf, Lfresh, rhoi, rhos, rhow, cp_ice, & spval_dbl, Tffresh, ice_ref_salinity, c1000 use ice_domain, only: blocks_ice, nblocks use ice_grid, only: tmask, lmask_n, lmask_s, tarea, HTE, HTN @@ -1682,7 +1682,7 @@ subroutine accum_hist (dt) fswthru_ai, strairx, strairy, strtltx, strtlty, strintx, strinty, & strocnx, strocny, fm, daidtt, dvidtt, dvsdtt, daidtd, dvidtd, dvsdtd, fsurf, & fcondtop, fsurfn, fcondtopn, & - fcondbot, fcondbotn, ice_freeboard, & + fcondbot, fcondbotn, & flatn, fsensn, albcnt, prs_sig, & stressp_1, stressm_1, stress12_1, & stressp_2, stressm_2, stress12_2, & @@ -1725,7 +1725,8 @@ subroutine accum_hist (dt) real (kind=dbl_kind) :: & qn , & ! temporary variable for enthalpy hs , & ! temporary variable for snow depth - Tmlts ! temporary variable for melting temperature + Tmlts , & ! temporary variable for melting temperature + rho_ice, rho_ocn ! temporary variables for freeboard real (kind=dbl_kind), dimension (nx_block,ny_block,ncat_hist) :: & ravgipn @@ -1824,8 +1825,6 @@ subroutine accum_hist (dt) call accum_hist_field(n_hi, iblk, vice(:,:,iblk), a2D) if (f_hs (1:1) /= 'x') & call accum_hist_field(n_hs, iblk, vsno(:,:,iblk), a2D) - if (f_sifb (1:1) /= 'x') & - call accum_hist_field(n_sifb, iblk, ice_freeboard(:,:,iblk), a2D) if (f_snowfrac(1:1) /= 'x') & call accum_hist_field(n_snowfrac, iblk, snowfrac(:,:,iblk), a2D) if (f_Tsfc (1:1) /= 'x') & @@ -2768,36 +2767,37 @@ subroutine accum_hist (dt) call accum_hist_field(n_sipr, iblk, worka(:,:), a2D) endif -! to-do: Possibly fix for mushy ? -! if (f_sifb(1:1) /= 'x') then -! worka(:,:) = c0 -! rho_ice = rhoi -! rho_ocn = rhow -! do j = jlo, jhi -! do i = ilo, ihi -! if (aice(i,j,iblk) > puny) then -! if (ktherm == 2) then -! rho_ocn = icepack_mushy_density_brine(sss(i,j,iblk)) -! rho_ice = c0 -! do k = 1, nzilyr -! Tice = icepack_mushy_temperature_mush(trcr(i,j,nt_qice+k-1,iblk),trcr(i,j,nt_sice+k-1,iblk)) -! Sbr = trcr(i,j,nt_sice+k-1,iblk) -! phi = icepack_mushy_liquid_fraction(Tice,Sbr) -! rhob = icepack_mushy_density_brine(Sbr) -! rho_ice = rho_ice + min(phi*rhob+(c1-phi)*rhoi,rho_ocn) -! enddo -! rho_ice = rho_ice / real(nzilyr,kind=dbl_kind) -! endif -! worka(i,j) = ((rho_ocn-rho_ice)*vice(i,j,iblk) - rhos*vsno(i,j,iblk))/rho_ocn -! ! if (worka(i,j) < c0) then -! ! write(nu_diag,*) 'negative fb',rho_ocn,rho_ice,rhos -! ! write(nu_diag,*) vice(i,j,iblk),vsno(i,j,iblk) -! ! endif -! endif -! enddo -! enddo -! call accum_hist_field(n_sifb, iblk, worka(:,:), a2D) -! endif + if (f_sifb(1:1) /= 'x') then + worka(:,:) = c0 + rho_ice = rhoi + rho_ocn = rhow + do j = jlo, jhi + do i = ilo, ihi + if (aice(i,j,iblk) > puny) then + !to-do : fix for mushy + if (ktherm == 2) then + call abort_ice("sifb not available when ktherm==2, set f_sifb = 'x' or fix in cice5 code") + ! ! rho_ocn = icepack_mushy_density_brine(sss(i,j,iblk)) + ! ! rho_ice = c0 + ! do k = 1, nzilyr + ! Tice = icepack_mushy_temperature_mush(trcr(i,j,nt_qice+k-1,iblk),trcr(i,j,nt_sice+k-1,iblk)) + ! Sbr = trcr(i,j,nt_sice+k-1,iblk) + ! phi = icepack_mushy_liquid_fraction(Tice,Sbr) + ! rhob = icepack_mushy_density_brine(Sbr) + ! rho_ice = rho_ice + min(phi*rhob+(c1-phi)*rhoi,rho_ocn) + ! enddo + ! rho_ice = rho_ice / real(nzilyr,kind=dbl_kind) + endif + worka(i,j) = ((rho_ocn-rho_ice)*vice(i,j,iblk) - rhos*vsno(i,j,iblk))/rho_ocn + if (worka(i,j) < c0) then + write(nu_diag,*) 'negative fb',rho_ocn,rho_ice,rhos + write(nu_diag,*) vice(i,j,iblk),vsno(i,j,iblk) + endif + endif + enddo + enddo + call accum_hist_field(n_sifb, iblk, worka(:,:), a2D) + endif if (f_siflsaltbot(1:1) /= 'x') then worka(:,:) = c0 diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index 575c5a6c..8de5fdb4 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -183,8 +183,7 @@ subroutine step_therm1 (dt, iblk) use ice_flux, only: frzmlt, sst, Tf, strocnxT, strocnyT, rside, & meltsn, melttn, meltbn, congeln, snoicen, dsnown, uatm, vatm, & wind, rhoa, potT, Qa, zlvl, strax, stray, flatn, fsensn, fsurfn, & - fcondtopn, fcondbotn, fcondbot, & - ice_freeboardn, ice_freeboard, snowfracn, & + fcondtopn, fcondbotn, fcondbot, snowfracn, & flw, fsnow, fpond, sss, mlt_onset, frz_onset, faero_atm, faero_ocn, & frain, Tair, coszen, strairxT, strairyT, fsurf, fcondtop, fsens, & flat, fswabs, flwout, evap, Tref, Qref, Uref, fresh, fsalt, fhocn, & @@ -562,7 +561,6 @@ subroutine step_therm1 (dt, iblk) fcondtopn(:,:,n,iblk), fcondbotn(:,:,n,iblk), & fsensn(:,:,n,iblk), flatn(:,:,n,iblk), & flwoutn, & - ice_freeboardn, & evapn, & evapn_ice, evapn_snow, & freshn, & @@ -724,7 +722,6 @@ subroutine step_therm1 (dt, iblk) fswabsn, flwoutn, & evapn, & evapn_ice, evapn_snow, & - ice_freeboardn(:,:,n,iblk), & Trefn, Qrefn, & freshn, fsaltn, & fhocnn, fswthrun(:,:,n,iblk), & @@ -736,7 +733,6 @@ subroutine step_therm1 (dt, iblk) fswabs (:,:,iblk), flwout (:,:,iblk), & evap (:,:,iblk), & evap_ice(:,:,iblk), evap_snow (:,:,iblk), & - ice_freeboard(:,:,iblk), & Tref (:,:,iblk), Qref (:,:,iblk), & fresh (:,:,iblk), fsalt (:,:,iblk), & fhocn (:,:,iblk), fswthru (:,:,iblk), & diff --git a/source/ice_therm_vertical.F90 b/source/ice_therm_vertical.F90 index 4c5d495b..5e8ecb7a 100755 --- a/source/ice_therm_vertical.F90 +++ b/source/ice_therm_vertical.F90 @@ -91,7 +91,6 @@ subroutine thermo_vertical (nx_block, ny_block, & fcondbotn, & fsensn, flatn, & flwoutn, & - ice_freeboardn, & evapn, & evapn_ice, evapn_snow,& freshn, fsaltn, & @@ -193,10 +192,7 @@ subroutine thermo_vertical (nx_block, ny_block, & snoice , & ! snow-ice formation (m/step-->cm/day) dsnow , & ! change in snow thickness (m/step-->cm/day) mlt_onset, & ! day of year that sfc melting begins - frz_onset, & ! day of year that freezing begins (congel or frazil) - ice_freeboardn ! height of ice surface (i.e. not snow surface) - ! above sea level in m - + frz_onset ! day of year that freezing begins (congel or frazil) real (kind=dbl_kind), intent(in) :: & yday ! day of year @@ -287,7 +283,6 @@ subroutine thermo_vertical (nx_block, ny_block, & fhocnn (i,j) = c0 fadvocn(i,j) = c0 fcondbotn(i,j) = c0 - ice_freeboardn(i,j) = c0 evapn_ice(i,j)= c0 evapn_snow(i,j)=c0 @@ -517,7 +512,6 @@ subroutine thermo_vertical (nx_block, ny_block, & fbot, Tbot, & flatn, fsurfn, & fcondtopn, fcondbot, & - ice_freeboardn, & fsnow, hsn_new, & fhocnn, evapn, & evapn_ice, evapn_snow,& @@ -1460,7 +1454,6 @@ subroutine thickness_changes (nx_block, ny_block, & fbot, Tbot, & flatn, fsurfn, & fcondtopn, fcondbot, & - ice_freeboardn, & fsnow, hsn_new, & fhocnn, evapn, & evapn_ice, evapn_snow,& @@ -1522,10 +1515,7 @@ subroutine thickness_changes (nx_block, ny_block, & dsnow , & ! snow formation (m/step-->cm/day) iage , & ! ice age (s) mlt_onset , & ! day of year that sfc melting begins - frz_onset , & ! day of year that freezing begins (congel or frazil) - ice_freeboardn ! height of ice surface (i.e. not snow surface) - ! above sea level in m - + frz_onset ! day of year that freezing begins (congel or frazil) real (kind=dbl_kind), dimension (icells), & intent(inout) :: & @@ -2030,7 +2020,7 @@ subroutine thickness_changes (nx_block, ny_block, & hin, hsn, & zqin, zqsn, & dzi, dzs, & - dsnow, ice_freeboardn) + dsnow ) !---!------------------------------------------------------------------- !---! Repartition the ice and snow into equal-thickness layers, @@ -2233,7 +2223,7 @@ subroutine freeboard (nx_block, ny_block, & hin, hsn, & zqin, zqsn, & dzi, dzs, & - dsnow, ice_freeboardn) + dsnow ) integer (kind=int_kind), intent(in) :: & nx_block, ny_block, & ! block dimensions @@ -2252,12 +2242,6 @@ subroutine freeboard (nx_block, ny_block, & dsnow , & ! change in snow thickness after snow-ice formation (m) iage ! snow thickness (m) - real (kind=dbl_kind), dimension(nx_block,ny_block), & - intent(inout) :: & - ice_freeboardn ! height of ice surface (i.e. not snow surface) - ! above sea level in m - - real (kind=dbl_kind), dimension (icells), & intent(inout) :: & hin , & ! ice thickness (m) @@ -2366,16 +2350,6 @@ subroutine freeboard (nx_block, ny_block, & endif ! dhin > puny enddo ! ij - ! Calculate diagnostic sea ice freeboard after adjustments (SIMIP) - do ij = 1, icells - i = indxi(ij) - j = indxj(ij) - - ice_freeboardn(i,j) = & - hin(ij) * (1 - rhoi / rhow) - hsn(ij) * (rhos / rhow) - enddo - - end subroutine freeboard !======================================================================= From 387dc7bf99e6fe29b7527c5d8c0db4b39c13fd46 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 7 Oct 2025 11:43:55 +1100 Subject: [PATCH 39/80] use cice6 implementation for temperature diags --- source/ice_history.F90 | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 0d28d586..b0b6df18 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2141,7 +2141,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - worka(i,j) = aice(i,j,iblk)*(trcr(i,j,nt_Tsfc,iblk)+Tffresh) + worka(i,j) = trcr(i,j,nt_Tsfc,iblk)+Tffresh enddo enddo call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) @@ -2151,11 +2151,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - ! Tsnice is aice_init weighted in thermo_vertical , so adjust that first - ! then convert C->K and weight by aice (as intrinsic CMIP diag) - worka(i,j) = aice(i,j,iblk)*(Tsnice(i,j,iblk)/aice_init(i,j,iblk)+Tffresh) - endif + if (aice(i,j,iblk) > puny) worka(i,j) = Tsnice(i,j,iblk)+Tffresh enddo enddo call accum_hist_field(n_sitempsnic, iblk, worka(:,:), a2D) @@ -2165,8 +2161,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) & - worka(i,j) = aice(i,j,iblk)*(Ti_bot(i,j,iblk)/aice_init(i,j,iblk)+Tffresh) + if (aice(i,j,iblk) > puny) worka(i,j) = Ti_bot(i,j,iblk)+Tffresh enddo enddo call accum_hist_field(n_sitempbot, iblk, worka(:,:), a2D) From a6cd05b2736d0d3890ce788898b052cc42ce0735 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 7 Oct 2025 11:50:58 +1100 Subject: [PATCH 40/80] sisaltmass is extensive --- source/ice_history.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index b0b6df18..03f2c38f 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1374,7 +1374,7 @@ subroutine init_hist (dt) call define_hist_field(n_sisaltmass,"sisaltmass","kg m^-2",tstr2D, tcstr, & "mass of salt in sea ice (for ocean fluxes)",& "none", c1, c0, & - ns1, f_sisaltmass, avg_ice_present=.true., mask_ice_free_points=.true.) !To-do : check this ! + ns1, f_sisaltmass) endif ! if (histfreq(ns1) /= 'x') then enddo ! ns1 From 15656b4cf2da02049b7d6c0a03d098f7546c9504 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 7 Oct 2025 14:14:58 +1100 Subject: [PATCH 41/80] siitdconc --- source/ice_history.F90 | 11 ++++++++++- source/ice_history_shared.F90 | 10 ++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 03f2c38f..39cbd874 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -396,6 +396,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_siforcecorioly, master_task) call broadcast_scalar (f_siforceintstrx, master_task) call broadcast_scalar (f_siforceintstry, master_task) + call broadcast_scalar (f_siitdconc, master_task) call broadcast_scalar (f_aicen, master_task) call broadcast_scalar (f_vicen, master_task) call broadcast_scalar (f_vsnon, master_task) @@ -1446,6 +1447,14 @@ subroutine init_hist (dt) "multilayer scheme", c1, c0, & ns1, f_keffn_top) + ! CMIP 3D + call define_hist_field(n_aicen,"siitdconc","1",tstr3Dc, tcstr, & + "ice area, categories","none", c1, c0, & + ns1, f_siitdconc) + + ! siitdthick, siitdsnconc, siitdsnthick are not implemented because it's not clear how to + ! mask them when ice free (e.g. by aice or aicen ? ) + endif ! if (histfreq(ns1) /= 'x') then enddo ! ns1 @@ -2856,7 +2865,7 @@ subroutine accum_hist (dt) !3D category fields - if (f_aicen (1:1) /= 'x') & + if (f_aicen (1:1) /= 'x' .or. f_siitdconc (1:1) /= 'x') & call accum_hist_field(n_aicen-n2D, iblk, ncat_hist, & aicen(:,:,1:ncat_hist,iblk), a3Dc) if (f_vicen (1:1) /= 'x') & diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 59323a34..ad82c289 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -295,8 +295,9 @@ module ice_history_shared f_siflfwbot = 'x', & f_siflfwdrain = 'x', & f_sisaltmass = 'x', & - f_aicen = 'x', f_vicen = 'x', & - f_vsnon = 'x', & + f_aicen = 'x' , f_siitdconc = 'x', & !same var, two names + f_vicen = 'x', & + f_vsnon = 'x', & f_trsig = 'm', & f_icepresent = 'm', f_sitimefrac = 'x',& f_fsurf_ai = 'm', f_fcondtop_ai= 'm', & @@ -431,8 +432,9 @@ module ice_history_shared f_siflfwbot, & f_siflfwdrain, & f_sisaltmass, & - f_aicen, f_vicen , & - f_vsnon, & + f_aicen, f_siitdconc, & + f_vicen, & + f_vsnon, & f_trsig, & f_icepresent, f_sitimefrac,& !same var, two names f_fsurf_ai, f_fcondtop_ai,& From a42695829954e42de93998f1b006e3c638d0412b Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 7 Oct 2025 14:41:58 +1100 Subject: [PATCH 42/80] some tidyup and average sisndmasssubl by aice --- source/ice_history.F90 | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 39cbd874..5361f757 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1235,12 +1235,12 @@ subroutine init_hist (dt) call define_hist_field(n_sndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from evaporation and sublimation", & "none", c1, c0, & - ns1, f_sndmasssubl) + ns1, f_sndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmasssubl,"sisndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from evaporation and sublimation", & "none", c1, c0, & - ns1, f_sisndmasssubl) + ns1, f_sisndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true. ) call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from top ice melt", & @@ -2456,17 +2456,11 @@ subroutine accum_hist (dt) endif if (f_sidmassgrowthwat(1:1) /= 'x') then - !Sea-Ice Mass Change Through Growth in Supercooled Open Water (Frazil) - !To-do: revisit to see if frazil still needs aice/aice_init weighting - !Data can be noisy. Weighting not used in CICE6. - !Possibly if weighting is included, set avg_ice_present=.true., mask_ice_free_points=.true. worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then worka(i,j) = frazil(i,j,iblk)*rhoi/dt - ! worka(i,j) = aice(i,j,iblk)*frazil(i,j,iblk)*rhoi / & - ! (dt*aice_init(i,j,iblk)) endif enddo enddo @@ -2474,14 +2468,11 @@ subroutine accum_hist (dt) endif if (f_sidmassgrowthbot(1:1) /= 'x') then - !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then worka(i,j) = congel(i,j,iblk)*rhoi/dt - ! worka(i,j) = aice(i,j,iblk)*congel(i,j,iblk)*rhoi / & - ! (dt *aice_init(i,j,iblk)) endif enddo enddo @@ -2489,14 +2480,11 @@ subroutine accum_hist (dt) endif if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') then - !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice_init(i,j,iblk) > puny) then worka(i,j) = snoice(i,j,iblk)*rhoi/dt - ! worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi /& - ! (dt * aice_init(i,j,iblk)) endif enddo enddo @@ -2522,7 +2510,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk) + worka(i,j) = evap_ice(i,j,iblk) endif enddo enddo From 34759cd7703b299e4eaf1d92b21ca0563e69556b Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 7 Oct 2025 14:51:13 +1100 Subject: [PATCH 43/80] snow mass melt should be grid cell average --- source/ice_history.F90 | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 5361f757..24b6c7c8 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1235,12 +1235,12 @@ subroutine init_hist (dt) call define_hist_field(n_sndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from evaporation and sublimation", & "none", c1, c0, & - ns1, f_sndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true.) + ns1, f_sndmasssubl) call define_hist_field(n_sndmasssubl,"sisndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from evaporation and sublimation", & "none", c1, c0, & - ns1, f_sisndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true. ) + ns1, f_sisndmasssubl) call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from top ice melt", & @@ -1275,12 +1275,12 @@ subroutine init_hist (dt) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from melt", & "none", c1, c0, & - ns1, f_sndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) + ns1, f_sndmassmelt) call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from melt", & "none", c1, c0, & - ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) + ns1, f_sisndmassmelt) call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change through snow to ice conversion", & @@ -2510,7 +2510,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = evap_ice(i,j,iblk) + worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk) endif enddo enddo @@ -2592,15 +2592,11 @@ subroutine accum_hist (dt) endif if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') then - !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then worka(i,j) = melts(i,j,iblk)*rhos/dt - ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = aice(i,j,iblk)*melts(i,j,iblk)*rhos/ & - ! (dt *aice_init(i,j,iblk)) endif enddo enddo From c549af9c244e0c0314b0773b072f9f488d1ff62b Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 7 Oct 2025 15:53:52 +1100 Subject: [PATCH 44/80] average all snow by aice --- source/ice_history.F90 | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 24b6c7c8..a4f8ae14 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1235,12 +1235,12 @@ subroutine init_hist (dt) call define_hist_field(n_sndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from evaporation and sublimation", & "none", c1, c0, & - ns1, f_sndmasssubl) + ns1, f_sndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmasssubl,"sisndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from evaporation and sublimation", & "none", c1, c0, & - ns1, f_sisndmasssubl) + ns1, f_sisndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "sea ice mass change from top ice melt", & @@ -1275,12 +1275,12 @@ subroutine init_hist (dt) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from melt", & "none", c1, c0, & - ns1, f_sndmassmelt) + ns1, f_sndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change from melt", & "none", c1, c0, & - ns1, f_sisndmassmelt) + ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "snow mass change through snow to ice conversion", & @@ -2497,8 +2497,8 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then - worka(i,j) = -c1*snoice(i,j,iblk)*rhoi/dt + if (aice(i,j,iblk) > puny) then + worka(i,j) = -c1*aice(i,j,iblk)*snoice(i,j,iblk)*rhoi/dt endif enddo enddo @@ -2530,7 +2530,6 @@ subroutine accum_hist (dt) endif if (f_sidmassmelttop(1:1) /= 'x') then - !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2596,7 +2595,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = melts(i,j,iblk)*rhos/dt + worka(i,j) = aice(i,j,iblk)*melts(i,j,iblk)*rhos/dt endif enddo enddo From b09a9851931ca0b3618cd69f00f91d770ae5e805 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 9 Oct 2025 12:03:07 +1100 Subject: [PATCH 45/80] fix sivol --- source/ice_history.F90 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index a4f8ae14..1d1eeb7a 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -232,6 +232,7 @@ subroutine init_hist (dt) ! call broadcast_scalar (f_example, master_task) call broadcast_scalar (f_hi, master_task) + call broadcast_scalar (f_sivol, master_task) call broadcast_scalar (f_hs, master_task) call broadcast_scalar (f_snowfrac, master_task) call broadcast_scalar (f_snowfracn, master_task) @@ -2776,10 +2777,10 @@ subroutine accum_hist (dt) ! rho_ice = rho_ice / real(nzilyr,kind=dbl_kind) endif worka(i,j) = ((rho_ocn-rho_ice)*vice(i,j,iblk) - rhos*vsno(i,j,iblk))/rho_ocn - if (worka(i,j) < c0) then - write(nu_diag,*) 'negative fb',rho_ocn,rho_ice,rhos - write(nu_diag,*) vice(i,j,iblk),vsno(i,j,iblk) - endif + ! if (worka(i,j) < c0) then + ! write(nu_diag,*) 'negative fb',rho_ocn,rho_ice,rhos + ! write(nu_diag,*) vice(i,j,iblk),vsno(i,j,iblk) + ! endif endif enddo enddo From 1db42f3907c81514a2af13785412d8b46df2128e Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 13 Oct 2025 11:49:54 +1100 Subject: [PATCH 46/80] Some fixes: move C->K conversion to better spo_edit_gsi fix sisndmasssubl etc --- source/ice_history.F90 | 43 +++++++++++++++++++++++------------------ source/ice_step_mod.F90 | 4 +++- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 1d1eeb7a..d3081324 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1075,17 +1075,17 @@ subroutine init_hist (dt) call define_hist_field(n_sitemptop,"sitemptop","K",tstr2D, tcstr, & "sea ice surface temperature", & - "none", c1, c0, & + "none", c1, Tffresh, & ns1, f_sitemptop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitempsnic,"sitempsnic","K",tstr2D, tcstr, & "snow ice interface temperature", & - "surface temperature when no snow present", c1, c0, & + "surface temperature when no snow present", c1, Tffresh, & ns1, f_sitempsnic, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitempbot,"sitempbot","K",tstr2D, tcstr, & "sea ice bottom temperature", & - "none", c1, c0, & + "none", c1, Tffresh, & ns1, f_sitempbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siu,"siu","m/s",ustr2D, ucstr, & @@ -2151,7 +2151,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - worka(i,j) = trcr(i,j,nt_Tsfc,iblk)+Tffresh + worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk) enddo enddo call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) @@ -2161,7 +2161,8 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) worka(i,j) = Tsnice(i,j,iblk)+Tffresh + if (aice(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk)*Tsnice(i,j,iblk) enddo enddo call accum_hist_field(n_sitempsnic, iblk, worka(:,:), a2D) @@ -2171,7 +2172,8 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) worka(i,j) = Ti_bot(i,j,iblk)+Tffresh + if (aice(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk)*Ti_bot(i,j,iblk) enddo enddo call accum_hist_field(n_sitempbot, iblk, worka(:,:), a2D) @@ -2236,11 +2238,11 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmasstrany, iblk, worka(:,:), a2D) endif - !to-do: scale by aice/aice_init as its a calculated based on initial state ? if (f_sistrxdtop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + !to-do: scale by aice/aice_init as its a calculated based on initial state ? if (aice(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk)*strairx(i,j,iblk) enddo @@ -2248,11 +2250,11 @@ subroutine accum_hist (dt) call accum_hist_field(n_sistrxdtop, iblk, worka(:,:), a2D) endif - !to-do: scale by aice/aice_init ? if (f_sistrydtop(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + !to-do: scale by aice/aice_init ? if (aice(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk)*strairy(i,j,iblk) enddo @@ -2499,7 +2501,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = -c1*aice(i,j,iblk)*snoice(i,j,iblk)*rhoi/dt + worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi/dt endif enddo enddo @@ -2527,7 +2529,7 @@ subroutine accum_hist (dt) endif enddo enddo - call accum_hist_field(n_sidmasssubl, iblk, worka(:,:), a2D) + call accum_hist_field(n_sndmasssubl, iblk, worka(:,:), a2D) endif if (f_sidmassmelttop(1:1) /= 'x') then @@ -2536,9 +2538,12 @@ subroutine accum_hist (dt) do i = ilo, ihi if (aice(i,j,iblk) > puny) then worka(i,j) = meltt(i,j,iblk)*rhoi/dt + ! arguably meltt is calculated by thermodynamics only, and is not + ! advected during dynamics, and so should be corrected for aice_init + ! e.g.: ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi /& - ! (dt * aice_init(i,j,iblk)) + ! worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi /& + ! (dt * aice_init(i,j,iblk)) endif enddo enddo @@ -2546,15 +2551,15 @@ subroutine accum_hist (dt) endif if (f_sidmassmeltbot(1:1) /= 'x') then - !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then worka(i,j) = meltb(i,j,iblk)*rhoi/dt - ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & - ! (dt * aice_init(i,j,iblk)) + ! arguably corrected to aice_init + ! if (aice_init(i,j,iblk) > puny) then + ! worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & + ! (dt * aice_init(i,j,iblk)) endif enddo enddo @@ -2562,15 +2567,15 @@ subroutine accum_hist (dt) endif if (f_sidmasslat(1:1) /= 'x' .or. f_sidmassmeltlat(1:1) /= 'x') then - !To-do: revisit to see if still needs aice/aice_init weighting worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then worka(i,j) = meltl(i,j,iblk)*rhoi/dt + ! arguably corrected to aice_init ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & - ! (dt * aice_init(i,j,iblk)) + ! worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & + ! (dt * aice_init(i,j,iblk)) endif enddo enddo diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index 8de5fdb4..723db6a8 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -746,7 +746,9 @@ subroutine step_therm1 (dt, iblk) enddo ! ncat - Ti_bot(:,:,iblk) = Tbot(:,:) * aice(:,:,iblk) + ! Tsnice is diagnostic only, it aggregated over ice thickness cats in thermo_vertical, + ! return to temperature over ice only + Tsnice(:,:,iblk) = Tsnice(:,:,iblk)/aice(:,:,iblk) !----------------------------------------------------------------- ! Calculate ponds from the topographic scheme From 5da106164806770e9143699e2bee97c21e344869 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 13 Oct 2025 13:17:24 +1100 Subject: [PATCH 47/80] better Tsnice weighting --- source/ice_step_mod.F90 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index 723db6a8..9678f127 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -748,8 +748,12 @@ subroutine step_therm1 (dt, iblk) ! Tsnice is diagnostic only, it aggregated over ice thickness cats in thermo_vertical, ! return to temperature over ice only - Tsnice(:,:,iblk) = Tsnice(:,:,iblk)/aice(:,:,iblk) - + do j = 1, ny_block + do i = 1, nx_block + if (tmask(i,j) .and. aice(i,j) > c0) & + Tsnice(i,j,iblk) = Tsnice(i,j,iblk)/aice(i,j,iblk) + enddo + enddo !----------------------------------------------------------------- ! Calculate ponds from the topographic scheme !----------------------------------------------------------------- From aafe5989c8577b7249ad2eb62a5252119953ce69 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 13 Oct 2025 13:40:45 +1100 Subject: [PATCH 48/80] better Tsnice weighting --- source/ice_step_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index 9678f127..7d3bdf47 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -750,7 +750,7 @@ subroutine step_therm1 (dt, iblk) ! return to temperature over ice only do j = 1, ny_block do i = 1, nx_block - if (tmask(i,j) .and. aice(i,j) > c0) & + if (tmask(i,j,iblk) .and. aice(i,j,iblk) > c0) & Tsnice(i,j,iblk) = Tsnice(i,j,iblk)/aice(i,j,iblk) enddo enddo From 79ad707777d19d5cfa509d92e043b07638ff5a10 Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:18:25 +1100 Subject: [PATCH 49/80] Apply suggestion from @anton-seaice --- source/ice_step_mod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index 7d3bdf47..e38e9a53 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -751,6 +751,7 @@ subroutine step_therm1 (dt, iblk) do j = 1, ny_block do i = 1, nx_block if (tmask(i,j,iblk) .and. aice(i,j,iblk) > c0) & + Ti_bot(i,j,iblk) = Tbot(i,j) * aice(i,j,iblk) Tsnice(i,j,iblk) = Tsnice(i,j,iblk)/aice(i,j,iblk) enddo enddo From 62dcb7ee19f6e0a71d4b8e3e548b8cece0b930cf Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 14 Oct 2025 08:41:36 +1100 Subject: [PATCH 50/80] syntax --- source/ice_step_mod.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index e38e9a53..d4f95393 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -750,9 +750,10 @@ subroutine step_therm1 (dt, iblk) ! return to temperature over ice only do j = 1, ny_block do i = 1, nx_block - if (tmask(i,j,iblk) .and. aice(i,j,iblk) > c0) & + if (tmask(i,j,iblk) .and. aice(i,j,iblk) > c0) then Ti_bot(i,j,iblk) = Tbot(i,j) * aice(i,j,iblk) Tsnice(i,j,iblk) = Tsnice(i,j,iblk)/aice(i,j,iblk) + endif enddo enddo !----------------------------------------------------------------- From 8c7035f6979659de2568ac08d2f93edb870b77f0 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Wed, 15 Oct 2025 08:46:06 +1100 Subject: [PATCH 51/80] Fix name for sivol var Calculate Tsfc tracer without open water set to Tf (unclear if this is important) Remove dougle weighting for Ti_bot --- source/ice_history.F90 | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index d3081324..28c8d5f1 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -451,7 +451,7 @@ subroutine init_hist (dt) "ice volume per unit grid cell area", c1, c0, & ns1, f_hi) - call define_hist_field(n_hi,"hi","m",tstr2D, tcstr, & + call define_hist_field(n_hi,"sivol","m",tstr2D, tcstr, & "grid cell mean ice thickness", & "ice volume per unit grid cell area", c1, c0, & ns1, f_sivol) @@ -2150,8 +2150,12 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) & - worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_Tsfc,iblk) + ! trcr(:,:,nt_Tsfc,:) includes Tfrz where open-water + ! we want ice-are temperature only, so calculate from each thickness cat + do n = 1, ncat_hist + if (aicen(i,j,n,iblk) > puny) & + worka(i,j) = worka(i,j) + aicen(i,j,n,iblk)*trcrn(i,j,nt_Tsfc,n,iblk) + enddo enddo enddo call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) @@ -2173,7 +2177,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - worka(i,j) = aice(i,j,iblk)*Ti_bot(i,j,iblk) + worka(i,j) = Ti_bot(i,j,iblk) + !nb Ti_bot already aice weighted https://github.com/ACCESS-NRI/cice5/blob/62dcb7ee19f6e0a71d4b8e3e548b8cece0b930cf/source/ice_step_mod.F90#L754 enddo enddo call accum_hist_field(n_sitempbot, iblk, worka(:,:), a2D) @@ -2513,7 +2518,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*evap_ice(i,j,iblk) + worka(i,j) = evap_ice(i,j,iblk) endif enddo enddo From acbecafd44ea60785b10371e039e95c775ffb49c Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 17 Oct 2025 14:57:20 +1100 Subject: [PATCH 52/80] test with aice_init masking --- source/ice_history.F90 | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 28c8d5f1..b26efb34 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -212,6 +212,15 @@ subroutine init_hist (dt) if (f_Tinz (1:1) /= 'x' .or. f_Sinz (1:1) /= 'x') f_VGRDi = .true. if (f_Tsnz (1:1) /= 'x') f_VGRDs = .true. +#ifdef ACCESS + if ( f_siflsenstop /= 'x' ) call abort_ice("f_siflsenstop not available, set to 'x'") + if ( f_sifllattop /= 'x' ) call abort_ice("f_sifllattop not available, set to 'x'") + if ( f_sifllwdtop /= 'x' ) call abort_ice("f_sifllwdtop not available, set to 'x'") + if ( f_sifllwutop /= 'x' ) call abort_ice("f_sifllwutop not available, set to 'x'") + if ( f_siflswdtop /= 'x' ) call abort_ice("f_siflswdtop not available, set to 'x'") + if ( f_siflswutop /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") +#endif + call broadcast_scalar (f_tmask, master_task) call broadcast_scalar (f_blkmask, master_task) call broadcast_scalar (f_tarea, master_task) @@ -2150,13 +2159,15 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - ! trcr(:,:,nt_Tsfc,:) includes Tfrz where open-water - ! we want ice-are temperature only, so calculate from each thickness cat - do n = 1, ncat_hist - if (aicen(i,j,n,iblk) > puny) & - worka(i,j) = worka(i,j) + aicen(i,j,n,iblk)*trcrn(i,j,nt_Tsfc,n,iblk) - enddo - enddo + if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then + ! trcr(:,:,nt_Tsfc,:) includes Tfrz where open-water + ! we want ice-are temperature only, so calculate from each thickness cat + do n = 1, ncat_hist + if (aicen(i,j,n,iblk) > puny) & + worka(i,j) = worka(i,j) + aicen(i,j,n,iblk)*trcrn(i,j,nt_Tsfc,n,iblk) + enddo + endif + enddo enddo call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) endif @@ -2165,7 +2176,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) & + if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk)*Tsnice(i,j,iblk) enddo enddo @@ -2176,7 +2187,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny) & + if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) & worka(i,j) = Ti_bot(i,j,iblk) !nb Ti_bot already aice weighted https://github.com/ACCESS-NRI/cice5/blob/62dcb7ee19f6e0a71d4b8e3e548b8cece0b930cf/source/ice_step_mod.F90#L754 enddo From 6781f6265616584af3223ae2b07ed42963bb2e71 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 17 Oct 2025 15:13:30 +1100 Subject: [PATCH 53/80] test with aice_init masking --- source/ice_history.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index b26efb34..6d34ed42 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -214,7 +214,7 @@ subroutine init_hist (dt) #ifdef ACCESS if ( f_siflsenstop /= 'x' ) call abort_ice("f_siflsenstop not available, set to 'x'") - if ( f_sifllattop /= 'x' ) call abort_ice("f_sifllattop not available, set to 'x'") + ! if ( f_sifllattop /= 'x' ) call abort_ice("f_sifllattop not available, set to 'x'") if ( f_sifllwdtop /= 'x' ) call abort_ice("f_sifllwdtop not available, set to 'x'") if ( f_sifllwutop /= 'x' ) call abort_ice("f_sifllwutop not available, set to 'x'") if ( f_siflswdtop /= 'x' ) call abort_ice("f_siflswdtop not available, set to 'x'") From d15555b3f8f097d92569755ec2d038efdfdaf86a Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 20 Oct 2025 15:39:37 +1100 Subject: [PATCH 54/80] some error handling and moving of aice weighting --- source/ice_history.F90 | 22 ++++++++++------------ source/ice_step_mod.F90 | 3 ++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 6d34ed42..5cf75927 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -197,8 +197,12 @@ subroutine init_hist (dt) ! (if using multilayers with UM-style coupling) if (calc_Tsfc .or. .not. heat_capacity) then !to-do: abort here if trying to use these - f_Tn_top = 'x' - f_keffn_top = 'x' + if (f_Tn_top /= 'x') call abort_ice("f_Tn_top not available, set to 'x'") + if (f_keffn_top /= 'x') call abort_ice("f_Tn_top not available, set to 'x' ") + endif + + if ( .not. calc_Tsfc) then + if (f_Tair /= 'x') call abort_ice ("f_Tn_top not available with calc_Tsfc = .false., set to 'x'") endif #ifndef ncdf @@ -2156,16 +2160,11 @@ subroutine accum_hist (dt) endif if (f_sitemptop(1:1) /= 'x') then - worka(:,:) = c0 + worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - ! trcr(:,:,nt_Tsfc,:) includes Tfrz where open-water - ! we want ice-are temperature only, so calculate from each thickness cat - do n = 1, ncat_hist - if (aicen(i,j,n,iblk) > puny) & - worka(i,j) = worka(i,j) + aicen(i,j,n,iblk)*trcrn(i,j,nt_Tsfc,n,iblk) - enddo + worka(i,j) = aice(i,j,iblk) * trcr(:,:,nt_Tsfc,iblk) endif enddo enddo @@ -2187,9 +2186,8 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) & - worka(i,j) = Ti_bot(i,j,iblk) - !nb Ti_bot already aice weighted https://github.com/ACCESS-NRI/cice5/blob/62dcb7ee19f6e0a71d4b8e3e548b8cece0b930cf/source/ice_step_mod.F90#L754 + if (aice(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk)*Ti_bot(i,j,iblk) enddo enddo call accum_hist_field(n_sitempbot, iblk, worka(:,:), a2D) diff --git a/source/ice_step_mod.F90 b/source/ice_step_mod.F90 index d4f95393..7235956d 100755 --- a/source/ice_step_mod.F90 +++ b/source/ice_step_mod.F90 @@ -391,6 +391,7 @@ subroutine step_therm1 (dt, iblk) endif Tsnice(:,:,iblk) = c0 + Ti_bot(:,:,iblk) = c0 do n = 1, ncat @@ -751,7 +752,7 @@ subroutine step_therm1 (dt, iblk) do j = 1, ny_block do i = 1, nx_block if (tmask(i,j,iblk) .and. aice(i,j,iblk) > c0) then - Ti_bot(i,j,iblk) = Tbot(i,j) * aice(i,j,iblk) + Ti_bot(i,j,iblk) = Tbot(i,j) Tsnice(i,j,iblk) = Tsnice(i,j,iblk)/aice(i,j,iblk) endif enddo From cf9c0ebfda34056f2219f6cac236471338168db5 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 20 Oct 2025 15:56:39 +1100 Subject: [PATCH 55/80] some error handling and moving of aice weighting --- source/ice_history.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 5cf75927..fa6baf7a 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2164,7 +2164,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk) * trcr(:,:,nt_Tsfc,iblk) + worka(i,j) = aice(i,j,iblk) * trcr(i,j,nt_Tsfc,iblk) endif enddo enddo From ac52cb612e092684c5e154830085357148be8189 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 20 Oct 2025 16:30:07 +1100 Subject: [PATCH 56/80] corrections --- source/ice_history.F90 | 9 +++++++-- source/ice_history_shared.F90 | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index fa6baf7a..63275a57 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -198,11 +198,11 @@ subroutine init_hist (dt) if (calc_Tsfc .or. .not. heat_capacity) then !to-do: abort here if trying to use these if (f_Tn_top /= 'x') call abort_ice("f_Tn_top not available, set to 'x'") - if (f_keffn_top /= 'x') call abort_ice("f_Tn_top not available, set to 'x' ") + if (f_keffn_top /= 'x') call abort_ice("f_keffn_top not available, set to 'x' ") endif if ( .not. calc_Tsfc) then - if (f_Tair /= 'x') call abort_ice ("f_Tn_top not available with calc_Tsfc = .false., set to 'x'") + if (f_Tair /= 'x') call abort_ice ("f_Tair not available with calc_Tsfc = .false., set to 'x'") endif #ifndef ncdf @@ -2100,6 +2100,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! sithick is intensive, vice is already aice*thickness if (aice(i,j,iblk) > puny) worka(i,j) = vice(i,j,iblk) enddo enddo @@ -2110,6 +2111,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! simass is extensive, -> grid cell average if (aice(i,j,iblk) > puny) worka(i,j) = rhoi*vice(i,j,iblk) enddo enddo @@ -2120,6 +2122,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! siage is intensive, weight each timestep by aice if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_iage,iblk) enddo enddo @@ -2130,6 +2133,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! siage is intensive, weight each timestep by aice if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk) * snowfrac(i,j,iblk) enddo @@ -2141,6 +2145,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! sisnthick is intensive, vsno is already aice*thickness if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & worka(i,j) = vsno(i,j,iblk) enddo diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index ad82c289..9654639c 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -306,7 +306,7 @@ module ice_history_shared f_fmelttn_ai= 'x', f_flatn_ai = 'x', & f_fsensn_ai = 'x', & ! f_field3dz = 'x', & - f_Tn_top = 'm', f_keffn_top = 'm', & + f_Tn_top = 'x', f_keffn_top = 'x', & f_Tinz = 'x', f_Sinz = 'x', & f_Tsnz = 'x', & f_a11 = 'x', f_a12 = 'x', & From d8e6797b4b576fa953fcb7704bc62fed4f480017 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 20 Oct 2025 16:55:36 +1100 Subject: [PATCH 57/80] corrections --- source/ice_history.F90 | 115 +++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 63275a57..6fc35fe1 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -159,71 +159,73 @@ subroutine init_hist (dt) enddo enddo - if (.not. tr_iage) then - !todo: abort here if trying to use these diagnostics and the tracer (and its restart) are not available - f_iage = 'x' - f_siage = 'x' - f_dagedtt = 'x' - f_dagedtd = 'x' - endif - if (.not. tr_FY) f_FY = 'x' - - if (kdyn /= 2) then - f_a11 = 'x' - f_a12 = 'x' - f_e11 = 'x' - f_e12 = 'x' - f_e22 = 'x' - f_s11 = 'x' - f_s12 = 'x' - f_s22 = 'x' - f_yieldstress11 = 'x' - f_yieldstress12 = 'x' - f_yieldstress22 = 'x' - endif + if ( my_task = master_task ) then !check history configuration + if (.not. tr_iage) then + !todo: abort here if trying to use these diagnostics and the tracer (and its restart) are not available + f_iage = 'x' + f_siage = 'x' + f_dagedtt = 'x' + f_dagedtd = 'x' + endif + if (.not. tr_FY) f_FY = 'x' + + if (kdyn /= 2) then + f_a11 = 'x' + f_a12 = 'x' + f_e11 = 'x' + f_e12 = 'x' + f_e22 = 'x' + f_s11 = 'x' + f_s12 = 'x' + f_s22 = 'x' + f_yieldstress11 = 'x' + f_yieldstress12 = 'x' + f_yieldstress22 = 'x' + endif - ! these must be output at the same frequency because of - ! cos(zenith angle) averaging - if (f_albice(1:1) /= 'x' .and. f_albsni(1:1) /= 'x') f_albice = f_albsni - if (f_albsno(1:1) /= 'x') f_albsno = f_albice - if (f_albpnd(1:1) /= 'x') f_albpnd = f_albice - if (f_coszen(1:1) /= 'x' .and. f_albice(1:1) /= 'x') f_coszen = f_albice - if (f_coszen(1:1) /= 'x' .and. f_albsni(1:1) /= 'x') f_coszen = f_albsni - - ! to prevent array-out-of-bounds when aggregating - if (f_fmeltt_ai(1:1) /= 'x') f_fmelttn_ai = f_fmeltt_ai - - ! AEW: These are only calculated under certain circumstances - ! (if using multilayers with UM-style coupling) - if (calc_Tsfc .or. .not. heat_capacity) then - !to-do: abort here if trying to use these - if (f_Tn_top /= 'x') call abort_ice("f_Tn_top not available, set to 'x'") - if (f_keffn_top /= 'x') call abort_ice("f_keffn_top not available, set to 'x' ") - endif + ! these must be output at the same frequency because of + ! cos(zenith angle) averaging + if (f_albice(1:1) /= 'x' .and. f_albsni(1:1) /= 'x') f_albice = f_albsni + if (f_albsno(1:1) /= 'x') f_albsno = f_albice + if (f_albpnd(1:1) /= 'x') f_albpnd = f_albice + if (f_coszen(1:1) /= 'x' .and. f_albice(1:1) /= 'x') f_coszen = f_albice + if (f_coszen(1:1) /= 'x' .and. f_albsni(1:1) /= 'x') f_coszen = f_albsni + + ! to prevent array-out-of-bounds when aggregating + if (f_fmeltt_ai(1:1) /= 'x') f_fmelttn_ai = f_fmeltt_ai + + ! AEW: These are only calculated under certain circumstances + ! (if using multilayers with UM-style coupling) + if (calc_Tsfc .or. .not. heat_capacity) then + !to-do: abort here if trying to use these + if (f_Tn_top /= 'x') call abort_ice("f_Tn_top not available, set to 'x'") + if (f_keffn_top /= 'x') call abort_ice("f_keffn_top not available, set to 'x' ") + endif - if ( .not. calc_Tsfc) then - if (f_Tair /= 'x') call abort_ice ("f_Tair not available with calc_Tsfc = .false., set to 'x'") - endif + if ( .not. calc_Tsfc) then + if (f_Tair /= 'x') call abort_ice ("f_Tair not available with calc_Tsfc = .false., set to 'x'") + endif #ifndef ncdf - f_bounds = .false. + f_bounds = .false. #endif - ! write dimensions for 3D or 4D history variables - ! note: list of variables checked here is incomplete - if (f_aicen(1:1) /= 'x' .or. f_vicen(1:1) /= 'x' .or. & - f_Tinz (1:1) /= 'x' .or. f_Sinz (1:1) /= 'x') f_NCAT = .true. - if (f_Tinz (1:1) /= 'x' .or. f_Sinz (1:1) /= 'x') f_VGRDi = .true. - if (f_Tsnz (1:1) /= 'x') f_VGRDs = .true. + ! write dimensions for 3D or 4D history variables + ! note: list of variables checked here is incomplete + if (f_aicen(1:1) /= 'x' .or. f_vicen(1:1) /= 'x' .or. & + f_Tinz (1:1) /= 'x' .or. f_Sinz (1:1) /= 'x') f_NCAT = .true. + if (f_Tinz (1:1) /= 'x' .or. f_Sinz (1:1) /= 'x') f_VGRDi = .true. + if (f_Tsnz (1:1) /= 'x') f_VGRDs = .true. #ifdef ACCESS - if ( f_siflsenstop /= 'x' ) call abort_ice("f_siflsenstop not available, set to 'x'") - ! if ( f_sifllattop /= 'x' ) call abort_ice("f_sifllattop not available, set to 'x'") - if ( f_sifllwdtop /= 'x' ) call abort_ice("f_sifllwdtop not available, set to 'x'") - if ( f_sifllwutop /= 'x' ) call abort_ice("f_sifllwutop not available, set to 'x'") - if ( f_siflswdtop /= 'x' ) call abort_ice("f_siflswdtop not available, set to 'x'") - if ( f_siflswutop /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") + if ( f_siflsenstop /= 'x' ) call abort_ice("f_siflsenstop not available, set to 'x'") + ! if ( f_sifllattop /= 'x' ) call abort_ice("f_sifllattop not available, set to 'x'") + if ( f_sifllwdtop /= 'x' ) call abort_ice("f_sifllwdtop not available, set to 'x'") + if ( f_sifllwutop /= 'x' ) call abort_ice("f_sifllwutop not available, set to 'x'") + if ( f_siflswdtop /= 'x' ) call abort_ice("f_siflswdtop not available, set to 'x'") + if ( f_siflswutop /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") #endif + endif ! end check history config call broadcast_scalar (f_tmask, master_task) call broadcast_scalar (f_blkmask, master_task) @@ -2169,6 +2171,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then + ! Tsfc is a tracer, so we shouldn't need aice_init here ! worka(i,j) = aice(i,j,iblk) * trcr(i,j,nt_Tsfc,iblk) endif enddo From 62fd66f37e0ca6493fe0ccd8f4d0f86beb111039 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 23 Oct 2025 09:41:04 +1100 Subject: [PATCH 58/80] reorder avg_ice_present and conb steps so that temp diagnostics work --- source/ice_history.F90 | 51 ++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 6fc35fe1..a161efe8 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -159,7 +159,7 @@ subroutine init_hist (dt) enddo enddo - if ( my_task = master_task ) then !check history configuration + if ( my_task == master_task ) then !check history configuration if (.not. tr_iage) then !todo: abort here if trying to use these diagnostics and the tracer (and its restart) are not available f_iage = 'x' @@ -197,15 +197,22 @@ subroutine init_hist (dt) ! AEW: These are only calculated under certain circumstances ! (if using multilayers with UM-style coupling) if (calc_Tsfc .or. .not. heat_capacity) then - !to-do: abort here if trying to use these if (f_Tn_top /= 'x') call abort_ice("f_Tn_top not available, set to 'x'") if (f_keffn_top /= 'x') call abort_ice("f_keffn_top not available, set to 'x' ") endif - if ( .not. calc_Tsfc) then + if ( .not. calc_Tsfc ) then if (f_Tair /= 'x') call abort_ice ("f_Tair not available with calc_Tsfc = .false., set to 'x'") endif + if ( .not. calc_Tsfc .and. .not. heat_capacity) then ! access-esm1.6 + ! surface temperature is neither coupled or calculated within cice + ! prognostic in the UM only + if (f_Tsfc /= 'x') call abort_ice ("f_Tsfc not available, set to 'x'") + if (f_sitemptop /= 'x') call abort_ice ("f_sitemptop not available, set to 'x'") + if (f_sitempsnic /= 'x') call abort_ice ("f_sitempsnic not available, set to 'x'") + endif + #ifndef ncdf f_bounds = .false. #endif @@ -2170,8 +2177,8 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - ! Tsfc is a tracer, so we shouldn't need aice_init here ! + if (aice(i,j,iblk) > puny) then + ! Tsfc is a tracer, so was advected during dynamics, so we shouldn't need aice_init here ! worka(i,j) = aice(i,j,iblk) * trcr(i,j,nt_Tsfc,iblk) endif enddo @@ -2183,7 +2190,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) & + if (aice(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk)*Tsnice(i,j,iblk) enddo enddo @@ -2264,7 +2271,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - !to-do: scale by aice/aice_init as its a calculated based on initial state ? + !to-do: scale by aice/aice_init as its a calculated based on coupled state ? if (aice(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk)*strairx(i,j,iblk) enddo @@ -3090,6 +3097,13 @@ subroutine accum_hist (dt) do n = 1, num_avail_hist_fields_2D if (avail_hist_fields(n)%vhistfreq == histfreq(ns)) then + ! Only average for timesteps when ice present + if (avail_hist_fields(n)%avg_ice_present) then + a2D(:,:,n,iblk) = a2D(:,:,n,iblk)*ravgip(:,:) + else + a2D(:,:,n,iblk) = a2D(:,:,n,iblk)*ravgct + endif + do j = jlo, jhi do i = ilo, ihi #ifdef AusCOM @@ -3098,14 +3112,14 @@ subroutine accum_hist (dt) a2D(i,j,n,iblk) = spval_dbl else ! convert units a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & - * ravgct + avail_hist_fields(n)%conb + + avail_hist_fields(n)%conb endif else if (.not. tmask(i,j,iblk)) then ! mask out land points a2D(i,j,n,iblk) = spval_dbl else ! convert units a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & - * ravgct + avail_hist_fields(n)%conb + + avail_hist_fields(n)%conb endif endif #else @@ -3113,26 +3127,15 @@ subroutine accum_hist (dt) a2D(i,j,n,iblk) = spval_dbl else ! convert units a2D(i,j,n,iblk) = avail_hist_fields(n)%cona*a2D(i,j,n,iblk) & - * ravgct + avail_hist_fields(n)%conb + + avail_hist_fields(n)%conb endif #endif enddo ! i enddo ! j - ! Only average for timesteps when ice present - if (avail_hist_fields(n)%avg_ice_present) then - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a2D(i,j,n,iblk) = & - a2D(i,j,n,iblk)*avgct(ns)*ravgip(i,j) - endif - ! Mask ice-free points - if (avail_hist_fields(n)%mask_ice_free_points) then - if (ravgip(i,j) == c0) a2D(i,j,n,iblk) = spval_dbl - endif - enddo ! i - enddo ! j + ! Mask ice-free points + if (avail_hist_fields(n)%mask_ice_free_points) then + where(ravgip(:,:) == c0) a2D(:,:,n,iblk) = spval_dbl endif ! CMIP albedo: also mask points below horizon From 22dcdf9a29c825b7a42573a4ff6ba0cb12f1d739 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 23 Oct 2025 09:41:21 +1100 Subject: [PATCH 59/80] fixes to metadata --- io_netcdf/ice_history_write.F90 | 52 +++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/io_netcdf/ice_history_write.F90 b/io_netcdf/ice_history_write.F90 index 75014d23..d7fec3b8 100644 --- a/io_netcdf/ice_history_write.F90 +++ b/io_netcdf/ice_history_write.F90 @@ -668,6 +668,11 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) call check(nf90_put_att(ncid,varid,'cell_measures', & avail_hist_fields(n)%vcellmeas), & 'put att cell_measures '//avail_hist_fields(n)%vname) + if (avail_hist_fields(n)%vcomment /= "none") then + call check(nf90_put_att(ncid,varid,'comment', & + avail_hist_fields(n)%vcomment), & + 'put att comment '//avail_hist_fields(n)%vname) + endif call check(nf90_put_att(ncid,varid,'missing_value',spval), & 'put att missing_value '//avail_hist_fields(n)%vname) call check(nf90_put_att(ncid,varid,'_FillValue',spval), & @@ -680,8 +685,15 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) if (TRIM(avail_hist_fields(n)%vname)/='sig1' .or. & TRIM(avail_hist_fields(n)%vname)/='sig2') then - call check(nf90_put_att(ncid,varid,'cell_methods','time: mean'), & + if (avail_hist_fields(n)%avg_ice_present) then + call check(nf90_put_att(ncid,varid,'cell_methods',& + 'area: time: mean where sea_ice (mask=siconc)'), & 'put att cell methods time mean '//avail_hist_fields(n)%vname) + else + call check(nf90_put_att(ncid,varid,'cell_methods', & + 'area: mean where sea time: mean'), & + 'put att cell methods time mean '//avail_hist_fields(n)%vname) + endif endif endif @@ -739,6 +751,11 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) avail_hist_fields(n)%vcellmeas) if (status /= nf90_noerr) call abort_ice( & 'Error defining cell measures for '//avail_hist_fields(n)%vname) + if (avail_hist_fields(n)%vcomment /= "none") then + call check(nf90_put_att(ncid,varid,'comment', & + avail_hist_fields(n)%vcomment), & + 'put att comment '//avail_hist_fields(n)%vname) + endif status = nf90_put_att(ncid,varid,'missing_value',spval) if (status /= nf90_noerr) call abort_ice( & 'Error defining missing_value for '//avail_hist_fields(n)%vname) @@ -750,7 +767,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) ! Add cell_methods attribute to variables if averaged !--------------------------------------------------------------- if (hist_avg) then - status = nf90_put_att(ncid,varid,'cell_methods','time: mean') + status = nf90_put_att(ncid,varid,'cell_methods','area: mean where sea time: mean') if (status /= nf90_noerr) call abort_ice( & 'Error defining cell methods for '//avail_hist_fields(n)%vname) endif @@ -802,6 +819,11 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) avail_hist_fields(n)%vcellmeas) if (status /= nf90_noerr) call abort_ice( & 'Error defining cell measures for '//avail_hist_fields(n)%vname) + if (avail_hist_fields(n)%vcomment /= "none") then + call check(nf90_put_att(ncid,varid,'comment', & + avail_hist_fields(n)%vcomment), & + 'put att comment '//avail_hist_fields(n)%vname) + endif status = nf90_put_att(ncid,varid,'missing_value',spval) if (status /= nf90_noerr) call abort_ice( & 'Error defining missing_value for '//avail_hist_fields(n)%vname) @@ -851,6 +873,11 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) avail_hist_fields(n)%vcellmeas) if (status /= nf90_noerr) call abort_ice( & 'Error defining cell measures for '//avail_hist_fields(n)%vname) + if (avail_hist_fields(n)%vcomment /= "none") then + call check(nf90_put_att(ncid,varid,'comment', & + avail_hist_fields(n)%vcomment), & + 'put att comment '//avail_hist_fields(n)%vname) + endif status = nf90_put_att(ncid,varid,'missing_value',spval) if (status /= nf90_noerr) call abort_ice( & 'Error defining missing_value for '//avail_hist_fields(n)%vname) @@ -901,6 +928,11 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) avail_hist_fields(n)%vcellmeas) if (status /= nf90_noerr) call abort_ice( & 'Error defining cell measures for '//avail_hist_fields(n)%vname) + if (avail_hist_fields(n)%vcomment /= "none") then + call check(nf90_put_att(ncid,varid,'comment', & + avail_hist_fields(n)%vcomment), & + 'put att comment '//avail_hist_fields(n)%vname) + endif status = nf90_put_att(ncid,varid,'missing_value',spval) if (status /= nf90_noerr) call abort_ice( & 'Error defining missing_value for '//avail_hist_fields(n)%vname) @@ -912,7 +944,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) ! Add cell_methods attribute to variables if averaged !--------------------------------------------------------------- if (hist_avg) then - status = nf90_put_att(ncid,varid,'cell_methods','time: mean') + status = nf90_put_att(ncid,varid,'cell_methods','area: mean where sea time: mean') if (status /= nf90_noerr) call abort_ice( & 'Error defining cell methods for '//avail_hist_fields(n)%vname) endif @@ -966,6 +998,11 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) avail_hist_fields(n)%vcellmeas) if (status /= nf90_noerr) call abort_ice( & 'Error defining cell measures for '//avail_hist_fields(n)%vname) + if (avail_hist_fields(n)%vcomment /= "none") then + call check(nf90_put_att(ncid,varid,'comment', & + avail_hist_fields(n)%vcomment), & + 'put att comment '//avail_hist_fields(n)%vname) + endif status = nf90_put_att(ncid,varid,'missing_value',spval) if (status /= nf90_noerr) call abort_ice( & 'Error defining missing_value for '//avail_hist_fields(n)%vname) @@ -977,7 +1014,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) ! Add cell_methods attribute to variables if averaged !--------------------------------------------------------------- if (hist_avg) then - status = nf90_put_att(ncid,varid,'cell_methods','time: mean') + status = nf90_put_att(ncid,varid,'cell_methods','area: mean where sea time: mean') if (status /= nf90_noerr) call abort_ice( & 'Error defining cell methods for '//avail_hist_fields(n)%vname) endif @@ -1031,6 +1068,11 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) avail_hist_fields(n)%vcellmeas) if (status /= nf90_noerr) call abort_ice( & 'Error defining cell measures for '//avail_hist_fields(n)%vname) + if (avail_hist_fields(n)%vcomment /= "none") then + call check(nf90_put_att(ncid,varid,'comment', & + avail_hist_fields(n)%vcomment), & + 'put att comment '//avail_hist_fields(n)%vname) + endif status = nf90_put_att(ncid,varid,'missing_value',spval) if (status /= nf90_noerr) call abort_ice( & 'Error defining missing_value for '//avail_hist_fields(n)%vname) @@ -1042,7 +1084,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) ! Add cell_methods attribute to variables if averaged !--------------------------------------------------------------- if (hist_avg) then - status = nf90_put_att(ncid,varid,'cell_methods','time: mean') + status = nf90_put_att(ncid,varid,'cell_methods','area: mean where sea time: mean') if (status /= nf90_noerr) call abort_ice( & 'Error defining cell methods for '//avail_hist_fields(n)%vname) endif From edd67f0411b8624c04dcf850a8060d4f4efe2507 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 23 Oct 2025 10:13:42 +1100 Subject: [PATCH 60/80] Use long names based on CMIP7 variable title --- source/ice_history.F90 | 175 +++++++++++++++++----------------- source/ice_history_shared.F90 | 4 +- 2 files changed, 91 insertions(+), 88 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index a161efe8..ff5c07d1 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -203,6 +203,7 @@ subroutine init_hist (dt) if ( .not. calc_Tsfc ) then if (f_Tair /= 'x') call abort_ice ("f_Tair not available with calc_Tsfc = .false., set to 'x'") + if (f_sialb /= 'x') call abort_ice ("f_sialb not available with calc_Tsfc = .false., set to 'x'") endif if ( .not. calc_Tsfc .and. .not. heat_capacity) then ! access-esm1.6 @@ -473,11 +474,6 @@ subroutine init_hist (dt) "ice volume per unit grid cell area", c1, c0, & ns1, f_hi) - call define_hist_field(n_hi,"sivol","m",tstr2D, tcstr, & - "grid cell mean ice thickness", & - "ice volume per unit grid cell area", c1, c0, & - ns1, f_sivol) - call define_hist_field(n_hs,"hs","m",tstr2D, tcstr, & "grid cell mean snow thickness", & "snow volume per unit grid cell area", c1, c0, & @@ -498,11 +494,6 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_aice) - call define_hist_field(n_aice,"siconc","1",tstr2D, tcstr, & - "sea ice area fraction", & - "none", c1, c0, & - ns1, f_siconc) - call define_hist_field(n_uvel,"uvel","m/s",ustr2D, ucstr, & "ice velocity (x)", & "positive is x direction on U grid", c1, c0, & @@ -1057,346 +1048,357 @@ subroutine init_hist (dt) ! these definitions against the intensive/extensive/inst def ! we use updated "mean where sea" or "mean where sea_ice" per CMIP7 data request - ! intensive means sea ice area weighted, and then averaged only when sea ice is present + ! intensive means sea ice area weighted, and averaged only when sea ice is present ! extensive means a normal average (over all time and grid box area) ! extensive vars tend to zero when aice is zero, intensive vars do not + + call define_hist_field(n_aice,"siconc","1",tstr2D, tcstr, & + "Sea-Ice Area Fraction (Ocean Grid)", & + "none", c1, c0, & + ns1, f_siconc) + + call define_hist_field(n_hi,"sivol","m",tstr2D, tcstr, & + "Sea-Ice Volume per Area", & + "ice volume per unit grid cell area", c1, c0, & + ns1, f_sivol) + call define_hist_field(n_sithick,"sithick","m",tstr2D, tcstr, & - "sea ice thickness", & - "volume divided by area", c1, c0, & + "Sea-Ice Thickness", & + "volume divided by ice area", c1, c0, & ns1, f_sithick, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_simass,"simass","kg m^-2",tstr2D, tcstr, & - "sea ice mass", & + "Sea-Ice Mass", & "mass divided by area", c1, c0, & ns1, f_simass) call define_hist_field(n_siage,"siage","s",tstr2D, tcstr, & - "sea ice age", & + "Age of Sea Ice", & "none", c1, c0, & ns1, f_siage, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifb,"sifb","m",tstr2D, tcstr, & - "sea ice freeboard", & - "none", c1, c0, & + "Sea-Ice Freeboard", & + "height of sea ice above ocean surface", c1, c0, & ns1, f_sifb, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisnconc,"sisnconc","1",tstr2D, tcstr, & - "snow area fraction", & - "none", c1, c0, & + "Snow Area Fraction", & + "fraction of grid cell with snow over sea ice", c1, c0, & ns1, f_sisnconc, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisnthick,"sisnthick","m",tstr2D, tcstr, & - "sea ice snow thickness", & + "Snow Thickness", & "snow volume divided by area", c1, c0, & ns1, f_sisnthick, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisnmass,"sisnmass","kg m^-2",tstr2D, tcstr, & - "snow mass per areas", & - "snow mass divided by area", c1, c0, & + "Snow Mass per Area", & + "snow mass divided by grid cell area", c1, c0, & ns1, f_sisnmass, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitemptop,"sitemptop","K",tstr2D, tcstr, & - "sea ice surface temperature", & + "Surface Temperature of Sea Ice", & "none", c1, Tffresh, & ns1, f_sitemptop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitempsnic,"sitempsnic","K",tstr2D, tcstr, & - "snow ice interface temperature", & + "Temperature at Snow-Ice Interface", & "surface temperature when no snow present", c1, Tffresh, & ns1, f_sitempsnic, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitempbot,"sitempbot","K",tstr2D, tcstr, & - "sea ice bottom temperature", & + "Temperature at Ice-Ocean Interface", & "none", c1, Tffresh, & ns1, f_sitempbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siu,"siu","m/s",ustr2D, ucstr, & - "ice x velocity component", & + "X-Component of Sea-Ice Velocity", & "none", c1, c0, & ns1, f_siu, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siv,"siv","m/s",ustr2D, ucstr, & - "ice y velocity component", & + "Y-Component of Sea-Ice Velocity", & "none", c1, c0, & ns1, f_siv, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidmasstranx,"sidmasstranx","kg/s",ustr2D, ucstr, & - "x component of snow and sea ice mass transport", & - "none", c1, c0, & + "X-Component of Sea-Ice Mass Transport", & + "includes sea-ice and snow transport", c1, c0, & ns1, f_sidmasstranx) call define_hist_field(n_sidmasstrany,"sidmasstrany","kg/s",ustr2D, ucstr, & - "y component of snow and sea ice mass transport", & - "none", c1, c0, & + "Y-Component of Sea-Ice Mass Transport", & + "includes sea-ice and snow transport", c1, c0, & ns1, f_sidmasstrany) call define_hist_field(n_sistrxdtop,"sistrxdtop","N m^-2",ustr2D, ucstr, & - "x component of atmospheric stress on sea ice", & + "X-Component of Atmospheric Stress on Sea Ice", & "none", c1, c0, & ns1, f_sistrxdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistrydtop,"sistrydtop","N m^-2",ustr2D, ucstr, & - "y component of atmospheric stress on sea ice", & + "Y-Component of Atmospheric Stress on Sea Ice", & "none", c1, c0, & ns1, f_sistrydtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistrxubot,"sistrxubot","N m^-2",ustr2D, ucstr, & - "x component of ocean stress on sea ice", & + "X-Component of Ocean Stress on Sea Ice", & "none", c1, c0, & ns1, f_sistrxubot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistryubot,"sistryubot","N m^-2",ustr2D, ucstr, & - "y component of ocean stress on sea ice", & + "Y-Component of Ocean Stress on Sea Ice", & "none", c1, c0, & ns1, f_sistryubot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcetiltx,"siforcetiltx","N m^-2",ustr2D, ucstr, & - "x component of sea surface tilt force", & + "xSea-Surface Tilt Term in Force Balance (X-Component)", & "none", c1, c0, & ns1, f_siforcetiltx, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcetilty,"siforcetilty","N m^-2",ustr2D, ucstr, & - "y component of sea surface tilt force", & + "Sea-Surface Tilt Term in Force Balance (Y-Component)", & "none", c1, c0, & ns1, f_siforcetilty, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcecoriolx,"siforcecoriolx","N m^-2",ustr2D, ucstr, & - "x component of Coriolis force", & + "Coriolis Force Term in Force Balance (X-Component)", & "none", c1, c0, & ns1, f_siforcecoriolx, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcecorioly,"siforcecorioly","N m^-2",ustr2D, ucstr, & - "y component of Coriolis force", & + "Coriolis Force Term in Force Balance (Y-Component)", & "none", c1, c0, & ns1, f_siforcecorioly, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforceintstrx,"siforceintstrx","N m^-2",ustr2D, ucstr, & - "x component of internal ice stress force", & + "Internal Stress Term in Force Balance (X-Component)", & "none", c1, c0, & ns1, f_siforceintstrx, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforceintstry,"siforceintstry","N m^-2",ustr2D, ucstr, & - "y component of internal ice stress force", & + "Internal Stress Term in Force Balance (Y-Component)", & "none", c1, c0, & ns1, f_siforceintstry, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sicompstren,"sicompstren","N/m",ustr2D, ucstr, & - "compressive sea ice strength", & + "Compressive Sea Ice Strength", & "none", c1, c0, & ns1, f_sicompstren, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidivvel,"sidivvel","1/s",ustr2D, ucstr, & - "divergence of the sea ice velocity field (ice area weighted)", & + "Divergence of the Sea-Ice Velocity Field", & "none", c1, c0, & ns1, f_sidivvel, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sispeed,"sispeed","m/s",ustr2D, ucstr, & - "ice speed", & + "Sea-Ice Speed", & "none", c1, c0, & ns1, f_sispeed, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sialb,"sialb","1",tstr2D, tcstr, & - "sea ice albedo", & + "Sea-Ice Albedo", & "none", c1, c0, & ns1, f_sialb, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sihc,"sihc","J m^-2",tstr2D, tcstr, & - "sea ice heat content", & + "Sea-Ice Heat Content", & "none", c1, c0, & ns1, f_sihc) call define_hist_field(n_sisnhc,"sisnhc","J m^-2",tstr2D, tcstr, & - "snow heat content", & + "Snow Heat Content", & "none", c1, c0, & ns1, f_sisnhc) call define_hist_field(n_sidconcth,"sidconcth","1/s",tstr2D, tcstr, & - "sea ice area change from thermodynamics", & + "Sea-Ice Area Fraction Tendency Due to Thermodynamics", & "none", c1, c0, & ns1, f_sidconcth) call define_hist_field(n_sidconcdyn,"sidconcdyn","1/s",tstr2D, tcstr, & - "sea ice area change from dynamics", & + "Sea-Ice Area Fraction Tendency Due to Dynamics", & "none", c1, c0, & ns1, f_sidconcdyn) call define_hist_field(n_sidmassth,"sidmassth","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from thermodynamics", & + "Sea-Ice Mass Change from Thermodynamics", & "none", c1, c0, & ns1, f_sidmassth) call define_hist_field(n_sidmassdyn,"sidmassdyn","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from dynamics", & + "Sea-Ice Mass Change from Dynamics", & "none", c1, c0, & ns1, f_sidmassdyn) call define_hist_field(n_sidmassgrowthwat,"sidmassgrowthwat","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from frazil growth", & + "Sea-Ice Mass Change Through Growth in Supercooled Open Water (Frazil)", & "none", c1, c0, & ns1, f_sidmassgrowthwat) call define_hist_field(n_sidmassgrowthbot,"sidmassgrowthbot","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from basal growth", & + "Sea-Ice Mass Change Through Basal Growth", & "none", c1, c0, & ns1, f_sidmassgrowthbot) call define_hist_field(n_sidmasssi,"sidmasssi","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from snow-ice formation", & + "Sea-Ice Mass Change Through Snow-to-Ice Conversion", & "none", c1, c0, & ns1, f_sidmasssi) call define_hist_field(n_sidmasssi,"sidmassgrowthsi","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from snow-ice formation", & + "Sea-Ice Mass Change Through Snow-to-Ice Conversion", & "none", c1, c0, & ns1, f_sidmassgrowthsi) call define_hist_field(n_sidmassevapsubl,"sidmassevapsubl","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from evaporation and sublimation", & + "Sea-Ice Mass Change Through Evaporation and Sublimation", & "none", c1, c0, & ns1, f_sidmassevapsubl) call define_hist_field(n_sndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & - "snow mass change from evaporation and sublimation", & + "Snow Mass Rate of Change Through Evaporation or Sublimation", & "none", c1, c0, & ns1, f_sndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmasssubl,"sisndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & - "snow mass change from evaporation and sublimation", & + "Snow Mass Rate of Change Through Evaporation or Sublimation", & "none", c1, c0, & ns1, f_sisndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from top ice melt", & + "Sea-Ice Mass Change Through Surface Melting", & "none", c1, c0, & ns1, f_sidmassmelttop) call define_hist_field(n_sidmassmeltbot,"sidmassmeltbot","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from bottom ice melt", & + "Sea-Ice Mass Change Through Bottom Melting", & "none", c1, c0, & ns1, f_sidmassmeltbot) call define_hist_field(n_sidmasslat,"sidmasslat","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from lateral ice melt", & + "Sea-Ice Mass Change Through Lateral Melting", & "none", c1, c0, & ns1, f_sidmasslat) call define_hist_field(n_sidmasslat,"sidmassmeltlat","kg m^-2 s^-1",tstr2D, tcstr, & - "sea ice mass change from lateral ice melt", & + "Sea-Ice Mass Change Through Lateral Melting", & "none", c1, c0, & ns1, f_sidmassmeltlat) call define_hist_field(n_sndmasssnf,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & - "snow mass change from snow fall", & + "Snow Mass Change Through Snowfall", & "none", c1, c0, & ns1, f_sndmasssnf, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmasssnf,"sisndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & - "snow mass change from snow fall", & + "Snow Mass Change Through Snowfall", & "none", c1, c0, & ns1, f_sisndmasssnf, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & - "snow mass change from melt", & + "Snow Mass Rate of Change Through Melt", & "none", c1, c0, & ns1, f_sndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & - "snow mass change from melt", & + "Snow Mass Rate of Change Through Melt", & "none", c1, c0, & ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & - "snow mass change through snow to ice conversion", & + "Snow Mass Rate of Change Through Snow-to-Ice Conversion", & "none", c1, c0, & ns1, f_sisndmasssi, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & - "snow mass change from dynamics (advection)", & + "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & "none", c1, c0, & ns1, f_sndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sisndmassdyn","kg m-2 s-1",tstr2D, tcstr, & - "snow mass rate of change through advection by sea ice dynamics", & + "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & "none", c1, c0, & ns1, f_sisndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdtop,"siflswdtop","W/m2",tstr2D, tcstr, & - "down shortwave flux over sea ice", & + "Downwelling Shortwave Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_siflswdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswutop,"siflswutop","W/m^2",tstr2D, tcstr, & - "upward shortwave flux over sea ice", & + "Upwelling Shortwave Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_siflswutop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdbot,"siflswdbot","W/m^2",tstr2D, tcstr, & - "down shortwave flux at bottom of ice", & + "Downwelling Shortwave Flux under Sea Ice", & "positive downward", c1, c0, & ns1, f_siflswdbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllwdtop,"sifllwdtop","W/m^2",tstr2D, tcstr, & - "down longwave flux over sea ice", & + "Downwelling Longwave Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_sifllwdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllwutop,"sifllwutop","W/m^2",tstr2D, tcstr, & - "upward longwave flux over sea ice", & + "Upwelling Longwave Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_sifllwutop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsenstop,"siflsenstop","W/m^2",tstr2D, tcstr, & - "sensible heat flux over sea ice", & + "Net Downward Sensible Heat Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_siflsenstop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsensupbot,"siflsensupbot","W/m^2",tstr2D, tcstr, & - "sensible heat flux at bottom of sea ice", & + "Net Upward Sensible Heat Flux under Sea Ice", & "positive downward", c1, c0, & ns1, f_siflsensupbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsensupbot,"siflsensbot","W/m^2",tstr2D, tcstr, & - "sensible heat flux at bottom of sea ice", & + "Net Upward Sensible Heat Flux under Sea Ice", & "positive downward", c1, c0, & ns1, f_siflsensbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllatstop,"sifllatstop","W/m^2",tstr2D, tcstr, & - "latent heat flux over sea ice", & + "Net Latent Heat Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_sifllatstop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflcondtop,"siflcondtop","W/m^2",tstr2D, tcstr, & - "conductive heat flux at top of sea ice", & + "Net Conductive Heat Flux in Sea Ice at the Surface", & "positive downward", c1, c0, & ns1, f_siflcondtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflcondbot,"siflcondbot","W/m^2",tstr2D, tcstr, & - "conductive heat flux at bottom of sea ice", & + "Net Conductive Heat Flux in Sea Ice at the Base", & "positive downward", c1, c0, & ns1, f_siflcondbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflfwdrain,"siflfwdrain","kg m^-2 s^-1",tstr2D, tcstr, & - "freshwater drainage through sea ice", & + "Freshwater Flux from Sea-Ice Surface", & "positive downward", c1, c0, & ns1, f_siflfwdrain, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sipr,"sipr","kg m^-2 s^-1",tstr2D, tcstr, & - "rainfall over sea ice", & + "Rainfall Rate over Sea Ice", & "none", c1, c0, & ns1, f_sipr, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsaltbot,"siflsaltbot","kg m^-2 s^-1",tstr2D, tcstr, & - "salt flux from sea ice", & + "Salt Flux from Sea Ice", & "positive downward", c1, c0, & ns1, f_siflsaltbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflfwbot,"siflfwbot","kg m^-2 s^-1",tstr2D, tcstr, & - "fresh water flux from sea ice", & + "Freshwater Flux from Sea Ice", & "positive downward", c1, c0, & ns1, f_siflfwbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisaltmass,"sisaltmass","kg m^-2",tstr2D, tcstr, & - "mass of salt in sea ice (for ocean fluxes)",& + "Mass of Salt in Sea Ice",& "none", c1, c0, & ns1, f_sisaltmass) @@ -1472,7 +1474,8 @@ subroutine init_hist (dt) ! CMIP 3D call define_hist_field(n_aicen,"siitdconc","1",tstr3Dc, tcstr, & - "ice area, categories","none", c1, c0, & + "Sea-Ice Area Fractions in Ice Thickness Categories", & + "none", c1, c0, & ns1, f_siitdconc) ! siitdthick, siitdsnconc, siitdsnthick are not implemented because it's not clear how to diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 9654639c..8e534d11 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -77,8 +77,8 @@ module ice_history_shared character (len=16) :: vunit ! variable units character (len=25) :: vcoord ! variable coordinates character (len=16) :: vcellmeas ! variable cell measures - character (len=55) :: vdesc ! variable description - character (len=55) :: vcomment ! variable description + character (len=255) :: vdesc ! variable description + character (len=255) :: vcomment ! variable description real (kind=dbl_kind) :: cona ! multiplicative conversion factor real (kind=dbl_kind) :: conb ! additive conversion factor character (len=1) :: vhistfreq ! frequency of history output From cd905a800abc53471994d042503bf5aa51ef1122 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 23 Oct 2025 10:16:12 +1100 Subject: [PATCH 61/80] consistentize units --- source/ice_history.F90 | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index ff5c07d1..b2c1ad39 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1322,57 +1322,57 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_sisndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflswdtop,"siflswdtop","W/m2",tstr2D, tcstr, & + call define_hist_field(n_siflswdtop,"siflswdtop","W m^-2",tstr2D, tcstr, & "Downwelling Shortwave Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_siflswdtop, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflswutop,"siflswutop","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_siflswutop,"siflswutop","W m^-2",tstr2D, tcstr, & "Upwelling Shortwave Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_siflswutop, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflswdbot,"siflswdbot","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_siflswdbot,"siflswdbot","W m^-2",tstr2D, tcstr, & "Downwelling Shortwave Flux under Sea Ice", & "positive downward", c1, c0, & ns1, f_siflswdbot, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sifllwdtop,"sifllwdtop","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_sifllwdtop,"sifllwdtop","W m^-2",tstr2D, tcstr, & "Downwelling Longwave Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_sifllwdtop, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sifllwutop,"sifllwutop","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_sifllwutop,"sifllwutop","W m^-2",tstr2D, tcstr, & "Upwelling Longwave Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_sifllwutop, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflsenstop,"siflsenstop","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_siflsenstop,"siflsenstop","W m^-2",tstr2D, tcstr, & "Net Downward Sensible Heat Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_siflsenstop, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflsensupbot,"siflsensupbot","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_siflsensupbot,"siflsensupbot","W m^-2",tstr2D, tcstr, & "Net Upward Sensible Heat Flux under Sea Ice", & "positive downward", c1, c0, & ns1, f_siflsensupbot, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflsensupbot,"siflsensbot","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_siflsensupbot,"siflsensbot","W m^-2",tstr2D, tcstr, & "Net Upward Sensible Heat Flux under Sea Ice", & "positive downward", c1, c0, & ns1, f_siflsensbot, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sifllatstop,"sifllatstop","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_sifllatstop,"sifllatstop","W m^-2",tstr2D, tcstr, & "Net Latent Heat Flux over Sea Ice", & "positive downward", c1, c0, & ns1, f_sifllatstop, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflcondtop,"siflcondtop","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_siflcondtop,"siflcondtop","W m^-2",tstr2D, tcstr, & "Net Conductive Heat Flux in Sea Ice at the Surface", & "positive downward", c1, c0, & ns1, f_siflcondtop, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_siflcondbot,"siflcondbot","W/m^2",tstr2D, tcstr, & + call define_hist_field(n_siflcondbot,"siflcondbot","W m^-2",tstr2D, tcstr, & "Net Conductive Heat Flux in Sea Ice at the Base", & "positive downward", c1, c0, & ns1, f_siflcondbot, avg_ice_present=.true., mask_ice_free_points=.true.) From 3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 23 Oct 2025 10:23:00 +1100 Subject: [PATCH 62/80] we arent CF compliant --- io_netcdf/ice_history_write.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/io_netcdf/ice_history_write.F90 b/io_netcdf/ice_history_write.F90 index d7fec3b8..b9c0eae2 100644 --- a/io_netcdf/ice_history_write.F90 +++ b/io_netcdf/ice_history_write.F90 @@ -1136,9 +1136,9 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) call check(nf90_put_att(ncid,nf90_global,'comment2',title), & 'global attribute comment2') - title = 'CF-1.0' - call check(nf90_put_att(ncid,nf90_global,'conventions',title), & - 'global attribute conventions') + ! title = 'CF-1.0' + ! call check(nf90_put_att(ncid,nf90_global,'conventions',title), & + ! 'global attribute conventions') call date_and_time(date=current_date, time=current_time) write(start_time,1000) current_date(1:4), current_date(5:6), & From d083b62ed977fdaec0892c1838a55868ba5818eb Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 24 Oct 2025 15:03:51 +1100 Subject: [PATCH 63/80] don't save sipr if it's passed straight through (per Notz 2016) fix some grid cell averages siflsaltbot was duplicated --- source/ice_history.F90 | 98 ++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index b2c1ad39..8ec82a73 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -214,6 +214,9 @@ subroutine init_hist (dt) if (f_sitempsnic /= 'x') call abort_ice ("f_sitempsnic not available, set to 'x'") endif + ! rain goes straight to ocean + if ( (.not. tr_pond) .and. f_sipr /= 'x') call abort_ice ("f_sipr not available, set to 'x'") + #ifndef ncdf f_bounds = .false. #endif @@ -731,7 +734,7 @@ subroutine init_hist (dt) call define_hist_field(n_congel,"congel","cm/day",tstr2D, tcstr, & "congelation ice growth", & - "none", mps_to_cmpdy/dt, c0, & + "ice area average", mps_to_cmpdy/dt, c0, & ns1, f_congel) call define_hist_field(n_frazil,"frazil","cm/day",tstr2D, tcstr, & @@ -741,8 +744,8 @@ subroutine init_hist (dt) call define_hist_field(n_snoice,"snoice","cm/day",tstr2D, tcstr, & "snow-ice formation", & - "none", mps_to_cmpdy/dt, c0, & - ns1, f_snoice) + "ice area average", mps_to_cmpdy/dt, c0, & + ns1, f_snoice) !rename to snoice_ai ? call define_hist_field(n_dsnow,"dsnow","cm/day",tstr2D, tcstr, & "snow formation", & @@ -1687,7 +1690,7 @@ subroutine accum_hist (dt) use ice_fileunits, only: nu_diag use ice_constants, only: c0, c1, p25, puny, secday, depressT, & - awtvdr, awtidr, awtvdf, awtidf, Lfresh, rhoi, rhos, rhow, cp_ice, & + awtvdr, awtidr, awtvdf, awtidf, Lfresh, rhoi, rhos, rhow, rhofresh, cp_ice, & spval_dbl, Tffresh, ice_ref_salinity, c1000 use ice_domain, only: blocks_ice, nblocks use ice_grid, only: tmask, lmask_n, lmask_s, tarea, HTE, HTN @@ -2009,7 +2012,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_dsnow, iblk, dsnow(:,:,iblk), a2D) if (f_meltt (1:1) /= 'x') & call accum_hist_field(n_meltt, iblk, meltt(:,:,iblk), a2D) - if (f_melts (1:1) /= 'x') & + if (f_melts (1:1) /= 'x') & ! is this actually melts_ai, its a grid cell average (https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L857-L862) call accum_hist_field(n_melts, iblk, melts(:,:,iblk), a2D) if (f_meltb (1:1) /= 'x') & call accum_hist_field(n_meltb, iblk, meltb(:,:,iblk), a2D) @@ -2145,9 +2148,9 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - ! siage is intensive, weight each timestep by aice + ! siage is intensive, snowfrac is grid cell average already if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & - worka(i,j) = aice(i,j,iblk) * snowfrac(i,j,iblk) + worka(i,j) = snowfrac(i,j,iblk) enddo enddo call accum_hist_field(n_sisnconc, iblk, worka(:,:), a2D) @@ -2518,8 +2521,10 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then - worka(i,j) = snoice(i,j,iblk)*rhoi/dt + if (aice(i,j,iblk) > puny) then + ! snoice is grid area average - see https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L861-L862 + ! sidmasssi is extensive + worka(i,j) = snoice(i,j,iblk)*rhoi/dt endif enddo enddo @@ -2533,7 +2538,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*snoice(i,j,iblk)*rhoi/dt + ! sisndmasssi is intensive + worka(i,j) = snoice(i,j,iblk)*rhoi/dt endif enddo enddo @@ -2545,7 +2551,9 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = evap_ice(i,j,iblk) + ! sidmassevapsubl is extensive + ! evap_ice is ice area average -> convert to grid cell area + worka(i,j) = aice(i,j,iblk) * evap_ice(i,j,iblk) endif enddo enddo @@ -2557,6 +2565,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then + ! sisndmasssubl is intensive + ! evap_snow is ice area average, see evap_snow_ai -> weight by aice worka(i,j) = aice(i,j,iblk)*evap_snow(i,j,iblk) endif enddo @@ -2569,7 +2579,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = meltt(i,j,iblk)*rhoi/dt + ! sidmassmelttop is extensive, meltt is grid cell average + worka(i,j) = meltt(i,j,iblk)*rhoi/dt ! arguably meltt is calculated by thermodynamics only, and is not ! advected during dynamics, and so should be corrected for aice_init ! e.g.: @@ -2587,7 +2598,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = meltb(i,j,iblk)*rhoi/dt + ! sidmassmeltbot is extensive, meltb is grid cell average + worka(i,j) = meltb(i,j,iblk)*rhoi/dt ! arguably corrected to aice_init ! if (aice_init(i,j,iblk) > puny) then ! worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & @@ -2603,7 +2615,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = meltl(i,j,iblk)*rhoi/dt + ! sidmasslat is extensive, meltl is grid cell average + worka(i,j) = meltl(i,j,iblk)*rhoi/dt ! arguably corrected to aice_init ! if (aice_init(i,j,iblk) > puny) then ! worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & @@ -2621,6 +2634,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then + ! sisndmassmelt is intensive worka(i,j) = aice(i,j,iblk)*fsnow(i,j,iblk) endif enddo @@ -2633,7 +2647,9 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*melts(i,j,iblk)*rhos/dt + ! sisndmassmelt is intensive + ! melts is grid cell average - see https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L861-L862 + worka(i,j) = melts(i,j,iblk)*rhos/dt endif enddo enddo @@ -2645,7 +2661,9 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = dvsdtd(i,j,iblk)*rhos + ! dvsdtd is change in snow volumne per grid cell area, + ! sisndmassdyn is intensive, therefore multiply by aice + worka(i,j) = aice(i,j,iblk)*dvsdtd(i,j,iblk)*rhos endif enddo enddo @@ -2766,8 +2784,10 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*fcondbot(i,j,iblk) + if (aice(i,j,iblk) > puny) then + ! siflcondbot is intensive, fcondbot is grid cell average + ! https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L833-L834 + worka(i,j) = fcondbot(i,j,iblk) ! CICE6 has this weighting, presumably an incorrent attempt to adjust ! fcondbot so its consistent with aice ? ! for ACCESS, fcondbot was caluclated in the UM, using aice from the timestep @@ -2780,12 +2800,13 @@ subroutine accum_hist (dt) endif if (f_sipr(1:1) /= 'x') then - !to-do: check scaling ? worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*frain(i,j,iblk) + !it looks like frain is ice_area average https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_step_mod.F90#L334-L335 + !sipr is intensive, so weight by aice + worka(i,j) = aice(i,j,iblk)*frain(i,j,iblk)*rhofresh endif enddo enddo @@ -2849,27 +2870,17 @@ subroutine accum_hist (dt) endif if (f_siflfwbot(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*fresh(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_siflfwbot, iblk, worka(:,:), a2D) - endif - - if (f_siflsaltbot(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*fsalt(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_siflsaltbot, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! ! siflfwbot is intensive, fresh_ai is a grid cell average already + ! worka(i,j) = fresh_ai(i,j,iblk) + ! endif + ! enddo + ! enddo + ! we seem to loose a lot of water if masking by aice ( i guess when cell totally melts out ) + call accum_hist_field(n_siflfwbot, iblk, fresh_ai(:,:,iblk), a2D) endif if (f_siflfwdrain(1:1) /= 'x') then @@ -2877,7 +2888,10 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*(frain(i,j,iblk) + melts(i,j,iblk)+meltt(i,j,iblk)) + worka(i,j) = aice(i,j,iblk)*(& + frain(i,j,iblk) * rhofresh & + + melts(i,j,iblk) * rhos/dt & + + meltt(i,j,iblk) * rhoi/dt) endif enddo enddo From bf9a47978b6300acf031cd03420aca8628579421 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 24 Oct 2025 16:31:35 +1100 Subject: [PATCH 64/80] try with less masking --- source/ice_history.F90 | 439 +++++++++++++++++++++-------------------- 1 file changed, 229 insertions(+), 210 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 8ec82a73..9f7e0c98 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2112,25 +2112,25 @@ subroutine accum_hist (dt) !2D CMIP6 fields if (f_sithick(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - ! sithick is intensive, vice is already aice*thickness - if (aice(i,j,iblk) > puny) worka(i,j) = vice(i,j,iblk) - enddo - enddo - call accum_hist_field(n_sithick, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! ! sithick is intensive, vice is already aice*thickness + ! if (aice(i,j,iblk) > puny) worka(i,j) = vice(i,j,iblk) + ! enddo + ! enddo + call accum_hist_field(n_sithick, iblk, vice(:,:,iblk), a2D) endif if (f_simass(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - ! simass is extensive, -> grid cell average - if (aice(i,j,iblk) > puny) worka(i,j) = rhoi*vice(i,j,iblk) - enddo - enddo - call accum_hist_field(n_simass, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! ! simass is extensive, -> grid cell average + ! if (aice(i,j,iblk) > puny) worka(i,j) = rhoi*vice(i,j,iblk) + ! enddo + ! enddo + call accum_hist_field(n_simass, iblk, rhoi*vice(:,:,iblk), a2D) endif if (f_siage(1:1) /= 'x') then @@ -2138,45 +2138,46 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi ! siage is intensive, weight each timestep by aice - if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_iage,iblk) + if (aice(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_iage,iblk) enddo enddo call accum_hist_field(n_siage, iblk, worka(:,:), a2D) endif if (f_sisnconc(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - ! siage is intensive, snowfrac is grid cell average already - if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & - worka(i,j) = snowfrac(i,j,iblk) - enddo - enddo - call accum_hist_field(n_sisnconc, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! ! siage is intensive, snowfrac is grid cell average already + ! if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & + ! worka(i,j) = snowfrac(i,j,iblk) + ! enddo + ! enddo + call accum_hist_field(n_sisnconc, iblk, snowfrac(:,:,iblk), a2D) endif if (f_sisnthick(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - ! sisnthick is intensive, vsno is already aice*thickness - if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & - worka(i,j) = vsno(i,j,iblk) - enddo - enddo - call accum_hist_field(n_sisnthick, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! ! sisnthick is intensive, vsno is already aice*thickness + ! if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & + ! worka(i,j) = vsno(i,j,iblk) + ! enddo + ! enddo + call accum_hist_field(n_sisnthick, iblk, vsno(:,:,iblk), a2D) endif if (f_sisnmass(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & - worka(i,j) = vsno(i,j,iblk) * rhos - enddo - enddo - call accum_hist_field(n_sisnmass, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & + ! worka(i,j) = vsno(i,j,iblk) * rhos + ! enddo + ! enddo + call accum_hist_field(n_sisnmass, iblk, vsno(:,:,iblk) * rhos, a2D) endif if (f_sitemptop(1:1) /= 'x') then @@ -2184,7 +2185,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - ! Tsfc is a tracer, so was advected during dynamics, so we shouldn't need aice_init here ! + ! Tsfc is a tracer, so was advected during dynamics + ! sitemptop is intensive, weight by aice worka(i,j) = aice(i,j,iblk) * trcr(i,j,nt_Tsfc,iblk) endif enddo @@ -2197,6 +2199,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! nb Tsnice is approximate, not a tracer + ! sitempsnic is intensive, weight by aice worka(i,j) = aice(i,j,iblk)*Tsnice(i,j,iblk) enddo enddo @@ -2208,6 +2212,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! nb Tsnice is approximate, not a tracer + ! sitempbot is intensive, weight by aice worka(i,j) = aice(i,j,iblk)*Ti_bot(i,j,iblk) enddo enddo @@ -2218,6 +2224,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! intensive, weight by aice if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*uvel(i,j,iblk) enddo enddo @@ -2228,6 +2235,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! intensive, weight by aice if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*vvel(i,j,iblk) enddo enddo @@ -2238,6 +2246,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! intensive, weight by aice if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk) & * sqrt(uvel(i,j,iblk)*uvel(i,j,iblk)+vvel(i,j,iblk)*vvel(i,j,iblk)) enddo @@ -2250,6 +2259,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! extensive, vice and vsno are grid cell averages worka(i,j) = p25*HTE(i,j,iblk)*( & rhoi*(vice(i,j,iblk)+vice(i+1,j,iblk)) & + rhos*(vsno(i,j,iblk)+vsno(i+1,j,iblk)) & @@ -2264,6 +2274,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! extensive, vice and vsno are grid cell averages worka(i,j) = p25*HTN(i,j,iblk)*( & rhoi*(vice(i,j,iblk)+vice(i,j+1,iblk)) & + rhos*(vsno(i,j,iblk)+vsno(i,j+1,iblk)) & @@ -2277,8 +2288,9 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - !to-do: scale by aice/aice_init as its a calculated based on coupled state ? + !to-do: scale by aice/aice_init as its calculated based on coupled state ? if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strairx(i,j,iblk) enddo enddo @@ -2291,6 +2303,7 @@ subroutine accum_hist (dt) do i = ilo, ihi !to-do: scale by aice/aice_init ? if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strairy(i,j,iblk) enddo enddo @@ -2302,6 +2315,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strocnx(i,j,iblk) enddo enddo @@ -2313,6 +2327,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strocny(i,j,iblk) enddo enddo @@ -2446,104 +2461,104 @@ subroutine accum_hist (dt) endif if (f_sidconcth(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = daidtt(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_sidconcth, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! worka(i,j) = daidtt(i,j,iblk) + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidconcth, iblk, daidtt(:,:,iblk), a2D) endif if (f_sidconcdyn(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = daidtd(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_sidconcdyn, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! worka(i,j) = daidtd(i,j,iblk) + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidconcdyn, iblk, daidtd(:,:,iblk), a2D) endif if (f_sidmassth(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = dvidtt(i,j,iblk) * rhoi - endif - enddo - enddo - call accum_hist_field(n_sidmassth, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! worka(i,j) = dvidtt(i,j,iblk) * rhoi + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidmassth, iblk, dvidtt(:,:,iblk) * rhoi, a2D) endif if (f_sidmassdyn(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = dvidtd(i,j,iblk) * rhoi - endif - enddo - enddo - call accum_hist_field(n_sidmassdyn, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! worka(i,j) = dvidtd(i,j,iblk) * rhoi + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidmassdyn, iblk, dvidtd(:,:,iblk) * rhoi, a2D) endif if (f_sidmassgrowthwat(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then - worka(i,j) = frazil(i,j,iblk)*rhoi/dt - endif - enddo - enddo - call accum_hist_field(n_sidmassgrowthwat, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice_init(i,j,iblk) > puny) then + ! worka(i,j) = frazil(i,j,iblk)*rhoi/dt + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidmassgrowthwat, iblk, frazil(:,:,iblk)*rhoi/dt, a2D) endif if (f_sidmassgrowthbot(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice_init(i,j,iblk) > puny) then - worka(i,j) = congel(i,j,iblk)*rhoi/dt - endif - enddo - enddo - call accum_hist_field(n_sidmassgrowthbot, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice_init(i,j,iblk) > puny) then + ! worka(i,j) = congel(i,j,iblk)*rhoi/dt + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidmassgrowthbot, iblk, congel(:,:,iblk)*rhoi/dt, a2D) endif if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! snoice is grid area average - see https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L861-L862 - ! sidmasssi is extensive - worka(i,j) = snoice(i,j,iblk)*rhoi/dt - endif - enddo - enddo - call accum_hist_field(n_sidmasssi, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! ! snoice is grid area average - see https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L861-L862 + ! ! sidmasssi is extensive + ! worka(i,j) = snoice(i,j,iblk)*rhoi/dt + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidmasssi, iblk, snoice(:,:,iblk)*rhoi/dt, a2D) endif if (f_sisndmasssi(1:1) /= 'x') then !To-do: calculate a seperate icesno diag for change in snow thickness in ice_therm_vertical ? ! Its equivalent though, so fairly moot - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! sisndmasssi is intensive - worka(i,j) = snoice(i,j,iblk)*rhoi/dt - endif - enddo - enddo - call accum_hist_field(n_sisndmasssi, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! ! sisndmasssi is intensive + ! worka(i,j) = snoice(i,j,iblk)*rhoi/dt + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sisndmasssi, iblk, snoice(:,:,iblk)*rhoi/dt, a2D) endif if (f_sidmassevapsubl(1:1) /= 'x') then @@ -2575,56 +2590,56 @@ subroutine accum_hist (dt) endif if (f_sidmassmelttop(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! sidmassmelttop is extensive, meltt is grid cell average - worka(i,j) = meltt(i,j,iblk)*rhoi/dt - ! arguably meltt is calculated by thermodynamics only, and is not - ! advected during dynamics, and so should be corrected for aice_init - ! e.g.: - ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi /& - ! (dt * aice_init(i,j,iblk)) - endif - enddo - enddo - call accum_hist_field(n_sidmassmelttop, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! ! sidmassmelttop is extensive, meltt is grid cell average + ! worka(i,j) = meltt(i,j,iblk)*rhoi/dt + ! ! arguably meltt is calculated by thermodynamics only, and is not + ! ! advected during dynamics, and so should be corrected for aice_init + ! ! e.g.: + ! ! if (aice_init(i,j,iblk) > puny) then + ! ! worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi /& + ! ! (dt * aice_init(i,j,iblk)) + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidmassmelttop, iblk, meltt(:,:,iblk)*rhoi/dt, a2D) endif if (f_sidmassmeltbot(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! sidmassmeltbot is extensive, meltb is grid cell average - worka(i,j) = meltb(i,j,iblk)*rhoi/dt - ! arguably corrected to aice_init - ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & - ! (dt * aice_init(i,j,iblk)) - endif - enddo - enddo - call accum_hist_field(n_sidmassmeltbot, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! ! sidmassmeltbot is extensive, meltb is grid cell average + ! worka(i,j) = meltb(i,j,iblk)*rhoi/dt + ! ! arguably corrected to aice_init + ! ! if (aice_init(i,j,iblk) > puny) then + ! ! worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & + ! ! (dt * aice_init(i,j,iblk)) + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidmassmeltbot, iblk, meltb(:,:,iblk)*rhoi/dt, a2D) endif if (f_sidmasslat(1:1) /= 'x' .or. f_sidmassmeltlat(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! sidmasslat is extensive, meltl is grid cell average - worka(i,j) = meltl(i,j,iblk)*rhoi/dt - ! arguably corrected to aice_init - ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & - ! (dt * aice_init(i,j,iblk)) - endif - enddo - enddo - call accum_hist_field(n_sidmasslat, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! ! sidmasslat is extensive, meltl is grid cell average + ! worka(i,j) = meltl(i,j,iblk)*rhoi/dt + ! ! arguably corrected to aice_init + ! ! if (aice_init(i,j,iblk) > puny) then + ! ! worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & + ! ! (dt * aice_init(i,j,iblk)) + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sidmasslat, iblk, meltl(:,:,iblk)*rhoi/dt, a2D) endif if (f_sndmasssnf(1:1) /= 'x' .or. f_sisndmasssnf(1:1) /= 'x') then @@ -2643,17 +2658,17 @@ subroutine accum_hist (dt) endif if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! sisndmassmelt is intensive - ! melts is grid cell average - see https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L861-L862 - worka(i,j) = melts(i,j,iblk)*rhos/dt - endif - enddo - enddo - call accum_hist_field(n_sndmassmelt, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! ! sisndmassmelt is intensive + ! ! melts is grid cell average - see https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L861-L862 + ! worka(i,j) = melts(i,j,iblk)*rhos/dt + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sndmassmelt, iblk, melts(:,:,iblk)*rhos/dt, a2D) endif if (f_sndmassdyn(1:1) /= 'x' .or. f_sisndmassdyn(1:1) /= 'x') then @@ -2661,7 +2676,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - ! dvsdtd is change in snow volumne per grid cell area, + ! dvsdtd is change in snow volume per grid cell area, ! sisndmassdyn is intensive, therefore multiply by aice worka(i,j) = aice(i,j,iblk)*dvsdtd(i,j,iblk)*rhos endif @@ -2772,6 +2787,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then + ! to-do remove divide by aice step ? + ! see https://github.com/ACCESS-NRI/cice5/blob/d083b62ed977fdaec0892c1838a55868ba5818eb/source/ice_flux.F90#L1030-L1031 worka(i,j) = aice(i,j,iblk)*fcondtop(i,j,iblk) endif enddo @@ -2781,22 +2798,22 @@ subroutine accum_hist (dt) if (f_siflcondbot(1:1) /= 'x') then !to-do: check about aice_init, still in CICE6 but different to siflcondtop - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! siflcondbot is intensive, fcondbot is grid cell average - ! https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L833-L834 - worka(i,j) = fcondbot(i,j,iblk) - ! CICE6 has this weighting, presumably an incorrent attempt to adjust - ! fcondbot so its consistent with aice ? - ! for ACCESS, fcondbot was caluclated in the UM, using aice from the timestep - ! before aice_init, so it doesn't really help - ! worka(i,j) = (aice(i,j,iblk)/aice_init(i,j,iblk))*fcondbot(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_siflcondbot, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! ! siflcondbot is intensive, fcondbot is grid cell average + ! ! https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L833-L834 + ! worka(i,j) = fcondbot(i,j,iblk) + ! ! CICE6 has this weighting, presumably an incorrent attempt to adjust + ! ! fcondbot so its consistent with aice ? + ! ! for ACCESS, fcondbot was caluclated in the UM, using aice from the timestep + ! ! before aice_init, so it doesn't really help + ! ! worka(i,j) = (aice(i,j,iblk)/aice_init(i,j,iblk))*fcondbot(i,j,iblk) + ! endif + ! enddo + ! enddo + call accum_hist_field(n_siflcondbot, iblk, fcondbot(:,:,iblk), a2D) endif if (f_sipr(1:1) /= 'x') then @@ -2846,27 +2863,28 @@ subroutine accum_hist (dt) endif if (f_siflsaltbot(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*fsalt(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_siflsaltbot, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! worka(i,j) = aice(i,j,iblk)*fsalt(i,j,iblk) + ! endif + ! enddo + ! enddo + call accum_hist_field(n_siflsaltbot, iblk, fsalt_ai(:,:,iblk), a2D) endif if (f_sisaltmass(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = ice_ref_salinity * rhoi * vice(i,j,iblk) / c1000 - endif - enddo - enddo - call accum_hist_field(n_sisaltmass, iblk, worka(:,:), a2D) + ! worka(:,:) = c0 + ! do j = jlo, jhi + ! do i = ilo, ihi + ! if (aice(i,j,iblk) > puny) then + ! worka(i,j) = ice_ref_salinity * rhoi * vice(i,j,iblk) / c1000 + ! endif + ! enddo + ! enddo + call accum_hist_field(n_sisaltmass, iblk, & + ice_ref_salinity * rhoi * vice(:,:,iblk) / c1000 , a2D) endif if (f_siflfwbot(1:1) /= 'x') then @@ -2888,6 +2906,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then + ! to-do : remove frain ? - goes straight to ocean (or into melt pond) worka(i,j) = aice(i,j,iblk)*(& frain(i,j,iblk) * rhofresh & + melts(i,j,iblk) * rhos/dt & From 25150ff5feaecb9f77eef161ccebdb02ed2ed932 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 28 Oct 2025 16:02:29 +1100 Subject: [PATCH 65/80] some prep for review --- drivers/access/CICE_RunMod.F90 | 4 +- io_netcdf/ice_history_write.F90 | 26 ++- source/ice_history.F90 | 364 +++++++------------------------- source/ice_history_shared.F90 | 14 +- 4 files changed, 105 insertions(+), 303 deletions(-) diff --git a/drivers/access/CICE_RunMod.F90 b/drivers/access/CICE_RunMod.F90 index d9424d40..c962cf17 100644 --- a/drivers/access/CICE_RunMod.F90 +++ b/drivers/access/CICE_RunMod.F90 @@ -144,7 +144,7 @@ subroutine CICE_Run if (dump_last .and. (itap == num_ice_ai) .and. (icpl_ai == num_cpl_ai)) then write_restart = 1 endif - + !*** ice "update" ***! call ice_step @@ -156,7 +156,7 @@ subroutine CICE_Run call time_average_fields_4_i2a !time averaging over ia cpl interval tmp_time = time_sec + dt - if ( mod(tmp_time, dt_cpl_ai) == 0 ) then !this happens at itap = num_ice_ai + if ( mod(tmp_time, dt_cpl_ai) == 0 ) then !this happens at itap = num_ice_ai !call ice_timer_start(timer_into_atm) !i2a fields ready to be sent for next IA cpl int in atm. call get_i2a_fields diff --git a/io_netcdf/ice_history_write.F90 b/io_netcdf/ice_history_write.F90 index b9c0eae2..53002dd0 100644 --- a/io_netcdf/ice_history_write.F90 +++ b/io_netcdf/ice_history_write.F90 @@ -684,15 +684,19 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) if (hist_avg) then if (TRIM(avail_hist_fields(n)%vname)/='sig1' .or. & TRIM(avail_hist_fields(n)%vname)/='sig2') then - if (avail_hist_fields(n)%avg_ice_present) then - call check(nf90_put_att(ncid,varid,'cell_methods',& - 'area: time: mean where sea_ice (mask=siconc)'), & - 'put att cell methods time mean '//avail_hist_fields(n)%vname) + call check(nf90_put_att(ncid,varid,'cell_methods',& + 'area: time: mean where sea_ice (mask=siconc)'), & + 'put att cell methods time mean '//avail_hist_fields(n)%vname) else - call check(nf90_put_att(ncid,varid,'cell_methods', & - 'area: mean where sea time: mean'), & - 'put att cell methods time mean '//avail_hist_fields(n)%vname) + if (TRIM(avail_hist_fields(n)%vname(1:2))/='si') then !native diags + call check(nf90_put_att(ncid,varid,'cell_methods','time: mean'), & + 'put att cell methods time mean '//avail_hist_fields(n)%vname) + else !cmip diags + call check(nf90_put_att(ncid,varid,'cell_methods', & + 'area: mean where sea time: mean'), & + 'put att cell methods time mean '//avail_hist_fields(n)%vname) + endif endif endif endif @@ -767,7 +771,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) ! Add cell_methods attribute to variables if averaged !--------------------------------------------------------------- if (hist_avg) then - status = nf90_put_att(ncid,varid,'cell_methods','area: mean where sea time: mean') + status = nf90_put_att(ncid,varid,'cell_methods','time: mean') if (status /= nf90_noerr) call abort_ice( & 'Error defining cell methods for '//avail_hist_fields(n)%vname) endif @@ -944,7 +948,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) ! Add cell_methods attribute to variables if averaged !--------------------------------------------------------------- if (hist_avg) then - status = nf90_put_att(ncid,varid,'cell_methods','area: mean where sea time: mean') + status = nf90_put_att(ncid,varid,'cell_methods','time: mean') if (status /= nf90_noerr) call abort_ice( & 'Error defining cell methods for '//avail_hist_fields(n)%vname) endif @@ -1014,7 +1018,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) ! Add cell_methods attribute to variables if averaged !--------------------------------------------------------------- if (hist_avg) then - status = nf90_put_att(ncid,varid,'cell_methods','area: mean where sea time: mean') + status = nf90_put_att(ncid,varid,'cell_methods','time: mean') if (status /= nf90_noerr) call abort_ice( & 'Error defining cell methods for '//avail_hist_fields(n)%vname) endif @@ -1084,7 +1088,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) ! Add cell_methods attribute to variables if averaged !--------------------------------------------------------------- if (hist_avg) then - status = nf90_put_att(ncid,varid,'cell_methods','area: mean where sea time: mean') + status = nf90_put_att(ncid,varid,'cell_methods','time: mean') if (status /= nf90_noerr) call abort_ice( & 'Error defining cell methods for '//avail_hist_fields(n)%vname) endif diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 9f7e0c98..2983d7cb 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -210,6 +210,7 @@ subroutine init_hist (dt) ! surface temperature is neither coupled or calculated within cice ! prognostic in the UM only if (f_Tsfc /= 'x') call abort_ice ("f_Tsfc not available, set to 'x'") + if (f_snowfracn /= 'x') call abort_ice ("f_Tsfc not available, set to 'x'") if (f_sitemptop /= 'x') call abort_ice ("f_sitemptop not available, set to 'x'") if (f_sitempsnic /= 'x') call abort_ice ("f_sitempsnic not available, set to 'x'") endif @@ -1050,11 +1051,18 @@ subroutine init_hist (dt) ! CMIP6 2D variables ! these definitions against the intensive/extensive/inst def - ! we use updated "mean where sea" or "mean where sea_ice" per CMIP7 data request + ! we use cell methods of "mean where sea" or "mean where sea_ice" per CMIP7 data request ! intensive means sea ice area weighted, and averaged only when sea ice is present ! extensive means a normal average (over all time and grid box area) ! extensive vars tend to zero when aice is zero, intensive vars do not + ! In general, this implementation is limited by only weighting intensive + ! variables by aice. It would be better if averaging using aice_init/aice_mid + ! was possible. These would then be used when accumulating history and averaging + ! variables which are calculated before cice runs (would be averaged using aice_init), + ! or based on thermodynamics only (would be averaged using aice_mid) + ! It would require new history variables for aice_init and aice_mid + call define_hist_field(n_aice,"siconc","1",tstr2D, tcstr, & "Sea-Ice Area Fraction (Ocean Grid)", & "none", c1, c0, & @@ -2111,27 +2119,11 @@ subroutine accum_hist (dt) !2D CMIP6 fields - if (f_sithick(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! ! sithick is intensive, vice is already aice*thickness - ! if (aice(i,j,iblk) > puny) worka(i,j) = vice(i,j,iblk) - ! enddo - ! enddo - call accum_hist_field(n_sithick, iblk, vice(:,:,iblk), a2D) - endif + if (f_sithick(1:1) /= 'x') & + call accum_hist_field(n_sithick, iblk, vice(:,:,iblk), a2D) - if (f_simass(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! ! simass is extensive, -> grid cell average - ! if (aice(i,j,iblk) > puny) worka(i,j) = rhoi*vice(i,j,iblk) - ! enddo - ! enddo - call accum_hist_field(n_simass, iblk, rhoi*vice(:,:,iblk), a2D) - endif + if (f_simass(1:1) /= 'x') & + call accum_hist_field(n_simass, iblk, rhoi*vice(:,:,iblk), a2D) if (f_siage(1:1) /= 'x') then worka(:,:) = c0 @@ -2145,40 +2137,15 @@ subroutine accum_hist (dt) call accum_hist_field(n_siage, iblk, worka(:,:), a2D) endif - if (f_sisnconc(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! ! siage is intensive, snowfrac is grid cell average already - ! if (aice(i,j,iblk) > puny .and. snowfrac(i,j,iblk) > puny) & - ! worka(i,j) = snowfrac(i,j,iblk) - ! enddo - ! enddo + if (f_sisnconc(1:1) /= 'x') & call accum_hist_field(n_sisnconc, iblk, snowfrac(:,:,iblk), a2D) - endif - if (f_sisnthick(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! ! sisnthick is intensive, vsno is already aice*thickness - ! if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & - ! worka(i,j) = vsno(i,j,iblk) - ! enddo - ! enddo - call accum_hist_field(n_sisnthick, iblk, vsno(:,:,iblk), a2D) - endif + if (f_sisnthick(1:1) /= 'x') & + call accum_hist_field(n_sisnthick, iblk, vsno(:,:,iblk), a2D) - if (f_sisnmass(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny .and. vsno(i,j,iblk) > puny) & - ! worka(i,j) = vsno(i,j,iblk) * rhos - ! enddo - ! enddo - call accum_hist_field(n_sisnmass, iblk, vsno(:,:,iblk) * rhos, a2D) - endif + if (f_sisnmass(1:1) /= 'x') & + ! sisnmass is intensive, vsno already grid cell average + call accum_hist_field(n_sisnmass, iblk, vsno(:,:,iblk) * rhos, a2D) if (f_sitemptop(1:1) /= 'x') then worka(:,:) = c0 @@ -2189,7 +2156,7 @@ subroutine accum_hist (dt) ! sitemptop is intensive, weight by aice worka(i,j) = aice(i,j,iblk) * trcr(i,j,nt_Tsfc,iblk) endif - enddo + enddo enddo call accum_hist_field(n_sitemptop, iblk, worka(:,:), a2D) endif @@ -2225,7 +2192,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi ! intensive, weight by aice - if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*uvel(i,j,iblk) + if (aice(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk)*uvel(i,j,iblk) enddo enddo call accum_hist_field(n_siu, iblk, worka(:,:), a2D) @@ -2236,7 +2204,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi ! intensive, weight by aice - if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk)*vvel(i,j,iblk) + if (aice(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk)*vvel(i,j,iblk) enddo enddo call accum_hist_field(n_siv, iblk, worka(:,:), a2D) @@ -2247,8 +2216,10 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi ! intensive, weight by aice - if (aice(i,j,iblk) > puny) worka(i,j) = aice(i,j,iblk) & - * sqrt(uvel(i,j,iblk)*uvel(i,j,iblk)+vvel(i,j,iblk)*vvel(i,j,iblk)) + if (aice(i,j,iblk) > puny) & + worka(i,j) = aice(i,j,iblk) & + * sqrt(uvel(i,j,iblk)*uvel(i,j,iblk) & + +vvel(i,j,iblk)*vvel(i,j,iblk)) enddo enddo call accum_hist_field(n_sispeed, iblk, worka(:,:), a2D) @@ -2301,7 +2272,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - !to-do: scale by aice/aice_init ? + !to-do: surface stress is from coupling, should use aice_init weighting if (aice(i,j,iblk) > puny) & ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strairy(i,j,iblk) @@ -2339,6 +2310,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strtltx(i,j,iblk) enddo enddo @@ -2350,6 +2322,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strtlty(i,j,iblk) enddo enddo @@ -2372,6 +2345,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = -aice(i,j,iblk)*fm(i,j,iblk)*uvel(i,j,iblk) enddo enddo @@ -2383,6 +2357,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strintx(i,j,iblk) enddo enddo @@ -2394,6 +2369,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strinty(i,j,iblk) enddo enddo @@ -2405,6 +2381,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*strength(i,j,iblk) enddo enddo @@ -2416,6 +2393,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*divu(i,j,iblk) enddo enddo @@ -2426,6 +2404,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi + ! to-do: weight by aice_init directly if (fsw(i,j,iblk) > puny .and. aice_init(i,j,iblk) > puny) then worka(i,j) = aice(i,j,iblk)*(fsw(i,j,iblk)-fswabs(i,j,iblk) & * aice(i,j,iblk)/aice_init(i,j,iblk)) & @@ -2460,106 +2439,32 @@ subroutine accum_hist (dt) call accum_hist_field(n_sisnhc, iblk, worka(:,:), a2D) endif - if (f_sidconcth(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! worka(i,j) = daidtt(i,j,iblk) - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidconcth, iblk, daidtt(:,:,iblk), a2D) - endif + if (f_sidconcth(1:1) /= 'x') & + call accum_hist_field(n_sidconcth, iblk, daidtt(:,:,iblk), a2D) - if (f_sidconcdyn(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! worka(i,j) = daidtd(i,j,iblk) - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidconcdyn, iblk, daidtd(:,:,iblk), a2D) - endif + if (f_sidconcdyn(1:1) /= 'x') & + call accum_hist_field(n_sidconcdyn, iblk, daidtd(:,:,iblk), a2D) - if (f_sidmassth(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! worka(i,j) = dvidtt(i,j,iblk) * rhoi - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidmassth, iblk, dvidtt(:,:,iblk) * rhoi, a2D) - endif - if (f_sidmassdyn(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! worka(i,j) = dvidtd(i,j,iblk) * rhoi - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidmassdyn, iblk, dvidtd(:,:,iblk) * rhoi, a2D) - endif + if (f_sidmassth(1:1) /= 'x') & + call accum_hist_field(n_sidmassth, iblk, dvidtt(:,:,iblk)*rhoi, a2D) - if (f_sidmassgrowthwat(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = frazil(i,j,iblk)*rhoi/dt - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidmassgrowthwat, iblk, frazil(:,:,iblk)*rhoi/dt, a2D) - endif + if (f_sidmassdyn(1:1) /= 'x') & + call accum_hist_field(n_sidmassdyn, iblk, dvidtd(:,:,iblk)*rhoi, a2D) - if (f_sidmassgrowthbot(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice_init(i,j,iblk) > puny) then - ! worka(i,j) = congel(i,j,iblk)*rhoi/dt - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidmassgrowthbot, iblk, congel(:,:,iblk)*rhoi/dt, a2D) - endif + if (f_sidmassgrowthwat(1:1) /= 'x') & + call accum_hist_field(n_sidmassgrowthwat, iblk, frazil(:,:,iblk)*rhoi/dt, a2D) - if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! ! snoice is grid area average - see https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L861-L862 - ! ! sidmasssi is extensive - ! worka(i,j) = snoice(i,j,iblk)*rhoi/dt - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidmasssi, iblk, snoice(:,:,iblk)*rhoi/dt, a2D) - endif + if (f_sidmassgrowthbot(1:1) /= 'x') & + call accum_hist_field(n_sidmassgrowthbot, iblk, congel(:,:,iblk)*rhoi/dt, a2D) - if (f_sisndmasssi(1:1) /= 'x') then - !To-do: calculate a seperate icesno diag for change in snow thickness in ice_therm_vertical ? - ! Its equivalent though, so fairly moot - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! ! sisndmasssi is intensive - ! worka(i,j) = snoice(i,j,iblk)*rhoi/dt - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sisndmasssi, iblk, snoice(:,:,iblk)*rhoi/dt, a2D) - endif + if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') & + call accum_hist_field(n_sidmasssi, iblk, snoice(:,:,iblk)*rhoi/dt, a2D) + + if (f_sisndmasssi(1:1) /= 'x') & + !To-do: calculate a seperate icesno diag for change in snow thickness in ice_therm_vertical ? + ! Its equivalent though, so fairly moot + call accum_hist_field(n_sisndmasssi, iblk, snoice(:,:,iblk)*rhoi/dt, a2D) if (f_sidmassevapsubl(1:1) /= 'x') then worka(:,:) = c0 @@ -2589,67 +2494,26 @@ subroutine accum_hist (dt) call accum_hist_field(n_sndmasssubl, iblk, worka(:,:), a2D) endif - if (f_sidmassmelttop(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! ! sidmassmelttop is extensive, meltt is grid cell average - ! worka(i,j) = meltt(i,j,iblk)*rhoi/dt - ! ! arguably meltt is calculated by thermodynamics only, and is not - ! ! advected during dynamics, and so should be corrected for aice_init - ! ! e.g.: - ! ! if (aice_init(i,j,iblk) > puny) then - ! ! worka(i,j) = aice(i,j,iblk)*meltt(i,j,iblk)*rhoi /& - ! ! (dt * aice_init(i,j,iblk)) - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidmassmelttop, iblk, meltt(:,:,iblk)*rhoi/dt, a2D) - endif + if (f_sidmassmelttop(1:1) /= 'x') & + ! sidmassmelttop is extensive, meltt is grid cell average + call accum_hist_field(n_sidmassmelttop, iblk, meltt(:,:,iblk)*rhoi/dt, a2D) - if (f_sidmassmeltbot(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! ! sidmassmeltbot is extensive, meltb is grid cell average - ! worka(i,j) = meltb(i,j,iblk)*rhoi/dt - ! ! arguably corrected to aice_init - ! ! if (aice_init(i,j,iblk) > puny) then - ! ! worka(i,j) = aice(i,j,iblk)*meltb(i,j,iblk)*rhoi / & - ! ! (dt * aice_init(i,j,iblk)) - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sidmassmeltbot, iblk, meltb(:,:,iblk)*rhoi/dt, a2D) - endif + if (f_sidmassmeltbot(1:1) /= 'x') & + ! sidmassmeltbot is extensive, meltb is grid cell average + call accum_hist_field(n_sidmassmeltbot, iblk, meltb(:,:,iblk)*rhoi/dt, a2D) - if (f_sidmasslat(1:1) /= 'x' .or. f_sidmassmeltlat(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! ! sidmasslat is extensive, meltl is grid cell average - ! worka(i,j) = meltl(i,j,iblk)*rhoi/dt - ! ! arguably corrected to aice_init - ! ! if (aice_init(i,j,iblk) > puny) then - ! ! worka(i,j) = aice(i,j,iblk)*meltl(i,j,iblk)*rhoi / & - ! ! (dt * aice_init(i,j,iblk)) - ! endif - ! enddo - ! enddo + if (f_sidmasslat(1:1) /= 'x' .or. f_sidmassmeltlat(1:1) /= 'x') & + ! sidmassmeltlat is extensive, meltl is grid cell average call accum_hist_field(n_sidmasslat, iblk, meltl(:,:,iblk)*rhoi/dt, a2D) - endif if (f_sndmasssnf(1:1) /= 'x' .or. f_sisndmasssnf(1:1) /= 'x') then - !to-do: fsnow seems to already be multiplied by aice - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/drivers/access/cpl_forcing_handler.F90#L702-L703 + !fsnow seems to already be multiplied by aice - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/drivers/access/cpl_forcing_handler.F90#L702-L703 !and then unweighted again - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/source/ice_step_mod.F90#L331-L332 - !therefore i will weight again. in theory should weight by aice_init so it from the same time as the incoming flux ? + !therefore i will weight again. do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - ! sisndmassmelt is intensive + ! sisndmasssnf is intensive worka(i,j) = aice(i,j,iblk)*fsnow(i,j,iblk) endif enddo @@ -2657,33 +2521,12 @@ subroutine accum_hist (dt) call accum_hist_field(n_sndmasssnf, iblk, worka(:,:), a2D) endif - if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! ! sisndmassmelt is intensive - ! ! melts is grid cell average - see https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L861-L862 - ! worka(i,j) = melts(i,j,iblk)*rhos/dt - ! endif - ! enddo - ! enddo - call accum_hist_field(n_sndmassmelt, iblk, melts(:,:,iblk)*rhos/dt, a2D) - endif + if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') & + ! sisndmassmelt is intensive, melts is grid cell average + call accum_hist_field(n_sndmassmelt, iblk, melts(:,:,iblk)*rhos/dt, a2D) - if (f_sndmassdyn(1:1) /= 'x' .or. f_sisndmassdyn(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! dvsdtd is change in snow volume per grid cell area, - ! sisndmassdyn is intensive, therefore multiply by aice - worka(i,j) = aice(i,j,iblk)*dvsdtd(i,j,iblk)*rhos - endif - enddo - enddo - call accum_hist_field(n_sndmassdyn, iblk, worka(:,:), a2D) - endif + if (f_sndmassdyn(1:1) /= 'x' .or. f_sisndmassdyn(1:1) /= 'x') & + call accum_hist_field(n_sndmassdyn, iblk, dvsdtd(:,:,iblk)*rhos, a2D) if (f_siflswdtop(1:1) /= 'x') then worka(:,:) = c0 @@ -2787,7 +2630,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - ! to-do remove divide by aice step ? + ! to-do: save fcondtop before its divided by aice step ! see https://github.com/ACCESS-NRI/cice5/blob/d083b62ed977fdaec0892c1838a55868ba5818eb/source/ice_flux.F90#L1030-L1031 worka(i,j) = aice(i,j,iblk)*fcondtop(i,j,iblk) endif @@ -2796,25 +2639,8 @@ subroutine accum_hist (dt) call accum_hist_field(n_siflcondtop, iblk, worka(:,:), a2D) endif - if (f_siflcondbot(1:1) /= 'x') then - !to-do: check about aice_init, still in CICE6 but different to siflcondtop - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! ! siflcondbot is intensive, fcondbot is grid cell average - ! ! https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L833-L834 - ! worka(i,j) = fcondbot(i,j,iblk) - ! ! CICE6 has this weighting, presumably an incorrent attempt to adjust - ! ! fcondbot so its consistent with aice ? - ! ! for ACCESS, fcondbot was caluclated in the UM, using aice from the timestep - ! ! before aice_init, so it doesn't really help - ! ! worka(i,j) = (aice(i,j,iblk)/aice_init(i,j,iblk))*fcondbot(i,j,iblk) - ! endif - ! enddo - ! enddo - call accum_hist_field(n_siflcondbot, iblk, fcondbot(:,:,iblk), a2D) - endif + if (f_siflcondbot(1:1) /= 'x') & + call accum_hist_field(n_siflcondbot, iblk, fcondbot(:,:,iblk), a2D) if (f_sipr(1:1) /= 'x') then worka(:,:) = c0 @@ -2862,44 +2688,16 @@ subroutine accum_hist (dt) call accum_hist_field(n_sifb, iblk, worka(:,:), a2D) endif - if (f_siflsaltbot(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! worka(i,j) = aice(i,j,iblk)*fsalt(i,j,iblk) - ! endif - ! enddo - ! enddo - call accum_hist_field(n_siflsaltbot, iblk, fsalt_ai(:,:,iblk), a2D) - endif + if (f_siflsaltbot(1:1) /= 'x') & + call accum_hist_field(n_siflsaltbot, iblk, fsalt_ai(:,:,iblk), a2D) - if (f_sisaltmass(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! worka(i,j) = ice_ref_salinity * rhoi * vice(i,j,iblk) / c1000 - ! endif - ! enddo - ! enddo + if (f_sisaltmass(1:1) /= 'x') & call accum_hist_field(n_sisaltmass, iblk, & ice_ref_salinity * rhoi * vice(:,:,iblk) / c1000 , a2D) - endif - if (f_siflfwbot(1:1) /= 'x') then - ! worka(:,:) = c0 - ! do j = jlo, jhi - ! do i = ilo, ihi - ! if (aice(i,j,iblk) > puny) then - ! ! siflfwbot is intensive, fresh_ai is a grid cell average already - ! worka(i,j) = fresh_ai(i,j,iblk) - ! endif - ! enddo - ! enddo - ! we seem to loose a lot of water if masking by aice ( i guess when cell totally melts out ) - call accum_hist_field(n_siflfwbot, iblk, fresh_ai(:,:,iblk), a2D) - endif + if (f_siflfwbot(1:1) /= 'x') & + ! siflfwbot is intensive, fresh_ai is a grid cell average already + call accum_hist_field(n_siflfwbot, iblk, fresh_ai(:,:,iblk), a2D) if (f_siflfwdrain(1:1) /= 'x') then worka(:,:) = c0 diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 8e534d11..f1d87d69 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -599,13 +599,13 @@ module ice_history_shared n_keffn_top , & n_Tinz , n_Sinz , & n_Tsnz, & - n_a11 , n_a12 , & - n_e11 , n_e12 , & - n_e22 , & - n_s11 , n_s12 , & - n_s22 , & - n_yieldstress11, n_yieldstress12, & - n_yieldstress22 + n_a11 , n_a12 , & + n_e11 , n_e12 , & + n_e22 , & + n_s11 , n_s12 , & + n_s22 , & + n_yieldstress11, n_yieldstress12, & + n_yieldstress22 interface accum_hist_field ! generic interface module procedure accum_hist_field_2D, & From 1b8fa36bb4e9264f5e29c318ad9ecbce4fbb3c06 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Wed, 29 Oct 2025 10:22:20 +1100 Subject: [PATCH 66/80] self review --- source/ice_history.F90 | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 2983d7cb..feadf954 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -32,7 +32,6 @@ module ice_history use ice_kinds_mod - use ice_constants, only: p5 use ice_exit, only: abort_ice @@ -231,7 +230,6 @@ subroutine init_hist (dt) #ifdef ACCESS if ( f_siflsenstop /= 'x' ) call abort_ice("f_siflsenstop not available, set to 'x'") - ! if ( f_sifllattop /= 'x' ) call abort_ice("f_sifllattop not available, set to 'x'") if ( f_sifllwdtop /= 'x' ) call abort_ice("f_sifllwdtop not available, set to 'x'") if ( f_sifllwutop /= 'x' ) call abort_ice("f_sifllwutop not available, set to 'x'") if ( f_siflswdtop /= 'x' ) call abort_ice("f_siflswdtop not available, set to 'x'") @@ -959,11 +957,6 @@ subroutine init_hist (dt) "ice extent flag", c1, c0, & ns1, f_icepresent) - call define_hist_field(n_icepresent,"sitimefrac","1",tstr2D, tcstr, & - "fraction of time-avg interval that ice is present", & - "ice extent flag", c1, c0, & - ns1, f_sitimefrac) - call define_hist_field(n_fsurf_ai,"fsurf_ai","W/m^2",tstr2D, tcstr, & "net surface heat flux", & "positive downward, excludes conductive flux, weighted by ice area", & @@ -1050,7 +1043,7 @@ subroutine init_hist (dt) ns1, f_FY) ! CMIP6 2D variables - ! these definitions against the intensive/extensive/inst def + ! these definitions follow the intensive/extensive/inst def in Notz 2016 ! we use cell methods of "mean where sea" or "mean where sea_ice" per CMIP7 data request ! intensive means sea ice area weighted, and averaged only when sea ice is present ! extensive means a normal average (over all time and grid box area) @@ -1068,6 +1061,11 @@ subroutine init_hist (dt) "none", c1, c0, & ns1, f_siconc) + call define_hist_field(n_icepresent,"sitimefrac","1",tstr2D, tcstr, & + "fraction of time-avg interval that ice is present", & + "ice extent flag", c1, c0, & + ns1, f_sitimefrac) + call define_hist_field(n_hi,"sivol","m",tstr2D, tcstr, & "Sea-Ice Volume per Area", & "ice volume per unit grid cell area", c1, c0, & From 14e1ecbf2e0e4acad6b86cbe9a7a1cf3b5195f4b Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:01:25 +1100 Subject: [PATCH 67/80] Apply suggestions from code review Co-authored-by: Spencer Wong <88933912+blimlim@users.noreply.github.com> --- source/ice_history.F90 | 11 +++++------ source/ice_read_write.F90 | 4 ++-- source/ice_therm_vertical.F90 | 24 ++++++++++++------------ 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index feadf954..fd888e7a 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1078,7 +1078,7 @@ subroutine init_hist (dt) call define_hist_field(n_simass,"simass","kg m^-2",tstr2D, tcstr, & "Sea-Ice Mass", & - "mass divided by area", c1, c0, & + "ice mass per unit grid cell area", c1, c0, & ns1, f_simass) call define_hist_field(n_siage,"siage","s",tstr2D, tcstr, & @@ -1098,12 +1098,12 @@ subroutine init_hist (dt) call define_hist_field(n_sisnthick,"sisnthick","m",tstr2D, tcstr, & "Snow Thickness", & - "snow volume divided by area", c1, c0, & + "snow volume divided by ice area", c1, c0, & ns1, f_sisnthick, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisnmass,"sisnmass","kg m^-2",tstr2D, tcstr, & "Snow Mass per Area", & - "snow mass divided by grid cell area", c1, c0, & + "snow mass volume per unit grid cell area", c1, c0, & ns1, f_sisnmass, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitemptop,"sitemptop","K",tstr2D, tcstr, & @@ -1162,7 +1162,7 @@ subroutine init_hist (dt) ns1, f_sistryubot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcetiltx,"siforcetiltx","N m^-2",ustr2D, ucstr, & - "xSea-Surface Tilt Term in Force Balance (X-Component)", & + "Sea-Surface Tilt Term in Force Balance (X-Component)", & "none", c1, c0, & ns1, f_siforcetiltx, avg_ice_present=.true., mask_ice_free_points=.true.) @@ -1719,7 +1719,6 @@ subroutine accum_hist (dt) use ice_flux, only: fsw, flw, fsnow, frain, sst, sss, uocn, vocn, & frzmlt_init, fswfac, fswabs, fswthru, alvdr, alvdf, alidr, alidf, & albice, albsno, albpnd, coszen, flat, fsens, flwout, evap, & - evap_ice,evap_snow, & Tair, Tref, Qref, congel, frazil, snoice, dsnow, & melts, meltb, meltt, meltl, fresh, fsalt, fresh_ai, fsalt_ai, & fhocn, fhocn_ai, uatm, vatm, & @@ -2177,7 +2176,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! nb Tsnice is approximate, not a tracer + ! nb Ti_bot is approximate, not a tracer ! sitempbot is intensive, weight by aice worka(i,j) = aice(i,j,iblk)*Ti_bot(i,j,iblk) enddo diff --git a/source/ice_read_write.F90 b/source/ice_read_write.F90 index fb190bbf..833bed90 100755 --- a/source/ice_read_write.F90 +++ b/source/ice_read_write.F90 @@ -1563,7 +1563,7 @@ subroutine ice_read_nc_z(fid, nrec, varname, work, diag, & if (status /= nf90_noerr) then call abort_ice ( & - 'ice_read_nc: Cannot get variable '//trim(varname) ) + 'ice_read_nc_z: Cannot get variable '//trim(varname) ) endif endif ! my_task = master_task @@ -1797,7 +1797,7 @@ subroutine ice_write_nc_xyz(fid, nrec, varid, work, diag, & if (status /= nf90_noerr) then call abort_ice ( & - 'ice_write_nc_xy: Cannot put variable '//trim(nf90_strerror(status)) ) + 'ice_write_nc_xyz: Cannot put variable '//trim(nf90_strerror(status)) ) endif endif ! my_task = master_task diff --git a/source/ice_therm_vertical.F90 b/source/ice_therm_vertical.F90 index 5e8ecb7a..4c3f1e1f 100755 --- a/source/ice_therm_vertical.F90 +++ b/source/ice_therm_vertical.F90 @@ -480,18 +480,18 @@ subroutine thermo_vertical (nx_block, ny_block, & ! Tsnice from https://github.com/CICE-Consortium/Icepack/blob/e9d626f0e5b743e143a2e87248a1aa22ee4f3751/columnphysics/icepack_therm_vertical.F90#L378C1-L385C12 ! Tsnice is : ! - the average of temperature of bottom snow layer and top ice layer, - ! - weighted by aicen across all thicknii categories - if ((hslyr(ij)+hilyr(ij)) > puny) then - if (hslyr(ij) > puny) then - Tsnice(ij) = Tsnice(ij) + aicen(i,j)*(& - (hslyr(ij)*zTsn(ij,nslyr) + hilyr(ij)*zTin(ij,1)) & - / (hslyr(ij)+hilyr(ij)) & - ) - else - Tsnice(ij) = Tsnice(ij) + aicen(i,j)*Tsf(ij) - endif - endif - enddo + ! - weighted by aicen across all thickness categories + if (hslyr(ij) > puny) then + ! interface temperature is average of top ice layer & bottom snow layer temperatures, + ! weighted by the thickness of each layer (https://github.com/CICE-Consortium/Icepack/pull/542#issuecomment-3464152061) + Tsnice(ij) = Tsnice(ij) + aicen(i,j)*(& + (hilyr(ij)*zTsn(ij,nslyr) + hslyr(ij)*zTin(ij,1)) & + / (hslyr(ij)+hilyr(ij)) & + ) + else + Tsnice(ij) = Tsnice(ij) + aicen(i,j)*Tsf(ij) + endif + enddo if (l_stop) return From a43343a1c8c1f99dd9e1d03c6bc2982c98d4fe4f Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:21:47 +1100 Subject: [PATCH 68/80] Apply suggestions from code review Co-authored-by: Spencer Wong <88933912+blimlim@users.noreply.github.com> --- io_netcdf/ice_history_write.F90 | 1 + source/ice_fileunits.F90 | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/io_netcdf/ice_history_write.F90 b/io_netcdf/ice_history_write.F90 index 53002dd0..4d75b228 100644 --- a/io_netcdf/ice_history_write.F90 +++ b/io_netcdf/ice_history_write.F90 @@ -1140,6 +1140,7 @@ subroutine ice_hist_create(ns, ncfile, ncid, var, coord_var, var_nverts, var_nz) call check(nf90_put_att(ncid,nf90_global,'comment2',title), & 'global attribute comment2') + ! TO-DO: Update output for CF compliance ! ! title = 'CF-1.0' ! call check(nf90_put_att(ncid,nf90_global,'conventions',title), & ! 'global attribute conventions') diff --git a/source/ice_fileunits.F90 b/source/ice_fileunits.F90 index a3a07fe0..4cdcad73 100755 --- a/source/ice_fileunits.F90 +++ b/source/ice_fileunits.F90 @@ -293,7 +293,7 @@ subroutine flush_fileunit(iunit) end subroutine flush_fileunit !======================================================================= - +! Namelist error handling ported from https://github.com/CICE-Consortium/CICE/blob/8e3ef7c4cb657705ceff5bfec3e12b49dec4973e/cicecore/shared/ice_fileunits.F90#L328 subroutine goto_nml(iunit, nml, status) ! Search to namelist group within ice_in file. ! for compilers that do not allow optional namelists @@ -306,7 +306,7 @@ subroutine goto_nml(iunit, nml, status) nml ! namelist to search for integer(kind=int_kind), intent(out) :: & - status ! status of subrouine + status ! status of subroutine ! local variables character(len=char_len) :: & From 2a9f9e40439939cd1361aa585b4a2f106fa3778b Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 7 Nov 2025 08:07:43 +1100 Subject: [PATCH 69/80] review feedback, and _ai variables --- drivers/access/CICE_RunMod.F90 | 9 + source/ice_flux.F90 | 30 ++- source/ice_history.F90 | 338 ++++++++++++++------------------- source/ice_history_shared.F90 | 18 +- 4 files changed, 180 insertions(+), 215 deletions(-) diff --git a/drivers/access/CICE_RunMod.F90 b/drivers/access/CICE_RunMod.F90 index c962cf17..9d066deb 100644 --- a/drivers/access/CICE_RunMod.F90 +++ b/drivers/access/CICE_RunMod.F90 @@ -572,6 +572,15 @@ subroutine coupling_prep (iblk) fsalt_ai (i,j,iblk) = fsalt (i,j,iblk) fhocn_ai (i,j,iblk) = fhocn (i,j,iblk) fswthru_ai(i,j,iblk) = fswthru(i,j,iblk) + fsens_ai (i,j,iblk) = fsens(i,j,iblk) + flat_ai (i,j,iblk) = flat(i,j,iblk) + fswabs_ai (i,j,iblk) = fswabs(i,j,iblk) + flwout_ai (i,j,iblk) = flwout(i,j,iblk) + evap_ai (i,j,iblk) = evap(i,j,iblk) + evap_ice_ai(i,j,iblk) = evap_ice(i,j,iblk) + evap_snow_ai(i,j,iblk) = evap_snow(i,j,iblk) + fcondtop_ai(i,j,iblk) = fcondtop(i,j,iblk) + fsurf_ai(i,j,iblk) = fsurf(i,j,iblk) if (nbtrcr > 0) then do k = 1, nbtrcr diff --git a/source/ice_flux.F90 b/source/ice_flux.F90 index 1dff7836..55f85c54 100755 --- a/source/ice_flux.F90 +++ b/source/ice_flux.F90 @@ -308,12 +308,21 @@ module ice_flux ! ice diagnostics and history files as these are more accurate. ! (The others suffer from problem of incorrect values at grid boxes ! that change from an ice free state to an icy state.) - + real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks), public :: & fresh_ai, & ! fresh water flux to ocean (kg/m^2/s) fsalt_ai, & ! salt flux to ocean (kg/m^2/s) fhocn_ai, & ! net heat flux to ocean (W/m^2) - fswthru_ai ! shortwave penetrating to ocean (W/m^2) + fswthru_ai, & ! shortwave penetrating to ocean (W/m^2) + fsens_ai, & ! sensible heat flux (W/m^2) + flat_ai, & ! latent heat flux (W/m^2) + fswabs_ai, & ! shortwave absorbed heat flx (W/m^2) + flwout_ai, & ! upwd lw emitted heat flx + evap_ai, & ! & evaporation (kg/m2/s) + evap_ice_ai, & ! & evaporation (kg/m2/s) + evap_snow_ai, & ! & evaporation (kg/m2/s) + fcondtop_ai, & ! downward cond flux at top surface (W m-2) + fsurf_ai ! net flux to top surface, excluding fcondtop ! Used with data assimilation in hadgem drivers real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: & @@ -613,11 +622,20 @@ subroutine init_history_therm fsalt_ai (:,:,:) = c0 fhocn_ai (:,:,:) = c0 fswthru_ai(:,:,:) = c0 - albice (:,:,:) = c0 - albsno (:,:,:) = c0 - albpnd (:,:,:) = c0 + fsens_ai (:,:,:) = c0 + flat_ai (:,:,:) = c0 + fswabs_ai (:,:,:) = c0 + flwout_ai (:,:,:) = c0 + evap_ai (:,:,:) = c0 + evap_ice_ai(:,:,:) = c0 + evap_snow_ai(:,:,:) = c0 + fcondtop_ai(:,:,:) = c0 + fsurf_ai (:,:,:) = c0 + albice (:,:,:) = c0 + albsno (:,:,:) = c0 + albpnd (:,:,:) = c0 snowfracn (:,:,:,:) = c0 - snowfrac (:,:,:) = c0 + snowfrac (:,:,:) = c0 ! drag coefficients are computed prior to the atmo_boundary call, ! during the thermodynamics section diff --git a/source/ice_history.F90 b/source/ice_history.F90 index fd888e7a..890605aa 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -60,8 +60,8 @@ subroutine init_hist (dt) use ice_blocks, only: nx_block, ny_block use ice_broadcast, only: broadcast_scalar, broadcast_array use ice_communicate, only: my_task, master_task - use ice_constants, only: c0, c1, c2, c100, mps_to_cmpdy, rhofresh, & - Tffresh, kg_to_g, secday + use ice_constants, only: c0, c1, c2, c100, c1000, mps_to_cmpdy, rhoi, rhos, & + rhow, rhofresh, Tffresh, kg_to_g, secday, ice_ref_salinity use ice_calendar, only: yday, days_per_year, histfreq, & histfreq_n, nstreams use ice_domain_size, only: max_blocks, max_nstrm @@ -81,6 +81,10 @@ subroutine init_hist (dt) use ice_zbgc_shared, only: skl_bgc use ice_fileunits, only: goto_nml +#ifdef AusCOM + use cpl_parameters, only: do_scale_fluxes +#endif + real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -229,12 +233,35 @@ subroutine init_hist (dt) if (f_Tsnz (1:1) /= 'x') f_VGRDs = .true. #ifdef ACCESS + ! these are not available with UM style coupling if ( f_siflsenstop /= 'x' ) call abort_ice("f_siflsenstop not available, set to 'x'") if ( f_sifllwdtop /= 'x' ) call abort_ice("f_sifllwdtop not available, set to 'x'") if ( f_sifllwutop /= 'x' ) call abort_ice("f_sifllwutop not available, set to 'x'") if ( f_siflswdtop /= 'x' ) call abort_ice("f_siflswdtop not available, set to 'x'") if ( f_siflswutop /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") #endif + +#ifdef AusCOM + if ( .not. do_scale_fluxes ) then + ! normal case is these are scaled in place to grid cell average, + ! however without do_scale_fluxes, these are ice area averages + if ( f_fsens /= 'x' ) call abort_ice("f_alidf not available, use f_fsens_ai") + if ( f_flat /= 'x' ) call abort_ice("f_alidf not available, use f_flat_ai") + if ( f_fswabs /= 'x' ) call abort_ice("f_alidf not available, use f_fswabs_ai") + if ( f_flwup /= 'x' ) call abort_ice("f_alidf not available, use f_flwup_ai") + if ( f_evap /= 'x' ) call abort_ice("f_alidf not available, use f_evap_ai") + if ( f_Tref /= 'x' ) call abort_ice("f_Tref not available, set to 'x'") + if ( f_Qref /= 'x' ) call abort_ice("f_Qref not available, set to 'x'") + if ( f_fresh /= 'x' ) call abort_ice("f_alidf not available, use f_fresh_ai") + if ( f_fsalt /= 'x' ) call abort_ice("f_alidf not available, use f_fsalt_ai") + if ( f_fhocn /= 'x' ) call abort_ice("f_alidf not available, use f_fhocn_ai") + if ( f_fswthru /= 'x' ) call abort_ice("f_alidf not available, use f_fswthru_ai") + if ( f_alvdr /= 'x' ) call abort_ice("f_alvdr not available, use f_alvdr_ai") + if ( f_alidr /= 'x' ) call abort_ice("f_alidr not available, use f_alidr_ai") + if ( f_alvdf /= 'x' ) call abort_ice("f_alvdf not available, use f_alvdf_ai") + if ( f_alidf /= 'x' ) call abort_ice("f_alidf not available, use f_alidf_ai") + endif +#endif endif ! end check history config call broadcast_scalar (f_tmask, master_task) @@ -1043,11 +1070,11 @@ subroutine init_hist (dt) ns1, f_FY) ! CMIP6 2D variables - ! these definitions follow the intensive/extensive/inst def in Notz 2016 - ! we use cell methods of "mean where sea" or "mean where sea_ice" per CMIP7 data request - ! intensive means sea ice area weighted, and averaged only when sea ice is present - ! extensive means a normal average (over all time and grid box area) - ! extensive vars tend to zero when aice is zero, intensive vars do not + ! these definitions follow the intensive/extensive/inst def in Notz 2016 + ! we use cell methods of "mean where sea" or "mean where sea_ice" per CMIP7 data request + ! intensive means sea ice area weighted, and averaged only when sea ice is present + ! extensive means a normal average (over all time and grid box area) + ! extensive vars tend to zero when aice is zero, intensive vars do not ! In general, this implementation is limited by only weighting intensive ! variables by aice. It would be better if averaging using aice_init/aice_mid @@ -1083,7 +1110,7 @@ subroutine init_hist (dt) call define_hist_field(n_siage,"siage","s",tstr2D, tcstr, & "Age of Sea Ice", & - "none", c1, c0, & + "average age of ice, when ice present, weighted by area fraction", c1, c0, & ns1, f_siage, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifb,"sifb","m",tstr2D, tcstr, & @@ -1233,32 +1260,32 @@ subroutine init_hist (dt) call define_hist_field(n_sidmassth,"sidmassth","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change from Thermodynamics", & - "none", c1, c0, & + "none", rhoi, c0, & ns1, f_sidmassth) call define_hist_field(n_sidmassdyn,"sidmassdyn","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change from Dynamics", & - "none", c1, c0, & + "none", rhoi, c0, & ns1, f_sidmassdyn) call define_hist_field(n_sidmassgrowthwat,"sidmassgrowthwat","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Growth in Supercooled Open Water (Frazil)", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sidmassgrowthwat) call define_hist_field(n_sidmassgrowthbot,"sidmassgrowthbot","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Basal Growth", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sidmassgrowthbot) call define_hist_field(n_sidmasssi,"sidmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Snow-to-Ice Conversion", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sidmasssi) call define_hist_field(n_sidmasssi,"sidmassgrowthsi","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Snow-to-Ice Conversion", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sidmassgrowthsi) call define_hist_field(n_sidmassevapsubl,"sidmassevapsubl","kg m^-2 s^-1",tstr2D, tcstr, & @@ -1278,22 +1305,22 @@ subroutine init_hist (dt) call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Surface Melting", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sidmassmelttop) call define_hist_field(n_sidmassmeltbot,"sidmassmeltbot","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Bottom Melting", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sidmassmeltbot) call define_hist_field(n_sidmasslat,"sidmasslat","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Lateral Melting", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sidmasslat) call define_hist_field(n_sidmasslat,"sidmassmeltlat","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Lateral Melting", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sidmassmeltlat) call define_hist_field(n_sndmasssnf,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & @@ -1308,27 +1335,27 @@ subroutine init_hist (dt) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Melt", & - "none", c1, c0, & + "none", rhos/dt, c0, & ns1, f_sndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Melt", & - "none", c1, c0, & + "none", rhos/dt, c0, & ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Snow-to-Ice Conversion", & - "none", c1, c0, & + "none", rhoi/dt, c0, & ns1, f_sisndmasssi, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & - "none", c1, c0, & + "none", rhos, c0, & ns1, f_sndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sisndmassdyn","kg m-2 s-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & - "none", c1, c0, & + "none", rhos, c0, & ns1, f_sisndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdtop,"siflswdtop","W m^-2",tstr2D, tcstr, & @@ -1408,7 +1435,7 @@ subroutine init_hist (dt) call define_hist_field(n_sisaltmass,"sisaltmass","kg m^-2",tstr2D, tcstr, & "Mass of Salt in Sea Ice",& - "none", c1, c0, & + "none", ice_ref_salinity * rhoi / c1000 , c0, & ns1, f_sisaltmass) endif ! if (histfreq(ns1) /= 'x') then @@ -1697,7 +1724,7 @@ subroutine accum_hist (dt) use ice_constants, only: c0, c1, p25, puny, secday, depressT, & awtvdr, awtidr, awtvdf, awtidf, Lfresh, rhoi, rhos, rhow, rhofresh, cp_ice, & - spval_dbl, Tffresh, ice_ref_salinity, c1000 + spval_dbl, Tffresh use ice_domain, only: blocks_ice, nblocks use ice_grid, only: tmask, lmask_n, lmask_s, tarea, HTE, HTN #ifdef AusCOM @@ -1716,24 +1743,7 @@ subroutine accum_hist (dt) use ice_dyn_eap, only: a11, a12, e11, e12, e22, s11, s12, s22, & yieldstress11, yieldstress12, yieldstress22 use ice_dyn_shared, only: kdyn, principal_stress,a_min - use ice_flux, only: fsw, flw, fsnow, frain, sst, sss, uocn, vocn, & - frzmlt_init, fswfac, fswabs, fswthru, alvdr, alvdf, alidr, alidf, & - albice, albsno, albpnd, coszen, flat, fsens, flwout, evap, & - Tair, Tref, Qref, congel, frazil, snoice, dsnow, & - melts, meltb, meltt, meltl, fresh, fsalt, fresh_ai, fsalt_ai, & - fhocn, fhocn_ai, uatm, vatm, & - fswthru_ai, strairx, strairy, strtltx, strtlty, strintx, strinty, & - strocnx, strocny, fm, daidtt, dvidtt, dvsdtt, daidtd, dvidtd, dvsdtd, fsurf, & - fcondtop, fsurfn, fcondtopn, & - fcondbot, fcondbotn, & - flatn, fsensn, albcnt, prs_sig, & - stressp_1, stressm_1, stress12_1, & - stressp_2, stressm_2, stress12_2, & - stressp_3, stressm_3, stress12_3, & - stressp_4, stressm_4, stress12_4, sig1, sig2, & - mlt_onset, frz_onset, dagedtt, dagedtd, fswint_ai, Tn_top, & - keffn_top, snowfrac, snowfracn, alvdr_ai, alvdf_ai, alidr_ai, & - alidf_ai, evap_snow, evap_ice + use ice_flux use ice_atmo, only: formdrag use ice_history_shared ! almost everything use ice_history_write, only: ice_write_hist @@ -1926,15 +1936,11 @@ subroutine accum_hist (dt) call accum_hist_field(n_fswfac, iblk, fswfac(:,:,iblk), a2D) if (f_fswabs (1:1) /= 'x') & call accum_hist_field(n_fswabs, iblk, fswabs(:,:,iblk), a2D) - + if (f_fswabs_ai(1:1)/= 'x') & + call accum_hist_field(n_fswabs_ai, iblk, fswabs_ai(:,:,iblk), a2D) if (f_fswint_ai (1:1) /= 'x') & call accum_hist_field(n_fswint_ai, iblk, fswint_ai(:,:,iblk), a2D) - workb(:,:) = aice(:,:,iblk) - - if (f_fswabs_ai(1:1)/= 'x') & - call accum_hist_field(n_fswabs_ai, iblk, fswabs(:,:,iblk)*workb(:,:), a2D) - if (f_fswup(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi @@ -1948,6 +1954,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_fswup, iblk, worka(:,:), a2D) endif + workb(:,:) = aice(:,:,iblk) if (f_albsni (1:1) /= 'x') & call accum_hist_field(n_albsni, iblk, & (awtvdr*alvdr(:,:,iblk) & @@ -1983,23 +1990,23 @@ subroutine accum_hist (dt) if (f_flat (1:1) /= 'x') & call accum_hist_field(n_flat, iblk, flat(:,:,iblk), a2D) if (f_flat_ai(1:1) /= 'x') & - call accum_hist_field(n_flat_ai,iblk, flat(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_flat_ai,iblk, flat_ai(:,:,iblk), a2D) if (f_fsens (1:1) /= 'x') & call accum_hist_field(n_fsens, iblk, fsens(:,:,iblk), a2D) if (f_fsens_ai(1:1)/= 'x') & - call accum_hist_field(n_fsens_ai,iblk, fsens(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_fsens_ai,iblk, fsens_ai(:,:,iblk), a2D) if (f_flwup (1:1) /= 'x') & call accum_hist_field(n_flwup, iblk, flwout(:,:,iblk), a2D) if (f_flwup_ai(1:1)/= 'x') & - call accum_hist_field(n_flwup_ai,iblk, flwout(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_flwup_ai,iblk, flwout_ai(:,:,iblk), a2D) if (f_evap (1:1) /= 'x') & call accum_hist_field(n_evap, iblk, evap(:,:,iblk), a2D) if (f_evap_ai(1:1) /= 'x') & call accum_hist_field(n_evap_ai,iblk, evap(:,:,iblk)*workb(:,:), a2D) if (f_evap_ice_ai(1:1) /= 'x') & - call accum_hist_field(n_evap_ice_ai,iblk, evap_ice(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_evap_ice_ai,iblk, evap_ice_ai(:,:,iblk), a2D) if (f_evap_snow_ai(1:1) /= 'x') & - call accum_hist_field(n_evap_snow_ai,iblk, evap_snow(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_evap_snow_ai,iblk, evap_snow_ai(:,:,iblk), a2D) if (f_Tair (1:1) /= 'x') & call accum_hist_field(n_Tair, iblk, Tair(:,:,iblk), a2D) @@ -2098,10 +2105,10 @@ subroutine accum_hist (dt) call accum_hist_field(n_dagedtd, iblk, dagedtd(:,:,iblk), a2D) if (f_fsurf_ai(1:1)/= 'x') & - call accum_hist_field(n_fsurf_ai,iblk, fsurf(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_fsurf_ai,iblk, fsurf_ai(:,:,iblk), a2D) if (f_fcondtop_ai(1:1)/= 'x') & call accum_hist_field(n_fcondtop_ai, iblk, & - fcondtop(:,:,iblk)*workb(:,:), a2D) + fcondtop_ai(:,:,iblk), a2D) if (f_icepresent(1:1) /= 'x' .or. f_sitimefrac(1:1) /= 'x') then worka(:,:) = c0 @@ -2120,7 +2127,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sithick, iblk, vice(:,:,iblk), a2D) if (f_simass(1:1) /= 'x') & - call accum_hist_field(n_simass, iblk, rhoi*vice(:,:,iblk), a2D) + call accum_hist_field(n_simass, iblk, vice(:,:,iblk), a2D) ! *rhoi in define_hist_field if (f_siage(1:1) /= 'x') then worka(:,:) = c0 @@ -2142,7 +2149,7 @@ subroutine accum_hist (dt) if (f_sisnmass(1:1) /= 'x') & ! sisnmass is intensive, vsno already grid cell average - call accum_hist_field(n_sisnmass, iblk, vsno(:,:,iblk) * rhos, a2D) + call accum_hist_field(n_sisnmass, iblk, vsno(:,:,iblk) , a2D) ! * rhos in define_hist_field if (f_sitemptop(1:1) /= 'x') then worka(:,:) = c0 @@ -2417,7 +2424,8 @@ subroutine accum_hist (dt) do k = 1,nilyr do j = jlo, jhi do i = ilo, ihi - worka(i,j) = worka(i,j) + trcr(i,j,nt_qice+k-1,iblk)*vice(i,j,iblk)/real(nilyr,kind=dbl_kind) + worka(i,j) = worka(i,j) & + + trcr(i,j,nt_qice+k-1,iblk)*vice(i,j,iblk)/real(nilyr,kind=dbl_kind) enddo enddo enddo @@ -2442,76 +2450,60 @@ subroutine accum_hist (dt) if (f_sidconcdyn(1:1) /= 'x') & call accum_hist_field(n_sidconcdyn, iblk, daidtd(:,:,iblk), a2D) - if (f_sidmassth(1:1) /= 'x') & - call accum_hist_field(n_sidmassth, iblk, dvidtt(:,:,iblk)*rhoi, a2D) + call accum_hist_field(n_sidmassth, iblk, dvidtt(:,:,iblk), a2D) ! *rhoi in define_hist_field if (f_sidmassdyn(1:1) /= 'x') & - call accum_hist_field(n_sidmassdyn, iblk, dvidtd(:,:,iblk)*rhoi, a2D) + call accum_hist_field(n_sidmassdyn, iblk, dvidtd(:,:,iblk), a2D) ! *rhoi in define_hist_field if (f_sidmassgrowthwat(1:1) /= 'x') & - call accum_hist_field(n_sidmassgrowthwat, iblk, frazil(:,:,iblk)*rhoi/dt, a2D) + call accum_hist_field(n_sidmassgrowthwat, iblk, frazil(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sidmassgrowthbot(1:1) /= 'x') & - call accum_hist_field(n_sidmassgrowthbot, iblk, congel(:,:,iblk)*rhoi/dt, a2D) + call accum_hist_field(n_sidmassgrowthbot, iblk, congel(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') & - call accum_hist_field(n_sidmasssi, iblk, snoice(:,:,iblk)*rhoi/dt, a2D) + call accum_hist_field(n_sidmasssi, iblk, snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sisndmasssi(1:1) /= 'x') & !To-do: calculate a seperate icesno diag for change in snow thickness in ice_therm_vertical ? ! Its equivalent though, so fairly moot - call accum_hist_field(n_sisndmasssi, iblk, snoice(:,:,iblk)*rhoi/dt, a2D) + call accum_hist_field(n_sisndmasssi, iblk, snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field - if (f_sidmassevapsubl(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! sidmassevapsubl is extensive - ! evap_ice is ice area average -> convert to grid cell area - worka(i,j) = aice(i,j,iblk) * evap_ice(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_sidmassevapsubl, iblk, worka(:,:), a2D) - endif + if (f_sidmassevapsubl(1:1) /= 'x') & + ! sidmassevapsubl is extensive, evap_snow_ai is grid cell average + call accum_hist_field(n_sidmassevapsubl, iblk, evap_ice_ai(:,:,iblk), a2D) if (f_sndmasssubl(1:1) /= 'x' .or. f_sisndmasssubl(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! sisndmasssubl is intensive - ! evap_snow is ice area average, see evap_snow_ai -> weight by aice - worka(i,j) = aice(i,j,iblk)*evap_snow(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_sndmasssubl, iblk, worka(:,:), a2D) + ! sisndmasssubl is intensive, evap_snow_ai is grid cell average + call accum_hist_field(n_sndmasssubl, iblk, evap_snow_ai(:,:,iblk), a2D) endif if (f_sidmassmelttop(1:1) /= 'x') & ! sidmassmelttop is extensive, meltt is grid cell average - call accum_hist_field(n_sidmassmelttop, iblk, meltt(:,:,iblk)*rhoi/dt, a2D) + call accum_hist_field(n_sidmassmelttop, iblk, meltt(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sidmassmeltbot(1:1) /= 'x') & ! sidmassmeltbot is extensive, meltb is grid cell average - call accum_hist_field(n_sidmassmeltbot, iblk, meltb(:,:,iblk)*rhoi/dt, a2D) + call accum_hist_field(n_sidmassmeltbot, iblk, meltb(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sidmasslat(1:1) /= 'x' .or. f_sidmassmeltlat(1:1) /= 'x') & ! sidmassmeltlat is extensive, meltl is grid cell average - call accum_hist_field(n_sidmasslat, iblk, meltl(:,:,iblk)*rhoi/dt, a2D) + call accum_hist_field(n_sidmasslat, iblk, meltl(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sndmasssnf(1:1) /= 'x' .or. f_sisndmasssnf(1:1) /= 'x') then - !fsnow seems to already be multiplied by aice - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/drivers/access/cpl_forcing_handler.F90#L702-L703 - !and then unweighted again - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/source/ice_step_mod.F90#L331-L332 - !therefore i will weight again. do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then ! sisndmasssnf is intensive - worka(i,j) = aice(i,j,iblk)*fsnow(i,j,iblk) +#ifdef ACCESS + !fsnow seems to already be multiplied by aice - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/drivers/access/cpl_forcing_handler.F90#L702-L703 + !and then unweighted again - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/source/ice_step_mod.F90#L331-L332 + !therefore i will weight again. + worka(i,j) = aice(i,j,iblk)*fsnow(i,j,iblk) +#else + worka(i,j) = fsnow(i,j,iblk) +#endif endif enddo enddo @@ -2520,10 +2512,10 @@ subroutine accum_hist (dt) if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') & ! sisndmassmelt is intensive, melts is grid cell average - call accum_hist_field(n_sndmassmelt, iblk, melts(:,:,iblk)*rhos/dt, a2D) + call accum_hist_field(n_sndmassmelt, iblk, melts(:,:,iblk), a2D) ! *rhos/dt in define_hist_field if (f_sndmassdyn(1:1) /= 'x' .or. f_sisndmassdyn(1:1) /= 'x') & - call accum_hist_field(n_sndmassdyn, iblk, dvsdtd(:,:,iblk)*rhos, a2D) + call accum_hist_field(n_sndmassdyn, iblk, dvsdtd(:,:,iblk), a2D) ! rhos in define_hist_field if (f_siflswdtop(1:1) /= 'x') then worka(:,:) = c0 @@ -2550,17 +2542,8 @@ subroutine accum_hist (dt) call accum_hist_field(n_siflswutop, iblk, worka(:,:), a2D) endif - if (f_siflswdbot(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*fswthru(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_siflswdbot, iblk, worka(:,:), a2D) - endif + if (f_siflswdbot(1:1) /= 'x') & + call accum_hist_field(n_siflswdbot, iblk, fswthru_ai(:,:,iblk), a2D) if (f_sifllwdtop(1:1) /= 'x') then worka(:,:) = c0 @@ -2574,69 +2557,24 @@ subroutine accum_hist (dt) call accum_hist_field(n_sifllwdtop, iblk, worka(:,:), a2D) endif - if (f_sifllwutop(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*flwout(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_sifllwutop, iblk, worka(:,:), a2D) - endif + if (f_sifllwutop(1:1) /= 'x') & + call accum_hist_field(n_sifllwutop, iblk, flwout_ai(:,:,iblk), a2D) - if (f_siflsenstop(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*fsens(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_siflsenstop, iblk, worka(:,:), a2D) - endif + if (f_siflsenstop(1:1) /= 'x') & + call accum_hist_field(n_siflsenstop, iblk, fsens_ai(:,:,iblk), a2D) - if (f_siflsensupbot(1:1) /= 'x' .or. f_siflsensbot(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*fhocn(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_siflsensupbot, iblk, worka(:,:), a2D) - endif + if (f_siflsensupbot(1:1) /= 'x' .or. f_siflsensbot(1:1) /= 'x') & + call accum_hist_field(n_siflsensupbot, iblk, fhocn_ai(:,:,iblk), a2D) - if (f_sifllatstop(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - worka(i,j) = aice(i,j,iblk)*flat(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_sifllatstop, iblk, worka(:,:), a2D) - endif + if (f_sifllatstop(1:1) /= 'x') & + call accum_hist_field(n_sifllatstop, iblk, flat_ai(:,:,iblk), a2D) - if (f_siflcondtop(1:1) /= 'x') then - worka(:,:) = c0 - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! to-do: save fcondtop before its divided by aice step - ! see https://github.com/ACCESS-NRI/cice5/blob/d083b62ed977fdaec0892c1838a55868ba5818eb/source/ice_flux.F90#L1030-L1031 - worka(i,j) = aice(i,j,iblk)*fcondtop(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_siflcondtop, iblk, worka(:,:), a2D) - endif + if (f_siflcondtop(1:1) /= 'x') & + ! siflcondtop is intensive, use grid cell average + call accum_hist_field(n_siflcondtop, iblk, fcondtop_ai(:,:,iblk), a2D) if (f_siflcondbot(1:1) /= 'x') & + ! siflcondbot is intensive, fcondbot is grid cell average call accum_hist_field(n_siflcondbot, iblk, fcondbot(:,:,iblk), a2D) if (f_sipr(1:1) /= 'x') then @@ -2644,10 +2582,14 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then +#ifdef ACCESS !it looks like frain is ice_area average https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_step_mod.F90#L334-L335 !sipr is intensive, so weight by aice - worka(i,j) = aice(i,j,iblk)*frain(i,j,iblk)*rhofresh - endif + worka(i,j) = aice(i,j,iblk)*frain(i,j,iblk) +#else + worka(i,j) = frain(i,j,iblk) +#endif + endif enddo enddo call accum_hist_field(n_sipr, iblk, worka(:,:), a2D) @@ -2689,23 +2631,21 @@ subroutine accum_hist (dt) call accum_hist_field(n_siflsaltbot, iblk, fsalt_ai(:,:,iblk), a2D) if (f_sisaltmass(1:1) /= 'x') & - call accum_hist_field(n_sisaltmass, iblk, & - ice_ref_salinity * rhoi * vice(:,:,iblk) / c1000 , a2D) + call accum_hist_field(n_sisaltmass, iblk, vice(:,:,iblk), a2D) ! *ice_ref_salinity*rhoi/c1000 in define_hist_field if (f_siflfwbot(1:1) /= 'x') & ! siflfwbot is intensive, fresh_ai is a grid cell average already - call accum_hist_field(n_siflfwbot, iblk, fresh_ai(:,:,iblk), a2D) + call accum_hist_field(n_siflfwbot, iblk, fresh_ai(:,:,iblk), a2D) if (f_siflfwdrain(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - ! to-do : remove frain ? - goes straight to ocean (or into melt pond) - worka(i,j) = aice(i,j,iblk)*(& - frain(i,j,iblk) * rhofresh & - + melts(i,j,iblk) * rhos/dt & - + meltt(i,j,iblk) * rhoi/dt) + ! to-do : drainage from meltpond + ! siflfwdrain is intensive, melts/t are grid cell average already + worka(i,j) = (melts(i,j,iblk) * rhos & + + meltt(i,j,iblk) * rhoi)/dt endif enddo enddo @@ -3044,30 +2984,28 @@ subroutine accum_hist (dt) nn = n2D + n if (avail_hist_fields(nn)%vhistfreq == histfreq(ns)) then - do k = 1, ncat_hist - do j = jlo, jhi - do i = ilo, ihi - if (.not. tmask(i,j,iblk)) then ! mask out land points - a3Dc(i,j,k,n,iblk) = spval_dbl - else ! convert units - a3Dc(i,j,k,n,iblk) = avail_hist_fields(nn)%cona*a3Dc(i,j,k,n,iblk) & - * ravgct + avail_hist_fields(nn)%conb - endif - enddo ! i - enddo ! j - enddo ! k - if (avail_hist_fields(nn)%avg_ice_present) then - do k = 1, ncat_hist - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j,iblk)) then - a3Dc(i,j,k,n,iblk) = & - a3Dc(i,j,k,n,iblk)*avgct(ns)*ravgipn(i,j,k) + ! Only average for timesteps when ice present + if (avail_hist_fields(n)%avg_ice_present) then + a3Dc(:,:,:,n,iblk) = a3Dc(:,:,:,n,iblk)*ravgipn(:,:,:) + else + a3Dc(:,:,:,n,iblk) = a3Dc(:,:,:,n,iblk)*ravgct + endif + + do k = 1, ncat_hist + do j = jlo, jhi + do i = ilo, ihi + if (.not. tmask(i,j,iblk)) then ! mask out land points + a3Dc(i,j,k,n,iblk) = spval_dbl + else ! convert units + a3Dc(i,j,k,n,iblk) = avail_hist_fields(nn)%cona*a3Dc(i,j,k,n,iblk) & + * ravgct + avail_hist_fields(nn)%conb endif - enddo ! i - enddo ! j - enddo ! k - endif + enddo ! i + enddo ! j + enddo ! k + + ! To-do: if (avail_hist_fields(n)%mask_ice_free_points) returns true, would + ! we mask by aice or aicen ? endif diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index f1d87d69..0802420d 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -200,7 +200,7 @@ module ice_history_shared f_hs = 'm', & f_snowfrac = 'x', f_snowfracn = 'x', & f_Tsfc = 'm', & - f_aice = 'm', f_siconc = 'x' , & !same var, two names, + f_aice = 'm', f_siconc = 'x' , & f_uvel = 'm', f_vvel = 'm', & f_uatm = 'm', f_vatm = 'm', & f_fswdn = 'm', f_flwdn = 'm', & @@ -269,16 +269,16 @@ module ice_history_shared f_sidmassth = 'x', f_sidmassdyn = 'x', & f_sidmassgrowthwat = 'x', & f_sidmassgrowthbot = 'x', & - f_sidmasssi = 'x', f_sidmassgrowthsi = 'x', & !same var, two names + f_sidmasssi = 'x', f_sidmassgrowthsi = 'x', & f_sidmassevapsubl = 'x', & f_sidmassmelttop = 'x', & f_sidmassmeltbot = 'x', & - f_sidmasslat = 'x', f_sidmassmeltlat = 'x', & !same var, two names - f_sndmasssnf = 'x', f_sisndmasssnf = 'x', & !same var, two names - f_sndmassmelt = 'x', f_sisndmassmelt = 'x', & !same var, two names - f_sndmassdyn = 'x', f_sisndmassdyn = 'x', & !same var, two names + f_sidmasslat = 'x', f_sidmassmeltlat = 'x', & + f_sndmasssnf = 'x', f_sisndmasssnf = 'x', & + f_sndmassmelt = 'x', f_sisndmassmelt = 'x', & + f_sndmassdyn = 'x', f_sisndmassdyn = 'x', & f_sisndmasssi = 'x', & - f_sndmasssubl = 'x', f_sisndmasssubl = 'x', & !same var, two names + f_sndmasssubl = 'x', f_sisndmasssubl = 'x', & f_sidivvel = 'x', & f_siflswdtop = 'x', & f_siflswutop = 'x', & @@ -286,7 +286,7 @@ module ice_history_shared f_sifllwdtop = 'x', & f_sifllwutop = 'x', & f_siflsenstop = 'x', & - f_siflsensupbot = 'x', f_siflsensbot = 'x', & !same var, two names + f_siflsensupbot = 'x', f_siflsensbot = 'x', & f_sifllatstop = 'x', & f_siflcondtop = 'x', & f_siflcondbot = 'x', & @@ -295,7 +295,7 @@ module ice_history_shared f_siflfwbot = 'x', & f_siflfwdrain = 'x', & f_sisaltmass = 'x', & - f_aicen = 'x' , f_siitdconc = 'x', & !same var, two names + f_aicen = 'x' , f_siitdconc = 'x', & f_vicen = 'x', & f_vsnon = 'x', & f_trsig = 'm', & From d18bc5869bf53fa102555434fee54edb1aa8f402 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Fri, 7 Nov 2025 12:12:52 +1100 Subject: [PATCH 70/80] some corrections from the data request --- source/ice_history.F90 | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 890605aa..88af7ed2 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -213,7 +213,7 @@ subroutine init_hist (dt) ! surface temperature is neither coupled or calculated within cice ! prognostic in the UM only if (f_Tsfc /= 'x') call abort_ice ("f_Tsfc not available, set to 'x'") - if (f_snowfracn /= 'x') call abort_ice ("f_Tsfc not available, set to 'x'") + if (f_snowfracn /= 'x') call abort_ice ("f_snowfracn not available, set to 'x'") if (f_sitemptop /= 'x') call abort_ice ("f_sitemptop not available, set to 'x'") if (f_sitempsnic /= 'x') call abort_ice ("f_sitempsnic not available, set to 'x'") endif @@ -1083,9 +1083,9 @@ subroutine init_hist (dt) ! or based on thermodynamics only (would be averaged using aice_mid) ! It would require new history variables for aice_init and aice_mid - call define_hist_field(n_aice,"siconc","1",tstr2D, tcstr, & - "Sea-Ice Area Fraction (Ocean Grid)", & - "none", c1, c0, & + call define_hist_field(n_aice,"siconc","%",tstr2D, tcstr, & + "Sea-Ice Area Percentage (Ocean Grid)", & + "none", c100, c0, & ns1, f_siconc) call define_hist_field(n_icepresent,"sitimefrac","1",tstr2D, tcstr, & @@ -1118,14 +1118,14 @@ subroutine init_hist (dt) "height of sea ice above ocean surface", c1, c0, & ns1, f_sifb, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sisnconc,"sisnconc","1",tstr2D, tcstr, & - "Snow Area Fraction", & - "fraction of grid cell with snow over sea ice", c1, c0, & + call define_hist_field(n_sisnconc,"sisnconc","%",tstr2D, tcstr, & + "Snow Area Percentage", & + "Percentage of the sea-ice surface that is covered by snow", c100, c0, & ns1, f_sisnconc, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisnthick,"sisnthick","m",tstr2D, tcstr, & "Snow Thickness", & - "snow volume divided by ice area", c1, c0, & + "Actual thickness of snow over the snow-covered part of the sea ice", c1, c0, & ns1, f_sisnthick, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisnmass,"sisnmass","kg m^-2",tstr2D, tcstr, & @@ -1330,7 +1330,7 @@ subroutine init_hist (dt) call define_hist_field(n_sndmasssnf,"sisndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Change Through Snowfall", & - "none", c1, c0, & + "Always positive or zero.", c1, c0, & ns1, f_sisndmasssnf, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & @@ -1340,12 +1340,12 @@ subroutine init_hist (dt) call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Melt", & - "none", rhos/dt, c0, & + "Always negative or zero.", -c1*rhos/dt, c0, & ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Snow-to-Ice Conversion", & - "none", rhoi/dt, c0, & + "Always negative or zero.", -c1*rhoi/dt, c0, & ns1, f_sisndmasssi, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & @@ -1509,9 +1509,9 @@ subroutine init_hist (dt) ns1, f_keffn_top) ! CMIP 3D - call define_hist_field(n_aicen,"siitdconc","1",tstr3Dc, tcstr, & - "Sea-Ice Area Fractions in Ice Thickness Categories", & - "none", c1, c0, & + call define_hist_field(n_aicen,"siitdconc","%",tstr3Dc, tcstr, & + "Sea-Ice Area Percentage in Ice Thickness Categories", & + "none", c100, c0, & ns1, f_siitdconc) ! siitdthick, siitdsnconc, siitdsnthick are not implemented because it's not clear how to @@ -2142,9 +2142,11 @@ subroutine accum_hist (dt) endif if (f_sisnconc(1:1) /= 'x') & + ! sisnconc is percentage of ice area only and intensive, weight each timestep by aice call accum_hist_field(n_sisnconc, iblk, snowfrac(:,:,iblk), a2D) if (f_sisnthick(1:1) /= 'x') & + ! to-do: divide by snowfrac call accum_hist_field(n_sisnthick, iblk, vsno(:,:,iblk), a2D) if (f_sisnmass(1:1) /= 'x') & From 1fe8164d9711cd3615906eb79913916f218f9229 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Mon, 10 Nov 2025 14:25:17 +1100 Subject: [PATCH 71/80] update comments and weightings --- source/ice_history.F90 | 157 ++++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 63 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 88af7ed2..4b1d3e99 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -239,6 +239,9 @@ subroutine init_hist (dt) if ( f_sifllwutop /= 'x' ) call abort_ice("f_sifllwutop not available, set to 'x'") if ( f_siflswdtop /= 'x' ) call abort_ice("f_siflswdtop not available, set to 'x'") if ( f_siflswutop /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") + if ( f_sisnconc /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") + ! there is a calculation of a sisnconc based on snow volume, but it doesn't represent a process + if ( f_sisnthick /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") #endif #ifdef AusCOM @@ -1071,9 +1074,11 @@ subroutine init_hist (dt) ! CMIP6 2D variables ! these definitions follow the intensive/extensive/inst def in Notz 2016 - ! we use cell methods of "mean where sea" or "mean where sea_ice" per CMIP7 data request - ! intensive means sea ice area weighted, and averaged only when sea ice is present + ! we interpret cell methods of "mean where sea" equivalent to "extensive" ! extensive means a normal average (over all time and grid box area) + ! and "mean where sea_ice" as intensive + ! intensive vars can be grid box or ice area means, and are then calulated as + ! an ice as aweighted mean in time ! extensive vars tend to zero when aice is zero, intensive vars do not ! In general, this implementation is limited by only weighting intensive @@ -1105,7 +1110,7 @@ subroutine init_hist (dt) call define_hist_field(n_simass,"simass","kg m^-2",tstr2D, tcstr, & "Sea-Ice Mass", & - "ice mass per unit grid cell area", c1, c0, & + "ice mass per unit grid cell area", rhoi, c0, & ns1, f_simass) call define_hist_field(n_siage,"siage","s",tstr2D, tcstr, & @@ -1130,7 +1135,7 @@ subroutine init_hist (dt) call define_hist_field(n_sisnmass,"sisnmass","kg m^-2",tstr2D, tcstr, & "Snow Mass per Area", & - "snow mass volume per unit grid cell area", c1, c0, & + "snow mass volume per unit grid cell area", rhos, c0, & ns1, f_sisnmass, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitemptop,"sitemptop","K",tstr2D, tcstr, & @@ -1340,12 +1345,12 @@ subroutine init_hist (dt) call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Melt", & - "Always negative or zero.", -c1*rhos/dt, c0, & + "Always negative or zero.", rhos/dt, c0, & ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Snow-to-Ice Conversion", & - "Always negative or zero.", -c1*rhoi/dt, c0, & + "Always negative or zero.", rhoi/dt, c0, & ns1, f_sisndmasssi, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & @@ -2123,18 +2128,29 @@ subroutine accum_hist (dt) !2D CMIP6 fields + ! for "extensive" vars, simply accumulate grid box mean values + ! for "intensive" vars, either: + ! - for grid box means, weight grid box means by aice (again) + ! - for ice area means, use grid box mean (to give the effect of ice area mean weighte by aice) + ! - for non spatial values (e.g. age), -> weight by aice + ! as intensive vars are divided by the sum of aice over time when written to file + + if (f_sithick(1:1) /= 'x') & + ! intensive - ice area mean -> use vice (grid box mean) call accum_hist_field(n_sithick, iblk, vice(:,:,iblk), a2D) if (f_simass(1:1) /= 'x') & - call accum_hist_field(n_simass, iblk, vice(:,:,iblk), a2D) ! *rhoi in define_hist_field + ! extensive -> use vice (grid box mean) + ! converted to mass when writing ( *rhoi in define_hist_field ) + call accum_hist_field(n_simass, iblk, vice(:,:,iblk), a2D) if (f_siage(1:1) /= 'x') then worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - ! siage is intensive, weight each timestep by aice if (aice(i,j,iblk) > puny) & + ! intensive, weight by aice worka(i,j) = aice(i,j,iblk)*trcr(i,j,nt_iage,iblk) enddo enddo @@ -2142,16 +2158,26 @@ subroutine accum_hist (dt) endif if (f_sisnconc(1:1) /= 'x') & - ! sisnconc is percentage of ice area only and intensive, weight each timestep by aice + ! intensive + ice area mean -> use snowfrac (grid box mean) call accum_hist_field(n_sisnconc, iblk, snowfrac(:,:,iblk), a2D) - if (f_sisnthick(1:1) /= 'x') & - ! to-do: divide by snowfrac - call accum_hist_field(n_sisnthick, iblk, vsno(:,:,iblk), a2D) + if (f_sisnthick(1:1) /= 'x') then + worka(:,:) = c0 + do j = jlo, jhi + do i = ilo, ihi + if (snowfrac(i,j,iblk) > puny) then + ! intensive + ice area mean -> calculate grid box mean + worka(i,j) = vsno(i,j,iblk) / snowfrac(i,j,iblk) + endif + enddo + enddo + call accum_hist_field(n_sisnthick, iblk, worka(:,:), a2D) + endif if (f_sisnmass(1:1) /= 'x') & - ! sisnmass is intensive, vsno already grid cell average - call accum_hist_field(n_sisnmass, iblk, vsno(:,:,iblk) , a2D) ! * rhos in define_hist_field + ! intensive + grid box mean -> weight by aice again + ! converted to mass when writing ( *rhos in define_hist_field ) + call accum_hist_field(n_sisnmass, iblk, aice(:,:,iblk)*vsno(:,:,iblk) , a2D) ! * rhos in define_hist_field if (f_sitemptop(1:1) /= 'x') then worka(:,:) = c0 @@ -2159,7 +2185,7 @@ subroutine accum_hist (dt) do i = ilo, ihi if (aice(i,j,iblk) > puny) then ! Tsfc is a tracer, so was advected during dynamics - ! sitemptop is intensive, weight by aice + ! intensive + ice area mean -> weight by aice worka(i,j) = aice(i,j,iblk) * trcr(i,j,nt_Tsfc,iblk) endif enddo @@ -2173,7 +2199,8 @@ subroutine accum_hist (dt) do i = ilo, ihi if (aice(i,j,iblk) > puny) & ! nb Tsnice is approximate, not a tracer - ! sitempsnic is intensive, weight by aice + ! intensive + ice area mean -> weight by aice + ! (we don't save Tsnice_ai as aice changes between calculating Tsnice and writing diagnostics) worka(i,j) = aice(i,j,iblk)*Tsnice(i,j,iblk) enddo enddo @@ -2186,7 +2213,7 @@ subroutine accum_hist (dt) do i = ilo, ihi if (aice(i,j,iblk) > puny) & ! nb Ti_bot is approximate, not a tracer - ! sitempbot is intensive, weight by aice + ! intensive + ice area mean -> weight by aice worka(i,j) = aice(i,j,iblk)*Ti_bot(i,j,iblk) enddo enddo @@ -2197,7 +2224,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - ! intensive, weight by aice + ! intensive -> weight by aice if (aice(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk)*uvel(i,j,iblk) enddo @@ -2209,7 +2236,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - ! intensive, weight by aice + ! intensive -> weight by aice if (aice(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk)*vvel(i,j,iblk) enddo @@ -2221,7 +2248,7 @@ subroutine accum_hist (dt) worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi - ! intensive, weight by aice + ! intensive -> weight by aice if (aice(i,j,iblk) > puny) & worka(i,j) = aice(i,j,iblk) & * sqrt(uvel(i,j,iblk)*uvel(i,j,iblk) & @@ -2267,7 +2294,7 @@ subroutine accum_hist (dt) do i = ilo, ihi !to-do: scale by aice/aice_init as its calculated based on coupled state ? if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strairx(i,j,iblk) enddo enddo @@ -2280,7 +2307,7 @@ subroutine accum_hist (dt) do i = ilo, ihi !to-do: surface stress is from coupling, should use aice_init weighting if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strairy(i,j,iblk) enddo enddo @@ -2292,7 +2319,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strocnx(i,j,iblk) enddo enddo @@ -2304,7 +2331,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strocny(i,j,iblk) enddo enddo @@ -2316,7 +2343,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strtltx(i,j,iblk) enddo enddo @@ -2328,7 +2355,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strtlty(i,j,iblk) enddo enddo @@ -2351,7 +2378,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = -aice(i,j,iblk)*fm(i,j,iblk)*uvel(i,j,iblk) enddo enddo @@ -2363,7 +2390,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strintx(i,j,iblk) enddo enddo @@ -2375,7 +2402,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strinty(i,j,iblk) enddo enddo @@ -2387,7 +2414,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) & - ! intensive, weight by aice + ! intensive + grid box mean -> weight by aice again worka(i,j) = aice(i,j,iblk)*strength(i,j,iblk) enddo enddo @@ -2426,6 +2453,7 @@ subroutine accum_hist (dt) do k = 1,nilyr do j = jlo, jhi do i = ilo, ihi + ! extensive, vice is grid cell average worka(i,j) = worka(i,j) & + trcr(i,j,nt_qice+k-1,iblk)*vice(i,j,iblk)/real(nilyr,kind=dbl_kind) enddo @@ -2439,7 +2467,9 @@ subroutine accum_hist (dt) do k = 1,nslyr do j = jlo, jhi do i = ilo, ihi - worka(i,j) = worka(i,j) + trcr(i,j,nt_qsno+k-1,iblk)*vsno(i,j,iblk)/real(nslyr,kind=dbl_kind) + ! extensive, vice is grid cell average + worka(i,j) = worka(i,j) + & + trcr(i,j,nt_qsno+k-1,iblk)*vsno(i,j,iblk)/real(nslyr,kind=dbl_kind) enddo enddo enddo @@ -2470,15 +2500,16 @@ subroutine accum_hist (dt) if (f_sisndmasssi(1:1) /= 'x') & !To-do: calculate a seperate icesno diag for change in snow thickness in ice_therm_vertical ? ! Its equivalent though, so fairly moot - call accum_hist_field(n_sisndmasssi, iblk, snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field + ! intensive + grid box mean -> weight by aice again + call accum_hist_field(n_sisndmasssi, iblk, aice(:,:,iblk)*snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sidmassevapsubl(1:1) /= 'x') & - ! sidmassevapsubl is extensive, evap_snow_ai is grid cell average + ! extensive -> use grid cell average call accum_hist_field(n_sidmassevapsubl, iblk, evap_ice_ai(:,:,iblk), a2D) if (f_sndmasssubl(1:1) /= 'x' .or. f_sisndmasssubl(1:1) /= 'x') then - ! sisndmasssubl is intensive, evap_snow_ai is grid cell average - call accum_hist_field(n_sndmasssubl, iblk, evap_snow_ai(:,:,iblk), a2D) + ! intensive + grid box mean -> weight by aice again + call accum_hist_field(n_sndmasssubl, iblk, aice(:,:,iblk)*evap_snow_ai(:,:,iblk), a2D) endif if (f_sidmassmelttop(1:1) /= 'x') & @@ -2497,15 +2528,8 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then - ! sisndmasssnf is intensive -#ifdef ACCESS - !fsnow seems to already be multiplied by aice - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/drivers/access/cpl_forcing_handler.F90#L702-L703 - !and then unweighted again - https://github.com/ACCESS-NRI/cice5/blob/77622b30cd68ee4f74fc835559a922cd64ee7fca/source/ice_step_mod.F90#L331-L332 - !therefore i will weight again. - worka(i,j) = aice(i,j,iblk)*fsnow(i,j,iblk) -#else - worka(i,j) = fsnow(i,j,iblk) -#endif + ! intensive + grid box mean -> weight fsnow by aice twice (see f_snow_ai) + worka(i,j) = aice(i,j,iblk)*aice_init(i,j,iblk)*fsnow(i,j,iblk) endif enddo enddo @@ -2513,13 +2537,15 @@ subroutine accum_hist (dt) endif if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') & - ! sisndmassmelt is intensive, melts is grid cell average - call accum_hist_field(n_sndmassmelt, iblk, melts(:,:,iblk), a2D) ! *rhos/dt in define_hist_field + ! intensive + grid box mean -> weight by aice again + call accum_hist_field(n_sndmassmelt, iblk, aice(:,:,iblk)*melts(:,:,iblk), a2D) ! *rhos/dt in define_hist_field if (f_sndmassdyn(1:1) /= 'x' .or. f_sisndmassdyn(1:1) /= 'x') & - call accum_hist_field(n_sndmassdyn, iblk, dvsdtd(:,:,iblk), a2D) ! rhos in define_hist_field + ! intensive + grid box mean -> weight by aice again + call accum_hist_field(n_sndmassdyn, iblk, aice(:,:,iblk)*dvsdtd(:,:,iblk), a2D) ! rhos in define_hist_field if (f_siflswdtop(1:1) /= 'x') then + ! intensive + ice area mean -> weight by aice worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2532,6 +2558,7 @@ subroutine accum_hist (dt) endif if (f_siflswutop(1:1) /= 'x') then + ! intensive + ice area mean -> weight by aice worka(:,:) = c0 do j = jlo, jhi do i = ilo, ihi @@ -2545,6 +2572,7 @@ subroutine accum_hist (dt) endif if (f_siflswdbot(1:1) /= 'x') & + ! intensive + ice area mean -> use weighted form call accum_hist_field(n_siflswdbot, iblk, fswthru_ai(:,:,iblk), a2D) if (f_sifllwdtop(1:1) /= 'x') then @@ -2552,6 +2580,7 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then + ! intensive + ice area mean -> weight by aice worka(i,j) = aice(i,j,iblk)*flw(i,j,iblk) endif enddo @@ -2560,23 +2589,27 @@ subroutine accum_hist (dt) endif if (f_sifllwutop(1:1) /= 'x') & + ! intensive + ice area mean -> use weighted form call accum_hist_field(n_sifllwutop, iblk, flwout_ai(:,:,iblk), a2D) if (f_siflsenstop(1:1) /= 'x') & + ! intensive + ice area mean -> use weighted form call accum_hist_field(n_siflsenstop, iblk, fsens_ai(:,:,iblk), a2D) if (f_siflsensupbot(1:1) /= 'x' .or. f_siflsensbot(1:1) /= 'x') & + ! intensive + ice area mean -> use weighted form call accum_hist_field(n_siflsensupbot, iblk, fhocn_ai(:,:,iblk), a2D) if (f_sifllatstop(1:1) /= 'x') & + ! intensive + ice area mean -> use weighted form call accum_hist_field(n_sifllatstop, iblk, flat_ai(:,:,iblk), a2D) if (f_siflcondtop(1:1) /= 'x') & - ! siflcondtop is intensive, use grid cell average + ! intensive + ice area mean -> use weighted form call accum_hist_field(n_siflcondtop, iblk, fcondtop_ai(:,:,iblk), a2D) if (f_siflcondbot(1:1) /= 'x') & - ! siflcondbot is intensive, fcondbot is grid cell average + ! intensive + ice area mean -> use weighted form call accum_hist_field(n_siflcondbot, iblk, fcondbot(:,:,iblk), a2D) if (f_sipr(1:1) /= 'x') then @@ -2584,14 +2617,9 @@ subroutine accum_hist (dt) do j = jlo, jhi do i = ilo, ihi if (aice(i,j,iblk) > puny) then -#ifdef ACCESS - !it looks like frain is ice_area average https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_step_mod.F90#L334-L335 - !sipr is intensive, so weight by aice - worka(i,j) = aice(i,j,iblk)*frain(i,j,iblk) -#else - worka(i,j) = frain(i,j,iblk) -#endif - endif + ! intensive + grid box mean -> weight frain by aice twice (see f_frain_ai) + worka(i,j) = aice(i,j,iblk)*aice_init(i,j,iblk)*frain(i,j,iblk) + endif enddo enddo call accum_hist_field(n_sipr, iblk, worka(:,:), a2D) @@ -2630,14 +2658,17 @@ subroutine accum_hist (dt) endif if (f_siflsaltbot(1:1) /= 'x') & - call accum_hist_field(n_siflsaltbot, iblk, fsalt_ai(:,:,iblk), a2D) + ! intensive + grid box mean -> weight by aice again + call accum_hist_field(n_siflsaltbot, iblk, aice(:,:,iblk)*fsalt_ai(:,:,iblk), a2D) if (f_sisaltmass(1:1) /= 'x') & - call accum_hist_field(n_sisaltmass, iblk, vice(:,:,iblk), a2D) ! *ice_ref_salinity*rhoi/c1000 in define_hist_field + ! extensive -> grid box mean + ! *ice_ref_salinity*rhoi/c1000 in define_hist_field + call accum_hist_field(n_sisaltmass, iblk, vice(:,:,iblk), a2D) ! if (f_siflfwbot(1:1) /= 'x') & - ! siflfwbot is intensive, fresh_ai is a grid cell average already - call accum_hist_field(n_siflfwbot, iblk, fresh_ai(:,:,iblk), a2D) + ! intensive + grid box mean -> weight by aice again + call accum_hist_field(n_siflfwbot, iblk, aice(:,:,iblk)*fresh_ai(:,:,iblk), a2D) if (f_siflfwdrain(1:1) /= 'x') then worka(:,:) = c0 @@ -2645,8 +2676,8 @@ subroutine accum_hist (dt) do i = ilo, ihi if (aice(i,j,iblk) > puny) then ! to-do : drainage from meltpond - ! siflfwdrain is intensive, melts/t are grid cell average already - worka(i,j) = (melts(i,j,iblk) * rhos & + ! intensive + grid box mean -> weight by aice again + worka(i,j) = aice(i,j,iblk)*(melts(i,j,iblk) * rhos & + meltt(i,j,iblk) * rhoi)/dt endif enddo From 4eccf5340b1121fedfb4b1590b124a35ced4c9ef Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 11 Nov 2025 13:08:26 +1100 Subject: [PATCH 72/80] allow for both _intensive and not _intensive for snow variables --- source/ice_history.F90 | 243 +++++++++++++++++++++------------- source/ice_history_shared.F90 | 33 +++-- 2 files changed, 167 insertions(+), 109 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 4b1d3e99..452784a6 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -390,6 +390,7 @@ subroutine init_hist (dt) call broadcast_scalar (f_sisnconc, master_task) call broadcast_scalar (f_sisnthick, master_task) call broadcast_scalar (f_sisnmass, master_task) + call broadcast_scalar (f_sisnmass_intensive, master_task) call broadcast_scalar (f_sitemptop, master_task) call broadcast_scalar (f_sitempsnic, master_task) call broadcast_scalar (f_sitempbot, master_task) @@ -418,17 +419,22 @@ subroutine init_hist (dt) call broadcast_scalar (f_sidmassevapsubl, master_task) call broadcast_scalar (f_sndmasssubl, master_task) call broadcast_scalar (f_sisndmasssubl, master_task) + call broadcast_scalar (f_sisndmasssubl_intensive, master_task) call broadcast_scalar (f_sidmassmelttop, master_task) call broadcast_scalar (f_sidmassmeltbot, master_task) call broadcast_scalar (f_sidmasslat, master_task) call broadcast_scalar (f_sidmassmeltlat, master_task) call broadcast_scalar (f_sndmasssnf, master_task) call broadcast_scalar (f_sisndmasssnf, master_task) + call broadcast_scalar (f_sisndmasssnf_intensive, master_task) call broadcast_scalar (f_sndmassmelt, master_task) call broadcast_scalar (f_sisndmassmelt, master_task) + call broadcast_scalar (f_sisndmassmelt_intensive, master_task) call broadcast_scalar (f_sisndmasssi, master_task) + call broadcast_scalar (f_sisndmasssi_intensive, master_task) call broadcast_scalar (f_sndmassdyn, master_task) call broadcast_scalar (f_sisndmassdyn, master_task) + call broadcast_scalar (f_sisndmassdyn_intensive, master_task) call broadcast_scalar (f_siflswdtop, master_task) call broadcast_scalar (f_siflswutop, master_task) call broadcast_scalar (f_siflswdbot, master_task) @@ -1105,7 +1111,7 @@ subroutine init_hist (dt) call define_hist_field(n_sithick,"sithick","m",tstr2D, tcstr, & "Sea-Ice Thickness", & - "volume divided by ice area", c1, c0, & + "area weighted average of volume divided by ice area", c1, c0, & ns1, f_sithick, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_simass,"simass","kg m^-2",tstr2D, tcstr, & @@ -1115,52 +1121,57 @@ subroutine init_hist (dt) call define_hist_field(n_siage,"siage","s",tstr2D, tcstr, & "Age of Sea Ice", & - "average age of ice, when ice present, weighted by area fraction", c1, c0, & + "area weighted average of age of sea ice", c1, c0, & ns1, f_siage, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifb,"sifb","m",tstr2D, tcstr, & "Sea-Ice Freeboard", & - "height of sea ice above ocean surface", c1, c0, & + "area weighted average of height of sea ice above ocean surface", c1, c0, & ns1, f_sifb, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisnconc,"sisnconc","%",tstr2D, tcstr, & "Snow Area Percentage", & - "Percentage of the sea-ice surface that is covered by snow", c100, c0, & + "area weighted average of Percentage of the sea-ice surface that is covered by snow", c100, c0, & ns1, f_sisnconc, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisnthick,"sisnthick","m",tstr2D, tcstr, & "Snow Thickness", & - "Actual thickness of snow over the snow-covered part of the sea ice", c1, c0, & + "area weighted average of actual thickness of snow over the snow-covered part of the sea ice", c1, c0, & ns1, f_sisnthick, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sisnmass,"sisnmass","kg m^-2",tstr2D, tcstr, & + call define_hist_field(n_hs,"sisnmass","kg m^-2",tstr2D, tcstr, & "Snow Mass per Area", & - "snow mass volume per unit grid cell area", rhos, c0, & - ns1, f_sisnmass, avg_ice_present=.true., mask_ice_free_points=.true.) + "snow mass per unit grid cell area", rhos, c0, & + ns1, f_sisnmass) + + call define_hist_field(n_sisnmass_intensive,"sisnmass_intensive","kg m^-2",tstr2D, tcstr, & + "Snow Mass per Area", & + "area weighted average of snow mass per unit grid cell area", rhos, c0, & + ns1, f_sisnmass_intensive, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitemptop,"sitemptop","K",tstr2D, tcstr, & "Surface Temperature of Sea Ice", & - "none", c1, Tffresh, & + "area weighted average of skin temperautre", c1, Tffresh, & ns1, f_sitemptop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitempsnic,"sitempsnic","K",tstr2D, tcstr, & "Temperature at Snow-Ice Interface", & - "surface temperature when no snow present", c1, Tffresh, & + "area weighted average of temperature at snow-ice interface,surface temperature when no snow present", c1, Tffresh, & ns1, f_sitempsnic, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sitempbot,"sitempbot","K",tstr2D, tcstr, & "Temperature at Ice-Ocean Interface", & - "none", c1, Tffresh, & + "area weighted average of ice-ocean interface temperature", c1, Tffresh, & ns1, f_sitempbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siu,"siu","m/s",ustr2D, ucstr, & "X-Component of Sea-Ice Velocity", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_siu, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siv,"siv","m/s",ustr2D, ucstr, & "Y-Component of Sea-Ice Velocity", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_siv, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidmasstranx,"sidmasstranx","kg/s",ustr2D, ucstr, & @@ -1175,72 +1186,72 @@ subroutine init_hist (dt) call define_hist_field(n_sistrxdtop,"sistrxdtop","N m^-2",ustr2D, ucstr, & "X-Component of Atmospheric Stress on Sea Ice", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_sistrxdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistrydtop,"sistrydtop","N m^-2",ustr2D, ucstr, & "Y-Component of Atmospheric Stress on Sea Ice", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_sistrydtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistrxubot,"sistrxubot","N m^-2",ustr2D, ucstr, & "X-Component of Ocean Stress on Sea Ice", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_sistrxubot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sistryubot,"sistryubot","N m^-2",ustr2D, ucstr, & "Y-Component of Ocean Stress on Sea Ice", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_sistryubot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcetiltx,"siforcetiltx","N m^-2",ustr2D, ucstr, & "Sea-Surface Tilt Term in Force Balance (X-Component)", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_siforcetiltx, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcetilty,"siforcetilty","N m^-2",ustr2D, ucstr, & "Sea-Surface Tilt Term in Force Balance (Y-Component)", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_siforcetilty, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcecoriolx,"siforcecoriolx","N m^-2",ustr2D, ucstr, & "Coriolis Force Term in Force Balance (X-Component)", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_siforcecoriolx, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforcecorioly,"siforcecorioly","N m^-2",ustr2D, ucstr, & "Coriolis Force Term in Force Balance (Y-Component)", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_siforcecorioly, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforceintstrx,"siforceintstrx","N m^-2",ustr2D, ucstr, & "Internal Stress Term in Force Balance (X-Component)", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_siforceintstrx, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siforceintstry,"siforceintstry","N m^-2",ustr2D, ucstr, & "Internal Stress Term in Force Balance (Y-Component)", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_siforceintstry, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sicompstren,"sicompstren","N/m",ustr2D, ucstr, & "Compressive Sea Ice Strength", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_sicompstren, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidivvel,"sidivvel","1/s",ustr2D, ucstr, & "Divergence of the Sea-Ice Velocity Field", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_sidivvel, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sispeed,"sispeed","m/s",ustr2D, ucstr, & "Sea-Ice Speed", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_sispeed, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sialb,"sialb","1",tstr2D, tcstr, & "Sea-Ice Albedo", & - "none", c1, c0, & + "area weighted average", c1, c0, & ns1, f_sialb, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sihc,"sihc","J m^-2",tstr2D, tcstr, & @@ -1265,182 +1276,207 @@ subroutine init_hist (dt) call define_hist_field(n_sidmassth,"sidmassth","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change from Thermodynamics", & - "none", rhoi, c0, & + "per unit grid cell area", rhoi, c0, & ns1, f_sidmassth) call define_hist_field(n_sidmassdyn,"sidmassdyn","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change from Dynamics", & - "none", rhoi, c0, & + "per unit grid cell area", rhoi, c0, & ns1, f_sidmassdyn) call define_hist_field(n_sidmassgrowthwat,"sidmassgrowthwat","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Growth in Supercooled Open Water (Frazil)", & - "none", rhoi/dt, c0, & + "per unit grid cell area", rhoi/dt, c0, & ns1, f_sidmassgrowthwat) call define_hist_field(n_sidmassgrowthbot,"sidmassgrowthbot","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Basal Growth", & - "none", rhoi/dt, c0, & + "per unit grid cell area", rhoi/dt, c0, & ns1, f_sidmassgrowthbot) call define_hist_field(n_sidmasssi,"sidmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Snow-to-Ice Conversion", & - "none", rhoi/dt, c0, & + "per unit grid cell area", rhoi/dt, c0, & ns1, f_sidmasssi) call define_hist_field(n_sidmasssi,"sidmassgrowthsi","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Snow-to-Ice Conversion", & - "none", rhoi/dt, c0, & + "per unit grid cell area", rhoi/dt, c0, & ns1, f_sidmassgrowthsi) call define_hist_field(n_sidmassevapsubl,"sidmassevapsubl","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Evaporation and Sublimation", & - "none", c1, c0, & + "per unit grid cell area", c1, c0, & ns1, f_sidmassevapsubl) - call define_hist_field(n_sndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sisndmasssubl,"sndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Evaporation or Sublimation", & - "none", c1, c0, & - ns1, f_sndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true.) + "per unit grid cell area", c1, c0, & + ns1, f_sndmasssubl) - call define_hist_field(n_sndmasssubl,"sisndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sisndmasssubl,"sisndmasssubl","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Evaporation or Sublimation", & - "none", c1, c0, & - ns1, f_sisndmasssubl, avg_ice_present=.true., mask_ice_free_points=.true.) + "per unit grid cell area", c1, c0, & + ns1, f_sisndmasssubl) + + call define_hist_field(n_sisndmasssubl_intensive,"sisndmasssubl_intensive","kg m^-2 s^-1",tstr2D, tcstr, & + "Snow Mass Rate of Change Through Evaporation or Sublimation, divided by grid cell area", & + "area weighted average per unit grid cell area", c1, c0, & + ns1, f_sisndmasssubl_intensive, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Surface Melting", & - "none", rhoi/dt, c0, & + "per unit grid cell area", rhoi/dt, c0, & ns1, f_sidmassmelttop) call define_hist_field(n_sidmassmeltbot,"sidmassmeltbot","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Bottom Melting", & - "none", rhoi/dt, c0, & + "per unit grid cell area", rhoi/dt, c0, & ns1, f_sidmassmeltbot) call define_hist_field(n_sidmasslat,"sidmasslat","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Lateral Melting", & - "none", rhoi/dt, c0, & + "per unit grid cell area", rhoi/dt, c0, & ns1, f_sidmasslat) call define_hist_field(n_sidmasslat,"sidmassmeltlat","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Lateral Melting", & - "none", rhoi/dt, c0, & + "per unit grid cell area", rhoi/dt, c0, & ns1, f_sidmassmeltlat) - call define_hist_field(n_sndmasssnf,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_snow_ai,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Change Through Snowfall", & - "none", c1, c0, & - ns1, f_sndmasssnf, avg_ice_present=.true., mask_ice_free_points=.true.) + "per unit grid cell area", c1, c0, & + ns1, f_sndmasssnf) - call define_hist_field(n_sndmasssnf,"sisndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_snow_ai,"sisndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Change Through Snowfall", & - "Always positive or zero.", c1, c0, & - ns1, f_sisndmasssnf, avg_ice_present=.true., mask_ice_free_points=.true.) + "Always positive or zero, per unit grid cell area", c1, c0, & + ns1, f_sisndmasssnf) + + call define_hist_field(n_sisndmasssnf_intensive,"sisndmasssnf_intensive","kg m^-2 s^-1",tstr2D, tcstr, & + "Snow Mass Change Through Snowfall", & + "area weighted average, always positive or zero, per unit grid cell area", c1, c0, & + ns1, f_sisndmasssnf_intensive, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassmelt,"sndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Melt", & - "none", rhos/dt, c0, & - ns1, f_sndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) + "per unit grid cell area", -c1*rhos/dt, c0, & + ns1, f_sndmassmelt) + + call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & + "Snow Mass Rate of Change Through Melt", & + "Always negative or zero, per unit grid cell area", -c1*rhos/dt, c0, & + ns1, f_sisndmassmelt) - call define_hist_field(n_sndmassmelt,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sisndmassmelt_intensive,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Melt", & - "Always negative or zero.", rhos/dt, c0, & + "area weighted average, always negative or zero, per unit grid cell area", -c1*rhos/dt, c0, & ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Snow-to-Ice Conversion", & - "Always negative or zero.", rhoi/dt, c0, & - ns1, f_sisndmasssi, avg_ice_present=.true., mask_ice_free_points=.true.) + "Always negative or zero, per unit grid cell area", -c1*rhoi/dt, c0, & + ns1, f_sisndmasssi) + + call define_hist_field(n_sisndmasssi_intensive,"sisndmasssi_intensive","kg m^-2 s^-1",tstr2D, tcstr, & + "Snow Mass Rate of Change Through Snow-to-Ice Conversion", & + "Always negative or zero, per unit grid cell area", -c1*rhoi/dt, c0, & + ns1, f_sisndmasssi_intensive, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & - "none", rhos, c0, & - ns1, f_sndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) + "per unit grid cell area", rhos, c0, & + ns1, f_sndmassdyn) call define_hist_field(n_sndmassdyn,"sisndmassdyn","kg m-2 s-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & - "none", rhos, c0, & + "per unit grid cell area", rhos, c0, & + ns1, f_sisndmassdyn) + + call define_hist_field(n_sisndmassdyn_intensive,"sisndmassdyn","kg m-2 s-1",tstr2D, tcstr, & + "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & + "area weighted average, per unit grid cell area", rhos, c0, & ns1, f_sisndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdtop,"siflswdtop","W m^-2",tstr2D, tcstr, & "Downwelling Shortwave Flux over Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflswdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswutop,"siflswutop","W m^-2",tstr2D, tcstr, & "Upwelling Shortwave Flux over Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflswutop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdbot,"siflswdbot","W m^-2",tstr2D, tcstr, & "Downwelling Shortwave Flux under Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflswdbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllwdtop,"sifllwdtop","W m^-2",tstr2D, tcstr, & "Downwelling Longwave Flux over Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_sifllwdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllwutop,"sifllwutop","W m^-2",tstr2D, tcstr, & "Upwelling Longwave Flux over Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_sifllwutop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsenstop,"siflsenstop","W m^-2",tstr2D, tcstr, & "Net Downward Sensible Heat Flux over Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflsenstop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsensupbot,"siflsensupbot","W m^-2",tstr2D, tcstr, & "Net Upward Sensible Heat Flux under Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflsensupbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsensupbot,"siflsensbot","W m^-2",tstr2D, tcstr, & "Net Upward Sensible Heat Flux under Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflsensbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllatstop,"sifllatstop","W m^-2",tstr2D, tcstr, & "Net Latent Heat Flux over Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_sifllatstop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflcondtop,"siflcondtop","W m^-2",tstr2D, tcstr, & "Net Conductive Heat Flux in Sea Ice at the Surface", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflcondtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflcondbot,"siflcondbot","W m^-2",tstr2D, tcstr, & "Net Conductive Heat Flux in Sea Ice at the Base", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflcondbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflfwdrain,"siflfwdrain","kg m^-2 s^-1",tstr2D, tcstr, & "Freshwater Flux from Sea-Ice Surface", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflfwdrain, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sipr,"sipr","kg m^-2 s^-1",tstr2D, tcstr, & "Rainfall Rate over Sea Ice", & - "none", c1, c0, & + "area weighted average, per unit grid cell area", c1, c0, & ns1, f_sipr, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsaltbot,"siflsaltbot","kg m^-2 s^-1",tstr2D, tcstr, & "Salt Flux from Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflsaltbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflfwbot,"siflfwbot","kg m^-2 s^-1",tstr2D, tcstr, & "Freshwater Flux from Sea Ice", & - "positive downward", c1, c0, & + "area weighted average, positive downward, per unit grid cell area", c1, c0, & ns1, f_siflfwbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisaltmass,"sisaltmass","kg m^-2",tstr2D, tcstr, & "Mass of Salt in Sea Ice",& - "none", ice_ref_salinity * rhoi / c1000 , c0, & + "per unit grid cell area", ice_ref_salinity * rhoi / c1000 , c0, & ns1, f_sisaltmass) endif ! if (histfreq(ns1) /= 'x') then @@ -2029,7 +2065,8 @@ subroutine accum_hist (dt) call accum_hist_field(n_dsnow, iblk, dsnow(:,:,iblk), a2D) if (f_meltt (1:1) /= 'x') & call accum_hist_field(n_meltt, iblk, meltt(:,:,iblk), a2D) - if (f_melts (1:1) /= 'x') & ! is this actually melts_ai, its a grid cell average (https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L857-L862) + if (f_melts (1:1) /= 'x') & + ! is this actually melts_ai, its a grid cell average (https://github.com/ACCESS-NRI/cice5/blob/3f0f38141cf5f87ac9b6f7b401f10b4b5fc15218/source/ice_flux.F90#L857-L862) call accum_hist_field(n_melts, iblk, melts(:,:,iblk), a2D) if (f_meltb (1:1) /= 'x') & call accum_hist_field(n_meltb, iblk, meltb(:,:,iblk), a2D) @@ -2175,9 +2212,13 @@ subroutine accum_hist (dt) endif if (f_sisnmass(1:1) /= 'x') & + ! converted to mass when writing ( *rhos in define_hist_field ) + call accum_hist_field(n_sisnmass, iblk, vsno(:,:,iblk), a2D) + + if (f_sisnmass_intensive(1:1) /= 'x') & ! intensive + grid box mean -> weight by aice again ! converted to mass when writing ( *rhos in define_hist_field ) - call accum_hist_field(n_sisnmass, iblk, aice(:,:,iblk)*vsno(:,:,iblk) , a2D) ! * rhos in define_hist_field + call accum_hist_field(n_sisnmass_intensive, iblk, aice(:,:,iblk)*vsno(:,:,iblk) , a2D) if (f_sitemptop(1:1) /= 'x') then worka(:,:) = c0 @@ -2497,19 +2538,22 @@ subroutine accum_hist (dt) if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') & call accum_hist_field(n_sidmasssi, iblk, snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field - if (f_sisndmasssi(1:1) /= 'x') & + if (f_sisndmasssi_intensive(1:1) /= 'x') & !To-do: calculate a seperate icesno diag for change in snow thickness in ice_therm_vertical ? ! Its equivalent though, so fairly moot ! intensive + grid box mean -> weight by aice again - call accum_hist_field(n_sisndmasssi, iblk, aice(:,:,iblk)*snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field + call accum_hist_field(n_sisndmasssi_intensive, iblk, aice(:,:,iblk)*snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sidmassevapsubl(1:1) /= 'x') & ! extensive -> use grid cell average call accum_hist_field(n_sidmassevapsubl, iblk, evap_ice_ai(:,:,iblk), a2D) - if (f_sndmasssubl(1:1) /= 'x' .or. f_sisndmasssubl(1:1) /= 'x') then + if (f_sndmasssubl(1:1) /= 'x' .or. f_sisndmasssubl(1:1) /= 'x') & + call accum_hist_field(n_sisndmasssubl,iblk, evap_snow_ai(:,:,iblk), a2D) + + if (f_sisndmasssubl_intensive(1:1) /= 'x') then ! intensive + grid box mean -> weight by aice again - call accum_hist_field(n_sndmasssubl, iblk, aice(:,:,iblk)*evap_snow_ai(:,:,iblk), a2D) + call accum_hist_field(n_sisndmasssubl_intensive, iblk, aice(:,:,iblk)*evap_snow_ai(:,:,iblk), a2D) endif if (f_sidmassmelttop(1:1) /= 'x') & @@ -2524,25 +2568,34 @@ subroutine accum_hist (dt) ! sidmassmeltlat is extensive, meltl is grid cell average call accum_hist_field(n_sidmasslat, iblk, meltl(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field - if (f_sndmasssnf(1:1) /= 'x' .or. f_sisndmasssnf(1:1) /= 'x') then - do j = jlo, jhi - do i = ilo, ihi - if (aice(i,j,iblk) > puny) then - ! intensive + grid box mean -> weight fsnow by aice twice (see f_snow_ai) - worka(i,j) = aice(i,j,iblk)*aice_init(i,j,iblk)*fsnow(i,j,iblk) - endif - enddo - enddo - call accum_hist_field(n_sndmasssnf, iblk, worka(:,:), a2D) + if (f_sndmasssnf(1:1) /= 'x' .or. f_sisndmasssnf(1:1) /= 'x') & + call accum_hist_field(n_snow_ai,iblk, fsnow(:,:,iblk)*aice_init(:,:,iblk), a2D) + + if (f_sisndmasssnf_intensive(1:1) /= 'x') then + do j = jlo, jhi + do i = ilo, ihi + if (aice(i,j,iblk) > puny) then + ! intensive + grid box mean -> weight fsnow by aice twice (see f_snow_ai) + worka(i,j) = aice(i,j,iblk)*aice_init(i,j,iblk)*fsnow(i,j,iblk) + endif + enddo + enddo + call accum_hist_field(n_sisndmasssnf_intensive, iblk, worka(:,:), a2D) endif - if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') & + if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') & + call accum_hist_field(n_melts, iblk, melts(:,:,iblk), a2D) + + if (f_sisndmassmelt_intensive(1:1) /= 'x') & ! intensive + grid box mean -> weight by aice again - call accum_hist_field(n_sndmassmelt, iblk, aice(:,:,iblk)*melts(:,:,iblk), a2D) ! *rhos/dt in define_hist_field + call accum_hist_field(n_sisndmassmelt_intensive, iblk, aice(:,:,iblk)*melts(:,:,iblk), a2D) ! *rhos/dt in define_hist_field if (f_sndmassdyn(1:1) /= 'x' .or. f_sisndmassdyn(1:1) /= 'x') & + call accum_hist_field(n_sndmassdyn, iblk, dvsdtd(:,:,iblk), a2D) ! rhos in define_hist_field + + if (f_sisndmassdyn_intensive(1:1) /= 'x') & ! intensive + grid box mean -> weight by aice again - call accum_hist_field(n_sndmassdyn, iblk, aice(:,:,iblk)*dvsdtd(:,:,iblk), a2D) ! rhos in define_hist_field + call accum_hist_field(n_sisndmassdyn_intensive, iblk, aice(:,:,iblk)*dvsdtd(:,:,iblk), a2D) ! rhos in define_hist_field if (f_siflswdtop(1:1) /= 'x') then ! intensive + ice area mean -> weight by aice diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 0802420d..fca89200 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -250,7 +250,7 @@ module ice_history_shared f_iage = 'm', f_FY = 'm', & f_hisnap = 'm', f_aisnap = 'm', & f_sithick = 'x', f_sisnthick = 'x', & - f_simass = 'x', f_sisnmass = 'x', & + f_simass = 'x', f_sisnmass = 'x', f_sisnmass_intensive = 'x',& f_sisnconc = 'x', f_siage = 'x', & f_sitemptop = 'x', f_sitempsnic = 'x', & f_sitempbot = 'x', f_sispeed = 'x', & @@ -274,11 +274,11 @@ module ice_history_shared f_sidmassmelttop = 'x', & f_sidmassmeltbot = 'x', & f_sidmasslat = 'x', f_sidmassmeltlat = 'x', & - f_sndmasssnf = 'x', f_sisndmasssnf = 'x', & - f_sndmassmelt = 'x', f_sisndmassmelt = 'x', & - f_sndmassdyn = 'x', f_sisndmassdyn = 'x', & - f_sisndmasssi = 'x', & - f_sndmasssubl = 'x', f_sisndmasssubl = 'x', & + f_sndmasssnf = 'x', f_sisndmasssnf = 'x', f_sisndmasssnf_intensive = 'x', & + f_sndmassmelt = 'x', f_sisndmassmelt = 'x', f_sisndmassmelt_intensive = 'x', & + f_sndmassdyn = 'x', f_sisndmassdyn = 'x', f_sisndmassdyn_intensive = 'x', & + f_sisndmasssi = 'x', f_sisndmasssi_intensive = 'x', & + f_sndmasssubl = 'x', f_sisndmasssubl = 'x', f_sisndmasssubl_intensive = 'x', & f_sidivvel = 'x', & f_siflswdtop = 'x', & f_siflswutop = 'x', & @@ -387,7 +387,7 @@ module ice_history_shared f_iage, f_FY , & f_hisnap, f_aisnap , & f_sithick, f_sisnthick, & - f_simass, f_sisnmass, & + f_simass, f_sisnmass, f_sisnmass_intensive, & f_sisnconc, f_siage, & f_sifb, & f_sitemptop, f_sitempsnic,& @@ -409,14 +409,14 @@ module ice_history_shared f_sidmassgrowthbot, & f_sidmasssi, f_sidmassgrowthsi , & f_sidmassevapsubl, & - f_sndmasssubl, f_sisndmasssubl, & f_sidmassmelttop, & f_sidmassmeltbot, & f_sidmasslat, f_sidmassmeltlat,& - f_sndmasssnf, f_sisndmasssnf, & - f_sndmassmelt, f_sisndmassmelt, & - f_sndmassdyn, f_sisndmassdyn, & - f_sisndmasssi, & + f_sndmasssubl, f_sisndmasssubl, f_sisndmasssubl_intensive, & + f_sndmasssnf, f_sisndmasssnf, f_sisndmasssnf_intensive, & + f_sndmassmelt, f_sisndmassmelt, f_sisndmassmelt_intensive, & + f_sndmassdyn, f_sisndmassdyn, f_sisndmassdyn_intensive, & + f_sisndmasssi, f_sisndmasssi_intensive, & f_siflswdtop, & f_siflswutop, & f_siflswdbot, & @@ -522,7 +522,7 @@ module ice_history_shared n_fsalt , n_fsalt_ai , & n_sidivvel, & n_sithick , n_sisnthick , & - n_simass , n_sisnmass , & + n_simass , n_sisnmass, n_sisnmass_intensive, & n_sisnconc, n_siage, & n_sifb, & n_sitemptop , n_sitempsnic , & @@ -544,14 +544,19 @@ module ice_history_shared n_sidmasssi, & n_sidmasssubl, & n_sidmassevapsubl, & - n_sndmasssubl, & n_sidmassmelttop, & n_sidmassmeltbot, & n_sidmasslat, & n_sndmasssnf, & + n_sisndmasssnf_intensive, & n_sndmassmelt, & + n_sisndmassmelt_intensive, & n_sndmassdyn, & + n_sisndmassdyn_intensive, & n_sisndmasssi, & + n_sisndmasssi_intensive, & + n_sisndmasssubl, & + n_sisndmasssubl_intensive, & n_siflswdtop, & n_siflswutop, & n_siflswdbot, & From 5e378b324b967b05c234ffde7d7e22798031e3bc Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Tue, 11 Nov 2025 16:36:08 +1100 Subject: [PATCH 73/80] bug fixes and sign corrections --- source/ice_history.F90 | 17 ++++++++++------- source/ice_history_shared.F90 | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 452784a6..dea9e204 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1326,22 +1326,22 @@ subroutine init_hist (dt) call define_hist_field(n_sidmassmelttop,"sidmassmelttop","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Surface Melting", & - "per unit grid cell area", rhoi/dt, c0, & + "per unit grid cell area", -c1*rhoi/dt, c0, & ns1, f_sidmassmelttop) call define_hist_field(n_sidmassmeltbot,"sidmassmeltbot","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Bottom Melting", & - "per unit grid cell area", rhoi/dt, c0, & + "per unit grid cell area", -c1*rhoi/dt, c0, & ns1, f_sidmassmeltbot) call define_hist_field(n_sidmasslat,"sidmasslat","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Lateral Melting", & - "per unit grid cell area", rhoi/dt, c0, & + "per unit grid cell area", -c1*rhoi/dt, c0, & ns1, f_sidmasslat) call define_hist_field(n_sidmasslat,"sidmassmeltlat","kg m^-2 s^-1",tstr2D, tcstr, & "Sea-Ice Mass Change Through Lateral Melting", & - "per unit grid cell area", rhoi/dt, c0, & + "per unit grid cell area", -c1*rhoi/dt, c0, & ns1, f_sidmassmeltlat) call define_hist_field(n_snow_ai,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & @@ -1369,7 +1369,7 @@ subroutine init_hist (dt) "Always negative or zero, per unit grid cell area", -c1*rhos/dt, c0, & ns1, f_sisndmassmelt) - call define_hist_field(n_sisndmassmelt_intensive,"sisndmassmelt","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sisndmassmelt_intensive,"sisndmassmelt_intensive","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Melt", & "area weighted average, always negative or zero, per unit grid cell area", -c1*rhos/dt, c0, & ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) @@ -1394,7 +1394,7 @@ subroutine init_hist (dt) "per unit grid cell area", rhos, c0, & ns1, f_sisndmassdyn) - call define_hist_field(n_sisndmassdyn_intensive,"sisndmassdyn","kg m-2 s-1",tstr2D, tcstr, & + call define_hist_field(n_sisndmassdyn_intensive,"sisndmassdyn_intensive","kg m-2 s-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & "area weighted average, per unit grid cell area", rhos, c0, & ns1, f_sisndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) @@ -2538,6 +2538,9 @@ subroutine accum_hist (dt) if (f_sidmasssi(1:1) /= 'x' .or. f_sidmassgrowthsi(1:1) /= 'x') & call accum_hist_field(n_sidmasssi, iblk, snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field + if (f_sisndmasssi(1:1) /= 'x') & + call accum_hist_field(n_sisndmasssi, iblk, snoice(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field + if (f_sisndmasssi_intensive(1:1) /= 'x') & !To-do: calculate a seperate icesno diag for change in snow thickness in ice_therm_vertical ? ! Its equivalent though, so fairly moot @@ -2584,7 +2587,7 @@ subroutine accum_hist (dt) endif if (f_sndmassmelt(1:1) /= 'x' .or. f_sisndmassmelt(1:1) /= 'x') & - call accum_hist_field(n_melts, iblk, melts(:,:,iblk), a2D) + call accum_hist_field(n_sndmassmelt, iblk, melts(:,:,iblk), a2D) if (f_sisndmassmelt_intensive(1:1) /= 'x') & ! intensive + grid box mean -> weight by aice again diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index fca89200..45c455b0 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -73,10 +73,10 @@ module ice_history_shared !--------------------------------------------------------------- type, public :: ice_hist_field - character (len=16) :: vname ! variable name + character (len=32) :: vname ! variable name character (len=16) :: vunit ! variable units character (len=25) :: vcoord ! variable coordinates - character (len=16) :: vcellmeas ! variable cell measures + character (len=32) :: vcellmeas ! variable cell measures character (len=255) :: vdesc ! variable description character (len=255) :: vcomment ! variable description real (kind=dbl_kind) :: cona ! multiplicative conversion factor From 6a912f8c1730ad3884500abb9d29e77df9971085 Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Wed, 12 Nov 2025 10:56:57 +1100 Subject: [PATCH 74/80] Apply suggestions from code review Co-authored-by: Spencer Wong <88933912+blimlim@users.noreply.github.com> --- source/ice_flux.F90 | 4 ++-- source/ice_history.F90 | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/source/ice_flux.F90 b/source/ice_flux.F90 index 55f85c54..602b8de6 100755 --- a/source/ice_flux.F90 +++ b/source/ice_flux.F90 @@ -317,12 +317,12 @@ module ice_flux fsens_ai, & ! sensible heat flux (W/m^2) flat_ai, & ! latent heat flux (W/m^2) fswabs_ai, & ! shortwave absorbed heat flx (W/m^2) - flwout_ai, & ! upwd lw emitted heat flx + flwout_ai, & ! upwd lw emitted heat flx (W/m^2) evap_ai, & ! & evaporation (kg/m2/s) evap_ice_ai, & ! & evaporation (kg/m2/s) evap_snow_ai, & ! & evaporation (kg/m2/s) fcondtop_ai, & ! downward cond flux at top surface (W m-2) - fsurf_ai ! net flux to top surface, excluding fcondtop + fsurf_ai ! net flux to top surface, excluding fcondtop (W/m^2) ! Used with data assimilation in hadgem drivers real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: & diff --git a/source/ice_history.F90 b/source/ice_history.F90 index dea9e204..d0ee174c 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -239,26 +239,26 @@ subroutine init_hist (dt) if ( f_sifllwutop /= 'x' ) call abort_ice("f_sifllwutop not available, set to 'x'") if ( f_siflswdtop /= 'x' ) call abort_ice("f_siflswdtop not available, set to 'x'") if ( f_siflswutop /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") - if ( f_sisnconc /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") + if ( f_sisnconc /= 'x' ) call abort_ice("f_sisnconc not available, set to 'x'") ! there is a calculation of a sisnconc based on snow volume, but it doesn't represent a process - if ( f_sisnthick /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") + if ( f_sisnthick /= 'x' ) call abort_ice("f_sisnthick not available, set to 'x'") #endif #ifdef AusCOM if ( .not. do_scale_fluxes ) then - ! normal case is these are scaled in place to grid cell average, - ! however without do_scale_fluxes, these are ice area averages - if ( f_fsens /= 'x' ) call abort_ice("f_alidf not available, use f_fsens_ai") - if ( f_flat /= 'x' ) call abort_ice("f_alidf not available, use f_flat_ai") - if ( f_fswabs /= 'x' ) call abort_ice("f_alidf not available, use f_fswabs_ai") - if ( f_flwup /= 'x' ) call abort_ice("f_alidf not available, use f_flwup_ai") - if ( f_evap /= 'x' ) call abort_ice("f_alidf not available, use f_evap_ai") + ! normal case is these are scaled in place to ice area average, + ! however without do_scale_fluxes, these are grid cell averages + if ( f_fsens /= 'x' ) call abort_ice("f_fsens not available, use f_fsens_ai") + if ( f_flat /= 'x' ) call abort_ice("f_flat not available, use f_flat_ai") + if ( f_fswabs /= 'x' ) call abort_ice("f_fswabs not available, use f_fswabs_ai") + if ( f_flwup /= 'x' ) call abort_ice("f_flwup not available, use f_flwup_ai") + if ( f_evap /= 'x' ) call abort_ice("f_evap not available, use f_evap_ai") if ( f_Tref /= 'x' ) call abort_ice("f_Tref not available, set to 'x'") if ( f_Qref /= 'x' ) call abort_ice("f_Qref not available, set to 'x'") - if ( f_fresh /= 'x' ) call abort_ice("f_alidf not available, use f_fresh_ai") - if ( f_fsalt /= 'x' ) call abort_ice("f_alidf not available, use f_fsalt_ai") - if ( f_fhocn /= 'x' ) call abort_ice("f_alidf not available, use f_fhocn_ai") - if ( f_fswthru /= 'x' ) call abort_ice("f_alidf not available, use f_fswthru_ai") + if ( f_fresh /= 'x' ) call abort_ice("f_fresh not available, use f_fresh_ai") + if ( f_fsalt /= 'x' ) call abort_ice("f_fsalt not available, use f_fsalt_ai") + if ( f_fhocn /= 'x' ) call abort_ice("f_fhocn not available, use f_fhocn_ai") + if ( f_fswthru /= 'x' ) call abort_ice("f_fswthru not available, use f_fswthru_ai") if ( f_alvdr /= 'x' ) call abort_ice("f_alvdr not available, use f_alvdr_ai") if ( f_alidr /= 'x' ) call abort_ice("f_alidr not available, use f_alidr_ai") if ( f_alvdf /= 'x' ) call abort_ice("f_alvdf not available, use f_alvdf_ai") @@ -1084,7 +1084,7 @@ subroutine init_hist (dt) ! extensive means a normal average (over all time and grid box area) ! and "mean where sea_ice" as intensive ! intensive vars can be grid box or ice area means, and are then calulated as - ! an ice as aweighted mean in time + ! an ice-fraction weighted mean in time ! extensive vars tend to zero when aice is zero, intensive vars do not ! In general, this implementation is limited by only weighting intensive @@ -1372,7 +1372,7 @@ subroutine init_hist (dt) call define_hist_field(n_sisndmassmelt_intensive,"sisndmassmelt_intensive","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Melt", & "area weighted average, always negative or zero, per unit grid cell area", -c1*rhos/dt, c0, & - ns1, f_sisndmassmelt, avg_ice_present=.true., mask_ice_free_points=.true.) + ns1, f_sisndmassmelt_intensive, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sisndmasssi,"sisndmasssi","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Snow-to-Ice Conversion", & @@ -1381,7 +1381,7 @@ subroutine init_hist (dt) call define_hist_field(n_sisndmasssi_intensive,"sisndmasssi_intensive","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Snow-to-Ice Conversion", & - "Always negative or zero, per unit grid cell area", -c1*rhoi/dt, c0, & + "area weighted average, always negative or zero, per unit grid cell area", -c1*rhoi/dt, c0, & ns1, f_sisndmasssi_intensive, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sndmassdyn,"sndmassdyn","kg m-2 s-1",tstr2D, tcstr, & @@ -1397,7 +1397,7 @@ subroutine init_hist (dt) call define_hist_field(n_sisndmassdyn_intensive,"sisndmassdyn_intensive","kg m-2 s-1",tstr2D, tcstr, & "Snow Mass Rate of Change Through Advection by Sea-Ice Dynamics", & "area weighted average, per unit grid cell area", rhos, c0, & - ns1, f_sisndmassdyn, avg_ice_present=.true., mask_ice_free_points=.true.) + ns1, f_sisndmassdyn_intensive, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdtop,"siflswdtop","W m^-2",tstr2D, tcstr, & "Downwelling Shortwave Flux over Sea Ice", & @@ -2168,7 +2168,7 @@ subroutine accum_hist (dt) ! for "extensive" vars, simply accumulate grid box mean values ! for "intensive" vars, either: ! - for grid box means, weight grid box means by aice (again) - ! - for ice area means, use grid box mean (to give the effect of ice area mean weighte by aice) + ! - for ice area means, use grid box mean (to give the effect of ice area mean weighted by aice) ! - for non spatial values (e.g. age), -> weight by aice ! as intensive vars are divided by the sum of aice over time when written to file @@ -2508,7 +2508,7 @@ subroutine accum_hist (dt) do k = 1,nslyr do j = jlo, jhi do i = ilo, ihi - ! extensive, vice is grid cell average + ! extensive, vsno is grid cell average worka(i,j) = worka(i,j) + & trcr(i,j,nt_qsno+k-1,iblk)*vsno(i,j,iblk)/real(nslyr,kind=dbl_kind) enddo From 2e8071fe13560f296e8efa33f802688555315be8 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Wed, 12 Nov 2025 13:21:44 +1100 Subject: [PATCH 75/80] review comments --- drivers/access/CICE_RunMod.F90 | 10 +------ source/ice_history.F90 | 53 +++++++++++++++++++--------------- source/ice_history_shared.F90 | 2 ++ source/ice_therm_vertical.F90 | 5 ++-- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/drivers/access/CICE_RunMod.F90 b/drivers/access/CICE_RunMod.F90 index 9d066deb..96f6afdd 100644 --- a/drivers/access/CICE_RunMod.F90 +++ b/drivers/access/CICE_RunMod.F90 @@ -434,15 +434,7 @@ subroutine coupling_prep (iblk) use ice_constants, only: c0, c1, puny, rhofresh use ice_coupling, only: top_layer_Tandk_run, sfcflux_to_ocn use ice_domain_size, only: ncat - use ice_flux, only: alvdf, alidf, alvdr, alidr, albice, albsno, & - albpnd, albcnt, apeff_ai, coszen, fpond, fresh, & - alvdf_ai, alidf_ai, alvdr_ai, alidr_ai, fhocn_ai, & - fresh_ai, fsalt_ai, fsalt, & - fswthru_ai, fhocn, fswthru, scale_factor, & - swvdr, swidr, swvdf, swidf, Tf, Tair, Qa, strairxT, strairyt, & - fsens, flat, fswabs, flwout, evap, Tref, Qref, faero_ocn, & - fsurfn_f, flatn_f, scale_fluxes, frzmlt_init, frzmlt, & - snowfrac, snowfracn, evap_ice, evap_snow + use ice_flux use ice_grid, only: tmask use ice_ocean, only: oceanmixed_ice, ocean_mixed_layer use ice_shortwave, only: alvdfn, alidfn, alvdrn, alidrn, & diff --git a/source/ice_history.F90 b/source/ice_history.F90 index d0ee174c..41c2d11a 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1094,7 +1094,7 @@ subroutine init_hist (dt) ! or based on thermodynamics only (would be averaged using aice_mid) ! It would require new history variables for aice_init and aice_mid - call define_hist_field(n_aice,"siconc","%",tstr2D, tcstr, & + call define_hist_field(n_siconc,"siconc","%",tstr2D, tcstr, & "Sea-Ice Area Percentage (Ocean Grid)", & "none", c100, c0, & ns1, f_siconc) @@ -1104,7 +1104,7 @@ subroutine init_hist (dt) "ice extent flag", c1, c0, & ns1, f_sitimefrac) - call define_hist_field(n_hi,"sivol","m",tstr2D, tcstr, & + call define_hist_field(n_sivol,"sivol","m",tstr2D, tcstr, & "Sea-Ice Volume per Area", & "ice volume per unit grid cell area", c1, c0, & ns1, f_sivol) @@ -1139,7 +1139,7 @@ subroutine init_hist (dt) "area weighted average of actual thickness of snow over the snow-covered part of the sea ice", c1, c0, & ns1, f_sisnthick, avg_ice_present=.true., mask_ice_free_points=.true.) - call define_hist_field(n_hs,"sisnmass","kg m^-2",tstr2D, tcstr, & + call define_hist_field(n_sisnmass,"sisnmass","kg m^-2",tstr2D, tcstr, & "Snow Mass per Area", & "snow mass per unit grid cell area", rhos, c0, & ns1, f_sisnmass) @@ -1256,12 +1256,12 @@ subroutine init_hist (dt) call define_hist_field(n_sihc,"sihc","J m^-2",tstr2D, tcstr, & "Sea-Ice Heat Content", & - "none", c1, c0, & + "area weighted average per unit grid cell area", c1, c0, & ns1, f_sihc) call define_hist_field(n_sisnhc,"sisnhc","J m^-2",tstr2D, tcstr, & "Snow Heat Content", & - "none", c1, c0, & + "area weighted average per unit grid cell area", c1, c0, & ns1, f_sisnhc) call define_hist_field(n_sidconcth,"sidconcth","1/s",tstr2D, tcstr, & @@ -1401,57 +1401,57 @@ subroutine init_hist (dt) call define_hist_field(n_siflswdtop,"siflswdtop","W m^-2",tstr2D, tcstr, & "Downwelling Shortwave Flux over Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_siflswdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswutop,"siflswutop","W m^-2",tstr2D, tcstr, & "Upwelling Shortwave Flux over Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_siflswutop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflswdbot,"siflswdbot","W m^-2",tstr2D, tcstr, & "Downwelling Shortwave Flux under Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_siflswdbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllwdtop,"sifllwdtop","W m^-2",tstr2D, tcstr, & "Downwelling Longwave Flux over Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_sifllwdtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllwutop,"sifllwutop","W m^-2",tstr2D, tcstr, & "Upwelling Longwave Flux over Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_sifllwutop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsenstop,"siflsenstop","W m^-2",tstr2D, tcstr, & "Net Downward Sensible Heat Flux over Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_siflsenstop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsensupbot,"siflsensupbot","W m^-2",tstr2D, tcstr, & "Net Upward Sensible Heat Flux under Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_siflsensupbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflsensupbot,"siflsensbot","W m^-2",tstr2D, tcstr, & "Net Upward Sensible Heat Flux under Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_siflsensbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_sifllatstop,"sifllatstop","W m^-2",tstr2D, tcstr, & "Net Latent Heat Flux over Sea Ice", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_sifllatstop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflcondtop,"siflcondtop","W m^-2",tstr2D, tcstr, & "Net Conductive Heat Flux in Sea Ice at the Surface", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_siflcondtop, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflcondbot,"siflcondbot","W m^-2",tstr2D, tcstr, & "Net Conductive Heat Flux in Sea Ice at the Base", & - "area weighted average, positive downward, per unit grid cell area", c1, c0, & + "area weighted average, positive downward, per sea ice area", c1, c0, & ns1, f_siflcondbot, avg_ice_present=.true., mask_ice_free_points=.true.) call define_hist_field(n_siflfwdrain,"siflfwdrain","kg m^-2 s^-1",tstr2D, tcstr, & @@ -1550,7 +1550,7 @@ subroutine init_hist (dt) ns1, f_keffn_top) ! CMIP 3D - call define_hist_field(n_aicen,"siitdconc","%",tstr3Dc, tcstr, & + call define_hist_field(n_siitdconc,"siitdconc","%",tstr3Dc, tcstr, & "Sea-Ice Area Percentage in Ice Thickness Categories", & "none", c100, c0, & ns1, f_siitdconc) @@ -1915,7 +1915,7 @@ subroutine accum_hist (dt) ! if (f_example(1:1) /= 'x') & ! call accum_hist_field(n_example,iblk, vice(:,:,iblk), a2D) - if (f_hi (1:1) /= 'x' .or. f_sivol(1:1) /= 'x') & + if (f_hi (1:1) /= 'x') & call accum_hist_field(n_hi, iblk, vice(:,:,iblk), a2D) if (f_hs (1:1) /= 'x') & call accum_hist_field(n_hs, iblk, vsno(:,:,iblk), a2D) @@ -1923,7 +1923,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_snowfrac, iblk, snowfrac(:,:,iblk), a2D) if (f_Tsfc (1:1) /= 'x') & call accum_hist_field(n_Tsfc, iblk, trcr(:,:,nt_Tsfc,iblk), a2D) - if (f_aice (1:1) /= 'x' .or. f_siconc (1:1) /= 'x') & + if (f_aice (1:1) /= 'x') & call accum_hist_field(n_aice, iblk, aice(:,:,iblk), a2D) if (f_uvel (1:1) /= 'x') & call accum_hist_field(n_uvel, iblk, uvel(:,:,iblk), a2D) @@ -2043,7 +2043,7 @@ subroutine accum_hist (dt) if (f_evap (1:1) /= 'x') & call accum_hist_field(n_evap, iblk, evap(:,:,iblk), a2D) if (f_evap_ai(1:1) /= 'x') & - call accum_hist_field(n_evap_ai,iblk, evap(:,:,iblk)*workb(:,:), a2D) + call accum_hist_field(n_evap_ai,iblk, evap_ai(:,:,iblk), a2D) if (f_evap_ice_ai(1:1) /= 'x') & call accum_hist_field(n_evap_ice_ai,iblk, evap_ice_ai(:,:,iblk), a2D) if (f_evap_snow_ai(1:1) /= 'x') & @@ -2172,6 +2172,11 @@ subroutine accum_hist (dt) ! - for non spatial values (e.g. age), -> weight by aice ! as intensive vars are divided by the sum of aice over time when written to file + if (f_sivol(1:1) /= 'x') & + call accum_hist_field(n_sivol, iblk, vice(:,:,iblk), a2D) + + if (f_siconc (1:1) /= 'x') & + call accum_hist_field(n_siconc, iblk, aice(:,:,iblk), a2D) if (f_sithick(1:1) /= 'x') & ! intensive - ice area mean -> use vice (grid box mean) @@ -2743,7 +2748,7 @@ subroutine accum_hist (dt) !3D category fields - if (f_aicen (1:1) /= 'x' .or. f_siitdconc (1:1) /= 'x') & + if (f_aicen (1:1) /= 'x') & call accum_hist_field(n_aicen-n2D, iblk, ncat_hist, & aicen(:,:,1:ncat_hist,iblk), a3Dc) if (f_vicen (1:1) /= 'x') & @@ -2780,7 +2785,9 @@ subroutine accum_hist (dt) call accum_hist_field(n_fmelttn_ai-n2D, iblk, ncat_hist, & max(fsurfn(:,:,1:ncat_hist,iblk) - fcondtopn(:,:,1:ncat_hist,iblk),c0) & *aicen_init(:,:,1:ncat_hist,iblk), a3Dc) - + if (f_siitdconc (1:1) /= 'x') & + call accum_hist_field(n_siitdconc-n2D, iblk, ncat_hist, & + aicen(:,:,1:ncat_hist,iblk), a3Dc) ! example for 3D field (x,y,z) ! if (f_field3dz (1:1) /= 'x') & ! call accum_hist_field(n_field3dz-n3Dccum, iblk, nzilyr, & @@ -3087,7 +3094,7 @@ subroutine accum_hist (dt) a3Dc(i,j,k,n,iblk) = spval_dbl else ! convert units a3Dc(i,j,k,n,iblk) = avail_hist_fields(nn)%cona*a3Dc(i,j,k,n,iblk) & - * ravgct + avail_hist_fields(nn)%conb + + avail_hist_fields(nn)%conb endif enddo ! i enddo ! j diff --git a/source/ice_history_shared.F90 b/source/ice_history_shared.F90 index 45c455b0..64cb4cce 100755 --- a/source/ice_history_shared.F90 +++ b/source/ice_history_shared.F90 @@ -537,6 +537,7 @@ module ice_history_shared n_sicompstren, & n_sialb, & n_sihc , n_sisnhc, & + n_siconc, n_sivol, & n_sidconcth , n_sidconcdyn, & n_sidmassth , n_sidmassdyn, & n_sidmassgrowthwat, & @@ -572,6 +573,7 @@ module ice_history_shared n_siflfwbot, & n_siflfwdrain, & n_sisaltmass, & + n_siitdconc, & n_vsnon, & n_fhocn , n_fhocn_ai , & n_fswthru , n_fswthru_ai , & diff --git a/source/ice_therm_vertical.F90 b/source/ice_therm_vertical.F90 index 4c3f1e1f..8cc47030 100755 --- a/source/ice_therm_vertical.F90 +++ b/source/ice_therm_vertical.F90 @@ -482,8 +482,9 @@ subroutine thermo_vertical (nx_block, ny_block, & ! - the average of temperature of bottom snow layer and top ice layer, ! - weighted by aicen across all thickness categories if (hslyr(ij) > puny) then - ! interface temperature is average of top ice layer & bottom snow layer temperatures, - ! weighted by the thickness of each layer (https://github.com/CICE-Consortium/Icepack/pull/542#issuecomment-3464152061) + ! interface temperature is taken by assumming a linear temperature gradient between temperature at + ! middle of top ice layer & middle of bottom snow layer temperatures, + ! weighted by the thickness of each layer (https://github.com/CICE-Consortium/Icepack/pull/542) Tsnice(ij) = Tsnice(ij) + aicen(i,j)*(& (hilyr(ij)*zTsn(ij,nslyr) + hslyr(ij)*zTin(ij,1)) & / (hslyr(ij)+hilyr(ij)) & From adff66cfea12b63fabe131973cdaf00be5638e57 Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:21:00 +1100 Subject: [PATCH 76/80] Apply suggestions from code review Co-authored-by: Spencer Wong <88933912+blimlim@users.noreply.github.com> --- source/ice_history.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 41c2d11a..ce3ce186 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1256,12 +1256,12 @@ subroutine init_hist (dt) call define_hist_field(n_sihc,"sihc","J m^-2",tstr2D, tcstr, & "Sea-Ice Heat Content", & - "area weighted average per unit grid cell area", c1, c0, & + "per unit grid cell area", c1, c0, & ns1, f_sihc) call define_hist_field(n_sisnhc,"sisnhc","J m^-2",tstr2D, tcstr, & "Snow Heat Content", & - "area weighted average per unit grid cell area", c1, c0, & + "per unit grid cell area", c1, c0, & ns1, f_sisnhc) call define_hist_field(n_sidconcth,"sidconcth","1/s",tstr2D, tcstr, & From fd8ccf375b4e4bd1e26d7782cc23ade50022e4e8 Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:21:36 +1100 Subject: [PATCH 77/80] Update source/ice_therm_vertical.F90 Co-authored-by: Spencer Wong <88933912+blimlim@users.noreply.github.com> --- source/ice_therm_vertical.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/ice_therm_vertical.F90 b/source/ice_therm_vertical.F90 index 8cc47030..e4a9e97f 100755 --- a/source/ice_therm_vertical.F90 +++ b/source/ice_therm_vertical.F90 @@ -479,8 +479,6 @@ subroutine thermo_vertical (nx_block, ny_block, & ! Tsnice from https://github.com/CICE-Consortium/Icepack/blob/e9d626f0e5b743e143a2e87248a1aa22ee4f3751/columnphysics/icepack_therm_vertical.F90#L378C1-L385C12 ! Tsnice is : - ! - the average of temperature of bottom snow layer and top ice layer, - ! - weighted by aicen across all thickness categories if (hslyr(ij) > puny) then ! interface temperature is taken by assumming a linear temperature gradient between temperature at ! middle of top ice layer & middle of bottom snow layer temperatures, From 41c6a649b04f050b6ae4a970c73260a8c709047f Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:28:04 +1100 Subject: [PATCH 78/80] Update source/ice_history.F90 --- source/ice_history.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index ce3ce186..7a7613c9 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -1344,7 +1344,7 @@ subroutine init_hist (dt) "per unit grid cell area", -c1*rhoi/dt, c0, & ns1, f_sidmassmeltlat) - call define_hist_field(n_snow_ai,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & + call define_hist_field(n_sndmasssnf,"sndmasssnf","kg m^-2 s^-1",tstr2D, tcstr, & "Snow Mass Change Through Snowfall", & "per unit grid cell area", c1, c0, & ns1, f_sndmasssnf) From 67863be3ec336102844269998c25daf6d842c271 Mon Sep 17 00:00:00 2001 From: Anton Steketee <79179784+anton-seaice@users.noreply.github.com> Date: Thu, 13 Nov 2025 09:22:29 +1100 Subject: [PATCH 79/80] Update source/ice_history.F90 Co-authored-by: Spencer Wong <88933912+blimlim@users.noreply.github.com> --- source/ice_history.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 7a7613c9..00e1f5bf 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -241,6 +241,8 @@ subroutine init_hist (dt) if ( f_siflswutop /= 'x' ) call abort_ice("f_siflswutop not available, set to 'x'") if ( f_sisnconc /= 'x' ) call abort_ice("f_sisnconc not available, set to 'x'") ! there is a calculation of a sisnconc based on snow volume, but it doesn't represent a process + + if ( f_snowfrac /= 'x' ) call abort_ice("f_snowfrac not available, set to 'x'") if ( f_sisnthick /= 'x' ) call abort_ice("f_sisnthick not available, set to 'x'") #endif From eb9583d3150c220060619331c5bf94a22f12c605 Mon Sep 17 00:00:00 2001 From: anton-seaice Date: Thu, 13 Nov 2025 09:32:16 +1100 Subject: [PATCH 80/80] fix n_sndmasssnf --- source/ice_history.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ice_history.F90 b/source/ice_history.F90 index 00e1f5bf..ff419e62 100755 --- a/source/ice_history.F90 +++ b/source/ice_history.F90 @@ -2579,7 +2579,7 @@ subroutine accum_hist (dt) call accum_hist_field(n_sidmasslat, iblk, meltl(:,:,iblk), a2D) ! *rhoi/dt in define_hist_field if (f_sndmasssnf(1:1) /= 'x' .or. f_sisndmasssnf(1:1) /= 'x') & - call accum_hist_field(n_snow_ai,iblk, fsnow(:,:,iblk)*aice_init(:,:,iblk), a2D) + call accum_hist_field(n_sndmasssnf,iblk, fsnow(:,:,iblk)*aice_init(:,:,iblk), a2D) if (f_sisndmasssnf_intensive(1:1) /= 'x') then do j = jlo, jhi