From 87f5104efd92d3a21b6c3e26cd10570c15913b09 Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Fri, 14 Aug 2020 18:24:09 -0400 Subject: [PATCH 1/9] Prepare for OBC segment queries - This update adds support for MOM6 OBC segment initialization for generic tracers. It adds obc_src_file_name and obc_src_field_name properties for generic tracers and sets their default to 'obgc_obc.nc' and the tracer name respectively. - Add a tracer called gtr1 to generic_CFC for testing, to be removed later --- generic_tracers/generic_CFC.F90 | 9 ++++++++- generic_tracers/generic_tracer_utils.F90 | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/generic_tracers/generic_CFC.F90 b/generic_tracers/generic_CFC.F90 index 5519b4f..a4e8049 100644 --- a/generic_tracers/generic_CFC.F90 +++ b/generic_tracers/generic_CFC.F90 @@ -390,7 +390,14 @@ subroutine user_add_tracers(tracer_list) standard_name = "mole_concentration_of_cfc11_in_sea_water", & diag_field_units = 'mol m-3', & diag_field_scaling_factor = 1035.0) ! rho = 1035.0 kg/m3, converts mol/kg to mol/m3 - + !fake passive tracer + call g_tracer_add(tracer_list,package_name, & + name = 'gtr1', & + longname = 'fake passive tracer', & + units = 'NA', & + prog = .true., & + requires_src_info = .false., & + flux_gas = .false.) end subroutine user_add_tracers diff --git a/generic_tracers/generic_tracer_utils.F90 b/generic_tracers/generic_tracer_utils.F90 index b1ec8a1..228cda9 100644 --- a/generic_tracers/generic_tracer_utils.F90 +++ b/generic_tracers/generic_tracer_utils.F90 @@ -267,6 +267,7 @@ module g_tracer_utils logical :: requires_restart = .true. ! Tracer source: filename, type, var name, units, record, gridfile character(len=fm_string_len) :: src_file, src_var_name, src_var_unit, src_var_gridspec + character(len=fm_string_len) :: obc_src_file_name,obc_src_field_name integer :: src_var_record logical :: requires_src_info = .false. real :: src_var_unit_conversion = 1.0 !This factor depends on the tracer. Ask Jasmin @@ -372,6 +373,7 @@ module g_tracer_utils public :: g_tracer_get_src_info public :: g_register_diag_field public :: g_send_data + public :: g_tracer_get_obc_segment_props ! ! ! Add a new parameter for the generic tracer package @@ -936,6 +938,8 @@ subroutine g_tracer_add(node_ptr, package, name, longname, units, prog, const_i call g_tracer_add_param(trim(g_tracer%name)//"_valid_min", g_tracer%src_var_valid_min , -99.0) call g_tracer_add_param(trim(g_tracer%name)//"_valid_max", g_tracer%src_var_valid_max , +1.0e64) call g_tracer_add_param(trim(g_tracer%name)//"_requires_restart", g_tracer%requires_restart , .true.) + call g_tracer_add_param(trim(g_tracer%name)//"_obc_src_file_name",g_tracer%obc_src_file_name , 'obgc_obc.nc') + call g_tracer_add_param(trim(g_tracer%name)//"_obc_src_field_name",g_tracer%obc_src_field_name,trim(g_tracer%name)) !=================================================================== !Reversed Linked List implementation! Make this new node to be the head of the list. @@ -3742,6 +3746,25 @@ subroutine g_tracer_get_src_info(g_tracer_list,name,src_file, src_var_name, src_ end subroutine g_tracer_get_src_info + subroutine g_tracer_get_obc_segment_props(g_tracer_list, name, src_file, src_var_name) + type(g_tracer_type), pointer :: g_tracer_list,g_tracer + character(len=*), intent(in) :: name + character(len=*), intent(out):: src_file, src_var_name + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_get_obc_segment_props' + + if(.NOT. associated(g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& + ": No tracer in the list.") + + g_tracer => g_tracer_list !Local pointer. Do not change the input pointer! + !Find the node which has name=name + call g_tracer_find(g_tracer,name) + if(.NOT. associated(g_tracer)) call mpp_error(FATAL, trim(sub_name)//& + ": No tracer in the list with name="//trim(name)) + + src_file = g_tracer%obc_src_file_name + src_var_name = g_tracer%obc_src_field_name + end subroutine g_tracer_get_obc_segment_props + function g_register_diag_field(module_name, field_name, axes, init_time, & long_name, units, missing_value, range, mask_variant, standard_name, & verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, & From d6efc6da7343c109c92c552cd6c0a48ee26850d3 Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Tue, 1 Sep 2020 10:39:55 -0400 Subject: [PATCH 2/9] Add property tr_obc_has to identify tracers with OBC --- generic_tracers/generic_CFC.F90 | 11 +++++++++-- generic_tracers/generic_tracer_utils.F90 | 8 ++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/generic_tracers/generic_CFC.F90 b/generic_tracers/generic_CFC.F90 index a4e8049..4eeccc9 100644 --- a/generic_tracers/generic_CFC.F90 +++ b/generic_tracers/generic_CFC.F90 @@ -390,10 +390,17 @@ subroutine user_add_tracers(tracer_list) standard_name = "mole_concentration_of_cfc11_in_sea_water", & diag_field_units = 'mol m-3', & diag_field_scaling_factor = 1035.0) ! rho = 1035.0 kg/m3, converts mol/kg to mol/m3 - !fake passive tracer + !fake passive tracers call g_tracer_add(tracer_list,package_name, & name = 'gtr1', & - longname = 'fake passive tracer', & + longname = 'fake passive tracer1', & + units = 'NA', & + prog = .true., & + requires_src_info = .false., & + flux_gas = .false.) + call g_tracer_add(tracer_list,package_name, & + name = 'gtr2', & + longname = 'fake passive tracer2', & units = 'NA', & prog = .true., & requires_src_info = .false., & diff --git a/generic_tracers/generic_tracer_utils.F90 b/generic_tracers/generic_tracer_utils.F90 index 228cda9..ba5583a 100644 --- a/generic_tracers/generic_tracer_utils.F90 +++ b/generic_tracers/generic_tracer_utils.F90 @@ -268,6 +268,7 @@ module g_tracer_utils ! Tracer source: filename, type, var name, units, record, gridfile character(len=fm_string_len) :: src_file, src_var_name, src_var_unit, src_var_gridspec character(len=fm_string_len) :: obc_src_file_name,obc_src_field_name + logical :: obc_has = .true. integer :: src_var_record logical :: requires_src_info = .false. real :: src_var_unit_conversion = 1.0 !This factor depends on the tracer. Ask Jasmin @@ -938,6 +939,7 @@ subroutine g_tracer_add(node_ptr, package, name, longname, units, prog, const_i call g_tracer_add_param(trim(g_tracer%name)//"_valid_min", g_tracer%src_var_valid_min , -99.0) call g_tracer_add_param(trim(g_tracer%name)//"_valid_max", g_tracer%src_var_valid_max , +1.0e64) call g_tracer_add_param(trim(g_tracer%name)//"_requires_restart", g_tracer%requires_restart , .true.) + call g_tracer_add_param(trim(g_tracer%name)//"_obc_has",g_tracer%obc_has , .true.) call g_tracer_add_param(trim(g_tracer%name)//"_obc_src_file_name",g_tracer%obc_src_file_name , 'obgc_obc.nc') call g_tracer_add_param(trim(g_tracer%name)//"_obc_src_field_name",g_tracer%obc_src_field_name,trim(g_tracer%name)) @@ -3746,10 +3748,11 @@ subroutine g_tracer_get_src_info(g_tracer_list,name,src_file, src_var_name, src_ end subroutine g_tracer_get_src_info - subroutine g_tracer_get_obc_segment_props(g_tracer_list, name, src_file, src_var_name) + subroutine g_tracer_get_obc_segment_props(g_tracer_list, name, obc_has, src_file, src_var_name) type(g_tracer_type), pointer :: g_tracer_list,g_tracer character(len=*), intent(in) :: name - character(len=*), intent(out):: src_file, src_var_name + logical, intent(out):: obc_has !<.true. if This tracer has OBC + character(len=*),optional,intent(out):: src_file, src_var_name ! Date: Wed, 2 Jun 2021 10:17:17 -0400 Subject: [PATCH 3/9] Raise threshold for carbon imbalance --- generic_tracers/generic_COBALT.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic_tracers/generic_COBALT.F90 b/generic_tracers/generic_COBALT.F90 index 6f74cf5..1a20078 100644 --- a/generic_tracers/generic_COBALT.F90 +++ b/generic_tracers/generic_COBALT.F90 @@ -8487,7 +8487,7 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h cobalt%p_nsmz(i,j,k,tau) + cobalt%p_nmdz(i,j,k,tau) + & cobalt%p_nlgz(i,j,k,tau)))*grid_tmask(i,j,k) imbal = (post_totc(i,j,k) - pre_totc(i,j,k))*86400.0/dt*1.03e6 - if (abs(imbal).gt.1.0e-10) then + if (abs(imbal).gt.1.0e-9) then call mpp_error(FATAL,& '==>biological source/sink imbalance (generic_COBALT_update_from_source): Carbon') endif From deabaaf282e27e58901a8eb0d83d33588266696a Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Fri, 7 Jan 2022 16:42:43 -0500 Subject: [PATCH 4/9] Allow obgc tracers have different reservoir length scales - This update along with an update to MOM6 brings in the capability to set tracer reservoir (inverse) length scales for individual obgc tracers via ocean_bgc field_table mechanism. - Tracer resevoir inverse length scales are set as before to 1.0/Lscale_in and 1.0/Lscale_out - Users should be able to specify a multiplicative factor for each obgc tracer for each IN or OUT direction in the field_table, e.g., alk_obc_lfac_in = 0.5 alk_obc_lfac_out = 0.75 - The factors are multiplied by the inverse length scales before reservoir calculations. - The default factors for all tracers are 1. - No answer changes unless non-one factors are specified in field_table - There is also a bugfix to COBALT to allow running in debug mode, log10 must be epsiloned to avoid log(0) - There is a bugfix to generic_tracer_utils to allow running in debug mode, intent(out) strings must have len=* otherwise we get a crash in debug mode like: forrtl: severe (408): fort: (18): Dummy character variable 'STRING' has length 1024 which is greater than actual variable length 200 --- generic_tracers/generic_COBALT.F90 | 2 +- generic_tracers/generic_tracer_utils.F90 | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/generic_tracers/generic_COBALT.F90 b/generic_tracers/generic_COBALT.F90 index 1a20078..a1dd3ad 100644 --- a/generic_tracers/generic_COBALT.F90 +++ b/generic_tracers/generic_COBALT.F90 @@ -9647,7 +9647,7 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h model_time, rmask = grid_tmask,& is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (cobalt%id_kfe_eq_lig .gt. 0) & - used = g_send_data(cobalt%id_kfe_eq_lig, log10(cobalt%kfe_eq_lig), & + used = g_send_data(cobalt%id_kfe_eq_lig, log10(cobalt%kfe_eq_lig+epsln), & model_time, rmask = grid_tmask,& is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (cobalt%id_feprime .gt. 0) & diff --git a/generic_tracers/generic_tracer_utils.F90 b/generic_tracers/generic_tracer_utils.F90 index ba5583a..45fe2b4 100644 --- a/generic_tracers/generic_tracer_utils.F90 +++ b/generic_tracers/generic_tracer_utils.F90 @@ -268,6 +268,8 @@ module g_tracer_utils ! Tracer source: filename, type, var name, units, record, gridfile character(len=fm_string_len) :: src_file, src_var_name, src_var_unit, src_var_gridspec character(len=fm_string_len) :: obc_src_file_name,obc_src_field_name + real :: obc_lfac_in = 1. + real :: obc_lfac_out= 1. logical :: obc_has = .true. integer :: src_var_record logical :: requires_src_info = .false. @@ -942,6 +944,8 @@ subroutine g_tracer_add(node_ptr, package, name, longname, units, prog, const_i call g_tracer_add_param(trim(g_tracer%name)//"_obc_has",g_tracer%obc_has , .true.) call g_tracer_add_param(trim(g_tracer%name)//"_obc_src_file_name",g_tracer%obc_src_file_name , 'obgc_obc.nc') call g_tracer_add_param(trim(g_tracer%name)//"_obc_src_field_name",g_tracer%obc_src_field_name,trim(g_tracer%name)) + call g_tracer_add_param(trim(g_tracer%name)//"_obc_lfac_in" ,g_tracer%obc_lfac_in , 1.0) + call g_tracer_add_param(trim(g_tracer%name)//"_obc_lfac_out",g_tracer%obc_lfac_out, 1.0) !=================================================================== !Reversed Linked List implementation! Make this new node to be the head of the list. @@ -2004,7 +2008,7 @@ subroutine g_tracer_get_string(g_tracer_list,name,member,string) character(len=*), intent(in) :: name character(len=*), intent(in) :: member type(g_tracer_type), pointer :: g_tracer_list, g_tracer - character(len=fm_string_len), intent(out) :: string + character(len=*), intent(out) :: string character(len=fm_string_len), parameter :: sub_name = 'g_tracer_get_string' if(.NOT. associated(g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& @@ -3748,11 +3752,12 @@ subroutine g_tracer_get_src_info(g_tracer_list,name,src_file, src_var_name, src_ end subroutine g_tracer_get_src_info - subroutine g_tracer_get_obc_segment_props(g_tracer_list, name, obc_has, src_file, src_var_name) + subroutine g_tracer_get_obc_segment_props(g_tracer_list, name, obc_has, src_file, src_var_name,lfac_in,lfac_out) type(g_tracer_type), pointer :: g_tracer_list,g_tracer character(len=*), intent(in) :: name logical, intent(out):: obc_has !<.true. if This tracer has OBC character(len=*),optional,intent(out):: src_file, src_var_name !biological source/sink imbalance (generic_COBALT_update_from_source): Carbon') endif From a18127083a3ffdd1c09aac8f81a2312235d5bf44 Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Mon, 10 Jan 2022 12:34:51 -0500 Subject: [PATCH 6/9] Allow obgc tracers have different reservoir length scales - This update along with an update to MOM6 brings in the capability to set tracer reservoir (inverse) length scales for individual obgc tracers via ocean_bgc field_table mechanism. - Tracer resevoir inverse length scales are set as before to 1.0/Lscale_in and 1.0/Lscale_out - Users should be able to specify a multiplicative factor for each obgc tracer for each IN or OUT direction in the field_table, e.g., alk_obc_lfac_in = 0.5 alk_obc_lfac_out = 0.75 - The factors are multiplied by the inverse length scales before reservoir calculations. - The default factors for all tracers are 1. - No answer changes unless non-one factors are specified in field_table - There is also a bugfix to COBALT to allow running in debug mode, log10 must be epsiloned to avoid log(0) - There is a bugfix to generic_tracer_utils to allow running in debug mode, intent(out) strings must have len=* otherwise we get a crash in debug mode like: forrtl: severe (408): fort: (18): Dummy character variable 'STRING' has length 1024 which is greater than actual variable length 200 --- generic_tracers/generic_CFC.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/generic_tracers/generic_CFC.F90 b/generic_tracers/generic_CFC.F90 index d27fcfe..5519b4f 100644 --- a/generic_tracers/generic_CFC.F90 +++ b/generic_tracers/generic_CFC.F90 @@ -391,6 +391,7 @@ subroutine user_add_tracers(tracer_list) diag_field_units = 'mol m-3', & diag_field_scaling_factor = 1035.0) ! rho = 1035.0 kg/m3, converts mol/kg to mol/m3 + end subroutine user_add_tracers ! From b425597e1cbf7e43dfabf2098fe947a38b668128 Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Mon, 10 Jan 2022 15:27:20 -0500 Subject: [PATCH 7/9] Decrease tolerance so model runs --- generic_tracers/generic_COBALT.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic_tracers/generic_COBALT.F90 b/generic_tracers/generic_COBALT.F90 index b7703fd..a1dd3ad 100644 --- a/generic_tracers/generic_COBALT.F90 +++ b/generic_tracers/generic_COBALT.F90 @@ -8487,7 +8487,7 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h cobalt%p_nsmz(i,j,k,tau) + cobalt%p_nmdz(i,j,k,tau) + & cobalt%p_nlgz(i,j,k,tau)))*grid_tmask(i,j,k) imbal = (post_totc(i,j,k) - pre_totc(i,j,k))*86400.0/dt*1.03e6 - if (abs(imbal).gt.1.0e-10) then + if (abs(imbal).gt.1.0e-9) then call mpp_error(FATAL,& '==>biological source/sink imbalance (generic_COBALT_update_from_source): Carbon') endif From 389e8de172807a54f6aa41d1147bc751c580a796 Mon Sep 17 00:00:00 2001 From: "Andrew C. Ross" Date: Wed, 16 Nov 2022 11:13:56 -0500 Subject: [PATCH 8/9] Keep track of whether runoff has been added to stf --- generic_tracers/generic_tracer_utils.F90 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/generic_tracers/generic_tracer_utils.F90 b/generic_tracers/generic_tracer_utils.F90 index 4816ba8..d11eecb 100644 --- a/generic_tracers/generic_tracer_utils.F90 +++ b/generic_tracers/generic_tracer_utils.F90 @@ -257,6 +257,7 @@ module g_tracer_utils logical :: flux_drydep = .false. !Is there a dry deposition? logical :: flux_bottom = .false. !Is there a flux through bottom? logical :: has_btm_reservoir = .false. !Is there a flux bottom reservoir? + logical :: runoff_added_to_stf = .false. ! Has flux in from runoff been added to stf? ! Flux identifiers to be set by aof_set_coupler_flux() integer :: flux_gas_ind = -1 @@ -2089,7 +2090,16 @@ subroutine g_tracer_set_2D(g_tracer_list,name,member,array,isd,jsd,weight) case ('sc_no') g_tracer%sc_no = w0*g_tracer%sc_no + w1*array case ('stf') - g_tracer%stf = w0*g_tracer%stf + w1*array + ! Check for edge case where the new value is a weighted combination of old and new values + ! and the old value had runoff added to it later. In this case, the result would be + ! invalid if the new value did not also have runoff added to it (which is not known). + if (w1 < 1 .and. g_tracer%runoff_added_to_stf) then + call mpp_error(FATAL, trim(sub_name)//& + ": Cannot set stf to a weighted combination of values with and without runoff.") + else + g_tracer%stf = w0*g_tracer%stf + w1*array + g_tracer%runoff_added_to_stf = .false. + endif case ('stf_gas') g_tracer%stf_gas= w0*g_tracer%stf_gas + w1*array case ('deltap') @@ -2234,6 +2244,7 @@ subroutine g_tracer_set_real(g_tracer_list,name,member,value) g_tracer%sc_no = value case ('stf') g_tracer%stf = value + g_tracer%runoff_added_to_stf = .false. case ('stf_gas') g_tracer%stf_gas = value case ('deltap') From 6cb6c0ca5f9bb8e32e731b60eabedd38f093e3e3 Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Thu, 11 May 2023 16:05:59 -0400 Subject: [PATCH 9/9] Charles Stock fixing the benthic denitrification and bottom layer diagnostics - Fixes from Charles Stock - 1) fix a bug in the benthic denitrification; and - 2) replace benthic calculations previously done with the bottom layer with an average over a specified thickness. - Merge some OBC changes from master branch to generic_tracer_utils.F90 These are interface changes needed to compile/run with the most recent MOM6/SIS2 commits --- generic_tracers/generic_COBALT.F90 | 219 +++++++++++++++++++++++++---- 1 file changed, 194 insertions(+), 25 deletions(-) diff --git a/generic_tracers/generic_COBALT.F90 b/generic_tracers/generic_COBALT.F90 index 37b7da2..5125762 100644 --- a/generic_tracers/generic_COBALT.F90 +++ b/generic_tracers/generic_COBALT.F90 @@ -649,6 +649,7 @@ module generic_COBALT lysis_phi_srdop, & lysis_phi_sldop, & wsink, & + bottom_thickness, & z_sed, & zeta, & refuge_conc, & @@ -905,10 +906,15 @@ module generic_COBALT flithdet_100, & btm_temp, & btm_o2, & + btm_no3, & + btm_alk, & + btm_dic, & btm_htotal, & btm_co3_ion, & btm_co3_sol_arag, & btm_co3_sol_calc, & + btm_omega_calc, & + btm_omega_arag, & cased_2d, & o2min, & z_o2min, & @@ -1212,6 +1218,9 @@ module generic_COBALT id_sfc_temp = -1, & id_btm_temp = -1, & id_btm_o2 = -1, & + id_btm_no3 = -1, & + id_btm_alk = -1, & + id_btm_dic = -1, & id_btm_htotal = -1, & id_btm_co3_sol_arag = -1, & id_btm_co3_sol_calc = -1, & @@ -1220,6 +1229,8 @@ module generic_COBALT id_sfc_co3_ion = -1, & id_sfc_co3_sol_arag = -1, & id_sfc_co3_sol_calc = -1, & + id_btm_omega_calc = -1, & + id_btm_omega_arag = -1, & id_runoff_flux_alk = -1, & id_runoff_flux_dic = -1, & id_runoff_flux_di14c = -1, & @@ -3152,6 +3163,18 @@ subroutine generic_COBALT_register_diag(diag_list) cobalt%id_btm_o2 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc("btm_no3","Bottom NO3",'h','1','s','mol kg-1','f') + cobalt%id_btm_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("btm_alk","Bottom Alkalinity",'h','1','s','eq kg-1','f') + cobalt%id_btm_alk = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("btm_dic","Bottom Dissolved Inorganic Carbon",'h','1','s','mol kg-1','f') + cobalt%id_btm_dic = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc("btm_htotal","Bottom Htotal",'h','1','s','mol kg-1','f') cobalt%id_btm_htotal = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) @@ -3168,6 +3191,14 @@ subroutine generic_COBALT_register_diag(diag_list) cobalt%id_btm_co3_sol_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc("btm_omega_arag","Bottom saturation state for aragonite",'h','1','s','none','f') + cobalt%id_btm_omega_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("btm_omega_calc","Bottom saturation state for calcite",'h','1','s','none','f') + cobalt%id_btm_omega_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc("cased_2d","calcium carbonite in sediment",'h','1','s','mol m-3','f') cobalt%id_cased_2d = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) @@ -5749,6 +5780,7 @@ subroutine user_add_params call g_tracer_add_param('gamma_sidet', cobalt%gamma_sidet, cobalt%wsink / 1.0e4 ) ! s-1 call g_tracer_add_param('phi_lith' , cobalt%phi_lith, 0.002) ! dimensionless call g_tracer_add_param('k_lith', cobalt%k_lith, 0.5/spery ) ! s-1 + call g_tracer_add_param('bottom_thickness',cobalt%bottom_thickness, 1.0 ) ! m call g_tracer_add_param('z_sed', cobalt%z_sed, 0.1 ) ! m call g_tracer_add_param('k_no3_denit',cobalt%k_no3_denit,1.0e-6) ! mol NO3 kg-1 call g_tracer_add_param('z_burial',cobalt%z_burial,50.0) ! m @@ -6656,7 +6688,7 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h real,dimension(1:NUM_ZOO) :: tot_prey real :: tot_prey_hp, sw_fac_denom, assim_eff real :: bact_uptake_ratio, vmax_bact, growth_ratio - real :: fpoc_btm, log_fpoc_btm + real :: fpoc_btm, log10_fpoc_btm real :: fe_salt real :: sal,tt,tkb,ts,ts2,ts3,ts4,ts5 @@ -8043,12 +8075,55 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h cobalt%jpo4_iceberg(i,j,k) = 0.0 enddo; enddo; enddo !} i,j,k + allocate(rho_dzt_bot(isc:iec,jsc:jec)) + allocate(k_bot(isc:iec,jsc:jec)) do j = jsc, jec; do i = isc, iec !{ - k = grid_kmt(i,j) - if (k .gt. 0) then !{ + if (grid_kmt(i,j) .gt. 0) then !{ + ! + ! Calculate the values of tracers influencing the sedimentary transformations + ! and fluxes over a layer defined by "bottom_thickess". The default is 1m. This + ! replaces the old approach with MOM4/5 that used the bottom layer since the + ! bottom layers in MOM6 are usually "vanished" layers that are 1 micron thick + ! + rho_dzt_bot(i,j) = 0.0 + cobalt%btm_o2(i,j) = 0.0 + cobalt%btm_no3(i,j) = 0.0 + cobalt%btm_co3_sol_calc(i,j) = 0.0 + cobalt%btm_co3_ion(i,j) = 0.0 + cobalt%btm_omega_calc(i,j) = 0.0 + k_bot(i,j) = 0 + do k = grid_kmt(i,j),1,-1 !{ + if (rho_dzt_bot(i,j).lt.(cobalt%Rho_0*cobalt%bottom_thickness)) then + k_bot(i,j) = k + rho_dzt_bot(i,j) = rho_dzt_bot(i,j) + rho_dzt(i,j,k) + cobalt%btm_o2(i,j) = cobalt%btm_o2(i,j) + & + cobalt%f_o2(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_no3(i,j) = cobalt%btm_no3(i,j) + & + cobalt%f_no3(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_co3_sol_calc(i,j) = cobalt%btm_co3_sol_calc(i,j) + & + cobalt%co3_sol_calc(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_co3_ion(i,j) = cobalt%btm_co3_ion(i,j) + & + cobalt%f_co3_ion(i,j,k)*rho_dzt(i,j,k) + endif + enddo + ! subtract off overshoot + drho_dzt = rho_dzt_bot(i,j) - cobalt%Rho_0*cobalt%bottom_thickness + cobalt%btm_o2(i,j)=cobalt%btm_o2(i,j)-cobalt%f_o2(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_no3(i,j)=cobalt%btm_no3(i,j)-cobalt%f_no3(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_co3_sol_calc(i,j)=cobalt%btm_co3_sol_calc(i,j)-cobalt%co3_sol_calc(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_co3_ion(i,j)=cobalt%btm_co3_ion(i,j)-cobalt%f_co3_ion(i,j,k_bot(i,j))*drho_dzt + ! convert back to moles kg-1 + cobalt%btm_o2(i,j)=cobalt%btm_o2(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_no3(i,j)=cobalt%btm_no3(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_co3_sol_calc(i,j)=cobalt%btm_co3_sol_calc(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_co3_ion(i,j)=cobalt%btm_co3_ion(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + ! calculate the saturation state with respect to calcite for subsequent calculations + cobalt%btm_omega_calc(i,j)=cobalt%btm_co3_ion(i,j)/cobalt%btm_co3_sol_calc(i,j) + ! ! Nitrogen flux from the sediments - ! + ! + k = grid_kmt(i,j) if (cobalt%f_ndet_btf(i,j,1) .gt. 0.0) then !{ ! fpoc_bottom in mmoles C m-2 day-1 for burial relationship fpoc_btm = cobalt%f_ndet_btf(i,j,1)*cobalt%c_2_n*sperd*1000.0 @@ -8066,23 +8141,25 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h cobalt%fpdet_burial(i,j) = cobalt%frac_burial(i,j)*cobalt%f_pdet_btf(i,j,1) ! fpoc_bottom in micromoles C cm-2 day-1 for denitrification relationship, cap at 43 ! to prevent anomalous extrapolation of the relationship - log_fpoc_btm = log(min(43.0,0.1*fpoc_btm)) - cobalt%fno3denit_sed(i,j) = min(cobalt%f_no3(i,j,k)*cobalt%Rho_0*r_dt, & + log10_fpoc_btm = log10(min(43.0,0.1*fpoc_btm)) + cobalt%fno3denit_sed(i,j) = min(cobalt%btm_no3(i,j)*cobalt%Rho_0*r_dt, & min((cobalt%f_ndet_btf(i,j,1)-cobalt%fndet_burial(i,j))*cobalt%n_2_n_denit, & - 10.0**(-0.9543+0.7662*log_fpoc_btm - 0.235*log_fpoc_btm**2.0)/(cobalt%c_2_n*sperd*100.0)* & - cobalt%n_2_n_denit*cobalt%f_no3(i,j,k)/(cobalt%k_no3_denit + cobalt%f_no3(i,j,k)))) * & + 10.0**(-0.9543+0.7662*log10_fpoc_btm - 0.235*log10_fpoc_btm**2.0)/(cobalt%c_2_n*sperd*100.0)* & + cobalt%n_2_n_denit*cobalt%btm_no3(i,j)/(cobalt%k_no3_denit + cobalt%btm_no3(i,j)))) * & cobalt%zt(i,j,k) / (cobalt%z_burial + cobalt%zt(i,j,k)) ! uncomment "no mass change" test !cobalt%fno3denit_sed(i,j) = 0.0 - if (cobalt%f_o2(i,j,k) .gt. cobalt%o2_min) then !{ - cobalt%fnoxic_sed(i,j) = max(0.0, min(cobalt%f_o2(i,j,k)*cobalt%Rho_0*r_dt*(1.0/cobalt%o2_2_nh4), & + if (cobalt%btm_o2(i,j) .gt. cobalt%o2_min) then !{ + cobalt%fnoxic_sed(i,j) = max(0.0, min(cobalt%btm_o2(i,j)*cobalt%bottom_thickness* & + cobalt%Rho_0*r_dt*(1.0/cobalt%o2_2_nh4), & cobalt%f_ndet_btf(i,j,1) - cobalt%fndet_burial(i,j) - & cobalt%fno3denit_sed(i,j)/cobalt%n_2_n_denit)) else cobalt%fnoxic_sed(i,j) = 0.0 endif !} cobalt%fno3denit_sed(i,j) = cobalt%fno3denit_sed(i,j) + & - min(cobalt%f_no3(i,j,k)*cobalt%Rho_0*r_dt-cobalt%fno3denit_sed(i,j), & + min(cobalt%btm_no3(i,j)*cobalt%bottom_thickness* & + cobalt%Rho_0*r_dt-cobalt%fno3denit_sed(i,j), & (cobalt%f_ndet_btf(i,j,1)-cobalt%fnoxic_sed(i,j)-cobalt%fndet_burial(i,j) - & cobalt%fno3denit_sed(i,j)/cobalt%n_2_n_denit)*cobalt%n_2_n_denit) cobalt%fnfeso4red_sed(i,j) = max(0.0, cobalt%f_ndet_btf(i,j,1)-cobalt%fnoxic_sed(i,j)- & @@ -8097,7 +8174,7 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h !cobalt%ffe_sed(i,j) = cobalt%fe_2_n_sed * cobalt%f_ndet_btf(i,j,1) ! iron from sediment (Dale) cobalt%ffe_sed(i,j) = cobalt%ffe_sed_max * tanh( (cobalt%f_ndet_btf(i,j,1)*cobalt%c_2_n*sperd*1.0e3)/ & - max(cobalt%f_o2(i,j,k)*1.0e6,epsln) ) + max(cobalt%btm_o2(i,j)*1.0e6,epsln) ) cobalt%ffe_geotherm(i,j) = cobalt%ffe_geotherm_ratio*internal_heat(i,j)*4184.0/dt ! default for icebergs: 40 nanomoles fe dissolved per kg of icemelt @@ -8135,7 +8212,7 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h cobalt%phi_surfresp_cased*cobalt%f_ndet_btf(i,j,1)*cobalt%c_2_n) ! Ca-specific dissolution coeficient, depends on calcite saturation state and is enhanced by ! respiration deep in the sediment (s-1), non-linearity controlled by alpha_cased - cobalt%cased_redis_coef(i,j) = cobalt%gamma_cased*max(0.0,1.0-cobalt%omega_calc(i,j,k)+ & + cobalt%cased_redis_coef(i,j) = cobalt%gamma_cased*max(0.0,1.0-cobalt%btm_omega_calc(i,j)+ & cobalt%phi_deepresp_cased*cobalt%f_ndet_btf(i,j,1)*cobalt%c_2_n*spery)**cobalt%alpha_cased ! Effective thickness term that enhances burial of calcite when total sediment accumulation is high ! dimensionless value between 0 and 1 @@ -9024,20 +9101,17 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h cobalt%jdin_plus_btm(i,j,k) = cobalt%jno3(i,j,k) + cobalt%jnh4(i,j,k) enddo; enddo; enddo !} i,j,k - allocate(rho_dzt_bot(isc:iec,jsc:jec)) - allocate(k_bot(isc:iec,jsc:jec)) - do j = jsc, jec ; do i = isc, iec !{ k = grid_kmt(i,j) rho_dzt_bot(i,j) = 0.0 if (k .gt. 0) then !{ do k = grid_kmt(i,j),1,-1 !{ - if (rho_dzt_bot(i,j).lt.cobalt%Rho_0*1.0) then + if (rho_dzt_bot(i,j).lt.cobalt%Rho_0*cobalt%bottom_thickness) then rho_dzt_bot(i,j) = rho_dzt_bot(i,j) + rho_dzt(i,j,k) k_bot(i,j) = k endif enddo - endif + endif enddo; enddo do j = jsc, jec ; do i = isc, iec !{ @@ -9465,16 +9539,81 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h do j = jsc, jec ; do i = isc, iec ; !{ if (grid_kmt(i,j) .gt. 0) then !{ - cobalt%btm_temp(i,j) = TEMP(i,j,grid_kmt(i,j)) - cobalt%btm_o2(i,j) = cobalt%f_o2(i,j,grid_kmt(i,j)) - cobalt%btm_htotal(i,j) = cobalt%f_htotal(i,j,grid_kmt(i,j)) - cobalt%btm_co3_sol_arag(i,j) = cobalt%co3_sol_arag(i,j,grid_kmt(i,j)) - cobalt%btm_co3_sol_calc(i,j) = cobalt%co3_sol_calc(i,j,grid_kmt(i,j)) - cobalt%btm_co3_ion(i,j) = cobalt%f_co3_ion(i,j,grid_kmt(i,j)) + !cobalt%btm_temp(i,j) = TEMP(i,j,grid_kmt(i,j)) + !cobalt%btm_o2(i,j) = cobalt%f_o2(i,j,grid_kmt(i,j)) + !cobalt%btm_htotal(i,j) = cobalt%f_htotal(i,j,grid_kmt(i,j)) + !cobalt%btm_co3_sol_arag(i,j) = cobalt%co3_sol_arag(i,j,grid_kmt(i,j)) + !cobalt%btm_co3_sol_calc(i,j) = cobalt%co3_sol_calc(i,j,grid_kmt(i,j)) + !cobalt%btm_co3_ion(i,j) = cobalt%f_co3_ion(i,j,grid_kmt(i,j)) cobalt%cased_2d(i,j) = cobalt%f_cased(i,j,1) endif enddo; enddo !} i, j + ! Calculate the bottom layer over a thickness defined by cobalt%bottom_thickness + ! rather than the bottom-most layer as in MOM4/5. This avoids numerical issues + ! generated in "vanishing" layers that overlie the benthos in most regions. + do j = jsc, jec ; do i = isc, iec !{ + rho_dzt_bot(i,j) = 0.0 + cobalt%btm_temp(i,j) = 0.0 + cobalt%btm_o2(i,j) = 0.0 + cobalt%btm_dic(i,j) = 0.0 + cobalt%btm_alk(i,j) = 0.0 + cobalt%btm_htotal(i,j) = 0.0 + cobalt%btm_co3_sol_arag(i,j) = 0.0 + cobalt%btm_co3_sol_calc(i,j) = 0.0 + cobalt%btm_co3_ion(i,j) = 0.0 + cobalt%btm_omega_calc(i,j) = 0.0 + cobalt%btm_omega_arag(i,j) = 0.0 + k_bot(i,j) = 0 + k = grid_kmt(i,j) + if (k .gt. 0) then !{ + do k = grid_kmt(i,j),1,-1 !{ + if (rho_dzt_bot(i,j).lt.cobalt%Rho_0*cobalt%bottom_thickness) then + k_bot(i,j) = k + rho_dzt_bot(i,j) = rho_dzt_bot(i,j) + rho_dzt(i,j,k) + cobalt%btm_o2(i,j) = cobalt%btm_o2(i,j) + & + cobalt%f_o2(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_alk(i,j) = cobalt%btm_alk(i,j) + & + cobalt%f_alk(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_dic(i,j) = cobalt%btm_dic(i,j) + & + cobalt%f_dic(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_temp(i,j) = cobalt%btm_temp(i,j) + & + Temp(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_htotal(i,j) = cobalt%btm_htotal(i,j) + & + cobalt%f_htotal(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_co3_sol_arag(i,j) = cobalt%btm_co3_sol_arag(i,j) + & + cobalt%co3_sol_arag(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_co3_sol_calc(i,j) = cobalt%btm_co3_sol_calc(i,j) + & + cobalt%co3_sol_calc(i,j,k)*rho_dzt(i,j,k) + cobalt%btm_co3_ion(i,j) = cobalt%btm_co3_ion(i,j) + & + cobalt%f_co3_ion(i,j,k)*rho_dzt(i,j,k) + endif + enddo + ! calculate overshoot and subtract off + drho_dzt = rho_dzt_bot(i,j) - cobalt%Rho_0*cobalt%bottom_thickness + cobalt%btm_temp(i,j)=cobalt%btm_temp(i,j)-Temp(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_o2(i,j)=cobalt%btm_o2(i,j)-cobalt%f_o2(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_alk(i,j)=cobalt%btm_alk(i,j)-cobalt%f_alk(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_dic(i,j)=cobalt%btm_dic(i,j)-cobalt%f_dic(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_htotal(i,j)=cobalt%btm_htotal(i,j)-cobalt%f_htotal(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_co3_sol_arag(i,j)=cobalt%btm_co3_sol_arag(i,j)-cobalt%co3_sol_arag(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_co3_sol_calc(i,j)=cobalt%btm_co3_sol_calc(i,j)-cobalt%co3_sol_calc(i,j,k_bot(i,j))*drho_dzt + cobalt%btm_co3_ion(i,j)=cobalt%btm_co3_ion(i,j)-cobalt%f_co3_ion(i,j,k_bot(i,j))*drho_dzt + ! convert back to moles kg-1 + cobalt%btm_temp(i,j)=cobalt%btm_temp(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_o2(i,j)=cobalt%btm_o2(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_alk(i,j)=cobalt%btm_alk(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_dic(i,j)=cobalt%btm_dic(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_htotal(i,j)=cobalt%btm_htotal(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_co3_sol_arag(i,j)=cobalt%btm_co3_sol_arag(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_co3_sol_calc(i,j)=cobalt%btm_co3_sol_calc(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + cobalt%btm_co3_ion(i,j)=cobalt%btm_co3_ion(i,j)/(cobalt%bottom_thickness*cobalt%Rho_0) + ! calculate bottom saturation states + cobalt%btm_omega_calc(i,j) = cobalt%btm_co3_ion(i,j)/cobalt%btm_co3_sol_calc(i,j) + cobalt%btm_omega_arag(i,j) = cobalt%btm_co3_ion(i,j)/cobalt%btm_co3_sol_arag(i,j) + endif + enddo; enddo + ! !--------------------------------------------------------------------- ! calculate upper 200m vertical integrals for mesozooplankton @@ -10374,6 +10513,18 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h used = g_send_data(cobalt%id_btm_o2, cobalt%btm_o2, & model_time, rmask = grid_tmask(:,:,1),& is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_btm_no3 .gt. 0) & + used = g_send_data(cobalt%id_btm_no3, cobalt%btm_no3, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_btm_alk .gt. 0) & + used = g_send_data(cobalt%id_btm_alk, cobalt%btm_alk, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_btm_dic .gt. 0) & + used = g_send_data(cobalt%id_btm_dic, cobalt%btm_dic, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (cobalt%id_btm_htotal .gt. 0) & used = g_send_data(cobalt%id_btm_htotal, cobalt%btm_htotal, & model_time, rmask = grid_tmask(:,:,1),& @@ -10406,6 +10557,14 @@ subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,h used = g_send_data(cobalt%id_btm_co3_sol_calc, cobalt%btm_co3_sol_calc, & model_time, rmask = grid_tmask(:,:,1),& is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_btm_omega_calc .gt. 0) & + used = g_send_data(cobalt%id_btm_omega_calc, cobalt%btm_omega_calc, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_btm_omega_arag .gt. 0) & + used = g_send_data(cobalt%id_btm_omega_arag, cobalt%btm_omega_arag, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) do n= 1, NUM_PHYTO if (phyto(n)%id_sfc_f_n .gt. 0) & @@ -13002,10 +13161,15 @@ subroutine user_allocate_arrays allocate(cobalt%btm_temp(isd:ied,jsd:jed)) ; cobalt%btm_temp = 0.0 allocate(cobalt%btm_o2(isd:ied,jsd:jed)) ; cobalt%btm_o2 = 0.0 - allocate(cobalt%btm_htotal(isd:ied,jsd:jed)) ; cobalt%btm_htotal = 0.0 + allocate(cobalt%btm_no3(isd:ied,jsd:jed)) ; cobalt%btm_no3 = 0.0 + allocate(cobalt%btm_alk(isd:ied,jsd:jed)) ; cobalt%btm_alk = 0.0 + allocate(cobalt%btm_dic(isd:ied,jsd:jed)) ; cobalt%btm_dic = 0.0 + allocate(cobalt%btm_htotal(isd:ied,jsd:jed)) ; cobalt%btm_htotal = 0.0 allocate(cobalt%btm_co3_ion(isd:ied,jsd:jed)) ; cobalt%btm_co3_ion = 0.0 allocate(cobalt%btm_co3_sol_arag(isd:ied,jsd:jed)) ; cobalt%btm_co3_sol_arag = 0.0 allocate(cobalt%btm_co3_sol_calc(isd:ied,jsd:jed)) ; cobalt%btm_co3_sol_calc = 0.0 + allocate(cobalt%btm_omega_arag(isd:ied,jsd:jed)) ; cobalt%btm_omega_arag = 0.0 + allocate(cobalt%btm_omega_calc(isd:ied,jsd:jed)) ; cobalt%btm_omega_calc = 0.0 allocate(cobalt%cased_2d(isd:ied,jsd:jed)) ; cobalt%cased_2d = 0.0 allocate(cobalt%o2min(isd:ied, jsd:jed)) ; cobalt%o2min=0.0 @@ -13406,10 +13570,15 @@ subroutine user_deallocate_arrays deallocate(cobalt%flithdet_100) deallocate(cobalt%btm_temp) deallocate(cobalt%btm_o2) + deallocate(cobalt%btm_no3) + deallocate(cobalt%btm_alk) + deallocate(cobalt%btm_dic) deallocate(cobalt%btm_htotal) deallocate(cobalt%btm_co3_ion) deallocate(cobalt%btm_co3_sol_arag) deallocate(cobalt%btm_co3_sol_calc) + deallocate(cobalt%btm_omega_arag) + deallocate(cobalt%btm_omega_calc) deallocate(cobalt%cased_2d) deallocate(cobalt%o2min) deallocate(cobalt%z_o2min)