Skip to content

Commit a84c3e3

Browse files
apcraigzhaobin74
andauthored
Add GEOS coupling capability including heat and mass flux options in Icepack (CICE-Consortium#1012)
Add GEOS coupling updates. This allows coupling to the GEOS coupled system where a semi-implicit thermodynamic coupling scheme is introduced. Similar to the explicit case, the fields fsurfn are provided by the coupler, along with their derivatives with respect to surface temperature dfsurfn_dTs. In this case, calc_Tsfc is still set to true, allowing ice surface and internal temperature to be updated implicitly. The resultant surface temperature change is passed back to the atmosphere model via coupler to complete the full update of its temperature profiles. This middle-ground approach, enabled by semi_implicit_Tsfc=true, does not sacrifice accuracy because it does not need limiting effective conductivity as in the explicit case. In addition, in GEOS, the atmosphere model assumes vapor deposits or sublimates at 0 degC. In this case, mass conservation is enforced and the resulting discrepancy in energy is resolved by another term, de_vapor, and passed to ocean. This option is only on when vapor_flux_correction is true. Add 4 new shortwave terms, uvrdr, uvrdf, pardr, pardf to the coupling. These terms represent a breakdown of the direct and diffuse visible shortwave terms into two components, par = photosynthetical active radiation (400-700nm) and uvr = rest of the visible shortwave term (>700nm). The current visible shortwave is exactly represented by these two components. Includes adding atm forcing and terms associated with radiation passthru to the ocean. Add support for GEOS semi-implicit coupling of surface temperature. In GEOS, surface and latent heat flux is computed in the atmosphere at 0degC. The sea ice model has to respect that calculation, but then computes the d(dh)/dTs terms to correct the heatflux for the sea ice temperature which is then applied conservatively in the coupled system. Implementation includes turning off some of the heat flux calculations in Icepack. This is controlled by the semi_implicit_Tsfc namelist. Add calculation of a vapor flux correction. A correction is needed for GEOS coupling to compute a mass and enthalpy correction for evaporation and sublimation. This is controlled by the vapor_flux_correction namelist. Add mapl/geos coupling directory and coupling files Add opmask (orphan mask) for points that are NOT ocean/ice in the ocean/ice model but are ocean/ice in the atmosphere model. This allows for thermodyanamic calculations on the orphan points while not being involved in any sea ice dynamics. opmask determined by ocn_gridcell_frac which should be set by coupling layer at initialization. Add geosmom grid_type to read GEOS MOM grid files Add discover port Update documentation Change use of grid_type='tripole' where ns_boundary_type='tripole' is more appropriate. Add distribution_wght=blockfull option to move away from CPP in init_domain_blocks. This option turns off land block elimination and sets all blocks to maximum weight for distribution. Clean up some declarations in ice_flux.F90 and ice_state.F90 Add some new initialization output for new GEOS options and to clean up grid_type output --------- Co-authored-by: bzhao <[email protected]>
1 parent 636856f commit a84c3e3

36 files changed

+4348
-232
lines changed

cicecore/cicedyn/dynamics/ice_dyn_eap.F90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,8 +2090,7 @@ subroutine read_restart_eap()
20902090
use ice_boundary, only: ice_HaloUpdate_stress
20912091
use ice_constants, only: &
20922092
field_loc_center, field_type_scalar
2093-
use ice_domain, only: nblocks, halo_info
2094-
use ice_grid, only: grid_type
2093+
use ice_domain, only: nblocks, halo_info, ns_boundary_type
20952094
use ice_restart, only: read_restart_field
20962095

20972096
! local variables
@@ -2131,7 +2130,8 @@ subroutine read_restart_eap()
21312130
call read_restart_field(nu_restart_eap,0,a12_4,'ruf8', &
21322131
'a12_4',1,diag,field_loc_center,field_type_scalar) ! a12_4
21332132

2134-
if (trim(grid_type) == 'tripole') then
2133+
if (trim(ns_boundary_type) == 'tripole' .or. &
2134+
trim(ns_boundary_type) == 'tripoleT') then
21352135

21362136
call ice_HaloUpdate_stress(a11_1, a11_3, halo_info, &
21372137
field_loc_center, field_type_scalar)

cicecore/cicedyn/dynamics/ice_dyn_evp.F90

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ subroutine evp (dt)
259259
use ice_boundary, only: ice_halo, ice_HaloMask, ice_HaloUpdate, &
260260
ice_HaloDestroy, ice_HaloUpdate_stress
261261
use ice_blocks, only: block, get_block, nx_block, ny_block, nghost
262-
use ice_domain, only: nblocks, blocks_ice, halo_info, maskhalo_dyn
262+
use ice_domain, only: nblocks, blocks_ice, halo_info, maskhalo_dyn, &
263+
ns_boundary_type
263264
use ice_domain_size, only: max_blocks, ncat
264265
use ice_flux, only: rdg_conv, rdg_shear, strairxT, strairyT, &
265266
strairxU, strairyU, uocn, vocn, ss_tltx, ss_tlty, fmU, &
@@ -280,8 +281,7 @@ subroutine evp (dt)
280281
use ice_grid, only: tmask, umask, umaskCD, nmask, emask, uvm, epm, npm, &
281282
dxE, dxN, dxT, dxU, dyE, dyN, dyT, dyU, &
282283
tarear, uarear, earear, narear, grid_average_X2Y, uarea, &
283-
grid_type, grid_ice, &
284-
grid_atm_dynu, grid_atm_dynv, grid_ocn_dynu, grid_ocn_dynv
284+
grid_ice, grid_atm_dynu, grid_atm_dynv, grid_ocn_dynu, grid_ocn_dynv
285285
use ice_state, only: aice, aiU, vice, vsno, uvel, vvel, uvelN, vvelN, &
286286
uvelE, vvelE, divu, shear, vort, &
287287
aice_init, aice0, aicen, vicen, strength
@@ -1313,7 +1313,8 @@ subroutine evp (dt)
13131313
endif
13141314

13151315
! Force symmetry across the tripole seam
1316-
if (trim(grid_type) == 'tripole') then
1316+
if (trim(ns_boundary_type) == 'tripole' .or. &
1317+
trim(ns_boundary_type) == 'tripoleT') then
13171318
! TODO: C/CD-grid
13181319
if (maskhalo_dyn) then
13191320
!-------------------------------------------------------

cicecore/cicedyn/dynamics/ice_dyn_shared.F90

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ subroutine init_dyn_shared (dt)
240240

241241
use ice_blocks, only: block, get_block
242242
use ice_boundary, only: ice_halo, ice_haloUpdate
243-
use ice_domain, only: nblocks, halo_dynbundle, blocks_ice, halo_info
243+
use ice_domain, only: nblocks, halo_dynbundle, blocks_ice, halo_info, &
244+
ns_boundary_type
244245
use ice_domain_size, only: max_blocks
245246
use ice_flux, only: &
246247
stressp_1, stressp_2, stressp_3, stressp_4, &
@@ -268,6 +269,13 @@ subroutine init_dyn_shared (dt)
268269

269270
character(len=*), parameter :: subname = '(init_dyn_shared)'
270271

272+
! checks
273+
if (kdyn == 1 .and. evp_algorithm == 'shared_mem_1d' .and. &
274+
(ns_boundary_type == 'tripole' .or. ns_boundary_type == 'tripoleT')) then
275+
call abort_ice(subname//' ERROR: evp_alg shared mem 1d not supported with tripole', &
276+
file=__FILE__, line=__LINE__)
277+
endif
278+
271279
call set_evp_parameters (dt)
272280
! allocate dyn shared (init_uvel,init_vvel)
273281
call alloc_dyn_shared

cicecore/cicedyn/dynamics/ice_dyn_vp.F90

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ subroutine implicit_solver (dt)
155155
use ice_boundary, only: ice_HaloMask, ice_HaloUpdate, &
156156
ice_HaloDestroy, ice_HaloUpdate_stress
157157
use ice_blocks, only: block, get_block, nx_block, ny_block
158-
use ice_domain, only: blocks_ice, halo_info, maskhalo_dyn
158+
use ice_domain, only: blocks_ice, halo_info, maskhalo_dyn, &
159+
ns_boundary_type
159160
use ice_domain_size, only: max_blocks, ncat
160161
use ice_dyn_shared, only: deformations, iceTmask, iceUmask, &
161162
cxp, cyp, cxm, cym
@@ -168,7 +169,7 @@ subroutine implicit_solver (dt)
168169
stressm_1, stressm_2, stressm_3, stressm_4, &
169170
stress12_1, stress12_2, stress12_3, stress12_4
170171
use ice_grid, only: tmask, umask, dxT, dyT, dxU, dyU, &
171-
tarear, grid_type, grid_average_X2Y, &
172+
tarear, grid_average_X2Y, &
172173
grid_atm_dynu, grid_atm_dynv, grid_ocn_dynu, grid_ocn_dynv
173174
use ice_state, only: aice, aiU, vice, vsno, uvel, vvel, divu, shear, vort, &
174175
aice_init, aice0, aicen, vicen, strength
@@ -546,7 +547,8 @@ subroutine implicit_solver (dt)
546547
endif
547548

548549
! Force symmetry across the tripole seam
549-
if (trim(grid_type) == 'tripole') then
550+
if (trim(ns_boundary_type) == 'tripole' .or. &
551+
trim(ns_boundary_type) == 'tripoleT') then
550552
if (maskhalo_dyn) then
551553
!-------------------------------------------------------
552554
! set halomask to zero because ice_HaloMask always keeps

cicecore/cicedyn/general/ice_flux.F90

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@ module ice_flux
114114
dvirdgdt, & ! rate of ice volume ridged (m/s)
115115
opening ! rate of opening due to divergence/shear (1/s)
116116

117-
real (kind=dbl_kind), &
118-
dimension (:,:,:,:), allocatable, public :: &
117+
real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: &
119118
! ridging diagnostics in categories
120119
dardg1ndt, & ! rate of area loss by ridging ice (1/s)
121120
dardg2ndt, & ! rate of area gain by new ridges (1/s)
@@ -177,13 +176,26 @@ module ice_flux
177176
! NOTE: when in CICE_IN_NEMO mode, these are gridbox mean fields,
178177
! not per ice area. When in standalone mode, these are per ice area.
179178

180-
real (kind=dbl_kind), &
181-
dimension (:,:,:,:), allocatable, public :: &
179+
real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: &
182180
fsurfn_f , & ! net flux to top surface, excluding fcondtop
183181
fcondtopn_f, & ! downward cond flux at top surface (W m-2)
184182
fsensn_f , & ! sensible heat flux (W m-2)
185183
flatn_f ! latent heat flux (W m-2)
186184

185+
! in from atmosphere
186+
! required for coupling in GEOS
187+
188+
real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: &
189+
evapn_f, & ! evaporation/sublimation (kg m-2 s-1)
190+
dflatndTsfc_f, & ! derivative of latent flux w.r.t. Tsfc
191+
dfsurfndTsfc_f ! derivative of surface flux w.r.t. Tsfc
192+
193+
real (kind=dbl_kind), dimension (:,:,:), allocatable, public :: &
194+
swuvrdr , & ! vis uvr flux, direct (W m-2)
195+
swuvrdf , & ! vis uvr flux, diffuse (W m-2)
196+
swpardr , & ! vis par flux, direct (W m-2)
197+
swpardf ! vis par flux, diffuse (W m-2)
198+
187199
! in from atmosphere
188200

189201
real (kind=dbl_kind), dimension (:,:,:), allocatable, public :: &
@@ -258,7 +270,11 @@ module ice_flux
258270
fswthru_vdr , & ! vis dir shortwave penetrating to ocean (W/m^2)
259271
fswthru_vdf , & ! vis dif shortwave penetrating to ocean (W/m^2)
260272
fswthru_idr , & ! nir dir shortwave penetrating to ocean (W/m^2)
261-
fswthru_idf ! nir dif shortwave penetrating to ocean (W/m^2)
273+
fswthru_idf , & ! nir dif shortwave penetrating to ocean (W/m^2)
274+
fswthru_uvrdr,& ! vis dir uvr SW penetrating to ocean (W/m^2)
275+
fswthru_uvrdf,& ! vis dif uvr SW penetrating to ocean (W/m^2)
276+
fswthru_pardr,& ! nir dir par SW penetrating to ocean (W/m^2)
277+
fswthru_pardf ! nir dif par SW penetrating to ocean (W/m^2)
262278

263279
! internal
264280

@@ -326,16 +342,14 @@ module ice_flux
326342
frz_onset, &! day of year that freezing begins (congel or frazil)
327343
frazil_diag ! frazil ice growth diagnostic (m/step-->cm/day)
328344

329-
real (kind=dbl_kind), &
330-
dimension (:,:,:,:), allocatable, public :: &
345+
real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: &
331346
fsurfn, & ! category fsurf
332347
fcondtopn,& ! category fcondtop
333348
fcondbotn,& ! category fcondbot
334349
fsensn, & ! category sensible heat flux
335350
flatn ! category latent heat flux
336351

337-
real (kind=dbl_kind), &
338-
dimension (:,:,:,:), allocatable, public :: &
352+
real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: &
339353
snwcnt ! counter for presence of snow
340354

341355
! As above but these remain grid box mean values i.e. they are not
@@ -453,6 +467,10 @@ subroutine alloc_flux
453467
swvdf (nx_block,ny_block,max_blocks), & ! sw down, visible, diffuse (W/m^2)
454468
swidr (nx_block,ny_block,max_blocks), & ! sw down, near IR, direct (W/m^2)
455469
swidf (nx_block,ny_block,max_blocks), & ! sw down, near IR, diffuse (W/m^2)
470+
swuvrdr (nx_block,ny_block,max_blocks), & ! vis uvr flux, direct (W m-2)
471+
swuvrdf (nx_block,ny_block,max_blocks), & ! vis uvr flux, diffuse (W m-2)
472+
swpardr (nx_block,ny_block,max_blocks), & ! vis par flux, direct (W m-2)
473+
swpardf (nx_block,ny_block,max_blocks), & ! vis par flux, diffuse (W m-2)
456474
flw (nx_block,ny_block,max_blocks), & ! incoming longwave radiation (W/m^2)
457475
frain (nx_block,ny_block,max_blocks), & ! rainfall rate (kg/m^2 s)
458476
fsnow (nx_block,ny_block,max_blocks), & ! snowfall rate (kg/m^2 s)
@@ -499,11 +517,15 @@ subroutine alloc_flux
499517
fhocn (nx_block,ny_block,max_blocks), & ! net heat flux to ocean (W/m^2)
500518
fsloss (nx_block,ny_block,max_blocks), & ! rate of snow loss to leads (kg/m^2/s)
501519
fswthru (nx_block,ny_block,max_blocks), & ! shortwave penetrating to ocean (W/m^2)
502-
fswthru_vdr (nx_block,ny_block,max_blocks), & ! vis dir shortwave penetrating to ocean (W/m^2)
503-
fswthru_vdf (nx_block,ny_block,max_blocks), & ! vis dif shortwave penetrating to ocean (W/m^2)
504-
fswthru_idr (nx_block,ny_block,max_blocks), & ! nir dir shortwave penetrating to ocean (W/m^2)
505-
fswthru_idf (nx_block,ny_block,max_blocks), & ! nir dif shortwave penetrating to ocean (W/m^2)
506-
scale_factor (nx_block,ny_block,max_blocks), & ! scaling factor for shortwave components
520+
fswthru_vdr(nx_block,ny_block,max_blocks), & ! vis dir shortwave penetrating to ocean (W/m^2)
521+
fswthru_vdf(nx_block,ny_block,max_blocks), & ! vis dif shortwave penetrating to ocean (W/m^2)
522+
fswthru_idr(nx_block,ny_block,max_blocks), & ! nir dir shortwave penetrating to ocean (W/m^2)
523+
fswthru_idf(nx_block,ny_block,max_blocks), & ! nir dif shortwave penetrating to ocean (W/m^2)
524+
fswthru_uvrdr (nx_block,ny_block,max_blocks), & ! vis dir uvr SW penetrating to ocean (W/m^2)
525+
fswthru_uvrdf (nx_block,ny_block,max_blocks), & ! vis dir uvr SW penetrating to ocean (W/m^2)
526+
fswthru_pardr (nx_block,ny_block,max_blocks), & ! vis dir par SW penetrating to ocean (W/m^2)
527+
fswthru_pardf (nx_block,ny_block,max_blocks), & ! vis dir par SW penetrating to ocean (W/m^2)
528+
scale_factor (nx_block,ny_block,max_blocks), & ! scaling factor for shortwave components
507529
strairx_ocn(nx_block,ny_block,max_blocks), & ! stress on ocean by air, x-direction
508530
strairy_ocn(nx_block,ny_block,max_blocks), & ! stress on ocean by air, y-direction
509531
fsens_ocn (nx_block,ny_block,max_blocks), & ! sensible heat flux (W/m^2)
@@ -566,6 +588,9 @@ subroutine alloc_flux
566588
fcondtopn_f(nx_block,ny_block,ncat,max_blocks), & ! downward cond flux at top surface (W m-2)
567589
fsensn_f (nx_block,ny_block,ncat,max_blocks), & ! sensible heat flux (W m-2)
568590
flatn_f (nx_block,ny_block,ncat,max_blocks), & ! latent heat flux (W m-2)
591+
evapn_f (nx_block,ny_block,ncat,max_blocks), & ! evaporative water flux (kg/m^2/s) by atmosphere model
592+
dflatndTsfc_f (nx_block,ny_block,ncat,max_blocks), & ! derivative of flatn with respect to Tsfc
593+
dfsurfndTsfc_f(nx_block,ny_block,ncat,max_blocks), & ! derivative of fsurfn with respect to Tsfc
569594
meltsn (nx_block,ny_block,ncat,max_blocks), & ! snow melt in category n (m)
570595
melttn (nx_block,ny_block,ncat,max_blocks), & ! top melt in category n (m)
571596
meltbn (nx_block,ny_block,ncat,max_blocks), & ! bottom melt in category n (m)
@@ -584,6 +609,11 @@ subroutine alloc_flux
584609
stat=ierr)
585610
if (ierr/=0) call abort_ice('(alloc_flux): Out of memory')
586611

612+
swuvrdr(:,:,:) = c0
613+
swuvrdf(:,:,:) = c0
614+
swpardr(:,:,:) = c0
615+
swpardf(:,:,:) = c0
616+
587617
if (grid_ice == "CD" .or. grid_ice == "C") &
588618
allocate( &
589619
taubxN (nx_block,ny_block,max_blocks), & ! seabed stress (x) at N points (N/m^2)
@@ -792,6 +822,10 @@ subroutine init_coupler_flux
792822
fswthru_vdf (:,:,:) = c0
793823
fswthru_idr (:,:,:) = c0
794824
fswthru_idf (:,:,:) = c0
825+
fswthru_uvrdr (:,:,:) = c0
826+
fswthru_uvrdf (:,:,:) = c0
827+
fswthru_pardr (:,:,:) = c0
828+
fswthru_pardf (:,:,:) = c0
795829
fresh_da(:,:,:) = c0 ! data assimilation
796830
fsalt_da(:,:,:) = c0
797831
flux_bio (:,:,:,:) = c0 ! bgc
@@ -853,6 +887,8 @@ subroutine init_flux_atm
853887
! strairxT(:,:,:) = 0.15_dbl_kind
854888
! strairyT(:,:,:) = 0.15_dbl_kind
855889

890+
fsurf (:,:,:) = c0
891+
fcondtop(:,:,:) = c0
856892
fsens (:,:,:) = c0
857893
flat (:,:,:) = c0
858894
fswabs (:,:,:) = c0
@@ -898,6 +934,10 @@ subroutine init_flux_ocn
898934
fswthru_vdf (:,:,:) = c0
899935
fswthru_idr (:,:,:) = c0
900936
fswthru_idf (:,:,:) = c0
937+
fswthru_uvrdr(:,:,:) = c0
938+
fswthru_uvrdf(:,:,:) = c0
939+
fswthru_pardr(:,:,:) = c0
940+
fswthru_pardf(:,:,:) = c0
901941

902942
faero_ocn (:,:,:,:) = c0
903943
fiso_ocn (:,:,:,:) = c0

0 commit comments

Comments
 (0)