diff --git a/examples/ocean_SIS/GOLD_SIS/available_diags.000000 b/examples/ocean_SIS/GOLD_SIS/available_diags.000000 index 9b9a4aea8a..6df9651bfb 100644 --- a/examples/ocean_SIS/GOLD_SIS/available_diags.000000 +++ b/examples/ocean_SIS/GOLD_SIS/available_diags.000000 @@ -316,6 +316,12 @@ "ocean_model", "MLv_restrat_time" [Unused] ! long_name: Mixed Layer Meridional Restratification Timescale ! units: second +"ocean_model", "temp_global" [Unused] + ! long_name: Global Volume Mean Ocean Temperature + ! units: Celsius +"ocean_model", "salt_global" [Unused] + ! long_name: Global Volume Mean Ocean Salinity + ! units: PSU "ocean_model", "e" [Used] ! long_name: Interface Height Relative to Mean Sea Level ! units: meter diff --git a/examples/ocean_SIS/MOM6z_SIS_025/available_diags.000000 b/examples/ocean_SIS/MOM6z_SIS_025/available_diags.000000 index 45b8b602ba..5d46861bc1 100644 --- a/examples/ocean_SIS/MOM6z_SIS_025/available_diags.000000 +++ b/examples/ocean_SIS/MOM6z_SIS_025/available_diags.000000 @@ -292,6 +292,12 @@ "ocean_model", "neutral_slope_y" [Unused] ! long_name: Meridional slope of neutral surface ! units: nondim +"ocean_model", "temp_global" [Unused] + ! long_name: Global Volume Mean Ocean Temperature + ! units: Celsius +"ocean_model", "salt_global" [Unused] + ! long_name: Global Volume Mean Ocean Salinity + ! units: PSU "ocean_model", "e" [Unused] ! long_name: Interface Height Relative to Mean Sea Level ! units: meter diff --git a/examples/ocean_SIS/OM4_025/available_diags.000000 b/examples/ocean_SIS/OM4_025/available_diags.000000 index 45b8b602ba..5d46861bc1 100644 --- a/examples/ocean_SIS/OM4_025/available_diags.000000 +++ b/examples/ocean_SIS/OM4_025/available_diags.000000 @@ -292,6 +292,12 @@ "ocean_model", "neutral_slope_y" [Unused] ! long_name: Meridional slope of neutral surface ! units: nondim +"ocean_model", "temp_global" [Unused] + ! long_name: Global Volume Mean Ocean Temperature + ! units: Celsius +"ocean_model", "salt_global" [Unused] + ! long_name: Global Volume Mean Ocean Salinity + ! units: PSU "ocean_model", "e" [Unused] ! long_name: Interface Height Relative to Mean Sea Level ! units: meter diff --git a/examples/ocean_SIS/OM4_025/diag_table.MOM6 b/examples/ocean_SIS/OM4_025/diag_table.MOM6 index 32893c3360..f9fc47adea 100644 --- a/examples/ocean_SIS/OM4_025/diag_table.MOM6 +++ b/examples/ocean_SIS/OM4_025/diag_table.MOM6 @@ -2,6 +2,8 @@ "ocean_daily", 1, "days", 1, "days", "time" "ocean_month", 1, "months", 1, "days", "time" "ocean_annual", 12, "months", 1, "days", "time" +"ocean_scalar_month", 1, "months", 1, "days", "time" +"ocean_scalar_annual", 12, "months", 1, "days", "time" "ocean_static", -1, "months", 1, "days", "time" "ocean_month_z", 1, "months", 1, "days", "time" "ocean_Drake_passage", 1, "days", 1, "days", "time" @@ -49,6 +51,12 @@ "ocean_model", "p_surf", "p_surf", "ocean_month", "all", "mean", "none",2 "ocean_model", "salt_flux", "salt_flux", "ocean_month", "all", "mean", "none",2 +# Monthly scalars + "ocean_model", "SST_global", "SST_global", "ocean_scalar_month", "all", "mean", "none",2 + "ocean_model", "SSS_global", "SSS_global", "ocean_scalar_month", "all", "mean", "none",2 + "ocean_model", "temp_global", "temp_global", "ocean_scalar_month", "all", "mean", "none",2 + "ocean_model", "salt_global", "salt_global", "ocean_scalar_month", "all", "mean", "none",2 + # Annual averages "ocean_model", "e", "e", "ocean_annual", "all", "mean", "none",2 "ocean_model", "h", "h", "ocean_annual", "all", "mean", "none",2 @@ -80,6 +88,12 @@ "ocean_model", "age", "age", "ocean_annual", "all", "mean", "none",2 #"ocean_model", "vintage", "vintage", "ocean_annual", "all", "mean", "none",2 +# Annual scalars + "ocean_model", "SST_global", "SST_global", "ocean_scalar_annual", "all", "mean", "none",2 + "ocean_model", "SSS_global", "SSS_global", "ocean_scalar_annual", "all", "mean", "none",2 + "ocean_model", "temp_global", "temp_global", "ocean_scalar_annual", "all", "mean", "none",2 + "ocean_model", "salt_global", "salt_global", "ocean_scalar_annual", "all", "mean", "none",2 + # Z diagnostics "ocean_model", "temp_z", "temp", "ocean_month_z", "all", "mean", "none",2 "ocean_model", "salt_z", "salt", "ocean_month_z", "all", "mean", "none",2 diff --git a/examples/solo_ocean/global/available_diags.000000 b/examples/solo_ocean/global/available_diags.000000 index c4e52ed064..08288b6268 100644 --- a/examples/solo_ocean/global/available_diags.000000 +++ b/examples/solo_ocean/global/available_diags.000000 @@ -313,6 +313,12 @@ "ocean_model", "MLv_restrat_time" [Unused] ! long_name: Mixed Layer Meridional Restratification Timescale ! units: second +"ocean_model", "temp_global" [Unused] + ! long_name: Global Volume Mean Ocean Temperature + ! units: Celsius +"ocean_model", "salt_global" [Unused] + ! long_name: Global Volume Mean Ocean Salinity + ! units: PSU "ocean_model", "e" [Used] ! long_name: Interface Height Relative to Mean Sea Level ! units: meter diff --git a/examples/solo_ocean/global_ALE/common/diag_table b/examples/solo_ocean/global_ALE/common/diag_table index 57496146ab..2899980092 100644 --- a/examples/solo_ocean/global_ALE/common/diag_table +++ b/examples/solo_ocean/global_ALE/common/diag_table @@ -1,5 +1,6 @@ "GOLD Experiment" 1 1 1 0 0 0 +"scalar", 1,"days",1,"days","Time", "prog", 1,"days",1,"days","Time", "prog_z", 1,"days",1,"days","Time", "ave_prog", 1,"days",1,"days","Time", @@ -15,6 +16,13 @@ #This is the field section of the diag_table. +# Scalar Diagnostics: +#==================== +"ocean_model","SST_global","SST_global","scalar","all",.false.,"none",2 +"ocean_model","SSS_global","SSS_global","scalar","all",.false.,"none",2 +"ocean_model","temp_global","temp_global","scalar","all",.false.,"none",2 +"ocean_model","salt_global","salt_global","scalar","all",.false.,"none",2 + # Prognostic Ocean fields: #========================= diff --git a/examples/solo_ocean/global_ALE/layer/available_diags.000000 b/examples/solo_ocean/global_ALE/layer/available_diags.000000 index c8058e5b4f..2bbdc087c4 100644 --- a/examples/solo_ocean/global_ALE/layer/available_diags.000000 +++ b/examples/solo_ocean/global_ALE/layer/available_diags.000000 @@ -313,6 +313,12 @@ "ocean_model", "MLv_restrat_time" [Unused] ! long_name: Mixed Layer Meridional Restratification Timescale ! units: second +"ocean_model", "temp_global" [Used] + ! long_name: Global Volume Mean Ocean Temperature + ! units: Celsius +"ocean_model", "salt_global" [Used] + ! long_name: Global Volume Mean Ocean Salinity + ! units: PSU "ocean_model", "e" [Used] ! long_name: Interface Height Relative to Mean Sea Level ! units: meter @@ -643,7 +649,7 @@ "ocean_model", "SST" [Used] ! long_name: Sea Surface Temperature ! units: Celsius -"ocean_model", "SST_global" [Unused] +"ocean_model", "SST_global" [Used] ! long_name: Global Average Sea Surface Temperature ! units: Celsius "ocean_model", "SST_sq" [Unused] @@ -652,7 +658,7 @@ "ocean_model", "SSS" [Used] ! long_name: Sea Surface Salinity ! units: PSU -"ocean_model", "SSS_global" [Unused] +"ocean_model", "SSS_global" [Used] ! long_name: Global Average Sea Surface Salinity ! units: PSU "ocean_model", "frazil" [Unused] diff --git a/examples/solo_ocean/global_ALE/z/available_diags.000000 b/examples/solo_ocean/global_ALE/z/available_diags.000000 index b90f4c308a..d264388765 100644 --- a/examples/solo_ocean/global_ALE/z/available_diags.000000 +++ b/examples/solo_ocean/global_ALE/z/available_diags.000000 @@ -301,6 +301,12 @@ "ocean_model", "neutral_slope_y" [Unused] ! long_name: Meridional slope of neutral surface ! units: nondim +"ocean_model", "temp_global" [Used] + ! long_name: Global Volume Mean Ocean Temperature + ! units: Celsius +"ocean_model", "salt_global" [Used] + ! long_name: Global Volume Mean Ocean Salinity + ! units: PSU "ocean_model", "e" [Used] ! long_name: Interface Height Relative to Mean Sea Level ! units: meter @@ -661,7 +667,7 @@ "ocean_model", "SST" [Used] ! long_name: Sea Surface Temperature ! units: Celsius -"ocean_model", "SST_global" [Unused] +"ocean_model", "SST_global" [Used] ! long_name: Global Average Sea Surface Temperature ! units: Celsius "ocean_model", "SST_sq" [Unused] @@ -670,7 +676,7 @@ "ocean_model", "SSS" [Used] ! long_name: Sea Surface Salinity ! units: PSU -"ocean_model", "SSS_global" [Unused] +"ocean_model", "SSS_global" [Used] ! long_name: Global Average Sea Surface Salinity ! units: PSU "ocean_model", "frazil" [Unused] diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index a4e8f32636..4568a484db 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_area_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_area_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_area_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..eb77d0f244 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_area_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..fc3fe2143f 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_area_mean, global_volume_mean contains +function global_area_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_area_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_area_mean = reproducing_sum( tmpForSumming ) * G%IareaT_global + +end function global_area_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(sum(tmpForSumming,3))) / (reproducing_sum(sum(weight,3))) + +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