28 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
30 use mom_cpu_clock, only : clock_module_driver, clock_module, clock_routine
43 use mom_domains, only : to_north, to_east, to_south, to_west
61 use mom_time_manager, only : time_type, set_time, time_type_to_real,
operator(+)
62 use mom_time_manager, only :
operator(-),
operator(>),
operator(*),
operator(/)
94 use mom_eos, only : gsw_sp_from_sr, gsw_pt_from_ct
143 implicit none ;
private 145 #include <MOM_memory.h> 149 real allocable_,
dimension(NIMEM_,NJMEM_,NKMEM_) :: &
150 h, & !< layer thickness (m or kg/m2 (H))
151 t, & !< potential temperature (degrees C)
153 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: &
154 u, & !< zonal velocity component (m/s)
155 uh, & !< uh = u * h * dy at u grid points (m3/s or kg/s)
157 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: &
158 v, & !< meridional velocity (m/s)
159 vh, & !< vh = v * h * dx at v grid points (m3/s or kg/s)
161 real allocable_,
dimension(NIMEM_,NJMEM_) :: &
163 real,
pointer,
dimension(:,:) :: hml => null()
164 real,
pointer,
dimension(:,:,:) :: &
183 logical :: legacy_split
190 logical :: use_temperature
191 logical :: calc_rho_for_sea_lev
192 logical :: use_frazil
194 logical :: bound_salinity
196 logical :: bulkmixedlayer
198 logical :: diabatic_first
200 logical :: use_cont_abss
205 logical :: thickness_diffuse_first
206 logical :: mixedlayer_restrat
209 logical :: debug_truncations
210 logical :: use_ale_algorithm
214 logical :: do_dynamics
216 logical :: offline_tracer_mode = .false.
223 logical :: thermo_spans_coupling
225 real :: t_dyn_rel_adv
230 real :: t_dyn_rel_thermo
235 real :: t_dyn_rel_diag
238 type(time_type) :: z_diag_interval
239 type(time_type) :: z_diag_time
240 type(time_type),
pointer :: time
241 real :: rel_time = 0.0
242 real :: dtbt_reset_period
247 logical :: interp_p_surf
250 logical :: p_surf_prev_set
259 real :: missing=-1.0e34
263 character(len=120) :: ic_file
267 logical :: check_bad_surface_vals
268 real :: bad_val_ssh_max
269 real :: bad_val_sst_max
270 real :: bad_val_sst_min
271 real :: bad_val_sss_max
272 real :: bad_val_column_thickness
274 real,
pointer,
dimension(:,:) :: &
275 p_surf_prev => null(), &
276 p_surf_begin => null(), &
280 vd_t, & !< vardesc array describing potential temperature
283 real,
pointer,
dimension(:,:,:) :: & !< diagnostic arrays of advective/diffusive tracer fluxes
284 t_adx => null(), t_ady => null(), t_diffx => null(), t_diffy => null(), &
285 s_adx => null(), s_ady => null(), s_diffx => null(), s_diffy => null()
287 real,
pointer,
dimension(:,:) :: & !< diagnostic arrays of vertically integrated advective/diffusive fluxes
288 t_adx_2d => null(), t_ady_2d => null(), t_diffx_2d => null(), t_diffy_2d => null(), &
289 s_adx_2d => null(), s_ady_2d => null(), s_diffx_2d => null(), s_diffy_2d => null()
291 real,
pointer,
dimension(:,:,:) :: & !< diagnostic arrays for advection tendencies and total tendencies
292 t_advection_xy => null(), s_advection_xy => null(), &
293 t_prev => null(), s_prev => null(), &
294 th_prev => null(), sh_prev => null()
296 real,
pointer,
dimension(:,:,:) :: & !< diagnostic arrays for variance decay through ALE
297 t_squared => null(), s_squared => null()
299 logical :: tendency_diagnostics = .false.
309 integer :: id_tcon = -1
310 integer :: id_sabs = -1
313 integer :: id_zos = -1
314 integer :: id_zossq = -1
315 integer :: id_volo = -1
316 integer :: id_ssh = -1
317 integer :: id_ssh_ga = -1
318 integer :: id_sst = -1
319 integer :: id_sst_sq = -1
320 integer :: id_sss = -1
321 integer :: id_sss_sq = -1
322 integer :: id_ssu = -1
323 integer :: id_ssv = -1
324 integer :: id_speed = -1
325 integer :: id_ssh_inst = -1
326 integer :: id_tob = -1
327 integer :: id_sob = -1
328 integer :: id_sstcon = -1
329 integer :: id_sssabs = -1
332 integer :: id_fraz = -1
333 integer :: id_salt_deficit = -1
334 integer :: id_heat_pme = -1
335 integer :: id_intern_heat = -1
338 integer :: id_tadx = -1
339 integer :: id_tady = -1
340 integer :: id_tdiffx = -1
341 integer :: id_tdiffy = -1
342 integer :: id_sadx = -1
343 integer :: id_sady = -1
344 integer :: id_sdiffx = -1
345 integer :: id_sdiffy = -1
346 integer :: id_tadx_2d = -1
347 integer :: id_tady_2d = -1
348 integer :: id_tdiffx_2d = -1
349 integer :: id_tdiffy_2d = -1
350 integer :: id_sadx_2d = -1
351 integer :: id_sady_2d = -1
352 integer :: id_sdiffx_2d = -1
353 integer :: id_sdiffy_2d = -1
356 integer :: id_t_advection_xy = -1
357 integer :: id_t_advection_xy_2d = -1
358 integer :: id_t_tendency = -1
359 integer :: id_th_tendency = -1
360 integer :: id_th_tendency_2d = -1
361 integer :: id_s_advection_xy = -1
362 integer :: id_s_advection_xy_2d = -1
363 integer :: id_s_tendency = -1
364 integer :: id_sh_tendency = -1
365 integer :: id_sh_tendency_2d = -1
368 integer :: id_t_vardec = -1
369 integer :: id_s_vardec = -1
372 integer :: id_h_pre_dyn = -1
375 integer :: id_u_predia = -1
376 integer :: id_v_predia = -1
377 integer :: id_h_predia = -1
378 integer :: id_t_predia = -1
379 integer :: id_s_predia = -1
380 integer :: id_e_predia = -1
381 integer :: id_u_preale = -1
382 integer :: id_v_preale = -1
383 integer :: id_h_preale = -1
384 integer :: id_t_preale = -1
385 integer :: id_s_preale = -1
386 integer :: id_e_preale = -1
389 integer :: id_uhtr = -1, id_umo = -1, id_umo_2d = 1
390 integer :: id_vhtr = -1, id_vmo = -1, id_vmo_2d = 1
416 type(
ale_cs),
pointer :: ale_csp => null()
420 type(group_pass_type) :: pass_tau_ustar_psurf
421 type(group_pass_type) :: pass_ray
422 type(group_pass_type) :: pass_bbl_thick_kv_bbl
423 type(group_pass_type) :: pass_t_s_h
424 type(group_pass_type) :: pass_t_s
425 type(group_pass_type) :: pass_kv_turb
426 type(group_pass_type) :: pass_uv_t_s_h
427 type(group_pass_type) :: pass_ssh
465 subroutine step_mom(fluxes, state, Time_start, time_interval, CS)
467 type(
surface),
intent(inout) :: state
468 type(time_type),
intent(in) :: Time_start
469 real,
intent(in) :: time_interval
476 integer,
save :: nt_debug = 1
480 integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, n
481 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
487 real :: dtbt_reset_time
489 real :: mass_src_time
496 real :: wt_end, wt_beg
502 logical :: do_advection
503 logical :: do_calc_bbl
504 logical :: thermo_does_span_coupling
506 real,
dimension(SZI_(CS%G),SZJ_(CS%G)) :: &
510 real,
pointer,
dimension(:,:,:) :: &
517 real,
dimension(SZI_(CS%G),SZJ_(CS%G),SZK_(CS%G)) :: h_pre_dyn
518 real :: tot_wt_ssh, Itot_wt_ssh
520 type(time_type) :: Time_local
521 logical :: showCallTree
523 logical :: do_pass_kv_turb, do_pass_Ray, do_pass_kv_bbl_thick
525 g => cs%G ; gv => cs%GV
526 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
527 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
528 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
529 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
530 u => cs%u ; v => cs%v ; h => cs%h
536 call mom_state_chksum(
"Beginning of step_MOM ", u, v, h, cs%uh, cs%vh, g, gv)
537 call hchksum(cs%h,
"CS%h beginning of step_MOM",g%HI, scale=gv%H_to_m)
540 showcalltree = calltree_showquery()
547 if (time_interval <= cs%dt)
then 550 n_max = ceiling(time_interval/cs%dt - 0.001)
553 dt = time_interval /
real(n_max)
555 thermo_does_span_coupling = (cs%thermo_spans_coupling .and. &
556 (cs%dt_therm > 1.5*time_interval))
557 if (thermo_does_span_coupling)
then 559 dt_therm = time_interval * floor(cs%dt_therm / time_interval + 0.001)
560 ntstep = floor(dt_therm/dt + 0.001)
562 ntstep = max(1,min(n_max,floor(cs%dt_therm/dt + 0.001)))
566 if (.not.
ASSOCIATED(fluxes%p_surf)) cs%interp_p_surf = .false.
571 call create_group_pass(cs%pass_tau_ustar_psurf, fluxes%taux, fluxes%tauy, g%Domain)
572 if (
ASSOCIATED(fluxes%ustar)) &
574 if (
ASSOCIATED(fluxes%p_surf)) &
577 do_pass_ray = .false.
578 if ((.not.g%Domain%symmetric) .and. &
579 associated(cs%visc%Ray_u) .and.
associated(cs%visc%Ray_v))
then 581 to_north+to_east+scalar_pair+omit_corners, cgrid_ne, halo=1)
584 do_pass_kv_bbl_thick = .false.
585 if (
associated(cs%visc%bbl_thick_u) .and.
associated(cs%visc%bbl_thick_v))
then 587 cs%visc%bbl_thick_v, g%Domain, &
588 to_north+to_east+scalar_pair+omit_corners, cgrid_ne, halo=1)
589 do_pass_kv_bbl_thick = .true.
591 if (
associated(cs%visc%kv_bbl_u) .and.
associated(cs%visc%kv_bbl_v))
then 593 cs%visc%kv_bbl_v, g%Domain, &
594 to_north+to_east+scalar_pair+omit_corners, cgrid_ne, halo=1)
595 do_pass_kv_bbl_thick = .true.
597 do_pass_kv_turb =
associated(cs%visc%Kv_turb)
598 if (
associated(cs%visc%Kv_turb)) &
599 call create_group_pass(cs%pass_kv_turb, cs%visc%Kv_turb, g%Domain, to_all+omit_corners, halo=1)
601 if (.not.cs%adiabatic .AND. cs%use_ALE_algorithm )
then 602 if (cs%use_temperature)
then 603 call create_group_pass(cs%pass_T_S_h, cs%tv%T, g%Domain, to_all+omit_corners, halo=1)
604 call create_group_pass(cs%pass_T_S_h, cs%tv%S, g%Domain, to_all+omit_corners, halo=1)
609 if ((cs%adiabatic .OR. cs%diabatic_first) .AND. cs%use_temperature)
then 617 if (g%nonblocking_updates)
then 620 call do_group_pass(cs%pass_tau_ustar_psurf, g%Domain)
624 if (
ASSOCIATED(cs%tv%frazil)) cs%tv%frazil(:,:) = 0.0
625 if (
ASSOCIATED(cs%tv%salt_deficit)) cs%tv%salt_deficit(:,:) = 0.0
626 if (
ASSOCIATED(cs%tv%TempxPmE)) cs%tv%TempxPmE(:,:) = 0.0
627 if (
ASSOCIATED(cs%tv%internal_heat)) cs%tv%internal_heat(:,:) = 0.0
632 do j=js,je ;
do i=is,ie ; cs%ave_ssh(i,j) = 0.0 ; ssh(i,j) = cs%missing;
enddo ;
enddo 634 if (
associated(cs%VarMix))
then 635 call enable_averaging(time_interval, time_start+set_time(int(time_interval)), &
638 call disable_averaging(cs%diag)
641 if (g%nonblocking_updates)
then 647 if (cs%interp_p_surf)
then 648 if (.not.
ASSOCIATED(cs%p_surf_end))
allocate(cs%p_surf_end(isd:ied,jsd:jed))
649 if (.not.
ASSOCIATED(cs%p_surf_begin))
allocate(cs%p_surf_begin(isd:ied,jsd:jed))
650 if (.not.cs%p_surf_prev_set)
then 651 do j=jsd,jed ;
do i=isd,ied
652 cs%p_surf_prev(i,j) = fluxes%p_surf(i,j)
654 cs%p_surf_prev_set = .true.
657 cs%p_surf_end => fluxes%p_surf
670 nt_debug = nt_debug + 1
673 cs%Time = time_start + set_time(int(floor(cs%rel_time+0.5*dt+0.5)))
674 cs%rel_time = cs%rel_time + dt
677 time_local = time_start + set_time(int(floor(cs%rel_time+0.5)))
678 if (showcalltree)
call calltree_enter(
"DT cycles (step_MOM) n=",n)
682 if (cs%diabatic_first .and. (cs%t_dyn_rel_adv==0.0))
then 684 if (thermo_does_span_coupling)
then 686 if ((fluxes%dt_buoy_accum > 0.0) .and. (dtdia > time_interval) .and. &
687 (abs(fluxes%dt_buoy_accum - dtdia) > 1e-6*dtdia))
then 688 call mom_error(fatal,
"step_MOM: Mismatch between long thermodynamic "//&
689 "timestep and time over which buoyancy fluxes have been accumulated.")
691 call mom_error(fatal,
"MOM is not yet set up to have restarts that work "//&
692 "with THERMO_SPANS_COUPLING and DIABATIC_FIRST.")
694 dtdia = dt*min(ntstep,n_max-(n-1))
699 call enable_averaging(dtdia, time_local + &
700 set_time(int(floor(dtdia-dt+0.5))), cs%diag)
703 call uvchksum(
"Pre set_viscous_BBL [uv]", u, v, g%HI, haloshift=1)
704 call hchksum(h,
"Pre set_viscous_BBL h", g%HI, haloshift=1, scale=gv%H_to_m)
705 if (
associated(cs%tv%T))
call hchksum(cs%tv%T,
"Pre set_viscous_BBL T", g%HI, haloshift=1)
706 if (
associated(cs%tv%S))
call hchksum(cs%tv%S,
"Pre set_viscous_BBL S", g%HI, haloshift=1)
714 call set_viscous_bbl(u, v, h, cs%tv, cs%visc, g, gv, cs%set_visc_CSp)
718 if (do_pass_ray)
call do_group_pass(cs%pass_ray, g%Domain )
719 if (do_pass_kv_bbl_thick)
call do_group_pass(cs%pass_bbl_thick_kv_bbl, g%Domain)
721 if (showcalltree)
call calltree_waypoint(
"done with set_viscous_BBL (diabatic_first)")
726 if (cs%split .and. cs%legacy_split .and. .not.cs%adiabatic)
then 734 cs%t_dyn_rel_thermo = -dtdia
737 call disable_averaging(cs%diag)
746 call disable_averaging(cs%diag)
748 if (cs%thickness_diffuse .and. cs%thickness_diffuse_first)
then 749 if (cs%t_dyn_rel_adv == 0.0)
then 750 if (thermo_does_span_coupling)
then 753 dtth = dt*min(ntstep,n_max-n+1)
756 call enable_averaging(dtth,time_local+set_time(int(floor(dtth-dt+0.5))), cs%diag)
758 if (
associated(cs%VarMix)) &
759 call calc_slope_functions(h, cs%tv, dt, g, gv, cs%VarMix)
761 cs%MEKE, cs%VarMix, cs%CDp, cs%thickness_diffuse_CSp)
766 call disable_averaging(cs%diag)
767 if (showcalltree)
call calltree_waypoint(
"finished thickness_diffuse_first (step_MOM)")
771 call diag_update_remap_grids(cs%diag)
779 do_calc_bbl = ((cs%t_dyn_rel_adv == 0.0) .or. (n==1))
780 if (do_calc_bbl)
then 783 bbl_time_int = max(dt, min(dt_therm - cs%t_dyn_rel_adv, dt*(1+n_max-n)) )
784 call enable_averaging(bbl_time_int, &
785 time_local+set_time(int(bbl_time_int-dt+0.5)), cs%diag)
786 call set_viscous_bbl(u, v, h, cs%tv, cs%visc, g, gv, cs%set_visc_CSp)
787 call disable_averaging(cs%diag)
793 if (do_pass_kv_turb)
call do_group_pass(cs%pass_kv_turb, g%Domain)
796 if (do_calc_bbl)
then 798 if (g%nonblocking_updates)
then 800 if (do_pass_kv_bbl_thick)
call start_group_pass(cs%pass_bbl_thick_kv_bbl, g%Domain)
803 if (do_pass_ray)
call do_group_pass(cs%pass_Ray, g%Domain)
804 if (do_pass_kv_bbl_thick)
call do_group_pass(cs%pass_bbl_thick_kv_bbl, g%Domain)
809 if (cs%interp_p_surf)
then 810 wt_end =
real(n) /
real(n_max)
811 wt_beg =
real(n-1) /
real(n_max)
812 do j=jsd,jed ;
do i=isd,ied
813 cs%p_surf_end(i,j) = wt_end * fluxes%p_surf(i,j) + &
814 (1.0-wt_end) * cs%p_surf_prev(i,j)
815 cs%p_surf_begin(i,j) = wt_beg * fluxes%p_surf(i,j) + &
816 (1.0-wt_beg) * cs%p_surf_prev(i,j)
820 if (
associated(cs%u_prev) .and.
associated(cs%v_prev))
then 821 do k=1,nz ;
do j=jsd,jed ;
do i=isdb,iedb
822 cs%u_prev(i,j,k) = u(i,j,k)
823 enddo ;
enddo ;
enddo 824 do k=1,nz ;
do j=jsdb,jedb ;
do i=isd,ied
825 cs%v_prev(i,j,k) = u(i,j,k)
826 enddo ;
enddo ;
enddo 830 do k=1,nz ;
do j=jsd,jed ;
do i=isd,ied
831 h_pre_dyn(i,j,k) = h(i,j,k)
832 enddo ;
enddo ;
enddo 834 if (g%nonblocking_updates)
then ;
if (do_calc_bbl)
then 841 if (cs%do_dynamics .and. cs%split)
then 846 if ((cs%dtbt_reset_period >= 0.0) .and. &
847 ((n==1) .or. (cs%dtbt_reset_period == 0.0) .or. &
848 (cs%rel_time >= dtbt_reset_time + 0.999*cs%dtbt_reset_period)))
then 850 dtbt_reset_time = cs%rel_time
853 mass_src_time = cs%t_dyn_rel_thermo
854 if (cs%legacy_split)
then 855 call step_mom_dyn_legacy_split(u, v, h, cs%tv, cs%visc, &
856 time_local, dt, fluxes, cs%p_surf_begin, cs%p_surf_end, &
857 mass_src_time, dt_therm, cs%uh, cs%vh, cs%uhtr, cs%vhtr, &
858 eta_av, g, gv, cs%dyn_legacy_split_CSp, calc_dtbt, cs%VarMix, cs%MEKE)
860 call step_mom_dyn_split_rk2(u, v, h, cs%tv, cs%visc, &
861 time_local, dt, fluxes, cs%p_surf_begin, cs%p_surf_end, &
862 mass_src_time, dt_therm, cs%uh, cs%vh, cs%uhtr, cs%vhtr, &
863 eta_av, g, gv, cs%dyn_split_RK2_CSp, calc_dtbt, cs%VarMix, cs%MEKE)
865 if (showcalltree)
call calltree_waypoint(
"finished step_MOM_dyn_split (step_MOM)")
868 elseif (cs%do_dynamics)
then 877 call step_mom_dyn_unsplit_rk2(u, v, h, cs%tv, cs%visc, time_local, dt, fluxes, &
878 cs%p_surf_begin, cs%p_surf_end, cs%uh, cs%vh, cs%uhtr, cs%vhtr, &
879 eta_av, g, gv, cs%dyn_unsplit_RK2_CSp, cs%VarMix, cs%MEKE)
881 call step_mom_dyn_unsplit(u, v, h, cs%tv, cs%visc, time_local, dt, fluxes, &
882 cs%p_surf_begin, cs%p_surf_end, cs%uh, cs%vh, cs%uhtr, cs%vhtr, &
883 eta_av, g, gv, cs%dyn_unsplit_CSp, cs%VarMix, cs%MEKE)
885 if (showcalltree)
call calltree_waypoint(
"finished step_MOM_dyn_unsplit (step_MOM)")
891 if (cs%thickness_diffuse .and. .not.cs%thickness_diffuse_first)
then 894 if (cs%debug)
call hchksum(h,
"Pre-thickness_diffuse h", g%HI, haloshift=0, scale=gv%H_to_m)
896 if (
associated(cs%VarMix)) &
897 call calc_slope_functions(h, cs%tv, dt, g, gv, cs%VarMix)
899 cs%MEKE, cs%VarMix, cs%CDp, cs%thickness_diffuse_CSp)
901 if (cs%debug)
call hchksum(h,
"Post-thickness_diffuse h", g%HI, haloshift=1, scale=gv%H_to_m)
906 if (showcalltree)
call calltree_waypoint(
"finished thickness_diffuse (step_MOM)")
910 if (cs%mixedlayer_restrat)
then 912 call hchksum(h,
"Pre-mixedlayer_restrat h", g%HI, haloshift=1, scale=gv%H_to_m)
913 call uvchksum(
"Pre-mixedlayer_restrat uhtr", &
914 cs%uhtr, cs%vhtr, g%HI, haloshift=0)
917 call mixedlayer_restrat(h, cs%uhtr ,cs%vhtr, cs%tv, fluxes, dt, cs%visc%MLD, &
918 cs%VarMix, g, gv, cs%mixedlayer_restrat_CSp)
924 call hchksum(h,
"Post-mixedlayer_restrat h", g%HI, haloshift=1, scale=gv%H_to_m)
925 call uvchksum(
"Post-mixedlayer_restrat [uv]htr", &
926 cs%uhtr, cs%vhtr, g%HI, haloshift=0)
932 call diag_update_remap_grids(cs%diag)
934 if (cs%useMEKE)
call step_forward_meke(cs%MEKE, h, cs%VarMix%SN_u, cs%VarMix%SN_v, &
935 cs%visc, dt, g, gv, cs%MEKE_CSp, cs%uhtr, cs%vhtr)
936 call disable_averaging(cs%diag)
939 cs%t_dyn_rel_adv = cs%t_dyn_rel_adv + dt
940 cs%t_dyn_rel_thermo = cs%t_dyn_rel_thermo + dt
941 cs%t_dyn_rel_diag = cs%t_dyn_rel_diag + dt
948 if (thermo_does_span_coupling)
then 949 do_advection = (cs%t_dyn_rel_adv + 0.5*dt > dt_therm)
951 do_advection = ((mod(n,ntstep) == 0) .or. (n==n_max))
954 if (do_advection)
then 958 call uvchksum(
"Pre-advection [uv]", u, v, g%HI, haloshift=2)
959 call hchksum(h,
"Pre-advection h", g%HI, haloshift=1, scale=gv%H_to_m)
960 call uvchksum(
"Pre-advection uhtr", cs%uhtr, cs%vhtr, g%HI, &
961 haloshift=0, scale=gv%H_to_m)
964 if (
associated(cs%tv%T))
call hchksum(cs%tv%T,
"Pre-advection T", g%HI, haloshift=1)
965 if (
associated(cs%tv%S))
call hchksum(cs%tv%S,
"Pre-advection S", g%HI, haloshift=1)
966 if (
associated(cs%tv%frazil))
call hchksum(cs%tv%frazil, &
967 "Pre-advection frazil", g%HI, haloshift=0)
968 if (
associated(cs%tv%salt_deficit))
call hchksum(cs%tv%salt_deficit, &
969 "Pre-advection salt deficit", g%HI, haloshift=0)
976 call enable_averaging(cs%t_dyn_rel_adv, time_local, cs%diag)
978 call advect_tracer(h, cs%uhtr, cs%vhtr, cs%OBC, cs%t_dyn_rel_adv, g, gv, &
979 cs%tracer_adv_CSp, cs%tracer_Reg)
980 call tracer_hordiff(h, cs%t_dyn_rel_adv, cs%MEKE, cs%VarMix, g, gv, &
981 cs%tracer_diff_CSp, cs%tracer_Reg, cs%tv)
982 if (showcalltree)
call calltree_waypoint(
"finished tracer advection/diffusion (step_MOM)")
989 call diag_update_remap_grids(cs%diag)
991 call disable_averaging(cs%diag)
999 cs%t_dyn_rel_adv = 0.0
1006 if (cs%t_dyn_rel_adv == 0.0)
then 1009 if (.not.cs%diabatic_first)
then 1010 dtdia = cs%t_dyn_rel_thermo
1011 if (thermo_does_span_coupling .and. (abs(dt_therm - dtdia) > 1e-6*dt_therm))
then 1012 call mom_error(fatal,
"step_MOM: Mismatch between dt_therm and dtdia "//&
1013 "before call to diabatic.")
1016 call enable_averaging(cs%t_dyn_rel_thermo, time_local, cs%diag)
1019 if (cs%split .and. cs%legacy_split .and. .not.cs%adiabatic)
then 1026 call disable_averaging(cs%diag)
1029 if (abs(cs%t_dyn_rel_thermo) > 1e-6*dt)
call mom_error(fatal, &
1030 "step_MOM: Mismatch between the dynamics and diabatic times "//&
1031 "with DIABATIC_FIRST.")
1034 if (cs%use_temperature)
then 1036 call do_group_pass(cs%pass_T_S, g%Domain)
1042 cs%t_dyn_rel_thermo = 0.0
1050 tot_wt_ssh = tot_wt_ssh + dt
1051 call find_eta(h, cs%tv, gv%g_Earth, g, gv, ssh, eta_av)
1052 do j=js,je ;
do i=is,ie
1053 cs%ave_ssh(i,j) = cs%ave_ssh(i,j) + dt*ssh(i,j)
1061 call enable_averaging(dt,time_local, cs%diag)
1063 if (cs%id_u > 0)
call post_data(cs%id_u, u, cs%diag)
1064 if (cs%id_v > 0)
call post_data(cs%id_v, v, cs%diag)
1065 if (cs%id_h > 0)
call post_data(cs%id_h, h, cs%diag)
1066 if (cs%id_ssh_inst > 0)
call post_data(cs%id_ssh_inst, ssh, cs%diag)
1067 call disable_averaging(cs%diag)
1069 if (cs%t_dyn_rel_adv == 0.0)
then 1072 call enable_averaging(cs%t_dyn_rel_diag, time_local, cs%diag)
1073 call calculate_diagnostic_fields(u, v, h, cs%uh, cs%vh, cs%tv, cs%ADp, &
1074 cs%CDp, fluxes, cs%t_dyn_rel_diag, g, gv, cs%diagnostics_CSp)
1076 if (showcalltree)
call calltree_waypoint(
"finished calculate_diagnostic_fields (step_MOM)")
1077 call disable_averaging(cs%diag)
1078 cs%t_dyn_rel_diag = 0.0
1081 if (time_local + set_time(int(0.5*dt_therm)) > cs%Z_diag_time)
then 1082 call enable_averaging(
real(time_type_to_real(CS%Z_diag_interval)), &
1083 CS%Z_diag_time, CS%diag)
1084 call calculate_z_diag_fields(u, v, h, ssh, fluxes%frac_shelf_h, &
1085 g, gv, cs%diag_to_Z_CSp)
1086 cs%Z_diag_time = cs%Z_diag_time + cs%Z_diag_interval
1087 call disable_averaging(cs%diag)
1088 if (showcalltree)
call calltree_waypoint(
"finished calculate_Z_diag_fields (step_MOM)")
1100 itot_wt_ssh = 1.0/tot_wt_ssh
1101 do j=js,je ;
do i=is,ie
1102 cs%ave_ssh(i,j) = cs%ave_ssh(i,j)*itot_wt_ssh
1105 call enable_averaging(dt*n_max, time_local, cs%diag)
1107 call disable_averaging(cs%diag)
1109 if (showcalltree)
call calltree_waypoint(
"calling calculate_surface_state (step_MOM)")
1113 call enable_averaging(dt*n_max, time_local, cs%diag)
1115 call disable_averaging(cs%diag)
1117 if (cs%interp_p_surf)
then ;
do j=jsd,jed ;
do i=isd,ied
1118 cs%p_surf_prev(i,j) = fluxes%p_surf(i,j)
1119 enddo ;
enddo ;
endif 1134 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1136 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1138 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
1141 type(
forcing),
intent(inout) :: fluxes
1142 real,
intent(in) :: dtdia
1144 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: eta_predia, eta_preale
1145 integer :: i, j, k, is, ie, js, je, nz
1146 logical :: use_ice_shelf
1147 logical :: showCallTree
1149 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1150 showcalltree = calltree_showquery()
1151 if (showcalltree)
call calltree_enter(
"step_MOM_thermo(), MOM.F90")
1153 use_ice_shelf = .false.
1154 if (
associated(fluxes%frac_shelf_h)) use_ice_shelf = .true.
1156 if (.not.cs%adiabatic)
then 1159 call uvchksum(
"Pre-diabatic [uv]", u, v, g%HI, haloshift=2)
1160 call hchksum(h,
"Pre-diabatic h", g%HI, haloshift=1, scale=gv%H_to_m)
1161 call uvchksum(
"Pre-diabatic [uv]h", cs%uhtr, cs%vhtr, g%HI, &
1162 haloshift=0, scale=gv%H_to_m)
1169 if (cs%id_u_predia > 0)
call post_data(cs%id_u_predia, u, cs%diag)
1170 if (cs%id_v_predia > 0)
call post_data(cs%id_v_predia, v, cs%diag)
1171 if (cs%id_h_predia > 0)
call post_data(cs%id_h_predia, h, cs%diag)
1172 if (cs%id_T_predia > 0)
call post_data(cs%id_T_predia, cs%tv%T, cs%diag)
1173 if (cs%id_S_predia > 0)
call post_data(cs%id_S_predia, cs%tv%S, cs%diag)
1174 if (cs%id_e_predia > 0)
then 1175 call find_eta(h, cs%tv, gv%g_Earth, g, gv, eta_predia)
1176 call post_data(cs%id_e_predia, eta_predia, cs%diag)
1180 call diabatic(u, v, h, tv, cs%Hml, fluxes, cs%visc, cs%ADp, cs%CDp, &
1181 dtdia, g, gv, cs%diabatic_CSp)
1182 fluxes%fluxes_used = .true.
1185 if (cs%id_u_preale > 0)
call post_data(cs%id_u_preale, u, cs%diag)
1186 if (cs%id_v_preale > 0)
call post_data(cs%id_v_preale, v, cs%diag)
1187 if (cs%id_h_preale > 0)
call post_data(cs%id_h_preale, h, cs%diag)
1188 if (cs%id_T_preale > 0)
call post_data(cs%id_T_preale, tv%T, cs%diag)
1189 if (cs%id_S_preale > 0)
call post_data(cs%id_S_preale, tv%S, cs%diag)
1190 if (cs%id_e_preale > 0)
then 1191 call find_eta(h, tv, gv%g_Earth, g, gv, eta_preale)
1192 call post_data(cs%id_e_preale, eta_preale, cs%diag)
1200 if ( cs%use_ALE_algorithm )
then 1202 call do_group_pass(cs%pass_T_S_h, g%Domain)
1205 if (
associated(cs%S_squared))
then ;
do k=1,nz ;
do j=js,je ;
do i=is,ie
1206 cs%S_squared(i,j,k) = tv%S(i,j,k)**2
1207 enddo ;
enddo ;
enddo ;
endif 1208 if (
associated(cs%T_squared))
then ;
do k=1,nz ;
do j=js,je ;
do i=is,ie
1209 cs%T_squared(i,j,k) = tv%T(i,j,k)**2
1210 enddo ;
enddo ;
enddo ;
endif 1214 call hchksum(tv%T,
"Pre-ALE T", g%HI, haloshift=1)
1215 call hchksum(tv%S,
"Pre-ALE S", g%HI, haloshift=1)
1219 if (use_ice_shelf)
then 1220 call ale_main(g, gv, h, u, v, tv, cs%tracer_Reg, cs%ALE_CSp, dtdia, &
1221 fluxes%frac_shelf_h)
1223 call ale_main(g, gv, h, u, v, tv, cs%tracer_Reg, cs%ALE_CSp, dtdia)
1231 call do_group_pass(cs%pass_uv_T_S_h, g%Domain)
1234 if (cs%debug .and. cs%use_ALE_algorithm)
then 1236 call hchksum(tv%T,
"Post-ALE T", g%HI, haloshift=1)
1237 call hchksum(tv%S,
"Post-ALE S", g%HI, haloshift=1)
1244 call diag_update_remap_grids(cs%diag)
1249 call uvchksum(
"Post-diabatic u", u, v, g%HI, haloshift=2)
1250 call hchksum(h,
"Post-diabatic h", g%HI, haloshift=1, scale=gv%H_to_m)
1251 call uvchksum(
"Post-diabatic [uv]h", cs%uhtr, cs%vhtr, g%HI, &
1252 haloshift=0, scale=gv%H_to_m)
1255 if (
associated(tv%T))
call hchksum(tv%T,
"Post-diabatic T", g%HI, haloshift=1)
1256 if (
associated(tv%S))
call hchksum(tv%S,
"Post-diabatic S", g%HI, haloshift=1)
1257 if (
associated(tv%frazil))
call hchksum(tv%frazil, &
1258 "Post-diabatic frazil", g%HI, haloshift=0)
1259 if (
associated(tv%salt_deficit))
call hchksum(tv%salt_deficit, &
1260 "Post-diabatic salt deficit", g%HI, haloshift=0)
1268 call adiabatic(h, tv, fluxes, dtdia, g, gv, cs%diabatic_CSp)
1269 fluxes%fluxes_used = .true.
1272 if (cs%use_temperature)
then 1274 call do_group_pass(cs%pass_T_S, g%Domain)
1277 if (
associated(tv%T))
call hchksum(tv%T,
"Post-diabatic T", g%HI, haloshift=1)
1278 if (
associated(tv%S))
call hchksum(tv%S,
"Post-diabatic S", g%HI, haloshift=1)
1284 if (showcalltree)
call calltree_leave(
"step_MOM_thermo(), MOM.F90")
1293 subroutine step_offline(fluxes, state, Time_start, time_interval, CS)
1295 type(
surface),
intent(inout) :: state
1296 type(time_type),
intent(in) :: Time_start
1297 real,
intent(in) :: time_interval
1306 logical :: first_iter
1307 logical :: last_iter
1308 logical :: do_vertical
1309 logical :: adv_converged
1311 integer :: dt_offline, dt_offline_vertical
1312 logical :: skip_diffusion
1313 integer :: id_eta_diff_end
1315 integer,
pointer :: accumulated_time
1317 integer :: is, ie, js, je, isd, ied, jsd, jed
1320 real,
dimension(:,:,:),
pointer :: &
1326 real,
dimension(SZI_(CS%G),SZJ_(CS%G)) :: eta_pre, eta_end
1327 type(time_type) :: Time_end
1333 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1334 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
1337 call extract_offline_main(cs%offline_CSp, uhtr, vhtr, eatr, ebtr, h_end, accumulated_time, &
1338 dt_offline, dt_offline_vertical, skip_diffusion)
1339 time_end = increment_date(time_start, seconds=floor(time_interval+0.001))
1340 call enable_averaging(time_interval, time_end, cs%diag)
1343 if(accumulated_time==0)
then 1346 first_iter = .false.
1350 if ( mod(accumulated_time, dt_offline_vertical) == 0 )
then 1351 do_vertical = .true.
1353 do_vertical = .false.
1357 accumulated_time = mod(accumulated_time + int(time_interval), dt_offline)
1358 if(accumulated_time==0)
then 1364 if(cs%use_ALE_algorithm)
then 1367 if (first_iter)
then 1368 if(is_root_pe()) print *,
"Reading in new offline fields" 1373 call update_offline_fields(cs%offline_CSp, cs%h, fluxes, cs%use_ALE_algorithm)
1376 call offline_fw_fluxes_into_ocean(g, gv, cs%offline_CSp, fluxes, cs%h)
1378 if (.not.cs%diabatic_first)
then 1379 call offline_advection_ale(fluxes, time_start, time_interval, cs%offline_CSp,
id_clock_ale, &
1380 cs%h, uhtr, vhtr, converged=adv_converged)
1383 call offline_redistribute_residual(cs%offline_CSp, cs%h, uhtr, vhtr, adv_converged)
1386 if (.not. skip_diffusion)
then 1387 if (
associated(cs%VarMix))
then 1390 call calc_slope_functions(cs%h, cs%tv,
REAL(dt_offline), G, GV, CS%VarMix)
1392 call tracer_hordiff(cs%h,
REAL(dt_offline), CS%MEKE, CS%VarMix, G, GV, &
1393 CS%tracer_diff_CSp, CS%tracer_Reg, CS%tv)
1398 if (do_vertical)
then 1399 call offline_diabatic_ale(fluxes, time_start, time_end, cs%offline_CSp, cs%h, eatr, ebtr)
1404 if (cs%diabatic_first)
then 1405 call offline_advection_ale(fluxes, time_start, time_interval, cs%offline_CSp,
id_clock_ale, &
1406 cs%h, uhtr, vhtr, converged=adv_converged)
1409 call offline_redistribute_residual(cs%offline_CSp, cs%h, uhtr, vhtr, adv_converged)
1411 if (.not. skip_diffusion)
then 1412 if (
associated(cs%VarMix))
then 1415 call calc_slope_functions(cs%h, cs%tv,
REAL(dt_offline), G, GV, CS%VarMix)
1417 call tracer_hordiff(cs%h,
REAL(dt_offline), CS%MEKE, CS%VarMix, G, GV, &
1418 CS%tracer_diff_CSp, CS%tracer_Reg, CS%tv)
1422 if(is_root_pe()) print *,
"Last iteration of offline interval" 1425 call offline_fw_fluxes_out_ocean(g, gv, cs%offline_CSp, fluxes, cs%h)
1428 call post_offline_convergence_diags(cs%offline_CSp, cs%h, h_end, uhtr, vhtr)
1438 call mom_error(warning, &
1439 "Offline tracer mode in non-ALE configuration has not been thoroughly tested")
1443 if(time_interval .NE. dt_offline)
then 1444 call mom_error(fatal, &
1445 "For offline tracer mode in a non-ALE configuration, dt_offline must equal time_interval")
1447 call update_offline_fields(cs%offline_CSp, cs%h, fluxes, cs%use_ALE_algorithm)
1449 cs%h, eatr, ebtr, uhtr, vhtr)
1451 if (.not. skip_diffusion)
then 1452 call tracer_hordiff(h_end,
REAL(dt_offline), CS%MEKE, CS%VarMix, G, GV, &
1453 CS%tracer_diff_CSp, CS%tracer_Reg, CS%tv)
1467 call disable_averaging(cs%diag)
1472 fluxes%fluxes_used = .true.
1479 subroutine initialize_mom(Time, param_file, dirs, CS, Time_in, offline_tracer_mode)
1480 type(time_type),
target,
intent(inout) :: Time
1484 type(time_type),
optional,
intent(in) :: Time_in
1486 logical,
optional,
intent(out) :: offline_tracer_mode
1495 character(len=4),
parameter :: vers_num =
'v2.0' 1498 #include "version_variable.h" 1500 integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
1501 integer :: IsdB, IedB, JsdB, JedB
1505 real,
allocatable,
dimension(:,:,:) :: e
1506 real,
allocatable,
dimension(:,:) :: eta
1507 real,
allocatable,
dimension(:,:) :: area_shelf_h
1508 real,
dimension(:,:),
allocatable,
target :: frac_shelf_h
1509 real,
dimension(:,:),
pointer :: shelf_area
1511 type(group_pass_type) :: tmp_pass_uv_T_S_h
1514 logical :: write_geom_files
1516 logical :: use_geothermal
1518 logical :: symmetric
1520 logical :: do_unit_tests
1521 logical :: test_grid_copy = .false.
1522 logical :: use_ice_shelf
1523 logical :: global_indexing
1525 logical :: bathy_at_vel
1527 integer :: first_direction
1531 integer :: nkml, nkbl, verbosity, write_geom
1532 integer :: dynamics_stencil
1535 type(time_type) :: Start_time
1537 character(len=200) :: area_varname, ice_shelf_file, inputdir, filename
1539 if (
associated(cs))
then 1540 call mom_error(warning,
"initialize_MOM called with an associated "// &
1541 "control structure.")
1546 if (test_grid_copy)
then ;
allocate(g)
1547 else ; g => cs%G ;
endif 1551 id_clock_init = cpu_clock_id(
'Ocean Initialization', grain=clock_subcomponent)
1554 start_time = time ;
if (
present(time_in)) start_time = time_in
1558 verbosity = 2 ;
call read_param(param_file,
"VERBOSITY", verbosity)
1559 call mom_set_verbosity(verbosity)
1566 call get_param(param_file,
"MOM",
"VERBOSITY", verbosity, &
1567 "Integer controlling level of messaging\n" // &
1568 "\t0 = Only FATAL messages\n" // &
1569 "\t2 = Only FATAL, WARNING, NOTE [default]\n" // &
1570 "\t9 = All)", default=2)
1571 call get_param(param_file,
"MOM",
"DO_UNIT_TESTS", do_unit_tests, &
1572 "If True, exercises unit tests at model start up.", &
1574 if (do_unit_tests)
then 1578 call get_param(param_file,
"MOM",
"SPLIT", cs%split, &
1579 "Use the split time stepping if true.", default=.true.)
1581 call get_param(param_file,
"MOM",
"USE_LEGACY_SPLIT", cs%legacy_split, &
1582 "If true, use the full range of options available from \n"//&
1583 "the older GOLD-derived split time stepping code.", &
1585 cs%use_RK2 = .false.
1587 call get_param(param_file,
"MOM",
"USE_RK2", cs%use_RK2, &
1588 "If true, use RK2 instead of RK3 in the unsplit time stepping.", &
1590 cs%legacy_split = .false.
1593 call get_param(param_file,
"MOM",
"CALC_RHO_FOR_SEA_LEVEL", cs%calc_rho_for_sea_lev, &
1594 "If true, the in-situ density is used to calculate the\n"//&
1595 "effective sea level that is returned to the coupler. If false,\n"//&
1596 "the Boussinesq parameter RHO_0 is used.", default=.false.)
1597 call get_param(param_file,
"MOM",
"ENABLE_THERMODYNAMICS", cs%use_temperature, &
1598 "If true, Temperature and salinity are used as state \n"//&
1599 "variables.", default=.true.)
1600 call get_param(param_file,
"MOM",
"USE_EOS", use_eos, &
1601 "If true, density is calculated from temperature and \n"//&
1602 "salinity with an equation of state. If USE_EOS is \n"//&
1603 "true, ENABLE_THERMODYNAMICS must be true as well.", &
1604 default=cs%use_temperature)
1605 call get_param(param_file,
"MOM",
"DIABATIC_FIRST", cs%diabatic_first, &
1606 "If true, apply diabatic and thermodynamic processes, \n"//&
1607 "including buoyancy forcing and mass gain or loss, \n"//&
1608 "before stepping the dynamics forward.", default=.false.)
1609 call get_param(param_file,
"MOM",
"USE_CONTEMP_ABSSAL", cs%use_conT_absS, &
1610 "If true, , the prognostics T&S are the conservative temperature \n"//&
1611 "and absolute salinity. Care should be taken to convert them \n"//&
1612 "to potential temperature and practical salinity before \n"//&
1613 "exchanging them with the coupler and/or reporting T&S diagnostics. \n"&
1615 call get_param(param_file,
"MOM",
"ADIABATIC", cs%adiabatic, &
1616 "There are no diapycnal mass fluxes if ADIABATIC is \n"//&
1617 "true. This assumes that KD = KDML = 0.0 and that \n"//&
1618 "there is no buoyancy forcing, but makes the model \n"//&
1619 "faster by eliminating subroutine calls.", default=.false.)
1620 call get_param(param_file,
"MOM",
"DO_DYNAMICS", cs%do_dynamics, &
1621 "If False, skips the dynamics calls that update u & v, as well as\n"//&
1622 "the gravity wave adjustment to h. This is a fragile feature and\n"//&
1623 "thus undocumented.", default=.true., do_not_log=.true. )
1624 call get_param(param_file,
"MOM",
"ADVECT_TS", cs%advect_TS , &
1625 "If True, advect temperature and salinity horizontally\n"//&
1626 "If False, T/S are registered for advection.\n"//&
1627 "This is intended only to be used in offline tracer mode.", &
1628 "and is by default false in that case", &
1629 do_not_log = .true., default=.true. )
1630 if (
present(offline_tracer_mode))
then 1631 call get_param(param_file,
"MOM",
"OFFLINE_TRACER_MODE", cs%offline_tracer_mode, &
1632 "If true, barotropic and baroclinic dynamics, thermodynamics\n"//&
1633 "are all bypassed with all the fields necessary to integrate\n"//&
1634 "the tracer advection and diffusion equation are read in from\n"//&
1635 "files stored from a previous integration of the prognostic model.\n"//&
1636 "NOTE: This option only used in the ocean_solo_driver.", default=.false.)
1637 if(cs%offline_tracer_mode)
then 1638 call get_param(param_file,
"MOM",
"ADVECT_TS", cs%advect_TS , &
1639 "If True, advect temperature and salinity horizontally\n"//&
1640 "If False, T/S are registered for advection.\n"//&
1641 "This is intended only to be used in offline tracer mode."//&
1642 "and is by default false in that case", &
1646 call get_param(param_file,
"MOM",
"USE_REGRIDDING", cs%use_ALE_algorithm , &
1647 "If True, use the ALE algorithm (regridding/remapping).\n"//&
1648 "If False, use the layered isopycnal algorithm.", default=.false. )
1649 call get_param(param_file,
"MOM",
"BULKMIXEDLAYER", cs%bulkmixedlayer, &
1650 "If true, use a Kraus-Turner-like bulk mixed layer \n"//&
1651 "with transitional buffer layers. Layers 1 through \n"//&
1652 "NKML+NKBL have variable densities. There must be at \n"//&
1653 "least NKML+NKBL+1 layers if BULKMIXEDLAYER is true. \n"//&
1654 "BULKMIXEDLAYER can not be used with USE_REGRIDDING. \n"//&
1655 "The default is influenced by ENABLE_THERMODYNAMICS.", &
1656 default=cs%use_temperature .and. .not.cs%use_ALE_algorithm)
1657 call get_param(param_file,
"MOM",
"THICKNESSDIFFUSE", cs%thickness_diffuse, &
1658 "If true, interface heights are diffused with a \n"//&
1659 "coefficient of KHTH.", default=.false.)
1660 call get_param(param_file,
"MOM",
"THICKNESSDIFFUSE_FIRST", &
1661 cs%thickness_diffuse_first, &
1662 "If true, do thickness diffusion before dynamics.\n"//&
1663 "This is only used if THICKNESSDIFFUSE is true.", &
1665 call get_param(param_file,
"MOM",
"BATHYMETRY_AT_VEL", bathy_at_vel, &
1666 "If true, there are separate values for the basin depths \n"//&
1667 "at velocity points. Otherwise the effects of topography \n"//&
1668 "are entirely determined from thickness points.", &
1671 call get_param(param_file,
"MOM",
"DEBUG", cs%debug, &
1672 "If true, write out verbose debugging data.", default=.false.)
1673 call get_param(param_file,
"MOM",
"DEBUG_TRUNCATIONS", cs%debug_truncations, &
1674 "If true, calculate all diagnostics that are useful for \n"//&
1675 "debugging truncations.", default=.false.)
1677 call get_param(param_file,
"MOM",
"DT", cs%dt, &
1678 "The (baroclinic) dynamics time step. The time-step that \n"//&
1679 "is actually used will be an integer fraction of the \n"//&
1680 "forcing time-step (DT_FORCING in ocean-only mode or the \n"//&
1681 "coupling timestep in coupled mode.)", units=
"s", &
1682 fail_if_missing=.true.)
1683 call get_param(param_file,
"MOM",
"DT_THERM", cs%dt_therm, &
1684 "The thermodynamic and tracer advection time step. \n"//&
1685 "Ideally DT_THERM should be an integer multiple of DT \n"//&
1686 "and less than the forcing or coupling time-step, unless \n"//&
1687 "THERMO_SPANS_COUPLING is true, in which case DT_THERM \n"//&
1688 "can be an integer multiple of the coupling timestep. By \n"//&
1689 "default DT_THERM is set to DT.", units=
"s", default=cs%dt)
1690 call get_param(param_file,
"MOM",
"THERMO_SPANS_COUPLING", cs%thermo_spans_coupling, &
1691 "If true, the MOM will take thermodynamic and tracer \n"//&
1692 "timesteps that can be longer than the coupling timestep. \n"//&
1693 "The actual thermodynamic timestep that is used in this \n"//&
1694 "case is the largest integer multiple of the coupling \n"//&
1695 "timestep that is less than or equal to DT_THERM.", default=.false.)
1697 if (.not.cs%bulkmixedlayer)
then 1698 call get_param(param_file,
"MOM",
"HMIX_SFC_PROP", cs%Hmix, &
1699 "If BULKMIXEDLAYER is false, HMIX_SFC_PROP is the depth \n"//&
1700 "over which to average to find surface properties like \n"//&
1701 "SST and SSS or density (but not surface velocities).", &
1702 units=
"m", default=1.0)
1703 call get_param(param_file,
"MOM",
"HMIX_UV_SFC_PROP", cs%Hmix_UV, &
1704 "If BULKMIXEDLAYER is false, HMIX_UV_SFC_PROP is the depth\n"//&
1705 "over which to average to find surface flow properties,\n"//&
1706 "SSU, SSV. A non-positive value indicates no averaging.", &
1707 units=
"m", default=0.)
1709 call get_param(param_file,
"MOM",
"MIN_Z_DIAG_INTERVAL", z_diag_int, &
1710 "The minimum amount of time in seconds between \n"//&
1711 "calculations of depth-space diagnostics. Making this \n"//&
1712 "larger than DT_THERM reduces the performance penalty \n"//&
1713 "of regridding to depth online.", units=
"s", default=0.0)
1714 call get_param(param_file,
"MOM",
"INTERPOLATE_P_SURF", cs%interp_p_surf, &
1715 "If true, linearly interpolate the surface pressure \n"//&
1716 "over the coupling time step, using the specified value \n"//&
1717 "at the end of the step.", default=.false.)
1720 call get_param(param_file,
"MOM",
"DTBT", dtbt, default=-0.98)
1721 default_val = cs%dt_therm ;
if (dtbt > 0.0) default_val = -1.0
1722 cs%dtbt_reset_period = -1.0
1723 call get_param(param_file,
"MOM",
"DTBT_RESET_PERIOD", cs%dtbt_reset_period, &
1724 "The period between recalculations of DTBT (if DTBT <= 0). \n"//&
1725 "If DTBT_RESET_PERIOD is negative, DTBT is set based \n"//&
1726 "only on information available at initialization. If \n"//&
1727 "dynamic, DTBT will be set at least every forcing time \n"//&
1728 "step, and if 0, every dynamics time step. The default is \n"//&
1729 "set by DT_THERM. This is only used if SPLIT is true.", &
1730 units=
"s", default=default_val, do_not_read=(dtbt > 0.0))
1734 cs%use_frazil = .false. ; cs%bound_salinity = .false. ; cs%tv%P_Ref = 2.0e7
1735 if (cs%use_temperature)
then 1736 call get_param(param_file,
"MOM",
"FRAZIL", cs%use_frazil, &
1737 "If true, water freezes if it gets too cold, and the \n"//&
1738 "the accumulated heat deficit is returned in the \n"//&
1739 "surface state. FRAZIL is only used if \n"//&
1740 "ENABLE_THERMODYNAMICS is true.", default=.false.)
1741 call get_param(param_file,
"MOM",
"DO_GEOTHERMAL", use_geothermal, &
1742 "If true, apply geothermal heating.", default=.false.)
1743 call get_param(param_file,
"MOM",
"BOUND_SALINITY", cs%bound_salinity, &
1744 "If true, limit salinity to being positive. (The sea-ice \n"//&
1745 "model may ask for more salt than is available and \n"//&
1746 "drive the salinity negative otherwise.)", default=.false.)
1747 call get_param(param_file,
"MOM",
"C_P", cs%tv%C_p, &
1748 "The heat capacity of sea water, approximated as a \n"//&
1749 "constant. This is only used if ENABLE_THERMODYNAMICS is \n"//&
1750 "true. The default value is from the TEOS-10 definition \n"//&
1751 "of conservative temperature.", units=
"J kg-1 K-1", &
1752 default=3991.86795711963)
1754 if (use_eos)
call get_param(param_file,
"MOM",
"P_REF", cs%tv%P_Ref, &
1755 "The pressure that is used for calculating the coordinate \n"//&
1756 "density. (1 Pa = 1e4 dbar, so 2e7 is commonly used.) \n"//&
1757 "This is only used if USE_EOS and ENABLE_THERMODYNAMICS \n"//&
1758 "are true.", units=
"Pa", default=2.0e7)
1760 if (cs%bulkmixedlayer)
then 1761 call get_param(param_file,
"MOM",
"NKML", nkml, &
1762 "The number of sublayers within the mixed layer if \n"//&
1763 "BULKMIXEDLAYER is true.", units=
"nondim", default=2)
1764 call get_param(param_file,
"MOM",
"NKBL", nkbl, &
1765 "The number of layers that are used as variable density \n"//&
1766 "buffer layers if BULKMIXEDLAYER is true.", units=
"nondim", &
1770 call get_param(param_file,
"MOM",
"GLOBAL_INDEXING", global_indexing, &
1771 "If true, use a global lateral indexing convention, so \n"//&
1772 "that corresponding points on different processors have \n"//&
1773 "the same index. This does not work with static memory.", &
1774 default=.false., layoutparam=.true.)
1775 #ifdef STATIC_MEMORY_ 1776 if (global_indexing)
call mom_error(fatal,
"initialize_MOM: "//&
1777 "GLOBAL_INDEXING can not be true with STATIC_MEMORY.")
1779 call get_param(param_file,
"MOM",
"FIRST_DIRECTION", first_direction, &
1780 "An integer that indicates which direction goes first \n"//&
1781 "in parts of the code that use directionally split \n"//&
1782 "updates, with even numbers (or 0) used for x- first \n"//&
1783 "and odd numbers used for y-first.", default=0)
1785 call get_param(param_file,
"MOM",
"CHECK_BAD_SURFACE_VALS", &
1786 cs%check_bad_surface_vals, &
1787 "If true, check the surface state for ridiculous values.", &
1789 if (cs%check_bad_surface_vals)
then 1790 call get_param(param_file,
"MOM",
"BAD_VAL_SSH_MAX", cs%bad_val_ssh_max, &
1791 "The value of SSH above which a bad value message is \n"//&
1792 "triggered, if CHECK_BAD_SURFACE_VALS is true.", units=
"m", &
1794 call get_param(param_file,
"MOM",
"BAD_VAL_SSS_MAX", cs%bad_val_sss_max, &
1795 "The value of SSS above which a bad value message is \n"//&
1796 "triggered, if CHECK_BAD_SURFACE_VALS is true.", units=
"PPT", &
1798 call get_param(param_file,
"MOM",
"BAD_VAL_SST_MAX", cs%bad_val_sst_max, &
1799 "The value of SST above which a bad value message is \n"//&
1800 "triggered, if CHECK_BAD_SURFACE_VALS is true.", &
1801 units=
"deg C", default=45.0)
1802 call get_param(param_file,
"MOM",
"BAD_VAL_SST_MIN", cs%bad_val_sst_min, &
1803 "The value of SST below which a bad value message is \n"//&
1804 "triggered, if CHECK_BAD_SURFACE_VALS is true.", &
1805 units=
"deg C", default=-2.1)
1806 call get_param(param_file,
"MOM",
"BAD_VAL_COLUMN_THICKNESS", cs%bad_val_column_thickness, &
1807 "The value of column thickness below which a bad value message is \n"//&
1808 "triggered, if CHECK_BAD_SURFACE_VALS is true.", units=
"m", &
1812 call get_param(param_file,
"MOM",
"SAVE_INITIAL_CONDS", save_ic, &
1813 "If true, write the initial conditions to a file given \n"//&
1814 "by IC_OUTPUT_FILE.", default=.false.)
1815 call get_param(param_file,
"MOM",
"IC_OUTPUT_FILE", cs%IC_file, &
1816 "The file into which to write the initial conditions.", &
1818 call get_param(param_file,
"MOM",
"WRITE_GEOM", write_geom, &
1819 "If =0, never write the geometry and vertical grid files.\n"//&
1820 "If =1, write the geometry and vertical grid files only for\n"//&
1821 "a new simulation. If =2, always write the geometry and\n"//&
1822 "vertical grid files. Other values are invalid.", default=1)
1823 if (write_geom<0 .or. write_geom>2)
call mom_error(fatal,
"MOM: "//&
1824 "WRITE_GEOM must be equal to 0, 1 or 2.")
1825 write_geom_files = ((write_geom==2) .or. ((write_geom==1) .and. &
1826 ((dirs%input_filename(1:1)==
'n') .and. (len_trim(dirs%input_filename)==1))))
1829 if (cs%use_ALE_algorithm .and. cs%bulkmixedlayer)
call mom_error(fatal, &
1830 "MOM: BULKMIXEDLAYER can not currently be used with the ALE algorithm.")
1831 if (cs%use_ALE_algorithm .and. .not.cs%use_temperature)
call mom_error(fatal, &
1832 "MOM: At this time, USE_EOS should be True when using the ALE algorithm.")
1833 if (cs%adiabatic .and. cs%use_temperature)
call mom_error(warning, &
1834 "MOM: ADIABATIC and ENABLE_THERMODYNAMICS both defined is usually unwise.")
1835 if (use_eos .and. .not.cs%use_temperature)
call mom_error(fatal, &
1836 "MOM: ENABLE_THERMODYNAMICS must be defined to use USE_EOS.")
1837 if (cs%adiabatic .and. cs%bulkmixedlayer)
call mom_error(fatal, &
1838 "MOM: ADIABATIC and BULKMIXEDLAYER can not both be defined.")
1839 if (cs%bulkmixedlayer .and. .not.use_eos)
call mom_error(fatal, &
1840 "initialize_MOM: A bulk mixed layer can only be used with T & S as "//&
1841 "state variables. Add USE_EOS = True to MOM_input.")
1843 call get_param(param_file,
'MOM',
"ICE_SHELF", use_ice_shelf, default=.false., do_not_log=.true.)
1844 if (use_ice_shelf)
then 1845 inputdir =
"." ;
call get_param(param_file,
'MOM',
"INPUTDIR", inputdir)
1846 inputdir = slasher(inputdir)
1847 call get_param(param_file,
'MOM',
"ICE_THICKNESS_FILE", ice_shelf_file, &
1848 "The file from which the ice bathymetry and area are read.", &
1849 fail_if_missing=.true.)
1850 call get_param(param_file,
'MOM',
"ICE_AREA_VARNAME", area_varname, &
1851 "The name of the area variable in ICE_THICKNESS_FILE.", &
1852 fail_if_missing=.true.)
1859 #ifdef SYMMETRIC_MEMORY_ 1864 #ifdef STATIC_MEMORY_ 1865 call mom_domains_init(g%domain, param_file, symmetric=symmetric, &
1866 static_memory=.true., nihalo=nihalo_, njhalo=njhalo_, &
1867 niglobal=niglobal_, njglobal=njglobal_, niproc=niproc_, &
1870 call mom_domains_init(g%domain, param_file, symmetric=symmetric)
1874 call mom_debugging_init(param_file)
1875 call diag_mediator_infrastructure_init()
1876 call mom_io_init(param_file)
1879 local_indexing=.not.global_indexing)
1884 call verticalgridinit( param_file, cs%GV )
1889 if (cs%debug .or. dg%symmetric) &
1897 call tracer_registry_init(param_file, cs%tracer_Reg)
1899 is = dg%isc ; ie = dg%iec ; js = dg%jsc ; je = dg%jec ; nz = gv%ke
1900 isd = dg%isd ; ied = dg%ied ; jsd = dg%jsd ; jed = dg%jed
1901 isdb = dg%IsdB ; iedb = dg%IedB ; jsdb = dg%JsdB ; jedb = dg%JedB
1904 alloc_(cs%u(isdb:iedb,jsd:jed,nz)) ; cs%u(:,:,:) = 0.0
1905 alloc_(cs%v(isd:ied,jsdb:jedb,nz)) ; cs%v(:,:,:) = 0.0
1906 alloc_(cs%h(isd:ied,jsd:jed,nz)) ; cs%h(:,:,:) = gv%Angstrom
1907 alloc_(cs%uh(isdb:iedb,jsd:jed,nz)) ; cs%uh(:,:,:) = 0.0
1908 alloc_(cs%vh(isd:ied,jsdb:jedb,nz)) ; cs%vh(:,:,:) = 0.0
1909 if (cs%use_temperature)
then 1910 alloc_(cs%T(isd:ied,jsd:jed,nz)) ; cs%T(:,:,:) = 0.0
1911 alloc_(cs%S(isd:ied,jsd:jed,nz)) ; cs%S(:,:,:) = 0.0
1912 cs%tv%T => cs%T ; cs%tv%S => cs%S
1913 cs%vd_T = var_desc(name=
"T",units=
"degC",longname=
"Potential Temperature", &
1914 cmor_field_name=
"thetao",cmor_units=
"C", &
1915 conversion=cs%tv%C_p)
1916 cs%vd_S = var_desc(name=
"S",units=
"PPT",longname=
"Salinity",&
1917 cmor_field_name=
"so",cmor_units=
"ppt", &
1919 if(cs%advect_TS)
then 1920 call register_tracer(cs%tv%T, cs%vd_T, param_file, dg%HI, gv, cs%tracer_Reg, cs%vd_T)
1921 call register_tracer(cs%tv%S, cs%vd_S, param_file, dg%HI, gv, cs%tracer_Reg, cs%vd_S)
1924 if (cs%use_frazil)
then 1925 allocate(cs%tv%frazil(isd:ied,jsd:jed)) ; cs%tv%frazil(:,:) = 0.0
1927 if (cs%bound_salinity)
then 1928 allocate(cs%tv%salt_deficit(isd:ied,jsd:jed)) ; cs%tv%salt_deficit(:,:)=0.0
1931 if (cs%bulkmixedlayer .or. cs%use_temperature)
then 1932 allocate(cs%Hml(isd:ied,jsd:jed)) ; cs%Hml(:,:) = 0.0
1935 if (cs%bulkmixedlayer)
then 1936 gv%nkml = nkml ; gv%nk_rho_varies = nkml + nkbl
1938 gv%nkml = 0 ; gv%nk_rho_varies = 0
1940 if (cs%use_ALE_algorithm)
then 1941 call get_param(param_file,
"MOM",
"NK_RHO_VARIES", gv%nk_rho_varies, default=0)
1944 alloc_(cs%uhtr(isdb:iedb,jsd:jed,nz)) ; cs%uhtr(:,:,:) = 0.0
1945 alloc_(cs%vhtr(isd:ied,jsdb:jedb,nz)) ; cs%vhtr(:,:,:) = 0.0
1946 cs%t_dyn_rel_adv = 0.0 ; cs%t_dyn_rel_thermo = 0.0 ; cs%t_dyn_rel_diag = 0.0
1948 if (cs%debug_truncations)
then 1949 allocate(cs%u_prev(isdb:iedb,jsd:jed,nz)) ; cs%u_prev(:,:,:) = 0.0
1950 allocate(cs%v_prev(isd:ied,jsdb:jedb,nz)) ; cs%u_prev(:,:,:) = 0.0
1953 mom_internal_state%u => cs%u ; mom_internal_state%v => cs%v
1954 mom_internal_state%h => cs%h
1955 mom_internal_state%uh => cs%uh ; mom_internal_state%vh => cs%vh
1956 if (cs%use_temperature)
then 1957 mom_internal_state%T => cs%T ; mom_internal_state%S => cs%S
1960 cs%CDp%uh => cs%uh ; cs%CDp%vh => cs%vh
1962 if (cs%interp_p_surf)
then 1963 allocate(cs%p_surf_prev(isd:ied,jsd:jed)) ; cs%p_surf_prev(:,:) = 0.0
1966 alloc_(cs%ave_ssh(isd:ied,jsd:jed)) ; cs%ave_ssh(:,:) = 0.0
1971 if (use_eos)
call eos_init(param_file, cs%tv%eqn_of_state)
1972 if (cs%use_temperature)
then 1973 allocate(cs%tv%TempxPmE(isd:ied,jsd:jed))
1974 cs%tv%TempxPmE(:,:) = 0.0
1975 if (use_geothermal)
then 1976 allocate(cs%tv%internal_heat(isd:ied,jsd:jed))
1977 cs%tv%internal_heat(:,:) = 0.0
1987 if (cs%legacy_split)
then 1988 call register_restarts_dyn_legacy_split(dg%HI, gv, param_file, &
1989 cs%dyn_legacy_split_CSp, cs%restart_CSp, cs%uh, cs%vh)
1991 call register_restarts_dyn_split_rk2(dg%HI, gv, param_file, &
1992 cs%dyn_split_RK2_CSp, cs%restart_CSp, cs%uh, cs%vh)
1995 if (cs%use_RK2)
then 1996 call register_restarts_dyn_unsplit_rk2(dg%HI, gv, param_file, &
1997 cs%dyn_unsplit_RK2_CSp, cs%restart_CSp)
1999 call register_restarts_dyn_unsplit(dg%HI, gv, param_file, &
2000 cs%dyn_unsplit_CSp, cs%restart_CSp)
2006 call call_tracer_register(dg%HI, gv, param_file, cs%tracer_flow_CSp, &
2007 cs%tracer_Reg, cs%restart_CSp)
2020 if (
associated(cs%OBC))
call call_obc_register(param_file, cs%update_OBC_CSp, cs%OBC)
2023 dirs%output_directory, cs%tv, dg%max_depth)
2026 if (cs%use_ALE_algorithm)
then 2027 call ale_init(param_file, gv, dg%max_depth, cs%ALE_CSp)
2035 call mom_grid_init(g, param_file, hi, bathymetry_at_vel=bathy_at_vel)
2040 call set_first_direction(g, first_direction)
2042 if (cs%debug .or. g%symmetric) &
2046 g%ke = gv%ke ; g%g_Earth = gv%g_Earth
2049 dirs, cs%restart_CSp, cs%ALE_CSp, cs%tracer_Reg, &
2050 cs%sponge_CSp, cs%ALE_sponge_CSp, cs%OBC, time_in)
2057 if (test_grid_copy)
then 2072 if (cs%debug .or. cs%G%symmetric) &
2074 g%ke = gv%ke ; g%g_Earth = gv%g_Earth
2082 if (ale_remap_init_conds(cs%ALE_CSp) .and. .not.
query_initialized(cs%h,
"h",cs%restart_CSp))
then 2087 call uvchksum(
"Pre ALE adjust init cond [uv]", &
2088 cs%u, cs%v, g%HI, haloshift=1)
2089 call hchksum(cs%h,
"Pre ALE adjust init cond h", g%HI, haloshift=1, scale=gv%H_to_m)
2091 call calltree_waypoint(
"Calling adjustGridForIntegrity() to remap initial conditions (initialize_MOM)")
2092 call adjustgridforintegrity(cs%ALE_CSp, g, gv, cs%h )
2093 call calltree_waypoint(
"Calling ALE_main() to remap initial conditions (initialize_MOM)")
2094 if (use_ice_shelf)
then 2095 filename = trim(inputdir)//trim(ice_shelf_file)
2096 if (.not.
file_exists(filename, g%Domain))
call mom_error(fatal, &
2097 "MOM: Unable to open "//trim(filename))
2099 allocate(area_shelf_h(isd:ied,jsd:jed))
2100 allocate(frac_shelf_h(isd:ied,jsd:jed))
2101 call read_data(filename,trim(area_varname),area_shelf_h,domain=g%Domain%mpp_domain)
2103 frac_shelf_h(:,:) = 0.0
2105 do j=jsd,jed ;
do i=isd,ied
2106 if (g%areaT(i,j) > 0.0) &
2107 frac_shelf_h(i,j) = area_shelf_h(i,j) / g%areaT(i,j)
2110 shelf_area => frac_shelf_h
2111 call ale_main(g, gv, cs%h, cs%u, cs%v, cs%tv, cs%tracer_Reg, cs%ALE_CSp, &
2112 frac_shelf_h = shelf_area)
2114 call ale_main( g, gv, cs%h, cs%u, cs%v, cs%tv, cs%tracer_Reg, cs%ALE_CSp )
2118 if (cs%use_temperature)
then 2123 call do_group_pass(tmp_pass_uv_t_s_h, g%Domain)
2127 call uvchksum(
"Post ALE adjust init cond [uv]", cs%u, cs%v, g%HI, haloshift=1)
2128 call hchksum(cs%h,
"Post ALE adjust init cond h", g%HI, haloshift=1, scale=gv%H_to_m)
2131 if ( cs%use_ALE_algorithm )
call ale_updateverticalgridtype( cs%ALE_CSp, gv )
2135 call diag_mediator_init(g, gv%ke, param_file, diag, doc_file_dir=dirs%output_directory)
2144 call diag_set_state_ptrs(cs%h, cs%T, cs%S, cs%tv%eqn_of_state, diag)
2153 call diag_update_remap_grids(diag)
2160 if (cs%use_ALE_algorithm)
then 2161 call ale_writecoordinatefile( cs%ALE_CSp, gv, dirs%output_directory )
2166 cs%useMEKE =
meke_init(time, g, param_file, diag, cs%MEKE_CSp, cs%MEKE, cs%restart_CSp)
2168 call varmix_init(time, g, param_file, diag, cs%VarMix)
2169 call set_visc_init(time, g, gv, param_file, diag, cs%visc, cs%set_visc_CSp,cs%OBC)
2171 allocate(eta(szi_(g),szj_(g))) ; eta(:,:) = 0.0
2172 if (cs%legacy_split)
then 2173 call initialize_dyn_legacy_split(cs%u, cs%v, cs%h, cs%uh, cs%vh, eta, time, &
2174 g, gv, param_file, diag, cs%dyn_legacy_split_CSp, cs%restart_CSp, &
2175 cs%dt, cs%ADp, cs%CDp, mom_internal_state, cs%VarMix, cs%MEKE, &
2176 cs%OBC, cs%update_OBC_CSp, cs%ALE_CSp, cs%set_visc_CSp, cs%visc, &
2179 call initialize_dyn_split_rk2(cs%u, cs%v, cs%h, cs%uh, cs%vh, eta, time, &
2180 g, gv, param_file, diag, cs%dyn_split_RK2_CSp, cs%restart_CSp, &
2181 cs%dt, cs%ADp, cs%CDp, mom_internal_state, cs%VarMix, cs%MEKE, &
2182 cs%OBC, cs%update_OBC_CSp, cs%ALE_CSp, cs%set_visc_CSp, &
2183 cs%visc, dirs, cs%ntrunc)
2186 if (cs%use_RK2)
then 2187 call initialize_dyn_unsplit_rk2(cs%u, cs%v, cs%h, time, g, gv, &
2188 param_file, diag, cs%dyn_unsplit_RK2_CSp, cs%restart_CSp, &
2189 cs%ADp, cs%CDp, mom_internal_state, cs%OBC, cs%update_OBC_CSp, &
2190 cs%ALE_CSp, cs%set_visc_CSp, cs%visc, dirs, cs%ntrunc)
2192 call initialize_dyn_unsplit(cs%u, cs%v, cs%h, time, g, gv, &
2193 param_file, diag, cs%dyn_unsplit_CSp, cs%restart_CSp, &
2194 cs%ADp, cs%CDp, mom_internal_state, cs%OBC, cs%update_OBC_CSp, &
2195 cs%ALE_CSp, cs%set_visc_CSp, cs%visc, dirs, cs%ntrunc)
2201 cs%mixedlayer_restrat = mixedlayer_restrat_init(time, g, gv, param_file, diag, &
2202 cs%mixedlayer_restrat_CSp)
2203 if (cs%mixedlayer_restrat)
then 2204 if (.not.(cs%bulkmixedlayer .or. cs%use_ALE_algorithm)) &
2205 call mom_error(fatal,
"MOM: MIXEDLAYER_RESTRAT true requires a boundary layer scheme.")
2207 if (.not. cs%diabatic_first .and.
associated(cs%visc%MLD)) &
2208 call pass_var(cs%visc%MLD, g%domain, halo=1)
2211 call mom_diagnostics_init(mom_internal_state, cs%ADp, cs%CDp, time, g, gv, &
2212 param_file, diag, cs%diagnostics_CSp)
2214 cs%Z_diag_interval = set_time(int((cs%dt_therm) * &
2215 max(1,floor(0.01 + z_diag_int/(cs%dt_therm)))))
2216 call mom_diag_to_z_init(time, g, gv, param_file, diag, cs%diag_to_Z_CSp)
2217 cs%Z_diag_time = start_time + cs%Z_diag_interval * (1 + &
2218 ((time + set_time(int(cs%dt_therm))) - start_time) / cs%Z_diag_interval)
2220 if (
associated(cs%sponge_CSp)) &
2223 if (
associated(cs%ALE_sponge_CSp)) &
2226 if (cs%adiabatic)
then 2228 cs%tracer_flow_CSp, cs%diag_to_Z_CSp)
2230 call diabatic_driver_init(time, g, gv, param_file, cs%use_ALE_algorithm, diag, &
2231 cs%ADp, cs%CDp, cs%diabatic_CSp, cs%tracer_flow_CSp, &
2232 cs%sponge_CSp, cs%ALE_sponge_CSp, cs%diag_to_Z_CSp)
2235 call tracer_advect_init(time, g, param_file, diag, cs%tracer_adv_CSp)
2236 call tracer_hor_diff_init(time, g, param_file, diag, cs%tracer_diff_CSp, cs%neutral_diffusion_CSp)
2238 if (cs%use_ALE_algorithm) &
2247 if (cs%use_ALE_algorithm)
then 2248 call ale_register_diags(time, g, diag, cs%tv%C_p, cs%tracer_Reg, cs%ALE_CSp)
2254 if (cs%use_temperature)
then 2255 if(cs%advect_TS)
then 2256 call add_tracer_diagnostics(
"T", cs%tracer_Reg, cs%T_adx, cs%T_ady, &
2257 cs%T_diffx, cs%T_diffy, cs%T_adx_2d, cs%T_ady_2d, &
2258 cs%T_diffx_2d, cs%T_diffy_2d, cs%T_advection_xy)
2259 call add_tracer_diagnostics(
"S", cs%tracer_Reg, cs%S_adx, cs%S_ady, &
2260 cs%S_diffx, cs%S_diffy, cs%S_adx_2d, cs%S_ady_2d, &
2261 cs%S_diffx_2d, cs%S_diffy_2d, cs%S_advection_xy)
2263 call register_z_tracer(cs%tv%T,
"temp",
"Potential Temperature",
"degC", time, &
2264 g, cs%diag_to_Z_CSp, cmor_field_name=
"thetao", cmor_units=
"C", &
2265 cmor_standard_name=
"sea_water_potential_temperature", &
2266 cmor_long_name =
"Sea Water Potential Temperature")
2267 call register_z_tracer(cs%tv%S,
"salt",
"Salinity",
"PPT", time, &
2268 g, cs%diag_to_Z_CSp, cmor_field_name=
"so", cmor_units=
"ppt", &
2269 cmor_standard_name=
"sea_water_salinity", &
2270 cmor_long_name =
"Sea Water Salinity")
2274 new_sim = ((dirs%input_filename(1:1) ==
'n') .and. &
2275 (len_trim(dirs%input_filename) == 1))
2276 call tracer_flow_control_init(.not.new_sim, time, g, gv, cs%h, param_file, &
2277 cs%diag, cs%OBC, cs%tracer_flow_CSp, cs%sponge_CSp, &
2278 cs%ALE_sponge_CSp, cs%diag_to_Z_CSp, cs%tv)
2283 if(
present(offline_tracer_mode)) offline_tracer_mode=cs%offline_tracer_mode
2285 if(cs%offline_tracer_mode)
then 2287 call offline_transport_init(param_file, cs%offline_CSp, cs%diabatic_CSp, g, gv)
2288 call insert_offline_main( cs=cs%offline_CSp, ale_csp=cs%ALE_CSp, diabatic_csp=cs%diabatic_CSp, &
2289 diag=cs%diag, obc=cs%OBC, tracer_adv_csp=cs%tracer_adv_CSp, &
2290 tracer_flow_csp=cs%tracer_flow_CSp, tracer_reg=cs%tracer_Reg, &
2291 tv=cs%tv, x_before_y = (mod(first_direction,2)==0), debug=cs%debug )
2292 call register_diags_offline_transport(time, cs%diag, cs%offline_CSp)
2298 dynamics_stencil = min(3, g%Domain%nihalo, g%Domain%njhalo)
2299 call create_group_pass(cs%pass_uv_T_S_h, cs%u, cs%v, g%Domain, halo=dynamics_stencil)
2300 if (cs%use_temperature)
then 2301 call create_group_pass(cs%pass_uv_T_S_h, cs%tv%T, g%Domain, halo=dynamics_stencil)
2302 call create_group_pass(cs%pass_uv_T_S_h, cs%tv%S, g%Domain, halo=dynamics_stencil)
2306 call do_group_pass(cs%pass_uv_T_S_h, g%Domain)
2312 if (cs%use_frazil)
then 2314 cs%tv%frazil(:,:) = 0.0
2317 if (cs%interp_p_surf)
then 2318 cs%p_surf_prev_set = &
2321 if (cs%p_surf_prev_set)
call pass_var(cs%p_surf_prev, g%domain)
2326 call find_eta(cs%h, cs%tv, gv%g_Earth, g, gv, cs%ave_ssh, eta)
2328 call find_eta(cs%h, cs%tv, gv%g_Earth, g, gv, cs%ave_ssh)
2331 if (cs%split)
deallocate(eta)
2334 cs%write_IC = save_ic .and. &
2335 .not.((dirs%input_filename(1:1) ==
'r') .and. &
2336 (len_trim(dirs%input_filename) == 1))
2345 type(time_type),
intent(in) :: Time
2348 type(
forcing),
intent(inout) :: fluxes
2353 real,
allocatable :: z_interface(:,:,:)
2354 real,
allocatable :: eta(:,:)
2361 g => cs%G ; gv => cs%GV
2364 if (cs%write_IC)
then 2365 allocate(restart_csp_tmp)
2366 restart_csp_tmp = cs%restart_CSp
2367 allocate(z_interface(szi_(g),szj_(g),szk_(g)+1))
2368 call find_eta(cs%h, cs%tv, gv%g_Earth, g, gv, z_interface)
2369 vd = var_desc(
"eta",
"meter",
"Interface heights",z_grid=
'i')
2372 call save_restart(dirs%output_directory, time, g, &
2373 restart_csp_tmp, filename=cs%IC_file, gv=gv)
2374 deallocate(z_interface)
2375 deallocate(restart_csp_tmp)
2385 type(time_type),
intent(in) :: Time
2391 character(len=48) :: thickness_units, flux_units, T_flux_units, S_flux_units
2393 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB, nz
2394 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
2395 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
2408 cs%id_u = register_diag_field(
'ocean_model',
'u', diag%axesCuL, time, &
2409 'Zonal velocity',
'meter second-1', cmor_field_name=
'uo', cmor_units=
'm s-1', &
2410 cmor_standard_name=
'sea_water_x_velocity', cmor_long_name=
'Sea Water X Velocity')
2411 cs%id_v = register_diag_field(
'ocean_model',
'v', diag%axesCvL, time, &
2412 'Meridional velocity',
'meter second-1', cmor_field_name=
'vo', cmor_units=
'm s-1', &
2413 cmor_standard_name=
'sea_water_y_velocity', cmor_long_name=
'Sea Water Y Velocity')
2414 cs%id_h = register_diag_field(
'ocean_model',
'h', diag%axesTL, time, &
2415 'Layer Thickness', thickness_units, v_extensive=.true.)
2417 cs%id_volo = register_scalar_field(
'ocean_model',
'volo', time, diag,&
2418 long_name=
'Total volume of liquid ocean', units=
'm3', &
2419 standard_name=
'sea_water_volume')
2420 cs%id_zos = register_diag_field(
'ocean_model',
'zos', diag%axesT1, time,&
2421 standard_name =
'sea_surface_height_above_geoid', &
2422 long_name=
'Sea surface height above geoid', units=
'meter', missing_value=cs%missing)
2423 cs%id_zossq = register_diag_field(
'ocean_model',
'zossq', diag%axesT1, time,&
2424 standard_name=
'square_of_sea_surface_height_above_geoid', &
2425 long_name=
'Square of sea surface height above geoid', units=
'm2', missing_value=cs%missing)
2426 cs%id_ssh = register_diag_field(
'ocean_model',
'SSH', diag%axesT1, time, &
2427 'Sea Surface Height',
'meter', cs%missing)
2428 cs%id_ssh_ga = register_scalar_field(
'ocean_model',
'ssh_ga', time, diag,&
2429 long_name=
'Area averaged sea surface height', units=
'm', &
2430 standard_name=
'area_averaged_sea_surface_height')
2431 cs%id_ssh_inst = register_diag_field(
'ocean_model',
'SSH_inst', diag%axesT1, time, &
2432 'Instantaneous Sea Surface Height',
'meter', cs%missing)
2433 cs%id_ssu = register_diag_field(
'ocean_model',
'SSU', diag%axesCu1, time, &
2434 'Sea Surface Zonal Velocity',
'meter second-1', cs%missing)
2435 cs%id_ssv = register_diag_field(
'ocean_model',
'SSV', diag%axesCv1, time, &
2436 'Sea Surface Meridional Velocity',
'meter second-1', cs%missing)
2437 cs%id_speed = register_diag_field(
'ocean_model',
'speed', diag%axesT1, time, &
2438 'Sea Surface Speed',
'meter second-1', cs%missing)
2440 if (cs%use_temperature)
then 2441 cs%id_T = register_diag_field(
'ocean_model',
'temp', diag%axesTL, time, &
2442 'Potential Temperature',
'Celsius', &
2443 cmor_field_name=
"thetao", cmor_units=
"C", &
2444 cmor_standard_name=
"sea_water_potential_temperature", &
2445 cmor_long_name =
"Sea Water Potential Temperature")
2446 cs%id_S = register_diag_field(
'ocean_model',
'salt', diag%axesTL, time, &
2447 long_name=
'Salinity', units=
'PPT', cmor_field_name=
'so', &
2448 cmor_long_name=
'Sea Water Salinity', cmor_units=
'ppt', &
2449 cmor_standard_name=
'sea_water_salinity')
2450 cs%id_tob = register_diag_field(
'ocean_model',
'tob', diag%axesT1, time, &
2451 long_name=
'Sea Water Potential Temperature at Sea Floor', &
2452 standard_name=
'sea_water_potential_temperature_at_sea_floor', units=
'degC')
2453 cs%id_sob = register_diag_field(
'ocean_model',
'sob',diag%axesT1, time, &
2454 long_name=
'Sea Water Salinity at Sea Floor', &
2455 standard_name=
'sea_water_salinity_at_sea_floor', units=
'ppt')
2456 cs%id_sst = register_diag_field(
'ocean_model',
'SST', diag%axesT1, time, &
2457 'Sea Surface Temperature',
'Celsius', cs%missing, cmor_field_name=
'tos', &
2458 cmor_long_name=
'Sea Surface Temperature', cmor_units=
'degC', &
2459 cmor_standard_name=
'sea_surface_temperature')
2460 cs%id_sst_sq = register_diag_field(
'ocean_model',
'SST_sq', diag%axesT1, time, &
2461 'Sea Surface Temperature Squared',
'Celsius**2', cs%missing, cmor_field_name=
'tossq', &
2462 cmor_long_name=
'Square of Sea Surface Temperature ', cmor_units=
'degC^2', &
2463 cmor_standard_name=
'square_of_sea_surface_temperature')
2464 cs%id_sss = register_diag_field(
'ocean_model',
'SSS', diag%axesT1, time, &
2465 'Sea Surface Salinity',
'PPT', cs%missing, cmor_field_name=
'sos', &
2466 cmor_long_name=
'Sea Surface Salinity', cmor_units=
'ppt', &
2467 cmor_standard_name=
'sea_surface_salinity')
2468 cs%id_sss_sq = register_diag_field(
'ocean_model',
'SSS_sq', diag%axesT1, time, &
2469 'Sea Surface Salinity Squared',
'ppt**2', cs%missing, cmor_field_name=
'sossq', &
2470 cmor_long_name=
'Square of Sea Surface Salinity ', cmor_units=
'ppt^2', &
2471 cmor_standard_name=
'square_of_sea_surface_salinity')
2472 cs%id_Tcon = register_diag_field(
'ocean_model',
'contemp', diag%axesTL, time, &
2473 'Conservative Temperature',
'Celsius')
2474 cs%id_Sabs = register_diag_field(
'ocean_model',
'abssalt', diag%axesTL, time, &
2475 long_name=
'Absolute Salinity', units=
'g/Kg')
2476 cs%id_sstcon = register_diag_field(
'ocean_model',
'conSST', diag%axesT1, time, &
2477 'Sea Surface Conservative Temperature',
'Celsius', cs%missing)
2478 cs%id_sssabs = register_diag_field(
'ocean_model',
'absSSS', diag%axesT1, time, &
2479 'Sea Surface Absolute Salinity',
'g/Kg', cs%missing)
2483 if (cs%use_temperature .and. cs%use_frazil)
then 2484 cs%id_fraz = register_diag_field(
'ocean_model',
'frazil', diag%axesT1, time, &
2485 'Heat from frazil formation',
'Watt meter-2', cmor_field_name=
'hfsifrazil', &
2486 cmor_units=
'W m-2', cmor_standard_name=
'heat_flux_into_sea_water_due_to_frazil_ice_formation', &
2487 cmor_long_name=
'Heat Flux into Sea Water due to Frazil Ice Formation')
2490 cs%id_salt_deficit = register_diag_field(
'ocean_model',
'salt_deficit', diag%axesT1, time, &
2491 'Salt sink in ocean due to ice flux',
'g Salt meter-2 s-1')
2492 cs%id_Heat_PmE = register_diag_field(
'ocean_model',
'Heat_PmE', diag%axesT1, time, &
2493 'Heat flux into ocean from mass flux into ocean',
'Watt meter-2')
2494 cs%id_intern_heat = register_diag_field(
'ocean_model',
'internal_heat', diag%axesT1, time,&
2495 'Heat flux into ocean from geothermal or other internal sources',
'Watt meter-2')
2499 cs%id_Tadx = register_diag_field(
'ocean_model',
'T_adx', diag%axesCuL, time, &
2500 'Advective (by residual mean) Zonal Flux of Potential Temperature', t_flux_units)
2501 cs%id_Tady = register_diag_field(
'ocean_model',
'T_ady', diag%axesCvL, time, &
2502 'Advective (by residual mean) Meridional Flux of Potential Temperature', t_flux_units)
2503 cs%id_Tdiffx = register_diag_field(
'ocean_model',
'T_diffx', diag%axesCuL, time, &
2504 'Diffusive Zonal Flux of Potential Temperature', t_flux_units)
2505 cs%id_Tdiffy = register_diag_field(
'ocean_model',
'T_diffy', diag%axesCvL, time, &
2506 'Diffusive Meridional Flux of Potential Temperature', t_flux_units)
2507 if (cs%id_Tadx > 0)
call safe_alloc_ptr(cs%T_adx,isdb,iedb,jsd,jed,nz)
2508 if (cs%id_Tady > 0)
call safe_alloc_ptr(cs%T_ady,isd,ied,jsdb,jedb,nz)
2509 if (cs%id_Tdiffx > 0)
call safe_alloc_ptr(cs%T_diffx,isdb,iedb,jsd,jed,nz)
2510 if (cs%id_Tdiffy > 0)
call safe_alloc_ptr(cs%T_diffy,isd,ied,jsdb,jedb,nz)
2514 cs%id_Sadx = register_diag_field(
'ocean_model',
'S_adx', diag%axesCuL, time, &
2515 'Advective (by residual mean) Zonal Flux of Salinity', s_flux_units)
2516 cs%id_Sady = register_diag_field(
'ocean_model',
'S_ady', diag%axesCvL, time, &
2517 'Advective (by residual mean) Meridional Flux of Salinity', s_flux_units)
2518 cs%id_Sdiffx = register_diag_field(
'ocean_model',
'S_diffx', diag%axesCuL, time, &
2519 'Diffusive Zonal Flux of Salinity', s_flux_units)
2520 cs%id_Sdiffy = register_diag_field(
'ocean_model',
'S_diffy', diag%axesCvL, time, &
2521 'Diffusive Meridional Flux of Salinity', s_flux_units)
2522 if (cs%id_Sadx > 0)
call safe_alloc_ptr(cs%S_adx,isdb,iedb,jsd,jed,nz)
2523 if (cs%id_Sady > 0)
call safe_alloc_ptr(cs%S_ady,isd,ied,jsdb,jedb,nz)
2524 if (cs%id_Sdiffx > 0)
call safe_alloc_ptr(cs%S_diffx,isdb,iedb,jsd,jed,nz)
2525 if (cs%id_Sdiffy > 0)
call safe_alloc_ptr(cs%S_diffy,isd,ied,jsdb,jedb,nz)
2529 cs%id_Tadx_2d = register_diag_field(
'ocean_model',
'T_adx_2d', diag%axesCu1, time, &
2530 'Vertically Integrated Advective Zonal Flux of Potential Temperature', t_flux_units)
2531 cs%id_Tady_2d = register_diag_field(
'ocean_model',
'T_ady_2d', diag%axesCv1, time, &
2532 'Vertically Integrated Advective Meridional Flux of Potential Temperature', t_flux_units)
2533 cs%id_Tdiffx_2d = register_diag_field(
'ocean_model',
'T_diffx_2d', diag%axesCu1, time, &
2534 'Vertically Integrated Diffusive Zonal Flux of Potential Temperature', t_flux_units)
2535 cs%id_Tdiffy_2d = register_diag_field(
'ocean_model',
'T_diffy_2d', diag%axesCv1, time, &
2536 'Vertically Integrated Diffusive Meridional Flux of Potential Temperature', t_flux_units)
2537 if (cs%id_Tadx_2d > 0)
call safe_alloc_ptr(cs%T_adx_2d,isdb,iedb,jsd,jed)
2538 if (cs%id_Tady_2d > 0)
call safe_alloc_ptr(cs%T_ady_2d,isd,ied,jsdb,jedb)
2539 if (cs%id_Tdiffx_2d > 0)
call safe_alloc_ptr(cs%T_diffx_2d,isdb,iedb,jsd,jed)
2540 if (cs%id_Tdiffy_2d > 0)
call safe_alloc_ptr(cs%T_diffy_2d,isd,ied,jsdb,jedb)
2543 cs%id_Sadx_2d = register_diag_field(
'ocean_model',
'S_adx_2d', diag%axesCu1, time, &
2544 'Vertically Integrated Advective Zonal Flux of Salinity', s_flux_units)
2545 cs%id_Sady_2d = register_diag_field(
'ocean_model',
'S_ady_2d', diag%axesCv1, time, &
2546 'Vertically Integrated Advective Meridional Flux of Salinity', s_flux_units)
2547 cs%id_Sdiffx_2d = register_diag_field(
'ocean_model',
'S_diffx_2d', diag%axesCu1, time, &
2548 'Vertically Integrated Diffusive Zonal Flux of Salinity', s_flux_units)
2549 cs%id_Sdiffy_2d = register_diag_field(
'ocean_model',
'S_diffy_2d', diag%axesCv1, time, &
2550 'Vertically Integrated Diffusive Meridional Flux of Salinity', s_flux_units)
2551 if (cs%id_Sadx_2d > 0)
call safe_alloc_ptr(cs%S_adx_2d,isdb,iedb,jsd,jed)
2552 if (cs%id_Sady_2d > 0)
call safe_alloc_ptr(cs%S_ady_2d,isd,ied,jsdb,jedb)
2553 if (cs%id_Sdiffx_2d > 0)
call safe_alloc_ptr(cs%S_diffx_2d,isdb,iedb,jsd,jed)
2554 if (cs%id_Sdiffy_2d > 0)
call safe_alloc_ptr(cs%S_diffy_2d,isd,ied,jsdb,jedb)
2557 if (cs%debug_truncations)
then 2558 call safe_alloc_ptr(adp%du_dt_visc,isdb,iedb,jsd,jed,nz)
2559 call safe_alloc_ptr(adp%dv_dt_visc,isd,ied,jsdb,jedb,nz)
2560 if (.not.cs%adiabatic)
then 2561 call safe_alloc_ptr(adp%du_dt_dia,isdb,iedb,jsd,jed,nz)
2562 call safe_alloc_ptr(adp%dv_dt_dia,isd,ied,jsdb,jedb,nz)
2567 cs%id_h_pre_dyn = register_diag_field(
'ocean_model',
'h_pre_dyn', diag%axesTL, time, &
2568 'Layer Thickness before dynamics step', thickness_units)
2571 cs%id_u_predia = register_diag_field(
'ocean_model',
'u_predia', diag%axesCuL, time, &
2572 'Zonal velocity before diabatic forcing',
'meter second-1')
2573 cs%id_v_predia = register_diag_field(
'ocean_model',
'v_predia', diag%axesCvL, time, &
2574 'Meridional velocity before diabatic forcing',
'meter second-1')
2575 cs%id_h_predia = register_diag_field(
'ocean_model',
'h_predia', diag%axesTL, time, &
2576 'Layer Thickness before diabatic forcing', thickness_units, v_extensive=.true.)
2577 cs%id_e_predia = register_diag_field(
'ocean_model',
'e_predia', diag%axesTi, time, &
2578 'Interface Heights before diabatic forcing',
'meter')
2579 if (.not. cs%adiabatic)
then 2580 cs%id_u_preale = register_diag_field(
'ocean_model',
'u_preale', diag%axesCuL, time, &
2581 'Zonal velocity before remapping',
'meter second-1')
2582 cs%id_v_preale = register_diag_field(
'ocean_model',
'v_preale', diag%axesCvL, time, &
2583 'Meridional velocity before remapping',
'meter second-1')
2584 cs%id_h_preale = register_diag_field(
'ocean_model',
'h_preale', diag%axesTL, time, &
2585 'Layer Thickness before remapping', thickness_units, v_extensive=.true.)
2586 cs%id_T_preale = register_diag_field(
'ocean_model',
'T_preale', diag%axesTL, time, &
2587 'Temperature before remapping',
'degC')
2588 cs%id_S_preale = register_diag_field(
'ocean_model',
'S_preale', diag%axesTL, time, &
2589 'Salinity before remapping',
'ppt')
2590 cs%id_e_preale = register_diag_field(
'ocean_model',
'e_preale', diag%axesTi, time, &
2591 'Interface Heights before remapping',
'meter')
2594 if (cs%use_temperature)
then 2595 cs%id_T_predia = register_diag_field(
'ocean_model',
'temp_predia', diag%axesTL, time, &
2596 'Potential Temperature',
'Celsius')
2597 cs%id_S_predia = register_diag_field(
'ocean_model',
'salt_predia', diag%axesTL, time, &
2602 cs%id_uhtr = register_diag_field(
'ocean_model',
'uhtr', diag%axesCuL, time, &
2603 'Accumulated zonal thickness fluxes to advect tracers',
'kg', &
2604 y_cell_method=
'sum', v_extensive=.true.)
2605 cs%id_vhtr = register_diag_field(
'ocean_model',
'vhtr', diag%axesCvL, time, &
2606 'Accumulated meridional thickness fluxes to advect tracers',
'kg', &
2607 x_cell_method=
'sum', v_extensive=.true.)
2608 cs%id_umo = register_diag_field(
'ocean_model',
'umo', &
2609 diag%axesCuL, time,
'Ocean Mass X Transport',
'kg/s', &
2610 standard_name=
'ocean_mass_x_transport', y_cell_method=
'sum', v_extensive=.true.)
2611 cs%id_vmo = register_diag_field(
'ocean_model',
'vmo', &
2612 diag%axesCvL, time,
'Ocean Mass Y Transport',
'kg/s', &
2613 standard_name=
'ocean_mass_y_transport', x_cell_method=
'sum', v_extensive=.true.)
2614 cs%id_umo_2d = register_diag_field(
'ocean_model',
'umo_2d', &
2615 diag%axesCu1, time,
'Ocean Mass X Transport Vertical Sum',
'kg/s', &
2616 standard_name=
'ocean_mass_x_transport_vertical_sum', y_cell_method=
'sum')
2617 cs%id_vmo_2d = register_diag_field(
'ocean_model',
'vmo_2d', &
2618 diag%axesCv1, time,
'Ocean Mass Y Transport Vertical Sum',
'kg/s', &
2619 standard_name=
'ocean_mass_y_transport_vertical_sum', x_cell_method=
'sum')
2626 type(time_type),
intent(in) :: Time
2632 integer :: isd, ied, jsd, jed, nz
2633 integer :: is, ie, js, je
2636 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
2637 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
2641 cs%id_T_advection_xy = register_diag_field(
'ocean_model',
'T_advection_xy', diag%axesTL, time, &
2642 'Horizontal convergence of residual mean heat advective fluxes',
'W/m2',v_extensive=.true.)
2643 cs%id_T_advection_xy_2d = register_diag_field(
'ocean_model',
'T_advection_xy_2d', diag%axesT1, time,&
2644 'Vertical sum of horizontal convergence of residual mean heat advective fluxes',
'W/m2')
2645 if (cs%id_T_advection_xy > 0 .or. cs%id_T_advection_xy_2d > 0)
then 2646 call safe_alloc_ptr(cs%T_advection_xy,isd,ied,jsd,jed,nz)
2647 cs%tendency_diagnostics = .true.
2651 cs%id_T_tendency = register_diag_field(
'ocean_model',
'T_tendency', diag%axesTL, time, &
2652 'Net time tendency for temperature',
'degC/s')
2653 cs%id_Th_tendency = register_diag_field(
'ocean_model',
'Th_tendency', diag%axesTL, time, &
2654 'Net time tendency for heat',
'W/m2', &
2655 cmor_field_name=
"opottemptend", cmor_units=
"W m-2", &
2656 cmor_standard_name=
"tendency_of_sea_water_potential_temperature_expressed_as_heat_content", &
2657 cmor_long_name =
"Tendency of Sea Water Potential Temperature Expressed as Heat Content", &
2659 cs%id_Th_tendency_2d = register_diag_field(
'ocean_model',
'Th_tendency_2d', diag%axesT1, time, &
2660 'Vertical sum of net time tendency for heat',
'W/m2', &
2661 cmor_field_name=
"opottemptend_2d", cmor_units=
"W m-2", &
2662 cmor_standard_name=
"tendency_of_sea_water_potential_temperature_expressed_as_heat_content_vertical_sum",&
2663 cmor_long_name =
"Tendency of Sea Water Potential Temperature Expressed as Heat Content Vertical Sum")
2664 if (cs%id_T_tendency > 0)
then 2665 cs%tendency_diagnostics = .true.
2666 call safe_alloc_ptr(cs%T_prev,isd,ied,jsd,jed,nz)
2667 do k=1,nz ;
do j=js,je ;
do i=is,ie
2668 cs%T_prev(i,j,k) = cs%tv%T(i,j,k)
2669 enddo ;
enddo ;
enddo 2671 if (cs%id_Th_tendency > 0 .or. cs%id_Th_tendency_2d > 0)
then 2672 cs%tendency_diagnostics = .true.
2673 call safe_alloc_ptr(cs%Th_prev,isd,ied,jsd,jed,nz)
2674 do k=1,nz ;
do j=js,je ;
do i=is,ie
2675 cs%Th_prev(i,j,k) = cs%tv%T(i,j,k) * cs%h(i,j,k)
2676 enddo ;
enddo ;
enddo 2681 cs%id_S_advection_xy = register_diag_field(
'ocean_model',
'S_advection_xy', diag%axesTL, time, &
2682 'Horizontal convergence of residual mean salt advective fluxes',
'kg/(m2 * s)', v_extensive=.true.)
2683 cs%id_S_advection_xy_2d = register_diag_field(
'ocean_model',
'S_advection_xy_2d', diag%axesT1, time,&
2684 'Vertical sum of horizontal convergence of residual mean salt advective fluxes',
'kg/(m2 * s)')
2685 if (cs%id_S_advection_xy > 0 .or. cs%id_S_advection_xy_2d > 0)
then 2686 call safe_alloc_ptr(cs%S_advection_xy,isd,ied,jsd,jed,nz)
2687 cs%tendency_diagnostics = .true.
2691 cs%id_S_tendency = register_diag_field(
'ocean_model',
'S_tendency', diag%axesTL, time, &
2692 'Net time tendency for salinity',
'PPT/s')
2693 cs%id_Sh_tendency = register_diag_field(
'ocean_model',
'Sh_tendency', diag%axesTL, time,&
2694 'Net time tendency for salt',
'kg/(m2 * s)', &
2695 cmor_field_name=
"osalttend", cmor_units=
"kg m-2 s-1", &
2696 cmor_standard_name=
"tendency_of_sea_water_salinity_expressed_as_salt_content", &
2697 cmor_long_name =
"Tendency of Sea Water Salinity Expressed as Salt Content", &
2699 cs%id_Sh_tendency_2d = register_diag_field(
'ocean_model',
'Sh_tendency_2d', diag%axesT1, time, &
2700 'Vertical sum of net time tendency for salt',
'kg/(m2 * s)', &
2701 cmor_field_name=
"osalttend_2d", cmor_units=
"kg m-2 s-1", &
2702 cmor_standard_name=
"tendency_of_sea_water_salinity_expressed_as_salt_content_vertical_sum",&
2703 cmor_long_name =
"Tendency of Sea Water Salinity Expressed as Salt Content Vertical Sum")
2704 if (cs%id_S_tendency > 0)
then 2705 cs%tendency_diagnostics = .true.
2706 call safe_alloc_ptr(cs%S_prev,isd,ied,jsd,jed,nz)
2707 do k=1,nz ;
do j=js,je ;
do i=is,ie
2708 cs%S_prev(i,j,k) = cs%tv%S(i,j,k)
2709 enddo ;
enddo ;
enddo 2711 if (cs%id_Sh_tendency > 0 .or. cs%id_Sh_tendency_2d > 0)
then 2712 cs%tendency_diagnostics = .true.
2713 call safe_alloc_ptr(cs%Sh_prev,isd,ied,jsd,jed,nz)
2714 do k=1,nz ;
do j=js,je ;
do i=is,ie
2715 cs%Sh_prev(i,j,k) = cs%tv%S(i,j,k) * cs%h(i,j,k)
2716 enddo ;
enddo ;
enddo 2725 type(time_type),
intent(in) :: Time
2731 integer :: isd, ied, jsd, jed, nz
2736 isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
2739 cs%id_T_vardec = register_diag_field(
'ocean_model',
'T_vardec', diag%axesTL, time, &
2740 'ALE variance decay for temperature',
'degC2 s-1')
2741 if (cs%id_T_vardec > 0)
then 2742 call safe_alloc_ptr(cs%T_squared,isd,ied,jsd,jed,nz)
2743 cs%T_squared(:,:,:) = 0.
2745 vd_tmp = var_desc(name=
"T2", units=
"degC2", longname=
"Squared Potential Temperature")
2746 call register_tracer(cs%T_squared, vd_tmp, param_file, hi, gv, cs%tracer_reg)
2749 cs%id_S_vardec = register_diag_field(
'ocean_model',
'S_vardec', diag%axesTL, time, &
2750 'ALE variance decay for salinity',
'PPT2 s-1')
2751 if (cs%id_S_vardec > 0)
then 2752 call safe_alloc_ptr(cs%S_squared,isd,ied,jsd,jed,nz)
2753 cs%S_squared(:,:,:) = 0.
2755 vd_tmp = var_desc(name=
"S2", units=
"PPT2", longname=
"Squared Salinity")
2756 call register_tracer(cs%S_squared, vd_tmp, param_file, hi, gv, cs%tracer_reg)
2767 id_clock_thermo = cpu_clock_id(
'Ocean thermodynamics and tracers', grain=clock_subcomponent)
2768 id_clock_other = cpu_clock_id(
'Ocean Other', grain=clock_subcomponent)
2769 id_clock_tracer = cpu_clock_id(
'(Ocean tracer advection)', grain=clock_module_driver)
2770 if (.not.cs%adiabatic) &
2771 id_clock_diabatic = cpu_clock_id(
'(Ocean diabatic driver)', grain=clock_module_driver)
2774 id_clock_bbl_visc = cpu_clock_id(
'(Ocean set BBL viscosity)', grain=clock_module)
2775 id_clock_pass = cpu_clock_id(
'(Ocean message passing *)', grain=clock_module)
2776 id_clock_mom_init = cpu_clock_id(
'(Ocean MOM_initialize_state)', grain=clock_module)
2777 id_clock_pass_init = cpu_clock_id(
'(Ocean init message passing *)', grain=clock_routine)
2778 if (cs%thickness_diffuse) &
2783 id_clock_z_diag = cpu_clock_id(
'(Ocean Z-space diagnostics)', grain=clock_module)
2784 id_clock_ale = cpu_clock_id(
'(Ocean ALE)', grain=clock_module)
2785 if(cs%offline_tracer_mode)
then 2798 real ,
intent(in) :: dt_trans
2799 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
2801 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
2802 intent(in) :: h_pre_dyn
2804 real,
dimension(SZIB_(G), SZJ_(G)) :: umo2d
2805 real,
dimension(SZI_(G), SZJB_(G)) :: vmo2d
2806 real,
dimension(SZIB_(G), SZJ_(G), SZK_(G)) :: umo
2807 real,
dimension(SZI_(G), SZJB_(G), SZK_(G)) :: vmo
2808 real :: H_to_kg_m2_dt
2809 integer :: i, j, k, is, ie, js, je, nz
2810 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
2813 call calculate_z_transport(cs%uhtr, cs%vhtr, h, dt_trans, g, gv, &
2819 call diag_update_remap_grids(diag, alt_h = h_pre_dyn)
2821 h_to_kg_m2_dt = gv%H_to_kg_m2 / dt_trans
2822 if (cs%id_umo_2d > 0)
then 2824 do k=1,nz ;
do j=js,je ;
do i=is-1,ie
2825 umo2d(i,j) = umo2d(i,j) + cs%uhtr(i,j,k) * h_to_kg_m2_dt
2826 enddo ;
enddo ;
enddo 2827 call post_data(cs%id_umo_2d, umo2d, diag)
2829 if (cs%id_umo > 0)
then 2831 do k=1,nz ;
do j=js,je ;
do i=is-1,ie
2832 umo(i,j,k) = cs%uhtr(i,j,k) * h_to_kg_m2_dt
2833 enddo ;
enddo ;
enddo 2834 call post_data(cs%id_umo, umo, diag, alt_h = h_pre_dyn)
2836 if (cs%id_vmo_2d > 0)
then 2838 do k=1,nz ;
do j=js-1,je ;
do i=is,ie
2839 vmo2d(i,j) = vmo2d(i,j) + cs%vhtr(i,j,k) * h_to_kg_m2_dt
2840 enddo ;
enddo ;
enddo 2841 call post_data(cs%id_vmo_2d, vmo2d, diag)
2843 if (cs%id_vmo > 0)
then 2845 do k=1,nz ;
do j=js-1,je ;
do i=is,ie
2846 vmo(i,j,k) = cs%vhtr(i,j,k) * h_to_kg_m2_dt
2847 enddo ;
enddo ;
enddo 2848 call post_data(cs%id_vmo, vmo, diag, alt_h = h_pre_dyn)
2851 if (cs%id_uhtr > 0)
call post_data(cs%id_uhtr, cs%uhtr, diag, alt_h = h_pre_dyn)
2852 if (cs%id_vhtr > 0)
call post_data(cs%id_vhtr, cs%vhtr, diag, alt_h = h_pre_dyn)
2863 real,
intent(in) :: dt
2865 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: potTemp, pracSal
2866 real :: work3d(szi_(g),szj_(g),szk_(g))
2867 real :: work2d(szi_(g),szj_(g))
2868 real :: Idt, ppt2mks
2869 integer :: i, j, k, is, ie, js, je, nz
2870 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
2872 if (.NOT. cs%use_conT_absS)
then 2874 if (cs%id_T > 0)
call post_data(cs%id_T, tv%T, diag)
2875 if (cs%id_S > 0)
call post_data(cs%id_S, tv%S, diag)
2877 if (cs%id_tob > 0)
call post_data(cs%id_tob, tv%T(:,:,g%ke), diag, mask=g%mask2dT)
2878 if (cs%id_sob > 0)
call post_data(cs%id_sob, tv%S(:,:,g%ke), diag, mask=g%mask2dT)
2881 if (cs%id_Tcon > 0)
call post_data(cs%id_Tcon, tv%T, diag)
2882 if (cs%id_Sabs > 0)
call post_data(cs%id_Sabs, tv%S, diag)
2886 do k=1,nz ;
do j=js,je ;
do i=is,ie
2887 pracsal(i,j,k) = gsw_sp_from_sr(tv%S(i,j,k))
2888 pottemp(i,j,k) = gsw_pt_from_ct(tv%S(i,j,k),tv%T(i,j,k))
2889 enddo; enddo ; enddo
2890 if (cs%id_T > 0)
call post_data(cs%id_T, pottemp, diag)
2891 if (cs%id_S > 0)
call post_data(cs%id_S, pracsal, diag)
2892 if (cs%id_tob > 0)
call post_data(cs%id_tob, pottemp(:,:,g%ke), diag, mask=g%mask2dT)
2893 if (cs%id_sob > 0)
call post_data(cs%id_sob, pracsal(:,:,g%ke), diag, mask=g%mask2dT)
2896 if (cs%id_Tadx > 0)
call post_data(cs%id_Tadx, cs%T_adx, diag)
2897 if (cs%id_Tady > 0)
call post_data(cs%id_Tady, cs%T_ady, diag)
2898 if (cs%id_Tdiffx > 0)
call post_data(cs%id_Tdiffx, cs%T_diffx, diag)
2899 if (cs%id_Tdiffy > 0)
call post_data(cs%id_Tdiffy, cs%T_diffy, diag)
2901 if (cs%id_Sadx > 0)
call post_data(cs%id_Sadx, cs%S_adx, diag)
2902 if (cs%id_Sady > 0)
call post_data(cs%id_Sady, cs%S_ady, diag)
2903 if (cs%id_Sdiffx > 0)
call post_data(cs%id_Sdiffx, cs%S_diffx, diag)
2904 if (cs%id_Sdiffy > 0)
call post_data(cs%id_Sdiffy, cs%S_diffy, diag)
2906 if (cs%id_Tadx_2d > 0)
call post_data(cs%id_Tadx_2d, cs%T_adx_2d, diag)
2907 if (cs%id_Tady_2d > 0)
call post_data(cs%id_Tady_2d, cs%T_ady_2d, diag)
2908 if (cs%id_Tdiffx_2d > 0)
call post_data(cs%id_Tdiffx_2d, cs%T_diffx_2d, diag)
2909 if (cs%id_Tdiffy_2d > 0)
call post_data(cs%id_Tdiffy_2d, cs%T_diffy_2d, diag)
2911 if (cs%id_Sadx_2d > 0)
call post_data(cs%id_Sadx_2d, cs%S_adx_2d, diag)
2912 if (cs%id_Sady_2d > 0)
call post_data(cs%id_Sady_2d, cs%S_ady_2d, diag)
2913 if (cs%id_Sdiffx_2d > 0)
call post_data(cs%id_Sdiffx_2d, cs%S_diffx_2d, diag)
2914 if (cs%id_Sdiffy_2d > 0)
call post_data(cs%id_Sdiffy_2d, cs%S_diffy_2d, diag)
2916 if(.not. cs%tendency_diagnostics)
return 2918 idt = 0.;
if (dt/=0.) idt = 1.0 / dt
2925 if (cs%id_T_advection_xy > 0 .or. cs%id_T_advection_xy_2d > 0)
then 2926 do k=1,nz ;
do j=js,je ;
do i=is,ie
2927 work3d(i,j,k) = cs%T_advection_xy(i,j,k) * gv%H_to_kg_m2 * tv%C_p
2928 enddo ;
enddo ;
enddo 2929 if (cs%id_T_advection_xy > 0)
call post_data(cs%id_T_advection_xy, work3d, diag)
2930 if (cs%id_T_advection_xy_2d > 0)
then 2931 do j=js,je ;
do i=is,ie
2934 work2d(i,j) = work2d(i,j) + work3d(i,j,k)
2937 call post_data(cs%id_T_advection_xy_2d, work2d, diag)
2943 if (cs%id_S_advection_xy > 0 .or. cs%id_S_advection_xy_2d > 0)
then 2944 do k=1,nz ;
do j=js,je ;
do i=is,ie
2945 work3d(i,j,k) = cs%S_advection_xy(i,j,k) * gv%H_to_kg_m2 * ppt2mks
2946 enddo ;
enddo ;
enddo 2947 if (cs%id_S_advection_xy > 0)
call post_data(cs%id_S_advection_xy, work3d, diag)
2948 if (cs%id_S_advection_xy_2d > 0)
then 2949 do j=js,je ;
do i=is,ie
2952 work2d(i,j) = work2d(i,j) + work3d(i,j,k)
2955 call post_data(cs%id_S_advection_xy_2d, work2d, diag)
2960 if (cs%id_T_tendency > 0)
then 2961 do k=1,nz ;
do j=js,je ;
do i=is,ie
2962 work3d(i,j,k) = (tv%T(i,j,k) - cs%T_prev(i,j,k))*idt
2963 cs%T_prev(i,j,k) = tv%T(i,j,k)
2964 enddo ;
enddo ;
enddo 2965 call post_data(cs%id_T_tendency, work3d, diag)
2969 if (cs%id_S_tendency > 0)
then 2970 do k=1,nz ;
do j=js,je ;
do i=is,ie
2971 work3d(i,j,k) = (tv%S(i,j,k) - cs%S_prev(i,j,k))*idt
2972 cs%S_prev(i,j,k) = tv%S(i,j,k)
2973 enddo ;
enddo ;
enddo 2974 call post_data(cs%id_S_tendency, work3d, diag)
2978 if (cs%id_Th_tendency > 0 .or. cs%id_Th_tendency_2d > 0)
then 2979 do k=1,nz ;
do j=js,je ;
do i=is,ie
2980 work3d(i,j,k) = (tv%T(i,j,k)*cs%h(i,j,k) - cs%Th_prev(i,j,k)) * idt * gv%H_to_kg_m2 * tv%C_p
2981 cs%Th_prev(i,j,k) = tv%T(i,j,k)*cs%h(i,j,k)
2982 enddo ;
enddo ;
enddo 2983 if (cs%id_Th_tendency > 0)
call post_data(cs%id_Th_tendency, work3d, diag)
2984 if (cs%id_Th_tendency_2d > 0)
then 2985 do j=js,je ;
do i=is,ie
2988 work2d(i,j) = work2d(i,j) + work3d(i,j,k)
2991 call post_data(cs%id_Th_tendency_2d, work2d, diag)
2996 if (cs%id_Sh_tendency > 0 .or. cs%id_Sh_tendency_2d > 0)
then 2997 do k=1,nz ;
do j=js,je ;
do i=is,ie
2998 work3d(i,j,k) = (tv%S(i,j,k)*cs%h(i,j,k) - cs%Sh_prev(i,j,k)) * idt * gv%H_to_kg_m2 * ppt2mks
2999 cs%Sh_prev(i,j,k) = tv%S(i,j,k)*cs%h(i,j,k)
3000 enddo ;
enddo ;
enddo 3001 if (cs%id_Sh_tendency > 0)
call post_data(cs%id_Sh_tendency, work3d, diag)
3002 if (cs%id_Sh_tendency_2d > 0)
then 3003 do j=js,je ;
do i=is,ie
3006 work2d(i,j) = work2d(i,j) + work3d(i,j,k)
3009 call post_data(cs%id_Sh_tendency_2d, work2d, diag)
3017 type(ocean_grid_type),
intent(in) :: G
3019 real,
intent(in) :: dt
3021 real :: work(szi_(g),szj_(g),szk_(g))
3023 integer :: i, j, k, is, ie, js, je, nz
3024 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3026 idt = 0.;
if (dt/=0.) idt = 1.0 / dt
3028 if (cs%id_T_vardec > 0)
then 3029 do k=1,nz ;
do j=js,je ;
do i=is,ie
3030 work(i,j,k) = (cs%T_squared(i,j,k) - cs%tv%T(i,j,k)**2) * idt
3031 enddo ;
enddo ;
enddo 3032 call post_data(cs%id_T_vardec, work, cs%diag)
3035 if (cs%id_S_vardec > 0)
then 3036 do k=1,nz ;
do j=js,je ;
do i=is,ie
3037 work(i,j,k) = (cs%S_squared(i,j,k) - cs%tv%S(i,j,k)**2) * idt
3038 enddo ;
enddo ;
enddo 3039 call post_data(cs%id_S_vardec, work, cs%diag)
3046 type(ocean_grid_type),
intent(in) :: G
3047 type(verticalgrid_type),
intent(in) :: GV
3048 type(diag_ctrl),
intent(in) :: diag
3049 real,
intent(in) :: dt_int
3050 type(thermo_var_ptrs),
intent(in) :: tv
3051 type(forcing),
intent(in) :: fluxes
3053 real,
allocatable,
dimension(:,:) :: &
3066 real :: zos_area_mean, volo, ssh_ga
3067 integer :: i, j, k, is, ie, js, je, nz
3069 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3072 if (cs%id_ssh_ga > 0)
then 3073 ssh_ga = global_area_mean(cs%ave_ssh, g)
3074 call post_data(cs%id_ssh_ga, ssh_ga, diag)
3077 i_time_int = 1.0 / dt_int
3078 if (cs%id_ssh > 0) &
3079 call post_data(cs%id_ssh, cs%ave_ssh, diag, mask=g%mask2dT)
3084 if(cs%id_zos > 0 .or. cs%id_zossq > 0)
then 3085 allocate(zos(g%isd:g%ied,g%jsd:g%jed))
3087 do j=js,je ;
do i=is,ie
3088 zos(i,j) = cs%ave_ssh(i,j)
3090 if (
ASSOCIATED(fluxes%p_surf))
then 3091 do j=js,je ;
do i=is,ie
3092 zos(i,j) = zos(i,j) + g%mask2dT(i,j)*fluxes%p_surf(i,j) / &
3093 (gv%Rho0 * gv%g_Earth)
3096 zos_area_mean = global_area_mean(zos, g)
3097 do j=js,je ;
do i=is,ie
3098 zos(i,j) = zos(i,j) - g%mask2dT(i,j)*zos_area_mean
3100 if(cs%id_zos > 0)
then 3101 call post_data(cs%id_zos, zos, diag, mask=g%mask2dT)
3103 if(cs%id_zossq > 0)
then 3104 allocate(zossq(g%isd:g%ied,g%jsd:g%jed))
3106 do j=js,je ;
do i=is,ie
3107 zossq(i,j) = zos(i,j)*zos(i,j)
3109 call post_data(cs%id_zossq, zossq, diag, mask=g%mask2dT)
3116 if(cs%id_volo > 0)
then 3117 allocate(tmp(g%isd:g%ied,g%jsd:g%jed))
3118 do j=js,je ;
do i=is,ie
3119 tmp(i,j) = g%mask2dT(i,j)*(cs%ave_ssh(i,j) + g%bathyT(i,j))
3121 volo = global_area_integral(tmp, g)
3122 call post_data(cs%id_volo, volo, diag)
3127 if (
ASSOCIATED(tv%frazil) .and. (cs%id_fraz > 0))
then 3128 allocate(frazil_ave(g%isd:g%ied,g%jsd:g%jed))
3129 do j=js,je ;
do i=is,ie
3130 frazil_ave(i,j) = tv%frazil(i,j) * i_time_int
3132 call post_data(cs%id_fraz, frazil_ave, diag, mask=g%mask2dT)
3133 deallocate(frazil_ave)
3137 if (
ASSOCIATED(tv%salt_deficit) .and. (cs%id_salt_deficit > 0))
then 3138 allocate(salt_deficit_ave(g%isd:g%ied,g%jsd:g%jed))
3139 do j=js,je ;
do i=is,ie
3140 salt_deficit_ave(i,j) = tv%salt_deficit(i,j) * i_time_int
3142 call post_data(cs%id_salt_deficit, salt_deficit_ave, diag, mask=g%mask2dT)
3143 deallocate(salt_deficit_ave)
3147 if (
ASSOCIATED(tv%TempxPmE) .and. (cs%id_Heat_PmE > 0))
then 3148 allocate(heat_pme_ave(g%isd:g%ied,g%jsd:g%jed))
3149 do j=js,je ;
do i=is,ie
3150 heat_pme_ave(i,j) = tv%TempxPmE(i,j) * (tv%C_p * i_time_int)
3152 call post_data(cs%id_Heat_PmE, heat_pme_ave, diag, mask=g%mask2dT)
3153 deallocate(heat_pme_ave)
3157 if (
ASSOCIATED(tv%internal_heat) .and. (cs%id_intern_heat > 0))
then 3158 allocate(intern_heat_ave(g%isd:g%ied,g%jsd:g%jed))
3159 do j=js,je ;
do i=is,ie
3160 intern_heat_ave(i,j) = tv%internal_heat(i,j) * (tv%C_p * i_time_int)
3162 call post_data(cs%id_intern_heat, intern_heat_ave, diag, mask=g%mask2dT)
3163 deallocate(intern_heat_ave)
3171 type(ocean_grid_type),
intent(in) :: G
3172 type(diag_ctrl),
intent(in) :: diag
3173 type(surface),
intent(in) :: state
3175 real,
dimension(SZI_(G),SZJ_(G)) :: &
3182 integer :: i, j, is, ie, js, je
3184 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3186 if (.NOT.cs%use_conT_absS)
then 3188 if (cs%id_sst > 0)
call post_data(cs%id_sst, state%SST, diag, mask=g%mask2dT)
3189 if (cs%id_sss > 0)
call post_data(cs%id_sss, state%SSS, diag, mask=g%mask2dT)
3192 if (cs%id_sstcon > 0)
call post_data(cs%id_sstcon, state%SST, diag, mask=g%mask2dT)
3193 if (cs%id_sssabs > 0)
call post_data(cs%id_sssabs, state%SSS, diag, mask=g%mask2dT)
3197 do j=js,je ;
do i=is,ie
3198 pracsal(i,j) = gsw_sp_from_sr(state%SSS(i,j))
3199 pottemp(i,j) = gsw_pt_from_ct(state%SSS(i,j),state%SST(i,j))
3201 if (cs%id_sst > 0)
call post_data(cs%id_sst, pottemp, diag, mask=g%mask2dT)
3202 if (cs%id_sss > 0)
call post_data(cs%id_sss, pracsal, diag, mask=g%mask2dT)
3205 if (cs%id_sst_sq > 0)
then 3206 do j=js,je ;
do i=is,ie
3207 sst_sq(i,j) = state%SST(i,j)*state%SST(i,j)
3209 call post_data(cs%id_sst_sq, sst_sq, diag, mask=g%mask2dT)
3211 if (cs%id_sss_sq > 0)
then 3212 do j=js,je ;
do i=is,ie
3213 sss_sq(i,j) = state%SSS(i,j)*state%SSS(i,j)
3215 call post_data(cs%id_sss_sq, sss_sq, diag, mask=g%mask2dT)
3218 if (cs%id_ssu > 0) &
3219 call post_data(cs%id_ssu, state%u, diag, mask=g%mask2dCu)
3220 if (cs%id_ssv > 0) &
3221 call post_data(cs%id_ssv, state%v, diag, mask=g%mask2dCv)
3223 if (cs%id_speed > 0)
then 3224 do j=js,je ;
do i=is,ie
3225 sfc_speed(i,j) = sqrt(0.5*(state%u(i-1,j)**2 + state%u(i,j)**2) + &
3226 0.5*(state%v(i,j-1)**2 + state%v(i,j)**2))
3228 call post_data(cs%id_speed, sfc_speed, diag, mask=g%mask2dT)
3236 type(ocean_grid_type),
intent(in) :: G
3237 type(diag_ctrl),
target,
intent(inout) :: diag
3241 real :: out_h(szi_(g),szj_(g))
3242 integer :: id, i, j, is, ie, js, je
3243 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3247 id = register_static_field(
'ocean_model',
'geolat', diag%axesT1, &
3248 'Latitude of tracer (T) points',
'degrees_N')
3249 if (id > 0)
call post_data(id, g%geoLatT, diag, .true.)
3251 id = register_static_field(
'ocean_model',
'geolon', diag%axesT1, &
3252 'Longitude of tracer (T) points',
'degrees_E')
3253 if (id > 0)
call post_data(id, g%geoLonT, diag, .true.)
3255 id = register_static_field(
'ocean_model',
'geolat_c', diag%axesB1, &
3256 'Latitude of corner (Bu) points',
'degrees_N', interp_method=
'none')
3257 if (id > 0)
call post_data(id, g%geoLatBu, diag, .true.)
3259 id = register_static_field(
'ocean_model',
'geolon_c', diag%axesB1, &
3260 'Longitude of corner (Bu) points',
'degrees_E', interp_method=
'none')
3261 if (id > 0)
call post_data(id, g%geoLonBu, diag, .true.)
3263 id = register_static_field(
'ocean_model',
'geolat_v', diag%axesCv1, &
3264 'Latitude of meridional velocity (Cv) points',
'degrees_N', interp_method=
'none')
3265 if (id > 0)
call post_data(id, g%geoLatCv, diag, .true.)
3267 id = register_static_field(
'ocean_model',
'geolon_v', diag%axesCv1, &
3268 'Longitude of meridional velocity (Cv) points',
'degrees_E', interp_method=
'none')
3269 if (id > 0)
call post_data(id, g%geoLonCv, diag, .true.)
3271 id = register_static_field(
'ocean_model',
'geolat_u', diag%axesCu1, &
3272 'Latitude of zonal velocity (Cu) points',
'degrees_N', interp_method=
'none')
3273 if (id > 0)
call post_data(id, g%geoLatCu, diag, .true.)
3275 id = register_static_field(
'ocean_model',
'geolon_u', diag%axesCu1, &
3276 'Longitude of zonal velocity (Cu) points',
'degrees_E', interp_method=
'none')
3277 if (id > 0)
call post_data(id, g%geoLonCu, diag, .true.)
3279 id = register_static_field(
'ocean_model',
'area_t', diag%axesT1, &
3280 'Surface area of tracer (T) cells',
'm2', &
3281 cmor_field_name=
'areacello', cmor_standard_name=
'cell_area', &
3282 cmor_units=
'm2', cmor_long_name=
'Ocean Grid-Cell Area')
3284 do j=js,je ;
do i=is,ie ; out_h(i,j) = g%areaT(i,j) ;
enddo ;
enddo 3285 call post_data(id, out_h, diag, .true.)
3286 call diag_register_area_ids(diag, id_area_t=id)
3289 id = register_static_field(
'ocean_model',
'depth_ocean', diag%axesT1, &
3290 'Depth of the ocean at tracer points',
'm', &
3291 standard_name=
'sea_floor_depth_below_geoid', &
3292 cmor_field_name=
'deptho', cmor_long_name=
'Sea Floor Depth', &
3293 cmor_units=
'm', cmor_standard_name=
'sea_floor_depth_below_geoid',&
3294 area=diag%axesT1%id_area)
3295 if (id > 0)
call post_data(id, g%bathyT, diag, .true., mask=g%mask2dT)
3297 id = register_static_field(
'ocean_model',
'wet', diag%axesT1, &
3298 '0 if land, 1 if ocean at tracer points',
'none', area=diag%axesT1%id_area)
3299 if (id > 0)
call post_data(id, g%mask2dT, diag, .true.)
3301 id = register_static_field(
'ocean_model',
'wet_c', diag%axesB1, &
3302 '0 if land, 1 if ocean at corner (Bu) points',
'none', interp_method=
'none')
3303 if (id > 0)
call post_data(id, g%mask2dBu, diag, .true.)
3305 id = register_static_field(
'ocean_model',
'wet_u', diag%axesCu1, &
3306 '0 if land, 1 if ocean at zonal velocity (Cu) points',
'none', interp_method=
'none')
3307 if (id > 0)
call post_data(id, g%mask2dCu, diag, .true.)
3309 id = register_static_field(
'ocean_model',
'wet_v', diag%axesCv1, &
3310 '0 if land, 1 if ocean at meridional velocity (Cv) points',
'none', interp_method=
'none')
3311 if (id > 0)
call post_data(id, g%mask2dCv, diag, .true.)
3313 id = register_static_field(
'ocean_model',
'Coriolis', diag%axesB1, &
3314 'Coriolis parameter at corner (Bu) points',
's-1', interp_method=
'none')
3315 if (id > 0)
call post_data(id, g%CoriolisBu, diag, .true.)
3317 id = register_static_field(
'ocean_model',
'dxt', diag%axesT1, &
3318 'Delta(x) at thickness/tracer points (meter)',
'm', interp_method=
'none')
3319 if (id > 0)
call post_data(id, g%dxt, diag, .true.)
3321 id = register_static_field(
'ocean_model',
'dyt', diag%axesT1, &
3322 'Delta(y) at thickness/tracer points (meter)',
'm', interp_method=
'none')
3323 if (id > 0)
call post_data(id, g%dyt, diag, .true.)
3325 id = register_static_field(
'ocean_model',
'dxCu', diag%axesCu1, &
3326 'Delta(x) at u points (meter)',
'm', interp_method=
'none')
3327 if (id > 0)
call post_data(id, g%dxCu, diag, .true.)
3329 id = register_static_field(
'ocean_model',
'dyCu', diag%axesCu1, &
3330 'Delta(y) at u points (meter)',
'm', interp_method=
'none')
3331 if (id > 0)
call post_data(id, g%dyCu, diag, .true.)
3333 id = register_static_field(
'ocean_model',
'dxCv', diag%axesCv1, &
3334 'Delta(x) at v points (meter)',
'm', interp_method=
'none')
3335 if (id > 0)
call post_data(id, g%dxCv, diag, .true.)
3337 id = register_static_field(
'ocean_model',
'dyCv', diag%axesCv1, &
3338 'Delta(y) at v points (meter)',
'm', interp_method=
'none')
3339 if (id > 0)
call post_data(id, g%dyCv, diag, .true.)
3354 type(verticalgrid_type),
intent(inout) :: GV
3355 type(param_file_type),
intent(in) :: param_file
3358 logical :: use_ice_shelf
3360 character(len=48) :: thickness_units, flux_units
3362 call get_param(param_file,
'',
"ICE_SHELF", use_ice_shelf, default=.false., do_not_log=.true.)
3364 thickness_units = get_thickness_units(gv)
3365 flux_units = get_flux_units(gv)
3367 if (cs%use_temperature)
then 3368 vd = var_desc(
"Temp",
"degC",
"Potential Temperature")
3369 call register_restart_field(cs%tv%T, vd, .true., cs%restart_CSp)
3371 vd = var_desc(
"Salt",
"PPT",
"Salinity")
3372 call register_restart_field(cs%tv%S, vd, .true., cs%restart_CSp)
3375 vd = var_desc(
"h",thickness_units,
"Layer Thickness")
3376 call register_restart_field(cs%h, vd, .true., cs%restart_CSp)
3378 vd = var_desc(
"u",
"meter second-1",
"Zonal velocity",
'u',
'L')
3379 call register_restart_field(cs%u, vd, .true., cs%restart_CSp)
3381 vd = var_desc(
"v",
"meter second-1",
"Meridional velocity",
'v',
'L')
3382 call register_restart_field(cs%v, vd, .true., cs%restart_CSp)
3384 if (cs%use_frazil)
then 3385 vd = var_desc(
"frazil",
"J m-2",
"Frazil heat flux into ocean",
'h',
'1')
3386 call register_restart_field(cs%tv%frazil, vd, .false., cs%restart_CSp)
3389 if (cs%interp_p_surf)
then 3390 vd = var_desc(
"p_surf_prev",
"Pa",
"Previous ocean surface pressure",
'h',
'1')
3391 call register_restart_field(cs%p_surf_prev, vd, .false., cs%restart_CSp)
3394 vd = var_desc(
"ave_ssh",
"meter",
"Time average sea surface height",
'h',
'1')
3395 call register_restart_field(cs%ave_ssh, vd, .false., cs%restart_CSp)
3398 if (use_ice_shelf .and.
associated(cs%Hml))
then 3399 vd = var_desc(
"hML",
"meter",
"Mixed layer thickness",
'h',
'1')
3400 call register_restart_field(cs%Hml, vd, .false., cs%restart_CSp)
3409 type(ocean_grid_type),
intent(in) :: G
3410 type(verticalgrid_type),
intent(in) :: GV
3411 real,
dimension(SZI_(G),SZJ_(G)),
intent(inout) :: ssh
3412 real,
dimension(:,:),
optional,
pointer :: p_atm
3417 integer :: i, j, is, ie, js, je
3419 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3420 if (
ASSOCIATED(p_atm))
then 3423 do j=js,je ;
do i=is,ie
3424 if ((
ASSOCIATED(cs%tv%eqn_of_state)) .and. (cs%calc_rho_for_sea_lev))
then 3425 call calculate_density(cs%tv%T(i,j,1), cs%tv%S(i,j,1), p_atm(i,j)/2.0, &
3426 rho_conv, cs%tv%eqn_of_state)
3430 igr0 = 1.0 / (rho_conv * gv%g_Earth)
3431 ssh(i,j) = ssh(i,j) + p_atm(i,j) * igr0
3441 type(ocean_grid_type),
intent(inout) :: G
3442 type(verticalgrid_type),
intent(inout) :: GV
3443 type(surface),
intent(inout) :: state
3444 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in) :: u
3445 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in) :: v
3446 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
3447 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: ssh
3451 real :: depth(szi_(g))
3458 integer :: i, j, k, is, ie, js, je, nz, numberOfErrors
3459 integer :: isd, ied, jsd, jed
3460 integer :: iscB, iecB, jscB, jecB, isdB, iedB, jsdB, jedB
3461 logical :: localError
3462 character(240) :: msg
3464 call calltree_enter(
"calculate_surface_state(), MOM.F90")
3465 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3466 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3467 iscb = g%iscB ; iecb = g%iecB; jscb = g%jscB ; jecb = g%jecB
3468 isdb = g%isdB ; iedb = g%iedB; jsdb = g%jsdB ; jedb = g%jedB
3470 if (.not.state%arrays_allocated)
then 3471 if (cs%use_temperature)
then 3472 allocate(state%SST(isd:ied,jsd:jed)) ; state%SST(:,:) = 0.0
3473 allocate(state%SSS(isd:ied,jsd:jed)) ; state%SSS(:,:) = 0.0
3475 allocate(state%sfc_density(isd:ied,jsd:jed)) ; state%sfc_density(:,:) = 0.0
3477 allocate(state%sea_lev(isd:ied,jsd:jed)) ; state%sea_lev(:,:) = 0.0
3478 allocate(state%Hml(isd:ied,jsd:jed)) ; state%Hml(:,:) = 0.0
3479 allocate(state%u(isdb:iedb,jsd:jed)) ; state%u(:,:) = 0.0
3480 allocate(state%v(isd:ied,jsdb:jedb)) ; state%v(:,:) = 0.0
3485 allocate(state%ocean_mass(isd:ied,jsd:jed)) ; state%ocean_mass(:,:) = 0.0
3486 if (cs%use_temperature)
then 3487 allocate(state%ocean_heat(isd:ied,jsd:jed)) ; state%ocean_heat(:,:) = 0.0
3488 allocate(state%ocean_salt(isd:ied,jsd:jed)) ; state%ocean_salt(:,:) = 0.0
3490 allocate(state%salt_deficit(isd:ied,jsd:jed)) ; state%salt_deficit(:,:) = 0.0
3492 state%arrays_allocated = .true.
3494 state%frazil => cs%tv%frazil
3495 state%TempxPmE => cs%tv%TempxPmE
3496 state%internal_heat => cs%tv%internal_heat
3497 if (
associated(cs%visc%taux_shelf)) state%taux_shelf => cs%visc%taux_shelf
3498 if (
associated(cs%visc%tauy_shelf)) state%tauy_shelf => cs%visc%tauy_shelf
3500 do j=js,je ;
do i=is,ie
3501 state%sea_lev(i,j) = ssh(i,j)
3504 if (cs%bulkmixedlayer)
then 3505 if (cs%use_temperature)
then ;
do j=js,je ;
do i=is,ie
3506 state%SST(i,j) = cs%tv%T(i,j,1)
3507 state%SSS(i,j) = cs%tv%S(i,j,1)
3508 enddo ;
enddo ;
endif 3509 do j=js,je ;
do i=iscb,iecb
3510 state%u(i,j) = u(i,j,1)
3512 do j=jscb,jecb ;
do i=is,ie
3513 state%v(i,j) = v(i,j,1)
3516 if (
associated(cs%Hml))
then ;
do j=js,je ;
do i=is,ie
3517 state%Hml(i,j) = cs%Hml(i,j)
3518 enddo ;
enddo ;
endif 3527 if (cs%use_temperature)
then 3528 state%SST(i,j) = 0.0 ; state%SSS(i,j) = 0.0
3530 state%sfc_density(i,j) = 0.0
3534 do k=1,nz ;
do i=is,ie
3535 if (depth(i) + h(i,j,k)*gv%H_to_m < depth_ml)
then 3536 dh = h(i,j,k)*gv%H_to_m
3537 elseif (depth(i) < depth_ml)
then 3538 dh = depth_ml - depth(i)
3542 if (cs%use_temperature)
then 3543 state%SST(i,j) = state%SST(i,j) + dh * cs%tv%T(i,j,k)
3544 state%SSS(i,j) = state%SSS(i,j) + dh * cs%tv%S(i,j,k)
3546 state%sfc_density(i,j) = state%sfc_density(i,j) + dh * gv%Rlay(k)
3548 depth(i) = depth(i) + dh
3552 if (depth(i) < gv%H_subroundoff*gv%H_to_m) &
3553 depth(i) = gv%H_subroundoff*gv%H_to_m
3554 if (cs%use_temperature)
then 3555 state%SST(i,j) = state%SST(i,j) / depth(i)
3556 state%SSS(i,j) = state%SSS(i,j) / depth(i)
3558 state%sfc_density(i,j) = state%sfc_density(i,j) / depth(i)
3560 state%Hml(i,j) = depth(i)
3565 if (cs%Hmix_UV>0.)
then 3566 depth_ml = cs%Hmix_UV
3573 do k=1,nz ;
do i=is,ie
3574 hv = 0.5 * (h(i,j,k) + h(i,j+1,k)) * gv%H_to_m
3575 if (depth(i) + hv < depth_ml)
then 3577 elseif (depth(i) < depth_ml)
then 3578 dh = depth_ml - depth(i)
3582 state%v(i,j) = state%v(i,j) + dh * v(i,j,k)
3583 depth(i) = depth(i) + dh
3587 if (depth(i) < gv%H_subroundoff*gv%H_to_m) &
3588 depth(i) = gv%H_subroundoff*gv%H_to_m
3589 state%v(i,j) = state%v(i,j) / depth(i)
3599 do k=1,nz ;
do i=iscb,iecb
3600 hu = 0.5 * (h(i,j,k) + h(i+1,j,k)) * gv%H_to_m
3601 if (depth(i) + hu < depth_ml)
then 3603 elseif (depth(i) < depth_ml)
then 3604 dh = depth_ml - depth(i)
3608 state%u(i,j) = state%u(i,j) + dh * u(i,j,k)
3609 depth(i) = depth(i) + dh
3613 if (depth(i) < gv%H_subroundoff*gv%H_to_m) &
3614 depth(i) = gv%H_subroundoff*gv%H_to_m
3615 state%u(i,j) = state%u(i,j) / depth(i)
3619 do j=js,je ;
do i=iscb,iecb
3620 state%u(i,j) = u(i,j,1)
3622 do j=jscb,jecb ;
do i=is,ie
3623 state%v(i,j) = v(i,j,1)
3628 if (
allocated(state%salt_deficit) .and.
associated(cs%tv%salt_deficit))
then 3630 do j=js,je ;
do i=is,ie
3632 state%salt_deficit(i,j) = 1000.0 * cs%tv%salt_deficit(i,j)
3636 if (
allocated(state%ocean_mass) .and.
allocated(state%ocean_heat) .and. &
3637 allocated(state%ocean_salt))
then 3639 do j=js,je ;
do i=is,ie
3640 state%ocean_mass(i,j) = 0.0
3641 state%ocean_heat(i,j) = 0.0 ; state%ocean_salt(i,j) = 0.0
3644 do j=js,je ;
do k=1,nz;
do i=is,ie
3645 mass = gv%H_to_kg_m2*h(i,j,k)
3646 state%ocean_mass(i,j) = state%ocean_mass(i,j) + mass
3647 state%ocean_heat(i,j) = state%ocean_heat(i,j) + mass*cs%tv%T(i,j,k)
3648 state%ocean_salt(i,j) = state%ocean_salt(i,j) + &
3649 mass * (1.0e-3*cs%tv%S(i,j,k))
3650 enddo ;
enddo ;
enddo 3652 if (
allocated(state%ocean_mass))
then 3654 do j=js,je ;
do i=is,ie ; state%ocean_mass(i,j) = 0.0 ;
enddo ;
enddo 3656 do j=js,je ;
do k=1,nz ;
do i=is,ie
3657 state%ocean_mass(i,j) = state%ocean_mass(i,j) + gv%H_to_kg_m2*h(i,j,k)
3658 enddo ;
enddo ;
enddo 3660 if (
allocated(state%ocean_heat))
then 3662 do j=js,je ;
do i=is,ie ; state%ocean_heat(i,j) = 0.0 ;
enddo ;
enddo 3664 do j=js,je ;
do k=1,nz ;
do i=is,ie
3665 mass = gv%H_to_kg_m2*h(i,j,k)
3666 state%ocean_heat(i,j) = state%ocean_heat(i,j) + mass*cs%tv%T(i,j,k)
3667 enddo ;
enddo ;
enddo 3669 if (
allocated(state%ocean_salt))
then 3671 do j=js,je ;
do i=is,ie ; state%ocean_salt(i,j) = 0.0 ;
enddo ;
enddo 3673 do j=js,je ;
do k=1,nz ;
do i=is,ie
3674 mass = gv%H_to_kg_m2*h(i,j,k)
3675 state%ocean_salt(i,j) = state%ocean_salt(i,j) + &
3676 mass * (1.0e-3*cs%tv%S(i,j,k))
3677 enddo ;
enddo ;
enddo 3681 if (
associated(cs%tracer_flow_CSp))
then 3682 if (.not.
associated(state%tr_fields))
allocate(state%tr_fields)
3683 call call_tracer_surface_state(state, h, g, cs%tracer_flow_CSp)
3686 if (cs%check_bad_surface_vals)
then 3688 do j=js,je;
do i=is,ie
3689 if (g%mask2dT(i,j)>0.)
then 3690 localerror = state%sea_lev(i,j)<=-g%bathyT(i,j) &
3691 .or. state%sea_lev(i,j)>= cs%bad_val_ssh_max &
3692 .or. state%sea_lev(i,j)<=-cs%bad_val_ssh_max &
3693 .or. state%sea_lev(i,j)+g%bathyT(i,j) < cs%bad_val_column_thickness
3694 if (cs%use_temperature) localerror = localerror &
3695 .or. state%SSS(i,j)<0. &
3696 .or. state%SSS(i,j)>=cs%bad_val_sss_max &
3697 .or. state%SST(i,j)< cs%bad_val_sst_min &
3698 .or. state%SST(i,j)>=cs%bad_val_sst_max
3699 if (localerror)
then 3700 numberoferrors=numberoferrors+1
3701 if (numberoferrors<9)
then 3702 if (cs%use_temperature)
then 3703 write(msg(1:240),
'(2(a,i4,x),2(a,f8.3,x),8(a,es11.4,x))') &
3704 'Extreme surface state detected: i=',i,
'j=',j, &
3705 'x=',g%geoLonT(i,j),
'y=',g%geoLatT(i,j), &
3706 'D=',g%bathyT(i,j), &
3707 'SSH=',state%sea_lev(i,j), &
3708 'SST=',state%SST(i,j), &
3709 'SSS=',state%SSS(i,j), &
3710 'U-=',state%u(i-1,j), &
3711 'U+=',state%u(i,j), &
3712 'V-=',state%v(i,j-1), &
3715 write(msg(1:240),
'(2(a,i4,x),2(a,f8.3,x),6(a,es11.4))') &
3716 'Extreme surface state detected: i=',i,
'j=',j, &
3717 'x=',g%geoLonT(i,j),
'y=',g%geoLatT(i,j), &
3718 'D=',g%bathyT(i,j), &
3719 'SSH=',state%sea_lev(i,j), &
3720 'U-=',state%u(i-1,j), &
3721 'U+=',state%u(i,j), &
3722 'V-=',state%v(i,j-1), &
3725 call mom_error(warning, trim(msg), all_print=.true.)
3726 elseif (numberoferrors==9)
then 3727 call mom_error(warning,
'There were more unreported extreme events!', all_print=.true.)
3732 call sum_across_pes(numberoferrors)
3733 if (numberoferrors>0)
then 3734 write(msg(1:240),
'(3(a,i9,x))')
'There were a total of ',numberoferrors, &
3735 'locations detected with extreme surface values!' 3736 call mom_error(fatal, trim(msg))
3740 call calltree_leave(
"calculate_surface_state()")
3748 if (cs%use_ALE_algorithm)
then 3749 call ale_end(cs%ALE_CSp)
3752 dealloc_(cs%u) ; dealloc_(cs%v) ; dealloc_(cs%h)
3753 dealloc_(cs%uh) ; dealloc_(cs%vh)
3755 if (cs%use_temperature)
then 3756 dealloc_(cs%T) ; cs%tv%T => null() ; dealloc_(cs%S) ; cs%tv%S => null()
3758 if (
associated(cs%tv%frazil))
deallocate(cs%tv%frazil)
3759 if (
associated(cs%tv%salt_deficit))
deallocate(cs%tv%salt_deficit)
3760 if (
associated(cs%Hml))
deallocate(cs%Hml)
3762 call tracer_advect_end(cs%tracer_adv_CSp)
3763 call tracer_hor_diff_end(cs%tracer_diff_CSp)
3764 call tracer_registry_end(cs%tracer_Reg)
3765 call tracer_flow_control_end(cs%tracer_flow_CSp)
3767 if(cs%offline_tracer_mode)
then 3768 call offline_transport_end(cs%offline_CSp)
3771 dealloc_(cs%uhtr) ; dealloc_(cs%vhtr)
3772 if (cs%split)
then ;
if (cs%legacy_split)
then 3773 call end_dyn_legacy_split(cs%dyn_legacy_split_CSp)
3775 call end_dyn_split_rk2(cs%dyn_split_RK2_CSp)
3776 endif ;
else ;
if (cs%use_RK2)
then 3777 call end_dyn_unsplit_rk2(cs%dyn_unsplit_RK2_CSp)
3779 call end_dyn_unsplit(cs%dyn_unsplit_CSp)
3781 dealloc_(cs%ave_ssh)
3782 if (
associated(cs%update_OBC_CSp))
call obc_register_end(cs%update_OBC_CSp)
3784 call verticalgridend(cs%GV)
3785 call mom_grid_end(cs%G)
subroutine, public mom_io_init(param_file)
Initialize the MOM_io module.
subroutine post_transport_diagnostics(G, GV, CS, diag, dt_trans, h, h_pre_dyn)
This routine posts diagnostics of the transports, including the subgridscale contributions.
subroutine, public step_mom_dyn_unsplit_rk2(u_in, v_in, h_in, tv, visc, Time_local, dt, fluxes, p_surf_begin, p_surf_end, uh, vh, uhtr, vhtr, eta_av, G, GV, CS, VarMix, MEKE)
subroutine, public register_diags_offline_transport(Time, diag, CS)
Initialize additional diagnostics required for offline tracer transport.
Control structure for mom_mixed_layer_restrat.
Module control structure.
The following structure contains pointers to various fields which may be used describe the surface st...
subroutine, public ale_writecoordinatefile(CS, GV, directory)
Write the vertical coordinate information into a file. This subroutine writes out a file containing a...
The routines here implement the offline tracer algorithm used in MOM6. These are called from step_off...
subroutine, public end_dyn_unsplit(CS)
subroutine, public mom_grid_init(G, param_file, HI, global_indexing, bathymetry_at_vel)
MOM_grid_init initializes the ocean grid array sizes and grid memory.
subroutine, public calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, fluxes, dt, G, GV, CS, eta_bt)
Diagnostics not more naturally calculated elsewhere are computed here.
subroutine, public mom_thermo_chksum(mesg, tv, G, haloshift)
subroutine, public coradcalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS)
Calculates the Coriolis and momentum advection contributions to the acceleration. ...
subroutine post_surface_diagnostics(CS, G, diag, state)
This routine posts diagnostics of various ocean surface quantities.
type(vardesc) function, public var_desc(name, units, longname, hor_grid, z_grid, t_grid, cmor_field_name, cmor_units, conversion, caller)
Returns a vardesc type whose elements have been filled with the provided fields. The argument name is...
subroutine, public initialize_dyn_split_rk2(u, v, h, uh, vh, eta, Time, G, GV, param_file, diag, CS, restart_CS, dt, Accel_diag, Cont_diag, MIS, VarMix, MEKE, OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, visc, dirs, ntrunc)
This subroutine initializes all of the variables that are used by this dynamic core, including diagnostics and the cpu clocks.
subroutine, public initialize_dyn_unsplit(u, v, h, Time, G, GV, param_file, diag, CS, restart_CS, Accel_diag, Cont_diag, MIS, OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, visc, dirs, ntrunc)
subroutine, public initialize_mom(Time, param_file, dirs, CS, Time_in, offline_tracer_mode)
This subroutine initializes MOM.
subroutine, public end_dyn_unsplit_rk2(CS)
This module contains the main regridding routines. Regridding comprises two steps: (1) Interpolation ...
subroutine post_diags_ts_vardec(G, CS, dt)
Calculate and post variance decay diagnostics for temp/salt.
subroutine, public step_mom_dyn_split_rk2(u, v, h, tv, visc, Time_local, dt, fluxes, p_surf_begin, p_surf_end, dt_since_flux, dt_therm, uh, vh, uhtr, vhtr, eta_av, G, GV, CS, calc_dtbt, VarMix, MEKE)
RK2 splitting for time stepping MOM adiabatic dynamics.
subroutine, public mom_diagnostics_init(MIS, ADp, CDp, Time, G, GV, param_file, diag, CS)
Provides a mechanism for recording diagnostic variables that are no longer valid, along with their re...
Methods for testing for, and list of, obsolete run-time parameters.
character(len=48) function, public get_flux_units(GV)
Returns the model's thickness flux units, usually m^3/s or kg/s.
This module implements boundary forcing for MOM6.
subroutine, public offline_diabatic_ale(fluxes, Time_start, Time_end, CS, h_pre, eatr, ebtr)
The vertical/diabatic driver for offline tracers. First the eatr/ebtr associated with the interpolate...
subroutine, public set_viscous_bbl(u, v, h, tv, visc, G, GV, CS)
The following subroutine calculates the thickness of the bottom boundary layer and the viscosity with...
subroutine, public step_mom_dyn_legacy_split(u, v, h, tv, visc, Time_local, dt, fluxes, p_surf_begin, p_surf_end, dt_since_flux, dt_therm, uh, vh, uhtr, vhtr, eta_av, G, GV, CS, calc_dtbt, VarMix, MEKE)
Control structure for this module.
subroutine, public set_visc_register_restarts(HI, GV, param_file, visc, restart_CS)
This subroutine is used to register any fields associated with the vertvisc_type. ...
integer id_clock_offline_tracer
subroutine, public register_restarts_dyn_unsplit_rk2(HI, GV, param_file, CS, restart_CS)
subroutine, public mom_initialize_coord(GV, PF, write_geom, output_dir, tv, max_depth)
MOM_initialize_coord sets up time-invariant quantities related to MOM6's vertical coordinate...
Initializes fixed aspects of the model, such as horizontal grid metrics, topography and Coriolis...
subroutine, public tracer_registry_init(param_file, Reg)
This routine include declares and sets the variable "version".
subroutine, public continuity_init(Time, G, GV, param_file, diag, CS)
Initializes continuity_cs.
subroutine, public mixedlayer_restrat(h, uhtr, vhtr, tv, fluxes, dt, MLD, VarMix, G, GV, CS)
Driver for the mixed-layer restratification parameterization. The code branches between two different...
integer, parameter, public to_all
subroutine, public hor_visc_init(Time, G, param_file, diag, CS)
This subroutine allocates space for and calculates static variables used by this module. The metrics may be 0, 1, or 2-D arrays, while fields like the background viscosities are 2-D arrays. ALLOC is a macro defined in MOM_memory.h to either allocate for dynamic memory, or do nothing when using static memory.
The module calculates interface heights, including free surface height.
Ocean grid type. See mom_grid for details.
integer id_clock_thick_diff
integer id_clock_mom_init
This is the main routine for MOM.
subroutine, public adiabatic_driver_init(Time, G, param_file, diag, CS, tracer_flow_CSp, diag_to_Z_CSp)
A simplified version of diabatic_driver_init that will allow tracer column functions to be called wit...
subroutine, public initialize_dyn_unsplit_rk2(u, v, h, Time, G, GV, param_file, diag, CS, restart_CS, Accel_diag, Cont_diag, MIS, OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, visc, dirs, ntrunc)
subroutine, public diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, G, GV, CS)
This subroutine imposes the diapycnal mass fluxes and the accompanying diapycnal advection of momentu...
Calculates density of sea water from T, S and P.
subroutine, public set_visc_init(Time, G, GV, param_file, diag, visc, CS, OBC)
Solve the layer continuity equation.
Controls where open boundary conditions are applied.
subroutine, public offline_advection_ale(fluxes, Time_start, time_interval, CS, id_clock_ale, h_pre, uhtr, vhtr, converged)
3D advection is done by doing flux-limited nonlinear horizontal advection interspersed with an ALE re...
integer id_clock_dynamics
subroutine, public tracer_flow_control_init(restart, day, G, GV, h, param_file, diag, OBC, CS, sponge_CSp, ALE_sponge_CSp, diag_to_Z_CSp, tv)
This subroutine calls all registered tracer initialization subroutines.
subroutine, public vertvisc_remnant(visc, visc_rem_u, visc_rem_v, dt, G, GV, CS)
Calculate the fraction of momentum originally in a layer that remains after a time-step of viscosity...
subroutine register_diags(Time, G, GV, CS, ADp)
Register the diagnostics.
Implements vertical viscosity (vertvisc)
Provides the ocean grid type.
real function, dimension(cs%nk+1), public ale_getcoordinate(CS)
Query the target coordinate interfaces positions.
subroutine, public do_group_pass(group, MOM_dom)
The vertvisc_type structure contains vertical viscosities, drag coefficients, and related fields...
subroutine, public register_restarts_dyn_split_rk2(HI, GV, param_file, CS, restart_CS, uh, vh)
This subroutine sets up any auxiliary restart variables that are specific to the unsplit time steppin...
logical function, public mixedlayer_restrat_init(Time, G, GV, param_file, diag, CS)
Initialize the mixed layer restratification module.
subroutine, public mom_forcing_chksum(mesg, fluxes, G, haloshift)
Write out chksums for basic state variables.
subroutine, public pressureforce_init(Time, G, GV, param_file, diag, CS, tides_CSp)
Initialize the pressure force control structure.
subroutine, public offline_fw_fluxes_into_ocean(G, GV, CS, fluxes, h, in_flux_optional)
Apply positive freshwater fluxes (into the ocean) and update netMassOut with only the negative (out o...
This routine drives the diabatic/dianeutral physics for MOM.
subroutine set_restart_fields(GV, param_file, CS)
Set the fields that are needed for bitwise identical restarting the time stepping scheme...
subroutine, public set_first_direction(G, y_first)
Main routine for lateral (along surface or neutral) diffusion of tracers.
Accelerations due to the Coriolis force and momentum advection.
subroutine, public call_tracer_register(HI, GV, param_file, CS, tr_Reg, restart_CS)
The following 5 subroutines and associated definitions provide the machinery to register and call the...
subroutine, public mom_initialize_state(u, v, h, tv, Time, G, GV, PF, dirs, restart_CS, ALE_CSp, tracer_Reg, sponge_CSp, ALE_sponge_CSp, OBC, Time_in)
subroutine, public post_offline_convergence_diags(CS, h_off, h_end, uhtr, vhtr)
Posts diagnostics related to offline convergence diagnostics.
integer id_clock_diabatic
subroutine, public ale_register_diags(Time, G, diag, C_p, Reg, CS)
Initialize diagnostics for the ALE module.
subroutine, public calltree_leave(mesg)
Writes a message about leaving a subroutine if call tree reporting is active.
A thin wrapper for Boussinesq/non-Boussinesq forms of the pressure force calculation.
subroutine post_ts_diagnostics(CS, G, GV, tv, diag, dt)
Post diagnostics of temperatures and salinities, their fluxes, and tendencies.
subroutine, public end_dyn_split_rk2(CS)
Close the dyn_split_RK2 module.
subroutine, public hor_index_init(Domain, HI, param_file, local_indexing, index_offset)
Sets various index values in a hor_index_type.
subroutine, public eos_init(param_file, EOS)
Initializes EOS_type by allocating and reading parameters.
subroutine, public register_restarts_dyn_legacy_split(HI, GV, param_file, CS, restart_CS, uh, vh)
This module contains I/O framework code.
subroutine, public offline_redistribute_residual(CS, h_pre, uhtr, vhtr, converged)
In the case where the main advection routine did not converge, something needs to be done with the re...
Defines the horizontal index type (hor_index_type) used for providing index ranges.
subroutine, public mom_accel_chksum(mesg, CAu, CAv, PFu, PFv, diffu, diffv, G, GV, pbce, u_accel_bt, v_accel_bt, symmetric)
integer id_clock_pass_init
subroutine unit_tests(verbosity)
Calls unit tests for other modules. Note that if a unit test returns true, a FATAL error is triggered...
The accel_diag_ptrs structure contains pointers to arrays with accelerations, which can later be used...
subroutine, public mom_diag_to_z_end(CS)
subroutine, public advect_tracer(h_end, uhtr, vhtr, OBC, dt, G, GV, CS, Reg, h_prev_opt, max_iter_in, x_first_in, uhr_out, vhr_out, h_out)
This routine time steps the tracer concentration using a monotonic, conservative, weakly diffusive sc...
Variable mixing coefficients.
This module contains the routines used to apply sponge layers when using the ALE mode. Applying sponges requires the following: (1) initialize_ALE_sponge (2) set_up_ALE_sponge_field (tracers) and set_up_ALE_sponge_vel_field (vel) (3) apply_ALE_sponge (4) init_ALE_sponge_diags (not being used for now) (5) ALE_sponge_end (not being used for now)
subroutine, public coriolisadv_init(Time, G, param_file, diag, AD, CS)
Initializes the control structure for coriolisadv_cs.
subroutine, public ale_updateverticalgridtype(CS, GV)
Update the vertical grid type with ALE information. This subroutine sets information in the verticalG...
SPONGE control structure.
character(len=48) function, public get_tr_flux_units(GV, tr_units, tr_vol_conc_units, tr_mass_conc_units)
Returns the model's tracer flux units.
Container for horizontal index ranges for data, computational and global domains. ...
Control structure for mom_coriolisadv.
subroutine, public varmix_init(Time, G, param_file, diag, CS)
Initializes the variables mixing coefficients container.
subroutine, public tracer_hor_diff_end(CS)
subroutine, public verticalgridinit(param_file, GV)
Allocates and initializes the model's vertical grid structure.
subroutine, public ale_end(CS)
End of regridding (memory deallocation). This routine is typically called (from MOM_end in file MOM...
subroutine adjust_ssh_for_p_atm(CS, G, GV, ssh, p_atm)
This subroutine applies a correction to the sea surface height to compensate for the atmospheric pres...
Variable mixing coefficients.
real function, public global_area_integral(var, G)
subroutine, public end_dyn_legacy_split(CS)
subroutine, public register_tracer(tr1, tr_desc, param_file, HI, GV, Reg, tr_desc_ptr, ad_x, ad_y, df_x, df_y, OBC_inflow, OBC_in_u, OBC_in_v, ad_2d_x, ad_2d_y, df_2d_x, df_2d_y, advection_xy)
This subroutine registers a tracer to be advected and laterally diffused.
subroutine, public find_obsolete_params(param_file)
Scans input parameter file for list obsolete parameters.
subroutine, public horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, CS, OBC)
This subroutine determines the acceleration due to the horizontal viscosity. A combination of biharmo...
subroutine, public verticalgridend(GV)
Deallocates the model's vertical grid structure.
subroutine, public offline_transport_end(CS)
Deallocates (if necessary) arrays within the offline control structure.
subroutine, public destroy_dyn_horgrid(G)
Release memory used by the dyn_horgrid_type and related structures.
Control structure that contains MEKE parameters and diagnostics handles.
subroutine, public mom_grid_end(G)
Release memory used by the ocean_grid_type and related structures.
subroutine, public copy_dyngrid_to_mom_grid(dG, oG)
Copies information from a dynamic (shared) horizontal grid type into an ocean_grid_type.
subroutine, public extract_offline_main(CS, uhtr, vhtr, eatr, ebtr, h_end, accumulated_time, dt_offline, dt_offline_vertical, skip_diffusion)
Extracts members of the offline main control structure. All arguments are optional except the control...
subroutine step_mom_thermo(CS, G, GV, u, v, h, tv, fluxes, dtdia)
MOM_step_thermo orchestrates the thermodynamic time stepping and vertical remapping, via calls to diabatic (or adiabatic) and ALE_main.
subroutine, public start_group_pass(group, MOM_dom)
logical function, public meke_init(Time, G, param_file, diag, CS, MEKE, restart_CS)
Initializes the MOM_MEKE module and reads parameters. Returns True if module is to be used...
subroutine, public calltree_waypoint(mesg, n)
Writes a message about reaching a milestone if call tree reporting is active.
This module contains the tracer_registry_type and the subroutines that handle registration of tracers...
subroutine, public adjustments_dyn_legacy_split(u, v, h, dt, G, GV, CS)
logical function, public ale_remap_init_conds(CS)
Returns true if initial conditions should be regridded and remapped.
integer id_clock_bbl_visc
Control structure for mom_continuity.
subroutine, public call_tracer_surface_state(state, h, G, CS)
This subroutine calls all registered tracer packages to enable them to add to the surface state retur...
character(len=20) function, public ale_getcoordinateunits(CS)
Query the target coordinate units.
subroutine, public tracer_advect_init(Time, G, param_file, diag, CS)
Initialize lateral tracer advection module.
subroutine, public register_restarts_dyn_unsplit(HI, GV, param_file, CS, restart_CS)
subroutine, public init_sponge_diags(Time, G, diag, CS)
subroutine, public calculate_z_diag_fields(u, v, h, ssh_in, frac_shelf_h, G, GV, CS)
This subroutine maps tracers and velocities into depth space for diagnostics.
Invokes unit tests in all modules that have them.
subroutine, public step_forward_meke(MEKE, h, SN_u, SN_v, visc, dt, G, GV, CS, hu, hv)
Integrates forward-in-time the MEKE eddy energy equation. See MEKE equations.
Type to carry basic OBC information needed for updating values.
subroutine, public calc_resoln_function(h, tv, G, GV, CS)
Calculates and stores the non-dimensional resolution functions.
Type to carry basic tracer information.
subroutine, public update_offline_fields(CS, h, fluxes, do_ale)
Update fields used in this round of offline transport. First fields are updated from files or from ar...
integer id_clock_ml_restrat
subroutine, public mom_domains_init(MOM_dom, param_file, symmetric, static_memory, NIHALO, NJHALO, NIGLOBAL, NJGLOBAL, NIPROC, NJPROC, min_halo, domain_name, include_name, param_suffix)
Thickness diffusion (or Gent McWilliams)
logical function, public is_root_pe()
subroutine, public complete_group_pass(group, MOM_dom)
The cont_diag_ptrs structure contains pointers to arrays with transports, which can later be used for...
subroutine, public tracer_flow_control_end(CS)
subroutine, public ale_offline_tracer_final(G, GV, h, tv, h_target, Reg, CS)
Remaps all tracers from h onto h_target. This is intended to be called when tracers are done offline...
subroutine, public pressureforce(h, tv, PFu, PFv, G, GV, CS, ALE_CSp, p_atm, pbce, eta)
A thin layer between the model and the Boussinesq and non-Boussinesq pressure force routines...
subroutine, public register_z_tracer(tr_ptr, name, long_name, units, Time, G, CS, standard_name, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name)
This subroutine registers a tracer to be output in depth space.
Control structure for this module.
subroutine, public diabatic_driver_end(CS)
Routine to close the diabatic driver module.
subroutine, public add_tracer_diagnostics(name, Reg, ad_x, ad_y, df_x, df_y, ad_2d_x, ad_2d_y, df_2d_x, df_2d_y, advection_xy)
This subroutine adds diagnostic arrays for a tracer that has previously been registered by a call to ...
subroutine, public mom_set_verbosity(verb)
subroutine, public adiabatic(h, tv, fluxes, dt, G, GV, CS)
Routine called for adiabatic physics.
character(len=48) function, public get_thickness_units(GV)
Returns the model's thickness units, usually m or kg/m^2.
subroutine, public tracer_advect_end(CS)
Close the tracer advection module.
The ocean_internal_state structure contains pointers to all of the prognostic variables allocated in ...
Implements the Mesoscale Eddy Kinetic Energy framework.
subroutine post_integrated_diagnostics(CS, G, GV, diag, dt_int, tv, fluxes)
This routine posts diagnostics of various integrated quantities.
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
subroutine, public vertvisc_init(MIS, Time, G, GV, param_file, diag, ADp, dirs, ntrunc, CS)
Initialise the vertical friction module.
subroutine, public set_viscous_ml(u, v, h, tv, fluxes, visc, dt, G, GV, CS)
The following subroutine calculates the thickness of the surface boundary layer for applying an eleva...
subroutine, public calc_slope_functions(h, tv, dt, G, GV, CS)
Calculates and stores functions of isopycnal slopes, e.g. Sx, Sy, S*N, mostly used in the Visbeck et ...
Provides subroutines for quantities specific to the equation of state.
subroutine write_static_fields(G, diag)
Offers the static fields in the ocean grid type for output via the diag_manager.
logical function, public calltree_showquery()
Returns True, if the verbosity>=6 indicating to show the call tree.
subroutine register_diags_ts_vardec(Time, HI, GV, param_file, CS)
Initialize diagnostics for the variance decay of temp/salt across regridding/remapping.
Type for describing a variable, typically a tracer.
subroutine, public tracer_registry_end(Reg)
This routine closes the tracer registry module.
Control structure for this module.
subroutine, public tracer_hordiff(h, dt, MEKE, VarMix, G, GV, CS, Reg, tv, do_online_flag, read_khdt_x, read_khdt_y)
Compute along-coordinate diffusion of all tracers using the diffusivity in CSKhTr, or using space-dependent diffusivity. Multiple iterations are used (if necessary) so that there is no limit on the acceptable time increment.
integer id_clock_diagnostics
integer function, public continuity_stencil(CS)
continuity_stencil returns the continuity solver stencil size
subroutine, public adjustgridforintegrity(CS, G, GV, h)
Crudely adjust (initial) grid for integrity. This routine is typically called (from initialize_MOM in...
integer id_clock_continuity
subroutine, public calculate_z_transport(uh_int, vh_int, h, dt, G, GV, CS)
This subroutine maps horizontal transport into depth space for diagnostic output. ...
subroutine mom_timing_init(CS)
This subroutine sets up clock IDs for timing various subroutines.
subroutine, public init_ale_sponge_diags(Time, G, diag, CS)
Initialize diagnostics for the ALE_sponge module.
subroutine, public lock_tracer_registry(Reg)
This subroutine locks the tracer registry to prevent the addition of more tracers. After locked=.true., can then register common diagnostics.
subroutine, public tidal_forcing_init(Time, G, param_file, CS)
This subroutine allocates space for the static variables used by this module. The metrics may be effe...
subroutine, public calculate_surface_state(state, u, v, h, ssh, G, GV, CS)
This subroutine sets the surface (return) properties of the ocean model by setting the appropriate fi...
subroutine, public continuity(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, visc_rem_u, visc_rem_v, u_cor, v_cor, uhbt_aux, vhbt_aux, u_cor_aux, v_cor_aux, BT_cont)
Time steps the layer thicknesses, using a monotonically limited, directionally split PPM scheme...
Initialize state variables, u, v, h, T and S.
Initializes fixed aspects of the related to its vertical coordinate.
subroutine, public tracer_hor_diff_init(Time, G, param_file, diag, CS, CSnd)
Initialize lateral tracer diffusion module.
subroutine register_diags_ts_tendency(Time, G, CS)
Initialize diagnostics for temp/heat and saln/salt tendencies.
subroutine, public mom_initialize_fixed(G, OBC, PF, write_geom, output_dir)
MOM_initialize_fixed sets up time-invariant quantities related to MOM6's horizontal grid...
subroutine, public step_offline(fluxes, state, Time_start, time_interval, CS)
step_offline is the main driver for running tracers offline in MOM6. This has been primarily develope...
subroutine, public save_restart(directory, time, G, CS, time_stamped, filename, GV)
subroutine, public vertvisc_limit_vel(u, v, h, ADp, CDp, fluxes, visc, dt, G, GV, CS)
Velocity components which exceed a threshold for physically reasonable values are truncated...
subroutine, public insert_offline_main(CS, ALE_CSp, diabatic_CSp, diag, OBC, tracer_adv_CSp, tracer_flow_CSp, tracer_Reg, tv, G, GV, x_before_y, debug)
Inserts (assigns values to) members of the offline main control structure. All arguments are optional...
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
subroutine, public copy_mom_grid_to_dyngrid(oG, dG)
Copies information from an ocean_grid_type into a dynamic (shared) horizontal grid type...
subroutine, public offline_advection_layer(fluxes, Time_start, time_interval, CS, h_pre, eatr, ebtr, uhtr, vhtr)
When in layer mode, 3D horizontal advection using stored mass fluxes must be used. Horizontal advection is done via tracer_advect, whereas the vertical component is actually handled by vertdiff in tracer_column_fns.
This program contains the subroutines that advect tracers along coordinate surfaces.
subroutine, public meke_alloc_register_restart(HI, param_file, MEKE, restart_CS)
Allocates memory and register restart fields for the MOM_MEKE module.
subroutine, public step_mom(fluxes, state, Time_start, time_interval, CS)
This subroutine orchestrates the time stepping of MOM. The adiabatic dynamics are stepped by calls to...
A column-wise toolbox for implementing neutral diffusion.
Control structure for thickness diffusion.
subroutine, public mom_debugging_init(param_file)
MOM_debugging_init initializes the MOM_debugging module, and sets the parameterts that control which ...
subroutine, public thickness_diffuse(h, uhtr, vhtr, tv, dt, G, GV, MEKE, VarMix, CDp, CS)
Calculates thickness diffusion coefficients and applies thickness diffusion to layer thicknesses...
subroutine, public ale_main_offline(G, GV, h, tv, Reg, CS, dt)
Takes care of (1) building a new grid and (2) remapping all variables between the old grid and the ne...
subroutine, public obc_register_end(CS)
Clean up the OBC registry.
subroutine, public ale_init(param_file, GV, max_depth, CS)
This routine is typically called (from initialize_MOM in file MOM.F90) before the main time integrati...
subroutine, public thickness_diffuse_init(Time, G, GV, param_file, diag, CDp, CS)
Initialize the thickness diffusion module/structure.
subroutine, public mom_diag_to_z_init(Time, G, GV, param_file, diag, CS)
Controls where open boundary conditions are applied.
subroutine, public register_obsolete_diagnostics(param_file, diag)
Scan through the diag_table searching for obsolete parameters and issue informational messages and op...
subroutine, public create_dyn_horgrid(G, HI, bathymetry_at_vel)
Allocate memory used by the dyn_horgrid_type and related structures.
subroutine, public step_mom_dyn_unsplit(u, v, h, tv, visc, Time_local, dt, fluxes, p_surf_begin, p_surf_end, uh, vh, uhtr, vhtr, eta_av, G, GV, CS, VarMix, MEKE)
subroutine, public mom_end(CS)
End of model.
subroutine, public mixedlayer_restrat_register_restarts(HI, param_file, CS, restart_CS)
Allocate and register fields in the mixed layer restratification structure for restarts.
subroutine, public ale_main(G, GV, h, u, v, tv, Reg, CS, dt, frac_shelf_h)
Takes care of (1) building a new grid and (2) remapping all variables between the old grid and the ne...
subroutine, public restart_init(param_file, CS, restart_root)
subroutine, public vertvisc(u, v, h, fluxes, visc, dt, OBC, ADp, CDp, G, GV, CS, taux_bot, tauy_bot)
Perform a fully implicit vertical diffusion of momentum. Stress top and bottom boundary conditions ar...
real function, public global_area_mean(var, G)
subroutine, public call_obc_register(param_file, CS, OBC)
The following subroutines and associated definitions provide the machinery to register and call the s...
subroutine, public initialize_dyn_legacy_split(u, v, h, uh, vh, eta, Time, G, GV, param_file, diag, CS, restart_CS, dt, Accel_diag, Cont_diag, MIS, VarMix, MEKE, OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, visc, dirs, ntrunc)
subroutine, public mom_error(level, message, all_print)
subroutine, public offline_transport_init(param_file, CS, diabatic_CSp, G, GV)
Initializes the control structure for offline transport and reads in some of the. ...
subroutine, public finish_mom_initialization(Time, dirs, CS, fluxes)
This subroutine finishes initializing MOM and writes out the initial conditions.
Time step the adiabatic dynamic core of MOM using RK2 method.
subroutine, public neutral_diffusion_diag_init(Time, G, diag, C_p, Reg, CS)
Diagnostic handles for neutral diffusion tendencies.
subroutine, public diabatic_driver_init(Time, G, GV, param_file, useALEalgorithm, diag, ADp, CDp, CS, tracer_flow_CSp, sponge_CSp, ALE_sponge_CSp, diag_to_Z_CSp)
This routine initializes the diabatic driver module.
Parameterization of mixed layer restratification by unresolved mixed-layer eddies.
subroutine, public offline_fw_fluxes_out_ocean(G, GV, CS, fluxes, h, out_flux_optional)
Apply negative freshwater fluxes (out of the ocean)
subroutine, public calltree_enter(mesg, n)
Writes a message about entering a subroutine if call tree reporting is active.