diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index a4e8f32636..c519ae0d10 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -392,6 +392,7 @@ module MOM use MOM_set_visc, only : set_viscous_BBL, set_viscous_ML, set_visc_init use MOM_set_visc, only : set_visc_register_restarts, set_visc_CS use MOM_sponge, only : init_sponge_diags, sponge_CS +use MOM_spatial_means, only : global_ij_mean, global_volume_mean use MOM_checksum_packages, only : MOM_thermo_chksum, MOM_state_chksum, MOM_accel_chksum use MOM_dynamics_unsplit, only : step_MOM_dyn_unsplit, register_restarts_dyn_unsplit use MOM_dynamics_unsplit, only : initialize_dyn_unsplit, end_dyn_unsplit @@ -649,13 +650,11 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) h ! h : Layer thickness, in m. real, dimension(SZI_(CS%G),SZJ_(CS%G),SZK_(CS%G)+1) :: eta_predia real :: tot_wt_ssh, Itot_wt_ssh, I_time_int - real, dimension(SZI_(CS%G),SZJ_(CS%G)) :: tmpForSumming real :: SST_global, SSS_global type(time_type) :: Time_local integer :: pid_tau, pid_ustar, pid_psurf, pid_u, pid_h integer :: pid_T, pid_S logical :: showCallTree - real :: temporary G => CS%G is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke @@ -1322,23 +1321,17 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) endif if (CS%id_sst_global > 0) then - tmpForSumming(:,:) = 0. - do j=js,je ; do i=is, ie - tmpForSumming(i,j) = ( state%SST(i,j) * (G%areaT(i,j) * G%mask2dT(i,j)) ) - enddo ; enddo - SST_global = reproducing_sum( tmpForSumming ) * G%IareaT_global + SST_global = global_ij_mean(state%SST, G) call post_data(CS%id_sst_global, SST_global, CS%diag) endif if (CS%id_sss_global > 0) then - tmpForSumming(:,:) = 0. - do j=js,je ; do i=is, ie - tmpForSumming(i,j) = ( state%SSS(i,j) * (G%areaT(i,j) * G%mask2dT(i,j)) ) - enddo ; enddo - SSS_global = reproducing_sum( tmpForSumming ) * G%IareaT_global + SSS_global = global_ij_mean(state%SSS, G) call post_data(CS%id_sss_global, SSS_global, CS%diag) endif + + if (CS%id_sss > 0) & call post_data(CS%id_sss, state%SSS, CS%diag, mask=G%mask2dT) if (CS%id_ssu > 0) & diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index cbec1e55f6..664ee0f4f0 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -45,12 +45,13 @@ module MOM_diagnostics !********+*********+*********+*********+*********+*********+*********+** use MOM_diag_mediator, only : post_data, register_diag_field, safe_alloc_ptr -use MOM_diag_mediator, only : diag_ctrl, time_type +use MOM_diag_mediator, only : diag_ctrl, time_type, register_scalar_field use MOM_domains, only : pass_vector, To_North, To_East use MOM_error_handler, only : MOM_error, FATAL, WARNING use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_grid, only : ocean_grid_type use MOM_interface_heights, only : find_eta +use MOM_spatial_means, only : global_volume_mean, global_ij_mean use MOM_variables, only : thermo_var_ptrs, ocean_internal_state, p3d use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs use MOM_wave_speed, only : wave_speed, wave_speed_init, wave_speed_CS @@ -116,6 +117,7 @@ module MOM_diagnostics integer :: id_cg1 = -1, id_Rd1 = -1, id_cfl_cg1 = -1, id_cfl_cg1_x = -1, id_cfl_cg1_y = -1 integer :: id_mass_wt = -1, id_temp_int = -1, id_salt_int = -1 integer :: id_col_ht = -1, id_col_mass = -1 + integer :: id_temp_global = -1, id_salt_global = -1 type(wave_speed_CS), pointer :: wave_speed_CSp => NULL() ! The following pointers are used the calculation of time derivatives. @@ -177,6 +179,7 @@ subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, dt, G, & ! squared that is used to avoid division by 0, in s-2. This ! value is roughly (pi / (the age of the universe) )^2. integer :: k_list + real :: temp_global, salt_global is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB nz = G%ke ; nkmb = G%nk_rho_varies @@ -213,7 +216,17 @@ subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, dt, G, & if (CS%id_e_D > 0) call post_data(CS%id_e_D, CS%e_D, CS%diag) endif - + + if (CS%id_temp_global>0) then + temp_global = global_volume_mean(tv%T, h, G) + call post_data(CS%id_temp_global, temp_global, CS%diag) + endif + + if (CS%id_salt_global>0) then + salt_global = global_volume_mean(tv%S, h, G) + call post_data(CS%id_salt_global, salt_global, CS%diag) + endif + call calculate_vertical_integrals(h, tv, G, CS) if ((CS%id_Rml > 0) .or. (CS%id_Rcv > 0) .or. ASSOCIATED(CS%h_Rlay) .or. & @@ -845,6 +858,12 @@ subroutine MOM_diagnostics_init(MIS, ADp, CDp, Time, G, param_file, diag, CS) thickness_units = "kilogram meter-2" ; flux_units = "kilogram second-1" endif + CS%id_temp_global = register_scalar_field('ocean_model', 'temp_global', & + Time, diag, 'Global Volume Mean Ocean Temperature', 'Celsius') + + CS%id_salt_global = register_scalar_field('ocean_model', 'salt_global', & + Time, diag, 'Global Volume Mean Ocean Salinity', 'PSU') + CS%id_e = register_diag_field('ocean_model', 'e', diag%axesTi, Time, & 'Interface Height Relative to Mean Sea Level', 'meter') if (CS%id_e>0) call safe_alloc_ptr(CS%e,isd,ied,jsd,jed,nz+1) diff --git a/src/framework/MOM_spatial_means.F90 b/src/framework/MOM_spatial_means.F90 index e2d79c5a92..1b540a510e 100644 --- a/src/framework/MOM_spatial_means.F90 +++ b/src/framework/MOM_spatial_means.F90 @@ -22,6 +22,7 @@ module MOM_spatial_means use MOM_coms, only : EFP_type, operator(+), operator(-), assignment(=) use MOM_coms, only : EFP_to_real, real_to_EFP, EFP_list_sum_across_PEs +use MOM_coms, only : reproducing_sum use MOM_coms, only : query_EFP_overflow_error, reset_EFP_overflow_error use MOM_error_handler, only : MOM_error, NOTE, WARNING, FATAL, is_root_pe use MOM_file_parser, only : get_param, log_version, param_file_type @@ -31,10 +32,46 @@ module MOM_spatial_means #include -public :: global_i_mean, global_j_mean +public :: global_i_mean, global_j_mean, global_ij_mean, global_volume_mean contains +function global_ij_mean(var,G) + type(ocean_grid_type), intent(in) :: G + real, dimension(SZI_(G), SZJ_(G)), intent(in) :: var + real, dimension(SZI_(G), SZJ_(G)) :: tmpForSumming + integer :: i, j, is, ie, js, je + real :: global_ij_mean + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + + tmpForSumming(:,:) = 0. + do j=js,je ; do i=is, ie + tmpForSumming(i,j) = ( var(i,j) * (G%areaT(i,j) * G%mask2dT(i,j)) ) + enddo ; enddo + global_ij_mean = reproducing_sum( tmpForSumming ) * G%IareaT_global + +end function global_ij_mean + +function global_volume_mean(var,h,G) + type(ocean_grid_type), intent(in) :: G + real, dimension(SZI_(G), SZJ_(G), SZK_(G)), intent(in) :: var + real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h + real, dimension(SZI_(G), SZJ_(G), SZK_(G)) :: tmpForSumming, weight + integer :: i, j, k, is, ie, js, je, nz + real :: global_volume_mean + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke + + tmpForSumming(:,:,:) = 0. ; weight(:,:,:) = 0. + + do k=1, nz ; do j=js,je ; do i=is, ie + weight(i,j,k) = h(i,j,k) * (G%areaT(i,j) * G%mask2dT(i,j)) + tmpForSumming(i,j,k) = var(i,j,k) * weight(i,j,k) + enddo ; enddo ; enddo + global_volume_mean = reproducing_sum(tmpForSumming) / reproducing_sum(weight) + +end function global_volume_mean + + subroutine global_i_mean(array, i_mean, G, mask) real, dimension(NIMEM_,NJMEM_), intent(in) :: array real, dimension(NJMEM_), intent(out) :: i_mean