9 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
13 use mom_diag_mediator,
only : enable_averages, enable_averaging, disable_averaging
26 use mom_io,
only : slasher, fieldtype
27 use mom_io,
only : write_field, close_file, single_file, multiple
30 use mom_time_manager,
only : time_type, time_type_to_real, real_to_time,
operator(>),
operator(-)
47 use user_shelf_init,
only : user_initialize_shelf_mass, user_update_shelf_mass
52 use time_interp_external_mod,
only : init_external_field, time_interp_external
53 use time_interp_external_mod,
only : time_interp_external_init
54 implicit none ;
private 56 #include <MOM_memory.h> 57 #ifdef SYMMETRIC_LAND_ICE 58 # define GRID_SYM_ .true. 60 # define GRID_SYM_ .false. 63 public shelf_calc_flux, add_shelf_flux, initialize_ice_shelf, ice_shelf_end
64 public ice_shelf_save_restart, solo_step_ice_shelf, add_shelf_forces
82 real :: flux_factor = 1.0
84 character(len=128) :: restart_output_dir =
' ' 89 real,
pointer,
dimension(:,:) :: &
105 real :: kd_molec_salt
106 real :: kd_molec_temp
111 real :: col_mass_melt_threshold
113 logical :: mass_from_file
122 logical :: solo_ice_sheet
124 logical :: gl_regularize
130 logical :: calve_to_mask
131 real :: min_thickness_simple_calve
135 real :: input_thickness
137 type(time_type) :: time
140 logical :: active_shelf_dynamics
142 logical :: override_shelf_movement
150 logical :: const_gamma
151 logical :: constant_sea_level
153 real :: min_ocean_mass_float
157 logical :: find_salt_root
163 integer :: id_melt = -1, id_exch_vel_s = -1, id_exch_vel_t = -1, &
164 id_tfreeze = -1, id_tfl_shelf = -1, &
165 id_thermal_driving = -1, id_haline_driving = -1, &
166 id_u_ml = -1, id_v_ml = -1, id_sbdry = -1, &
167 id_h_shelf = -1, id_h_mask = -1, &
168 id_surf_elev = -1, id_bathym = -1, &
169 id_area_shelf_h = -1, &
170 id_ustar_shelf = -1, id_shelf_mass = -1, id_mass_flux = -1
173 integer :: id_read_mass
175 integer :: id_read_area
186 integer :: id_clock_shelf
187 integer :: id_clock_pass
194 subroutine shelf_calc_flux(sfc_state, fluxes, Time, time_step, CS, forces)
198 type(
forcing),
intent(inout) :: fluxes
200 type(time_type),
intent(in) :: time
201 real,
intent(in) :: time_step
214 real,
dimension(SZI_(CS%grid)) :: &
215 rhoml, & !< Ocean mixed layer density [R ~> kg m-3].
216 dr0_dt, & !< Partial derivative of the mixed layer density
222 real,
dimension(SZI_(CS%grid),SZJ_(CS%grid)) :: &
223 exch_vel_t, & !< Sub-shelf thermal exchange velocity [Z T-1 ~> m s-1]
226 real,
dimension(SZDI_(CS%grid),SZDJ_(CS%grid)) :: &
228 real,
dimension(SZDI_(CS%grid),SZDJ_(CS%grid)) :: &
232 real,
parameter :: vk = 0.40
233 real :: zeta_n = 0.052
235 real,
parameter :: rc = 0.20
242 real,
dimension(SZDI_(CS%grid),SZDJ_(CS%grid)) :: &
245 real :: sbdry1, sbdry2
246 real :: s_a, s_b, s_c
249 real :: hbl_neut_h_molec
265 real :: gam_mol_t, gam_mol_s
269 real :: sb_min, sb_max
270 real :: ds_min, ds_max
272 real :: wb_flux_new, ddwb_dwb_in
273 real :: i_gam_t, i_gam_s
281 logical :: sb_min_set, sb_max_set
282 logical :: update_ice_vel
283 logical :: coupled_gl
286 real,
parameter :: c2_3 = 2.0/3.0
287 character(len=160) :: mesg
288 integer,
dimension(2) :: eosdom
289 integer :: i, j, is, ie, js, je, ied, jed, it1, it3
291 if (.not.
associated(cs))
call mom_error(fatal,
"shelf_calc_flux: "// &
292 "initialize_ice_shelf must be called before shelf_calc_flux.")
293 call cpu_clock_begin(id_clock_shelf)
295 g => cs%grid ; us => cs%US
299 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; ied = g%ied ; jed = g%jed
300 i_zeta_n = 1.0 / zeta_n
301 i_lf = 1.0 / cs%Lat_fusion
302 sc = cs%kv_molec/cs%kd_molec_salt
303 pr = cs%kv_molec/cs%kd_molec_temp
305 rhocp = cs%Rho_ocn * cs%Cp
308 gam_mol_t = 12.5 * (pr**c2_3) - 6.0
309 gam_mol_s = 12.5 * (sc**c2_3) - 6.0
315 exch_vel_t(:,:) = 0.0 ; exch_vel_s(:,:) = 0.0
316 iss%tflux_shelf(:,:) = 0.0 ; iss%water_flux(:,:) = 0.0
317 iss%salt_flux(:,:) = 0.0 ; iss%tflux_ocn(:,:) = 0.0 ; iss%tfreeze(:,:) = 0.0
319 haline_driving(:,:) = 0.0
320 sbdry(:,:) = sfc_state%sss(:,:)
325 if (cs%override_shelf_movement)
then 326 cs%time_step = time_step
328 if (cs%mass_from_file)
call update_shelf_mass(g, us, cs, iss, time)
332 call hchksum(fluxes%frac_shelf_h,
"frac_shelf_h before apply melting", g%HI, haloshift=0)
333 call hchksum(sfc_state%sst,
"sst before apply melting", g%HI, haloshift=0)
334 call hchksum(sfc_state%sss,
"sss before apply melting", g%HI, haloshift=0)
335 call hchksum(sfc_state%u,
"u_ml before apply melting", g%HI, haloshift=0, scale=us%L_T_to_m_s)
336 call hchksum(sfc_state%v,
"v_ml before apply melting", g%HI, haloshift=0, scale=us%L_T_to_m_s)
337 call hchksum(sfc_state%ocean_mass,
"ocean_mass before apply melting", g%HI, haloshift=0, &
338 scale=us%RZ_to_kg_m2)
342 if (
allocated(sfc_state%taux_shelf) .and.
allocated(sfc_state%tauy_shelf))
then 343 call pass_vector(sfc_state%taux_shelf, sfc_state%tauy_shelf, g%domain, to_all, cgrid_ne)
345 irho0 = us%Z_to_L / cs%Rho_ocn
346 do j=js,je ;
do i=is,ie ;
if (fluxes%frac_shelf_h(i,j) > 0.0)
then 347 taux2 = 0.0 ; tauy2 = 0.0 ; u2_av = 0.0 ; v2_av = 0.0
348 asu1 = (iss%area_shelf_h(i-1,j) + iss%area_shelf_h(i,j))
349 asu2 = (iss%area_shelf_h(i,j) + iss%area_shelf_h(i+1,j))
350 asv1 = (iss%area_shelf_h(i,j-1) + iss%area_shelf_h(i,j))
351 asv2 = (iss%area_shelf_h(i,j) + iss%area_shelf_h(i,j+1))
352 i_au = 0.0 ;
if (asu1 + asu2 > 0.0) i_au = 1.0 / (asu1 + asu2)
353 i_av = 0.0 ;
if (asv1 + asv2 > 0.0) i_av = 1.0 / (asv1 + asv2)
354 if (
allocated(sfc_state%taux_shelf) .and.
allocated(sfc_state%tauy_shelf))
then 355 taux2 = (asu1 * sfc_state%taux_shelf(i-1,j)**2 + asu2 * sfc_state%taux_shelf(i,j)**2 ) * i_au
356 tauy2 = (asv1 * sfc_state%tauy_shelf(i,j-1)**2 + asv2 * sfc_state%tauy_shelf(i,j)**2 ) * i_av
358 u2_av = (asu1 * sfc_state%u(i-1,j)**2 + asu2 * sfc_state%u(i,j)**2) * i_au
359 v2_av = (asv1 * sfc_state%v(i,j-1)**2 + asu2 * sfc_state%v(i,j)**2) * i_av
361 if (taux2 + tauy2 > 0.0)
then 362 fluxes%ustar_shelf(i,j) = max(cs%ustar_bg, us%L_to_Z * &
363 sqrt(irho0 * sqrt(taux2 + tauy2) + cs%cdrag*cs%utide(i,j)**2))
365 fluxes%ustar_shelf(i,j) = max(cs%ustar_bg, us%L_TO_Z * &
366 sqrt(cs%cdrag*((u2_av + v2_av) + cs%utide(i,j)**2)))
369 fluxes%ustar_shelf(i,j) = 0.0
370 endif ;
enddo ;
enddo 372 eosdom(:) = eos_domain(g%HI)
376 do i=is,ie ; p_int(i) = cs%g_Earth * iss%mass_shelf(i,j) ;
enddo 379 call calculate_density(sfc_state%sst(:,j), sfc_state%sss(:,j), p_int, rhoml(:), &
380 cs%eqn_of_state, eosdom)
382 cs%eqn_of_state, eosdom)
385 if ((sfc_state%ocean_mass(i,j) > cs%col_mass_melt_threshold) .and. &
386 (iss%area_shelf_h(i,j) > 0.0) .and. cs%isthermo)
then 393 ustar_h = fluxes%ustar_shelf(i,j)
397 absf = 0.25*((abs(g%CoriolisBu(i,j)) + abs(g%CoriolisBu(i-1,j-1))) + &
398 (abs(g%CoriolisBu(i,j-1)) + abs(g%CoriolisBu(i-1,j))))
399 if (absf*sfc_state%Hml(i,j) <= vk*ustar_h)
then ; hbl_neut = sfc_state%Hml(i,j)
400 else ; hbl_neut = (vk*ustar_h) / absf ;
endif 401 hbl_neut_h_molec = zeta_n * ((hbl_neut * ustar_h) / (5.0 * cs%kv_molec))
404 db_ds = (us%L_to_Z**2*cs%g_Earth / rhoml(i)) * dr0_ds(i)
405 db_dt = (us%L_to_Z**2*cs%g_Earth / rhoml(i)) * dr0_dt(i)
406 ln_neut = 0.0 ;
if (hbl_neut_h_molec > 1.0) ln_neut = log(hbl_neut_h_molec)
408 if (cs%find_salt_root)
then 415 s_a = cs%dTFr_dS * cs%Gamma_T_3EQ * cs%Cp
416 s_b = cs%Gamma_T_3EQ*cs%Cp*(cs%TFr_0_0 + cs%dTFr_dp*p_int(i) - sfc_state%sst(i,j)) - &
417 cs%Lat_fusion * cs%Gamma_S_3EQ
418 s_c = cs%Lat_fusion * cs%Gamma_S_3EQ * sfc_state%sss(i,j)
422 elseif (s_a < 0.0)
then 424 sbdry(i,j) = 2.0*s_c / (-s_b + sqrt(s_b*s_b - 4.*s_a*s_c))
426 sbdry(i,j) = (s_b + sqrt(s_b*s_b - 4.*s_a*s_c)) / (-2.*s_a)
428 elseif ((s_a == 0.0) .and. (s_b < 0.0))
then 429 sbdry(i,j) = -s_c / s_b
431 call mom_error(fatal,
"Impossible conditions found in 3-equation skin salinity calculation.")
435 if (sbdry(i,j) < 0.)
then 436 write(mesg,*)
'sfc_state%sss(i,j) = ',sfc_state%sss(i,j),
'S_a, S_b, S_c', s_a, s_b, s_c
437 call mom_error(warning, mesg, .true.)
438 write(mesg,*)
'I,J,Sbdry1,Sbdry2',i,j,sbdry1,sbdry2
439 call mom_error(warning, mesg, .true.)
440 call mom_error(fatal,
"shelf_calc_flux: Negative salinity (Sbdry).")
444 sbdry(i,j) = sfc_state%sss(i,j) ; sb_max_set = .false.
450 call calculate_tfreeze(sbdry(i,j), p_int(i), iss%tfreeze(i,j), cs%eqn_of_state, &
451 pres_scale=us%RL2_T2_to_Pa)
453 dt_ustar = (iss%tfreeze(i,j) - sfc_state%sst(i,j)) * ustar_h
454 ds_ustar = (sbdry(i,j) - sfc_state%sss(i,j)) * ustar_h
460 if (cs%const_gamma)
then 462 i_gam_t = cs%Gamma_T_3EQ
463 i_gam_s = cs%Gamma_S_3EQ
465 gam_turb = i_vk * (ln_neut + (0.5 * i_zeta_n - 1.0))
466 i_gam_t = 1.0 / (gam_mol_t + gam_turb)
467 i_gam_s = 1.0 / (gam_mol_s + gam_turb)
470 wt_flux = dt_ustar * i_gam_t
471 wb_flux = db_ds * (ds_ustar * i_gam_s) + db_dt * wt_flux
473 if (wb_flux < 0.0)
then 476 n_star_term = (zeta_n/rc) * (hbl_neut * vk) / (ustar_h)**3
482 i_n_star = sqrt(1.0 - n_star_term * wb_flux)
483 dins_dwb = 0.5 * n_star_term / i_n_star
484 if (hbl_neut_h_molec > i_n_star**2)
then 485 gam_turb = i_vk * ((ln_neut - 2.0*log(i_n_star)) + &
486 (0.5*i_zeta_n*i_n_star - 1.0))
487 dg_dwb = i_vk * ( -2.0 / i_n_star + (0.5 * i_zeta_n)) * dins_dwb
491 gam_turb = i_vk * (0.5 * i_zeta_n*i_n_star - 1.0)
492 dg_dwb = i_vk * (0.5 * i_zeta_n) * dins_dwb
495 if (cs%const_gamma)
then 497 i_gam_t = cs%Gamma_T_3EQ
498 i_gam_s = cs%Gamma_S_3EQ
500 i_gam_t = 1.0 / (gam_mol_t + gam_turb)
501 i_gam_s = 1.0 / (gam_mol_s + gam_turb)
504 wt_flux = dt_ustar * i_gam_t
505 wb_flux_new = db_ds * (ds_ustar * i_gam_s) + db_dt * wt_flux
508 if (abs(wb_flux_new - wb_flux) < 1.0e-4*(abs(wb_flux_new) + abs(wb_flux)))
exit 510 ddwb_dwb_in = dg_dwb * (db_ds * (ds_ustar * i_gam_s**2) + &
511 db_dt * (dt_ustar * i_gam_t**2)) - 1.0
513 wb_flux_new = wb_flux - (wb_flux_new - wb_flux) / ddwb_dwb_in
517 iss%tflux_ocn(i,j) = rhocp * wt_flux
518 exch_vel_t(i,j) = ustar_h * i_gam_t
519 exch_vel_s(i,j) = ustar_h * i_gam_s
528 if (iss%tflux_ocn(i,j) >= 0.0)
then 530 iss%water_flux(i,j) = -i_lf * iss%tflux_ocn(i,j)
531 iss%tflux_shelf(i,j) = 0.0
533 if (cs%insulator)
then 535 iss%tflux_shelf(i,j) = 0.0
536 iss%water_flux(i,j) = i_lf * (iss%tflux_shelf(i,j) - iss%tflux_ocn(i,j))
543 iss%water_flux(i,j) = -iss%tflux_ocn(i,j) / &
544 (cs%Lat_fusion + cs%Cp_ice * (iss%tfreeze(i,j) - cs%Temp_Ice))
546 iss%tflux_shelf(i,j) = iss%tflux_ocn(i,j) + cs%Lat_fusion*iss%water_flux(i,j)
555 if (cs%find_salt_root)
then 559 mass_exch = exch_vel_s(i,j) * cs%Rho_ocn
560 sbdry_it = (sfc_state%sss(i,j) * mass_exch + cs%Salin_ice * iss%water_flux(i,j)) / &
561 (mass_exch + iss%water_flux(i,j))
562 ds_it = sbdry_it - sbdry(i,j)
563 if (abs(ds_it) < 1.0e-4*(0.5*(sfc_state%sss(i,j) + sbdry(i,j) + 1.0e-10)))
exit 566 if (ds_it < 0.0)
then 567 if (sb_max_set .and. (sbdry(i,j) > sb_max)) &
568 call mom_error(fatal,
"shelf_calc_flux: Irregular iteration for Sbdry (max).")
569 sb_max = sbdry(i,j) ; ds_max = ds_it ; sb_max_set = .true.
571 if (sb_min_set .and. (sbdry(i,j) < sb_min)) &
572 call mom_error(fatal,
"shelf_calc_flux: Irregular iteration for Sbdry (min).")
573 sb_min = sbdry(i,j) ; ds_min = ds_it ; sb_min_set = .true.
576 if (sb_min_set .and. sb_max_set)
then 578 sbdry(i,j) = sb_min + (sb_max-sb_min) * (ds_min / (ds_min - ds_max))
580 sbdry(i,j) = sbdry_it
583 sbdry(i,j) = sbdry_it
594 call calculate_tfreeze(sfc_state%sss(i,j), p_int(i), iss%tfreeze(i,j), cs%eqn_of_state, &
595 pres_scale=us%RL2_T2_to_Pa)
597 exch_vel_t(i,j) = cs%gamma_t
598 iss%tflux_ocn(i,j) = rhocp * exch_vel_t(i,j) * (iss%tfreeze(i,j) - sfc_state%sst(i,j))
599 iss%tflux_shelf(i,j) = 0.0
600 iss%water_flux(i,j) = -i_lf * iss%tflux_ocn(i,j)
603 elseif (iss%area_shelf_h(i,j) > 0.0)
then 604 iss%tflux_ocn(i,j) = 0.0
606 iss%tflux_ocn(i,j) = 0.0
615 do j=js,je ;
do i=is,ie
617 fluxes%iceshelf_melt(i,j) = iss%water_flux(i,j) * cs%flux_factor
619 if ((sfc_state%ocean_mass(i,j) > cs%col_mass_melt_threshold) .and. &
620 (iss%area_shelf_h(i,j) > 0.0) .and. (cs%isthermo))
then 624 if (iss%mass_shelf(i,j) < cs%Rho_ocn*cs%cutoff_depth)
then 625 iss%water_flux(i,j) = 0.0
626 fluxes%iceshelf_melt(i,j) = 0.0
629 haline_driving(i,j) = (iss%water_flux(i,j) * sbdry(i,j)) / (cs%Rho_ocn * exch_vel_s(i,j))
645 if ((abs(fluxes%iceshelf_melt(i,j))>0.0) .and. (fluxes%ustar_shelf(i,j) == 0.0))
then 646 write(mesg,*)
"|melt| = ",fluxes%iceshelf_melt(i,j),
" > 0 and ustar_shelf = 0. at i,j", i, j
647 call mom_error(fatal,
"shelf_calc_flux: "//trim(mesg))
650 elseif (iss%area_shelf_h(i,j) > 0.0)
then 652 haline_driving(i,j) = 0.0
653 iss%water_flux(i,j) = 0.0
654 fluxes%iceshelf_melt(i,j) = 0.0
658 mass_flux(i,j) = iss%water_flux(i,j) * iss%area_shelf_h(i,j)
661 if (cs%active_shelf_dynamics .or. cs%override_shelf_movement)
then 662 call cpu_clock_begin(id_clock_pass)
663 call pass_var(iss%area_shelf_h, g%domain, complete=.false.)
664 call pass_var(iss%mass_shelf, g%domain)
665 call cpu_clock_end(id_clock_pass)
669 if ( cs%override_shelf_movement .and. (.not.cs%mass_from_file))
then 670 call change_thickness_using_melt(iss, g, us, us%s_to_T*time_step, fluxes, cs%density_ice, cs%debug)
673 call hchksum(iss%h_shelf,
"h_shelf after change thickness using melt", g%HI, haloshift=0, scale=us%Z_to_m)
674 call hchksum(iss%mass_shelf,
"mass_shelf after change thickness using melt", g%HI, haloshift=0, &
675 scale=us%RZ_to_kg_m2)
679 if (cs%debug)
call mom_forcing_chksum(
"Before add shelf flux", fluxes, g, cs%US, haloshift=0)
681 call add_shelf_flux(g, us, cs, sfc_state, fluxes)
685 if (cs%active_shelf_dynamics)
then 686 update_ice_vel = .false.
687 coupled_gl = (cs%GL_couple .and. .not.cs%solo_ice_sheet)
691 call update_ice_shelf(cs%dCS, iss, g, us, us%s_to_T*time_step, time, &
692 sfc_state%ocean_mass, coupled_gl)
696 call enable_averaging(time_step,time,cs%diag)
697 if (cs%id_shelf_mass > 0)
call post_data(cs%id_shelf_mass, iss%mass_shelf, cs%diag)
698 if (cs%id_area_shelf_h > 0)
call post_data(cs%id_area_shelf_h, iss%area_shelf_h, cs%diag)
699 if (cs%id_ustar_shelf > 0)
call post_data(cs%id_ustar_shelf, fluxes%ustar_shelf, cs%diag)
700 if (cs%id_melt > 0)
call post_data(cs%id_melt, fluxes%iceshelf_melt, cs%diag)
701 if (cs%id_thermal_driving > 0)
call post_data(cs%id_thermal_driving, (sfc_state%sst-iss%tfreeze), cs%diag)
702 if (cs%id_Sbdry > 0)
call post_data(cs%id_Sbdry, sbdry, cs%diag)
703 if (cs%id_haline_driving > 0)
call post_data(cs%id_haline_driving, haline_driving, cs%diag)
704 if (cs%id_mass_flux > 0)
call post_data(cs%id_mass_flux, mass_flux, cs%diag)
705 if (cs%id_u_ml > 0)
call post_data(cs%id_u_ml, sfc_state%u, cs%diag)
706 if (cs%id_v_ml > 0)
call post_data(cs%id_v_ml, sfc_state%v, cs%diag)
707 if (cs%id_tfreeze > 0)
call post_data(cs%id_tfreeze, iss%tfreeze, cs%diag)
708 if (cs%id_tfl_shelf > 0)
call post_data(cs%id_tfl_shelf, iss%tflux_shelf, cs%diag)
709 if (cs%id_exch_vel_t > 0)
call post_data(cs%id_exch_vel_t, exch_vel_t, cs%diag)
710 if (cs%id_exch_vel_s > 0)
call post_data(cs%id_exch_vel_s, exch_vel_s, cs%diag)
711 if (cs%id_h_shelf > 0)
call post_data(cs%id_h_shelf, iss%h_shelf, cs%diag)
712 if (cs%id_h_mask > 0)
call post_data(cs%id_h_mask,iss%hmask,cs%diag)
713 call disable_averaging(cs%diag)
715 if (
present(forces))
then 716 call add_shelf_forces(g, us, cs, forces, do_shelf_area=(cs%active_shelf_dynamics .or. &
717 cs%override_shelf_movement))
720 call cpu_clock_end(id_clock_shelf)
722 if (cs%debug)
call mom_forcing_chksum(
"End of shelf calc flux", fluxes, g, cs%US, haloshift=0)
724 end subroutine shelf_calc_flux
727 subroutine change_thickness_using_melt(ISS, G, US, time_step, fluxes, density_ice, debug)
728 type(ocean_grid_type),
intent(inout) :: G
729 type(ice_shelf_state),
intent(inout) :: ISS
731 type(unit_scale_type),
intent(in) :: US
732 real,
intent(in) :: time_step
733 type(forcing),
intent(inout) :: fluxes
735 real,
intent(in) :: density_ice
736 logical,
optional,
intent(in) :: debug
742 i_rho_ice = 1.0 / density_ice
745 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
746 if ((iss%hmask(i,j) == 1) .or. (iss%hmask(i,j) == 2))
then 748 if (
associated(fluxes%lprec)) fluxes%lprec(i,j) = 0.0
749 if (
associated(fluxes%sens)) fluxes%sens(i,j) = 0.0
750 if (
associated(fluxes%frac_shelf_h)) fluxes%frac_shelf_h(i,j) = 0.0
751 if (
associated(fluxes%salt_flux)) fluxes%salt_flux(i,j) = 0.0
753 if (iss%water_flux(i,j) * time_step / density_ice < iss%h_shelf(i,j))
then 754 iss%h_shelf(i,j) = iss%h_shelf(i,j) - iss%water_flux(i,j) * time_step / density_ice
758 iss%h_shelf(i,j) = 0.0
760 iss%area_shelf_h(i,j) = 0.0
762 iss%mass_shelf(i,j) = iss%h_shelf(i,j) * density_ice
766 call pass_var(iss%area_shelf_h, g%domain)
767 call pass_var(iss%h_shelf, g%domain)
769 call pass_var(iss%mass_shelf, g%domain)
771 end subroutine change_thickness_using_melt
775 subroutine add_shelf_forces(G, US, CS, forces, do_shelf_area)
780 logical,
optional,
intent(in) :: do_shelf_area
788 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
789 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
790 isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
792 if ((cs%grid%isc /= g%isc) .or. (cs%grid%iec /= g%iec) .or. &
793 (cs%grid%jsc /= g%jsc) .or. (cs%grid%jec /= g%jec)) &
794 call mom_error(fatal,
"add_shelf_forces: Incompatible ocean and ice shelf grids.")
798 find_area = .true. ;
if (
present(do_shelf_area)) find_area = do_shelf_area
802 do j=jsd,jed ;
do i=isd,ied-1
803 forces%frac_shelf_u(i,j) = 0.0
804 if ((g%areaT(i,j) + g%areaT(i+1,j) > 0.0)) &
805 forces%frac_shelf_u(i,j) = (iss%area_shelf_h(i,j) + iss%area_shelf_h(i+1,j)) / &
806 (g%areaT(i,j) + g%areaT(i+1,j))
808 do j=jsd,jed-1 ;
do i=isd,ied
809 forces%frac_shelf_v(i,j) = 0.0
810 if ((g%areaT(i,j) + g%areaT(i,j+1) > 0.0)) &
811 forces%frac_shelf_v(i,j) = (iss%area_shelf_h(i,j) + iss%area_shelf_h(i,j+1)) / &
812 (g%areaT(i,j) + g%areaT(i,j+1))
814 call pass_vector(forces%frac_shelf_u, forces%frac_shelf_v, g%domain, to_all, cgrid_ne)
817 do j=js,je ;
do i=is,ie
818 press_ice = (iss%area_shelf_h(i,j) * g%IareaT(i,j)) * (cs%g_Earth * iss%mass_shelf(i,j))
819 if (
associated(forces%p_surf))
then 820 if (.not.forces%accumulate_p_surf) forces%p_surf(i,j) = 0.0
821 forces%p_surf(i,j) = forces%p_surf(i,j) + press_ice
823 if (
associated(forces%p_surf_full))
then 824 if (.not.forces%accumulate_p_surf) forces%p_surf_full(i,j) = 0.0
825 forces%p_surf_full(i,j) = forces%p_surf_full(i,j) + press_ice
833 kv_rho_ice = cs%kv_ice / cs%density_ice
834 do j=js,je ;
do i=is-1,ie
835 if (.not.forces%accumulate_rigidity) forces%rigidity_ice_u(i,j) = 0.0
836 forces%rigidity_ice_u(i,j) = forces%rigidity_ice_u(i,j) + &
837 kv_rho_ice * min(iss%mass_shelf(i,j), iss%mass_shelf(i+1,j))
839 do j=js-1,je ;
do i=is,ie
840 if (.not.forces%accumulate_rigidity) forces%rigidity_ice_v(i,j) = 0.0
841 forces%rigidity_ice_v(i,j) = forces%rigidity_ice_v(i,j) + &
842 kv_rho_ice * min(iss%mass_shelf(i,j), iss%mass_shelf(i,j+1))
846 call uvchksum(
"rigidity_ice_[uv]", forces%rigidity_ice_u, forces%rigidity_ice_v, &
847 g%HI, symmetric=.true., scale=us%L_to_m**3*us%L_to_Z*us%s_to_T)
848 call uvchksum(
"frac_shelf_[uv]", forces%frac_shelf_u, forces%frac_shelf_v, &
849 g%HI, symmetric=.true.)
852 end subroutine add_shelf_forces
855 subroutine add_shelf_pressure(G, US, CS, fluxes)
856 type(ocean_grid_type),
intent(inout) :: G
857 type(unit_scale_type),
intent(in) :: US
858 type(ice_shelf_CS),
intent(in) :: CS
859 type(forcing),
intent(inout) :: fluxes
862 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
863 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
865 if ((cs%grid%isc /= g%isc) .or. (cs%grid%iec /= g%iec) .or. &
866 (cs%grid%jsc /= g%jsc) .or. (cs%grid%jec /= g%jec)) &
867 call mom_error(fatal,
"add_shelf_pressure: Incompatible ocean and ice shelf grids.")
869 do j=js,je ;
do i=is,ie
870 press_ice = (cs%ISS%area_shelf_h(i,j) * g%IareaT(i,j)) * (cs%g_Earth * cs%ISS%mass_shelf(i,j))
871 if (
associated(fluxes%p_surf))
then 872 if (.not.fluxes%accumulate_p_surf) fluxes%p_surf(i,j) = 0.0
873 fluxes%p_surf(i,j) = fluxes%p_surf(i,j) + press_ice
875 if (
associated(fluxes%p_surf_full))
then 876 if (.not.fluxes%accumulate_p_surf) fluxes%p_surf_full(i,j) = 0.0
877 fluxes%p_surf_full(i,j) = fluxes%p_surf_full(i,j) + press_ice
881 end subroutine add_shelf_pressure
884 subroutine add_shelf_flux(G, US, CS, sfc_state, fluxes)
888 type(
surface),
intent(inout) :: sfc_state
889 type(
forcing),
intent(inout) :: fluxes
894 real :: delta_mass_shelf
895 real :: balancing_flux
896 real :: balancing_area
897 type(time_type) :: dtime
898 type(time_type) :: time0
899 real,
dimension(SZDI_(G),SZDJ_(G)) :: bal_frac
901 real,
dimension(SZDI_(G),SZDJ_(G)) :: last_mass_shelf
903 real,
dimension(SZDI_(G),SZDJ_(G)) :: delta_float_mass
905 real,
dimension(SZDI_(G),SZDJ_(G)) :: last_h_shelf
907 real,
dimension(SZDI_(G),SZDJ_(G)) :: last_hmask
909 real,
dimension(SZDI_(G),SZDJ_(G)) :: last_area_shelf_h
914 character(len=160) :: mesg
915 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
916 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
917 isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
919 if ((cs%grid%isc /= g%isc) .or. (cs%grid%iec /= g%iec) .or. &
920 (cs%grid%jsc /= g%jsc) .or. (cs%grid%jec /= g%jec)) &
921 call mom_error(fatal,
"add_shelf_flux: Incompatible ocean and ice shelf grids.")
926 call add_shelf_pressure(g, us, cs, fluxes)
933 if (
allocated(sfc_state%taux_shelf) .and.
allocated(sfc_state%tauy_shelf))
then 934 call uvchksum(
"tau[xy]_shelf", sfc_state%taux_shelf, sfc_state%tauy_shelf, &
935 g%HI, haloshift=0, scale=us%RZ_T_to_kg_m2s*us%L_T_to_m_s)
939 if (cs%active_shelf_dynamics .or. cs%override_shelf_movement)
then 940 do j=jsd,jed ;
do i=isd,ied
941 if (g%areaT(i,j) > 0.0) &
942 fluxes%frac_shelf_h(i,j) = min(1.0, iss%area_shelf_h(i,j) * g%IareaT(i,j))
947 call mom_forcing_chksum(
"Before adding shelf fluxes", fluxes, g, cs%US, haloshift=0)
950 do j=js,je ;
do i=is,ie ;
if (iss%area_shelf_h(i,j) > 0.0)
then 952 frac_shelf = min(1.0, iss%area_shelf_h(i,j) * g%IareaT(i,j))
953 frac_open = max(0.0, 1.0 - frac_shelf)
955 if (
associated(fluxes%sw)) fluxes%sw(i,j) = frac_open * fluxes%sw(i,j)
956 if (
associated(fluxes%sw_vis_dir)) fluxes%sw_vis_dir(i,j) = frac_open * fluxes%sw_vis_dir(i,j)
957 if (
associated(fluxes%sw_vis_dif)) fluxes%sw_vis_dif(i,j) = frac_open * fluxes%sw_vis_dif(i,j)
958 if (
associated(fluxes%sw_nir_dir)) fluxes%sw_nir_dir(i,j) = frac_open * fluxes%sw_nir_dir(i,j)
959 if (
associated(fluxes%sw_nir_dif)) fluxes%sw_nir_dif(i,j) = frac_open * fluxes%sw_nir_dif(i,j)
960 if (
associated(fluxes%lw)) fluxes%lw(i,j) = frac_open * fluxes%lw(i,j)
961 if (
associated(fluxes%latent)) fluxes%latent(i,j) = frac_open * fluxes%latent(i,j)
962 if (
associated(fluxes%evap)) fluxes%evap(i,j) = frac_open * fluxes%evap(i,j)
963 if (
associated(fluxes%lprec))
then 964 if (iss%water_flux(i,j) > 0.0)
then 965 fluxes%lprec(i,j) = frac_shelf*iss%water_flux(i,j)*cs%flux_factor + frac_open * fluxes%lprec(i,j)
967 fluxes%lprec(i,j) = frac_open * fluxes%lprec(i,j)
968 fluxes%evap(i,j) = fluxes%evap(i,j) + frac_shelf*iss%water_flux(i,j)*cs%flux_factor
972 if (
associated(fluxes%sens)) &
973 fluxes%sens(i,j) = frac_shelf*iss%tflux_ocn(i,j)*cs%flux_factor + frac_open * fluxes%sens(i,j)
975 if (
associated(fluxes%salt_flux)) &
976 fluxes%salt_flux(i,j) = frac_shelf * iss%salt_flux(i,j)*cs%flux_factor + frac_open * fluxes%salt_flux(i,j)
977 endif ;
enddo ;
enddo 980 call hchksum(iss%water_flux,
"water_flux add shelf fluxes", g%HI, haloshift=0, scale=us%RZ_T_to_kg_m2s)
981 call hchksum(iss%tflux_ocn,
"tflux_ocn add shelf fluxes", g%HI, haloshift=0, scale=us%QRZ_T_to_W_m2)
982 call mom_forcing_chksum(
"After adding shelf fluxes", fluxes, g, cs%US, haloshift=0)
990 if (cs%constant_sea_level)
then 991 if (.not.
associated(fluxes%salt_flux))
allocate(fluxes%salt_flux(ie,je))
992 if (.not.
associated(fluxes%vprec))
allocate(fluxes%vprec(ie,je))
993 fluxes%salt_flux(:,:) = 0.0 ; fluxes%vprec(:,:) = 0.0
996 if (cs%override_shelf_movement .and. cs%mass_from_file)
then 997 dtime = real_to_time(cs%time_step)
1000 if (cs%Time > dtime)
then 1001 time0 = cs%Time - dtime
1002 do j=js,je ;
do i=is,ie
1003 last_hmask(i,j) = iss%hmask(i,j) ; last_area_shelf_h(i,j) = iss%area_shelf_h(i,j)
1005 call time_interp_external(cs%id_read_mass, time0, last_mass_shelf)
1006 do j=js,je ;
do i=is,ie
1008 last_mass_shelf(i,j) = us%kg_m3_to_R*us%m_to_Z * last_mass_shelf(i,j)
1009 last_h_shelf(i,j) = last_mass_shelf(i,j) / cs%density_ice
1013 if (cs%min_thickness_simple_calve > 0.0)
then 1014 call ice_shelf_min_thickness_calve(g, last_h_shelf, last_area_shelf_h, last_hmask, &
1015 cs%min_thickness_simple_calve, halo=0)
1017 do j=js,je ;
do i=is,ie
1018 last_mass_shelf(i,j) = last_h_shelf(i,j) * cs%density_ice
1023 do j=js,je ;
do i=is,ie
1025 if ((sfc_state%ocean_mass(i,j) > cs%min_ocean_mass_float) .and. &
1026 (iss%area_shelf_h(i,j) > 0.0))
then 1027 delta_float_mass(i,j) = iss%mass_shelf(i,j) - last_mass_shelf(i,j)
1029 delta_float_mass(i,j) = 0.0
1032 delta_mass_shelf = us%kg_m2s_to_RZ_T*(global_area_integral(delta_float_mass, g, scale=us%RZ_to_kg_m2, &
1033 area=iss%area_shelf_h) / cs%time_step)
1035 delta_mass_shelf = 0.0
1038 delta_mass_shelf = 0.0
1042 do j=js,je ;
do i=is,ie
1043 if ((g%mask2dT(i,j) > 0.0) .AND. (iss%area_shelf_h(i,j) * g%IareaT(i,j) < 1.0))
then 1046 bal_frac(i,j) = max(1.0 - iss%area_shelf_h(i,j) * g%IareaT(i,j), 0.0)
1052 balancing_area = global_area_integral(bal_frac, g)
1053 if (balancing_area > 0.0)
then 1054 balancing_flux = ( us%kg_m2s_to_RZ_T*global_area_integral(iss%water_flux, g, scale=us%RZ_T_to_kg_m2s, &
1055 area=iss%area_shelf_h) + &
1056 delta_mass_shelf ) / balancing_area
1058 balancing_flux = 0.0
1062 do j=js,je ;
do i=is,ie
1063 if (bal_frac(i,j) > 0.0)
then 1065 fluxes%vprec(i,j) = -balancing_flux
1066 fluxes%sens(i,j) = fluxes%vprec(i,j) * cs%Cp * cs%T0
1067 fluxes%salt_flux(i,j) = fluxes%vprec(i,j) * cs%S0*1.0e-3
1072 write(mesg,*)
'Balancing flux (kg/(m^2 s)), dt = ', balancing_flux*us%RZ_T_to_kg_m2s, cs%time_step
1074 call mom_forcing_chksum(
"After constant sea level", fluxes, g, cs%US, haloshift=0)
1079 end subroutine add_shelf_flux
1083 subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces, fluxes, Time_in, solo_ice_sheet_in)
1086 type(time_type),
intent(inout) :: time
1088 type(
diag_ctrl),
target,
intent(in) :: diag
1089 type(
forcing),
optional,
intent(inout) :: fluxes
1092 type(time_type),
optional,
intent(in) :: time_in
1093 logical,
optional,
intent(in) :: solo_ice_sheet_in
1109 real :: meltrate_conversion
1110 real :: dz_ocean_min_float
1112 real :: cdrag, drag_bg_vel
1113 logical :: new_sim, save_ic, var_force
1115 # include "version_variable.h" 1116 character(len=200) :: config
1117 character(len=200) :: ic_file,filename,inputdir
1118 character(len=40) :: mdl =
"MOM_ice_shelf" 1119 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed, isdq, iedq, jsdq, jedq
1120 integer :: wd_halos(2)
1121 logical :: read_tideamp, shelf_mass_is_dynamic, debug
1122 character(len=240) :: tideamp_file
1124 real :: col_thick_melt_thresh
1126 if (
associated(cs))
then 1127 call mom_error(fatal,
"MOM_ice_shelf.F90, initialize_ice_shelf: "// &
1128 "called with an associated control structure.")
1136 call get_mom_input(dirs=dirs)
1139 call unit_scaling_init(param_file, cs%US)
1143 call mom_domains_init(cs%grid%domain, param_file, min_halo=wd_halos, symmetric=grid_sym_)
1146 call mom_grid_init(cs%grid, param_file, cs%US)
1148 call create_dyn_horgrid(dg, cs%grid%HI)
1151 call set_grid_metrics(dg, param_file, cs%US)
1155 if (
associated(ocn_grid))
then ; cs%ocn_grid => ocn_grid
1156 else ; cs%ocn_grid => cs%grid ;
endif 1163 if (is_root_pe())
then 1164 write(0,*)
'OG: ', og%isd, og%isc, og%iec, og%ied, og%jsd, og%jsc, og%jsd, og%jed
1165 write(0,*)
'IG: ', g%isd, g%isc, g%iec, g%ied, g%jsd, g%jsc, g%jsd, g%jed
1172 cs%solo_ice_sheet = .false.
1173 if (
present(solo_ice_sheet_in)) cs%solo_ice_sheet = solo_ice_sheet_in
1175 if (
present(time_in)) time = time_in
1177 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1178 isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
1179 isdq = g%IsdB ; iedq = g%IedB ; jsdq = g%JsdB ; jedq = g%JedB
1181 cs%override_shelf_movement = .false. ; cs%active_shelf_dynamics = .false.
1184 call get_param(param_file, mdl,
"DEBUG", debug, default=.false.)
1185 call get_param(param_file, mdl,
"DEBUG_IS", cs%debug, &
1186 "If true, write verbose debugging messages for the ice shelf.", &
1188 call get_param(param_file, mdl,
"DYNAMIC_SHELF_MASS", shelf_mass_is_dynamic, &
1189 "If true, the ice sheet mass can evolve with time.", &
1191 if (shelf_mass_is_dynamic)
then 1192 call get_param(param_file, mdl,
"OVERRIDE_SHELF_MOVEMENT", cs%override_shelf_movement, &
1193 "If true, user provided code specifies the ice-shelf "//&
1194 "movement instead of the dynamic ice model.", default=.false.)
1195 cs%active_shelf_dynamics = .not.cs%override_shelf_movement
1196 call get_param(param_file, mdl,
"GROUNDING_LINE_INTERPOLATE", cs%GL_regularize, &
1197 "If true, regularize the floatation condition at the "//&
1198 "grounding line as in Goldberg Holland Schoof 2009.", default=.false.)
1199 call get_param(param_file, mdl,
"GROUNDING_LINE_COUPLE", cs%GL_couple, &
1200 "If true, let the floatation condition be determined by "//&
1201 "ocean column thickness. This means that update_OD_ffrac "//&
1202 "will be called. GL_REGULARIZE and GL_COUPLE are exclusive.", &
1203 default=.false., do_not_log=cs%GL_regularize)
1204 if (cs%GL_regularize) cs%GL_couple = .false.
1207 call get_param(param_file, mdl,
"SHELF_THERMO", cs%isthermo, &
1208 "If true, use a thermodynamically interactive ice shelf.", &
1210 call get_param(param_file, mdl,
"LATENT_HEAT_FUSION", cs%Lat_fusion, &
1211 "The latent heat of fusion.", units=
"J/kg", default=hlf, scale=us%J_kg_to_Q)
1212 call get_param(param_file, mdl,
"SHELF_THREE_EQN", cs%threeeq, &
1213 "If true, use the three equation expression of "//&
1214 "consistency to calculate the fluxes at the ice-ocean "//&
1215 "interface.", default=.true.)
1216 call get_param(param_file, mdl,
"SHELF_INSULATOR", cs%insulator, &
1217 "If true, the ice shelf is a perfect insulatior "//&
1218 "(no conduction).", default=.false.)
1219 call get_param(param_file, mdl,
"MELTING_CUTOFF_DEPTH", cs%cutoff_depth, &
1220 "Depth above which the melt is set to zero (it must be >= 0) "//&
1221 "Default value won't affect the solution.", units=
"m", default=0.0, scale=us%m_to_Z)
1222 if (cs%cutoff_depth < 0.) &
1223 call mom_error(warning,
"Initialize_ice_shelf: MELTING_CUTOFF_DEPTH must be >= 0.")
1225 call get_param(param_file, mdl,
"CONST_SEA_LEVEL", cs%constant_sea_level, &
1226 "If true, apply evaporative, heat and salt fluxes in "//&
1227 "the sponge region. This will avoid a large increase "//&
1228 "in sea level. This option is needed for some of the "//&
1229 "ISOMIP+ experiments (Ocean3 and Ocean4). "//&
1230 "IMPORTANT: it is not currently possible to do "//&
1231 "prefect restarts using this flag.", default=.false.)
1232 call get_param(param_file, mdl,
"MIN_OCEAN_FLOAT_THICK", dz_ocean_min_float, &
1233 "The minimum ocean thickness above which the ice shelf is considered to be "//&
1234 "floating when CONST_SEA_LEVEL = True.", &
1235 default=0.1, units=
"m", scale=us%m_to_Z, do_not_log=.not.cs%constant_sea_level)
1237 call get_param(param_file, mdl,
"ISOMIP_S_SUR_SPONGE", cs%S0, &
1238 "Surface salinity in the restoring region.", &
1239 default=33.8, units=
'ppt', do_not_log=.true.)
1241 call get_param(param_file, mdl,
"ISOMIP_T_SUR_SPONGE", cs%T0, &
1242 "Surface temperature in the restoring region.", &
1243 default=-1.9, units=
'degC', do_not_log=.true.)
1245 call get_param(param_file, mdl,
"SHELF_3EQ_GAMMA", cs%const_gamma, &
1246 "If true, user specifies a constant nondimensional heat-transfer coefficient "//&
1247 "(GAMMA_T_3EQ), from which the default salt-transfer coefficient is set "//&
1248 "as GAMMA_T_3EQ/35. This is used with SHELF_THREE_EQN.", default=.false.)
1249 if (cs%threeeq)
then 1250 call get_param(param_file, mdl,
"SHELF_S_ROOT", cs%find_salt_root, &
1251 "If SHELF_S_ROOT = True, salinity at the ice/ocean interface (Sbdry) "//&
1252 "is computed from a quadratic equation. Otherwise, the previous "//&
1253 "interactive method to estimate Sbdry is used.", default=.false.)
1255 call get_param(param_file, mdl,
"SHELF_2EQ_GAMMA_T", cs%gamma_t, &
1256 "If SHELF_THREE_EQN is false, this the fixed turbulent "//&
1257 "exchange velocity at the ice-ocean interface.", &
1258 units=
"m s-1", scale=us%m_to_Z*us%T_to_s, fail_if_missing=.true.)
1260 if (cs%const_gamma .or. cs%find_salt_root)
then 1261 call get_param(param_file, mdl,
"SHELF_3EQ_GAMMA_T", cs%Gamma_T_3EQ, &
1262 "Nondimensional heat-transfer coefficient.", &
1263 units=
"nondim", default=2.2e-2)
1264 call get_param(param_file, mdl,
"SHELF_3EQ_GAMMA_S", cs%Gamma_S_3EQ, &
1265 "Nondimensional salt-transfer coefficient.", &
1266 default=cs%Gamma_T_3EQ/35.0, units=
"nondim")
1269 call get_param(param_file, mdl,
"ICE_SHELF_MASS_FROM_FILE", &
1270 cs%mass_from_file,
"Read the mass of the "//&
1271 "ice shelf (every time step) from a file.", default=.false.)
1273 if (cs%find_salt_root)
then 1274 call get_param(param_file, mdl,
"TFREEZE_S0_P0", cs%TFr_0_0, &
1275 "this is the freezing potential temperature at "//&
1276 "S=0, P=0.", units=
"degC", default=0.0, do_not_log=.true.)
1277 call get_param(param_file, mdl,
"DTFREEZE_DS", cs%dTFr_dS, &
1278 "this is the derivative of the freezing potential temperature with salinity.", &
1279 units=
"degC psu-1", default=-0.054, do_not_log=.true.)
1280 call get_param(param_file, mdl,
"DTFREEZE_DP", cs%dTFr_dp, &
1281 "this is the derivative of the freezing potential temperature with pressure.", &
1282 units=
"degC Pa-1", default=0.0, scale=us%RL2_T2_to_Pa, do_not_log=.true.)
1285 call get_param(param_file, mdl,
"G_EARTH", cs%g_Earth, &
1286 "The gravitational acceleration of the Earth.", &
1287 units=
"m s-2", default = 9.80, scale=us%m_s_to_L_T**2*us%Z_to_m)
1288 call get_param(param_file, mdl,
"C_P", cs%Cp, &
1289 "The heat capacity of sea water, approximated as a constant. "//&
1290 "The default value is from the TEOS-10 definition of conservative temperature.", &
1291 units=
"J kg-1 K-1", default=3991.86795711963, scale=us%J_kg_to_Q)
1292 call get_param(param_file, mdl,
"RHO_0", cs%Rho_ocn, &
1293 "The mean ocean density used with BOUSSINESQ true to "//&
1294 "calculate accelerations and the mass for conservation "//&
1295 "properties, or with BOUSSINSEQ false to convert some "//&
1296 "parameters from vertical units of m to kg m-2.", &
1297 units=
"kg m-3", default=1035.0, scale=us%kg_m3_to_R)
1298 call get_param(param_file, mdl,
"C_P_ICE", cs%Cp_ice, &
1299 "The heat capacity of ice.", units=
"J kg-1 K-1", scale=us%J_kg_to_Q, &
1301 if (cs%constant_sea_level) cs%min_ocean_mass_float = dz_ocean_min_float*cs%Rho_ocn
1303 call get_param(param_file, mdl,
"ICE_SHELF_FLUX_FACTOR", cs%flux_factor, &
1304 "Non-dimensional factor applied to shelf thermodynamic "//&
1305 "fluxes.", units=
"none", default=1.0)
1307 call get_param(param_file, mdl,
"KV_ICE", cs%kv_ice, &
1308 "The viscosity of the ice.", &
1309 units=
"m2 s-1", default=1.0e10, scale=us%Z_to_L**2*us%m_to_L**2*us%T_to_s)
1310 call get_param(param_file, mdl,
"KV_MOLECULAR", cs%kv_molec, &
1311 "The molecular kinimatic viscosity of sea water at the "//&
1312 "freezing temperature.", units=
"m2 s-1", default=1.95e-6, scale=us%m2_s_to_Z2_T)
1313 call get_param(param_file, mdl,
"ICE_SHELF_SALINITY", cs%Salin_ice, &
1314 "The salinity of the ice inside the ice shelf.", units=
"psu", &
1316 call get_param(param_file, mdl,
"ICE_SHELF_TEMPERATURE", cs%Temp_ice, &
1317 "The temperature at the center of the ice shelf.", &
1318 units =
"degC", default=-15.0)
1319 call get_param(param_file, mdl,
"KD_SALT_MOLECULAR", cs%kd_molec_salt, &
1320 "The molecular diffusivity of salt in sea water at the "//&
1321 "freezing point.", units=
"m2 s-1", default=8.02e-10, scale=us%m2_s_to_Z2_T)
1322 call get_param(param_file, mdl,
"KD_TEMP_MOLECULAR", cs%kd_molec_temp, &
1323 "The molecular diffusivity of heat in sea water at the "//&
1324 "freezing point.", units=
"m2 s-1", default=1.41e-7, scale=us%m2_s_to_Z2_T)
1325 call get_param(param_file, mdl,
"DT_FORCING", cs%time_step, &
1326 "The time step for changing forcing, coupling with other "//&
1327 "components, or potentially writing certain diagnostics. "//&
1328 "The default value is given by DT.", units=
"s", default=0.0)
1330 call get_param(param_file, mdl,
"COL_THICK_MELT_THRESHOLD", col_thick_melt_thresh, &
1331 "The minimum ocean column thickness where melting is allowed.", &
1332 units=
"m", scale=us%m_to_Z, default=0.0)
1333 cs%col_mass_melt_threshold = cs%Rho_ocn * col_thick_melt_thresh
1335 call get_param(param_file, mdl,
"READ_TIDEAMP", read_tideamp, &
1336 "If true, read a file (given by TIDEAMP_FILE) containing "//&
1337 "the tidal amplitude with INT_TIDE_DISSIPATION.", default=.false.)
1339 call safe_alloc_ptr(cs%utide,isd,ied,jsd,jed) ; cs%utide(:,:) = 0.0
1341 if (read_tideamp)
then 1342 call get_param(param_file, mdl,
"TIDEAMP_FILE", tideamp_file, &
1343 "The path to the file containing the spatially varying "//&
1344 "tidal amplitudes.", &
1345 default=
"tideamp.nc")
1346 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
1347 inputdir = slasher(inputdir)
1348 tideamp_file = trim(inputdir) // trim(tideamp_file)
1349 call mom_read_data(tideamp_file,
'tideamp', cs%utide, g%domain, timelevel=1, scale=us%m_s_to_L_T)
1351 call get_param(param_file, mdl,
"UTIDE", utide, &
1352 "The constant tidal amplitude used with INT_TIDE_DISSIPATION.", &
1353 units=
"m s-1", default=0.0 , scale=us%m_s_to_L_T)
1354 cs%utide(:,:) = utide
1357 call eos_init(param_file, cs%eqn_of_state)
1361 if (cs%active_shelf_dynamics)
then 1363 call get_param(param_file, mdl,
"DENSITY_ICE", cs%density_ice, &
1364 "A typical density of ice.", units=
"kg m-3", default=917.0, scale=us%kg_m3_to_R)
1366 call get_param(param_file, mdl,
"INPUT_FLUX_ICE_SHELF", cs%input_flux, &
1367 "volume flux at upstream boundary", units=
"m2 s-1", default=0.)
1368 call get_param(param_file, mdl,
"INPUT_THICK_ICE_SHELF", cs%input_thickness, &
1369 "flux thickness at upstream boundary", units=
"m", default=1000.)
1372 call get_param(param_file, mdl,
"DENSITY_ICE", cs%density_ice, &
1373 "A typical density of ice.", units=
"kg m-3", default=900.0, scale=us%kg_m3_to_R)
1375 call get_param(param_file, mdl,
"MIN_THICKNESS_SIMPLE_CALVE", &
1376 cs%min_thickness_simple_calve, &
1377 "Min thickness rule for the very simple calving law",&
1378 units=
"m", default=0.0, scale=us%m_to_Z)
1380 call get_param(param_file, mdl,
"USTAR_SHELF_BG", cs%ustar_bg, &
1381 "The minimum value of ustar under ice shelves.", &
1382 units=
"m s-1", default=0.0, scale=us%m_to_Z*us%T_to_s)
1383 call get_param(param_file, mdl,
"CDRAG_SHELF", cdrag, &
1384 "CDRAG is the drag coefficient relating the magnitude of "//&
1385 "the velocity field to the surface stress.", units=
"nondim", &
1388 if (cs%ustar_bg <= 0.0)
then 1389 call get_param(param_file, mdl,
"DRAG_BG_VEL_SHELF", drag_bg_vel, &
1390 "DRAG_BG_VEL is either the assumed bottom velocity (with "//&
1391 "LINEAR_DRAG) or an unresolved velocity that is "//&
1392 "combined with the resolved velocity to estimate the "//&
1393 "velocity magnitude.", units=
"m s-1", default=0.0, scale=us%m_to_Z*us%T_to_s)
1394 if (cs%cdrag*drag_bg_vel > 0.0) cs%ustar_bg = sqrt(cs%cdrag)*drag_bg_vel
1398 call ice_shelf_state_init(cs%ISS, cs%grid)
1402 if (.not. cs%solo_ice_sheet)
then 1403 call mom_mesg(
"MOM_ice_shelf.F90, initialize_ice_shelf: allocating fluxes.")
1407 if (
present(fluxes)) &
1409 press=.true., water=cs%isthermo, heat=cs%isthermo)
1410 if (
present(forces)) &
1413 call mom_mesg(
"MOM_ice_shelf.F90, initialize_ice_shelf: allocating fluxes in solo mode.")
1414 if (
present(fluxes)) &
1416 if (
present(forces)) &
1421 call mom_initialize_topography(dg%bathyT, g%max_depth, dg, param_file)
1422 call rescale_dyn_horgrid_bathymetry(dg, us%Z_to_m)
1425 call mom_initialize_rotation(dg%CoriolisBu, dg, param_file, us)
1427 call copy_dyngrid_to_mom_grid(dg, cs%grid, us)
1429 call destroy_dyn_horgrid(dg)
1432 call restart_init(param_file, cs%restart_CSp,
"Shelf.res")
1434 "Ice shelf mass",
"kg m-2")
1436 "Ice shelf area in cell",
"m2")
1438 "ice sheet/shelf thickness",
"m")
1440 "Height unit conversion factor",
"Z meter-1")
1442 "Length unit conversion factor",
"L meter-1")
1444 "Density unit conversion factor",
"R m3 kg-1")
1445 if (cs%active_shelf_dynamics)
then 1447 "ice sheet/shelf thickness mask" ,
"none")
1450 if (cs%active_shelf_dynamics)
then 1452 call register_ice_shelf_dyn_restarts(g, param_file, cs%dCS, cs%restart_CSp)
1461 cs%restart_output_dir = dirs%restart_output_dir
1464 if ((dirs%input_filename(1:1) ==
'n') .and. &
1465 (len_trim(dirs%input_filename) == 1)) new_sim = .true.
1467 if (cs%override_shelf_movement .and. cs%mass_from_file)
then 1470 call initialize_shelf_mass(g, param_file, cs, iss)
1474 call initialize_ice_thickness(iss%h_shelf, iss%area_shelf_h, iss%hmask, g, us, param_file)
1477 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
1478 if ((iss%hmask(i,j) == 1) .or. (iss%hmask(i,j) == 2))
then 1479 iss%mass_shelf(i,j) = iss%h_shelf(i,j)*cs%density_ice
1483 if (cs%min_thickness_simple_calve > 0.0) &
1484 call ice_shelf_min_thickness_calve(g, iss%h_shelf, iss%area_shelf_h, iss%hmask, &
1485 cs%min_thickness_simple_calve)
1489 if (cs%active_shelf_dynamics)
then 1499 if (new_sim .and. (.not. (cs%override_shelf_movement .and. cs%mass_from_file)))
then 1502 call initialize_ice_thickness(iss%h_shelf, iss%area_shelf_h, iss%hmask, g, us, param_file)
1505 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
1506 if ((iss%hmask(i,j) == 1) .or. (iss%hmask(i,j) == 2))
then 1507 iss%mass_shelf(i,j) = iss%h_shelf(i,j)*cs%density_ice
1512 elseif (.not.new_sim)
then 1514 call mom_mesg(
"MOM_ice_shelf.F90, initialize_ice_shelf: Restoring ice shelf from file.")
1515 call restore_state(dirs%input_filename, dirs%restart_input_dir, time, &
1518 if ((us%m_to_Z_restart /= 0.0) .and. (us%m_to_Z_restart /= us%m_to_Z))
then 1519 z_rescale = us%m_to_Z / us%m_to_Z_restart
1520 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
1521 iss%h_shelf(i,j) = z_rescale * iss%h_shelf(i,j)
1525 if ((us%m_to_Z_restart*us%kg_m3_to_R_restart /= 0.0) .and. &
1526 (us%m_to_Z*us%kg_m3_to_R /= us%m_to_Z_restart * us%kg_m3_to_R_restart))
then 1527 rz_rescale = us%m_to_Z*us%kg_m3_to_R / (us%m_to_Z_restart * us%kg_m3_to_R_restart)
1528 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
1529 iss%mass_shelf(i,j) = rz_rescale * iss%mass_shelf(i,j)
1533 if ((us%m_to_L_restart /= 0.0) .and. (us%m_to_L_restart /= us%m_to_L))
then 1534 l_rescale = us%m_to_L / us%m_to_L_restart
1535 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
1536 iss%area_shelf_h(i,j) = l_rescale**2 * iss%area_shelf_h(i,j)
1544 call cpu_clock_begin(id_clock_pass)
1545 call pass_var(iss%area_shelf_h, g%domain)
1546 call pass_var(iss%h_shelf, g%domain)
1547 call pass_var(iss%mass_shelf, g%domain)
1550 call cpu_clock_end(id_clock_pass)
1552 do j=jsd,jed ;
do i=isd,ied
1553 if (iss%area_shelf_h(i,j) > g%areaT(i,j))
then 1554 call mom_error(warning,
"Initialize_ice_shelf: area_shelf_h exceeds G%areaT.")
1555 iss%area_shelf_h(i,j) = g%areaT(i,j)
1558 if (
present(fluxes))
then ;
do j=jsd,jed ;
do i=isd,ied
1559 if (g%areaT(i,j) > 0.0) fluxes%frac_shelf_h(i,j) = iss%area_shelf_h(i,j) / g%areaT(i,j)
1560 enddo ;
enddo ;
endif 1563 call hchksum(fluxes%frac_shelf_h,
"IS init: frac_shelf_h", g%HI, haloshift=0)
1566 if (
present(forces)) &
1567 call add_shelf_forces(g, us, cs, forces, do_shelf_area=.not.cs%solo_ice_sheet)
1569 if (
present(fluxes))
call add_shelf_pressure(g, us, cs, fluxes)
1571 if (cs%active_shelf_dynamics .and. .not.cs%isthermo)
then 1572 iss%water_flux(:,:) = 0.0
1575 if (shelf_mass_is_dynamic) &
1576 call initialize_ice_shelf_dyn(param_file, time, iss, cs%dCS, g, us, diag, new_sim, solo_ice_sheet_in)
1578 call fix_restart_unit_scaling(us)
1580 call get_param(param_file, mdl,
"SAVE_INITIAL_CONDS", save_ic, &
1581 "If true, save the ice shelf initial conditions.", &
1583 if (save_ic)
call get_param(param_file, mdl,
"SHELF_IC_OUTPUT_FILE", ic_file,&
1584 "The name-root of the output file for the ice shelf "//&
1585 "initial conditions.", default=
"MOM_Shelf_IC")
1587 if (save_ic .and. .not.((dirs%input_filename(1:1) ==
'r') .and. &
1588 (len_trim(dirs%input_filename) == 1)))
then 1589 call save_restart(dirs%output_directory, cs%Time, g, &
1590 cs%restart_CSp, filename=ic_file)
1594 cs%id_area_shelf_h = register_diag_field(
'ocean_model',
'area_shelf_h', cs%diag%axesT1, cs%Time, &
1595 'Ice Shelf Area in cell',
'meter-2', conversion=us%L_to_m**2)
1596 cs%id_shelf_mass = register_diag_field(
'ocean_model',
'shelf_mass', cs%diag%axesT1, cs%Time, &
1597 'mass of shelf',
'kg/m^2', conversion=us%RZ_to_kg_m2)
1598 cs%id_h_shelf = register_diag_field(
'ocean_model',
'h_shelf', cs%diag%axesT1, cs%Time, &
1599 'ice shelf thickness',
'm', conversion=us%Z_to_m)
1600 cs%id_mass_flux = register_diag_field(
'ocean_model',
'mass_flux', cs%diag%axesT1,&
1601 cs%Time,
'Total mass flux of freshwater across the ice-ocean interface.', &
1602 'kg/s', conversion=us%RZ_T_to_kg_m2s*us%L_to_m**2)
1604 if (cs%const_gamma)
then 1605 meltrate_conversion = 86400.0*365.0*us%Z_to_m*us%s_to_T / (1000.0*us%kg_m3_to_R)
1607 meltrate_conversion = 86400.0*365.0*us%Z_to_m*us%s_to_T / cs%density_ice
1609 cs%id_melt = register_diag_field(
'ocean_model',
'melt', cs%diag%axesT1, cs%Time, &
1610 'Ice Shelf Melt Rate',
'm yr-1', conversion= meltrate_conversion)
1611 cs%id_thermal_driving = register_diag_field(
'ocean_model',
'thermal_driving', cs%diag%axesT1, cs%Time, &
1612 'pot. temp. in the boundary layer minus freezing pot. temp. at the ice-ocean interface.',
'Celsius')
1613 cs%id_haline_driving = register_diag_field(
'ocean_model',
'haline_driving', cs%diag%axesT1, cs%Time, &
1614 'salinity in the boundary layer minus salinity at the ice-ocean interface.',
'psu')
1615 cs%id_Sbdry = register_diag_field(
'ocean_model',
'sbdry', cs%diag%axesT1, cs%Time, &
1616 'salinity at the ice-ocean interface.',
'psu')
1617 cs%id_u_ml = register_diag_field(
'ocean_model',
'u_ml', cs%diag%axesCu1, cs%Time, &
1618 'Eastward vel. in the boundary layer (used to compute ustar)',
'm s-1', conversion=us%L_T_to_m_s)
1619 cs%id_v_ml = register_diag_field(
'ocean_model',
'v_ml', cs%diag%axesCv1, cs%Time, &
1620 'Northward vel. in the boundary layer (used to compute ustar)',
'm s-1', conversion=us%L_T_to_m_s)
1621 cs%id_exch_vel_s = register_diag_field(
'ocean_model',
'exch_vel_s', cs%diag%axesT1, cs%Time, &
1622 'Sub-shelf salinity exchange velocity',
'm s-1', conversion=us%Z_to_m*us%s_to_T)
1623 cs%id_exch_vel_t = register_diag_field(
'ocean_model',
'exch_vel_t', cs%diag%axesT1, cs%Time, &
1624 'Sub-shelf thermal exchange velocity',
'm s-1' , conversion=us%Z_to_m*us%s_to_T)
1625 cs%id_tfreeze = register_diag_field(
'ocean_model',
'tfreeze', cs%diag%axesT1, cs%Time, &
1626 'In Situ Freezing point at ice shelf interface',
'degC')
1627 cs%id_tfl_shelf = register_diag_field(
'ocean_model',
'tflux_shelf', cs%diag%axesT1, cs%Time, &
1628 'Heat conduction into ice shelf',
'W m-2', conversion=-us%QRZ_T_to_W_m2)
1629 cs%id_ustar_shelf = register_diag_field(
'ocean_model',
'ustar_shelf', cs%diag%axesT1, cs%Time, &
1630 'Fric vel under shelf',
'm/s', conversion=us%Z_to_m*us%s_to_T)
1631 if (cs%active_shelf_dynamics)
then 1632 cs%id_h_mask = register_diag_field(
'ocean_model',
'h_mask', cs%diag%axesT1, cs%Time, &
1633 'ice shelf thickness mask',
'none')
1636 id_clock_shelf = cpu_clock_id(
'Ice shelf', grain=clock_component)
1637 id_clock_pass = cpu_clock_id(
' Ice shelf halo updates', grain=clock_routine)
1639 end subroutine initialize_ice_shelf
1642 subroutine initialize_shelf_mass(G, param_file, CS, ISS, new_sim)
1644 type(ocean_grid_type),
intent(in) :: G
1645 type(param_file_type),
intent(in) :: param_file
1646 type(ice_shelf_CS),
pointer :: CS
1647 type(ice_shelf_state),
intent(inout) :: ISS
1648 logical,
optional,
intent(in) :: new_sim
1650 integer :: i, j, is, ie, js, je
1651 logical :: read_shelf_area, new_sim_2
1652 character(len=240) :: config, inputdir, shelf_file, filename
1653 character(len=120) :: shelf_mass_var
1654 character(len=120) :: shelf_area_var
1655 character(len=40) :: mdl =
"MOM_ice_shelf" 1656 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1658 new_sim_2 = .true. ;
if (
present(new_sim)) new_sim_2 = new_sim
1660 call get_param(param_file, mdl,
"ICE_SHELF_CONFIG", config, &
1661 "A string that specifies how the ice shelf is "//&
1662 "initialized. Valid options include:\n"//&
1663 " \tfile\t Read from a file.\n"//&
1664 " \tzero\t Set shelf mass to 0 everywhere.\n"//&
1665 " \tUSER\t Call USER_initialize_shelf_mass.\n", &
1666 fail_if_missing=.true.)
1668 select case ( trim(config) )
1671 call time_interp_external_init()
1673 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
1674 inputdir = slasher(inputdir)
1676 call get_param(param_file, mdl,
"SHELF_FILE", shelf_file, &
1677 "If DYNAMIC_SHELF_MASS = True, OVERRIDE_SHELF_MOVEMENT = True "//&
1678 "and ICE_SHELF_MASS_FROM_FILE = True, this is the file from "//&
1679 "which to read the shelf mass and area.", &
1680 default=
"shelf_mass.nc")
1681 call get_param(param_file, mdl,
"SHELF_MASS_VAR", shelf_mass_var, &
1682 "The variable in SHELF_FILE with the shelf mass.", &
1683 default=
"shelf_mass")
1684 call get_param(param_file, mdl,
"READ_SHELF_AREA", read_shelf_area, &
1685 "If true, also read the area covered by ice-shelf from SHELF_FILE.", &
1688 filename = trim(slasher(inputdir))//trim(shelf_file)
1689 call log_param(param_file, mdl,
"INPUTDIR/SHELF_FILE", filename)
1691 cs%id_read_mass = init_external_field(filename, shelf_mass_var, &
1692 domain=g%Domain%mpp_domain, verbose=cs%debug)
1694 if (read_shelf_area)
then 1695 call get_param(param_file, mdl,
"SHELF_AREA_VAR", shelf_area_var, &
1696 "The variable in SHELF_FILE with the shelf area.", &
1697 default=
"shelf_area")
1699 cs%id_read_area = init_external_field(filename,shelf_area_var, &
1700 domain=g%Domain%mpp_domain)
1703 if (.not.
file_exists(filename, g%Domain))
call mom_error(fatal, &
1704 " initialize_shelf_mass: Unable to open "//trim(filename))
1707 do j=js,je ;
do i=is,ie
1708 iss%mass_shelf(i,j) = 0.0
1709 iss%area_shelf_h(i,j) = 0.0
1713 call user_initialize_shelf_mass(iss%mass_shelf, iss%area_shelf_h, &
1714 iss%h_shelf, iss%hmask, g, cs%US, cs%user_CS, param_file, new_sim_2)
1716 case default ;
call mom_error(fatal,
"initialize_ice_shelf: "// &
1717 "Unrecognized ice shelf setup "//trim(config))
1720 end subroutine initialize_shelf_mass
1723 subroutine update_shelf_mass(G, US, CS, ISS, Time)
1724 type(ocean_grid_type),
intent(inout) :: G
1725 type(unit_scale_type),
intent(in) :: US
1726 type(ice_shelf_CS),
intent(in) :: CS
1727 type(ice_shelf_state),
intent(inout) :: ISS
1728 type(time_type),
intent(in) :: Time
1731 integer :: i, j, is, ie, js, je
1732 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1734 call time_interp_external(cs%id_read_mass, time, iss%mass_shelf)
1736 do j=js,je ;
do i=is,ie
1737 iss%mass_shelf(i,j) = us%kg_m3_to_R*us%m_to_Z * iss%mass_shelf(i,j)
1740 do j=js,je ;
do i=is,ie
1741 iss%area_shelf_h(i,j) = 0.0
1743 if (iss%mass_shelf(i,j) > 0.0)
then 1744 iss%area_shelf_h(i,j) = g%areaT(i,j)
1745 iss%h_shelf(i,j) = iss%mass_shelf(i,j) / cs%density_ice
1753 if (cs%min_thickness_simple_calve > 0.0)
then 1754 call ice_shelf_min_thickness_calve(g, iss%h_shelf, iss%area_shelf_h, iss%hmask, &
1755 cs%min_thickness_simple_calve, halo=0)
1758 call pass_var(iss%area_shelf_h, g%domain)
1759 call pass_var(iss%h_shelf, g%domain)
1761 call pass_var(iss%mass_shelf, g%domain)
1763 end subroutine update_shelf_mass
1766 subroutine ice_shelf_save_restart(CS, Time, directory, time_stamped, filename_suffix)
1768 type(time_type),
intent(in) :: time
1769 character(len=*),
optional,
intent(in) :: directory
1771 logical,
optional,
intent(in) :: time_stamped
1773 character(len=*),
optional,
intent(in) :: filename_suffix
1777 character(len=200) :: restart_dir
1781 if (
present(directory))
then ; restart_dir = directory
1782 else ; restart_dir = cs%restart_output_dir ;
endif 1784 call save_restart(restart_dir, time, cs%grid, cs%restart_CSp, time_stamped)
1786 end subroutine ice_shelf_save_restart
1789 subroutine ice_shelf_end(CS)
1792 if (.not.
associated(cs))
return 1794 call ice_shelf_state_end(cs%ISS)
1796 if (cs%active_shelf_dynamics)
call ice_shelf_dyn_end(cs%dCS)
1800 end subroutine ice_shelf_end
1803 subroutine solo_step_ice_shelf(CS, time_interval, nsteps, Time, min_time_step_in)
1805 type(time_type),
intent(in) :: time_interval
1806 integer,
intent(inout) :: nsteps
1807 type(time_type),
intent(inout) :: time
1808 real,
optional,
intent(in) :: min_time_step_in
1815 real :: remaining_time
1817 real :: min_time_step
1818 character(len=240) :: mesg
1819 logical :: update_ice_vel
1820 logical :: coupled_gl
1822 integer :: is, iec, js, jec, i, j
1827 is = g%isc ; iec = g%iec ; js = g%jsc ; jec = g%jec
1829 remaining_time = us%s_to_T*time_type_to_real(time_interval)
1831 if (
present (min_time_step_in))
then 1832 min_time_step = min_time_step_in
1834 min_time_step = 1000.0*us%s_to_T
1837 write (mesg,*)
"TIME in ice shelf call, yrs: ", time_type_to_real(time)/(365. * 86400.)
1838 call mom_mesg(
"solo_step_ice_shelf: "//mesg, 5)
1840 do while (remaining_time > 0.0)
1844 time_step = min(ice_time_step_cfl(cs%dCS, iss, g), remaining_time)
1846 write (mesg,*)
"Ice model timestep = ", us%T_to_s*time_step,
" seconds" 1847 if ((time_step < min_time_step) .and. (time_step < remaining_time))
then 1848 call mom_error(fatal,
"MOM_ice_shelf:solo_step_ice_shelf: abnormally small timestep "//mesg)
1850 call mom_mesg(
"solo_step_ice_shelf: "//mesg, 5)
1853 remaining_time = remaining_time - time_step
1857 update_ice_vel = ((time_step > min_time_step) .or. (remaining_time > 0.0))
1858 coupled_gl = .false.
1860 call update_ice_shelf(cs%dCS, iss, g, us, time_step, time, must_update_vel=update_ice_vel)
1862 call enable_averages(time_step, time, cs%diag)
1863 if (cs%id_area_shelf_h > 0)
call post_data(cs%id_area_shelf_h, iss%area_shelf_h, cs%diag)
1864 if (cs%id_h_shelf > 0)
call post_data(cs%id_h_shelf, iss%h_shelf, cs%diag)
1865 if (cs%id_h_mask > 0)
call post_data(cs%id_h_mask, iss%hmask, cs%diag)
1866 call disable_averaging(cs%diag)
1870 end subroutine solo_step_ice_shelf
The control structure for the ice shelf dynamics.
Structure that describes the ice shelf state.
Pointers to various fields which may be used describe the surface state of MOM, and which will be ret...
Checksums an array (2d or 3d) staggered at C-grid u points.
Functions and routines to take area, volume, mass-weighted, layerwise, zonal or meridional means...
Wraps the FMS time manager functions.
This module implements boundary forcing for MOM6.
Initializes fixed aspects of the model, such as horizontal grid metrics, topography and Coriolis...
Ocean grid type. See mom_grid for details.
Calculates density of sea water from T, S and P.
Calculates the freezing point of sea water from T, S and P.
Allocate the fields of a mechanical forcing type, based on either a set of input flags for each group...
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
Wraps the MPP cpu clock functions.
Initializes horizontal grid.
Register fields for restarts.
Describes the horizontal ocean grid with only dynamic memory arrays.
This module contains I/O framework code.
The MOM6 facility to parse input files for runtime parameters.
An overloaded interface to log the values of various types of parameters.
A template of a user to code up customized initial conditions.
Checksums a pair velocity arrays (2d or 3d) staggered at C-grid locations.
Do a halo update on a pair of arrays representing the two components of a vector. ...
Routines to calculate checksums of various array and vector types.
Provides a few physical constants.
Structure that contains pointers to the mechanical forcing at the surface used to drive the liquid oc...
Interfaces to non-domain-oriented communication subroutines, including the MOM6 reproducing sums faci...
Allocate the fields of a (flux) forcing type, based on either a set of input flags for each group of ...
This is an older interface that has been renamed Bchksum.
Make a diagnostic available for averaging or output.
Implements the thermodynamic aspects of ocean / ice-shelf interactions, along with a crude placeholde...
A restart registry and the control structure for restarts.
Describes various unit conversion factors.
Copy one MOM_domain_type into another.
Checksums an array (2d or 3d) staggered at tracer points.
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Initialize ice shelf variables.
Describes the decomposed MOM domain and has routines for communications across PEs.
Routines for error handling and I/O management.
This module specifies the initial values and evolving properties of the MOM6 ice shelf, using user-provided code.
The MOM6 facility for reading and writing restart files, and querying what has been read...
Implements the thermodynamic aspects of ocean / ice-shelf interactions, along with a crude placeholde...
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
Calculate the derivatives of density with temperature and salinity from T, S, and P...
Provides subroutines for quantities specific to the equation of state.
Implements a crude placeholder for a later implementation of full ice shelf dynamics.
An overloaded interface to log version information about modules.
This is an older interface for 1-, 2-, or 3-D checksums.
Indicate whether a file exists, perhaps with domain decomposition.
Control structure that contains ice shelf parameters and diagnostics handles.
An overloaded interface to read various types of parameters.
Indicate whether a field has been read from a restart file.
Module with routines for copying information from a shared dynamic horizontal grid to an ocean-specif...
Find an accurate and order-invariant sum of a distributed 2d or 3d field.
Checksums an array (2d or 3d) staggered at C-grid v points.
Contains a shareable dynamic type for describing horizontal grids and metric data and utilty routines...
Provides transparent structures with groups of MOM6 variables and supporting routines.
The control structure for the user_ice_shelf module.
Do a halo update on an array.
Read a data field from a file.
An overloaded interface to read and log the values of various types of parameters.
A control structure for the equation of state.