From 4acea916ffe8c0b53c420b4d8e793bb225f7b9a8 Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Wed, 28 Aug 2024 16:06:48 -0600 Subject: [PATCH 1/2] MARBL: convert salt_flux to tracer flux and add to STF This is done for DIC, ALK, and related tracers. This mimics uptake and release of these tracers by sea ice. --- src/tracer/MARBL_tracers.F90 | 95 +++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/src/tracer/MARBL_tracers.F90 b/src/tracer/MARBL_tracers.F90 index baf7931e51..93c6988130 100644 --- a/src/tracer/MARBL_tracers.F90 +++ b/src/tracer/MARBL_tracers.F90 @@ -82,6 +82,8 @@ module MARBL_tracers integer :: alk_alt_co2_ind !< ALK_ALT_CO2 index integer :: dic_ind !< DIC index integer :: dic_alt_co2_ind !< DIC_ALT_CO2 index + integer :: abio_dic_ind !< ABIO_DIC index + integer :: abio_di14c_ind !< ABIO_DI14C index end type tracer_ind_type !> MOM needs to store some information about saved_state; besides providing these @@ -183,6 +185,7 @@ module MARBL_tracers !! because we already copy data into CS%STF; latter requires copying data and indices !! so currently using temp_MARBL_diag for that. integer, allocatable :: id_surface_flux_out(:) !< register_diag indices for surface_flux output + integer, allocatable :: id_surface_flux_from_salt_flux(:) !< register_diag indices for surface_flux from salt_flux type(temp_MARBL_diag), allocatable :: interior_tendency_out(:) !< collect interior tendencies for diagnostic output type(temp_MARBL_diag), allocatable :: interior_tendency_out_zint(:) !< vertical integral of interior tendencies !! (full column) @@ -192,6 +195,9 @@ module MARBL_tracers integer, allocatable :: fracr_cat_id(:) !< register_diag index for per-category ice fraction integer, allocatable :: qsw_cat_id(:) !< register_diag index for per-category shortwave + real :: DIC_salt_ratio !< ratio to convert salt surface flux to DIC surface flux [conc ppt-1] + real :: ALK_salt_ratio !< ratio to convert salt surface flux to ALK surface flux [conc ppt-1] + real, allocatable :: STF(:,:,:) !< surface fluxes returned from MARBL to use in tracer_vertdiff !! (dims: i, j, tracer) [conc Z T-1 ~> conc m s-1] real, allocatable :: SFO(:,:,:) !< surface flux output returned from MARBL for use in GCM @@ -703,7 +709,14 @@ function register_MARBL_tracers(HI, GV, US, param_file, CS, tr_Reg, restart_CS, call log_param(param_file, mdl, "INPUTDIR/D14C_FILE", CS%d14c_dataset(m)%file_name) endif enddo -endif + endif + + call get_param(param_file, mdl, "DIC_SALT_RATIO", CS%DIC_salt_ratio, & + "Ratio to convert salt surface flux to DIC surface flux", units="conc ppt-1", & + default=64.0) + call get_param(param_file, mdl, "ALK_SALT_RATIO", CS%ALK_salt_ratio, & + "Ratio to convert salt surface flux to ALK surface flux", units="conc ppt-1", & + default=70.0) ! ** Tracer Restoring call get_param(param_file, mdl, "MARBL_TRACER_RESTORING_SOURCE", CS%restoring_source, & @@ -858,6 +871,7 @@ subroutine initialize_MARBL_tracers(restart, day, G, GV, US, h, param_file, diag ! Register per-tracer diagnostics computed from MARBL surface flux / interior tendency values allocate(CS%id_surface_flux_out(CS%ntr)) + allocate(CS%id_surface_flux_from_salt_flux(CS%ntr)) allocate(CS%interior_tendency_out(CS%ntr)) allocate(CS%interior_tendency_out_zint(CS%ntr)) allocate(CS%interior_tendency_out_zint_100m(CS%ntr)) @@ -869,6 +883,12 @@ subroutine initialize_MARBL_tracers(restart, day, G, GV, US, h, param_file, diag diag%axesT1, & ! T => tracer grid? 1 => no vertical grid day, trim(longname), trim(units), conversion=US%Z_to_m*US%s_to_T) + write(name, "(2A)") "STF_SALT_", trim(MARBL_instances%tracer_metadata(m)%short_name) + write(longname, "(2A)") trim(MARBL_instances%tracer_metadata(m)%long_name), " Surface Flux from Salt Flux" + CS%id_surface_flux_from_salt_flux(m) = register_diag_field("ocean_model", trim(name), & + diag%axesT1, & ! T => tracer grid? 1 => no vertical grid + day, trim(longname), trim(units), conversion=US%Z_to_m*US%s_to_T) + write(name, "(2A)") "J_", trim(MARBL_instances%tracer_metadata(m)%short_name) write(longname, "(2A)") trim(MARBL_instances%tracer_metadata(m)%long_name), " Source Sink Term" write(units, "(2A)") trim(MARBL_instances%tracer_metadata(m)%units), "/s" @@ -1239,6 +1259,10 @@ subroutine MARBL_tracers_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, ! Local variables character(len=256) :: log_message + real, dimension(SZI_(G),SZJ_(G)) :: net_salt_rate !< Surface salt flux into the ocean + !! [S H T-1 ~> ppt m s-1 or ppt kg m-2 s-1]. + real, dimension(SZI_(G),SZJ_(G)) :: flux_from_salt_flux !< Surface tracer flux from salt flux + !! [conc Z T-1 ~> conc m s-1]. real, dimension(SZI_(G),SZJ_(G)) :: ref_mask ! Mask for 2D MARBL diags using ref_depth real, dimension(SZI_(G),SZJ_(G)) :: riv_flux_loc ! Local copy of CS%RIV_FLUXES*dt real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified @@ -1368,6 +1392,69 @@ subroutine MARBL_tracers_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, enddo enddo + ! convert salt flux to tracer fluxes and add to STF + do j=js,je ; do i=is,ie + net_salt_rate(i,j) = (1000.0*US%ppt_to_S * fluxes%salt_flux(i,j)) * GV%RZ_to_H + enddo ; enddo + + ! DIC related tracers + do j=js,je ; do i=is,ie + flux_from_salt_flux(i,j) = (CS%DIC_salt_ratio * GV%H_to_Z) * net_salt_rate(i,j) + enddo ; enddo + m = CS%tracer_inds%dic_ind + if (m > 0) then + do j=js,je ; do i=is,ie + CS%STF(i,j,m) = CS%STF(i,j,m) + flux_from_salt_flux(i,j) + enddo ; enddo + if (CS%id_surface_flux_from_salt_flux(m) > 0) & + call post_data(CS%id_surface_flux_from_salt_flux(m), flux_from_salt_flux, CS%diag) + endif + m = CS%tracer_inds%dic_alt_co2_ind + if (m > 0) then + do j=js,je ; do i=is,ie + CS%STF(i,j,m) = CS%STF(i,j,m) + flux_from_salt_flux(i,j) + enddo ; enddo + if (CS%id_surface_flux_from_salt_flux(m) > 0) & + call post_data(CS%id_surface_flux_from_salt_flux(m), flux_from_salt_flux, CS%diag) + endif + m = CS%tracer_inds%abio_dic_ind + if (m > 0) then + do j=js,je ; do i=is,ie + CS%STF(i,j,m) = CS%STF(i,j,m) + flux_from_salt_flux(i,j) + enddo ; enddo + if (CS%id_surface_flux_from_salt_flux(m) > 0) & + call post_data(CS%id_surface_flux_from_salt_flux(m), flux_from_salt_flux, CS%diag) + endif + m = CS%tracer_inds%abio_di14c_ind + if (m > 0) then + do j=js,je ; do i=is,ie + CS%STF(i,j,m) = CS%STF(i,j,m) + flux_from_salt_flux(i,j) + enddo ; enddo + if (CS%id_surface_flux_from_salt_flux(m) > 0) & + call post_data(CS%id_surface_flux_from_salt_flux(m), flux_from_salt_flux, CS%diag) + endif + + ! ALK related tracers + do j=js,je ; do i=is,ie + flux_from_salt_flux(i,j) = (CS%ALK_salt_ratio * GV%H_to_Z) * net_salt_rate(i,j) + enddo ; enddo + m = CS%tracer_inds%alk_ind + if (m > 0) then + do j=js,je ; do i=is,ie + CS%STF(i,j,m) = CS%STF(i,j,m) + flux_from_salt_flux(i,j) + enddo ; enddo + if (CS%id_surface_flux_from_salt_flux(m) > 0) & + call post_data(CS%id_surface_flux_from_salt_flux(m), flux_from_salt_flux, CS%diag) + endif + m = CS%tracer_inds%alk_alt_co2_ind + if (m > 0) then + do j=js,je ; do i=is,ie + CS%STF(i,j,m) = CS%STF(i,j,m) + flux_from_salt_flux(i,j) + enddo ; enddo + if (CS%id_surface_flux_from_salt_flux(m) > 0) & + call post_data(CS%id_surface_flux_from_salt_flux(m), flux_from_salt_flux, CS%diag) + endif + if (CS%debug) then do m=1,CS%ntr call hchksum(CS%STF(:,:,m), & @@ -2061,6 +2148,8 @@ subroutine set_riv_flux_tracer_inds(CS) CS%tracer_inds%alk_alt_co2_ind = 0 CS%tracer_inds%dic_ind = 0 CS%tracer_inds%dic_alt_co2_ind = 0 + CS%tracer_inds%abio_dic_ind = 0 + CS%tracer_inds%abio_di14c_ind = 0 do m=1,CS%ntr name = MARBL_instances%tracer_metadata(m)%short_name if (trim(name) == "NO3") then @@ -2091,6 +2180,10 @@ subroutine set_riv_flux_tracer_inds(CS) CS%tracer_inds%dic_ind = m elseif (trim(name) == "DIC_ALT_CO2") then CS%tracer_inds%dic_alt_co2_ind = m + elseif (trim(name) == "ABIO_DIC") then + CS%tracer_inds%abio_dic_ind = m + elseif (trim(name) == "ABIO_DI14C") then + CS%tracer_inds%abio_di14c_ind = m endif enddo From f8f76f2940dd52fcd80d006d68693d26e1e35286 Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Fri, 30 Aug 2024 15:35:47 -0600 Subject: [PATCH 2/2] remove doxygen formatting on local variables correct some indentation issues --- src/tracer/MARBL_tracers.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MARBL_tracers.F90 b/src/tracer/MARBL_tracers.F90 index 93c6988130..0896917f2c 100644 --- a/src/tracer/MARBL_tracers.F90 +++ b/src/tracer/MARBL_tracers.F90 @@ -1257,12 +1257,12 @@ subroutine MARBL_tracers_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which !! fluxes can be applied [m] -! Local variables + ! Local variables character(len=256) :: log_message - real, dimension(SZI_(G),SZJ_(G)) :: net_salt_rate !< Surface salt flux into the ocean - !! [S H T-1 ~> ppt m s-1 or ppt kg m-2 s-1]. - real, dimension(SZI_(G),SZJ_(G)) :: flux_from_salt_flux !< Surface tracer flux from salt flux - !! [conc Z T-1 ~> conc m s-1]. + real, dimension(SZI_(G),SZJ_(G)) :: net_salt_rate ! Surface salt flux into the ocean + ! [S H T-1 ~> ppt m s-1 or ppt kg m-2 s-1]. + real, dimension(SZI_(G),SZJ_(G)) :: flux_from_salt_flux ! Surface tracer flux from salt flux + ! [conc Z T-1 ~> conc m s-1]. real, dimension(SZI_(G),SZJ_(G)) :: ref_mask ! Mask for 2D MARBL diags using ref_depth real, dimension(SZI_(G),SZJ_(G)) :: riv_flux_loc ! Local copy of CS%RIV_FLUXES*dt real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified @@ -2010,7 +2010,7 @@ function MARBL_tracers_stock(h, stocks, G, GV, CS, names, units, stock_index) integer :: MARBL_tracers_stock !< Return value: the number of stocks !! calculated here. -! Local variables + ! Local variables integer :: i, j, k, is, ie, js, je, nz, m is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke