8 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
25 use mom_io,
only : slasher, fieldtype
26 use mom_io,
only : write_field, close_file, single_file, multiple
50 use time_interp_external_mod,
only : init_external_field, time_interp_external
51 use time_interp_external_mod,
only : time_interp_external_init
52 use time_manager_mod,
only : print_time
53 implicit none ;
private
55 #include <MOM_memory.h>
56 #ifdef SYMMETRIC_LAND_ICE
57 # define GRID_SYM_ .true.
59 # define GRID_SYM_ .false.
81 real :: flux_factor = 1.0
83 character(len=128) :: restart_output_dir =
' '
88 real,
pointer,
dimension(:,:) :: &
105 real :: kd_molec_salt
106 real :: kd_molec_temp
110 real :: col_thick_melt_threshold
111 logical :: mass_from_file
120 logical :: solo_ice_sheet
122 logical :: gl_regularize
128 real :: density_ocean_avg
132 logical :: calve_to_mask
133 real :: min_thickness_simple_calve
137 real :: input_thickness
139 type(time_type) :: time
142 logical :: active_shelf_dynamics
144 logical :: override_shelf_movement
152 logical :: const_gamma
153 logical :: find_salt_root
154 logical :: constant_sea_level
161 integer :: id_melt = -1, id_exch_vel_s = -1, id_exch_vel_t = -1, &
162 id_tfreeze = -1, id_tfl_shelf = -1, &
163 id_thermal_driving = -1, id_haline_driving = -1, &
164 id_u_ml = -1, id_v_ml = -1, id_sbdry = -1, &
165 id_h_shelf = -1, id_h_mask = -1, &
166 id_surf_elev = -1, id_bathym = -1, &
167 id_area_shelf_h = -1, &
168 id_ustar_shelf = -1, id_shelf_mass = -1, id_mass_flux = -1
171 integer :: id_read_mass
173 integer :: id_read_area
196 type(
forcing),
intent(inout) :: fluxes
198 type(time_type),
intent(in) :: time
199 real,
intent(in) :: time_step
212 real,
dimension(SZI_(CS%grid)) :: &
213 rhoml, & !< Ocean mixed layer density [kg m-3].
214 dr0_dt, & !< Partial derivative of the mixed layer density
220 real,
dimension(SZI_(CS%grid),SZJ_(CS%grid)) :: &
221 exch_vel_t, & !< Sub-shelf thermal exchange velocity [m s-1]
224 real,
dimension(SZDI_(CS%grid),SZDJ_(CS%grid)) :: &
226 real,
dimension(SZDI_(CS%grid),SZDJ_(CS%grid)) :: &
230 real,
parameter :: vk = 0.40
231 real :: zeta_n = 0.052
233 real,
parameter :: rc = 0.20
240 real,
dimension(SZDI_(CS%grid),SZDJ_(CS%grid)) :: &
243 real :: sbdry1, sbdry2, s_a, s_b, s_c
246 real :: hbl_neut_h_molec
253 real :: i_n_star, n_star_term, absf
255 real :: dt_ustar, ds_ustar
258 real :: gam_mol_t, gam_mol_s
263 real :: sb_min, sb_max
264 real :: ds_min, ds_max
266 real :: wb_flux_new, dwb, ddwb_dwb_in
267 real :: i_gam_t, i_gam_s, dg_dwb, idens
268 real :: u_at_h, v_at_h, isqrt2
269 logical :: sb_min_set, sb_max_set
270 logical :: update_ice_vel
271 logical :: coupled_gl
274 real,
parameter :: c2_3 = 2.0/3.0
275 character(len=160) :: mesg
276 integer :: i, j, is, ie, js, je, ied, jed, it1, it3
277 real,
parameter :: rho_fw = 1000.0
279 if (.not.
associated(cs))
call mom_error(fatal,
"shelf_calc_flux: "// &
280 "initialize_ice_shelf must be called before shelf_calc_flux.")
283 g => cs%grid ; us => cs%US
287 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; ied = g%ied ; jed = g%jed
288 i_zeta_n = 1.0 / zeta_n
290 i_rholf = 1.0/(cs%Rho0*lf)
292 sc = cs%kv_molec/cs%kd_molec_salt
293 pr = cs%kv_molec/cs%kd_molec_temp
295 rhocp = cs%Rho0 * cs%Cp
296 isqrt2 = 1.0/sqrt(2.0)
299 gam_mol_t = 12.5 * (pr**c2_3) - 6
300 gam_mol_s = 12.5 * (sc**c2_3) - 6
302 idens = 1.0/cs%density_ocean_avg
308 exch_vel_t(:,:) = 0.0 ; exch_vel_s(:,:) = 0.0
309 iss%tflux_shelf(:,:) = 0.0 ; iss%water_flux(:,:) = 0.0
310 iss%salt_flux(:,:) = 0.0; iss%tflux_ocn(:,:) = 0.0
311 iss%tfreeze(:,:) = 0.0
313 haline_driving(:,:) = 0.0
314 sbdry(:,:) = state%sss(:,:)
319 if (cs%override_shelf_movement)
then
320 cs%time_step = time_step
326 call hchksum(fluxes%frac_shelf_h,
"frac_shelf_h before apply melting", g%HI, haloshift=0)
327 call hchksum(state%sst,
"sst before apply melting", g%HI, haloshift=0)
328 call hchksum(state%sss,
"sss before apply melting", g%HI, haloshift=0)
329 call hchksum(state%u,
"u_ml before apply melting", g%HI, haloshift=0)
330 call hchksum(state%v,
"v_ml before apply melting", g%HI, haloshift=0)
331 call hchksum(state%ocean_mass,
"ocean_mass before apply melting", g%HI, haloshift=0)
337 do i=is,ie ; p_int(i) = cs%g_Earth * iss%mass_shelf(i,j) ;
enddo
341 rhoml(:), is, ie-is+1, cs%eqn_of_state)
343 dr0_dt, dr0_ds, is, ie-is+1, cs%eqn_of_state)
348 fluxes%ustar_shelf(i,j)= 0.0
353 if ((idens*state%ocean_mass(i,j) > cs%col_thick_melt_threshold) .and. &
354 (iss%area_shelf_h(i,j) > 0.0) .and. &
355 (cs%isthermo) .and. (state%Hml(i,j) > 0.0) )
then
363 u_at_h = state%u(i,j)
364 v_at_h = state%v(i,j)
369 fluxes%ustar_shelf(i,j) = max(cs%ustar_bg, us%m_to_Z*us%T_to_s * &
370 sqrt(cs%cdrag*((u_at_h**2 + v_at_h**2) + cs%utide(i,j)**1)))
372 ustar_h = us%Z_to_m*us%s_to_T*fluxes%ustar_shelf(i,j)
384 absf = 0.25*us%s_to_T*((abs(us%s_to_T*g%CoriolisBu(i,j)) + abs(us%s_to_T*g%CoriolisBu(i-1,j-1))) + &
385 (abs(us%s_to_T*g%CoriolisBu(i,j-1)) + abs(us%s_to_T*g%CoriolisBu(i-1,j))))
386 if (absf*state%Hml(i,j) <= vk*ustar_h)
then ; hbl_neut = state%Hml(i,j)
387 else ; hbl_neut = (vk*ustar_h) / absf ;
endif
388 hbl_neut_h_molec = zeta_n * ((hbl_neut * ustar_h) / (5.0 * cs%Kv_molec))
391 db_ds = (cs%g_Earth / rhoml(i)) * dr0_ds(i)
392 db_dt = (cs%g_Earth / rhoml(i)) * dr0_dt(i)
393 ln_neut = 0.0 ;
if (hbl_neut_h_molec > 1.0) ln_neut = log(hbl_neut_h_molec)
395 if (cs%find_salt_root)
then
398 s_a = cs%lambda1 * cs%Gamma_T_3EQ * cs%Cp
402 s_b = cs%Gamma_T_3EQ*cs%Cp*(cs%lambda2+cs%lambda3*p_int(i)- &
403 state%sst(i,j))-lf*cs%Gamma_T_3EQ/35.0
404 s_c = lf*(cs%Gamma_T_3EQ/35.0)*state%sss(i,j)
407 sbdry1 = (-s_b + sqrt(s_b*s_b-4*s_a*s_c))/(2*s_a)
408 sbdry2 = (-s_b - sqrt(s_b*s_b-4*s_a*s_c))/(2*s_a)
409 sbdry(i,j) = max(sbdry1, sbdry2)
411 if (sbdry(i,j) < 0.)
then
412 write(mesg,*)
'state%sss(i,j) = ',state%sss(i,j),
'S_a, S_b, S_c', s_a, s_b, s_c
414 write(mesg,*)
'I,J,Sbdry1,Sbdry2',i,j,sbdry1,sbdry2
416 call mom_error(fatal,
"shelf_calc_flux: Negative salinity (Sbdry).")
420 sbdry(i,j) = state%sss(i,j) ; sb_max_set = .false.
428 dt_ustar = (state%sst(i,j) - iss%tfreeze(i,j)) * ustar_h
429 ds_ustar = (state%sss(i,j) - sbdry(i,j)) * ustar_h
435 if (cs%const_gamma)
then
437 i_gam_t = cs%Gamma_T_3EQ
438 i_gam_s = cs%Gamma_T_3EQ/35.
440 gam_turb = i_vk * (ln_neut + (0.5 * i_zeta_n - 1.0))
441 i_gam_t = 1.0 / (gam_mol_t + gam_turb)
442 i_gam_s = 1.0 / (gam_mol_s + gam_turb)
445 wt_flux = dt_ustar * i_gam_t
446 wb_flux = db_ds * (ds_ustar * i_gam_s) + db_dt * wt_flux
448 if (wb_flux > 0.0)
then
451 n_star_term = (zeta_n/rc) * (hbl_neut * vk) / ustar_h**3
457 i_n_star = sqrt(1.0 + n_star_term * wb_flux)
458 dins_dwb = 0.5 * n_star_term / i_n_star
459 if (hbl_neut_h_molec > i_n_star**2)
then
460 gam_turb = i_vk * ((ln_neut - 2.0*log(i_n_star)) + &
461 (0.5*i_zeta_n*i_n_star - 1.0))
462 dg_dwb = i_vk * ( -2.0 / i_n_star + (0.5 * i_zeta_n)) * dins_dwb
466 gam_turb = i_vk * (0.5 * i_zeta_n*i_n_star - 1.0)
467 dg_dwb = i_vk * (0.5 * i_zeta_n) * dins_dwb
470 if (cs%const_gamma)
then
472 i_gam_t = cs%Gamma_T_3EQ
473 i_gam_s = cs%Gamma_T_3EQ/35.
475 i_gam_t = 1.0 / (gam_mol_t + gam_turb)
476 i_gam_s = 1.0 / (gam_mol_s + gam_turb)
479 wt_flux = dt_ustar * i_gam_t
480 wb_flux_new = db_ds * (ds_ustar * i_gam_s) + db_dt * wt_flux
483 dwb = wb_flux_new - wb_flux
484 if (abs(wb_flux_new - wb_flux) < &
485 1e-4*(abs(wb_flux_new) + abs(wb_flux)))
exit
487 ddwb_dwb_in = -dg_dwb * (db_ds * (ds_ustar * i_gam_s**2) + &
488 db_dt * (dt_ustar * i_gam_t**2)) - 1.0
491 wb_flux_new = wb_flux - dwb / ddwb_dwb_in
495 iss%tflux_ocn(i,j) = rhocp * wt_flux
496 exch_vel_t(i,j) = ustar_h * i_gam_t
497 exch_vel_s(i,j) = ustar_h * i_gam_s
507 if (iss%tflux_ocn(i,j) <= 0.0)
then
508 iss%water_flux(i,j) = i_lf * iss%tflux_ocn(i,j)
509 iss%tflux_shelf(i,j) = 0.0
511 if (cs%insulator)
then
513 iss%tflux_shelf(i,j) = 0.0
514 iss%water_flux(i,j) = i_lf * (- iss%tflux_shelf(i,j) + iss%tflux_ocn(i,j))
521 iss%water_flux(i,j) = iss%tflux_ocn(i,j) / &
522 (lf + cs%CP_Ice * (iss%tfreeze(i,j) - cs%Temp_Ice))
524 iss%tflux_shelf(i,j) = iss%tflux_ocn(i,j) - lf*iss%water_flux(i,j)
533 if (cs%find_salt_root)
then
537 mass_exch = exch_vel_s(i,j) * cs%Rho0
538 sbdry_it = (state%sss(i,j) * mass_exch + cs%Salin_ice * &
539 iss%water_flux(i,j)) / (mass_exch + iss%water_flux(i,j))
540 ds_it = sbdry_it - sbdry(i,j)
541 if (abs(ds_it) < 1e-4*(0.5*(state%sss(i,j) + sbdry(i,j) + 1.e-10)))
exit
544 if (ds_it < 0.0)
then
545 if (sb_max_set .and. (sbdry(i,j) > sb_max)) &
546 call mom_error(fatal,
"shelf_calc_flux: Irregular iteration for Sbdry (max).")
547 sb_max = sbdry(i,j) ; ds_max = ds_it ; sb_max_set = .true.
549 if (sb_min_set .and. (sbdry(i,j) < sb_min)) &
551 "shelf_calc_flux: Irregular iteration for Sbdry (min).")
552 sb_min = sbdry(i,j) ; ds_min = ds_it ; sb_min_set = .true.
555 if (sb_min_set .and. sb_max_set)
then
557 sbdry(i,j) = sb_min + (sb_max-sb_min) * &
558 (ds_min / (ds_min - ds_max))
560 sbdry(i,j) = sbdry_it
563 sbdry(i,j) = sbdry_it
574 call calculate_tfreeze(state%sss(i,j), p_int(i), iss%tfreeze(i,j), cs%eqn_of_state)
576 exch_vel_t(i,j) = cs%gamma_t
577 iss%tflux_ocn(i,j) = rhocp * exch_vel_t(i,j) * (state%sst(i,j) - iss%tfreeze(i,j))
578 iss%tflux_shelf(i,j) = 0.0
579 iss%water_flux(i,j) = i_lf * iss%tflux_ocn(i,j)
583 iss%tflux_ocn(i,j) = 0.0
593 if (cs%const_gamma)
then
594 fluxes%iceshelf_melt = iss%water_flux * (86400.0*365.0/rho_fw) * cs%flux_factor
596 fluxes%iceshelf_melt = iss%water_flux * (86400.0*365.0/cs%density_ice) * cs%flux_factor
599 do j=js,je ;
do i=is,ie
600 if ((idens*state%ocean_mass(i,j) > cs%col_thick_melt_threshold) .and. &
601 (iss%area_shelf_h(i,j) > 0.0) .and. &
602 (cs%isthermo) .and. (state%Hml(i,j) > 0.0) )
then
607 if ((cs%g_Earth * iss%mass_shelf(i,j)) < cs%Rho0*cs%cutoff_depth* &
609 iss%water_flux(i,j) = 0.0
610 fluxes%iceshelf_melt(i,j) = 0.0
613 haline_driving(i,j) = (iss%water_flux(i,j) * sbdry(i,j)) / &
614 (cs%Rho0 * exch_vel_s(i,j))
630 if ((abs(fluxes%iceshelf_melt(i,j))>0.0) .and. (fluxes%ustar_shelf(i,j) == 0.0))
then
631 write(mesg,*)
"|melt| = ",fluxes%iceshelf_melt(i,j),
" > 0 and ustar_shelf = 0. at i,j", i, j
632 call mom_error(fatal,
"shelf_calc_flux: "//trim(mesg))
640 mass_flux(:,:) = iss%water_flux(:,:) * iss%area_shelf_h(:,:)
642 if (cs%active_shelf_dynamics .or. cs%override_shelf_movement)
then
644 call pass_var(iss%area_shelf_h, g%domain, complete=.false.)
645 call pass_var(iss%mass_shelf, g%domain)
650 if ( cs%override_shelf_movement .and. (.not.cs%mass_from_file))
then
654 call hchksum(iss%h_shelf,
"h_shelf after change thickness using melt", g%HI, haloshift=0, scale=us%Z_to_m)
655 call hchksum(iss%mass_shelf,
"mass_shelf after change thickness using melt", g%HI, haloshift=0)
659 if (cs%debug)
call mom_forcing_chksum(
"Before add shelf flux", fluxes, g, cs%US, haloshift=0)
665 if (cs%active_shelf_dynamics)
then
666 update_ice_vel = .false.
667 coupled_gl = (cs%GL_couple .and. .not.cs%solo_ice_sheet)
671 call update_ice_shelf(cs%dCS, iss, g, us, time_step, time, state%ocean_mass, coupled_gl)
676 if (cs%id_shelf_mass > 0)
call post_data(cs%id_shelf_mass, iss%mass_shelf, cs%diag)
677 if (cs%id_area_shelf_h > 0)
call post_data(cs%id_area_shelf_h, iss%area_shelf_h, cs%diag)
678 if (cs%id_ustar_shelf > 0)
call post_data(cs%id_ustar_shelf, fluxes%ustar_shelf, cs%diag)
679 if (cs%id_melt > 0)
call post_data(cs%id_melt, fluxes%iceshelf_melt, cs%diag)
680 if (cs%id_thermal_driving > 0)
call post_data(cs%id_thermal_driving, (state%sst-iss%tfreeze), cs%diag)
681 if (cs%id_Sbdry > 0)
call post_data(cs%id_Sbdry, sbdry, cs%diag)
682 if (cs%id_haline_driving > 0)
call post_data(cs%id_haline_driving, haline_driving, cs%diag)
683 if (cs%id_mass_flux > 0)
call post_data(cs%id_mass_flux, mass_flux, cs%diag)
684 if (cs%id_u_ml > 0)
call post_data(cs%id_u_ml, state%u, cs%diag)
685 if (cs%id_v_ml > 0)
call post_data(cs%id_v_ml, state%v, cs%diag)
686 if (cs%id_tfreeze > 0)
call post_data(cs%id_tfreeze, iss%tfreeze, cs%diag)
687 if (cs%id_tfl_shelf > 0)
call post_data(cs%id_tfl_shelf, iss%tflux_shelf, cs%diag)
688 if (cs%id_exch_vel_t > 0)
call post_data(cs%id_exch_vel_t, exch_vel_t, cs%diag)
689 if (cs%id_exch_vel_s > 0)
call post_data(cs%id_exch_vel_s, exch_vel_s, cs%diag)
690 if (cs%id_h_shelf > 0)
call post_data(cs%id_h_shelf,iss%h_shelf,cs%diag)
691 if (cs%id_h_mask > 0)
call post_data(cs%id_h_mask,iss%hmask,cs%diag)
694 if (
present(forces))
then
695 call add_shelf_forces(g, us, cs, forces, do_shelf_area=(cs%active_shelf_dynamics .or. &
696 cs%override_shelf_movement))
701 if (cs%debug)
call mom_forcing_chksum(
"End of shelf calc flux", fluxes, g, cs%US, haloshift=0)
710 real,
intent(in) :: time_step
711 type(
forcing),
intent(inout) :: fluxes
713 real,
intent(in) :: rho_ice
714 logical,
optional,
intent(in) :: debug
720 i_rho_ice = 1.0 / rho_ice
722 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
723 if ((iss%hmask(i,j) == 1) .or. (iss%hmask(i,j) == 2))
then
725 if (
associated(fluxes%lprec)) fluxes%lprec(i,j) = 0.0
726 if (
associated(fluxes%sens)) fluxes%sens(i,j) = 0.0
727 if (
associated(fluxes%frac_shelf_h)) fluxes%frac_shelf_h(i,j) = 0.0
728 if (
associated(fluxes%salt_flux)) fluxes%salt_flux(i,j) = 0.0
730 if (iss%water_flux(i,j) / rho_ice * time_step < iss%h_shelf(i,j))
then
731 iss%h_shelf(i,j) = iss%h_shelf(i,j) - iss%water_flux(i,j) / rho_ice * time_step
735 iss%h_shelf(i,j) = 0.0
737 iss%area_shelf_h(i,j) = 0.0
742 call pass_var(iss%area_shelf_h, g%domain)
743 call pass_var(iss%h_shelf, g%domain)
747 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
748 if ((iss%hmask(i,j) == 1) .or. (iss%hmask(i,j) == 2))
then
749 iss%mass_shelf(i,j) = iss%h_shelf(i,j)*rho_ice
753 call pass_var(iss%mass_shelf, g%domain)
764 logical,
optional,
intent(in) :: do_shelf_area
772 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
773 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
774 isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
776 if ((cs%grid%isc /= g%isc) .or. (cs%grid%iec /= g%iec) .or. &
777 (cs%grid%jsc /= g%jsc) .or. (cs%grid%jec /= g%jec)) &
778 call mom_error(fatal,
"add_shelf_forces: Incompatible ocean and ice shelf grids.")
782 find_area = .true. ;
if (
present(do_shelf_area)) find_area = do_shelf_area
786 do j=jsd,jed ;
do i=isd,ied-1
787 forces%frac_shelf_u(i,j) = 0.0
788 if ((g%areaT(i,j) + g%areaT(i+1,j) > 0.0)) &
789 forces%frac_shelf_u(i,j) = ((iss%area_shelf_h(i,j) + iss%area_shelf_h(i+1,j)) / &
790 (us%L_to_m**2*g%areaT(i,j) + us%L_to_m**2*g%areaT(i+1,j)))
792 do j=jsd,jed-1 ;
do i=isd,ied
793 forces%frac_shelf_v(i,j) = 0.0
794 if ((g%areaT(i,j) + g%areaT(i,j+1) > 0.0)) &
795 forces%frac_shelf_v(i,j) = ((iss%area_shelf_h(i,j) + iss%area_shelf_h(i,j+1)) / &
796 (us%L_to_m**2*g%areaT(i,j) + us%L_to_m**2*g%areaT(i,j+1)))
798 call pass_vector(forces%frac_shelf_u, forces%frac_shelf_v, g%domain,
to_all, cgrid_ne)
802 do j=jsd,jed ;
do i=isd,ied
803 press_ice = (iss%area_shelf_h(i,j) * us%m_to_L**2*g%IareaT(i,j)) * (cs%g_Earth * iss%mass_shelf(i,j))
804 if (
associated(forces%p_surf))
then
805 if (.not.forces%accumulate_p_surf) forces%p_surf(i,j) = 0.0
806 forces%p_surf(i,j) = forces%p_surf(i,j) + press_ice
808 if (
associated(forces%p_surf_full))
then
809 if (.not.forces%accumulate_p_surf) forces%p_surf_full(i,j) = 0.0
810 forces%p_surf_full(i,j) = forces%p_surf_full(i,j) + press_ice
818 kv_rho_ice = cs%kv_ice / cs%density_ice
819 do j=js,je ;
do i=is-1,ie
820 if (.not.forces%accumulate_rigidity) forces%rigidity_ice_u(i,j) = 0.0
821 forces%rigidity_ice_u(i,j) = forces%rigidity_ice_u(i,j) + &
822 kv_rho_ice * min(iss%mass_shelf(i,j), iss%mass_shelf(i+1,j))
824 do j=js-1,je ;
do i=is,ie
825 if (.not.forces%accumulate_rigidity) forces%rigidity_ice_v(i,j) = 0.0
826 forces%rigidity_ice_v(i,j) = forces%rigidity_ice_v(i,j) + &
827 kv_rho_ice * min(iss%mass_shelf(i,j), iss%mass_shelf(i,j+1))
831 call uvchksum(
"rigidity_ice_[uv]", forces%rigidity_ice_u, forces%rigidity_ice_v, &
832 g%HI, symmetric=.true.)
833 call uvchksum(
"frac_shelf_[uv]", forces%frac_shelf_u, forces%frac_shelf_v, &
834 g%HI, symmetric=.true.)
844 type(
forcing),
intent(inout) :: fluxes
847 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
848 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
850 if ((cs%grid%isc /= g%isc) .or. (cs%grid%iec /= g%iec) .or. &
851 (cs%grid%jsc /= g%jsc) .or. (cs%grid%jec /= g%jec)) &
852 call mom_error(fatal,
"add_shelf_pressure: Incompatible ocean and ice shelf grids.")
854 do j=js,je ;
do i=is,ie
855 press_ice = (cs%ISS%area_shelf_h(i,j) * us%m_to_L**2*g%IareaT(i,j)) * (cs%g_Earth * cs%ISS%mass_shelf(i,j))
856 if (
associated(fluxes%p_surf))
then
857 if (.not.fluxes%accumulate_p_surf) fluxes%p_surf(i,j) = 0.0
858 fluxes%p_surf(i,j) = fluxes%p_surf(i,j) + press_ice
860 if (
associated(fluxes%p_surf_full))
then
861 if (.not.fluxes%accumulate_p_surf) fluxes%p_surf_full(i,j) = 0.0
862 fluxes%p_surf_full(i,j) = fluxes%p_surf_full(i,j) + press_ice
873 type(
surface),
intent(inout) :: state
874 type(
forcing),
intent(inout) :: fluxes
881 real :: delta_mass_shelf
887 real :: mean_melt_flux
890 type(time_type) :: time0
891 real,
dimension(SZDI_(G),SZDJ_(G)) :: last_mass_shelf
893 real,
dimension(SZDI_(G),SZDJ_(G)) :: last_h_shelf
895 real,
dimension(SZDI_(G),SZDJ_(G)) :: last_hmask
897 real,
dimension(SZDI_(G),SZDJ_(G)) :: last_area_shelf_h
903 real,
parameter :: rho_fw = 1000.0
904 character(len=160) :: mesg
905 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
906 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
907 isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
909 if ((cs%grid%isc /= g%isc) .or. (cs%grid%iec /= g%iec) .or. &
910 (cs%grid%jsc /= g%jsc) .or. (cs%grid%jec /= g%jec)) &
911 call mom_error(fatal,
"add_shelf_flux: Incompatible ocean and ice shelf grids.")
922 if (
allocated(state%taux_shelf) .and.
allocated(state%tauy_shelf))
then
923 call uvchksum(
"tau[xy]_shelf", state%taux_shelf, state%tauy_shelf, &
928 if (
allocated(state%taux_shelf) .and.
allocated(state%tauy_shelf))
then
951 if (cs%active_shelf_dynamics .or. cs%override_shelf_movement)
then
952 do j=jsd,jed ;
do i=isd,ied
953 if (g%areaT(i,j) > 0.0) &
954 fluxes%frac_shelf_h(i,j) = iss%area_shelf_h(i,j) * us%m_to_L**2*g%IareaT(i,j)
958 do j=js,je ;
do i=is,ie ;
if (iss%area_shelf_h(i,j) > 0.0)
then
959 frac_area = fluxes%frac_shelf_h(i,j)
960 if (
associated(fluxes%sw)) fluxes%sw(i,j) = 0.0
961 if (
associated(fluxes%sw_vis_dir)) fluxes%sw_vis_dir(i,j) = 0.0
962 if (
associated(fluxes%sw_vis_dif)) fluxes%sw_vis_dif(i,j) = 0.0
963 if (
associated(fluxes%sw_nir_dir)) fluxes%sw_nir_dir(i,j) = 0.0
964 if (
associated(fluxes%sw_nir_dif)) fluxes%sw_nir_dif(i,j) = 0.0
965 if (
associated(fluxes%lw)) fluxes%lw(i,j) = 0.0
966 if (
associated(fluxes%latent)) fluxes%latent(i,j) = 0.0
967 if (
associated(fluxes%evap)) fluxes%evap(i,j) = 0.0
968 if (
associated(fluxes%lprec))
then
969 if (iss%water_flux(i,j) > 0.0)
then
970 fluxes%lprec(i,j) = us%kg_m3_to_R*us%m_to_Z*us%T_to_s*frac_area*iss%water_flux(i,j)*cs%flux_factor
972 fluxes%lprec(i,j) = 0.0
973 fluxes%evap(i,j) = us%kg_m3_to_R*us%m_to_Z*us%T_to_s*frac_area*iss%water_flux(i,j)*cs%flux_factor
977 if (
associated(fluxes%sens)) &
978 fluxes%sens(i,j) = -frac_area*iss%tflux_ocn(i,j)*cs%flux_factor
979 if (
associated(fluxes%salt_flux)) &
980 fluxes%salt_flux(i,j) = frac_area * iss%salt_flux(i,j)*cs%flux_factor
981 endif ;
enddo ;
enddo
989 if (cs%constant_sea_level)
then
993 if (.not.
associated(fluxes%salt_flux))
allocate(fluxes%salt_flux(ie,je))
994 if (.not.
associated(fluxes%vprec))
allocate(fluxes%vprec(ie,je))
995 fluxes%salt_flux(:,:) = 0.0 ; fluxes%vprec(:,:) = 0.0
997 mean_melt_flux = 0.0; sponge_area = 0.0
998 do j=js,je ;
do i=is,ie
999 frac_area = fluxes%frac_shelf_h(i,j)
1000 if (frac_area > 0.0) &
1001 mean_melt_flux = mean_melt_flux + (iss%water_flux(i,j)) * iss%area_shelf_h(i,j)
1004 if (g%geoLonT(i,j) >= 790.0 .AND. g%geoLonT(i,j) <= 800.0)
then
1005 sponge_area = sponge_area + us%L_to_m**2*g%areaT(i,j)
1010 if (cs%override_shelf_movement .and. cs%mass_from_file)
then
1011 t0 = time_type_to_real(cs%Time) - cs%time_step
1016 last_hmask(:,:) = iss%hmask(:,:) ; last_area_shelf_h(:,:) = iss%area_shelf_h(:,:)
1017 call time_interp_external(cs%id_read_mass, time0, last_mass_shelf)
1018 last_h_shelf(:,:) = last_mass_shelf(:,:) / cs%rho_ice
1021 if (cs%min_thickness_simple_calve > 0.0)
then
1022 call ice_shelf_min_thickness_calve(g, last_h_shelf, last_area_shelf_h, last_hmask, &
1023 cs%min_thickness_simple_calve)
1025 last_mass_shelf(:,:) = last_h_shelf(:,:) * cs%rho_ice
1028 shelf_mass0 = 0.0; shelf_mass1 = 0.0
1030 do j=js,je ;
do i=is,ie
1032 if (((1.0/cs%density_ocean_avg)*state%ocean_mass(i,j) > 0.1) .and. &
1033 (iss%area_shelf_h(i,j) > 0.0))
then
1034 shelf_mass0 = shelf_mass0 + (last_mass_shelf(i,j) * iss%area_shelf_h(i,j))
1035 shelf_mass1 = shelf_mass1 + (iss%mass_shelf(i,j) * iss%area_shelf_h(i,j))
1038 call sum_across_pes(shelf_mass0);
call sum_across_pes(shelf_mass1)
1039 delta_mass_shelf = (shelf_mass1 - shelf_mass0)/cs%time_step
1045 delta_mass_shelf = 0.0
1048 delta_mass_shelf = 0.0
1051 call sum_across_pes(mean_melt_flux)
1052 call sum_across_pes(sponge_area)
1055 mean_melt_flux = (mean_melt_flux+delta_mass_shelf) / sponge_area
1058 do j=js,je ;
do i=is,ie
1060 if (g%geoLonT(i,j) >= 790.0 .AND. g%geoLonT(i,j) <= 800.0)
then
1061 fluxes%vprec(i,j) = -mean_melt_flux * cs%density_ice/1000.
1062 fluxes%sens(i,j) = fluxes%vprec(i,j) * cs%Cp * cs%T0
1064 fluxes%vprec(i,j) = us%kg_m3_to_R*us%m_to_Z*us%T_to_s * fluxes%vprec(i,j)
1065 fluxes%salt_flux(i,j) = fluxes%vprec(i,j) * cs%S0*1.0e-3
1070 write(mesg,*)
'Mean melt flux (kg/(m^2 s)), dt = ', mean_melt_flux, cs%time_step
1072 call mom_forcing_chksum(
"After constant sea level", fluxes, g, cs%US, haloshift=0)
1081 subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces, fluxes, Time_in, solo_ice_sheet_in)
1084 type(time_type),
intent(inout) :: time
1086 type(
diag_ctrl),
target,
intent(in) :: diag
1087 type(
forcing),
optional,
intent(inout) :: fluxes
1090 type(time_type),
optional,
intent(in) :: time_in
1091 logical,
optional,
intent(in) :: solo_ice_sheet_in
1103 real :: cdrag, drag_bg_vel
1104 logical :: new_sim, save_ic, var_force
1106 #include "version_variable.h"
1107 character(len=200) :: config
1108 character(len=200) :: ic_file,filename,inputdir
1109 character(len=40) :: mdl =
"MOM_ice_shelf"
1110 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed, isdq, iedq, jsdq, jedq
1111 integer :: wd_halos(2)
1112 logical :: read_tideamp, shelf_mass_is_dynamic, debug
1113 character(len=240) :: tideamp_file
1115 if (
associated(cs))
then
1116 call mom_error(fatal,
"MOM_ice_shelf.F90, initialize_ice_shelf: "// &
1117 "called with an associated control structure.")
1132 call mom_domains_init(cs%grid%domain, param_file, min_halo=wd_halos, symmetric=grid_sym_)
1137 call create_dyn_horgrid(dg, cs%grid%HI)
1144 if (
associated(ocn_grid))
then ; cs%ocn_grid => ocn_grid
1145 else ; cs%ocn_grid => cs%grid ;
endif
1153 write(0,*)
'OG: ', og%isd, og%isc, og%iec, og%ied, og%jsd, og%jsc, og%jsd, og%jed
1154 write(0,*)
'IG: ', g%isd, g%isc, g%iec, g%ied, g%jsd, g%jsc, g%jsd, g%jed
1162 cs%solo_ice_sheet = .false.
1163 if (
present(solo_ice_sheet_in)) cs%solo_ice_sheet = solo_ice_sheet_in
1165 if (
present(time_in)) time = time_in
1167 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1168 isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
1169 isdq = g%IsdB ; iedq = g%IedB ; jsdq = g%JsdB ; jedq = g%JedB
1171 cs%Lat_fusion = 3.34e5
1172 cs%override_shelf_movement = .false. ; cs%active_shelf_dynamics = .false.
1175 call get_param(param_file, mdl,
"DEBUG", debug, default=.false.)
1176 call get_param(param_file, mdl,
"DEBUG_IS", cs%debug, &
1177 "If true, write verbose debugging messages for the ice shelf.", &
1179 call get_param(param_file, mdl,
"DYNAMIC_SHELF_MASS", shelf_mass_is_dynamic, &
1180 "If true, the ice sheet mass can evolve with time.", &
1182 if (shelf_mass_is_dynamic)
then
1183 call get_param(param_file, mdl,
"OVERRIDE_SHELF_MOVEMENT", cs%override_shelf_movement, &
1184 "If true, user provided code specifies the ice-shelf "//&
1185 "movement instead of the dynamic ice model.", default=.false.)
1186 cs%active_shelf_dynamics = .not.cs%override_shelf_movement
1187 call get_param(param_file, mdl,
"GROUNDING_LINE_INTERPOLATE", cs%GL_regularize, &
1188 "If true, regularize the floatation condition at the "//&
1189 "grounding line as in Goldberg Holland Schoof 2009.", default=.false.)
1190 call get_param(param_file, mdl,
"GROUNDING_LINE_COUPLE", cs%GL_couple, &
1191 "If true, let the floatation condition be determined by "//&
1192 "ocean column thickness. This means that update_OD_ffrac "//&
1193 "will be called. GL_REGULARIZE and GL_COUPLE are exclusive.", &
1194 default=.false., do_not_log=cs%GL_regularize)
1195 if (cs%GL_regularize) cs%GL_couple = .false.
1198 call get_param(param_file, mdl,
"SHELF_THERMO", cs%isthermo, &
1199 "If true, use a thermodynamically interactive ice shelf.", &
1201 call get_param(param_file, mdl,
"SHELF_THREE_EQN", cs%threeeq, &
1202 "If true, use the three equation expression of "//&
1203 "consistency to calculate the fluxes at the ice-ocean "//&
1204 "interface.", default=.true.)
1205 call get_param(param_file, mdl,
"SHELF_INSULATOR", cs%insulator, &
1206 "If true, the ice shelf is a perfect insulatior "//&
1207 "(no conduction).", default=.false.)
1208 call get_param(param_file, mdl,
"MELTING_CUTOFF_DEPTH", cs%cutoff_depth, &
1209 "Depth above which the melt is set to zero (it must be >= 0) "//&
1210 "Default value won't affect the solution.", default=0.0)
1211 if (cs%cutoff_depth < 0.) &
1212 call mom_error(warning,
"Initialize_ice_shelf: MELTING_CUTOFF_DEPTH must be >= 0.")
1214 call get_param(param_file, mdl,
"CONST_SEA_LEVEL", cs%constant_sea_level, &
1215 "If true, apply evaporative, heat and salt fluxes in "//&
1216 "the sponge region. This will avoid a large increase "//&
1217 "in sea level. This option is needed for some of the "//&
1218 "ISOMIP+ experiments (Ocean3 and Ocean4). "//&
1219 "IMPORTANT: it is not currently possible to do "//&
1220 "prefect restarts using this flag.", default=.false.)
1222 call get_param(param_file, mdl,
"ISOMIP_S_SUR_SPONGE", &
1223 cs%S0,
"Surface salinity in the resoring region.", &
1224 default=33.8, do_not_log=.true.)
1226 call get_param(param_file, mdl,
"ISOMIP_T_SUR_SPONGE", &
1227 cs%T0,
"Surface temperature in the resoring region.", &
1228 default=-1.9, do_not_log=.true.)
1230 call get_param(param_file, mdl,
"SHELF_3EQ_GAMMA", cs%const_gamma, &
1231 "If true, user specifies a constant nondimensional heat-transfer coefficient "//&
1232 "(GAMMA_T_3EQ), from which the salt-transfer coefficient is then computed "//&
1233 " as GAMMA_T_3EQ/35. This is used with SHELF_THREE_EQN.", default=.false.)
1234 if (cs%const_gamma)
call get_param(param_file, mdl,
"SHELF_3EQ_GAMMA_T", cs%Gamma_T_3EQ, &
1235 "Nondimensional heat-transfer coefficient.",default=2.2e-2, &
1236 units=
"nondim.", fail_if_missing=.true.)
1238 call get_param(param_file, mdl,
"ICE_SHELF_MASS_FROM_FILE", &
1239 cs%mass_from_file,
"Read the mass of the "//&
1240 "ice shelf (every time step) from a file.", default=.false.)
1243 call get_param(param_file, mdl,
"SHELF_S_ROOT", cs%find_salt_root, &
1244 "If SHELF_S_ROOT = True, salinity at the ice/ocean interface (Sbdry) "//&
1245 "is computed from a quadratic equation. Otherwise, the previous "//&
1246 "interactive method to estimate Sbdry is used.", default=.false.)
1247 if (cs%find_salt_root)
then
1248 call get_param(param_file, mdl,
"TFREEZE_S0_P0",cs%lambda1, &
1249 "this is the freezing potential temperature at "//&
1250 "S=0, P=0.", units=
"degC", default=0.0, do_not_log=.true.)
1251 call get_param(param_file, mdl,
"DTFREEZE_DS",cs%lambda1, &
1252 "this is the derivative of the freezing potential "//&
1253 "temperature with salinity.", &
1254 units=
"degC psu-1", default=-0.054, do_not_log=.true.)
1255 call get_param(param_file, mdl,
"DTFREEZE_DP",cs%lambda3, &
1256 "this is the derivative of the freezing potential "//&
1257 "temperature with pressure.", &
1258 units=
"degC Pa-1", default=0.0, do_not_log=.true.)
1262 if (.not.cs%threeeq) &
1263 call get_param(param_file, mdl,
"SHELF_2EQ_GAMMA_T", cs%gamma_t, &
1264 "If SHELF_THREE_EQN is false, this the fixed turbulent "//&
1265 "exchange velocity at the ice-ocean interface.", &
1266 units=
"m s-1", fail_if_missing=.true.)
1268 call get_param(param_file, mdl,
"G_EARTH", cs%g_Earth, &
1269 "The gravitational acceleration of the Earth.", &
1270 units=
"m s-2", default = 9.80)
1271 call get_param(param_file, mdl,
"C_P", cs%Cp, &
1272 "The heat capacity of sea water.", units=
"J kg-1 K-1", &
1273 fail_if_missing=.true.)
1274 call get_param(param_file, mdl,
"RHO_0", cs%Rho0, &
1275 "The mean ocean density used with BOUSSINESQ true to "//&
1276 "calculate accelerations and the mass for conservation "//&
1277 "properties, or with BOUSSINSEQ false to convert some "//&
1278 "parameters from vertical units of m to kg m-2.", &
1279 units=
"kg m-3", default=1035.0)
1280 call get_param(param_file, mdl,
"C_P_ICE", cs%Cp_ice, &
1281 "The heat capacity of ice.", units=
"J kg-1 K-1", &
1284 call get_param(param_file, mdl,
"ICE_SHELF_FLUX_FACTOR", cs%flux_factor, &
1285 "Non-dimensional factor applied to shelf thermodynamic "//&
1286 "fluxes.", units=
"none", default=1.0)
1288 call get_param(param_file, mdl,
"KV_ICE", cs%kv_ice, &
1289 "The viscosity of the ice.", units=
"m2 s-1", default=1.0e10)
1290 call get_param(param_file, mdl,
"KV_MOLECULAR", cs%kv_molec, &
1291 "The molecular kinimatic viscosity of sea water at the "//&
1292 "freezing temperature.", units=
"m2 s-1", default=1.95e-6)
1293 call get_param(param_file, mdl,
"ICE_SHELF_SALINITY", cs%Salin_ice, &
1294 "The salinity of the ice inside the ice shelf.", units=
"psu", &
1296 call get_param(param_file, mdl,
"ICE_SHELF_TEMPERATURE", cs%Temp_ice, &
1297 "The temperature at the center of the ice shelf.", &
1298 units =
"degC", default=-15.0)
1299 call get_param(param_file, mdl,
"KD_SALT_MOLECULAR", cs%kd_molec_salt, &
1300 "The molecular diffusivity of salt in sea water at the "//&
1301 "freezing point.", units=
"m2 s-1", default=8.02e-10)
1302 call get_param(param_file, mdl,
"KD_TEMP_MOLECULAR", cs%kd_molec_temp, &
1303 "The molecular diffusivity of heat in sea water at the "//&
1304 "freezing point.", units=
"m2 s-1", default=1.41e-7)
1305 call get_param(param_file, mdl,
"RHO_0", cs%density_ocean_avg, &
1306 "avg ocean density used in floatation cond", &
1307 units=
"kg m-3", default=1035.)
1308 call get_param(param_file, mdl,
"DT_FORCING", cs%time_step, &
1309 "The time step for changing forcing, coupling with other "//&
1310 "components, or potentially writing certain diagnostics. "//&
1311 "The default value is given by DT.", units=
"s", default=0.0)
1313 call get_param(param_file, mdl,
"COL_THICK_MELT_THRESHOLD", cs%col_thick_melt_threshold, &
1314 "The minimum ML thickness where melting is allowed.", units=
"m", &
1317 call get_param(param_file, mdl,
"READ_TIDEAMP", read_tideamp, &
1318 "If true, read a file (given by TIDEAMP_FILE) containing "//&
1319 "the tidal amplitude with INT_TIDE_DISSIPATION.", default=.false.)
1321 call safe_alloc_ptr(cs%utide,isd,ied,jsd,jed) ; cs%utide(:,:) = 0.0
1323 if (read_tideamp)
then
1324 call get_param(param_file, mdl,
"TIDEAMP_FILE", tideamp_file, &
1325 "The path to the file containing the spatially varying "//&
1326 "tidal amplitudes.", &
1327 default=
"tideamp.nc")
1328 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
1329 inputdir = slasher(inputdir)
1330 tideamp_file = trim(inputdir) // trim(tideamp_file)
1331 call mom_read_data(tideamp_file,
'tideamp',cs%utide,g%domain,timelevel=1)
1333 call get_param(param_file, mdl,
"UTIDE", utide, &
1334 "The constant tidal amplitude used with INT_TIDE_DISSIPATION.", &
1335 units=
"m s-1", default=0.0)
1336 cs%utide(:,:) = utide
1339 call eos_init(param_file, cs%eqn_of_state)
1343 if (cs%active_shelf_dynamics)
then
1345 call get_param(param_file, mdl,
"DENSITY_ICE", cs%density_ice, &
1346 "A typical density of ice.", units=
"kg m-3", default=917.0)
1348 call get_param(param_file, mdl,
"INPUT_FLUX_ICE_SHELF", cs%input_flux, &
1349 "volume flux at upstream boundary", units=
"m2 s-1", default=0.)
1350 call get_param(param_file, mdl,
"INPUT_THICK_ICE_SHELF", cs%input_thickness, &
1351 "flux thickness at upstream boundary", units=
"m", default=1000.)
1354 call get_param(param_file, mdl,
"DENSITY_ICE", cs%density_ice, &
1355 "A typical density of ice.", units=
"kg m-3", default=900.0)
1357 cs%rho_ice = cs%density_ice*us%Z_to_m
1358 call get_param(param_file, mdl,
"MIN_THICKNESS_SIMPLE_CALVE", &
1359 cs%min_thickness_simple_calve, &
1360 "Min thickness rule for the very simple calving law",&
1361 units=
"m", default=0.0, scale=us%m_to_Z)
1363 call get_param(param_file, mdl,
"USTAR_SHELF_BG", cs%ustar_bg, &
1364 "The minimum value of ustar under ice sheves.", &
1365 units=
"m s-1", default=0.0, scale=us%m_to_Z*us%T_to_s)
1366 call get_param(param_file, mdl,
"CDRAG_SHELF", cdrag, &
1367 "CDRAG is the drag coefficient relating the magnitude of "//&
1368 "the velocity field to the surface stress.", units=
"nondim", &
1371 if (cs%ustar_bg <= 0.0)
then
1372 call get_param(param_file, mdl,
"DRAG_BG_VEL_SHELF", drag_bg_vel, &
1373 "DRAG_BG_VEL is either the assumed bottom velocity (with "//&
1374 "LINEAR_DRAG) or an unresolved velocity that is "//&
1375 "combined with the resolved velocity to estimate the "//&
1376 "velocity magnitude.", units=
"m s-1", default=0.0, scale=us%m_to_Z*us%T_to_s)
1377 if (cs%cdrag*drag_bg_vel > 0.0) cs%ustar_bg = sqrt(cs%cdrag)*drag_bg_vel
1385 if (.not. cs%solo_ice_sheet)
then
1386 call mom_mesg(
"MOM_ice_shelf.F90, initialize_ice_shelf: allocating fluxes.")
1390 if (
present(fluxes)) &
1391 call allocate_forcing_type(cs%ocn_grid, fluxes, ustar=.true., shelf=.true., &
1392 press=.true., water=cs%isthermo, heat=cs%isthermo)
1393 if (
present(forces)) &
1394 call allocate_mech_forcing(cs%ocn_grid, forces, ustar=.true., shelf=.true., press=.true.)
1396 call mom_mesg(
"MOM_ice_shelf.F90, initialize_ice_shelf: allocating fluxes in solo mode.")
1397 if (
present(fluxes)) &
1398 call allocate_forcing_type(g, fluxes, ustar=.true., shelf=.true., press=.true.)
1399 if (
present(forces)) &
1400 call allocate_mech_forcing(g, forces, ustar=.true., shelf=.true., press=.true.)
1404 call mom_initialize_topography(dg%bathyT, g%max_depth, dg, param_file)
1408 call mom_initialize_rotation(dg%CoriolisBu, dg, param_file, us)
1412 call destroy_dyn_horgrid(dg)
1415 call restart_init(param_file, cs%restart_CSp,
"Shelf.res")
1417 "Ice shelf mass",
"kg m-2")
1419 "Ice shelf area in cell",
"m2")
1421 "ice sheet/shelf thickness",
"m")
1423 "Height unit conversion factor",
"Z meter-1")
1424 if (cs%active_shelf_dynamics)
then
1426 "ice sheet/shelf thickness mask" ,
"none")
1431 call register_ice_shelf_dyn_restarts(g, param_file, cs%dCS, cs%restart_CSp)
1442 cs%restart_output_dir = dirs%restart_output_dir
1445 if ((dirs%input_filename(1:1) ==
'n') .and. &
1446 (len_trim(dirs%input_filename) == 1)) new_sim = .true.
1448 if (cs%override_shelf_movement .and. cs%mass_from_file)
then
1458 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
1459 if ((iss%hmask(i,j) == 1) .or. (iss%hmask(i,j) == 2))
then
1460 iss%mass_shelf(i,j) = iss%h_shelf(i,j)*cs%rho_ice
1464 if (cs%min_thickness_simple_calve > 0.0) &
1465 call ice_shelf_min_thickness_calve(g, iss%h_shelf, iss%area_shelf_h, iss%hmask, &
1466 cs%min_thickness_simple_calve)
1470 if (cs%active_shelf_dynamics)
then
1480 if (new_sim .and. (.not. (cs%override_shelf_movement .and. cs%mass_from_file)))
then
1486 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
1487 if ((iss%hmask(i,j) == 1) .or. (iss%hmask(i,j) == 2))
then
1488 iss%mass_shelf(i,j) = iss%h_shelf(i,j)*cs%rho_ice
1493 elseif (.not.new_sim)
then
1495 call mom_mesg(
"MOM_ice_shelf.F90, initialize_ice_shelf: Restoring ice shelf from file.")
1496 call restore_state(dirs%input_filename, dirs%restart_input_dir, time, &
1499 if ((us%m_to_Z_restart /= 0.0) .and. (us%m_to_Z_restart /= us%m_to_Z))
then
1500 z_rescale = us%m_to_Z / us%m_to_Z_restart
1501 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
1502 iss%h_shelf(i,j) = z_rescale * iss%h_shelf(i,j)
1511 call pass_var(iss%area_shelf_h, g%domain)
1512 call pass_var(iss%h_shelf, g%domain)
1513 call pass_var(iss%mass_shelf, g%domain)
1518 do j=jsd,jed ;
do i=isd,ied
1519 if (iss%area_shelf_h(i,j) > us%L_to_m**2*g%areaT(i,j))
then
1520 call mom_error(warning,
"Initialize_ice_shelf: area_shelf_h exceeds G%areaT.")
1521 iss%area_shelf_h(i,j) = us%L_to_m**2*g%areaT(i,j)
1524 if (
present(fluxes))
then ;
do j=jsd,jed ;
do i=isd,ied
1525 if (g%areaT(i,j) > 0.0) fluxes%frac_shelf_h(i,j) = iss%area_shelf_h(i,j) / (us%L_to_m**2*g%areaT(i,j))
1526 enddo ;
enddo ;
endif
1529 call hchksum(fluxes%frac_shelf_h,
"IS init: frac_shelf_h", g%HI, haloshift=0)
1532 if (
present(forces)) &
1533 call add_shelf_forces(g, us, cs, forces, do_shelf_area=.not.cs%solo_ice_sheet)
1537 if (cs%active_shelf_dynamics .and. .not.cs%isthermo)
then
1538 iss%water_flux(:,:) = 0.0
1541 if (shelf_mass_is_dynamic) &
1542 call initialize_ice_shelf_dyn(param_file, time, iss, cs%dCS, g, us, diag, new_sim, solo_ice_sheet_in)
1546 call get_param(param_file, mdl,
"SAVE_INITIAL_CONDS", save_ic, &
1547 "If true, save the ice shelf initial conditions.", &
1549 if (save_ic)
call get_param(param_file, mdl,
"SHELF_IC_OUTPUT_FILE", ic_file,&
1550 "The name-root of the output file for the ice shelf "//&
1551 "initial conditions.", default=
"MOM_Shelf_IC")
1553 if (save_ic .and. .not.((dirs%input_filename(1:1) ==
'r') .and. &
1554 (len_trim(dirs%input_filename) == 1)))
then
1555 call save_restart(dirs%output_directory, cs%Time, g, &
1556 cs%restart_CSp, filename=ic_file)
1560 cs%id_area_shelf_h = register_diag_field(
'ocean_model',
'area_shelf_h', cs%diag%axesT1, cs%Time, &
1561 'Ice Shelf Area in cell',
'meter-2')
1562 cs%id_shelf_mass = register_diag_field(
'ocean_model',
'shelf_mass', cs%diag%axesT1, cs%Time, &
1563 'mass of shelf',
'kg/m^2')
1564 cs%id_h_shelf = register_diag_field(
'ocean_model',
'h_shelf', cs%diag%axesT1, cs%Time, &
1565 'ice shelf thickness',
'm', conversion=us%Z_to_m)
1566 cs%id_mass_flux = register_diag_field(
'ocean_model',
'mass_flux', cs%diag%axesT1,&
1567 cs%Time,
'Total mass flux of freshwater across the ice-ocean interface.',
'kg/s')
1568 cs%id_melt = register_diag_field(
'ocean_model',
'melt', cs%diag%axesT1, cs%Time, &
1569 'Ice Shelf Melt Rate',
'm yr-1')
1570 cs%id_thermal_driving = register_diag_field(
'ocean_model',
'thermal_driving', cs%diag%axesT1, cs%Time, &
1571 'pot. temp. in the boundary layer minus freezing pot. temp. at the ice-ocean interface.',
'Celsius')
1572 cs%id_haline_driving = register_diag_field(
'ocean_model',
'haline_driving', cs%diag%axesT1, cs%Time, &
1573 'salinity in the boundary layer minus salinity at the ice-ocean interface.',
'psu')
1574 cs%id_Sbdry = register_diag_field(
'ocean_model',
'sbdry', cs%diag%axesT1, cs%Time, &
1575 'salinity at the ice-ocean interface.',
'psu')
1576 cs%id_u_ml = register_diag_field(
'ocean_model',
'u_ml', cs%diag%axesCu1, cs%Time, &
1577 'Eastward vel. in the boundary layer (used to compute ustar)',
'm s-1')
1578 cs%id_v_ml = register_diag_field(
'ocean_model',
'v_ml', cs%diag%axesCv1, cs%Time, &
1579 'Northward vel. in the boundary layer (used to compute ustar)',
'm s-1')
1580 cs%id_exch_vel_s = register_diag_field(
'ocean_model',
'exch_vel_s', cs%diag%axesT1, cs%Time, &
1581 'Sub-shelf salinity exchange velocity',
'm s-1')
1582 cs%id_exch_vel_t = register_diag_field(
'ocean_model',
'exch_vel_t', cs%diag%axesT1, cs%Time, &
1583 'Sub-shelf thermal exchange velocity',
'm s-1')
1584 cs%id_tfreeze = register_diag_field(
'ocean_model',
'tfreeze', cs%diag%axesT1, cs%Time, &
1585 'In Situ Freezing point at ice shelf interface',
'degC')
1586 cs%id_tfl_shelf = register_diag_field(
'ocean_model',
'tflux_shelf', cs%diag%axesT1, cs%Time, &
1587 'Heat conduction into ice shelf',
'W m-2')
1588 cs%id_ustar_shelf = register_diag_field(
'ocean_model',
'ustar_shelf', cs%diag%axesT1, cs%Time, &
1589 'Fric vel under shelf',
'm/s', conversion=us%Z_to_m*us%s_to_T)
1590 if (cs%active_shelf_dynamics)
then
1591 cs%id_h_mask = register_diag_field(
'ocean_model',
'h_mask', cs%diag%axesT1, cs%Time, &
1592 'ice shelf thickness mask',
'none')
1595 id_clock_shelf = cpu_clock_id(
'Ice shelf', grain=clock_component)
1596 id_clock_pass = cpu_clock_id(
' Ice shelf halo updates', grain=clock_routine)
1607 logical,
optional,
intent(in) :: new_sim
1609 integer :: i, j, is, ie, js, je
1610 logical :: read_shelf_area, new_sim_2
1611 character(len=240) :: config, inputdir, shelf_file, filename
1612 character(len=120) :: shelf_mass_var
1613 character(len=120) :: shelf_area_var
1614 character(len=40) :: mdl =
"MOM_ice_shelf"
1615 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1617 new_sim_2 = .true. ;
if (
present(new_sim)) new_sim_2 = new_sim
1619 call get_param(param_file, mdl,
"ICE_SHELF_CONFIG", config, &
1620 "A string that specifies how the ice shelf is "//&
1621 "initialized. Valid options include:\n"//&
1622 " \tfile\t Read from a file.\n"//&
1623 " \tzero\t Set shelf mass to 0 everywhere.\n"//&
1624 " \tUSER\t Call USER_initialize_shelf_mass.\n", &
1625 fail_if_missing=.true.)
1627 select case ( trim(config) )
1630 call time_interp_external_init()
1632 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
1633 inputdir = slasher(inputdir)
1635 call get_param(param_file, mdl,
"SHELF_FILE", shelf_file, &
1636 "If DYNAMIC_SHELF_MASS = True, OVERRIDE_SHELF_MOVEMENT = True "//&
1637 "and ICE_SHELF_MASS_FROM_FILE = True, this is the file from "//&
1638 "which to read the shelf mass and area.", &
1639 default=
"shelf_mass.nc")
1640 call get_param(param_file, mdl,
"SHELF_MASS_VAR", shelf_mass_var, &
1641 "The variable in SHELF_FILE with the shelf mass.", &
1642 default=
"shelf_mass")
1643 call get_param(param_file, mdl,
"READ_SHELF_AREA", read_shelf_area, &
1644 "If true, also read the area covered by ice-shelf from SHELF_FILE.", &
1647 filename = trim(slasher(inputdir))//trim(shelf_file)
1648 call log_param(param_file, mdl,
"INPUTDIR/SHELF_FILE", filename)
1650 cs%id_read_mass = init_external_field(filename, shelf_mass_var, &
1651 domain=g%Domain%mpp_domain, verbose=cs%debug)
1653 if (read_shelf_area)
then
1654 call get_param(param_file, mdl,
"SHELF_AREA_VAR", shelf_area_var, &
1655 "The variable in SHELF_FILE with the shelf area.", &
1656 default=
"shelf_area")
1658 cs%id_read_area = init_external_field(filename,shelf_area_var, &
1659 domain=g%Domain%mpp_domain)
1663 " initialize_shelf_mass: Unable to open "//trim(filename))
1666 do j=js,je ;
do i=is,ie
1667 iss%mass_shelf(i,j) = 0.0
1668 iss%area_shelf_h(i,j) = 0.0
1672 call user_initialize_shelf_mass(iss%mass_shelf, iss%area_shelf_h, &
1673 iss%h_shelf, iss%hmask, g, cs%US, cs%user_CS, param_file, new_sim_2)
1675 case default ;
call mom_error(fatal,
"initialize_ice_shelf: "// &
1676 "Unrecognized ice shelf setup "//trim(config))
1686 type(time_type),
intent(in) :: Time
1689 integer :: i, j, is, ie, js, je
1690 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1692 call time_interp_external(cs%id_read_mass, time, iss%mass_shelf)
1694 do j=js,je ;
do i=is,ie
1695 iss%area_shelf_h(i,j) = 0.0
1697 if (iss%mass_shelf(i,j) > 0.0)
then
1698 iss%area_shelf_h(i,j) = g%US%L_to_m**2*g%areaT(i,j)
1699 iss%h_shelf(i,j) = iss%mass_shelf(i,j) / cs%rho_ice
1707 if (cs%min_thickness_simple_calve > 0.0)
then
1708 call ice_shelf_min_thickness_calve(g, iss%h_shelf, iss%area_shelf_h, iss%hmask, &
1709 cs%min_thickness_simple_calve)
1712 call pass_var(iss%area_shelf_h, g%domain)
1713 call pass_var(iss%h_shelf, g%domain)
1715 call pass_var(iss%mass_shelf, g%domain)
1722 type(time_type),
intent(in) :: time
1723 character(len=*),
optional,
intent(in) :: directory
1725 logical,
optional,
intent(in) :: time_stamped
1727 character(len=*),
optional,
intent(in) :: filename_suffix
1731 character(len=200) :: restart_dir
1735 if (
present(directory))
then ; restart_dir = directory
1736 else ; restart_dir = cs%restart_output_dir ;
endif
1738 call save_restart(restart_dir, time, cs%grid, cs%restart_CSp, time_stamped)
1746 if (.not.
associated(cs))
return
1757 subroutine solo_time_step(CS, time_step, nsteps, Time, min_time_step_in)
1759 real,
intent(in) :: time_step
1760 integer,
intent(inout) :: nsteps
1761 type(time_type),
intent(inout) :: time
1762 real,
optional,
intent(in) :: min_time_step_in
1769 integer :: is, iec, js, jec, i, j
1770 real :: time_step_remain
1771 real :: time_step_int, min_time_step
1772 character(len=240) :: mesg
1773 logical :: update_ice_vel
1774 logical :: coupled_gl
1780 is = g%isc ; iec = g%iec ; js = g%jsc ; jec = g%jec
1782 time_step_remain = time_step
1783 if (
present (min_time_step_in))
then
1784 min_time_step = min_time_step_in
1786 min_time_step = 1000.0
1789 write (mesg,*)
"TIME in ice shelf call, yrs: ", time_type_to_real(time)/(365. * 86400.)
1790 call mom_mesg(
"solo_time_step: "//mesg)
1792 do while (time_step_remain > 0.0)
1798 write (mesg,*)
"Ice model timestep = ", time_step_int,
" seconds"
1799 if (time_step_int < min_time_step)
then
1800 call mom_error(fatal,
"MOM_ice_shelf:solo_time_step: abnormally small timestep "//mesg)
1802 call mom_mesg(
"solo_time_step: "//mesg)
1805 if (time_step_int >= time_step_remain)
then
1806 time_step_int = time_step_remain
1807 time_step_remain = 0.0
1809 time_step_remain = time_step_remain - time_step_int
1814 update_ice_vel = ((time_step_int > min_time_step) .or. (time_step_int >= time_step))
1815 coupled_gl = .false.
1817 call update_ice_shelf(cs%dCS, iss, g, us, time_step_int, time, must_update_vel=update_ice_vel)
1820 if (cs%id_area_shelf_h > 0)
call post_data(cs%id_area_shelf_h, iss%area_shelf_h, cs%diag)
1821 if (cs%id_h_shelf > 0)
call post_data(cs%id_h_shelf, iss%h_shelf, cs%diag)
1822 if (cs%id_h_mask > 0)
call post_data(cs%id_h_mask, iss%hmask, cs%diag)