From eb016cc01182eb51505cc4f2ec0d4ac8e3914f7f Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Tue, 12 Nov 2024 11:26:37 +1100 Subject: [PATCH 01/23] Added: * Variable remineralisation rate (reminr) that increases as phytoplankton biomass increases and decreases with depth (emulating variable sinking rate of detritus) * Fixed a bug in the calculation of the minimum Fe quota of phytoplankton that reduced their dFe limitation * Added new diagnostics, particularly for terms contributing to the calculation of nutrient limitations --- generic_tracers/generic_WOMBATlite.F90 | 200 +++++++++++++++++++------ 1 file changed, 153 insertions(+), 47 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 47b746f..f8ec816 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -146,6 +146,7 @@ module generic_WOMBATlite detlrem, & detlrem_sed, & wdetbio, & + phybiot, & caco3lrem, & caco3lrem_sed, & wcaco3, & @@ -260,6 +261,8 @@ module generic_WOMBATlite phy_mumax, & phy_mu, & pchl_mu, & + phy_kni, & + phy_kfe, & phy_lpar, & phy_lnit, & phy_lfer, & @@ -273,6 +276,8 @@ module generic_WOMBATlite fecoag2det, & fesources, & fesinks, & + phy_feupreg, & + phy_fedoreg, & phygrow, & phyresp, & phymort, & @@ -281,6 +286,7 @@ module generic_WOMBATlite zoomort, & zooexcr, & zooslop, & + reminr, & detremi, & caldiss, & no3_prev, & @@ -323,6 +329,8 @@ module generic_WOMBATlite id_radmid3d = -1, & id_radbio1 = -1, & id_pprod_gross = -1, & + id_phy_kni = -1, & + id_phy_kfe = -1, & id_phy_lpar = -1, & id_phy_lnit = -1, & id_phy_lfer = -1, & @@ -336,6 +344,8 @@ module generic_WOMBATlite id_fecoag2det = -1, & id_fesources = -1, & id_fesinks = -1, & + id_phy_feupreg = -1, & + id_phy_fedoreg = -1, & id_phygrow = -1, & id_phyresp = -1, & id_phymort = -1, & @@ -344,6 +354,7 @@ module generic_WOMBATlite id_zoomort = -1, & id_zooexcr = -1, & id_zooslop = -1, & + id_reminr = -1, & id_detremi = -1, & id_caldiss = -1, & id_phy_mumax = -1, & @@ -742,6 +753,16 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_phy_lpar = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & + 'phy_kni', 'Half-saturation coefficient of nitrogen uptake by phytoplankton', 'h', 'L', 's', 'mmol/m3', 'f') + wombat%id_phy_kni = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'phy_kfe', 'Half-saturation coefficient of iron uptake by phytoplankton', 'h', 'L', 's', 'umol/m3', 'f') + wombat%id_phy_kfe = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & 'phy_lnit', 'Limitation of phytoplankton by nitrogen', 'h', 'L', 's', '[0-1]', 'f') wombat%id_phy_lnit = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & @@ -802,6 +823,16 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_fesinks = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & + 'phy_feupreg', 'Factor up regulation of dFe uptake by phytoplankton', 'h', 'L', 's', ' ', 'f') + wombat%id_phy_feupreg = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'phy_fedoreg', 'Factor down regulation of dFe uptake by phytoplankton', 'h', 'L', 's', ' ', 'f') + wombat%id_phy_fedoreg = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & 'phygrow', 'Growth of phytoplankton', 'h', 'L', 's', 'molC/kg/s', 'f') wombat%id_phygrow = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & @@ -842,6 +873,11 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_zooslop = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & + 'reminr', 'rate of remineralisation', 'h', 'L', 's', '/s', 'f') + wombat%id_reminr = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & 'detremi', 'Remineralisation rate of detritus', 'h', 'L', 's', 'molC/kg/s', 'f') wombat%id_detremi = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & @@ -1129,11 +1165,11 @@ subroutine user_add_params ! Phytoplankton linear mortality rate constant [1/s] !----------------------------------------------------------------------- - call g_tracer_add_param('phylmor', wombat%phylmor, 0.005/86400.0) + call g_tracer_add_param('phylmor', wombat%phylmor, 0.01/86400.0) ! Phytoplankton quadratic mortality rate constant [m3/mmolN/s] !----------------------------------------------------------------------- - call g_tracer_add_param('phyqmor', wombat%phyqmor, 0.025/86400.0) + call g_tracer_add_param('phyqmor', wombat%phyqmor, 0.05/86400.0) ! Zooplankton assimilation efficiency [1] !----------------------------------------------------------------------- @@ -1149,7 +1185,7 @@ subroutine user_add_params ! Zooplankton prey capture rate constant [m6/mmol2/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zooepsi', wombat%zooepsi, 0.05/86400.0) + call g_tracer_add_param('zooepsi', wombat%zooepsi, 0.25/86400.0) ! Zooplankton respiration rate constant [1/s] !----------------------------------------------------------------------- @@ -1171,6 +1207,10 @@ subroutine user_add_params ! consistent with what is in ACCESS-ESM1.5 (undocumented in Ziehn et al ! 2020) call g_tracer_add_param('detlrem_sed', wombat%detlrem_sed, 0.02/86400.0) + + ! Phytoplankton biomass threshold to scale recycling [mmolC/m3] + !----------------------------------------------------------------------- + call g_tracer_add_param('phybiot', wombat%phybiot, 0.5) ! CaCO3 remineralisation rate constant [1/s] !----------------------------------------------------------------------- @@ -1200,7 +1240,7 @@ subroutine user_add_params ! Scavenging of Fe` onto biogenic particles [(mmolC/m3)-1 d-1] !----------------------------------------------------------------------- - call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 0.005) + call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 5e-6) ! Iron background concentration [umol Fe m^-3] !----------------------------------------------------------------------- @@ -1711,7 +1751,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: swpar real :: u_npz, g_npz real :: biophy, biozoo, biodet, biono3, biofer, biocaco3 - real :: biophyfe + real :: biophyfe, biophy1 real :: fbc real :: no3_bgc_change, caco3_bgc_change real :: epsi = 1.0e-30 @@ -1719,7 +1759,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & integer :: ichl real :: par_phy_mldsum, par_z_mldsum real :: chl, zchl, zval, phy_chlc - real :: phy_k_nit, phy_k_fer real :: phy_pisl, phy_pisl2 real :: pchl_pisl, pchl_lpar, pchl_mumin, pchl_muopt real, dimension(:,:), allocatable :: ek_bgr, par_bgr_mid, par_bgr_top @@ -1730,7 +1769,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: fesol1, fesol2, fesol3, fesol4, fesol5, hp, fe3sol real :: biof, biodoc real :: phy_Fe2C, zoo_Fe2C, det_Fe2C - real :: phy_minqfe, phy_maxqfe, phy_dFeupt_upreg, phy_dFeupt_doreg + real :: phy_minqfe, phy_maxqfe real :: zoo_slmor logical :: used @@ -1919,9 +1958,11 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phy_mumax(:,:,:) = 0.0 wombat%phy_mu(:,:,:) = 0.0 wombat%pchl_mu(:,:,:) = 0.0 - wombat%phy_lpar(:,:,:) = 1.0 - wombat%phy_lnit(:,:,:) = 1.0 - wombat%phy_lfer(:,:,:) = 1.0 + wombat%phy_kni(:,:,:) = 0.0 + wombat%phy_kfe(:,:,:) = 0.0 + wombat%phy_lpar(:,:,:) = 0.0 + wombat%phy_lnit(:,:,:) = 0.0 + wombat%phy_lfer(:,:,:) = 0.0 wombat%phy_dfeupt(:,:,:) = 0.0 wombat%feIII(:,:,:) = 0.0 wombat%felig(:,:,:) = 0.0 @@ -1932,6 +1973,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fesources(:,:,:) = 0.0 wombat%fesinks(:,:,:) = 0.0 wombat%fecoag2det(:,:,:) = 0.0 + wombat%phy_feupreg(:,:,:) = 0.0 + wombat%phy_fedoreg(:,:,:) = 0.0 wombat%phygrow(:,:,:) = 0.0 wombat%phyresp(:,:,:) = 0.0 wombat%phymort(:,:,:) = 0.0 @@ -1940,6 +1983,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zoomort(:,:,:) = 0.0 wombat%zooexcr(:,:,:) = 0.0 wombat%zooslop(:,:,:) = 0.0 + wombat%reminr(:,:,:) = 0.0 wombat%detremi(:,:,:) = 0.0 wombat%caldiss(:,:,:) = 0.0 wombat%export_prod(:,:) = 0.0 @@ -2125,7 +2169,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & if (swpar.gt.0.0) then ! Euphotic zone - if (par_mid(k).gt.(swpar*0.01) .and. par_mid(k).gt.1.0) then + if (par_mid(k).gt.(swpar*0.01) .and. par_mid(k).gt.0.01) then wombat%zeuphot(i,j) = wombat%zw(i,j,k) endif ! Light attenuation mean over the grid cells (Eq. 19 of Baird et al., 2020 GMD) @@ -2151,7 +2195,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & enddo !} ! Calculate impact of euphotic zone depth on phytoplankton and chlorophyll production - wombat%phy_leup(i,j) = MIN(1.0, wombat%zeuphot(i,j)/(hblt_depth(i,j) + epsi)) +! wombat%phy_leup(i,j) = MIN(1.0, wombat%zeuphot(i,j)/(hblt_depth(i,j) + epsi)) + wombat%phy_leup(i,j) = 1.0 !--- Aggregate light in mixed layer and calculate maximum growth rates ---! do k = 1,grid_kmt(i,j) !{ @@ -2199,6 +2244,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Initialise some values and ratios (put into nicer units than mol/kg) biophy = max(epsi, wombat%f_phy(i,j,k) ) / mmol_m3_to_mol_kg ![mmol/m3] + biophy1 = max(epsi, wombat%f_phy(i,j,1) ) / mmol_m3_to_mol_kg ![mmol/m3] biophyfe = max(epsi, wombat%f_phyfe(i,j,k))/ mmol_m3_to_mol_kg ![mmol/m3] biozoo = max(epsi, wombat%f_zoo(i,j,k) ) / mmol_m3_to_mol_kg ![mmol/m3] biodet = max(epsi, wombat%f_det(i,j,k) ) / mmol_m3_to_mol_kg ![mmol/m3] @@ -2222,30 +2268,39 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! 1. Allometric scaling of 0.37 (Wickman et al., 2024; Science) ! 2. Apply variable K to set limitation term - phy_k_nit = wombat%phykn * max(biophy, 0.1)**(0.37) - phy_k_fer = wombat%phykf * max(biophy, 0.1)**(0.37) + wombat%phy_kni(i,j,k) = wombat%phykn * max(0.1, max(0.0, (biophy-wombat%phybiot))**0.37) + wombat%phy_kfe(i,j,k) = wombat%phykf * max(0.5, max(0.0, (biophy-wombat%phybiot))**0.37) ! Nitrogen limitation (currently Michaelis-Menten term) - wombat%phy_lnit(i,j,k) = biono3 / (biono3 + phy_k_nit + epsi) + wombat%phy_lnit(i,j,k) = biono3 / (biono3 + wombat%phy_kni(i,j,k)) ! Iron limitation (Quota model, constants from Flynn & Hipkin 1999) - if (biophy.gt.1e-3) then - phy_minqfe = 0.00167 / 55.85 * phy_chlc + & - 1.21e-5 * 14.0 / 55.85 / 7.625 * 0.5 * 1.5 * wombat%phy_lnit(i,j,k) + & - 1.15e-4 * 14.0 / 55.85 / 7.625 * 0.5 * wombat%phy_lnit(i,j,k) - wombat%phy_lfer(i,j,k) = min(1.0, max(0.0, (phy_Fe2C - phy_minqfe) / wombat%phyoptqf )) - endif + phy_minqfe = 0.00167 / 55.85 * max(wombat%phyminqc, phy_chlc)*12 + & + 1.21e-5 * 14.0 / 55.85 / 7.625 * 0.5 * 1.5 * wombat%phy_lnit(i,j,k) + & + 1.15e-4 * 14.0 / 55.85 / 7.625 * 0.5 * wombat%phy_lnit(i,j,k) + wombat%phy_lfer(i,j,k) = min(1.0, max(0.0, (phy_Fe2C - phy_minqfe) / wombat%phyoptqf )) !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! - ! [Step 3] Temperature-dependence of heterotrophy ! + ! [Step 3] Heterotrophy and remineralisation ! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! - ! Temperature dependance of heterotrophy + ! Temperature dependance of heterotrophy (applies to bact and zoo) fbc = wombat%bbioh ** (Temp(i,j,k)) + ! Variable rates of remineralisation + ! We set the rate of remineralisation to be variable to emulate variations + ! in the sinking speeds of detritus, which in MOM must be constant. + ! Thus, we (1) increase remineralisation in the gyres where bacterial + ! recycling of material is rapid and where large quantities of suspended + ! organics exist, and (2) decrease remineralisation with depth to + ! account for the power-law behaviour of POC in the water column + wombat%reminr(i,j,k) = wombat%detlrem * fbc * & + min(2.0, (wombat%phybiot / biophy1)**0.21) * & + max(0.25, (1. - wombat%zm(i,j,k) / 5000.0)) + !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! @@ -2266,6 +2321,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phy_mu(i,j,k) = wombat%phy_mumax(i,j,k) * wombat%phy_lpar(i,j,k) * & min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k)) + ! Save the average light limitation over the euphotic zone if (wombat%zw(i,j,k) .le. wombat%zeuphot(i,j)) then wombat%light_limit(i,j) = wombat%light_limit(i,j) + dzt(i,j,k) & @@ -2284,10 +2340,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! 1. Light limitation of chlorophyll production ! 2. minimum and optimal rates of chlorophyll growth ! 3. Calculate mg Chl m-3 s-1 - + pchl_pisl = phy_pisl / ( wombat%phy_mumax(i,j,k) * 86400.0 * & - (1. - min(wombat%phy_lnit(i,j,k), & - wombat%phy_lfer(i,j,k))) + epsi ) + (1. - min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k))) + epsi ) pchl_lpar = (1. - exp(-pchl_pisl * par_phymld(i,j,k))) * wombat%phy_leup(i,j) pchl_mumin = wombat%phyminqc * wombat%phy_mu(i,j,k) * biophy * 12.0 ![mg/m3/s] pchl_muopt = wombat%phyoptqc * wombat%phy_mu(i,j,k) * biophy * 12.0 ![mg/m3/s] @@ -2312,14 +2367,15 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! 2. Ensure that dFe uptake increases or decreases in response to cell quota ! 3. Iron uptake of phytoplankton - phy_maxqfe = biophy * wombat%phymaxqf - phy_dFeupt_upreg = (4.0 - 4.5 * wombat%phy_lfer(i,j,k) / & - (wombat%phy_lfer(i,j,k) + 0.5) ) - phy_dFeupt_doreg = max(0.0, (1.0 - biophyfe/phy_maxqfe) / & + phy_maxqfe = biophy * wombat%phymaxqf !mmol Fe / m3 + wombat%phy_feupreg(i,j,k) = (4.0 - 4.5 * wombat%phy_lfer(i,j,k) / & + (wombat%phy_lfer(i,j,k) + 0.5) ) + wombat%phy_fedoreg(i,j,k) = max(0.0, (1.0 - biophyfe/phy_maxqfe) / & abs(1.05 - biophyfe/phy_maxqfe) ) wombat%phy_dfeupt(i,j,k) = (biophy * wombat%phy_mumax(i,j,k) * wombat%phymaxqf * & - biofer / (biofer + phy_k_fer) * & - phy_dFeupt_doreg * phy_dFeupt_upreg) * mmol_m3_to_mol_kg + biofer / (biofer + wombat%phy_kfe(i,j,k)) * & + wombat%phy_feupreg(i,j,k) * & + wombat%phy_fedoreg(i,j,k)) * mmol_m3_to_mol_kg !-----------------------------------------------------------------------! @@ -2338,11 +2394,13 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & fesol3 = 10**(0.4511 - 0.3305*zval**0.5 - 1996.0/ztemk) fesol4 = 10**(-0.2965 - 0.7881*zval**0.5 - 4086.0/ztemk) fesol5 = 10**(4.4466 - 0.8505*zval**0.5 - 7980.0/ztemk) - hp = wombat%ahtotal(i,j,k) + hp = 10**(-7.9) + if (wombat%ahtotal(i,j,k).gt.0.0) hp = wombat%ahtotal(i,j,k) fe3sol = fesol1 * ( hp**3 + fesol2 * hp**2 + fesol3 * hp + fesol4 + fesol5 / hp ) *1e9 ! Estimate total colloidal iron - ! ... for now, we assume that 50% of all dFe is colloidal + ! ... for now, we assume that 50% of all dFe is colloidal, and we separate this from the + ! equilibrium fractionation between Fe' and Fe-L below wombat%fecol(i,j,k) = 0.5 * biofer ! Determine equilibriuim fractionation of the remain dFe (non-colloidal fraction) into Fe' and L-Fe @@ -2360,7 +2418,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Scavenging of Fe` onto biogenic particles partic = (biodet + biocaco3) - wombat%fescaven(i,j,k) = wombat%feIII(i,j,k) * (3e-5 + wombat%kscav_dfe * partic) / 86400.0 + wombat%fescaven(i,j,k) = wombat%feIII(i,j,k) * (3e-8 + wombat%kscav_dfe * partic) / 86400.0 wombat%fescadet(i,j,k) = wombat%fescaven(i,j,k) * biodet / (partic+epsi) ! Coagulation of colloidal Fe (umol/m3) to form sinking particles (mmol/m3) @@ -2368,17 +2426,20 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & biof = max(1/3., biophy / (biophy + 0.03)) biodoc = 2.0 + (1.0 - min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k))) * 38.0 ! proxy of DOC (mmol/m3) if (wombat%zw(i,j,k).le.hblt_depth(i,j)) then - zval = ( (12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-8 + zval = ( (12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-9 else - zval = ( 0.01*(12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-8 + zval = ( 0.01*(12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-9 endif wombat%fecoag2det(i,j,k) = wombat%fecol(i,j,k) * zval / 86400.0 - ! Convert the sink terms to mol/kg - wombat%feprecip(i,j,k) = wombat%feprecip(i,j,k) * umol_m3_to_mol_kg - wombat%fescaven(i,j,k) = wombat%fescaven(i,j,k) * umol_m3_to_mol_kg - wombat%fescadet(i,j,k) = wombat%fescadet(i,j,k) * umol_m3_to_mol_kg - wombat%fecoag2det(i,j,k) = wombat%fecoag2det(i,j,k) * umol_m3_to_mol_kg + ! Convert the terms back to mol/kg + wombat%feprecip(i,j,k) = wombat%feprecip(i,j,k) * umol_m3_to_mol_kg + wombat%fescaven(i,j,k) = wombat%fescaven(i,j,k) * umol_m3_to_mol_kg * 0.0 + wombat%fescadet(i,j,k) = wombat%fescadet(i,j,k) * umol_m3_to_mol_kg * 0.0 + wombat%fecoag2det(i,j,k) = wombat%fecoag2det(i,j,k) * umol_m3_to_mol_kg * 0.0 + wombat%feIII(i,j,k) = wombat%feIII(i,j,k) * umol_m3_to_mol_kg + wombat%felig(i,j,k) = wombat%felig(i,j,k) * umol_m3_to_mol_kg + wombat%fecol(i,j,k) = wombat%fecol(i,j,k) * umol_m3_to_mol_kg !-----------------------------------------------------------------------! @@ -2419,8 +2480,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phyresp(i,j,k) = 0.0 wombat%phymort(i,j,k) = 0.0 endif - wombat%zooexcr(i,j,k) = wombat%zoograz(i,j,k) * (1.0 - wombat%zooassi)*0.75 - wombat%zooslop(i,j,k) = wombat%zoograz(i,j,k) * (1.0 - wombat%zooassi)*0.25 + wombat%zooexcr(i,j,k) = wombat%zoograz(i,j,k) * (1.0 - wombat%zooassi)*0.75 + wombat%zooslop(i,j,k) = wombat%zoograz(i,j,k) * (1.0 - wombat%zooassi)*0.25 if (biozoo .gt. 1e-3) then wombat%zooresp(i,j,k) = wombat%zoolmor * fbc * wombat%f_zoo(i,j,k) * zoo_slmor ! [molC/kg/s] @@ -2431,7 +2492,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif if (wombat%f_det(i,j,k) .gt. epsi) then - wombat%detremi(i,j,k) = wombat%detlrem * fbc * wombat%f_det(i,j,k) ! [molC/kg/s] + wombat%detremi(i,j,k) = wombat%reminr(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = 0.5 * wombat%detremi(i,j,k) ! reduce decay below 180m else wombat%detremi(i,j,k) = 0.0 @@ -2559,17 +2620,30 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fecoag2det(i,j,k) ) ! Collect dFe sources and sinks for diagnostic output - wombat%fesources(i,j,k) = wombat%fesources(i,j,k) + dtsb*rdtts * ( & + wombat%fesources(i,j,k) = wombat%fesources(i,j,k) + dtsb * ( & wombat%detremi(i,j,k) * det_Fe2C + & wombat%zooresp(i,j,k) * zoo_Fe2C + & wombat%zooexcr(i,j,k) * zoo_Fe2C + & wombat%phyresp(i,j,k) * phy_Fe2C) - wombat%fesinks(i,j,k) = wombat%fesinks(i,j,k) + dtsb*rdtts * ( & + wombat%fesinks(i,j,k) = wombat%fesinks(i,j,k) + dtsb * ( & wombat%phy_dfeupt(i,j,k) + & wombat%feprecip(i,j,k) + & wombat%fescaven(i,j,k) + & wombat%fecoag2det(i,j,k)) + if (i.eq.150 .and. j.eq.180 .and. k.lt.25) then + print*, k, wombat%zm(i,j,k), wombat%f_fe(i,j,k) + print*, wombat%feIII(i,j,k), wombat%felig(i,j,k), wombat%fecol(i,j,k) + print*, "Fe Sources", wombat%fesources(i,j,k) * rdtts * ts_npzd/tn + print*, wombat%detremi(i,j,k)* det_Fe2C + print*, wombat%zooresp(i,j,k)*zoo_Fe2C, wombat%zooexcr(i,j,k)*zoo_Fe2C + print*, wombat%phyresp(i,j,k)* phy_Fe2C + print*, "Fe Sinks", wombat%fesinks(i,j,k) * rdtts * ts_npzd/tn + print*, wombat%phy_dfeupt(i,j,k), wombat%feprecip(i,j,k) + print*, wombat%fescaven(i,j,k), wombat%fecoag2det(i,j,k) + print*, " " + endif + enddo; enddo; enddo enddo @@ -2596,6 +2670,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%pprod_gross(i,j,k) = rdtts * wombat%pprod_gross(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] wombat%zprod_gross(i,j,k) = rdtts * wombat%zprod_gross(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] wombat%npp3d(i,j,k) = rdtts * wombat%npp3d(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] + wombat%fesources(i,j,k) = rdtts * wombat%fesources(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] + wombat%fesinks(i,j,k) = rdtts * wombat%fesinks(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] if (wombat%zw(i,j,k) .le. hblt_depth(i,j)) then wombat%adic_intmld(i,j) = wombat%adic_intmld(i,j) + & @@ -2763,6 +2839,14 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_pchl_mu, wombat%pchl_mu, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_phy_kni .gt. 0) & + used = g_send_data(wombat%id_phy_kni, wombat%phy_kni, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_phy_kfe .gt. 0) & + used = g_send_data(wombat%id_phy_kfe, wombat%phy_kfe, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_phy_lpar .gt. 0) & used = g_send_data(wombat%id_phy_lpar, wombat%phy_lpar, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) @@ -2815,6 +2899,14 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_fesinks, wombat%fesinks, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_phy_feupreg .gt. 0) & + used = g_send_data(wombat%id_phy_feupreg, wombat%phy_feupreg, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_phy_fedoreg .gt. 0) & + used = g_send_data(wombat%id_phy_fedoreg, wombat%phy_fedoreg, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_phygrow .gt. 0) & used = g_send_data(wombat%id_phygrow, wombat%phygrow, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) @@ -2847,6 +2939,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_zooslop, wombat%zooslop, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_reminr .gt. 0) & + used = g_send_data(wombat%id_reminr, wombat%reminr, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_detremi .gt. 0) & used = g_send_data(wombat%id_detremi, wombat%detremi, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) @@ -3324,6 +3420,8 @@ subroutine user_allocate_arrays allocate(wombat%phy_mumax(isd:ied, jsd:jed, 1:nk)); wombat%phy_mumax(:,:,:)=0.0 allocate(wombat%phy_mu(isd:ied, jsd:jed, 1:nk)); wombat%phy_mu(:,:,:)=0.0 allocate(wombat%pchl_mu(isd:ied, jsd:jed, 1:nk)); wombat%pchl_mu(:,:,:)=0.0 + allocate(wombat%phy_kni(isd:ied, jsd:jed, 1:nk)); wombat%phy_kni(:,:,:)=0.0 + allocate(wombat%phy_kfe(isd:ied, jsd:jed, 1:nk)); wombat%phy_kfe(:,:,:)=0.0 allocate(wombat%phy_lpar(isd:ied, jsd:jed, 1:nk)); wombat%phy_lpar(:,:,:)=0.0 allocate(wombat%phy_lnit(isd:ied, jsd:jed, 1:nk)); wombat%phy_lnit(:,:,:)=0.0 allocate(wombat%phy_lfer(isd:ied, jsd:jed, 1:nk)); wombat%phy_lfer(:,:,:)=0.0 @@ -3337,6 +3435,8 @@ subroutine user_allocate_arrays allocate(wombat%fecoag2det(isd:ied, jsd:jed, 1:nk)); wombat%fecoag2det(:,:,:)=0.0 allocate(wombat%fesources(isd:ied, jsd:jed, 1:nk)); wombat%fesources(:,:,:)=0.0 allocate(wombat%fesinks(isd:ied, jsd:jed, 1:nk)); wombat%fesinks(:,:,:)=0.0 + allocate(wombat%phy_feupreg(isd:ied, jsd:jed, 1:nk)); wombat%phy_feupreg(:,:,:)=0.0 + allocate(wombat%phy_fedoreg(isd:ied, jsd:jed, 1:nk)); wombat%phy_fedoreg(:,:,:)=0.0 allocate(wombat%phygrow(isd:ied, jsd:jed, 1:nk)); wombat%phygrow(:,:,:)=0.0 allocate(wombat%phyresp(isd:ied, jsd:jed, 1:nk)); wombat%phyresp(:,:,:)=0.0 allocate(wombat%phymort(isd:ied, jsd:jed, 1:nk)); wombat%phymort(:,:,:)=0.0 @@ -3345,6 +3445,7 @@ subroutine user_allocate_arrays allocate(wombat%zoomort(isd:ied, jsd:jed, 1:nk)); wombat%zoomort(:,:,:)=0.0 allocate(wombat%zooexcr(isd:ied, jsd:jed, 1:nk)); wombat%zooexcr(:,:,:)=0.0 allocate(wombat%zooslop(isd:ied, jsd:jed, 1:nk)); wombat%zooslop(:,:,:)=0.0 + allocate(wombat%reminr(isd:ied, jsd:jed, 1:nk)); wombat%reminr(:,:,:)=0.0 allocate(wombat%detremi(isd:ied, jsd:jed, 1:nk)); wombat%detremi(:,:,:)=0.0 allocate(wombat%caldiss(isd:ied, jsd:jed, 1:nk)); wombat%caldiss(:,:,:)=0.0 allocate(wombat%no3_prev(isd:ied, jsd:jed, 1:nk)); wombat%no3_prev(:,:,:)=0.0 @@ -3454,6 +3555,8 @@ subroutine user_deallocate_arrays wombat%phy_mumax, & wombat%phy_mu, & wombat%pchl_mu, & + wombat%phy_kni, & + wombat%phy_kfe, & wombat%phy_lpar, & wombat%phy_lnit, & wombat%phy_lfer, & @@ -3467,6 +3570,8 @@ subroutine user_deallocate_arrays wombat%fecoag2det, & wombat%fesources, & wombat%fesinks, & + wombat%phy_feupreg, & + wombat%phy_fedoreg, & wombat%phygrow, & wombat%phyresp, & wombat%phymort, & @@ -3475,6 +3580,7 @@ subroutine user_deallocate_arrays wombat%zoomort, & wombat%zooexcr, & wombat%zooslop, & + wombat%reminr, & wombat%detremi, & wombat%caldiss, & wombat%no3_prev, & From 6460fc6f2af549bf0636b86f049a29aacb548e67 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Tue, 12 Nov 2024 15:58:15 +1100 Subject: [PATCH 02/23] Added: * Zooplankton grazing of detritus, now we have additional diagnostics * Bug fix of zooplankton excretion on Fe having the Fe2C quota of Zoo, not Phy --- generic_tracers/generic_WOMBATlite.F90 | 176 ++++++++++++++++++------- 1 file changed, 126 insertions(+), 50 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index f8ec816..e29c3db 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -141,6 +141,8 @@ module generic_WOMBATlite zookz, & zoogmax, & zooepsi, & + zprefphy, & + zprefdet, & zoolmor, & zooqmor, & detlrem, & @@ -281,11 +283,14 @@ module generic_WOMBATlite phygrow, & phyresp, & phymort, & - zoograz, & + zoograzphy, & + zoograzdet, & zooresp, & zoomort, & - zooexcr, & - zooslop, & + zooexcrphy, & + zooexcrdet, & + zooslopphy, & + zooslopdet, & reminr, & detremi, & caldiss, & @@ -349,11 +354,14 @@ module generic_WOMBATlite id_phygrow = -1, & id_phyresp = -1, & id_phymort = -1, & - id_zoograz = -1, & + id_zoograzphy = -1, & + id_zoograzdet = -1, & id_zooresp = -1, & id_zoomort = -1, & - id_zooexcr = -1, & - id_zooslop = -1, & + id_zooexcrphy = -1, & + id_zooexcrdet = -1, & + id_zooslopphy = -1, & + id_zooslopdet = -1, & id_reminr = -1, & id_detremi = -1, & id_caldiss = -1, & @@ -849,8 +857,13 @@ subroutine generic_WOMBATlite_register_diag(diag_list) init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'zoograz', 'Grazing rate of zootoplankton', 'h', 'L', 's', 'molC/kg/s', 'f') - wombat%id_zoograz = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + 'zoograzphy', 'Grazing rate of zooplankton on phytoplankton', 'h', 'L', 's', 'molC/kg/s', 'f') + wombat%id_zoograzphy = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'zoograzdet', 'Grazing rate of zooplankton on detritus', 'h', 'L', 's', 'molC/kg/s', 'f') + wombat%id_zoograzdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & @@ -864,13 +877,23 @@ subroutine generic_WOMBATlite_register_diag(diag_list) init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'zooexcr', 'Excretion rate of zootoplankton', 'h', 'L', 's', 'molC/kg/s', 'f') - wombat%id_zooexcr = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + 'zooexcrphy', 'Excretion rate of zooplankton eating phytoplankton', 'h', 'L', 's', 'molC/kg/s', 'f') + wombat%id_zooexcrphy = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'zooexcrdet', 'Excretion rate of zooplankton eating detritus', 'h', 'L', 's', 'molC/kg/s', 'f') + wombat%id_zooexcrdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'zooslop', 'Sloppy feeding of zootoplankton', 'h', 'L', 's', 'molC/kg/s', 'f') - wombat%id_zooslop = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + 'zooslopphy', 'Sloppy feeding of zooplankton on phytoplankton', 'h', 'L', 's', 'molC/kg/s', 'f') + wombat%id_zooslopphy = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'zooslopdet', 'Sloppy feeding of zooplankton on detritus', 'h', 'L', 's', 'molC/kg/s', 'f') + wombat%id_zooslopdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & @@ -1187,6 +1210,14 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('zooepsi', wombat%zooepsi, 0.25/86400.0) + ! Zooplankton preference for phytoplankton [0-1] + !----------------------------------------------------------------------- + call g_tracer_add_param('zprefphy', wombat%zprefphy, 1.0) + + ! Zooplankton preference for detritus [0-1] + !----------------------------------------------------------------------- + call g_tracer_add_param('zprefdet', wombat%zprefdet, 0.25) + ! Zooplankton respiration rate constant [1/s] !----------------------------------------------------------------------- call g_tracer_add_param('zoolmor', wombat%zoolmor, 0.01/86400.0) @@ -1751,7 +1782,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: swpar real :: u_npz, g_npz real :: biophy, biozoo, biodet, biono3, biofer, biocaco3 - real :: biophyfe, biophy1 + real :: biophyfe, biophy1, zooprey real :: fbc real :: no3_bgc_change, caco3_bgc_change real :: epsi = 1.0e-30 @@ -1978,11 +2009,14 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phygrow(:,:,:) = 0.0 wombat%phyresp(:,:,:) = 0.0 wombat%phymort(:,:,:) = 0.0 - wombat%zoograz(:,:,:) = 0.0 + wombat%zoograzphy(:,:,:) = 0.0 + wombat%zoograzdet(:,:,:) = 0.0 wombat%zooresp(:,:,:) = 0.0 wombat%zoomort(:,:,:) = 0.0 - wombat%zooexcr(:,:,:) = 0.0 - wombat%zooslop(:,:,:) = 0.0 + wombat%zooexcrphy(:,:,:) = 0.0 + wombat%zooexcrdet(:,:,:) = 0.0 + wombat%zooslopphy(:,:,:) = 0.0 + wombat%zooslopdet(:,:,:) = 0.0 wombat%reminr(:,:,:) = 0.0 wombat%detremi(:,:,:) = 0.0 wombat%caldiss(:,:,:) = 0.0 @@ -2433,7 +2467,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fecoag2det(i,j,k) = wombat%fecol(i,j,k) * zval / 86400.0 ! Convert the terms back to mol/kg - wombat%feprecip(i,j,k) = wombat%feprecip(i,j,k) * umol_m3_to_mol_kg + wombat%feprecip(i,j,k) = wombat%feprecip(i,j,k) * umol_m3_to_mol_kg * 0.0 wombat%fescaven(i,j,k) = wombat%fescaven(i,j,k) * umol_m3_to_mol_kg * 0.0 wombat%fescadet(i,j,k) = wombat%fescadet(i,j,k) * umol_m3_to_mol_kg * 0.0 wombat%fecoag2det(i,j,k) = wombat%fecoag2det(i,j,k) * umol_m3_to_mol_kg * 0.0 @@ -2450,11 +2484,13 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! + ! reduce linear mortality (respiration losses) of zooplankton when there is low biomass zoo_slmor = biozoo / (biozoo + wombat%zookz) ! Grazing function ! [1/s] - g_npz = wombat%zoogmax * fbc * (wombat%zooepsi * biophy * biophy) / & - (wombat%zoogmax * fbc + (wombat%zooepsi * biophy * biophy)) + zooprey = wombat%zprefphy * biophy + wombat%zprefdet * biodet + g_npz = wombat%zoogmax * fbc * (wombat%zooepsi * zooprey*zooprey) / & + (wombat%zoogmax * fbc + (wombat%zooepsi * zooprey*zooprey)) !-----------------------------------------------------------------------! @@ -2471,19 +2507,27 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phygrow(i,j,k) = 0.0 endif - if (biophy .gt. 1e-3) then - wombat%zoograz(i,j,k) = g_npz * wombat%f_zoo(i,j,k) ! [molC/kg/s] + if (zooprey.gt.1e-3) then + wombat%zoograzphy(i,j,k) = g_npz * wombat%f_zoo(i,j,k) * (wombat%zprefphy*biophy)/zooprey ! [molC/kg/s] + wombat%zoograzdet(i,j,k) = g_npz * wombat%f_zoo(i,j,k) * (wombat%zprefdet*biodet)/zooprey ! [molC/kg/s] + else + wombat%zoograzphy(i,j,k) = 0.0 + wombat%zoograzdet(i,j,k) = 0.0 + endif + wombat%zooexcrphy(i,j,k) = wombat%zoograzphy(i,j,k) * (1.0 - wombat%zooassi)*0.75 + wombat%zooexcrdet(i,j,k) = wombat%zoograzdet(i,j,k) * (1.0 - wombat%zooassi)*0.75 + wombat%zooslopphy(i,j,k) = wombat%zoograzphy(i,j,k) * (1.0 - wombat%zooassi)*0.25 + wombat%zooslopdet(i,j,k) = wombat%zoograzdet(i,j,k) * (1.0 - wombat%zooassi)*0.25 + + if (biophy.gt.1e-3) then wombat%phyresp(i,j,k) = wombat%phylmor * fbc * wombat%f_phy(i,j,k) ! [molC/kg/s] wombat%phymort(i,j,k) = wombat%phyqmor / mmol_m3_to_mol_kg * wombat%f_phy(i,j,k) * wombat%f_phy(i,j,k) ! [molC/kg/s] else - wombat%zoograz(i,j,k) = 0.0 wombat%phyresp(i,j,k) = 0.0 wombat%phymort(i,j,k) = 0.0 endif - wombat%zooexcr(i,j,k) = wombat%zoograz(i,j,k) * (1.0 - wombat%zooassi)*0.75 - wombat%zooslop(i,j,k) = wombat%zoograz(i,j,k) * (1.0 - wombat%zooassi)*0.25 - if (biozoo .gt. 1e-3) then + if (biozoo.gt.1e-3) then wombat%zooresp(i,j,k) = wombat%zoolmor * fbc * wombat%f_zoo(i,j,k) * zoo_slmor ! [molC/kg/s] wombat%zoomort(i,j,k) = wombat%zooqmor / mmol_m3_to_mol_kg * wombat%f_zoo(i,j,k) * wombat%f_zoo(i,j,k) ! [molC/kg/s] else @@ -2518,7 +2562,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%f_no3(i,j,k) = wombat%f_no3(i,j,k) + dtsb * 16./122. * ( & wombat%detremi(i,j,k) + & wombat%zooresp(i,j,k) + & - wombat%zooexcr(i,j,k) + & + wombat%zooexcrphy(i,j,k) + & + wombat%zooexcrdet(i,j,k) + & wombat%phyresp(i,j,k) - & wombat%phygrow(i,j,k) ) @@ -2528,7 +2573,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phygrow(i,j,k) - & wombat%phyresp(i,j,k) - & wombat%phymort(i,j,k) - & - wombat%zoograz(i,j,k) ) + wombat%zoograzphy(i,j,k) ) ! Phytoplankton chlorophyll equation ! [molChl/kg] !----------------------------------------------------------------------- @@ -2536,7 +2581,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%pchl_mu(i,j,k) - & wombat%phyresp(i,j,k) * phy_chlc - & wombat%phymort(i,j,k) * phy_chlc - & - wombat%zoograz(i,j,k) * phy_chlc ) + wombat%zoograzphy(i,j,k) * phy_chlc ) ! Phytoplankton iron equation ! [molFe/kg] !----------------------------------------------------------------------- @@ -2544,7 +2589,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phy_dfeupt(i,j,k) - & wombat%phyresp(i,j,k) * phy_Fe2C - & wombat%phymort(i,j,k) * phy_Fe2C - & - wombat%zoograz(i,j,k) * phy_Fe2C ) + wombat%zoograzphy(i,j,k) * phy_Fe2C ) ! Estimate primary productivity from phytoplankton growth ! [molC/kg/s] wombat%pprod_gross(i,j,k) = wombat%pprod_gross(i,j,k) + dtsb * wombat%phygrow(i,j,k) @@ -2556,35 +2601,41 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Zooplankton equation ! [molC/kg] !----------------------------------------------------------------------- wombat%f_zoo(i,j,k) = wombat%f_zoo(i,j,k) + dtsb * ( & - wombat%zooassi * wombat%zoograz(i,j,k) - & + wombat%zooassi * wombat%zoograzphy(i,j,k) + & + wombat%zooassi * wombat%zoograzdet(i,j,k) - & wombat%zooresp(i,j,k) - & wombat%zoomort(i,j,k) ) ! Zooplankton iron equation ! [molFe/kg] !----------------------------------------------------------------------- wombat%f_zoofe(i,j,k) = wombat%f_zoofe(i,j,k) + dtsb * ( & - wombat%zooassi * wombat%zoograz(i,j,k) * phy_Fe2C - & + wombat%zooassi * wombat%zoograzphy(i,j,k) * phy_Fe2C + & + wombat%zooassi * wombat%zoograzdet(i,j,k) * det_Fe2C - & wombat%zooresp(i,j,k) * zoo_Fe2C - & wombat%zoomort(i,j,k) * zoo_Fe2C ) ! Estimate secondary productivity from zooplankton growth ! [molC/kg/s] wombat%zprod_gross(i,j,k) = wombat%zprod_gross(i,j,k) + dtsb * & - wombat%zooassi * wombat%zoograz(i,j,k) + wombat%zooassi * (wombat%zoograzphy(i,j,k) + wombat%zoograzdet(i,j,k)) ! Detritus equation ! [molC/kg] !----------------------------------------------------------------------- wombat%f_det(i,j,k) = wombat%f_det(i,j,k) + dtsb * ( & - wombat%zooslop(i,j,k) + & + wombat%zooslopphy(i,j,k) + & + wombat%zooslopdet(i,j,k) + & wombat%phymort(i,j,k) + & wombat%zoomort(i,j,k) - & + wombat%zoograzdet(i,j,k) - & wombat%detremi(i,j,k) ) ! Detrital iron equation ! [molFe/kg] !----------------------------------------------------------------------- wombat%f_detfe(i,j,k) = wombat%f_detfe(i,j,k) + dtsb * ( & - wombat%zooslop(i,j,k) * phy_Fe2C + & + wombat%zooslopphy(i,j,k) * phy_Fe2C + & + wombat%zooslopdet(i,j,k) * det_Fe2C + & wombat%phymort(i,j,k) * phy_Fe2C + & wombat%zoomort(i,j,k) * zoo_Fe2C - & + wombat%zoograzdet(i,j,k) * det_Fe2C - & wombat%detremi(i,j,k) * det_Fe2C + & wombat%fescadet(i,j,k) + & wombat%fecoag2det(i,j,k) ) @@ -2595,6 +2646,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%f_o2(i,j,k) = wombat%f_o2(i,j,k) - 172./122. * dtsb * ( & wombat%detremi(i,j,k) + & wombat%zooresp(i,j,k) + & + wombat%zooexcrphy(i,j,k) + & + wombat%zooexcrdet(i,j,k) + & wombat%phyresp(i,j,k) - & wombat%phygrow(i,j,k) ) @@ -2602,7 +2655,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !----------------------------------------------------------------------- ! rjm: 6.2% of POC by default wombat%f_caco3(i,j,k) = wombat%f_caco3(i,j,k) + dtsb * ( & - wombat%zooslop(i,j,k) * wombat%f_inorg + & + wombat%zooslopphy(i,j,k) * wombat%f_inorg + & + wombat%zooslopdet(i,j,k) * wombat%f_inorg + & wombat%phymort(i,j,k) * wombat%f_inorg + & wombat%zoomort(i,j,k) * wombat%f_inorg - & wombat%caldiss(i,j,k) ) @@ -2612,7 +2666,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%f_fe(i,j,k) = wombat%f_fe(i,j,k) + dtsb * ( & wombat%detremi(i,j,k) * det_Fe2C + & wombat%zooresp(i,j,k) * zoo_Fe2C + & - wombat%zooexcr(i,j,k) * zoo_Fe2C + & + wombat%zooexcrphy(i,j,k) * phy_Fe2C + & + wombat%zooexcrdet(i,j,k) * det_Fe2C + & wombat%phyresp(i,j,k) * phy_Fe2C - & wombat%phy_dfeupt(i,j,k) - & wombat%feprecip(i,j,k) - & @@ -2623,7 +2678,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fesources(i,j,k) = wombat%fesources(i,j,k) + dtsb * ( & wombat%detremi(i,j,k) * det_Fe2C + & wombat%zooresp(i,j,k) * zoo_Fe2C + & - wombat%zooexcr(i,j,k) * zoo_Fe2C + & + wombat%zooexcrphy(i,j,k) * phy_Fe2C + & + wombat%zooexcrdet(i,j,k) * det_Fe2C + & wombat%phyresp(i,j,k) * phy_Fe2C) wombat%fesinks(i,j,k) = wombat%fesinks(i,j,k) + dtsb * ( & wombat%phy_dfeupt(i,j,k) + & @@ -2636,7 +2692,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & print*, wombat%feIII(i,j,k), wombat%felig(i,j,k), wombat%fecol(i,j,k) print*, "Fe Sources", wombat%fesources(i,j,k) * rdtts * ts_npzd/tn print*, wombat%detremi(i,j,k)* det_Fe2C - print*, wombat%zooresp(i,j,k)*zoo_Fe2C, wombat%zooexcr(i,j,k)*zoo_Fe2C + print*, wombat%zooresp(i,j,k)*zoo_Fe2C + print*, wombat%zooexcrphy(i,j,k)*phy_Fe2C + print*, wombat%zooexcrdet(i,j,k)*det_Fe2C print*, wombat%phyresp(i,j,k)* phy_Fe2C print*, "Fe Sinks", wombat%fesinks(i,j,k) * rdtts * ts_npzd/tn print*, wombat%phy_dfeupt(i,j,k), wombat%feprecip(i,j,k) @@ -2919,8 +2977,12 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_phymort, wombat%phymort, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_zoograz .gt. 0) & - used = g_send_data(wombat%id_zoograz, wombat%zoograz, model_time, & + if (wombat%id_zoograzphy .gt. 0) & + used = g_send_data(wombat%id_zoograzphy, wombat%zoograzphy, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_zoograzdet .gt. 0) & + used = g_send_data(wombat%id_zoograzdet, wombat%zoograzdet, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) if (wombat%id_zooresp .gt. 0) & @@ -2931,12 +2993,20 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_zoomort, wombat%zoomort, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_zooexcr .gt. 0) & - used = g_send_data(wombat%id_zooexcr, wombat%zooexcr, model_time, & + if (wombat%id_zooexcrphy .gt. 0) & + used = g_send_data(wombat%id_zooexcrphy, wombat%zooexcrphy, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_zooexcrdet .gt. 0) & + used = g_send_data(wombat%id_zooexcrdet, wombat%zooexcrdet, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_zooslopphy .gt. 0) & + used = g_send_data(wombat%id_zooslopphy, wombat%zooslopphy, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_zooslop .gt. 0) & - used = g_send_data(wombat%id_zooslop, wombat%zooslop, model_time, & + if (wombat%id_zooslopdet .gt. 0) & + used = g_send_data(wombat%id_zooslopdet, wombat%zooslopdet, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) if (wombat%id_reminr .gt. 0) & @@ -3440,11 +3510,14 @@ subroutine user_allocate_arrays allocate(wombat%phygrow(isd:ied, jsd:jed, 1:nk)); wombat%phygrow(:,:,:)=0.0 allocate(wombat%phyresp(isd:ied, jsd:jed, 1:nk)); wombat%phyresp(:,:,:)=0.0 allocate(wombat%phymort(isd:ied, jsd:jed, 1:nk)); wombat%phymort(:,:,:)=0.0 - allocate(wombat%zoograz(isd:ied, jsd:jed, 1:nk)); wombat%zoograz(:,:,:)=0.0 + allocate(wombat%zoograzphy(isd:ied, jsd:jed, 1:nk)); wombat%zoograzphy(:,:,:)=0.0 + allocate(wombat%zoograzdet(isd:ied, jsd:jed, 1:nk)); wombat%zoograzdet(:,:,:)=0.0 allocate(wombat%zooresp(isd:ied, jsd:jed, 1:nk)); wombat%zooresp(:,:,:)=0.0 allocate(wombat%zoomort(isd:ied, jsd:jed, 1:nk)); wombat%zoomort(:,:,:)=0.0 - allocate(wombat%zooexcr(isd:ied, jsd:jed, 1:nk)); wombat%zooexcr(:,:,:)=0.0 - allocate(wombat%zooslop(isd:ied, jsd:jed, 1:nk)); wombat%zooslop(:,:,:)=0.0 + allocate(wombat%zooexcrphy(isd:ied, jsd:jed, 1:nk)); wombat%zooexcrphy(:,:,:)=0.0 + allocate(wombat%zooexcrdet(isd:ied, jsd:jed, 1:nk)); wombat%zooexcrdet(:,:,:)=0.0 + allocate(wombat%zooslopphy(isd:ied, jsd:jed, 1:nk)); wombat%zooslopphy(:,:,:)=0.0 + allocate(wombat%zooslopdet(isd:ied, jsd:jed, 1:nk)); wombat%zooslopdet(:,:,:)=0.0 allocate(wombat%reminr(isd:ied, jsd:jed, 1:nk)); wombat%reminr(:,:,:)=0.0 allocate(wombat%detremi(isd:ied, jsd:jed, 1:nk)); wombat%detremi(:,:,:)=0.0 allocate(wombat%caldiss(isd:ied, jsd:jed, 1:nk)); wombat%caldiss(:,:,:)=0.0 @@ -3575,11 +3648,14 @@ subroutine user_deallocate_arrays wombat%phygrow, & wombat%phyresp, & wombat%phymort, & - wombat%zoograz, & + wombat%zoograzphy, & + wombat%zoograzdet, & wombat%zooresp, & wombat%zoomort, & - wombat%zooexcr, & - wombat%zooslop, & + wombat%zooexcrphy, & + wombat%zooexcrdet, & + wombat%zooslopphy, & + wombat%zooslopdet, & wombat%reminr, & wombat%detremi, & wombat%caldiss, & From 58c7bbff718425615d9c32f3257313b351018696 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Thu, 14 Nov 2024 15:17:29 +1100 Subject: [PATCH 03/23] Added: * spatially variable sinking of detritus via "move_vertical" option * hence, removed the spatially complex variations in remineralisation rates * moved DIC and aDIC source/sink calculations into the nested timestep --- generic_tracers/generic_WOMBATlite.F90 | 142 +++++++++++++++-------- generic_tracers/generic_tracer_utils.F90 | 51 ++++---- 2 files changed, 126 insertions(+), 67 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index e29c3db..e801c0b 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -148,6 +148,7 @@ module generic_WOMBATlite detlrem, & detlrem_sed, & wdetbio, & + wdetmax, & phybiot, & caco3lrem, & caco3lrem_sed, & @@ -300,8 +301,6 @@ module generic_WOMBATlite zm real, dimension(:,:,:,:), pointer :: & - p_dic, & - p_adic, & p_alk, & p_o2 @@ -310,6 +309,10 @@ module generic_WOMBATlite p_detfe_sediment, & p_caco3_sediment + real, dimension(:,:,:), pointer :: & + p_wdet, & + p_wdetfe + real, dimension(:,:), pointer :: & p_no3_stf, & p_dic_stf, & @@ -1232,6 +1235,14 @@ subroutine user_add_params ! detlrem/2 call g_tracer_add_param('detlrem', wombat%detlrem, 0.09/86400.0) + ! Detritus sinking rate coefficient [m/s] + !----------------------------------------------------------------------- + call g_tracer_add_param('wdetbio', wombat%wdetbio, 18.0/86400.0) + + ! Detritus maximum sinking rate coefficient [m/s] + !----------------------------------------------------------------------- + call g_tracer_add_param('wdetmax', wombat%wdetmax, 35.0/86400.0) + ! Detritus remineralisation rate constant in sediments [1/s] !----------------------------------------------------------------------- ! This would normally equal detlrem, but we set the default value to be @@ -1446,7 +1457,9 @@ subroutine user_add_tracers(tracer_list) longname = 'Detritus', & units = 'mol/kg', & prog = .true., & - sink_rate = wombat%wdetbio, & + sink_rate = wombat%wdetbio*0.0, & + move_vertical = .true., & + flux_bottom = .false., & btm_reservoir = .true.) ! Detrital iron content @@ -1456,7 +1469,9 @@ subroutine user_add_tracers(tracer_list) longname = 'Detrital iron content', & units = 'mol/kg', & prog = .true., & - sink_rate = wombat%wdetbio, & + sink_rate = wombat%wdetbio*0.0, & + move_vertical = .true., & + flux_bottom = .false., & btm_reservoir = .true.) ! CaCO3 @@ -1467,6 +1482,7 @@ subroutine user_add_tracers(tracer_list) units = 'mol/kg', & prog = .true., & sink_rate = wombat%wcaco3, & + move_vertical = .false., & btm_reservoir = .true.) ! ADIC (Natural + anthropogenic dissolved inorganic carbon) @@ -2325,15 +2341,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & fbc = wombat%bbioh ** (Temp(i,j,k)) ! Variable rates of remineralisation - ! We set the rate of remineralisation to be variable to emulate variations - ! in the sinking speeds of detritus, which in MOM must be constant. - ! Thus, we (1) increase remineralisation in the gyres where bacterial - ! recycling of material is rapid and where large quantities of suspended - ! organics exist, and (2) decrease remineralisation with depth to - ! account for the power-law behaviour of POC in the water column - wombat%reminr(i,j,k) = wombat%detlrem * fbc * & - min(2.0, (wombat%phybiot / biophy1)**0.21) * & - max(0.25, (1. - wombat%zm(i,j,k) / 5000.0)) + wombat%reminr(i,j,k) = wombat%detlrem * fbc !-----------------------------------------------------------------------! @@ -2651,16 +2659,42 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phyresp(i,j,k) - & wombat%phygrow(i,j,k) ) - ! Extra equation for caco3 - alkalinity ! [molCaCO3/kg] + ! Equation for CaCO3 ! [molCaCO3/kg] !----------------------------------------------------------------------- - ! rjm: 6.2% of POC by default wombat%f_caco3(i,j,k) = wombat%f_caco3(i,j,k) + dtsb * ( & wombat%zooslopphy(i,j,k) * wombat%f_inorg + & - wombat%zooslopdet(i,j,k) * wombat%f_inorg + & wombat%phymort(i,j,k) * wombat%f_inorg + & wombat%zoomort(i,j,k) * wombat%f_inorg - & wombat%caldiss(i,j,k) ) + ! Equation for DIC ! [molC/kg] + !----------------------------------------------------------------------- + wombat%f_dic(i,j,k) = wombat%f_dic(i,j,k) + dtsb * ( & + wombat%detremi(i,j,k) + & + wombat%zooresp(i,j,k) + & + wombat%zooexcrphy(i,j,k) + & + wombat%zooexcrdet(i,j,k) + & + wombat%phyresp(i,j,k) - & + wombat%phygrow(i,j,k) - & + wombat%zooslopphy(i,j,k) * wombat%f_inorg - & + wombat%phymort(i,j,k) * wombat%f_inorg - & + wombat%zoomort(i,j,k) * wombat%f_inorg + & + wombat%caldiss(i,j,k) ) + + ! Equation for aDIC ! [molC/kg] + !----------------------------------------------------------------------- + wombat%f_adic(i,j,k) = wombat%f_adic(i,j,k) + dtsb * ( & + wombat%detremi(i,j,k) + & + wombat%zooresp(i,j,k) + & + wombat%zooexcrphy(i,j,k) + & + wombat%zooexcrdet(i,j,k) + & + wombat%phyresp(i,j,k) - & + wombat%phygrow(i,j,k) - & + wombat%zooslopphy(i,j,k) * wombat%f_inorg - & + wombat%phymort(i,j,k) * wombat%f_inorg - & + wombat%zoomort(i,j,k) * wombat%f_inorg + & + wombat%caldiss(i,j,k) ) + ! Extra equation for iron ! [molFe/kg] !----------------------------------------------------------------------- wombat%f_fe(i,j,k) = wombat%f_fe(i,j,k) + dtsb * ( & @@ -2687,20 +2721,20 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fescaven(i,j,k) + & wombat%fecoag2det(i,j,k)) - if (i.eq.150 .and. j.eq.180 .and. k.lt.25) then - print*, k, wombat%zm(i,j,k), wombat%f_fe(i,j,k) - print*, wombat%feIII(i,j,k), wombat%felig(i,j,k), wombat%fecol(i,j,k) - print*, "Fe Sources", wombat%fesources(i,j,k) * rdtts * ts_npzd/tn - print*, wombat%detremi(i,j,k)* det_Fe2C - print*, wombat%zooresp(i,j,k)*zoo_Fe2C - print*, wombat%zooexcrphy(i,j,k)*phy_Fe2C - print*, wombat%zooexcrdet(i,j,k)*det_Fe2C - print*, wombat%phyresp(i,j,k)* phy_Fe2C - print*, "Fe Sinks", wombat%fesinks(i,j,k) * rdtts * ts_npzd/tn - print*, wombat%phy_dfeupt(i,j,k), wombat%feprecip(i,j,k) - print*, wombat%fescaven(i,j,k), wombat%fecoag2det(i,j,k) - print*, " " - endif + ! if (i.eq.150 .and. j.eq.180 .and. k.lt.25) then + ! print*, k, wombat%zm(i,j,k), wombat%f_fe(i,j,k) + ! print*, wombat%feIII(i,j,k), wombat%felig(i,j,k), wombat%fecol(i,j,k) + ! print*, "Fe Sources", wombat%fesources(i,j,k) * rdtts * ts_npzd/tn + ! print*, wombat%detremi(i,j,k)* det_Fe2C + ! print*, wombat%zooresp(i,j,k)*zoo_Fe2C + ! print*, wombat%zooexcrphy(i,j,k)*phy_Fe2C + ! print*, wombat%zooexcrdet(i,j,k)*det_Fe2C + ! print*, wombat%phyresp(i,j,k)* phy_Fe2C + ! print*, "Fe Sinks", wombat%fesinks(i,j,k) * rdtts * ts_npzd/tn + ! print*, wombat%phy_dfeupt(i,j,k), wombat%feprecip(i,j,k) + ! print*, wombat%fescaven(i,j,k), wombat%fecoag2det(i,j,k) + ! print*, " " + ! endif enddo; enddo; enddo enddo @@ -2708,20 +2742,12 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Add biotically induced tendency to biotracers !----------------------------------------------------------------------- ! dts: update prognostic tracers via pointers - call g_tracer_get_pointer(tracer_list, 'dic', 'field', wombat%p_dic) ! [mol/kg] - call g_tracer_get_pointer(tracer_list, 'adic', 'field', wombat%p_adic) ! [mol/kg] call g_tracer_get_pointer(tracer_list, 'alk', 'field', wombat%p_alk) ! [mol/kg] do k = 1,nk; do j = jsc,jec; do i = isc,iec; no3_bgc_change = grid_tmask(i,j,k) * (wombat%f_no3(i,j,k) - wombat%no3_prev(i,j,k)) ! [mol/kg] caco3_bgc_change = grid_tmask(i,j,k) * (wombat%f_caco3(i,j,k) - wombat%caco3_prev(i,j,k)) ! [mol/kg] - wombat%p_dic(i,j,k,tau) = wombat%p_dic(i,j,k,tau) + & - (122./16. * no3_bgc_change - caco3_bgc_change) ! [mol/kg] - - wombat%p_adic(i,j,k,tau) = wombat%p_adic(i,j,k,tau) + & - (122./16. * no3_bgc_change - caco3_bgc_change) ! [mol/kg] - wombat%p_alk(i,j,k,tau) = wombat%p_alk(i,j,k,tau) + & (-2.0 * caco3_bgc_change - no3_bgc_change) ! [mol/kg] @@ -2732,9 +2758,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fesinks(i,j,k) = rdtts * wombat%fesinks(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] if (wombat%zw(i,j,k) .le. hblt_depth(i,j)) then - wombat%adic_intmld(i,j) = wombat%adic_intmld(i,j) + & - wombat%p_adic(i,j,k,tau) * rho_dzt(i,j,k) ! [mol/m2] - wombat%dic_intmld(i,j) = wombat%dic_intmld(i,j) + wombat%p_dic(i,j,k,tau) * rho_dzt(i,j,k) ! [mol/m2] + wombat%adic_intmld(i,j) = wombat%adic_intmld(i,j) + wombat%f_adic(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] + wombat%dic_intmld(i,j) = wombat%dic_intmld(i,j) + wombat%f_dic(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%o2_intmld(i,j) = wombat%o2_intmld(i,j) + wombat%f_o2(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%no3_intmld(i,j) = wombat%no3_intmld(i,j) + wombat%f_no3(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%fe_intmld(i,j) = wombat%fe_intmld(i,j) + wombat%f_fe(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] @@ -2747,9 +2772,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif if (wombat%zw(i,j,k) .le. 100) then - wombat%adic_int100(i,j) = wombat%adic_int100(i,j) + & - wombat%p_adic(i,j,k,tau) * rho_dzt(i,j,k) ! [mol/m2] - wombat%dic_int100(i,j) = wombat%dic_int100(i,j) + wombat%p_dic(i,j,k,tau) * rho_dzt(i,j,k) ! [mol/m2] + wombat%adic_int100(i,j) = wombat%adic_int100(i,j) + wombat%f_adic(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] + wombat%dic_int100(i,j) = wombat%dic_int100(i,j) + wombat%f_dic(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%o2_int100(i,j) = wombat%o2_int100(i,j) + wombat%f_o2(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%no3_int100(i,j) = wombat%no3_int100(i,j) + wombat%f_no3(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%fe_int100(i,j) = wombat%fe_int100(i,j) + wombat%f_fe(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] @@ -2768,8 +2792,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & do j = jsc,jec; do i = isc,iec; if (grid_kmt(i,j) .gt. 0) then k = grid_kmt(i,j) - if (wombat%zw(i,j,k) .le. 200) & - wombat%f_fe(i,j,k)= umol_m3_to_mol_kg * 0.999 ! [mol/kg] + if (wombat%zw(i,j,k) .le. 200) wombat%f_fe(i,j,k)= umol_m3_to_mol_kg * 0.999 ! [mol/kg] endif enddo; enddo @@ -2785,6 +2808,33 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_set_values(tracer_list, 'o2', 'field', wombat%f_o2, isd, jsd, ntau=tau) call g_tracer_set_values(tracer_list, 'caco3', 'field', wombat%f_caco3, isd, jsd, ntau=tau) call g_tracer_set_values(tracer_list, 'fe', 'field', wombat%f_fe, isd, jsd, ntau=tau) + call g_tracer_set_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=tau) + call g_tracer_set_values(tracer_list, 'adic', 'field', wombat%f_adic, isd, jsd, ntau=tau) + + + !----------------------------------------------------------------------- + ! Assign spatially variable vertical movement of tracers + !----------------------------------------------------------------------- + call g_tracer_get_pointer(tracer_list, 'det', 'vmove', wombat%p_wdet) ! [mol/kg] + call g_tracer_get_pointer(tracer_list, 'detfe', 'vmove', wombat%p_wdetfe) ! [mol/kg] + + ! Variable sinking rates of organic detritus (negative for sinking) + do j = jsc,jec; do i = isc,iec; + if (grid_kmt(i,j).gt.0) then + biophy1 = max(epsi, wombat%f_phy(i,j,1) ) / mmol_m3_to_mol_kg ![mmol/m3] + wombat%p_wdet(i,j,:) = -wombat%wdetbio * max(0.01, biophy1 - wombat%phybiot)**(0.21) + wombat%p_wdetfe(i,j,:) = -wombat%wdetbio * max(0.01, biophy1 - wombat%phybiot)**(0.21) + do k=1,nk + wombat%p_wdet(i,j,k) = wombat%p_wdet(i,j,k) + min(0.0, & + wombat%zw(i,j,k)/5000.0 * (-wombat%wdetmax - wombat%p_wdet(i,j,k))) + wombat%p_wdetfe(i,j,k) = wombat%p_wdetfe(i,j,k) + min(0.0, & + wombat%zw(i,j,k)/5000.0 * (-wombat%wdetmax - wombat%p_wdetfe(i,j,k))) + enddo + else + wombat%p_wdet(i,j,:) = 0.0 + wombat%p_wdetfe(i,j,:) = 0.0 + endif + enddo; enddo !----------------------------------------------------------------------- ! Remineralisation of sediment tracers diff --git a/generic_tracers/generic_tracer_utils.F90 b/generic_tracers/generic_tracer_utils.F90 index e00b39f..1eea9a6 100644 --- a/generic_tracers/generic_tracer_utils.F90 +++ b/generic_tracers/generic_tracer_utils.F90 @@ -3181,8 +3181,10 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, nz=g_tracer_com%grid_kmt(i,j) if (g_tracer%move_vertical) then - do k=2,nz; sink_dist(k) = (dt*g_tracer%vmove(i,j,k)) * m_to_H; enddo - endif + do k=2,nz; sink_dist(k) = (dt*g_tracer%vmove(i,j,k)) * m_to_H; enddo + sink_dist(nz+1) = (dt*g_tracer%vmove(i,j,nz)) * m_to_H !PJB [13th Nov 2024] to allow sinking into bottom reservoir + ! PJB... although this doesn't work because "move_vertical==.true." makes "GOLDtridiag==.false." + endif sfc_src = 0.0 ; btm_src = 0.0 ! Find the sinking rates at all interfaces, limiting them if necesary @@ -3316,8 +3318,8 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) GOLDtridiag = .true. IOWtridiag = .false. if (g_tracer%move_vertical) then - GOLDtridiag = .false. - IOWtridiag = .true. + GOLDtridiag = .false. + IOWtridiag = .true. endif eps = 1.e-30 @@ -3415,34 +3417,41 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) kp1 = min(k+1,g_tracer_com%nk) do i=g_tracer_com%isc,g_tracer_com%iec fact1 = dt/dh(i,j,k) - fact2 = rho0*fact1*0.5 - factu = fact1/dhw(i,j,km1) + fact2 = rho0*fact1*0.5 + factu = fact1/dhw(i,j,km1) factl = fact1/dhw(i,j,k) - wabsu = abs(g_tracer%vmove(i,j,km1)) - wposu(i,k) = fact2*(g_tracer%vmove(i,j,km1) + wabsu)*g_tracer_com%grid_tmask(i,j,k) - wnegu(i,k) = fact2*(g_tracer%vmove(i,j,km1) - wabsu)*g_tracer_com%grid_tmask(i,j,k) - wabsl = abs(g_tracer%vmove(i,j,k)) - wposl(i,k) = fact2*(g_tracer%vmove(i,j,k ) + wabsl)*g_tracer_com%grid_tmask(i,j,kp1) - wnegl(i,k) = fact2*(g_tracer%vmove(i,j,k ) - wabsl)*g_tracer_com%grid_tmask(i,j,kp1) - a1(i,k) = dcb(i,j,km1)*factu*g_tracer_com%grid_tmask(i,j,k) - c1(i,k) = dcb(i,j,k) *factl*g_tracer_com%grid_tmask(i,j,kp1) - a(i,k) = -(a1(i,k) - wnegu(i,k)) - c(i,k) = -(c1(i,k) + wposl(i,k)) + wabsu = abs(g_tracer%vmove(i,j,km1)) + wposu(i,k) = fact2*(g_tracer%vmove(i,j,km1) + wabsu)*g_tracer_com%grid_tmask(i,j,k) + wnegu(i,k) = fact2*(g_tracer%vmove(i,j,km1) - wabsu)*g_tracer_com%grid_tmask(i,j,k) + wabsl = abs(g_tracer%vmove(i,j,k)) + wposl(i,k) = fact2*(g_tracer%vmove(i,j,k ) + wabsl)*g_tracer_com%grid_tmask(i,j,kp1) + wnegl(i,k) = fact2*(g_tracer%vmove(i,j,k ) - wabsl)*g_tracer_com%grid_tmask(i,j,kp1) + if (k.eq.g_tracer_com%grid_kmt(i,j) .and. _ALLOCATED(g_tracer%btm_reservoir)) then ! PJB [14th Nov 2024] + wnegl(i,k) = fact2*(g_tracer%vmove(i,j,k ) - wabsl)*g_tracer_com%grid_tmask(i,j,k) + g_tracer%btm_reservoir(i,j) = g_tracer%btm_reservoir(i,j) - & + wnegl(i,k)*g_tracer%field(i,j,k,tau)*dh(i,j,k) + endif + a1(i,k) = dcb(i,j,km1)*factu*g_tracer_com%grid_tmask(i,j,k) + c1(i,k) = dcb(i,j,k) *factl*g_tracer_com%grid_tmask(i,j,kp1) + a(i,k) = -(a1(i,k) - wnegu(i,k)) ! lower diagonal coefs + c(i,k) = -(c1(i,k) + wposl(i,k)) ! upper diagonal coefs f(i,k) = g_tracer%field(i,j,k,tau)*g_tracer_com%grid_tmask(i,j,k) - b(i,k) = 1.0 + a1(i,k) + c1(i,k) - wnegl(i,k) + wposu(i,k) + b(i,k) = 1.0 + a1(i,k) + c1(i,k) - wnegl(i,k) + wposu(i,k) ! main diagonal enddo enddo + ! Set boundary conditions (zero flow out the top and bottom of the water column) do i=g_tracer_com%isc,g_tracer_com%iec a1(i,1) = 0.0 - wnegu(i,1) = 0.0; wposu(i,1) = 0.0 - a(i,1) = 0.0 + wnegu(i,1) = 0.0; wposu(i,1) = 0.0 + a(i,1) = 0.0 c1(i,g_tracer_com%nk) = 0.0 - wposl(i,g_tracer_com%nk) = 0.0; wnegl(i,g_tracer_com%nk) = 0.0 + wposl(i,g_tracer_com%nk) = 0.0 + if (.not. _ALLOCATED(g_tracer%btm_reservoir)) wnegl(i,g_tracer_com%nk) = 0.0 !PJB [14th Nov 2024] c(i,g_tracer_com%nk) = 0.0 b(i,1) = 1.0 + a1(i,1) + c1(i,1) - wnegl(i,1) + wposu(i,1) b(i,g_tracer_com%nk) = 1.0 + a1(i,g_tracer_com%nk) + c1(i,g_tracer_com%nk) & - - wnegl(i,g_tracer_com%nk) + wposu(i,g_tracer_com%nk) + - wnegl(i,g_tracer_com%nk) + wposu(i,g_tracer_com%nk) ! top and bottom b.c. if (_ALLOCATED(g_tracer%stf)) & From 3258e8911ab8a1413416f4b833cdc0a085e7f96c Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Fri, 15 Nov 2024 17:31:16 +1100 Subject: [PATCH 04/23] Trying to determine why Fe-limitation spreads too much across ocean. My changes are: * new light diagnostics and chlorophyll light limitation diagnostic * made zooplankton epsilon (prey capture coefficient) variable from zooepsmin to zooepsmax * slowed dFe uptake by phytoplankton to min of 20% under darkness and nitrogen limitation * made remineralisation of detritus quadratic rather than linear to allow more detrital aggregation in gyres --- generic_tracers/generic_WOMBATlite.F90 | 171 +++++++++++++++---------- 1 file changed, 100 insertions(+), 71 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index e801c0b..b8b51ce 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -140,7 +140,8 @@ module generic_WOMBATlite zooassi, & zookz, & zoogmax, & - zooepsi, & + zooepsmin, & + zooepsmax, & zprefphy, & zprefdet, & zoolmor, & @@ -258,12 +259,14 @@ module generic_WOMBATlite f_fe, & pprod_gross, & zprod_gross, & - radbio3d, & - radmid3d, & + radbio, & + radmid, & + radmld, & npp3d, & phy_mumax, & phy_mu, & pchl_mu, & + pchl_lpar, & phy_kni, & phy_kfe, & phy_lpar, & @@ -333,13 +336,15 @@ module generic_WOMBATlite id_adic_vstf = -1, & id_alk_vstf = -1, & id_light_limit = -1, & - id_radbio3d = -1, & - id_radmid3d = -1, & + id_radbio = -1, & + id_radmid = -1, & + id_radmld = -1, & id_radbio1 = -1, & id_pprod_gross = -1, & id_phy_kni = -1, & id_phy_kfe = -1, & id_phy_lpar = -1, & + id_pchl_lpar = -1, & id_phy_lnit = -1, & id_phy_lfer = -1, & id_phy_dfeupt = -1, & @@ -653,15 +658,21 @@ subroutine generic_WOMBATlite_register_diag(diag_list) init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'radbio3d', 'Photosynthetically active radiation available for phytoplankton growth', & + 'radbio', 'Photosynthetically active radiation available for phytoplankton growth', & 'h', 'L', 's', 'W m-2', 'f') - wombat%id_radbio3d = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + wombat%id_radbio = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'radmid3d', 'Photosynthetically active radiation at centre point of grid cell', & + 'radmid', 'Photosynthetically active radiation at centre point of grid cell', & 'h', 'L', 's', 'W m-2', 'f') - wombat%id_radmid3d = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + wombat%id_radmid = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'radmld', 'Photosynthetically active radiation averaged in mixed layer', & + 'h', 'L', 's', 'W m-2', 'f') + wombat%id_radmld = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & @@ -759,6 +770,11 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_pchl_mu = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & + 'pchl_lpar', 'Limitation of chlorophyll production by light', 'h', 'L', 's', '[0-1]', 'f') + wombat%id_pchl_lpar = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & 'phy_lpar', 'Limitation of phytoplankton by light', 'h', 'L', 's', '[0-1]', 'f') wombat%id_phy_lpar = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & @@ -1151,7 +1167,7 @@ subroutine user_add_params ! Initial slope of P-I curve [(mg Chl m-3)-1 (W m-2)-1] !----------------------------------------------------------------------- - call g_tracer_add_param('alphabio', wombat%alphabio, 2.25) + call g_tracer_add_param('alphabio', wombat%alphabio, 2.5) ! Autotrophy maximum growth rate parameter a [1/s] !----------------------------------------------------------------------- @@ -1209,9 +1225,13 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('zoogmax', wombat%zoogmax, 3.0/86400.0) - ! Zooplankton prey capture rate constant [m6/mmol2/s] + ! Zooplankton minimum prey capture rate constant [m6/mmol2/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zooepsi', wombat%zooepsi, 0.25/86400.0) + call g_tracer_add_param('zooepsmin', wombat%zooepsmin, 0.025/86400.0) + + ! Zooplankton maximum prey capture rate constant [m6/mmol2/s] + !----------------------------------------------------------------------- + call g_tracer_add_param('zooepsmax', wombat%zooepsmax, 0.5/86400.0) ! Zooplankton preference for phytoplankton [0-1] !----------------------------------------------------------------------- @@ -1282,7 +1302,7 @@ subroutine user_add_params ! Scavenging of Fe` onto biogenic particles [(mmolC/m3)-1 d-1] !----------------------------------------------------------------------- - call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 5e-6) + call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 0.005) ! Iron background concentration [umol Fe m^-3] !----------------------------------------------------------------------- @@ -1310,7 +1330,8 @@ subroutine user_add_params ! Global average surface no3 used for virtual flux correction [mol/kg] !----------------------------------------------------------------------- - call g_tracer_add_param('no3_global', wombat%no3_global, 4.512e-06) + !call g_tracer_add_param('no3_global', wombat%no3_global, 4.512e-06) + call g_tracer_add_param('no3_global', wombat%no3_global, 0.0) call g_tracer_end_param_list(package_name) @@ -1807,17 +1828,15 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: par_phy_mldsum, par_z_mldsum real :: chl, zchl, zval, phy_chlc real :: phy_pisl, phy_pisl2 - real :: pchl_pisl, pchl_lpar, pchl_mumin, pchl_muopt + real :: pchl_pisl, pchl_mumin, pchl_muopt real, dimension(:,:), allocatable :: ek_bgr, par_bgr_mid, par_bgr_top - real, dimension(:), allocatable :: par_mid - real, dimension(:,:,:), allocatable :: par_phy, par_phymld real, dimension(4,61) :: zbgr real :: ztemk, fe_keq, fe_par, fe_sfe, fe_tfe, partic real :: fesol1, fesol2, fesol3, fesol4, fesol5, hp, fe3sol real :: biof, biodoc real :: phy_Fe2C, zoo_Fe2C, det_Fe2C real :: phy_minqfe, phy_maxqfe - real :: zoo_slmor + real :: zooeps, zoo_slmor logical :: used call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, & @@ -1999,8 +2018,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%pprod_gross(:,:,:) = 0.0 wombat%zprod_gross(:,:,:) = 0.0 wombat%light_limit(:,:) = 0.0 - wombat%radbio3d(:,:,:) = 0.0 - wombat%radmid3d(:,:,:) = 0.0 + wombat%radbio(:,:,:) = 0.0 + wombat%radmid(:,:,:) = 0.0 + wombat%radmld(:,:,:) = 0.0 wombat%npp3d(:,:,:) = 0.0 wombat%phy_mumax(:,:,:) = 0.0 wombat%phy_mu(:,:,:) = 0.0 @@ -2008,6 +2028,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phy_kni(:,:,:) = 0.0 wombat%phy_kfe(:,:,:) = 0.0 wombat%phy_lpar(:,:,:) = 0.0 + wombat%pchl_lpar(:,:,:) = 0.0 wombat%phy_lnit(:,:,:) = 0.0 wombat%phy_lfer(:,:,:) = 0.0 wombat%phy_dfeupt(:,:,:) = 0.0 @@ -2069,9 +2090,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & allocate(ek_bgr(nk,3)); ek_bgr(:,:)=0.0 allocate(par_bgr_mid(nk,3)); par_bgr_mid(:,:)=0.0 allocate(par_bgr_top(nk,3)); par_bgr_top(:,:)=0.0 - allocate(par_mid(nk)); par_mid(:)=0.0 - allocate(par_phy(isc:iec, jsc:jec, nk)); par_phy(:,:,:)=0.0 - allocate(par_phymld(isc:iec, jsc:jec, nk)); par_phymld(:,:,:)=0.0 ! Set the maximum index for euphotic depth ! dts: in WOMBAT v3, kmeuph and k100 are integers but here they are arrays since zw @@ -2171,11 +2189,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & par_bgr_top(:,:) = 0.0 par_bgr_mid(:,:) = 0.0 - par_mid(:) = 0.0 do k = 1,grid_kmt(i,j) !{ - ! chlorophyll concentration conversion from mol/kg --> mg/m3 + ! chlorophyll concentration conversion from mol/kg --> mg/m3 for look-up table chl = wombat%f_pchl(i,j,k) * 12.0 / mmol_m3_to_mol_kg ! Attenuation coefficients given chlorophyll concentration @@ -2205,7 +2222,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif ! Light attenuation at mid point of the cells - par_mid(k) = par_bgr_mid(k,1) + par_bgr_mid(k,2) + par_bgr_mid(k,3) + wombat%radmid(i,j,k) = par_bgr_mid(k,1) + par_bgr_mid(k,2) + par_bgr_mid(k,3) enddo !} k @@ -2219,26 +2236,26 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & if (swpar.gt.0.0) then ! Euphotic zone - if (par_mid(k).gt.(swpar*0.01) .and. par_mid(k).gt.0.01) then + if (wombat%radmid(i,j,k).gt.(swpar*0.01) .and. wombat%radmid(i,j,k).gt.0.01) then wombat%zeuphot(i,j) = wombat%zw(i,j,k) endif ! Light attenuation mean over the grid cells (Eq. 19 of Baird et al., 2020 GMD) if (k.lt.grid_kmt(i,j)) then - par_phy(i,j,k) = ((par_bgr_top(k,1) - par_bgr_top(k+1,1)) / ek_bgr(k,1)) + & - ((par_bgr_top(k,2) - par_bgr_top(k+1,2)) / ek_bgr(k,2)) + & - ((par_bgr_top(k,3) - par_bgr_top(k+1,3)) / ek_bgr(k,3)) + wombat%radbio(i,j,k) = ((par_bgr_top(k,1) - par_bgr_top(k+1,1)) / ek_bgr(k,1)) + & + ((par_bgr_top(k,2) - par_bgr_top(k+1,2)) / ek_bgr(k,2)) + & + ((par_bgr_top(k,3) - par_bgr_top(k+1,3)) / ek_bgr(k,3)) else - par_phy(i,j,k) = ((par_bgr_top(k,1) - par_bgr_top(k,1)*exp(-ek_bgr(k,1))) / ek_bgr(k,1)) + & - ((par_bgr_top(k,2) - par_bgr_top(k,2)*exp(-ek_bgr(k,2))) / ek_bgr(k,2)) + & - ((par_bgr_top(k,3) - par_bgr_top(k,3)*exp(-ek_bgr(k,3))) / ek_bgr(k,3)) + wombat%radbio(i,j,k) = ((par_bgr_top(k,1) - par_bgr_top(k,1)*exp(-ek_bgr(k,1))) / ek_bgr(k,1)) + & + ((par_bgr_top(k,2) - par_bgr_top(k,2)*exp(-ek_bgr(k,2))) / ek_bgr(k,2)) + & + ((par_bgr_top(k,3) - par_bgr_top(k,3)*exp(-ek_bgr(k,3))) / ek_bgr(k,3)) endif else - par_phy(i,j,k) = 0.0 + wombat%radbio(i,j,k) = 0.0 endif ! Integrated light field in the mixed layer if (wombat%zw(i,j,k).le.hblt_depth(i,j)) then - par_phy_mldsum = par_phy_mldsum + par_phy(i,j,k) * dzt(i,j,k) + par_phy_mldsum = par_phy_mldsum + wombat%radbio(i,j,k) * dzt(i,j,k) par_z_mldsum = par_z_mldsum + dzt(i,j,k) endif @@ -2254,15 +2271,11 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Calculate average light level in the mixed layer if (wombat%zw(i,j,k).le.hblt_depth(i,j)) then zval = 1.0/(par_z_mldsum + epsi) - par_phymld(i,j,k) = par_phy_mldsum * zval + wombat%radmld(i,j,k) = par_phy_mldsum * zval else - par_phymld(i,j,k) = par_phy(i,j,k) + wombat%radmld(i,j,k) = wombat%radbio(i,j,k) endif - ! Save total PAR to radbio and radmid arrays for diagnostic output - wombat%radbio3d(i,j,k) = par_phy(i,j,k) - wombat%radmid3d(i,j,k) = par_mid(k) - ! Temperature-dependent maximum growth rate (Eppley curve) wombat%phy_mumax(i,j,k) = wombat%abioa * wombat%bbioa ** (Temp(i,j,k)) ! [1/s] @@ -2359,7 +2372,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & phy_pisl = max(wombat%alphabio * phy_chlc, wombat%alphabio * wombat%phyminqc) phy_pisl2 = phy_pisl / ( (1. + wombat%phylmor*86400.0 * fbc) ) ! add daylength estimate here - wombat%phy_lpar(i,j,k) = (1. - exp(-phy_pisl2 * par_phy(i,j,k))) * wombat%phy_leup(i,j) + wombat%phy_lpar(i,j,k) = (1. - exp(-phy_pisl2 * wombat%radbio(i,j,k))) * wombat%phy_leup(i,j) wombat%phy_mu(i,j,k) = wombat%phy_mumax(i,j,k) * wombat%phy_lpar(i,j,k) * & min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k)) @@ -2385,14 +2398,14 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & pchl_pisl = phy_pisl / ( wombat%phy_mumax(i,j,k) * 86400.0 * & (1. - min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k))) + epsi ) - pchl_lpar = (1. - exp(-pchl_pisl * par_phymld(i,j,k))) * wombat%phy_leup(i,j) + wombat%pchl_lpar(i,j,k) = (1. - exp(-pchl_pisl * wombat%radmld(i,j,k))) * wombat%phy_leup(i,j) pchl_mumin = wombat%phyminqc * wombat%phy_mu(i,j,k) * biophy * 12.0 ![mg/m3/s] pchl_muopt = wombat%phyoptqc * wombat%phy_mu(i,j,k) * biophy * 12.0 ![mg/m3/s] - wombat%pchl_mu(i,j,k) = (pchl_muopt - pchl_mumin) * pchl_lpar * & - min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k)) - if ( (phy_pisl * par_phymld(i,j,k)) .gt. 0.0 ) then + wombat%pchl_mu(i,j,k) = (pchl_muopt - pchl_mumin) * wombat%pchl_lpar(i,j,k) * & + min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k)) + if ( (phy_pisl * wombat%radmld(i,j,k)) .gt. 0.0 ) then wombat%pchl_mu(i,j,k) = pchl_mumin + wombat%pchl_mu(i,j,k) / & - (phy_pisl * par_phymld(i,j,k)) + (phy_pisl * wombat%radmld(i,j,k)) endif wombat%pchl_mu(i,j,k) = wombat%pchl_mu(i,j,k) / 12.0 * mmol_m3_to_mol_kg ![mol/kg/s] @@ -2407,17 +2420,18 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! 1. Maximum iron content of phytoplankton cell ! 2. Ensure that dFe uptake increases or decreases in response to cell quota - ! 3. Iron uptake of phytoplankton + ! 3. Iron uptake of phytoplankton (slowed to 20% at night and when N is limiting) phy_maxqfe = biophy * wombat%phymaxqf !mmol Fe / m3 wombat%phy_feupreg(i,j,k) = (4.0 - 4.5 * wombat%phy_lfer(i,j,k) / & (wombat%phy_lfer(i,j,k) + 0.5) ) wombat%phy_fedoreg(i,j,k) = max(0.0, (1.0 - biophyfe/phy_maxqfe) / & abs(1.05 - biophyfe/phy_maxqfe) ) - wombat%phy_dfeupt(i,j,k) = (biophy * wombat%phy_mumax(i,j,k) * wombat%phymaxqf * & + wombat%phy_dfeupt(i,j,k) = (wombat%phy_mumax(i,j,k) * wombat%phymaxqf * & + max(0.2, wombat%phy_lpar(i,j,k) * wombat%phy_lnit(i,j,k)) * & biofer / (biofer + wombat%phy_kfe(i,j,k)) * & wombat%phy_feupreg(i,j,k) * & - wombat%phy_fedoreg(i,j,k)) * mmol_m3_to_mol_kg + wombat%phy_fedoreg(i,j,k) * biophy) * mmol_m3_to_mol_kg !-----------------------------------------------------------------------! @@ -2447,7 +2461,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Determine equilibriuim fractionation of the remain dFe (non-colloidal fraction) into Fe' and L-Fe fe_keq = 10**( 17.27 - 1565.7 / ztemk ) * 1e-9 ! Temperature reduces solubility - fe_par = 4.77e-7 * wombat%radbio3d(i,j,k) * 0.5 / 10**(-6.3) ! Light increases solubility + fe_par = 4.77e-7 * wombat%radbio(i,j,k) * 0.5 / 10**(-6.3) ! Light increases solubility fe_sfe = max(0.0, biofer - wombat%fecol(i,j,k)) fe_tfe = (1.0 + fe_par) * fe_sfe wombat%feIII(i,j,k) = ( -( 1. + wombat%ligand * fe_keq + fe_par - fe_sfe * fe_keq ) & @@ -2460,7 +2474,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Scavenging of Fe` onto biogenic particles partic = (biodet + biocaco3) - wombat%fescaven(i,j,k) = wombat%feIII(i,j,k) * (3e-8 + wombat%kscav_dfe * partic) / 86400.0 + wombat%fescaven(i,j,k) = wombat%feIII(i,j,k) * (3e-5 + wombat%kscav_dfe * partic) / 86400.0 wombat%fescadet(i,j,k) = wombat%fescaven(i,j,k) * biodet / (partic+epsi) ! Coagulation of colloidal Fe (umol/m3) to form sinking particles (mmol/m3) @@ -2475,10 +2489,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fecoag2det(i,j,k) = wombat%fecol(i,j,k) * zval / 86400.0 ! Convert the terms back to mol/kg - wombat%feprecip(i,j,k) = wombat%feprecip(i,j,k) * umol_m3_to_mol_kg * 0.0 - wombat%fescaven(i,j,k) = wombat%fescaven(i,j,k) * umol_m3_to_mol_kg * 0.0 - wombat%fescadet(i,j,k) = wombat%fescadet(i,j,k) * umol_m3_to_mol_kg * 0.0 - wombat%fecoag2det(i,j,k) = wombat%fecoag2det(i,j,k) * umol_m3_to_mol_kg * 0.0 + wombat%feprecip(i,j,k) = wombat%feprecip(i,j,k) * umol_m3_to_mol_kg + wombat%fescaven(i,j,k) = wombat%fescaven(i,j,k) * umol_m3_to_mol_kg + wombat%fescadet(i,j,k) = wombat%fescadet(i,j,k) * umol_m3_to_mol_kg + wombat%fecoag2det(i,j,k) = wombat%fecoag2det(i,j,k) * umol_m3_to_mol_kg wombat%feIII(i,j,k) = wombat%feIII(i,j,k) * umol_m3_to_mol_kg wombat%felig(i,j,k) = wombat%felig(i,j,k) * umol_m3_to_mol_kg wombat%fecol(i,j,k) = wombat%fecol(i,j,k) * umol_m3_to_mol_kg @@ -2497,8 +2511,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Grazing function ! [1/s] zooprey = wombat%zprefphy * biophy + wombat%zprefdet * biodet - g_npz = wombat%zoogmax * fbc * (wombat%zooepsi * zooprey*zooprey) / & - (wombat%zoogmax * fbc + (wombat%zooepsi * zooprey*zooprey)) + zooeps = wombat%zooepsmin + (wombat%zooepsmax - wombat%zooepsmin) / & + (1. + exp(5.*(biophy - 2.*wombat%phybiot))) + g_npz = wombat%zoogmax * fbc * (zooeps * zooprey*zooprey) / & + (wombat%zoogmax * fbc + (zooeps * zooprey*zooprey)) !-----------------------------------------------------------------------! @@ -2544,8 +2560,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif if (wombat%f_det(i,j,k) .gt. epsi) then - wombat%detremi(i,j,k) = wombat%reminr(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] - if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = 0.5 * wombat%detremi(i,j,k) ! reduce decay below 180m + wombat%detremi(i,j,k) = wombat%reminr(i,j,k) / mmol_m3_to_mol_kg * & + wombat%f_det(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] + ! if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = 0.5 * wombat%detremi(i,j,k) ! reduce decay below 180m else wombat%detremi(i,j,k) = 0.0 endif @@ -2768,7 +2785,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%pprod_gross_intmld(i,j) = wombat%pprod_gross_intmld(i,j) + & wombat%pprod_gross(i,j,k) * rho_dzt(i,j,k) ! [mol/m2/s] wombat%npp_intmld(i,j) = wombat%npp_intmld(i,j) + wombat%npp3d(i,j,k) * rho_dzt(i,j,k) ! [mol/m2/s] - wombat%radbio_intmld(i,j) = wombat%radbio_intmld(i,j) + wombat%radbio3d(i,j,k) * dzt(i,j,k) ! [W/m] + wombat%radbio_intmld(i,j) = wombat%radbio_intmld(i,j) + wombat%radbio(i,j,k) * dzt(i,j,k) ! [W/m] endif if (wombat%zw(i,j,k) .le. 100) then @@ -2782,7 +2799,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%pprod_gross_int100(i,j) = wombat%pprod_gross_int100(i,j) + & wombat%pprod_gross(i,j,k) * rho_dzt(i,j,k) ! [mol/m2/s] wombat%npp_int100(i,j) = wombat%npp_int100(i,j) + wombat%npp3d(i,j,k) * rho_dzt(i,j,k) ! [mol/m2/s] - wombat%radbio_int100(i,j) = wombat%radbio_int100(i,j) + wombat%radbio3d(i,j,k) * dzt(i,j,k) ! [W/m] + wombat%radbio_int100(i,j) = wombat%radbio_int100(i,j) + wombat%radbio(i,j,k) * dzt(i,j,k) ! [W/m] endif enddo; enddo; enddo @@ -2919,16 +2936,20 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_light_limit, wombat%light_limit, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_radbio3d .gt. 0) & - used = g_send_data(wombat%id_radbio3d, wombat%radbio3d, model_time, & + if (wombat%id_radbio .gt. 0) & + used = g_send_data(wombat%id_radbio, wombat%radbio, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_radmid3d .gt. 0) & - used = g_send_data(wombat%id_radmid3d, wombat%radmid3d, model_time, & + if (wombat%id_radmid .gt. 0) & + used = g_send_data(wombat%id_radmid, wombat%radmid, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_radmld .gt. 0) & + used = g_send_data(wombat%id_radmld, wombat%radmld, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) if (wombat%id_radbio1 .gt. 0) & - used = g_send_data(wombat%id_radbio1, wombat%radbio3d(:,:,1), model_time, & + used = g_send_data(wombat%id_radbio1, wombat%radbio(:,:,1), model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) if (wombat%id_pprod_gross .gt. 0) & @@ -2947,6 +2968,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_pchl_mu, wombat%pchl_mu, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_pchl_lpar .gt. 0) & + used = g_send_data(wombat%id_pchl_lpar, wombat%pchl_lpar, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_phy_kni .gt. 0) & used = g_send_data(wombat%id_phy_kni, wombat%phy_kni, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) @@ -3527,8 +3552,9 @@ subroutine user_allocate_arrays allocate(wombat%b_alk(isd:ied, jsd:jed)); wombat%b_alk(:,:)=0.0 allocate(wombat%light_limit(isd:ied, jsd:jed)); wombat%light_limit(:,:)=0.0 - allocate(wombat%radbio3d(isd:ied, jsd:jed, 1:nk)); wombat%radbio3d(:,:,:)=0.0 - allocate(wombat%radmid3d(isd:ied, jsd:jed, 1:nk)); wombat%radmid3d(:,:,:)=0.0 + allocate(wombat%radbio(isd:ied, jsd:jed, 1:nk)); wombat%radbio(:,:,:)=0.0 + allocate(wombat%radmid(isd:ied, jsd:jed, 1:nk)); wombat%radmid(:,:,:)=0.0 + allocate(wombat%radmld(isd:ied, jsd:jed, 1:nk)); wombat%radmld(:,:,:)=0.0 allocate(wombat%pprod_gross(isd:ied, jsd:jed, 1:nk)); wombat%pprod_gross(:,:,:)=0.0 allocate(wombat%pprod_gross_2d(isd:ied, jsd:jed)); wombat%pprod_gross_2d(:,:)=0.0 allocate(wombat%zprod_gross(isd:ied, jsd:jed, 1:nk)); wombat%zprod_gross(:,:,:)=0.0 @@ -3540,6 +3566,7 @@ subroutine user_allocate_arrays allocate(wombat%phy_mumax(isd:ied, jsd:jed, 1:nk)); wombat%phy_mumax(:,:,:)=0.0 allocate(wombat%phy_mu(isd:ied, jsd:jed, 1:nk)); wombat%phy_mu(:,:,:)=0.0 allocate(wombat%pchl_mu(isd:ied, jsd:jed, 1:nk)); wombat%pchl_mu(:,:,:)=0.0 + allocate(wombat%pchl_lpar(isd:ied, jsd:jed, 1:nk)); wombat%pchl_lpar(:,:,:)=0.0 allocate(wombat%phy_kni(isd:ied, jsd:jed, 1:nk)); wombat%phy_kni(:,:,:)=0.0 allocate(wombat%phy_kfe(isd:ied, jsd:jed, 1:nk)); wombat%phy_kfe(:,:,:)=0.0 allocate(wombat%phy_lpar(isd:ied, jsd:jed, 1:nk)); wombat%phy_lpar(:,:,:)=0.0 @@ -3665,8 +3692,9 @@ subroutine user_deallocate_arrays deallocate( & wombat%light_limit, & - wombat%radbio3d, & - wombat%radmid3d, & + wombat%radbio, & + wombat%radmid, & + wombat%radmld, & wombat%pprod_gross, & wombat%pprod_gross_2d, & wombat%zprod_gross, & @@ -3678,6 +3706,7 @@ subroutine user_deallocate_arrays wombat%phy_mumax, & wombat%phy_mu, & wombat%pchl_mu, & + wombat%pchl_lpar, & wombat%phy_kni, & wombat%phy_kfe, & wombat%phy_lpar, & From cdfe9192ce17bf362cd78135302ac4caa1872cd3 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Tue, 26 Nov 2024 13:31:38 +1100 Subject: [PATCH 05/23] Figured out why dFe was becoming so limiting: * Missed the retuning of dFe back to a minimum concentration at every timestep. This happens under "Additional operations on dissolved iron" Also took the opportunity to: * Add N and C conservation of mass checks * remove some unnecessary print statements * reduce dFe scavenging rates * Apply limitations to dFe uptake at night and when N is limiting * increase zooplankton quadratic mortality but halve their linear mortality * also reduced phytoplankton linear and quadratic mortality --- generic_tracers/generic_WOMBATlite.F90 | 109 ++++++++++++++++--------- 1 file changed, 69 insertions(+), 40 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index b8b51ce..7a4ec65 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -1207,11 +1207,11 @@ subroutine user_add_params ! Phytoplankton linear mortality rate constant [1/s] !----------------------------------------------------------------------- - call g_tracer_add_param('phylmor', wombat%phylmor, 0.01/86400.0) + call g_tracer_add_param('phylmor', wombat%phylmor, 0.0025/86400.0) ! Phytoplankton quadratic mortality rate constant [m3/mmolN/s] !----------------------------------------------------------------------- - call g_tracer_add_param('phyqmor', wombat%phyqmor, 0.05/86400.0) + call g_tracer_add_param('phyqmor', wombat%phyqmor, 0.025/86400.0) ! Zooplankton assimilation efficiency [1] !----------------------------------------------------------------------- @@ -1243,11 +1243,11 @@ subroutine user_add_params ! Zooplankton respiration rate constant [1/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zoolmor', wombat%zoolmor, 0.01/86400.0) + call g_tracer_add_param('zoolmor', wombat%zoolmor, 0.005/86400.0) ! Zooplankton quadratic mortality rate constant [m3/mmolN/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zooqmor', wombat%zooqmor, 0.5/86400.0) + call g_tracer_add_param('zooqmor', wombat%zooqmor, 0.9/86400.0) ! Detritus remineralisation rate constant for <180 m; value for >=180m is half of this [1/s] !----------------------------------------------------------------------- @@ -1261,7 +1261,7 @@ subroutine user_add_params ! Detritus maximum sinking rate coefficient [m/s] !----------------------------------------------------------------------- - call g_tracer_add_param('wdetmax', wombat%wdetmax, 35.0/86400.0) + call g_tracer_add_param('wdetmax', wombat%wdetmax, 36.0/86400.0) ! Detritus remineralisation rate constant in sediments [1/s] !----------------------------------------------------------------------- @@ -1302,7 +1302,7 @@ subroutine user_add_params ! Scavenging of Fe` onto biogenic particles [(mmolC/m3)-1 d-1] !----------------------------------------------------------------------- - call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 0.005) + call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 5e-5) ! Iron background concentration [umol Fe m^-3] !----------------------------------------------------------------------- @@ -1330,8 +1330,7 @@ subroutine user_add_params ! Global average surface no3 used for virtual flux correction [mol/kg] !----------------------------------------------------------------------- - !call g_tracer_add_param('no3_global', wombat%no3_global, 4.512e-06) - call g_tracer_add_param('no3_global', wombat%no3_global, 0.0) + call g_tracer_add_param('no3_global', wombat%no3_global, 4.512e-06) call g_tracer_end_param_list(package_name) @@ -1833,10 +1832,11 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real, dimension(4,61) :: zbgr real :: ztemk, fe_keq, fe_par, fe_sfe, fe_tfe, partic real :: fesol1, fesol2, fesol3, fesol4, fesol5, hp, fe3sol - real :: biof, biodoc + real :: biof, biodoc, zno3, zfermin real :: phy_Fe2C, zoo_Fe2C, det_Fe2C real :: phy_minqfe, phy_maxqfe real :: zooeps, zoo_slmor + real, dimension(:,:,:,:), allocatable :: n_pools, c_pools logical :: used call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, & @@ -2090,6 +2090,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & allocate(ek_bgr(nk,3)); ek_bgr(:,:)=0.0 allocate(par_bgr_mid(nk,3)); par_bgr_mid(:,:)=0.0 allocate(par_bgr_top(nk,3)); par_bgr_top(:,:)=0.0 + allocate(n_pools(isc:iec,jsc:jec,nk,2)); n_pools(:,:,:,:)=0.0 + allocate(c_pools(isc:iec,jsc:jec,nk,2)); c_pools(:,:,:,:)=0.0 ! Set the maximum index for euphotic depth ! dts: in WOMBAT v3, kmeuph and k100 are integers but here they are arrays since zw @@ -2159,6 +2161,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! 8. Mortality scalings and grazing ! ! 9. Sources and sinks ! ! 10. Tracer tendencies ! + ! 11. Check for conservation by ecosystem component ! ! ! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! @@ -2288,21 +2291,18 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%export_inorg(i,j) = (wombat%Rho_0 * wombat%wcaco3) * wombat%f_caco3(i,j,k) ! [mol/m2/s] enddo; enddo - - !----------------------------------------------------------------------- - ! Calculate source terms using Euler forward timestepping - !----------------------------------------------------------------------- - ! chd: This is the NPZD model: - ! (P: phytoplankton, Z: Zooplankton, N: Nitrate and D: Detritus) - ! dP/dt = u(N,Temp.,Light) P - p_P P - g(P) P Z - ! dZ/dt = a g(P) P Z - d Z - p_Z Z^2 - ! dN/dt = r D + d Z - u(N,Temp.,Light) P [ + r_d DOC ] - ! dD/dt = (1-s)[ (1-a) g(P) P Z + p_P P + p_Z Z^2] -r D + w_D dD/dz - wombat%no3_prev(:,:,:) = wombat%f_no3(:,:,:) wombat%caco3_prev(:,:,:) = wombat%f_caco3(:,:,:) + ! Arrays for assessing conservation of mass within ecosystem component + n_pools(:,:,:,:) = 0.0 + c_pools(:,:,:,:) = 0.0 + do tn = 1,ts_npzd + + n_pools(:,:,:,2) = n_pools(:,:,:,1) + c_pools(:,:,:,2) = c_pools(:,:,:,1) + do k = 1,nk; do j = jsc,jec; do i = isc,iec; ! Initialise some values and ratios (put into nicer units than mol/kg) @@ -2332,7 +2332,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! 2. Apply variable K to set limitation term wombat%phy_kni(i,j,k) = wombat%phykn * max(0.1, max(0.0, (biophy-wombat%phybiot))**0.37) - wombat%phy_kfe(i,j,k) = wombat%phykf * max(0.5, max(0.0, (biophy-wombat%phybiot))**0.37) + wombat%phy_kfe(i,j,k) = wombat%phykf * max(0.1, max(0.0, (biophy-wombat%phybiot))**0.37) ! Nitrogen limitation (currently Michaelis-Menten term) wombat%phy_lnit(i,j,k) = biono3 / (biono3 + wombat%phy_kni(i,j,k)) ! Iron limitation (Quota model, constants from Flynn & Hipkin 1999) @@ -2420,7 +2420,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! 1. Maximum iron content of phytoplankton cell ! 2. Ensure that dFe uptake increases or decreases in response to cell quota - ! 3. Iron uptake of phytoplankton (slowed to 20% at night and when N is limiting) + ! 3. Iron uptake of phytoplankton (reduced to 20% at night and when N is limiting) phy_maxqfe = biophy * wombat%phymaxqf !mmol Fe / m3 wombat%phy_feupreg(i,j,k) = (4.0 - 4.5 * wombat%phy_lfer(i,j,k) / & @@ -2474,7 +2474,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Scavenging of Fe` onto biogenic particles partic = (biodet + biocaco3) - wombat%fescaven(i,j,k) = wombat%feIII(i,j,k) * (3e-5 + wombat%kscav_dfe * partic) / 86400.0 + wombat%fescaven(i,j,k) = wombat%feIII(i,j,k) * (3e-8 + wombat%kscav_dfe * partic) / 86400.0 wombat%fescadet(i,j,k) = wombat%fescaven(i,j,k) * biodet / (partic+epsi) ! Coagulation of colloidal Fe (umol/m3) to form sinking particles (mmol/m3) @@ -2563,6 +2563,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%detremi(i,j,k) = wombat%reminr(i,j,k) / mmol_m3_to_mol_kg * & wombat%f_det(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] ! if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = 0.5 * wombat%detremi(i,j,k) ! reduce decay below 180m + ! wombat%detremi(i,j,k) = wombat%reminr(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] + ! if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = 0.5 * wombat%detremi(i,j,k) ! reduce decay below 180m else wombat%detremi(i,j,k) = 0.0 endif @@ -2738,20 +2740,41 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fescaven(i,j,k) + & wombat%fecoag2det(i,j,k)) - ! if (i.eq.150 .and. j.eq.180 .and. k.lt.25) then - ! print*, k, wombat%zm(i,j,k), wombat%f_fe(i,j,k) - ! print*, wombat%feIII(i,j,k), wombat%felig(i,j,k), wombat%fecol(i,j,k) - ! print*, "Fe Sources", wombat%fesources(i,j,k) * rdtts * ts_npzd/tn - ! print*, wombat%detremi(i,j,k)* det_Fe2C - ! print*, wombat%zooresp(i,j,k)*zoo_Fe2C - ! print*, wombat%zooexcrphy(i,j,k)*phy_Fe2C - ! print*, wombat%zooexcrdet(i,j,k)*det_Fe2C - ! print*, wombat%phyresp(i,j,k)* phy_Fe2C - ! print*, "Fe Sinks", wombat%fesinks(i,j,k) * rdtts * ts_npzd/tn - ! print*, wombat%phy_dfeupt(i,j,k), wombat%feprecip(i,j,k) - ! print*, wombat%fescaven(i,j,k), wombat%fecoag2det(i,j,k) - ! print*, " " - ! endif + + !-----------------------------------------------------------------------! + !-----------------------------------------------------------------------! + !-----------------------------------------------------------------------! + ! [Step 11] Check for conservation of mass by ecosystem component ! + !-----------------------------------------------------------------------! + !-----------------------------------------------------------------------! + !-----------------------------------------------------------------------! + + n_pools(i,j,k,1) = wombat%f_no3(i,j,k) + (wombat%f_phy(i,j,k) + wombat%f_det(i,j,k) + & + wombat%f_zoo(i,j,k)) * 16/122.0 + c_pools(i,j,k,1) = wombat%f_dic(i,j,k) + wombat%f_phy(i,j,k) + wombat%f_det(i,j,k) + & + wombat%f_zoo(i,j,k) + wombat%f_caco3(i,j,k) + + if (tn.gt.1) then + if (abs(n_pools(i,j,k,2) - n_pools(i,j,k,1)).gt.1e-15) then + print*, "Error: Ecosystem model is not conserving nitrogen" + print*, " Longitude index = ", i + print*, " Latitude index = ", j + print*, " Depth index and value = ", k, wombat%zm(i,j,k) + print*, " " + print*, " Biological N budget (molN/kg) at two timesteps ", n_pools(i,j,k,:) + stop + endif + if (abs(c_pools(i,j,k,2) - c_pools(i,j,k,1)).gt.1e-15) then + print*, "Error: Ecosystem model is not conserving carbon" + print*, " Longitude index = ", i + print*, " Latitude index = ", j + print*, " Depth index and value = ", k, wombat%zm(i,j,k) + print*, " " + print*, " Biological C budget (molC/kg) at two timesteps ", c_pools(i,j,k,:) + stop + endif + endif + enddo; enddo; enddo enddo @@ -2803,15 +2826,21 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif enddo; enddo; enddo - ! Bottom iron fix + ! Additional operations on dissolved iron concentration !----------------------------------------------------------------------- - ! mac: only apply this fix when the water is <= 200 m deep. + ! mac: bottom dFe fix to 1 nM when the water is <= 200 m deep. + ! pjb: tune minimum dissolved iron concentration to detection limit... + ! this is essential for ensuring dFe is replenished in upper ocean do j = jsc,jec; do i = isc,iec; if (grid_kmt(i,j) .gt. 0) then k = grid_kmt(i,j) if (wombat%zw(i,j,k) .le. 200) wombat%f_fe(i,j,k)= umol_m3_to_mol_kg * 0.999 ! [mol/kg] endif - enddo; enddo + do k = 1,nk + zno3 = wombat%f_no3(i,j,k) / mmol_m3_to_mol_kg + zfermin = min( max( 3e-2 * zno3 * zno3, 5e-3), 7e-2) * umol_m3_to_mol_kg + wombat%f_fe(i,j,k) = max(zfermin, wombat%f_fe(i,j,k)) * grid_tmask(i,j,k) + enddo; enddo; enddo ! Set tracers values call g_tracer_set_values(tracer_list, 'no3', 'field', wombat%f_no3, isd, jsd, ntau=tau) From e80a2f727028d4f2b037af9cfc69bfee9f53045d Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Wed, 27 Nov 2024 14:03:15 +1100 Subject: [PATCH 06/23] * Syntax corrections and removal of unnecessary code snippets * Adjustment of zooepsmin and zooepsmax values from 0.025 - 0.5 to 0.01 - 0.1 --- generic_tracers/generic_WOMBATlite.F90 | 44 +++++--------------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 7a4ec65..1785b4d 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -239,8 +239,7 @@ module generic_WOMBATlite pprod_gross_int100, & npp_int100, & radbio_int100, & - zeuphot, & - phy_leup + zeuphot real, dimension(:,:,:), allocatable :: & f_dic, & @@ -410,8 +409,7 @@ module generic_WOMBATlite id_detfe_sed_depst = -1, & id_caco3_sed_remin = -1, & id_caco3_sed_depst = -1, & - id_zeuphot = -1, & - id_phy_leup = -1 + id_zeuphot = -1 end type generic_WOMBATlite_type @@ -1059,12 +1057,6 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_zeuphot = 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( & - 'phy_leup', 'Limitation factor due to depth of euphotic zone / MLD', & - 'h', '1', 's', 'm', 'f') - wombat%id_phy_leup = register_diag_field(package_name, vardesc_temp%name, axes(1:2), & - init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) - end subroutine generic_WOMBATlite_register_diag !####################################################################### @@ -1227,11 +1219,11 @@ subroutine user_add_params ! Zooplankton minimum prey capture rate constant [m6/mmol2/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zooepsmin', wombat%zooepsmin, 0.025/86400.0) + call g_tracer_add_param('zooepsmin', wombat%zooepsmin, 0.01/86400.0) ! Zooplankton maximum prey capture rate constant [m6/mmol2/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zooepsmax', wombat%zooepsmax, 0.5/86400.0) + call g_tracer_add_param('zooepsmax', wombat%zooepsmax, 0.1/86400.0) ! Zooplankton preference for phytoplankton [0-1] !----------------------------------------------------------------------- @@ -1477,7 +1469,6 @@ subroutine user_add_tracers(tracer_list) longname = 'Detritus', & units = 'mol/kg', & prog = .true., & - sink_rate = wombat%wdetbio*0.0, & move_vertical = .true., & flux_bottom = .false., & btm_reservoir = .true.) @@ -1489,7 +1480,6 @@ subroutine user_add_tracers(tracer_list) longname = 'Detrital iron content', & units = 'mol/kg', & prog = .true., & - sink_rate = wombat%wdetbio*0.0, & move_vertical = .true., & flux_bottom = .false., & btm_reservoir = .true.) @@ -1502,7 +1492,6 @@ subroutine user_add_tracers(tracer_list) units = 'mol/kg', & prog = .true., & sink_rate = wombat%wcaco3, & - move_vertical = .false., & btm_reservoir = .true.) ! ADIC (Natural + anthropogenic dissolved inorganic carbon) @@ -2080,7 +2069,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%npp_int100(:,:) = 0.0 wombat%radbio_int100(:,:) = 0.0 wombat%zeuphot(:,:) = 0.0 - wombat%phy_leup(:,:) = 1.0 ! Some unit conversion factors mmol_m3_to_mol_kg = 1.e-3 / wombat%Rho_0 @@ -2264,10 +2252,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & enddo !} - ! Calculate impact of euphotic zone depth on phytoplankton and chlorophyll production -! wombat%phy_leup(i,j) = MIN(1.0, wombat%zeuphot(i,j)/(hblt_depth(i,j) + epsi)) - wombat%phy_leup(i,j) = 1.0 - !--- Aggregate light in mixed layer and calculate maximum growth rates ---! do k = 1,grid_kmt(i,j) !{ @@ -2372,7 +2356,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & phy_pisl = max(wombat%alphabio * phy_chlc, wombat%alphabio * wombat%phyminqc) phy_pisl2 = phy_pisl / ( (1. + wombat%phylmor*86400.0 * fbc) ) ! add daylength estimate here - wombat%phy_lpar(i,j,k) = (1. - exp(-phy_pisl2 * wombat%radbio(i,j,k))) * wombat%phy_leup(i,j) + wombat%phy_lpar(i,j,k) = (1. - exp(-phy_pisl2 * wombat%radbio(i,j,k))) wombat%phy_mu(i,j,k) = wombat%phy_mumax(i,j,k) * wombat%phy_lpar(i,j,k) * & min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k)) @@ -2398,7 +2382,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & pchl_pisl = phy_pisl / ( wombat%phy_mumax(i,j,k) * 86400.0 * & (1. - min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k))) + epsi ) - wombat%pchl_lpar(i,j,k) = (1. - exp(-pchl_pisl * wombat%radmld(i,j,k))) * wombat%phy_leup(i,j) + wombat%pchl_lpar(i,j,k) = (1. - exp(-pchl_pisl * wombat%radmld(i,j,k))) pchl_mumin = wombat%phyminqc * wombat%phy_mu(i,j,k) * biophy * 12.0 ![mg/m3/s] pchl_muopt = wombat%phyoptqc * wombat%phy_mu(i,j,k) * biophy * 12.0 ![mg/m3/s] wombat%pchl_mu(i,j,k) = (pchl_muopt - pchl_mumin) * wombat%pchl_lpar(i,j,k) * & @@ -2562,9 +2546,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & if (wombat%f_det(i,j,k) .gt. epsi) then wombat%detremi(i,j,k) = wombat%reminr(i,j,k) / mmol_m3_to_mol_kg * & wombat%f_det(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] - ! if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = 0.5 * wombat%detremi(i,j,k) ! reduce decay below 180m - ! wombat%detremi(i,j,k) = wombat%reminr(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] - ! if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = 0.5 * wombat%detremi(i,j,k) ! reduce decay below 180m else wombat%detremi(i,j,k) = 0.0 endif @@ -2861,8 +2842,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !----------------------------------------------------------------------- ! Assign spatially variable vertical movement of tracers !----------------------------------------------------------------------- - call g_tracer_get_pointer(tracer_list, 'det', 'vmove', wombat%p_wdet) ! [mol/kg] - call g_tracer_get_pointer(tracer_list, 'detfe', 'vmove', wombat%p_wdetfe) ! [mol/kg] + call g_tracer_get_pointer(tracer_list, 'det', 'vmove', wombat%p_wdet) ! [m/s] + call g_tracer_get_pointer(tracer_list, 'detfe', 'vmove', wombat%p_wdetfe) ! [m/s] ! Variable sinking rates of organic detritus (negative for sinking) do j = jsc,jec; do i = isc,iec; @@ -3270,10 +3251,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_zeuphot, wombat%zeuphot, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_phy_leup .gt. 0) & - used = g_send_data(wombat%id_phy_leup, wombat%phy_leup, model_time, & - rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - deallocate(kmeuph, k100) end subroutine generic_WOMBATlite_update_from_source @@ -3659,10 +3636,7 @@ subroutine user_allocate_arrays allocate(wombat%pprod_gross_int100(isd:ied, jsd:jed)); wombat%pprod_gross_int100(:,:)=0.0 allocate(wombat%npp_int100(isd:ied, jsd:jed)); wombat%npp_int100(:,:)=0.0 allocate(wombat%radbio_int100(isd:ied, jsd:jed)); wombat%radbio_int100(:,:)=0.0 - -! allocate(wombat%yt(isd:ied, jsd:jed)); wombat%yt(:,:)=0.0 allocate(wombat%zeuphot(isd:ied, jsd:jed)); wombat%zeuphot(:,:)=0.0 - allocate(wombat%phy_leup(isd:ied, jsd:jed)); wombat%phy_leup(:,:)=0.0 end subroutine user_allocate_arrays @@ -3801,8 +3775,6 @@ subroutine user_deallocate_arrays wombat%radbio_int100) deallocate( & -! wombat%yt, & - wombat%phy_leup, & wombat%zeuphot) end subroutine user_deallocate_arrays From 70788dcaa9dd27e5bd5ce4edbaad4f88cea7ab21 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Wed, 4 Dec 2024 08:30:14 +1100 Subject: [PATCH 07/23] * minimum values of DIC and ALK * Explicit ALK source and sink terms within nested tilmestep * Using GOLDtridiag with vertical_movement for consistency with MOM6 * Variable epsilon of zooplankton with phy biomass and temp dependencies --- generic_tracers/generic_WOMBATlite.F90 | 237 ++++++++++++++++++----- generic_tracers/generic_tracer_utils.F90 | 13 +- 2 files changed, 192 insertions(+), 58 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 1785b4d..0ccc7a3 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -167,6 +167,8 @@ module generic_WOMBATlite alk_global, & no3_global, & sio2_surf, & + dic_min, & + alk_min, & htotal_scale_lo, & htotal_scale_hi, & htotal_in, & @@ -286,6 +288,7 @@ module generic_WOMBATlite phygrow, & phyresp, & phymort, & + zooeps, & zoograzphy, & zoograzdet, & zooresp, & @@ -299,11 +302,13 @@ module generic_WOMBATlite caldiss, & no3_prev, & caco3_prev, & + dic_correct, & + adic_correct, & + alk_correct, & zw, & zm real, dimension(:,:,:,:), pointer :: & - p_alk, & p_o2 real, dimension(:,:,:), pointer :: & @@ -334,6 +339,9 @@ module generic_WOMBATlite id_dic_vstf = -1, & id_adic_vstf = -1, & id_alk_vstf = -1, & + id_dic_correct = -1, & + id_adic_correct = -1, & + id_alk_correct = -1, & id_light_limit = -1, & id_radbio = -1, & id_radmid = -1, & @@ -361,6 +369,7 @@ module generic_WOMBATlite id_phygrow = -1, & id_phyresp = -1, & id_phymort = -1, & + id_zooeps = -1, & id_zoograzphy = -1, & id_zoograzdet = -1, & id_zooresp = -1, & @@ -649,6 +658,21 @@ subroutine generic_WOMBATlite_register_diag(diag_list) !======================================================================= ! Tracer and source term diagnostics !======================================================================= + vardesc_temp = vardesc( & + 'dic_correct', 'Correction to DIC tracer (min limit)', 'h', 'L', 's', 'mol/kg', 'f') + wombat%id_dic_correct = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'adic_correct', 'Correction to aDIC tracer (min limit)', 'h', 'L', 's', 'mol/kg', 'f') + wombat%id_adic_correct = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'alk_correct', 'Correction to Alk tracer (min limit)', 'h', 'L', 's', 'mol/kg', 'f') + wombat%id_alk_correct = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & 'light_limit', 'Integrated light limitation of phytoplankton growth', & 'h', '1', 's', 'm', 'f') @@ -873,6 +897,11 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_phymort = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & + 'zooeps', 'Zooplankton prey capture rate coefficient', 'h', 'L', 's', 'm^6/mmolC^2/s', 'f') + wombat%id_zooeps = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & 'zoograzphy', 'Grazing rate of zooplankton on phytoplankton', 'h', 'L', 's', 'molC/kg/s', 'f') wombat%id_zoograzphy = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & @@ -1145,6 +1174,14 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('htotal_scale_hi', wombat%htotal_scale_hi, 100.0) + ! Absolute maximum of dissolved inorganic carbon [mmol/m3] + !----------------------------------------------------------------------- + call g_tracer_add_param('dic_min', wombat%dic_min, 1000.0) + + ! Absolute minimum of alkalinity [mmol/m3] + !----------------------------------------------------------------------- + call g_tracer_add_param('alk_min', wombat%alk_min, 1000.0) + ! Global average surface concentration of inorganic silicate [mol/kg] !----------------------------------------------------------------------- call g_tracer_add_param('sio2_surf', wombat%sio2_surf, 35.0e-3 / 1035.0) @@ -1219,11 +1256,11 @@ subroutine user_add_params ! Zooplankton minimum prey capture rate constant [m6/mmol2/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zooepsmin', wombat%zooepsmin, 0.01/86400.0) + call g_tracer_add_param('zooepsmin', wombat%zooepsmin, 0.025/86400.0) ! Zooplankton maximum prey capture rate constant [m6/mmol2/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zooepsmax', wombat%zooepsmax, 0.1/86400.0) + call g_tracer_add_param('zooepsmax', wombat%zooepsmax, 0.25/86400.0) ! Zooplankton preference for phytoplankton [0-1] !----------------------------------------------------------------------- @@ -1824,7 +1861,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: biof, biodoc, zno3, zfermin real :: phy_Fe2C, zoo_Fe2C, det_Fe2C real :: phy_minqfe, phy_maxqfe - real :: zooeps, zoo_slmor + real :: zoo_slmor, epsmin real, dimension(:,:,:,:), allocatable :: n_pools, c_pools logical :: used @@ -1845,6 +1882,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zm(i,j,k) = wombat%zw(i,j,k-1) + 0.5 * dzt(i,j,k) enddo; enddo ; enddo + ! Some unit conversion factors + mmol_m3_to_mol_kg = 1.e-3 / wombat%Rho_0 + umol_m3_to_mol_kg = 1.e-3 * mmol_m3_to_mol_kg + !======================================================================= ! Attenuation coefficients for blue, green and red light @@ -1944,10 +1985,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & if (k.eq.1) then !{ call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & - wombat%f_dic(:,:,k), & + max(wombat%f_dic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg), & wombat%f_no3(:,:,k) / 16., & wombat%sio2(:,:), & - wombat%f_alk(:,:,k), & + max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & wombat%htotal(:,:,k), & co2_calc=trim(co2_calc), & @@ -1957,10 +1998,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & - wombat%f_adic(:,:,k), & + max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg), & wombat%f_no3(:,:,k) / 16., & wombat%sio2(:,:), & - wombat%f_alk(:,:,k), & + max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & wombat%ahtotal(:,:,k), & co2_calc=trim(co2_calc), & @@ -1977,10 +2018,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & - wombat%f_dic(:,:,k), & + max(wombat%f_dic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg), & wombat%f_no3(:,:,k) / 16., & wombat%sio2(:,:), & - wombat%f_alk(:,:,k), & + max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & wombat%htotal(:,:,k), & co2_calc=trim(co2_calc), & @@ -1988,10 +2029,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & - wombat%f_adic(:,:,k), & + max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg), & wombat%f_no3(:,:,k) / 16., & wombat%sio2(:,:), & - wombat%f_alk(:,:,k), & + max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & wombat%ahtotal(:,:,k), & co2_calc=trim(co2_calc), & @@ -2004,6 +2045,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Calculate the source terms !======================================================================= + wombat%dic_correct(:,:,:) = 0.0 + wombat%adic_correct(:,:,:) = 0.0 + wombat%alk_correct(:,:,:) = 0.0 wombat%pprod_gross(:,:,:) = 0.0 wombat%zprod_gross(:,:,:) = 0.0 wombat%light_limit(:,:) = 0.0 @@ -2035,6 +2079,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%phygrow(:,:,:) = 0.0 wombat%phyresp(:,:,:) = 0.0 wombat%phymort(:,:,:) = 0.0 + wombat%zooeps(:,:,:) = 0.0 wombat%zoograzphy(:,:,:) = 0.0 wombat%zoograzdet(:,:,:) = 0.0 wombat%zooresp(:,:,:) = 0.0 @@ -2070,10 +2115,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%radbio_int100(:,:) = 0.0 wombat%zeuphot(:,:) = 0.0 - ! Some unit conversion factors - mmol_m3_to_mol_kg = 1.e-3 / wombat%Rho_0 - umol_m3_to_mol_kg = 1.e-3 * mmol_m3_to_mol_kg - ! Allocate and initialise some multi-dimensional variables allocate(ek_bgr(nk,3)); ek_bgr(:,:)=0.0 allocate(par_bgr_mid(nk,3)); par_bgr_mid(:,:)=0.0 @@ -2125,7 +2166,13 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & positive=.true.) ! [mol/kg] call g_tracer_get_values(tracer_list, 'fe', 'field', wombat%f_fe, isd, jsd, ntau=tau, & positive=.true.) ! [mol/kg] - + call g_tracer_get_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=tau, & + positive=.true.) ! [mol/kg] + call g_tracer_get_values(tracer_list, 'adic', 'field', wombat%f_adic, isd, jsd, ntau=tau, & + positive=.true.) ! [mol/kg] + call g_tracer_get_values(tracer_list, 'alk', 'field', wombat%f_alk, isd, jsd, ntau=tau, & + positive=.true.) ! [mol/kg] + !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! @@ -2284,8 +2331,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & do tn = 1,ts_npzd - n_pools(:,:,:,2) = n_pools(:,:,:,1) - c_pools(:,:,:,2) = c_pools(:,:,:,1) + n_pools(:,:,:,1) = n_pools(:,:,:,2) + c_pools(:,:,:,1) = c_pools(:,:,:,2) do k = 1,nk; do j = jsc,jec; do i = isc,iec; @@ -2495,10 +2542,15 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Grazing function ! [1/s] zooprey = wombat%zprefphy * biophy + wombat%zprefdet * biodet - zooeps = wombat%zooepsmin + (wombat%zooepsmax - wombat%zooepsmin) / & - (1. + exp(5.*(biophy - 2.*wombat%phybiot))) - g_npz = wombat%zoogmax * fbc * (zooeps * zooprey*zooprey) / & - (wombat%zoogmax * fbc + (zooeps * zooprey*zooprey)) + ! Epsilon (prey capture rate coefficient) is made a function of phytoplankton biomass (Fig 2 of Rohr et al., 2024; GRL) + ! - We add a temperature dependence that reduces epsilon in cool temperatures to enforce mesozooplankton at high lats + ! - We add a temperature dependence that elevates the minimum epsilon in the tropics + epsmin = wombat%zooepsmin * ( 1.5 * tanh(0.2*(Temp(i,j,k)-15.0)) + 2.5 ) + wombat%zooeps(i,j,k) = epsmin + (wombat%zooepsmax - epsmin) / & + (1. + exp(3.*(biophy - 2.*wombat%phybiot))) / & + (1. + exp(-(Temp(i,j,k)-10.0))) + g_npz = wombat%zoogmax * fbc * (wombat%zooeps(i,j,k) * zooprey*zooprey) / & + (wombat%zoogmax * fbc + (wombat%zooeps(i,j,k) * zooprey*zooprey)) !-----------------------------------------------------------------------! @@ -2544,8 +2596,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif if (wombat%f_det(i,j,k) .gt. epsi) then - wombat%detremi(i,j,k) = wombat%reminr(i,j,k) / mmol_m3_to_mol_kg * & - wombat%f_det(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] + wombat%detremi(i,j,k) = wombat%reminr(i,j,k)/(mmol_m3_to_mol_kg*1e3) * wombat%f_det(i,j,k)**1.5 ! [molC/kg/s] else wombat%detremi(i,j,k) = 0.0 endif @@ -2695,6 +2746,20 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zoomort(i,j,k) * wombat%f_inorg + & wombat%caldiss(i,j,k) ) + ! Equation for ALK ! [molC/kg] + !----------------------------------------------------------------------- + wombat%f_alk(i,j,k) = wombat%f_alk(i,j,k) + dtsb * 16.0/122.0 * ( & + wombat%phygrow(i,j,k) - & + wombat%detremi(i,j,k) - & + wombat%zooresp(i,j,k) - & + wombat%zooexcrphy(i,j,k) - & + wombat%zooexcrdet(i,j,k) - & + wombat%phyresp(i,j,k) ) + dtsb * 2.0 * ( & + wombat%caldiss(i,j,k) - & + wombat%zooslopphy(i,j,k) * wombat%f_inorg - & + wombat%phymort(i,j,k) * wombat%f_inorg - & + wombat%zoomort(i,j,k) * wombat%f_inorg ) + ! Extra equation for iron ! [molFe/kg] !----------------------------------------------------------------------- wombat%f_fe(i,j,k) = wombat%f_fe(i,j,k) + dtsb * ( & @@ -2730,28 +2795,66 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! - n_pools(i,j,k,1) = wombat%f_no3(i,j,k) + (wombat%f_phy(i,j,k) + wombat%f_det(i,j,k) + & + n_pools(i,j,k,2) = wombat%f_no3(i,j,k) + (wombat%f_phy(i,j,k) + wombat%f_det(i,j,k) + & wombat%f_zoo(i,j,k)) * 16/122.0 - c_pools(i,j,k,1) = wombat%f_dic(i,j,k) + wombat%f_phy(i,j,k) + wombat%f_det(i,j,k) + & + c_pools(i,j,k,2) = wombat%f_dic(i,j,k) + wombat%f_phy(i,j,k) + wombat%f_det(i,j,k) + & wombat%f_zoo(i,j,k) + wombat%f_caco3(i,j,k) if (tn.gt.1) then - if (abs(n_pools(i,j,k,2) - n_pools(i,j,k,1)).gt.1e-15) then + if (abs(n_pools(i,j,k,2) - n_pools(i,j,k,1)).gt.1e-16) then print*, "Error: Ecosystem model is not conserving nitrogen" print*, " Longitude index = ", i print*, " Latitude index = ", j print*, " Depth index and value = ", k, wombat%zm(i,j,k) + print*, " Nested timestep number = ", tn print*, " " print*, " Biological N budget (molN/kg) at two timesteps ", n_pools(i,j,k,:) + print*, " " + print*, " NO3 (molNO3/kg) = ", wombat%f_no3(i,j,k) + print*, " PHY (molN/kg) = ", wombat%f_phy(i,j,k) * 16/122.0 + print*, " ZOO (molN/kg) = ", wombat%f_zoo(i,j,k) * 16/122.0 + print*, " DET (molN/kg) = ", wombat%f_det(i,j,k) * 16/122.0 + print*, " " + print*, " phygrow (molC/kg/s) = ", wombat%phygrow(i,j,k) + print*, " detremi (molC/kg/s) = ", wombat%detremi(i,j,k) + print*, " zooresp (molC/kg/s) = ", wombat%zooresp(i,j,k) + print*, " zooexcrphy (molC/kg/s) = ", wombat%zooexcrphy(i,j,k) + print*, " zooexcrdet (molC/kg/s) = ", wombat%zooexcrdet(i,j,k) + print*, " phyresp (molC/kg/s) = ", wombat%phyresp(i,j,k) + print*, " " stop endif - if (abs(c_pools(i,j,k,2) - c_pools(i,j,k,1)).gt.1e-15) then + if (abs(c_pools(i,j,k,2) - c_pools(i,j,k,1)).gt.1e-16) then print*, "Error: Ecosystem model is not conserving carbon" print*, " Longitude index = ", i print*, " Latitude index = ", j print*, " Depth index and value = ", k, wombat%zm(i,j,k) + print*, " Nested timestep number = ", tn print*, " " print*, " Biological C budget (molC/kg) at two timesteps ", c_pools(i,j,k,:) + print*, " " + print*, " DIC (molC/kg) = ", wombat%f_dic(i,j,k) + print*, " ALK (molC/kg) = ", wombat%f_alk(i,j,k) + print*, " PHY (molC/kg) = ", wombat%f_phy(i,j,k) + print*, " ZOO (molC/kg) = ", wombat%f_zoo(i,j,k) + print*, " DET (molC/kg) = ", wombat%f_det(i,j,k) + print*, " CaCO3 (molC/kg) = ", wombat%f_caco3(i,j,k) + print*, " Temp = ", Temp(i,j,k) + print*, " Salt = ", Salt(i,j,k) + print*, " surface pCO2 = ", wombat%pco2_csurf(i,j) + print*, " htotal = ", wombat%htotal(i,j,k) + print*, " " + print*, " phygrow (molC/kg/s) = ", wombat%phygrow(i,j,k) + print*, " detremi (molC/kg/s) = ", wombat%detremi(i,j,k) + print*, " zooresp (molC/kg/s) = ", wombat%zooresp(i,j,k) + print*, " zooexcrphy (molC/kg/s) = ", wombat%zooexcrphy(i,j,k) + print*, " zooexcrdet (molC/kg/s) = ", wombat%zooexcrdet(i,j,k) + print*, " phyresp (molC/kg/s) = ", wombat%phyresp(i,j,k) + print*, " zooslopphy * f_inorg (molC/kg/s) = ", wombat%zooslopphy(i,j,k)*wombat%f_inorg + print*, " phymort * f_inorg (molC/kg/s) = ", wombat%phymort(i,j,k)*wombat%f_inorg + print*, " zoomort * f_inorg (molC/kg/s) = ", wombat%zoomort(i,j,k)*wombat%f_inorg + print*, " caldiss (molC/kg/s) = ", wombat%caldiss(i,j,k) + print*, " " stop endif endif @@ -2762,16 +2865,11 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Add biotically induced tendency to biotracers !----------------------------------------------------------------------- - ! dts: update prognostic tracers via pointers - call g_tracer_get_pointer(tracer_list, 'alk', 'field', wombat%p_alk) ! [mol/kg] do k = 1,nk; do j = jsc,jec; do i = isc,iec; no3_bgc_change = grid_tmask(i,j,k) * (wombat%f_no3(i,j,k) - wombat%no3_prev(i,j,k)) ! [mol/kg] caco3_bgc_change = grid_tmask(i,j,k) * (wombat%f_caco3(i,j,k) - wombat%caco3_prev(i,j,k)) ! [mol/kg] - wombat%p_alk(i,j,k,tau) = wombat%p_alk(i,j,k,tau) + & - (-2.0 * caco3_bgc_change - no3_bgc_change) ! [mol/kg] - wombat%pprod_gross(i,j,k) = rdtts * wombat%pprod_gross(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] wombat%zprod_gross(i,j,k) = rdtts * wombat%zprod_gross(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] wombat%npp3d(i,j,k) = rdtts * wombat%npp3d(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] @@ -2807,20 +2905,31 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif enddo; enddo; enddo - ! Additional operations on dissolved iron concentration + ! Additional operations on tracers !----------------------------------------------------------------------- - ! mac: bottom dFe fix to 1 nM when the water is <= 200 m deep. - ! pjb: tune minimum dissolved iron concentration to detection limit... - ! this is essential for ensuring dFe is replenished in upper ocean do j = jsc,jec; do i = isc,iec; + ! mac: bottom dFe fix to 1 nM when the water is <= 200 m deep. if (grid_kmt(i,j) .gt. 0) then k = grid_kmt(i,j) if (wombat%zw(i,j,k) .le. 200) wombat%f_fe(i,j,k)= umol_m3_to_mol_kg * 0.999 ! [mol/kg] endif do k = 1,nk + ! pjb: tune minimum dissolved iron concentration to detection limit... + ! this is essential for ensuring dFe is replenished in upper ocean and actually + ! looks to be the secret of PISCES ability to replicate dFe limitation in the right places zno3 = wombat%f_no3(i,j,k) / mmol_m3_to_mol_kg zfermin = min( max( 3e-2 * zno3 * zno3, 5e-3), 7e-2) * umol_m3_to_mol_kg wombat%f_fe(i,j,k) = max(zfermin, wombat%f_fe(i,j,k)) * grid_tmask(i,j,k) + ! pjb: set upper and lower limits of some tracers and save corrections to output for budgets + wombat%alk_correct(i,j,k) = (max(wombat%alk_min * mmol_m3_to_mol_kg, wombat%f_alk(i,j,k) ) & + - wombat%f_alk(i,j,k) ) * grid_tmask(i,j,k) + wombat%dic_correct(i,j,k) = (max(wombat%dic_min * mmol_m3_to_mol_kg, wombat%f_dic(i,j,k) ) & + - wombat%f_dic(i,j,k) ) * grid_tmask(i,j,k) + wombat%adic_correct(i,j,k) = (max(wombat%dic_min * mmol_m3_to_mol_kg, wombat%f_adic(i,j,k) ) & + - wombat%f_adic(i,j,k) ) * grid_tmask(i,j,k) + wombat%f_alk(i,j,k) = wombat%f_alk(i,j,k) + wombat%alk_correct(i,j,k) + wombat%f_dic(i,j,k) = wombat%f_dic(i,j,k) + wombat%dic_correct(i,j,k) + wombat%f_adic(i,j,k) = wombat%f_adic(i,j,k) + wombat%adic_correct(i,j,k) enddo; enddo; enddo ! Set tracers values @@ -2837,6 +2946,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_set_values(tracer_list, 'fe', 'field', wombat%f_fe, isd, jsd, ntau=tau) call g_tracer_set_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=tau) call g_tracer_set_values(tracer_list, 'adic', 'field', wombat%f_adic, isd, jsd, ntau=tau) + call g_tracer_set_values(tracer_list, 'alk', 'field', wombat%f_alk, isd, jsd, ntau=tau) !----------------------------------------------------------------------- @@ -2845,17 +2955,18 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_get_pointer(tracer_list, 'det', 'vmove', wombat%p_wdet) ! [m/s] call g_tracer_get_pointer(tracer_list, 'detfe', 'vmove', wombat%p_wdetfe) ! [m/s] - ! Variable sinking rates of organic detritus (negative for sinking) + ! Variable sinking rates of organic detritus (positive for sinking when GOLDtridiag == .true.) + ! (negative for sinking when IOWtridiag ==.true.) do j = jsc,jec; do i = isc,iec; if (grid_kmt(i,j).gt.0) then biophy1 = max(epsi, wombat%f_phy(i,j,1) ) / mmol_m3_to_mol_kg ![mmol/m3] - wombat%p_wdet(i,j,:) = -wombat%wdetbio * max(0.01, biophy1 - wombat%phybiot)**(0.21) - wombat%p_wdetfe(i,j,:) = -wombat%wdetbio * max(0.01, biophy1 - wombat%phybiot)**(0.21) - do k=1,nk - wombat%p_wdet(i,j,k) = wombat%p_wdet(i,j,k) + min(0.0, & - wombat%zw(i,j,k)/5000.0 * (-wombat%wdetmax - wombat%p_wdet(i,j,k))) - wombat%p_wdetfe(i,j,k) = wombat%p_wdetfe(i,j,k) + min(0.0, & - wombat%zw(i,j,k)/5000.0 * (-wombat%wdetmax - wombat%p_wdetfe(i,j,k))) + wombat%p_wdet(i,j,:) = wombat%wdetbio * max(0.0, biophy1 - wombat%phybiot)**(0.21) + wombat%p_wdetfe(i,j,:) = wombat%wdetbio * max(0.0, biophy1 - wombat%phybiot)**(0.21) + do k=1,nk + wombat%p_wdet(i,j,k) = wombat%p_wdet(i,j,k) + max(0.0, & + wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wombat%p_wdet(i,j,k))) + wombat%p_wdetfe(i,j,k) = wombat%p_wdetfe(i,j,k) + max(0.0, & + wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wombat%p_wdetfe(i,j,k))) enddo else wombat%p_wdet(i,j,:) = 0.0 @@ -2942,6 +3053,18 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_alk_vstf, wombat%alk_vstf, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (wombat%id_dic_correct .gt. 0) & + used = g_send_data(wombat%id_dic_correct, wombat%dic_correct, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_adic_correct .gt. 0) & + used = g_send_data(wombat%id_adic_correct, wombat%adic_correct, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_alk_correct .gt. 0) & + used = g_send_data(wombat%id_alk_correct, wombat%alk_correct, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_light_limit .gt. 0) & used = g_send_data(wombat%id_light_limit, wombat%light_limit, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) @@ -3062,6 +3185,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_phymort, wombat%phymort, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_zooeps .gt. 0) & + used = g_send_data(wombat%id_zooeps, wombat%zooeps, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_zoograzphy .gt. 0) & used = g_send_data(wombat%id_zoograzphy, wombat%zoograzphy, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) @@ -3310,6 +3437,7 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il integer :: isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, i, j real :: sal, ST, o2_saturation real :: tt, tk, ts, ts2, ts3, ts4, ts5 + real :: mmol_m3_to_mol_kg real, dimension(:,:,:), pointer :: grid_tmask character(len=fm_string_len), parameter :: sub_name = 'generic_WOMBATlite_set_boundary_values' @@ -3318,7 +3446,10 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il grid_tmask=grid_tmask) call g_tracer_get_pointer(tracer_list, 'o2', 'field', wombat%p_o2) - + + ! Some unit conversion factors + mmol_m3_to_mol_kg = 1.e-3 / wombat%Rho_0 + ! nnz: Since the generic_WOMBATlite_update_from_source() subroutine is called by this time ! the following if block is not really necessary (since this calculation is already done in ! source). @@ -3351,10 +3482,10 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,1), & SST(:,:), SSS(:,:), & - wombat%f_dic(:,:,1), & + max(wombat%f_dic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg), & wombat%f_no3(:,:,1) / 16., & wombat%sio2(:,:), & - wombat%f_alk(:,:,1), & + max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & wombat%htotal(:,:,1), & co2_calc=trim(co2_calc), & @@ -3364,10 +3495,10 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,1), & SST(:,:), SSS(:,:), & - wombat%f_adic(:,:,1), & + max(wombat%f_adic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg), & wombat%f_no3(:,:,1) / 16., & wombat%sio2(:,:), & - wombat%f_alk(:,:,1), & + max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & wombat%ahtotal(:,:,1), & co2_calc=trim(co2_calc), & @@ -3557,6 +3688,9 @@ subroutine user_allocate_arrays allocate(wombat%b_fe(isd:ied, jsd:jed)); wombat%b_fe(:,:)=0.0 allocate(wombat%b_alk(isd:ied, jsd:jed)); wombat%b_alk(:,:)=0.0 + allocate(wombat%dic_correct(isd:ied, jsd:jed, 1:nk)); wombat%dic_correct(:,:,:)=0.0 + allocate(wombat%adic_correct(isd:ied, jsd:jed, 1:nk)); wombat%adic_correct(:,:,:)=0.0 + allocate(wombat%alk_correct(isd:ied, jsd:jed, 1:nk)); wombat%alk_correct(:,:,:)=0.0 allocate(wombat%light_limit(isd:ied, jsd:jed)); wombat%light_limit(:,:)=0.0 allocate(wombat%radbio(isd:ied, jsd:jed, 1:nk)); wombat%radbio(:,:,:)=0.0 allocate(wombat%radmid(isd:ied, jsd:jed, 1:nk)); wombat%radmid(:,:,:)=0.0 @@ -3593,6 +3727,7 @@ subroutine user_allocate_arrays allocate(wombat%phygrow(isd:ied, jsd:jed, 1:nk)); wombat%phygrow(:,:,:)=0.0 allocate(wombat%phyresp(isd:ied, jsd:jed, 1:nk)); wombat%phyresp(:,:,:)=0.0 allocate(wombat%phymort(isd:ied, jsd:jed, 1:nk)); wombat%phymort(:,:,:)=0.0 + allocate(wombat%zooeps(isd:ied, jsd:jed, 1:nk)); wombat%zooeps(:,:,:)=0.0 allocate(wombat%zoograzphy(isd:ied, jsd:jed, 1:nk)); wombat%zoograzphy(:,:,:)=0.0 allocate(wombat%zoograzdet(isd:ied, jsd:jed, 1:nk)); wombat%zoograzdet(:,:,:)=0.0 allocate(wombat%zooresp(isd:ied, jsd:jed, 1:nk)); wombat%zooresp(:,:,:)=0.0 diff --git a/generic_tracers/generic_tracer_utils.F90 b/generic_tracers/generic_tracer_utils.F90 index 1eea9a6..734e484 100644 --- a/generic_tracers/generic_tracer_utils.F90 +++ b/generic_tracers/generic_tracer_utils.F90 @@ -3182,8 +3182,6 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, if (g_tracer%move_vertical) then do k=2,nz; sink_dist(k) = (dt*g_tracer%vmove(i,j,k)) * m_to_H; enddo - sink_dist(nz+1) = (dt*g_tracer%vmove(i,j,nz)) * m_to_H !PJB [13th Nov 2024] to allow sinking into bottom reservoir - ! PJB... although this doesn't work because "move_vertical==.true." makes "GOLDtridiag==.false." endif sfc_src = 0.0 ; btm_src = 0.0 @@ -3195,7 +3193,7 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, do k=2,nz sink(k) = sink_dist(k) ; h_minus_dsink(k) = h_old(i,j,k) enddo - sink(nz+1) = sink_dist(nz+1) + sink(nz+1) = sink_dist(nz) !PJB [13th Nov 2024] to allow sinking into bottom reservoir else sink(nz+1) = 0.0 ! Find the limited sinking distance at the interfaces. @@ -3317,10 +3315,11 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) GOLDtridiag = .true. IOWtridiag = .false. - if (g_tracer%move_vertical) then - GOLDtridiag = .false. - IOWtridiag = .true. - endif + ! PJB [1st Dec 2024] Commenting out the next 4 lines ensures GOLDtridiag even when move_vertical==.true. + !if (g_tracer%move_vertical) then + ! GOLDtridiag = .false. + ! IOWtridiag = .true. + !endif eps = 1.e-30 From ab7863be97295e0cbbb5247d02dcd7449299a55b Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Wed, 4 Dec 2024 08:47:53 +1100 Subject: [PATCH 08/23] reverting syntax in generic_tracers_utils.F90 on request of Dougie Squire --- generic_tracers/generic_tracer_utils.F90 | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/generic_tracers/generic_tracer_utils.F90 b/generic_tracers/generic_tracer_utils.F90 index 734e484..0a03432 100644 --- a/generic_tracers/generic_tracer_utils.F90 +++ b/generic_tracers/generic_tracer_utils.F90 @@ -3317,8 +3317,8 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) IOWtridiag = .false. ! PJB [1st Dec 2024] Commenting out the next 4 lines ensures GOLDtridiag even when move_vertical==.true. !if (g_tracer%move_vertical) then - ! GOLDtridiag = .false. - ! IOWtridiag = .true. + ! GOLDtridiag = .false. + ! IOWtridiag = .true. !endif eps = 1.e-30 @@ -3416,15 +3416,15 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) kp1 = min(k+1,g_tracer_com%nk) do i=g_tracer_com%isc,g_tracer_com%iec fact1 = dt/dh(i,j,k) - fact2 = rho0*fact1*0.5 - factu = fact1/dhw(i,j,km1) + fact2 = rho0*fact1*0.5 + factu = fact1/dhw(i,j,km1) factl = fact1/dhw(i,j,k) - wabsu = abs(g_tracer%vmove(i,j,km1)) - wposu(i,k) = fact2*(g_tracer%vmove(i,j,km1) + wabsu)*g_tracer_com%grid_tmask(i,j,k) - wnegu(i,k) = fact2*(g_tracer%vmove(i,j,km1) - wabsu)*g_tracer_com%grid_tmask(i,j,k) - wabsl = abs(g_tracer%vmove(i,j,k)) - wposl(i,k) = fact2*(g_tracer%vmove(i,j,k ) + wabsl)*g_tracer_com%grid_tmask(i,j,kp1) - wnegl(i,k) = fact2*(g_tracer%vmove(i,j,k ) - wabsl)*g_tracer_com%grid_tmask(i,j,kp1) + wabsu = abs(g_tracer%vmove(i,j,km1)) + wposu(i,k) = fact2*(g_tracer%vmove(i,j,km1) + wabsu)*g_tracer_com%grid_tmask(i,j,k) + wnegu(i,k) = fact2*(g_tracer%vmove(i,j,km1) - wabsu)*g_tracer_com%grid_tmask(i,j,k) + wabsl = abs(g_tracer%vmove(i,j,k)) + wposl(i,k) = fact2*(g_tracer%vmove(i,j,k ) + wabsl)*g_tracer_com%grid_tmask(i,j,kp1) + wnegl(i,k) = fact2*(g_tracer%vmove(i,j,k ) - wabsl)*g_tracer_com%grid_tmask(i,j,kp1) if (k.eq.g_tracer_com%grid_kmt(i,j) .and. _ALLOCATED(g_tracer%btm_reservoir)) then ! PJB [14th Nov 2024] wnegl(i,k) = fact2*(g_tracer%vmove(i,j,k ) - wabsl)*g_tracer_com%grid_tmask(i,j,k) g_tracer%btm_reservoir(i,j) = g_tracer%btm_reservoir(i,j) - & @@ -3432,25 +3432,25 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) endif a1(i,k) = dcb(i,j,km1)*factu*g_tracer_com%grid_tmask(i,j,k) c1(i,k) = dcb(i,j,k) *factl*g_tracer_com%grid_tmask(i,j,kp1) - a(i,k) = -(a1(i,k) - wnegu(i,k)) ! lower diagonal coefs - c(i,k) = -(c1(i,k) + wposl(i,k)) ! upper diagonal coefs + a(i,k) = -(a1(i,k) - wnegu(i,k)) + c(i,k) = -(c1(i,k) + wposl(i,k)) f(i,k) = g_tracer%field(i,j,k,tau)*g_tracer_com%grid_tmask(i,j,k) - b(i,k) = 1.0 + a1(i,k) + c1(i,k) - wnegl(i,k) + wposu(i,k) ! main diagonal + b(i,k) = 1.0 + a1(i,k) + c1(i,k) - wnegl(i,k) + wposu(i,k) enddo enddo ! Set boundary conditions (zero flow out the top and bottom of the water column) do i=g_tracer_com%isc,g_tracer_com%iec a1(i,1) = 0.0 - wnegu(i,1) = 0.0; wposu(i,1) = 0.0 - a(i,1) = 0.0 + wnegu(i,1) = 0.0; wposu(i,1) = 0.0 + a(i,1) = 0.0 c1(i,g_tracer_com%nk) = 0.0 - wposl(i,g_tracer_com%nk) = 0.0 + wposl(i,g_tracer_com%nk) = 0.0 if (.not. _ALLOCATED(g_tracer%btm_reservoir)) wnegl(i,g_tracer_com%nk) = 0.0 !PJB [14th Nov 2024] c(i,g_tracer_com%nk) = 0.0 b(i,1) = 1.0 + a1(i,1) + c1(i,1) - wnegl(i,1) + wposu(i,1) b(i,g_tracer_com%nk) = 1.0 + a1(i,g_tracer_com%nk) + c1(i,g_tracer_com%nk) & - - wnegl(i,g_tracer_com%nk) + wposu(i,g_tracer_com%nk) + - wnegl(i,g_tracer_com%nk) + wposu(i,g_tracer_com%nk) ! top and bottom b.c. if (_ALLOCATED(g_tracer%stf)) & From 9b79d47d5b803e0cc832bb491f38020e8fcee6e5 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Mon, 9 Dec 2024 11:59:01 +1100 Subject: [PATCH 09/23] Problems with DIC air-sea flux solved: fix was to ensure upper and lower bounds on the DIC concentration that feeds into the omip2_co2calc subroutine. Setting upper and lower limits of the DIC that is fed into the subroutine does not preclude DIC concentrations from going higher or lower than those limits, but only ensures that the air-sea fluxes are reasonable. --- generic_tracers/generic_WOMBATlite.F90 | 66 ++++++++++++-------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 0ccc7a3..3b1e6b2 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -155,11 +155,9 @@ module generic_WOMBATlite caco3lrem_sed, & wcaco3, & f_inorg, & - tscav_fe, & ligand, & knano_dfe, & kscav_dfe, & - fe_bkgnd, & dt_npzd, & sal_global, & dic_global, & @@ -168,6 +166,7 @@ module generic_WOMBATlite no3_global, & sio2_surf, & dic_min, & + dic_max, & alk_min, & htotal_scale_lo, & htotal_scale_hi, & @@ -1174,10 +1173,14 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('htotal_scale_hi', wombat%htotal_scale_hi, 100.0) - ! Absolute maximum of dissolved inorganic carbon [mmol/m3] + ! Absolute minimum of dissolved inorganic carbon [mmol/m3] !----------------------------------------------------------------------- call g_tracer_add_param('dic_min', wombat%dic_min, 1000.0) + ! Absolute maximum of dissolved inorganic carbon [mmol/m3] + !----------------------------------------------------------------------- + call g_tracer_add_param('dic_max', wombat%dic_max, 3000.0) + ! Absolute minimum of alkalinity [mmol/m3] !----------------------------------------------------------------------- call g_tracer_add_param('alk_min', wombat%alk_min, 1000.0) @@ -1196,7 +1199,7 @@ subroutine user_add_params ! Initial slope of P-I curve [(mg Chl m-3)-1 (W m-2)-1] !----------------------------------------------------------------------- - call g_tracer_add_param('alphabio', wombat%alphabio, 2.5) + call g_tracer_add_param('alphabio', wombat%alphabio, 2.25) ! Autotrophy maximum growth rate parameter a [1/s] !----------------------------------------------------------------------- @@ -1236,11 +1239,11 @@ subroutine user_add_params ! Phytoplankton linear mortality rate constant [1/s] !----------------------------------------------------------------------- - call g_tracer_add_param('phylmor', wombat%phylmor, 0.0025/86400.0) + call g_tracer_add_param('phylmor', wombat%phylmor, 0.01/86400.0) ! Phytoplankton quadratic mortality rate constant [m3/mmolN/s] !----------------------------------------------------------------------- - call g_tracer_add_param('phyqmor', wombat%phyqmor, 0.025/86400.0) + call g_tracer_add_param('phyqmor', wombat%phyqmor, 0.05/86400.0) ! Zooplankton assimilation efficiency [1] !----------------------------------------------------------------------- @@ -1272,7 +1275,7 @@ subroutine user_add_params ! Zooplankton respiration rate constant [1/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zoolmor', wombat%zoolmor, 0.005/86400.0) + call g_tracer_add_param('zoolmor', wombat%zoolmor, 0.05/86400.0) ! Zooplankton quadratic mortality rate constant [m3/mmolN/s] !----------------------------------------------------------------------- @@ -1301,7 +1304,7 @@ subroutine user_add_params ! Phytoplankton biomass threshold to scale recycling [mmolC/m3] !----------------------------------------------------------------------- - call g_tracer_add_param('phybiot', wombat%phybiot, 0.5) + call g_tracer_add_param('phybiot', wombat%phybiot, 0.6) ! CaCO3 remineralisation rate constant [1/s] !----------------------------------------------------------------------- @@ -1315,12 +1318,8 @@ subroutine user_add_params ! CaCO3 inorganic fraction [1] !----------------------------------------------------------------------- - call g_tracer_add_param('f_inorg', wombat%f_inorg, 0.062) + call g_tracer_add_param('f_inorg', wombat%f_inorg, 0.05) - ! Iron scavenging rate constant [1/s] - !----------------------------------------------------------------------- - call g_tracer_add_param('tscav_fe', wombat%tscav_fe, 3.17098e-8) - ! Background concentration of iron-binding ligand [umol/m3] !----------------------------------------------------------------------- call g_tracer_add_param('ligand', wombat%ligand, 0.7) @@ -1331,11 +1330,7 @@ subroutine user_add_params ! Scavenging of Fe` onto biogenic particles [(mmolC/m3)-1 d-1] !----------------------------------------------------------------------- - call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 5e-5) - - ! Iron background concentration [umol Fe m^-3] - !----------------------------------------------------------------------- - call g_tracer_add_param('fe_bkgnd', wombat%fe_bkgnd, 0.6) + call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 5e-3) ! Nested timestep for the ecosystem model [s] !----------------------------------------------------------------------- @@ -1985,8 +1980,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & if (k.eq.1) then !{ call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & - max(wombat%f_dic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg), & - wombat%f_no3(:,:,k) / 16., & + min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_dic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & + max(wombat%f_no3(:,:,k) / 16., 1e-9), & wombat%sio2(:,:), & max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & @@ -1998,8 +1993,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & - max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg), & - wombat%f_no3(:,:,k) / 16., & + min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & + max(wombat%f_no3(:,:,k) / 16., 1e-9), & wombat%sio2(:,:), & max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & @@ -2018,8 +2013,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & - max(wombat%f_dic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg), & - wombat%f_no3(:,:,k) / 16., & + min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_dic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & + max(wombat%f_no3(:,:,k) / 16., 1e-9), & wombat%sio2(:,:), & max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & @@ -2029,8 +2024,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & - max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg), & - wombat%f_no3(:,:,k) / 16., & + min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & + max(wombat%f_no3(:,:,k) / 16., 1e-9), & wombat%sio2(:,:), & max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & @@ -2548,7 +2543,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & epsmin = wombat%zooepsmin * ( 1.5 * tanh(0.2*(Temp(i,j,k)-15.0)) + 2.5 ) wombat%zooeps(i,j,k) = epsmin + (wombat%zooepsmax - epsmin) / & (1. + exp(3.*(biophy - 2.*wombat%phybiot))) / & - (1. + exp(-(Temp(i,j,k)-10.0))) + (1. + exp(-(Temp(i,j,k)-15.0))) g_npz = wombat%zoogmax * fbc * (wombat%zooeps(i,j,k) * zooprey*zooprey) / & (wombat%zoogmax * fbc + (wombat%zooeps(i,j,k) * zooprey*zooprey)) @@ -2596,7 +2591,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif if (wombat%f_det(i,j,k) .gt. epsi) then - wombat%detremi(i,j,k) = wombat%reminr(i,j,k)/(mmol_m3_to_mol_kg*1e3) * wombat%f_det(i,j,k)**1.5 ! [molC/kg/s] + wombat%detremi(i,j,k) = wombat%reminr(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] + if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = wombat%detremi(i,j,k) * 0.5 else wombat%detremi(i,j,k) = 0.0 endif @@ -2920,7 +2916,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & zno3 = wombat%f_no3(i,j,k) / mmol_m3_to_mol_kg zfermin = min( max( 3e-2 * zno3 * zno3, 5e-3), 7e-2) * umol_m3_to_mol_kg wombat%f_fe(i,j,k) = max(zfermin, wombat%f_fe(i,j,k)) * grid_tmask(i,j,k) - ! pjb: set upper and lower limits of some tracers and save corrections to output for budgets + ! pjb: set limits of some tracers and save corrections to output for budgets wombat%alk_correct(i,j,k) = (max(wombat%alk_min * mmol_m3_to_mol_kg, wombat%f_alk(i,j,k) ) & - wombat%f_alk(i,j,k) ) * grid_tmask(i,j,k) wombat%dic_correct(i,j,k) = (max(wombat%dic_min * mmol_m3_to_mol_kg, wombat%f_dic(i,j,k) ) & @@ -2960,8 +2956,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & do j = jsc,jec; do i = isc,iec; if (grid_kmt(i,j).gt.0) then biophy1 = max(epsi, wombat%f_phy(i,j,1) ) / mmol_m3_to_mol_kg ![mmol/m3] - wombat%p_wdet(i,j,:) = wombat%wdetbio * max(0.0, biophy1 - wombat%phybiot)**(0.21) - wombat%p_wdetfe(i,j,:) = wombat%wdetbio * max(0.0, biophy1 - wombat%phybiot)**(0.21) + wombat%p_wdet(i,j,:) = wombat%wdetbio * max(1e-3, biophy1 - wombat%phybiot)**(0.21) + wombat%p_wdetfe(i,j,:) = wombat%wdetbio * max(1e-3, biophy1 - wombat%phybiot)**(0.21) do k=1,nk wombat%p_wdet(i,j,k) = wombat%p_wdet(i,j,k) + max(0.0, & wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wombat%p_wdet(i,j,k))) @@ -3482,8 +3478,8 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,1), & SST(:,:), SSS(:,:), & - max(wombat%f_dic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg), & - wombat%f_no3(:,:,1) / 16., & + min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_dic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg)), & + max(wombat%f_no3(:,:,1) / 16., 1e-9), & wombat%sio2(:,:), & max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & @@ -3495,8 +3491,8 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,1), & SST(:,:), SSS(:,:), & - max(wombat%f_adic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg), & - wombat%f_no3(:,:,1) / 16., & + min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg)), & + max(wombat%f_no3(:,:,1) / 16., 1e-9), & wombat%sio2(:,:), & max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & From 5017183c4e8d1974b122d92ef22c33db821861c1 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Wed, 11 Dec 2024 18:45:04 +1100 Subject: [PATCH 10/23] Updated some Fe cycling parameters to increase the loss rates of Fe in the interior, and also added a max to Alk in the CO2 flux calculations --- generic_tracers/generic_WOMBATlite.F90 | 50 ++++++++++++++------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 3b1e6b2..7e3c784 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -168,6 +168,7 @@ module generic_WOMBATlite dic_min, & dic_max, & alk_min, & + alk_max, & htotal_scale_lo, & htotal_scale_hi, & htotal_in, & @@ -1173,18 +1174,22 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('htotal_scale_hi', wombat%htotal_scale_hi, 100.0) - ! Absolute minimum of dissolved inorganic carbon [mmol/m3] + ! Absolute minimum of dissolved inorganic carbon [mmol/m3] for co2 sys calcs !----------------------------------------------------------------------- call g_tracer_add_param('dic_min', wombat%dic_min, 1000.0) - ! Absolute maximum of dissolved inorganic carbon [mmol/m3] + ! Absolute maximum of dissolved inorganic carbon [mmol/m3] for co2 sys calcs !----------------------------------------------------------------------- call g_tracer_add_param('dic_max', wombat%dic_max, 3000.0) - ! Absolute minimum of alkalinity [mmol/m3] + ! Absolute minimum of alkalinity [mmol/m3] for co2 sys calcs !----------------------------------------------------------------------- call g_tracer_add_param('alk_min', wombat%alk_min, 1000.0) + ! Absolute maximum of alkalinity [mmol/m3] for co2 sys calcs + !----------------------------------------------------------------------- + call g_tracer_add_param('alk_max', wombat%alk_max, 3000.0) + ! Global average surface concentration of inorganic silicate [mol/kg] !----------------------------------------------------------------------- call g_tracer_add_param('sio2_surf', wombat%sio2_surf, 35.0e-3 / 1035.0) @@ -1239,7 +1244,7 @@ subroutine user_add_params ! Phytoplankton linear mortality rate constant [1/s] !----------------------------------------------------------------------- - call g_tracer_add_param('phylmor', wombat%phylmor, 0.01/86400.0) + call g_tracer_add_param('phylmor', wombat%phylmor, 0.005/86400.0) ! Phytoplankton quadratic mortality rate constant [m3/mmolN/s] !----------------------------------------------------------------------- @@ -1247,7 +1252,7 @@ subroutine user_add_params ! Zooplankton assimilation efficiency [1] !----------------------------------------------------------------------- - call g_tracer_add_param('zooassi', wombat%zooassi, 0.6) + call g_tracer_add_param('zooassi', wombat%zooassi, 0.5) ! Zooplankton half saturation coefficient for linear mortality !----------------------------------------------------------------------- @@ -1322,15 +1327,15 @@ subroutine user_add_params ! Background concentration of iron-binding ligand [umol/m3] !----------------------------------------------------------------------- - call g_tracer_add_param('ligand', wombat%ligand, 0.7) + call g_tracer_add_param('ligand', wombat%ligand, 0.6) ! Precipitation of Fe` as nanoparticles (in excess of solubility) [/d] !----------------------------------------------------------------------- - call g_tracer_add_param('knano_dfe', wombat%knano_dfe, 0.01) + call g_tracer_add_param('knano_dfe', wombat%knano_dfe, 0.1) ! Scavenging of Fe` onto biogenic particles [(mmolC/m3)-1 d-1] !----------------------------------------------------------------------- - call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 5e-3) + call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 5e-2) ! Nested timestep for the ecosystem model [s] !----------------------------------------------------------------------- @@ -1983,7 +1988,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_dic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & max(wombat%f_no3(:,:,k) / 16., 1e-9), & wombat%sio2(:,:), & - max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & + min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg)), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & wombat%htotal(:,:,k), & co2_calc=trim(co2_calc), & @@ -1996,7 +2001,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & max(wombat%f_no3(:,:,k) / 16., 1e-9), & wombat%sio2(:,:), & - max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & + min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg)), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & wombat%ahtotal(:,:,k), & co2_calc=trim(co2_calc), & @@ -2016,7 +2021,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_dic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & max(wombat%f_no3(:,:,k) / 16., 1e-9), & wombat%sio2(:,:), & - max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & + min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg)), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & wombat%htotal(:,:,k), & co2_calc=trim(co2_calc), & @@ -2027,7 +2032,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & max(wombat%f_no3(:,:,k) / 16., 1e-9), & wombat%sio2(:,:), & - max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg), & + min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg)), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & wombat%ahtotal(:,:,k), & co2_calc=trim(co2_calc), & @@ -2500,7 +2505,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Scavenging of Fe` onto biogenic particles partic = (biodet + biocaco3) - wombat%fescaven(i,j,k) = wombat%feIII(i,j,k) * (3e-8 + wombat%kscav_dfe * partic) / 86400.0 + wombat%fescaven(i,j,k) = wombat%feIII(i,j,k) * (1e-7 + wombat%kscav_dfe * partic) / 86400.0 wombat%fescadet(i,j,k) = wombat%fescaven(i,j,k) * biodet / (partic+epsi) ! Coagulation of colloidal Fe (umol/m3) to form sinking particles (mmol/m3) @@ -2508,9 +2513,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & biof = max(1/3., biophy / (biophy + 0.03)) biodoc = 2.0 + (1.0 - min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k))) * 38.0 ! proxy of DOC (mmol/m3) if (wombat%zw(i,j,k).le.hblt_depth(i,j)) then - zval = ( (12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-9 + zval = ( (12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-6 else - zval = ( 0.01*(12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-9 + zval = ( 0.01*(12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-6 endif wombat%fecoag2det(i,j,k) = wombat%fecol(i,j,k) * zval / 86400.0 @@ -2543,7 +2548,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & epsmin = wombat%zooepsmin * ( 1.5 * tanh(0.2*(Temp(i,j,k)-15.0)) + 2.5 ) wombat%zooeps(i,j,k) = epsmin + (wombat%zooepsmax - epsmin) / & (1. + exp(3.*(biophy - 2.*wombat%phybiot))) / & - (1. + exp(-(Temp(i,j,k)-15.0))) + (1. + exp(-(Temp(i,j,k)-10.0))) g_npz = wombat%zoogmax * fbc * (wombat%zooeps(i,j,k) * zooprey*zooprey) / & (wombat%zoogmax * fbc + (wombat%zooeps(i,j,k) * zooprey*zooprey)) @@ -2591,8 +2596,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif if (wombat%f_det(i,j,k) .gt. epsi) then - wombat%detremi(i,j,k) = wombat%reminr(i,j,k) * wombat%f_det(i,j,k) ! [molC/kg/s] - if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = wombat%detremi(i,j,k) * 0.5 + wombat%detremi(i,j,k) = wombat%reminr(i,j,k) / mmol_m3_to_mol_kg * wombat%f_det(i,j,k)**2.0 ! [molC/kg/s] + !if (wombat%zw(i,j,k) .ge. 180.0) wombat%detremi(i,j,k) = wombat%detremi(i,j,k) * 0.5 else wombat%detremi(i,j,k) = 0.0 endif @@ -2914,7 +2919,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! this is essential for ensuring dFe is replenished in upper ocean and actually ! looks to be the secret of PISCES ability to replicate dFe limitation in the right places zno3 = wombat%f_no3(i,j,k) / mmol_m3_to_mol_kg - zfermin = min( max( 3e-2 * zno3 * zno3, 5e-3), 7e-2) * umol_m3_to_mol_kg + zfermin = min( max( 3e-2 * zno3 * zno3, 5e-2), 7e-2) * umol_m3_to_mol_kg wombat%f_fe(i,j,k) = max(zfermin, wombat%f_fe(i,j,k)) * grid_tmask(i,j,k) ! pjb: set limits of some tracers and save corrections to output for budgets wombat%alk_correct(i,j,k) = (max(wombat%alk_min * mmol_m3_to_mol_kg, wombat%f_alk(i,j,k) ) & @@ -2971,7 +2976,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & enddo; enddo !----------------------------------------------------------------------- - ! Remineralisation of sediment tracers + ! Remineralisation and burial of sediment tracers !----------------------------------------------------------------------- call g_tracer_get_pointer(tracer_list, 'det_sediment', 'field', wombat%p_det_sediment) ! [mol/m2] call g_tracer_get_pointer(tracer_list, 'detfe_sediment', 'field', wombat%p_detfe_sediment) ! [mol/m2] @@ -2993,6 +2998,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%b_adic(i,j) = wombat%b_dic(i,j) ! [mol/m2/s] wombat%b_fe(i,j) = -1.0 * wombat%detfe_sed_remin(i,j) ! [mol/m2/s] wombat%b_alk(i,j) = -2.0 * wombat%caco3_sed_remin(i,j) - wombat%b_no3(i,j) ! [mol/m2/s] + endif enddo; enddo @@ -3481,7 +3487,7 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_dic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg)), & max(wombat%f_no3(:,:,1) / 16., 1e-9), & wombat%sio2(:,:), & - max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg), & + min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg)), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & wombat%htotal(:,:,1), & co2_calc=trim(co2_calc), & @@ -3494,7 +3500,7 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg)), & max(wombat%f_no3(:,:,1) / 16., 1e-9), & wombat%sio2(:,:), & - max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg), & + min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg)), & wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & wombat%ahtotal(:,:,1), & co2_calc=trim(co2_calc), & From f3062bbe0a256f25b1f3700ec1d49f2cdfcd7dd5 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Wed, 11 Dec 2024 19:42:46 +1100 Subject: [PATCH 11/23] First pass of adding burial. Seems to work well so far. --- generic_tracers/generic_WOMBATlite.F90 | 66 ++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 7e3c784..b9f3747 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -221,6 +221,9 @@ module generic_WOMBATlite det_sed_remin, & detfe_sed_remin, & caco3_sed_remin, & + det_sed_bury, & + detfe_sed_bury, & + caco3_sed_bury, & dic_intmld, & adic_intmld, & o2_intmld, & @@ -414,10 +417,13 @@ module generic_WOMBATlite id_radbio_int100 = -1, & id_det_sed_remin = -1, & id_det_sed_depst = -1, & + id_det_sed_bury = -1, & id_detfe_sed_remin = -1, & id_detfe_sed_depst = -1, & + id_detfe_sed_bury = -1, & id_caco3_sed_remin = -1, & id_caco3_sed_depst = -1, & + id_caco3_sed_bury = -1, & id_zeuphot = -1 end type generic_WOMBATlite_type @@ -715,6 +721,12 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_det_sed_depst = 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( & + 'det_sed_bury', 'Rate of permanent burial of detrital carbon within sediment', & + 'h', '1', 's', 'mol/m^2/s', 'f') + wombat%id_det_sed_bury = 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( & 'detfe_sed_remin', 'Rate of remineralisation of detrital iron in accumulated sediment', & 'h', '1', 's', 'mol/m^2/s', 'f') @@ -723,10 +735,16 @@ subroutine generic_WOMBATlite_register_diag(diag_list) vardesc_temp = vardesc( & 'detfe_sed_depst', 'Rate of deposition of detrital iron to sediment at base of water column', & - 'h', '1', 's', 'mol/m^2/s', 'f') + 'h', '1', 's', 'molFe/m^2/s', 'f') wombat%id_detfe_sed_depst = 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( & + 'detfe_sed_bury', 'Rate of permanent burial of detrital iron within sediment', & + 'h', '1', 's', 'mol/m^2/s', 'f') + wombat%id_detfe_sed_bury = 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( & 'caco3_sed_remin', 'Rate of remineralisation of CaCO3 in accumulated sediment', & 'h', '1', 's', 'mol/m^2/s', 'f') @@ -739,6 +757,12 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_caco3_sed_depst = 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( & + 'caco3_sed_bury', 'Rate of permanent burial of CaCO3 within sediment', & + 'h', '1', 's', 'molFe/m^2/s', 'f') + wombat%id_caco3_sed_bury = 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( & 'wdet100', 'Detritus export at 100 m (det*sinking rate)', & 'h', '1', 's', 'mol/m^2/s', 'f') @@ -1711,8 +1735,9 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim integer, intent(in) :: tau type(time_type), intent(in) :: model_time - integer :: isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau + integer :: isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, i, j real, dimension(:,:,:), pointer :: grid_tmask + real :: orgflux, burfac logical :: used call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, & @@ -1721,16 +1746,31 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim ! Move bottom reservoirs to sediment tracers !----------------------------------------------------------------------- call g_tracer_get_values(tracer_list, 'det', 'btm_reservoir', wombat%det_btm, isd, jsd) + call g_tracer_get_values(tracer_list, 'detfe', 'btm_reservoir', wombat%detfe_btm, isd, jsd) + call g_tracer_get_values(tracer_list, 'caco3', 'btm_reservoir', wombat%caco3_btm, isd, jsd) + + ! Calculate burial of deposited detritus (Dunne et al., 2007) + do i = isc, iec + do j = jsc, jec + orgflux = wombat%det_btm(i,j) / dt * 86400 * 1e6 * 1e4 ! umol C cm-2 day-1 + burfac = 0.013 + 0.53 * orgflux**2.0 / (7.0 + orgflux)**2.0 + wombat%det_sed_bury(i,j) = wombat%det_btm(i,j) * burfac ! [mol/m2] + wombat%detfe_sed_bury(i,j) = wombat%detfe_btm(i,j) * burfac ! [mol/m2] + wombat%caco3_sed_bury(i,j) = wombat%caco3_btm(i,j) * burfac ! [mol/m2] + enddo + enddo + wombat%det_btm = wombat%det_btm - wombat%det_sed_bury + wombat%detfe_btm = wombat%detfe_btm - wombat%detfe_sed_bury + wombat%caco3_btm = wombat%caco3_btm - wombat%caco3_sed_bury + call g_tracer_get_pointer(tracer_list, 'det_sediment', 'field', wombat%p_det_sediment) wombat%p_det_sediment(:,:,1) = wombat%p_det_sediment(:,:,1) + wombat%det_btm(:,:) ! [mol/m2] call g_tracer_set_values(tracer_list, 'det', 'btm_reservoir', 0.0) - call g_tracer_get_values(tracer_list, 'detfe', 'btm_reservoir', wombat%detfe_btm, isd, jsd) call g_tracer_get_pointer(tracer_list, 'detfe_sediment', 'field', wombat%p_detfe_sediment) wombat%p_detfe_sediment(:,:,1) = wombat%p_detfe_sediment(:,:,1) + wombat%detfe_btm(:,:) ! [mol/m2] call g_tracer_set_values(tracer_list, 'detfe', 'btm_reservoir', 0.0) - call g_tracer_get_values(tracer_list, 'caco3', 'btm_reservoir', wombat%caco3_btm, isd, jsd) call g_tracer_get_pointer(tracer_list, 'caco3_sediment', 'field', wombat%p_caco3_sediment) wombat%p_caco3_sediment(:,:,1) = wombat%p_caco3_sediment(:,:,1) + wombat%caco3_btm(:,:) ! [mol/m2] call g_tracer_set_values(tracer_list, 'caco3', 'btm_reservoir', 0.0) @@ -1749,6 +1789,18 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim used = g_send_data(wombat%id_caco3_sed_depst, wombat%caco3_btm / dt, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (wombat%id_det_sed_bury .gt. 0) & + used = g_send_data(wombat%id_det_sed_bury, wombat%det_sed_bury / dt, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_detfe_sed_bury .gt. 0) & + used = g_send_data(wombat%id_detfe_sed_bury, wombat%detfe_sed_bury / dt, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_caco3_sed_bury .gt. 0) & + used = g_send_data(wombat%id_caco3_sed_bury, wombat%caco3_sed_bury / dt, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + end subroutine generic_WOMBATlite_update_from_bottom !####################################################################### @@ -3745,10 +3797,13 @@ subroutine user_allocate_arrays allocate(wombat%caco3_prev(isd:ied, jsd:jed, 1:nk)); wombat%caco3_prev(:,:,:)=0.0 allocate(wombat%det_sed_remin(isd:ied, jsd:jed)); wombat%det_sed_remin(:,:)=0.0 allocate(wombat%det_btm(isd:ied, jsd:jed)); wombat%det_btm(:,:)=0.0 + allocate(wombat%det_sed_bury(isd:ied, jsd:jed)); wombat%det_sed_bury(:,:)=0.0 allocate(wombat%detfe_sed_remin(isd:ied, jsd:jed)); wombat%detfe_sed_remin(:,:)=0.0 allocate(wombat%detfe_btm(isd:ied, jsd:jed)); wombat%detfe_btm(:,:)=0.0 + allocate(wombat%detfe_sed_bury(isd:ied, jsd:jed)); wombat%detfe_sed_bury(:,:)=0.0 allocate(wombat%caco3_sed_remin(isd:ied, jsd:jed)); wombat%caco3_sed_remin(:,:)=0.0 allocate(wombat%caco3_btm(isd:ied, jsd:jed)); wombat%caco3_btm(:,:)=0.0 + allocate(wombat%caco3_sed_bury(isd:ied, jsd:jed)); wombat%caco3_sed_bury(:,:)=0.0 allocate(wombat%zw(isd:ied, jsd:jed, 1:nk)); wombat%zw(:,:,:)=0.0 allocate(wombat%zm(isd:ied, jsd:jed, 1:nk)); wombat%zm(:,:,:)=0.0 @@ -3882,10 +3937,13 @@ subroutine user_deallocate_arrays wombat%caco3_prev, & wombat%det_sed_remin, & wombat%det_btm, & + wombat%det_sed_bury, & wombat%detfe_sed_remin, & wombat%detfe_btm, & + wombat%detfe_sed_bury, & wombat%caco3_sed_remin, & wombat%caco3_btm, & + wombat%caco3_sed_bury, & wombat%zw, & wombat%zm) From 56b83695f5f92a65cfd40fa25709505d674206ec Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Thu, 12 Dec 2024 10:53:29 +1100 Subject: [PATCH 12/23] Computing omega_ara and omega_cal and added diagnostics to the output of the model --- generic_tracers/generic_WOMBATlite.F90 | 73 ++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index b9f3747..928adbb 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -195,7 +195,8 @@ module generic_WOMBATlite no3_vstf, dic_vstf, adic_vstf, alk_vstf real, dimension(:,:,:), allocatable :: & - htotal, ahtotal + htotal, ahtotal, & + omega_ara, omega_cal !----------------------------------------------------------------------- ! Arrays for tracer fields and source terms @@ -338,6 +339,8 @@ module generic_WOMBATlite id_paco2 = -1, & id_htotal = -1, & id_ahtotal = -1, & + id_omega_ara = -1, & + id_omega_cal = -1, & id_no3_vstf = -1, & id_dic_vstf = -1, & id_adic_vstf = -1, & @@ -637,6 +640,16 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_ahtotal = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & + 'omega_ara', 'Saturation state of aragonite', 'h', 'L', 's', ' ', 'f') + wombat%id_omega_ara = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'omega_cal', 'Saturation state of calcite', 'h', 'L', 's', ' ', 'f') + wombat%id_omega_cal = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & 'no3_vstf', 'Virtual flux of nitrate into ocean due to salinity restoring/correction', & 'h', '1', 's', 'mol/m^2/s', 'f') @@ -2046,7 +2059,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & co2_calc=trim(co2_calc), & zt=wombat%zw(:,:,k), & co2star=wombat%co2_csurf(:,:), alpha=wombat%co2_alpha(:,:), & - pCO2surf=wombat%pco2_csurf(:,:)) + pCO2surf=wombat%pco2_csurf(:,:), omega_arag=wombat%omega_ara(:,:,k), omega_calc=wombat%omega_cal(:,:,k)) call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & @@ -2077,7 +2090,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%htotallo(:,:), wombat%htotalhi(:,:), & wombat%htotal(:,:,k), & co2_calc=trim(co2_calc), & - zt=wombat%zw(:,:,k)) + zt=wombat%zw(:,:,k), omega_arag=wombat%omega_ara(:,:,k), omega_calc=wombat%omega_cal(:,:,k)) call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & @@ -2246,9 +2259,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! 6. Phytoplankton uptake of iron ! ! 7. Iron chemistry ! ! 8. Mortality scalings and grazing ! - ! 9. Sources and sinks ! - ! 10. Tracer tendencies ! - ! 11. Check for conservation by ecosystem component ! + ! 9. CaCO3 calculations ! + ! 10. Sources and sinks ! + ! 11. Tracer tendencies ! + ! 12. Check for conservation by ecosystem component ! ! ! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! @@ -2534,7 +2548,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & fesol4 = 10**(-0.2965 - 0.7881*zval**0.5 - 4086.0/ztemk) fesol5 = 10**(4.4466 - 0.8505*zval**0.5 - 7980.0/ztemk) hp = 10**(-7.9) - if (wombat%ahtotal(i,j,k).gt.0.0) hp = wombat%ahtotal(i,j,k) + if (wombat%htotal(i,j,k).gt.0.0) hp = wombat%htotal(i,j,k) fe3sol = fesol1 * ( hp**3 + fesol2 * hp**2 + fesol3 * hp + fesol4 + fesol5 / hp ) *1e9 ! Estimate total colloidal iron @@ -2608,7 +2622,32 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! - ! [Step 9] Sources and sinks ! + ! [Step 9] CaCO3 calculations ! + !-----------------------------------------------------------------------! + !-----------------------------------------------------------------------! + !-----------------------------------------------------------------------! + + + !! PIC:POC ratio is a function of the substrate:inhibitor ratio, which is the HCO3- to free H+ ions ratio (mol/nmol), + !! following Lehmann & Bach (2024). We also add a T-dependent function to scale down CaCO3 production in waters colder + !! than 3 degrees C based off the observation of no E hux growth beneath this (Fielding 2013; L&O) + !wombat%pic2poc(i,j,k) = min(0.3, (wombat%f_inorg + 10**(-3.0 + 4.31 * & + ! wombat%hco3(i,j,k)*1e-3 / (wombat%hfree(i,j,k)*1e9))) * & + ! (0.55 + 0.45 * tanh(Temp(i,j,k) - 4.0)) + + !! The dissolution rate is a function of omegas for calcite and aragonite, as well the + !! concentration of POC, following Kwon et al., 2024, Science Advances; Table S1 + !diss_cal = (0.253 * max(0.0, 1.0 - wombat%omega_cal(i,j,k))**2.2) / 86400.0 + !diss_ara = (0.090 * max(0.0, 1.0 - wombat%omega_ara(i,j,k))**1.5) / 86400.0 + !diss_det = (0.250 * biodet * fbc * detlrem(i,j)) + !wombat%caco3dis(i,j,k) = diss_cal + diss_ara + diss_det + + + + !-----------------------------------------------------------------------! + !-----------------------------------------------------------------------! + !-----------------------------------------------------------------------! + ! [Step 10] Sources and sinks ! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! @@ -2664,7 +2703,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! - ! [Step 10] Tracer tendencies ! + ! [Step 11] Tracer tendencies ! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! @@ -2843,7 +2882,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! - ! [Step 11] Check for conservation of mass by ecosystem component ! + ! [Step 12] Check for conservation of mass by ecosystem component ! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! @@ -3091,6 +3130,14 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_ahtotal, wombat%ahtotal, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_omega_ara .gt. 0) & + used = g_send_data(wombat%id_omega_ara, wombat%omega_ara, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_omega_cal .gt. 0) & + used = g_send_data(wombat%id_omega_cal, wombat%omega_cal, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_no3_vstf .gt. 0) & used = g_send_data(wombat%id_no3_vstf, wombat%no3_vstf, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) @@ -3545,7 +3592,7 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il co2_calc=trim(co2_calc), & zt=dzt(:,:,1), & co2star=wombat%co2_csurf(:,:), alpha=wombat%co2_alpha(:,:), & - pCO2surf=wombat%pco2_csurf(:,:)) + pCO2surf=wombat%pco2_csurf(:,:), omega_arag=wombat%omega_ara(:,:,1), omega_calc=wombat%omega_cal(:,:,1)) call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,1), & SST(:,:), SSS(:,:), & @@ -3704,6 +3751,8 @@ subroutine user_allocate_arrays allocate(wombat%ahtotallo(isd:ied, jsd:jed)); wombat%ahtotallo(:,:)=0.0 allocate(wombat%ahtotalhi(isd:ied, jsd:jed)); wombat%ahtotalhi(:,:)=0.0 allocate(wombat%ahtotal(isd:ied, jsd:jed, 1:nk)); wombat%ahtotal(:,:,:)=wombat%htotal_in + allocate(wombat%omega_ara(isd:ied, jsd:jed, 1:nk)); wombat%omega_ara(:,:,:)=1.0 + allocate(wombat%omega_cal(isd:ied, jsd:jed, 1:nk)); wombat%omega_cal(:,:,:)=1.0 allocate(wombat%sio2(isd:ied, jsd:jed)); wombat%sio2(:,:)=wombat%sio2_surf allocate(wombat%co2_csurf(isd:ied, jsd:jed)); wombat%co2_csurf(:,:)=0.0 allocate(wombat%co2_alpha(isd:ied, jsd:jed)); wombat%co2_alpha(:,:)=0.0 @@ -3846,6 +3895,8 @@ subroutine user_deallocate_arrays wombat%ahtotallo, & wombat%ahtotalhi, & wombat%ahtotal, & + wombat%omega_ara, & + wombat%omega_cal, & wombat%co2_csurf, & wombat%co2_alpha, & wombat%co2_sc_no, & From 09eaaf06bf6f5d9846ef2cdb11d09e32ab937e33 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Fri, 13 Dec 2024 14:39:37 +1100 Subject: [PATCH 13/23] Considering CaCO3 dynamics: * Dissolution of CaCO3 based on detrital remin and saturation states of aragonite and calcite (Kwon et al., 2024) * Precipation of CaCO3 based on HCO3- to H+ ratio (Lehmann et al., in prep) * Sinking rate of material affected by ballasting, specifically CaCO3/Det ratio (Bach et al., 2016) These feedbacks can be turned on and off using the "caco3_dynamics" logical --- generic_tracers/FMS_ocmip2_co2calc.F90 | 114 ++++++++++++++- generic_tracers/generic_WOMBATlite.F90 | 190 +++++++++++++++++-------- 2 files changed, 243 insertions(+), 61 deletions(-) diff --git a/generic_tracers/FMS_ocmip2_co2calc.F90 b/generic_tracers/FMS_ocmip2_co2calc.F90 index e5345ad..0b17a42 100644 --- a/generic_tracers/FMS_ocmip2_co2calc.F90 +++ b/generic_tracers/FMS_ocmip2_co2calc.F90 @@ -209,7 +209,7 @@ subroutine FMS_ocmip2_co2calc(dope_vec, mask, & ! local variables ! integer :: isc, iec, jsc, jec -integer :: i,j +integer :: i,j,ipc real :: alpha_internal real :: bt real :: co2star_internal @@ -229,17 +229,32 @@ subroutine FMS_ocmip2_co2calc(dope_vec, mask, & real :: ks real :: ksi real :: kw +real :: Kspa +real :: Kspc +real :: calcium real :: log100 real :: s2 real :: scl real :: sqrtis real :: sqrts +real :: s15 real :: st real :: tk real :: tk100 real :: tk1002 real :: logf_of_s +real :: prb real :: salinity +real :: R +real :: total2free_0p, total2free, ks_0p, kf_0p, free2SWS, total2SWS, SWS2total, free2SWS_0p, total2SWS_0p +real, dimension(12) :: deltav, deltak, lnkpok0 +real, dimension(12) :: a0, a1, a2, b0, b1, b2 +DATA a0 /-25.5, -15.82, -29.48, -20.02, -18.03, -9.78, -48.76, -45.96, -14.51, -23.12, -26.57, -29.48/ +DATA a1 /0.1271, -0.0219, 0.1622, 0.1119, 0.0466, -0.0090, 0.5304, 0.5304, 0.1211, 0.1758, 0.2020, 0.1622/ +DATA a2 /0.0, 0.0, -2.608e-3, -1.409e-3, 0.316e-3, -0.942e-3, 0.0, 0.0, -0.321e-3, -2.647e-3, -3.042e-3, -2.6080e-3/ +DATA b0 /-3.08e-3, 1.13e-3, -2.84e-3, -5.13e-3, -4.53e-3, -3.91e-3, -11.76e-3, -11.76e-3, -2.67e-3, -5.15e-3, -4.08e-3, -2.84e-3/ +DATA b1 /0.0877e-3, -0.1475e-3, 0.0, 0.0794e-3, 0.09e-3, 0.054e-3, 0.3692e-3, 0.3692e-3, 0.0427e-3, 0.09e-3, 0.0714e-3, 0.0/ +DATA b2 /12*0.0/ character(len=10) :: co2_calc_method @@ -254,8 +269,7 @@ subroutine FMS_ocmip2_co2calc(dope_vec, mask, & co2_calc_method = 'ocmip2' end if - - +R = 83.14472 ! Set the loop indices. isc = dope_vec%isc ; iec = dope_vec%iec @@ -364,8 +378,10 @@ subroutine FMS_ocmip2_co2calc(dope_vec, mask, & sqrtis = sqrt(max(0.0,is)) s2 = s_in(i,j) * s_in(i,j) sqrts = sqrt(max(0.0,s_in(i,j))) + s15 = sqrts**3 scl = s_in(i,j) / 1.80655 logf_of_s = log(1.0 - 0.001005 * s_in(i,j)) + prb = zt(i,j) / 10.0 ! ! k0 from Weiss 1974 ! @@ -478,6 +494,85 @@ subroutine FMS_ocmip2_co2calc(dope_vec, mask, & ! ft = 0.000067 / 18.9984 * scl ! +! Omega saturation states +! + if (present(omega_arag)) then + Kspa = 10.0**(-171.945 - 0.077993*tk + 2903.293/tk + 71.595*LOG10(tk) & + + (-0.068393 + 0.0017276*tk + 88.135/tk)*sqrts & + - 0.10018*s_in(i,j) + 0.0059415*s15 ) + endif + if (present(omega_calc)) then + Kspc = 10.0**(-171.9065 - 0.077993*tk + 2839.319/tk + 71.595*LOG10(tk) & + + (-0.77712 + 0.0028426*tk + 178.34/tk)*sqrts & + - 0.07711*s_in(i,j) + 0.0041249*s15 ) + endif + + !!! ------------------------------------------- !!! + !!! Pressure corrections to the above constants !!! (Pearse J. Buchanan, July 2024) + !!! ------------------------------------------- !!! (copied from mocsy) + ! This must be done to ensure that the co2 sys ! + ! calculations are accurate beneath the surface ! + + do ipc=1,12 + deltav(ipc) = a0(ipc) + a1(ipc)*t_in(i,j) + a2(ipc)*t_in(i,j)*t_in(i,j) + deltak(ipc) = b0(ipc) + b1(ipc)*t_in(i,j) + b2(ipc)*t_in(i,j)*t_in(i,j) + lnkpok0(ipc) = ( -deltav(ipc) + (0.5*deltak(ipc) * prb) )*prb/(R*tk) + enddo + + ! Conversion factor total -> free scale at pressure zero + total2free_0p = 1.0/(1.0 + st/ks) ! Kfree = Ktotal*total2free + ks_0p = ks*1 + ks = ks * EXP(lnkpok0(5)) + ! Conversion factor total -> free scale + total2free = 1.0/(1.0 + st/ks) ! Kfree = Ktotal*total2free + + kf_0p = kf * total2free_0p + kf = kf_0p * EXP(lnkpok0(6)) + kf = kf / total2free + + ! Convert between seawater and total hydrogen (pH) scales + free2SWS = 1.0 + st/ks + ft/(kf*total2free) ! using Kf on free scale + total2SWS = total2free * free2SWS ! KSWS = Ktotal*total2SWS + SWS2total = 1.0 / total2SWS + ! Conversion at pressure zero + free2SWS_0p = 1.0 + st/ks_0p + ft/(kf_0p) ! using Kf on free scale + total2SWS_0p = total2free_0p * free2SWS_0p ! KSWS = Ktotal*total2SWS + + ! Convert from Total to Seawater scale before pressure correction + ! Must change to SEAWATER scale: Kb + kb = kb*total2SWS_0p + + ! Already on SEAWATER scale: K1p, K2p, K3p, Kb, Ksi, Kw + + ! Other contants (keep on another scale): + ! - K0 (independent of pH scale, already pressure corrected) + ! - Ks (already on Free scale; already pressure corrected) + ! - Kf (already on Total scale; already pressure corrected) + ! - Kspc, Kspa (independent of pH scale; pressure-corrected below) + + ! Perform actual pressure correction (on seawater scale) + k1 = k1*EXP(lnkpok0(1)) + k2 = k2*EXP(lnkpok0(2)) + kb = kb*EXP(lnkpok0(3)) + kw = kw*EXP(lnkpok0(4)) + Kspc = Kspc*EXP(lnkpok0(7)) + Kspa = Kspa*EXP(lnkpok0(8)) + k1p = k1p*EXP(lnkpok0(9)) + k2p = k2p*EXP(lnkpok0(10)) + k3p = k3p*EXP(lnkpok0(11)) + ksi = ksi*EXP(lnkpok0(12)) + + ! Convert back to original total scale: + k1 = k1 *SWS2total + k2 = k2 *SWS2total + k1p = k1p*SWS2total + k2p = k2p*SWS2total + k3p = k3p*SWS2total + kb = kb *SWS2total + ksi = ksi*SWS2total + kw = kw *SWS2total + +! !*********************************************************************** ! ! Calculate [H+] total when DIC and TA are known at T, S and 1 atm. @@ -515,6 +610,12 @@ subroutine FMS_ocmip2_co2calc(dope_vec, mask, & k1 * htotal(i,j) + k1 * k2) if (present(co2star)) co2star(i,j) = co2star_internal if (present(co3_ion)) co3_ion(i,j) = co2star_internal * k1 * k2 / htotal2 + if (present(omega_arag) .or. present(omega_calc)) then + co3_ion(i,j) = co2star_internal * k1 * k2 / htotal2 + calcium = (0.02128/40.078)*s_in(i,j)/1.80655 + if (present(omega_arag)) omega_arag(i,j) = (calcium * co3_ion(i,j)) / Kspa + if (present(omega_calc)) omega_calc(i,j) = (calcium * co3_ion(i,j)) / Kspc + endif ! ! Weiss & Price (1980, Mar. Chem., 8, 347-359; Eq 13 with table 6 ! values) @@ -548,7 +649,12 @@ subroutine FMS_ocmip2_co2calc(dope_vec, mask, & if (present(pco2surf)) then !{ pCO2surf(i,j) = 0.0 endif !} - + if (present(omega_arag)) then + omega_arag(i,j) = 0.0 + endif + if (present(omega_calc)) then + omega_calc(i,j) = 0.0 + endif endif !}mask diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 928adbb..0f46fd6 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -122,6 +122,8 @@ module generic_WOMBATlite ! See user_add_params for descriptions of each parameter logical :: & init, & + caco3_dynamics, & + burial, & force_update_fluxes ! Set in generic_tracer_nml real :: & @@ -153,7 +155,6 @@ module generic_WOMBATlite phybiot, & caco3lrem, & caco3lrem_sed, & - wcaco3, & f_inorg, & ligand, & knano_dfe, & @@ -196,7 +197,8 @@ module generic_WOMBATlite real, dimension(:,:,:), allocatable :: & htotal, ahtotal, & - omega_ara, omega_cal + omega_ara, omega_cal, & + co3, co2_star !----------------------------------------------------------------------- ! Arrays for tracer fields and source terms @@ -303,6 +305,8 @@ module generic_WOMBATlite zooslopdet, & reminr, & detremi, & + pic2poc, & + dissrat, & caldiss, & no3_prev, & caco3_prev, & @@ -322,7 +326,8 @@ module generic_WOMBATlite real, dimension(:,:,:), pointer :: & p_wdet, & - p_wdetfe + p_wdetfe, & + p_wcaco3 real, dimension(:,:), pointer :: & p_no3_stf, & @@ -341,6 +346,8 @@ module generic_WOMBATlite id_ahtotal = -1, & id_omega_ara = -1, & id_omega_cal = -1, & + id_co3 = -1, & + id_co2_star = -1, & id_no3_vstf = -1, & id_dic_vstf = -1, & id_adic_vstf = -1, & @@ -386,6 +393,8 @@ module generic_WOMBATlite id_zooslopdet = -1, & id_reminr = -1, & id_detremi = -1, & + id_pic2poc = -1, & + id_dissrat = -1, & id_caldiss = -1, & id_phy_mumax = -1, & id_phy_mu = -1, & @@ -650,6 +659,16 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_omega_cal = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & + 'co3', 'Carbonate ion concentration', 'h', 'L', 's', 'mol/kg', 'f') + wombat%id_co3 = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'co2_star', 'CO2* (CO2(g) + H2CO3)) concentration', 'h', 'L', 's', 'mol/kg', 'f') + wombat%id_co2_star = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + vardesc_temp = vardesc( & 'no3_vstf', 'Virtual flux of nitrate into ocean due to salinity restoring/correction', & 'h', '1', 's', 'mol/m^2/s', 'f') @@ -980,17 +999,27 @@ subroutine generic_WOMBATlite_register_diag(diag_list) init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'reminr', 'rate of remineralisation', 'h', 'L', 's', '/s', 'f') + 'reminr', 'Rate of remineralisation', 'h', 'L', 's', '/s', 'f') wombat%id_reminr = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'detremi', 'Remineralisation rate of detritus', 'h', 'L', 's', 'molC/kg/s', 'f') + 'detremi', 'Remineralisation of detritus', 'h', 'L', 's', 'molC/kg/s', 'f') wombat%id_detremi = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'caldiss', 'Dissolution rate of CaCO3', 'h', 'L', 's', 'molCaCO3/kg/s', 'f') + 'pic2poc', 'Inorganic (CaCO3) to organic carbon ratio', 'h', 'L', 's', ' ', 'f') + wombat%id_pic2poc = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'dissrat', 'Dissolution rate of CaCO3', 'h', 'L', 's', '/s', 'f') + wombat%id_dissrat = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + + vardesc_temp = vardesc( & + 'caldiss', 'Dissolution of CaCO3', 'h', 'L', 's', 'molCaCO3/kg/s', 'f') wombat%id_caldiss = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) @@ -1348,6 +1377,14 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('phybiot', wombat%phybiot, 0.6) + ! Do dynamic CaCO3 precipiation, dissolution and ballasting? + !----------------------------------------------------------------------- + call g_tracer_add_param('caco3_dynamics', wombat%caco3_dynamics, .true. ) + + ! Permanental burial organics and CaCO3 in sediments? + !----------------------------------------------------------------------- + call g_tracer_add_param('burial', wombat%burial, .true. ) + ! CaCO3 remineralisation rate constant [1/s] !----------------------------------------------------------------------- ! Default value matches 0.001714 day-1 in Ziehn et al 2020; differs from @@ -1360,7 +1397,7 @@ subroutine user_add_params ! CaCO3 inorganic fraction [1] !----------------------------------------------------------------------- - call g_tracer_add_param('f_inorg', wombat%f_inorg, 0.05) + call g_tracer_add_param('f_inorg', wombat%f_inorg, 0.04) ! Background concentration of iron-binding ligand [umol/m3] !----------------------------------------------------------------------- @@ -1426,12 +1463,6 @@ subroutine user_add_tracers(tracer_list) call g_tracer_start_param_list(package_name) - ! CaCO3 sinking velocity [m/s] - !----------------------------------------------------------------------- - ! Default value matches Ziehn et al 2020 but differs from Hayashida et - ! al 2020 - call g_tracer_add_param('wcaco3', wombat%wcaco3, 5.0/86400.0) - ! Detritus sinking velocity [m/s] !----------------------------------------------------------------------- ! Default value matches Ziehn et al 2020 but differs from Hayashida et @@ -1565,7 +1596,8 @@ subroutine user_add_tracers(tracer_list) longname = 'CaCO3', & units = 'mol/kg', & prog = .true., & - sink_rate = wombat%wcaco3, & + move_vertical = .true., & + flux_bottom = .false., & btm_reservoir = .true.) ! ADIC (Natural + anthropogenic dissolved inorganic carbon) @@ -1763,6 +1795,7 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim call g_tracer_get_values(tracer_list, 'caco3', 'btm_reservoir', wombat%caco3_btm, isd, jsd) ! Calculate burial of deposited detritus (Dunne et al., 2007) + if (wombat%burial) then do i = isc, iec do j = jsc, jec orgflux = wombat%det_btm(i,j) / dt * 86400 * 1e6 * 1e4 ! umol C cm-2 day-1 @@ -1775,6 +1808,7 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim wombat%det_btm = wombat%det_btm - wombat%det_sed_bury wombat%detfe_btm = wombat%detfe_btm - wombat%detfe_sed_bury wombat%caco3_btm = wombat%caco3_btm - wombat%caco3_sed_bury + endif call g_tracer_get_pointer(tracer_list, 'det_sediment', 'field', wombat%p_det_sediment) wombat%p_det_sediment(:,:,1) = wombat%p_det_sediment(:,:,1) + wombat%det_btm(:,:) ! [mol/m2] @@ -1920,6 +1954,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: phy_pisl, phy_pisl2 real :: pchl_pisl, pchl_mumin, pchl_muopt real, dimension(:,:), allocatable :: ek_bgr, par_bgr_mid, par_bgr_top + real, dimension(:), allocatable :: wsink real, dimension(4,61) :: zbgr real :: ztemk, fe_keq, fe_par, fe_sfe, fe_tfe, partic real :: fesol1, fesol2, fesol3, fesol4, fesol5, hp, fe3sol @@ -1927,6 +1962,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: phy_Fe2C, zoo_Fe2C, det_Fe2C real :: phy_minqfe, phy_maxqfe real :: zoo_slmor, epsmin + real :: hco3, diss_cal, diss_ara, diss_det real, dimension(:,:,:,:), allocatable :: n_pools, c_pools logical :: used @@ -2058,7 +2094,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%htotal(:,:,k), & co2_calc=trim(co2_calc), & zt=wombat%zw(:,:,k), & - co2star=wombat%co2_csurf(:,:), alpha=wombat%co2_alpha(:,:), & + co2star=wombat%co2_csurf(:,:), alpha=wombat%co2_alpha(:,:), co3_ion=wombat%co3(:,:,k), & pCO2surf=wombat%pco2_csurf(:,:), omega_arag=wombat%omega_ara(:,:,k), omega_calc=wombat%omega_cal(:,:,k)) call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & @@ -2079,6 +2115,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_set_values(tracer_list, 'adic', 'alpha', wombat%aco2_alpha, isd, jsd) call g_tracer_set_values(tracer_list, 'adic', 'csurf', wombat%aco2_csurf, isd, jsd) + wombat%co2_star(:,:,1) = wombat%co2_csurf(:,:) + else call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & @@ -2089,9 +2127,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg)), & wombat%htotallo(:,:), wombat%htotalhi(:,:), & wombat%htotal(:,:,k), & - co2_calc=trim(co2_calc), & - zt=wombat%zw(:,:,k), omega_arag=wombat%omega_ara(:,:,k), omega_calc=wombat%omega_cal(:,:,k)) - + co2_calc=trim(co2_calc), zt=wombat%zw(:,:,k), & + co2star=wombat%co2_star(:,:,k), co3_ion=wombat%co3(:,:,k), & + omega_arag=wombat%omega_ara(:,:,k), omega_calc=wombat%omega_cal(:,:,k)) + call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & Temp(:,:,k), Salt(:,:,k), & min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & @@ -2155,6 +2194,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zooslopdet(:,:,:) = 0.0 wombat%reminr(:,:,:) = 0.0 wombat%detremi(:,:,:) = 0.0 + wombat%pic2poc(:,:,:) = 0.0 + wombat%dissrat(:,:,:) = 0.0 wombat%caldiss(:,:,:) = 0.0 wombat%export_prod(:,:) = 0.0 wombat%export_inorg(:,:) = 0.0 @@ -2181,6 +2222,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zeuphot(:,:) = 0.0 ! Allocate and initialise some multi-dimensional variables + allocate(wsink(nk)); wsink(:)=0.0 allocate(ek_bgr(nk,3)); ek_bgr(:,:)=0.0 allocate(par_bgr_mid(nk,3)); par_bgr_mid(:,:)=0.0 allocate(par_bgr_top(nk,3)); par_bgr_top(:,:)=0.0 @@ -2382,10 +2424,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & enddo !} k ! dts: in WOMBAT v3, export production was calucated before updating the source terms so we do - ! the same here + ! the same here. pjb: need to fix this. k = k100(i,j) - wombat%export_prod(i,j) = (wombat%Rho_0 * wombat%wdetbio) * wombat%f_det(i,j,k) ! [mol/m2/s] - wombat%export_inorg(i,j) = (wombat%Rho_0 * wombat%wcaco3) * wombat%f_caco3(i,j,k) ! [mol/m2/s] + !wombat%export_prod(i,j) = (wombat%Rho_0 * wombat%wdetbio) * wombat%f_det(i,j,k) ! [mol/m2/s] + !wombat%export_inorg(i,j) = (wombat%Rho_0 * wombat%wcaco3) * wombat%f_caco3(i,j,k) ! [mol/m2/s] enddo; enddo wombat%no3_prev(:,:,:) = wombat%f_no3(:,:,:) @@ -2627,22 +2669,30 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! - - !! PIC:POC ratio is a function of the substrate:inhibitor ratio, which is the HCO3- to free H+ ions ratio (mol/nmol), - !! following Lehmann & Bach (2024). We also add a T-dependent function to scale down CaCO3 production in waters colder - !! than 3 degrees C based off the observation of no E hux growth beneath this (Fielding 2013; L&O) - !wombat%pic2poc(i,j,k) = min(0.3, (wombat%f_inorg + 10**(-3.0 + 4.31 * & - ! wombat%hco3(i,j,k)*1e-3 / (wombat%hfree(i,j,k)*1e9))) * & - ! (0.55 + 0.45 * tanh(Temp(i,j,k) - 4.0)) + if (wombat%caco3_dynamics) then - !! The dissolution rate is a function of omegas for calcite and aragonite, as well the - !! concentration of POC, following Kwon et al., 2024, Science Advances; Table S1 - !diss_cal = (0.253 * max(0.0, 1.0 - wombat%omega_cal(i,j,k))**2.2) / 86400.0 - !diss_ara = (0.090 * max(0.0, 1.0 - wombat%omega_ara(i,j,k))**1.5) / 86400.0 - !diss_det = (0.250 * biodet * fbc * detlrem(i,j)) - !wombat%caco3dis(i,j,k) = diss_cal + diss_ara + diss_det + ! PIC:POC ratio is a function of the substrate:inhibitor ratio, which is the + ! HCO3- to free H+ ions ratio (mol/umol), following Lehmann & Bach (2024). + ! We also add a T-dependent function to scale down CaCO3 production in waters colder + ! than 3 degrees C based off the observation of no E hux growth beneath this (Fielding 2013; L&O) + hco3 = wombat%f_dic(i,j,k) - wombat%co3(i,j,k) - wombat%co2_star(i,j,k) + wombat%pic2poc(i,j,k) = min(0.3, (wombat%f_inorg + 10**(-3.0 + 4.31 * & + hco3 / (wombat%htotal(i,j,k)*1e6))) * & + (0.55 + 0.45 * tanh(Temp(i,j,k) - 4.0)) ) + ! The dissolution rate is a function of omegas for calcite and aragonite, as well the + ! concentration of POC, following Kwon et al., 2024, Science Advances; Table S1 + diss_cal = (0.253 * max(0.0, 1.0 - wombat%omega_cal(i,j,k))**2.2) / 86400.0 + diss_ara = (0.090 * max(0.0, 1.0 - wombat%omega_ara(i,j,k))**1.5) / 86400.0 + diss_det = (0.250 * wombat%reminr(i,j,k) * biodet**2.0) + wombat%dissrat(i,j,k) = diss_cal + diss_ara + diss_det + else + + wombat%pic2poc(i,j,k) = wombat%f_inorg + 0.025 + wombat%dissrat(i,j,k) = wombat%caco3lrem + + endif !-----------------------------------------------------------------------! !-----------------------------------------------------------------------! @@ -2694,7 +2744,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif if (wombat%f_caco3(i,j,k) .gt. epsi) then - wombat%caldiss(i,j,k) = wombat%caco3lrem * wombat%f_caco3(i,j,k) ! [mol/kg/s] + wombat%caldiss(i,j,k) = wombat%dissrat(i,j,k) * wombat%f_caco3(i,j,k) ! [mol/kg/s] else wombat%caldiss(i,j,k) = 0.0 endif @@ -2805,9 +2855,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Equation for CaCO3 ! [molCaCO3/kg] !----------------------------------------------------------------------- wombat%f_caco3(i,j,k) = wombat%f_caco3(i,j,k) + dtsb * ( & - wombat%zooslopphy(i,j,k) * wombat%f_inorg + & - wombat%phymort(i,j,k) * wombat%f_inorg + & - wombat%zoomort(i,j,k) * wombat%f_inorg - & + wombat%zooslopphy(i,j,k) * wombat%pic2poc(i,j,k) + & + wombat%phymort(i,j,k) * wombat%pic2poc(i,j,k) + & + wombat%zoomort(i,j,k) * wombat%pic2poc(i,j,k) - & wombat%caldiss(i,j,k) ) ! Equation for DIC ! [molC/kg] @@ -2819,9 +2869,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zooexcrdet(i,j,k) + & wombat%phyresp(i,j,k) - & wombat%phygrow(i,j,k) - & - wombat%zooslopphy(i,j,k) * wombat%f_inorg - & - wombat%phymort(i,j,k) * wombat%f_inorg - & - wombat%zoomort(i,j,k) * wombat%f_inorg + & + wombat%zooslopphy(i,j,k) * wombat%pic2poc(i,j,k) - & + wombat%phymort(i,j,k) * wombat%pic2poc(i,j,k) - & + wombat%zoomort(i,j,k) * wombat%pic2poc(i,j,k) + & wombat%caldiss(i,j,k) ) ! Equation for aDIC ! [molC/kg] @@ -2833,9 +2883,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zooexcrdet(i,j,k) + & wombat%phyresp(i,j,k) - & wombat%phygrow(i,j,k) - & - wombat%zooslopphy(i,j,k) * wombat%f_inorg - & - wombat%phymort(i,j,k) * wombat%f_inorg - & - wombat%zoomort(i,j,k) * wombat%f_inorg + & + wombat%zooslopphy(i,j,k) * wombat%pic2poc(i,j,k) - & + wombat%phymort(i,j,k) * wombat%pic2poc(i,j,k) - & + wombat%zoomort(i,j,k) * wombat%pic2poc(i,j,k) + & wombat%caldiss(i,j,k) ) ! Equation for ALK ! [molC/kg] @@ -2848,9 +2898,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zooexcrdet(i,j,k) - & wombat%phyresp(i,j,k) ) + dtsb * 2.0 * ( & wombat%caldiss(i,j,k) - & - wombat%zooslopphy(i,j,k) * wombat%f_inorg - & - wombat%phymort(i,j,k) * wombat%f_inorg - & - wombat%zoomort(i,j,k) * wombat%f_inorg ) + wombat%zooslopphy(i,j,k) * wombat%pic2poc(i,j,k) - & + wombat%phymort(i,j,k) * wombat%pic2poc(i,j,k) - & + wombat%zoomort(i,j,k) * wombat%pic2poc(i,j,k) ) ! Extra equation for iron ! [molFe/kg] !----------------------------------------------------------------------- @@ -2942,9 +2992,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & print*, " zooexcrphy (molC/kg/s) = ", wombat%zooexcrphy(i,j,k) print*, " zooexcrdet (molC/kg/s) = ", wombat%zooexcrdet(i,j,k) print*, " phyresp (molC/kg/s) = ", wombat%phyresp(i,j,k) - print*, " zooslopphy * f_inorg (molC/kg/s) = ", wombat%zooslopphy(i,j,k)*wombat%f_inorg - print*, " phymort * f_inorg (molC/kg/s) = ", wombat%phymort(i,j,k)*wombat%f_inorg - print*, " zoomort * f_inorg (molC/kg/s) = ", wombat%zoomort(i,j,k)*wombat%f_inorg + print*, " zooslopphy * pic2poc(i,j,k) (molC/kg/s) = ", wombat%zooslopphy(i,j,k)*wombat%pic2poc(i,j,k) + print*, " phymort * pic2poc(i,j,k) (molC/kg/s) = ", wombat%phymort(i,j,k)*wombat%pic2poc(i,j,k) + print*, " zoomort * pic2poc(i,j,k) (molC/kg/s) = ", wombat%zoomort(i,j,k)*wombat%pic2poc(i,j,k) print*, " caldiss (molC/kg/s) = ", wombat%caldiss(i,j,k) print*, " " stop @@ -3046,23 +3096,25 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !----------------------------------------------------------------------- call g_tracer_get_pointer(tracer_list, 'det', 'vmove', wombat%p_wdet) ! [m/s] call g_tracer_get_pointer(tracer_list, 'detfe', 'vmove', wombat%p_wdetfe) ! [m/s] + call g_tracer_get_pointer(tracer_list, 'caco3', 'vmove', wombat%p_wcaco3) ! [m/s] ! Variable sinking rates of organic detritus (positive for sinking when GOLDtridiag == .true.) ! (negative for sinking when IOWtridiag ==.true.) do j = jsc,jec; do i = isc,iec; if (grid_kmt(i,j).gt.0) then biophy1 = max(epsi, wombat%f_phy(i,j,1) ) / mmol_m3_to_mol_kg ![mmol/m3] - wombat%p_wdet(i,j,:) = wombat%wdetbio * max(1e-3, biophy1 - wombat%phybiot)**(0.21) - wombat%p_wdetfe(i,j,:) = wombat%wdetbio * max(1e-3, biophy1 - wombat%phybiot)**(0.21) + wsink(:) = wombat%wdetbio * max(1e-3, biophy1 - wombat%phybiot)**(0.21) do k=1,nk - wombat%p_wdet(i,j,k) = wombat%p_wdet(i,j,k) + max(0.0, & - wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wombat%p_wdet(i,j,k))) - wombat%p_wdetfe(i,j,k) = wombat%p_wdetfe(i,j,k) + max(0.0, & - wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wombat%p_wdetfe(i,j,k))) + wsink(k) = wsink(k) + 30.0/86400.0 * min(1.0, (wombat%f_caco3(i,j,k) / (wombat%f_det(i,j,k) + epsi))) + wsink(k) = wsink(k) + max(0.0, wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wsink(k))) enddo + wombat%p_wdet(i,j,:) = wsink(:) + wombat%p_wdetfe(i,j,:) = wsink(:) + wombat%p_wcaco3(i,j,:) = wsink(:) else wombat%p_wdet(i,j,:) = 0.0 wombat%p_wdetfe(i,j,:) = 0.0 + wombat%p_wcaco3(i,j,:) = 0.0 endif enddo; enddo @@ -3138,6 +3190,14 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_omega_cal, wombat%omega_cal, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_co3 .gt. 0) & + used = g_send_data(wombat%id_co3, wombat%co3, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_co2_star .gt. 0) & + used = g_send_data(wombat%id_co2_star, wombat%co2_star, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_no3_vstf .gt. 0) & used = g_send_data(wombat%id_no3_vstf, wombat%no3_vstf, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) @@ -3330,6 +3390,14 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_detremi, wombat%detremi, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_pic2poc .gt. 0) & + used = g_send_data(wombat%id_pic2poc, wombat%pic2poc, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + + if (wombat%id_dissrat .gt. 0) & + used = g_send_data(wombat%id_dissrat, wombat%dissrat, model_time, & + rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + if (wombat%id_caldiss .gt. 0) & used = g_send_data(wombat%id_caldiss, wombat%caldiss, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) @@ -3591,7 +3659,7 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il wombat%htotal(:,:,1), & co2_calc=trim(co2_calc), & zt=dzt(:,:,1), & - co2star=wombat%co2_csurf(:,:), alpha=wombat%co2_alpha(:,:), & + co2star=wombat%co2_csurf(:,:), alpha=wombat%co2_alpha(:,:), co3_ion=wombat%co3(:,:,1), & pCO2surf=wombat%pco2_csurf(:,:), omega_arag=wombat%omega_ara(:,:,1), omega_calc=wombat%omega_cal(:,:,1)) call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,1), & @@ -3753,6 +3821,8 @@ subroutine user_allocate_arrays allocate(wombat%ahtotal(isd:ied, jsd:jed, 1:nk)); wombat%ahtotal(:,:,:)=wombat%htotal_in allocate(wombat%omega_ara(isd:ied, jsd:jed, 1:nk)); wombat%omega_ara(:,:,:)=1.0 allocate(wombat%omega_cal(isd:ied, jsd:jed, 1:nk)); wombat%omega_cal(:,:,:)=1.0 + allocate(wombat%co3(isd:ied, jsd:jed, 1:nk)); wombat%co3(:,:,:)=0.0 + allocate(wombat%co2_star(isd:ied, jsd:jed, 1:nk)); wombat%co2_star(:,:,:)=0.0 allocate(wombat%sio2(isd:ied, jsd:jed)); wombat%sio2(:,:)=wombat%sio2_surf allocate(wombat%co2_csurf(isd:ied, jsd:jed)); wombat%co2_csurf(:,:)=0.0 allocate(wombat%co2_alpha(isd:ied, jsd:jed)); wombat%co2_alpha(:,:)=0.0 @@ -3841,6 +3911,8 @@ subroutine user_allocate_arrays allocate(wombat%zooslopdet(isd:ied, jsd:jed, 1:nk)); wombat%zooslopdet(:,:,:)=0.0 allocate(wombat%reminr(isd:ied, jsd:jed, 1:nk)); wombat%reminr(:,:,:)=0.0 allocate(wombat%detremi(isd:ied, jsd:jed, 1:nk)); wombat%detremi(:,:,:)=0.0 + allocate(wombat%pic2poc(isd:ied, jsd:jed, 1:nk)); wombat%pic2poc(:,:,:)=0.0 + allocate(wombat%dissrat(isd:ied, jsd:jed, 1:nk)); wombat%dissrat(:,:,:)=0.0 allocate(wombat%caldiss(isd:ied, jsd:jed, 1:nk)); wombat%caldiss(:,:,:)=0.0 allocate(wombat%no3_prev(isd:ied, jsd:jed, 1:nk)); wombat%no3_prev(:,:,:)=0.0 allocate(wombat%caco3_prev(isd:ied, jsd:jed, 1:nk)); wombat%caco3_prev(:,:,:)=0.0 @@ -3897,6 +3969,8 @@ subroutine user_deallocate_arrays wombat%ahtotal, & wombat%omega_ara, & wombat%omega_cal, & + wombat%co3, & + wombat%co2_star, & wombat%co2_csurf, & wombat%co2_alpha, & wombat%co2_sc_no, & @@ -3983,6 +4057,8 @@ subroutine user_deallocate_arrays wombat%zooslopdet, & wombat%reminr, & wombat%detremi, & + wombat%pic2poc, & + wombat%dissrat, & wombat%caldiss, & wombat%no3_prev, & wombat%caco3_prev, & From b995b374c375116f52b88d8ebf0abf7db7327dc3 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Fri, 13 Dec 2024 17:17:55 +1100 Subject: [PATCH 14/23] Added dicp and dicr as new tracers (DIC preformed and DIC remineralised) Removed adic as a tracer because CaCO3 dynamics mean that it is not appropriate --- generic_tracers/generic_WOMBATlite.F90 | 247 +++++++------------------ 1 file changed, 62 insertions(+), 185 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 0f46fd6..71a4b93 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -162,7 +162,6 @@ module generic_WOMBATlite dt_npzd, & sal_global, & dic_global, & - adic_global, & alk_global, & no3_global, & sio2_surf, & @@ -188,15 +187,13 @@ module generic_WOMBATlite !----------------------------------------------------------------------- real, dimension(:,:), allocatable :: & htotallo, htotalhi, & - ahtotallo, ahtotalhi, & sio2, & co2_csurf, co2_alpha, co2_sc_no, pco2_csurf, & - aco2_csurf, aco2_alpha, paco2_csurf, & o2_csurf, o2_alpha, o2_sc_no, & - no3_vstf, dic_vstf, adic_vstf, alk_vstf + no3_vstf, dic_vstf, dicp_vstf, alk_vstf real, dimension(:,:,:), allocatable :: & - htotal, ahtotal, & + htotal, & omega_ara, omega_cal, & co3, co2_star @@ -207,7 +204,7 @@ module generic_WOMBATlite ! to a bottom flux and "p_" to a "pointer". real, dimension(:,:), allocatable :: & b_dic, & - b_adic, & + b_dicr, & b_alk, & b_no3, & b_o2, & @@ -228,7 +225,6 @@ module generic_WOMBATlite detfe_sed_bury, & caco3_sed_bury, & dic_intmld, & - adic_intmld, & o2_intmld, & no3_intmld, & fe_intmld, & @@ -238,7 +234,6 @@ module generic_WOMBATlite npp_intmld, & radbio_intmld, & dic_int100, & - adic_int100, & o2_int100, & no3_int100, & fe_int100, & @@ -251,7 +246,8 @@ module generic_WOMBATlite real, dimension(:,:,:), allocatable :: & f_dic, & - f_adic, & + f_dicr, & + f_dicp, & f_alk, & f_no3, & f_phy, & @@ -311,7 +307,6 @@ module generic_WOMBATlite no3_prev, & caco3_prev, & dic_correct, & - adic_correct, & alk_correct, & zw, & zm @@ -332,7 +327,7 @@ module generic_WOMBATlite real, dimension(:,:), pointer :: & p_no3_stf, & p_dic_stf, & - p_adic_stf, & + p_dicp_stf, & p_alk_stf !----------------------------------------------------------------------- @@ -341,19 +336,16 @@ module generic_WOMBATlite ! See register_diagnostics for descriptions of each diagnostic integer :: & id_pco2 = -1, & - id_paco2 = -1, & id_htotal = -1, & - id_ahtotal = -1, & id_omega_ara = -1, & id_omega_cal = -1, & id_co3 = -1, & id_co2_star = -1, & id_no3_vstf = -1, & id_dic_vstf = -1, & - id_adic_vstf = -1, & + id_dicp_vstf = -1, & id_alk_vstf = -1, & id_dic_correct = -1, & - id_adic_correct = -1, & id_alk_correct = -1, & id_light_limit = -1, & id_radbio = -1, & @@ -408,7 +400,6 @@ module generic_WOMBATlite id_npp1 = -1, & id_zprod_gross = -1, & id_dic_intmld = -1, & - id_adic_intmld = -1, & id_o2_intmld = -1, & id_no3_intmld = -1, & id_fe_intmld = -1, & @@ -418,7 +409,6 @@ module generic_WOMBATlite id_npp_intmld = -1, & id_radbio_intmld = -1, & id_dic_int100 = -1, & - id_adic_int100 = -1, & id_o2_int100 = -1, & id_no3_int100 = -1, & id_fe_int100 = -1, & @@ -633,22 +623,11 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_pco2 = 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( & - 'paco2', 'Surface aqueous partial pressure of CO2 inc. anthropogenic', & - 'h', '1', 's', 'uatm', 'f') - wombat%id_paco2 = 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( & 'htotal', 'H+ concentration', 'h', 'L', 's', 'mol/kg', 'f') wombat%id_htotal = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) - vardesc_temp = vardesc( & - 'ahtotal', 'H+ concentration inc. anthropogenic', 'h', 'L', 's', 'mol/kg', 'f') - wombat%id_ahtotal = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & - init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) - vardesc_temp = vardesc( & 'omega_ara', 'Saturation state of aragonite', 'h', 'L', 's', ' ', 'f') wombat%id_omega_ara = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & @@ -676,15 +655,15 @@ subroutine generic_WOMBATlite_register_diag(diag_list) init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'dic_vstf', 'Virtual flux of natural dissolved inorganic carbon into ocean due to '// & + 'dic_vstf', 'Virtual flux of dissolved inorganic carbon into ocean due to '// & 'salinity restoring/correction', 'h', '1', 's', 'mol/m^2/s', 'f') wombat%id_dic_vstf = 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( & - 'adic_vstf', 'Virtual flux of natural + anthropogenic dissolved inorganic carbon '// & - 'into ocean due to salinity restoring/correction', 'h', '1', 's', 'mol/m^2/s', 'f') - wombat%id_adic_vstf = register_diag_field(package_name, vardesc_temp%name, axes(1:2), & + 'dicp_vstf', 'Virtual flux of preformed dissolved inorganic carbon into ocean due to '// & + 'salinity restoring/correction', 'h', '1', 's', 'mol/m^2/s', 'f') + wombat%id_dicp_vstf = 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( & @@ -701,11 +680,6 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_dic_correct = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) - vardesc_temp = vardesc( & - 'adic_correct', 'Correction to aDIC tracer (min limit)', 'h', 'L', 's', 'mol/kg', 'f') - wombat%id_adic_correct = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & - init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) - vardesc_temp = vardesc( & 'alk_correct', 'Correction to Alk tracer (min limit)', 'h', 'L', 's', 'mol/kg', 'f') wombat%id_alk_correct = register_diag_field(package_name, vardesc_temp%name, axes(1:3), & @@ -1037,17 +1011,11 @@ subroutine generic_WOMBATlite_register_diag(diag_list) ! MLD-integrated diagnostics !----------------------------------------------------------------------- vardesc_temp = vardesc( & - 'dic_intmld', 'MLD-integrated natural dissolved inorganic carbon', & + 'dic_intmld', 'MLD-integrated dissolved inorganic carbon', & 'h', '1', 's', 'mol/m^2', 'f') wombat%id_dic_intmld = 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( & - 'adic_intmld', 'MLD-integrated natural + anthropogenic dissolved inorganic carbon', & - 'h', '1', 's', 'mol/m^2', 'f') - wombat%id_adic_intmld = 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( & 'o2_intmld', 'MLD-integrated dissolved oxygen', 'h', '1', 's', 'mol/m^2', 'f') wombat%id_o2_intmld = register_diag_field(package_name, vardesc_temp%name, axes(1:2), & @@ -1093,17 +1061,11 @@ subroutine generic_WOMBATlite_register_diag(diag_list) ! 100m-integrated diagnostics !----------------------------------------------------------------------- vardesc_temp = vardesc( & - 'dic_int100', '100m-integrated natural dissolved inorganic carbon', & + 'dic_int100', '100m-integrated dissolved inorganic carbon', & 'h', '1', 's', 'mol/m^2', 'f') wombat%id_dic_int100 = 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( & - 'adic_int100', '100m-integrated natural + anthropogenic dissolved inorganic carbon', & - 'h', '1', 's', 'mol/m^2', 'f') - wombat%id_adic_int100 = 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( & 'o2_int100', '100m-integrated dissolved oxygen', 'h', '1', 's', 'mol/m^2', 'f') wombat%id_o2_int100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2), & @@ -1423,10 +1385,6 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('dic_global', wombat%dic_global, 1.90e-3) - ! Global average surface adic used for virtual flux correction [mol/kg] - !----------------------------------------------------------------------- - call g_tracer_add_param('adic_global', wombat%adic_global, 1.90e-3) - ! Global average surface alk used for virtual flux correction [mol/kg] !----------------------------------------------------------------------- call g_tracer_add_param('alk_global', wombat%alk_global, 2.225e-3) @@ -1600,11 +1558,11 @@ subroutine user_add_tracers(tracer_list) flux_bottom = .false., & btm_reservoir = .true.) - ! ADIC (Natural + anthropogenic dissolved inorganic carbon) + ! DIC (Dissolved inorganic carbon) !----------------------------------------------------------------------- call g_tracer_add(tracer_list, package_name, & - name = 'adic', & - longname = 'Natural + anthropogenic Dissolved Inorganic Carbon', & + name = 'dic', & + longname = 'Dissolved Inorganic Carbon', & units = 'mol/kg', & prog = .true., & flux_gas = .true., & @@ -1615,23 +1573,33 @@ subroutine user_add_tracers(tracer_list) flux_gas_param = (/ as_coeff_wombatlite, 9.7561e-06 /), & ! dts: param(2) converts Pa -> atm flux_gas_restart_file = 'ocean_wombatlite_airsea_flux.res.nc', & flux_virtual = .true.) - - ! DIC (Natural dissolved inorganic carbon) + + ! DICp (preformed Dissolved inorganic carbon) !----------------------------------------------------------------------- call g_tracer_add(tracer_list, package_name, & - name = 'dic', & - longname = 'Natural Dissolved Inorganic Carbon', & + name = 'dicp', & + longname = 'preformed Dissolved Inorganic Carbon', & units = 'mol/kg', & prog = .true., & flux_gas = .true., & - flux_bottom = .true., & - flux_gas_name = 'co2_nat_flux', & + flux_bottom = .false., & + flux_gas_name = 'co2_pre_flux', & flux_gas_type = 'air_sea_gas_flux_generic', & flux_gas_molwt = WTMCO2, & flux_gas_param = (/ as_coeff_wombatlite, 9.7561e-06 /), & ! dts: param(2) converts Pa -> atm flux_gas_restart_file = 'ocean_wombatlite_airsea_flux.res.nc', & flux_virtual = .true.) + ! DICr (remineralised dissolved inorganic carbon) + !----------------------------------------------------------------------- + call g_tracer_add(tracer_list, package_name, & + name = 'dicr', & + longname = 'remineralised Dissolved Inorganic Carbon', & + units = 'mol/kg', & + prog = .true., & + flux_bottom = .true., & + flux_virtual = .true.) + ! Alk (Total carbonate alkalinity) !----------------------------------------------------------------------- call g_tracer_add(tracer_list, package_name, & @@ -1732,9 +1700,9 @@ subroutine generic_WOMBATlite_update_from_coupler(tracer_list, ilb, jlb, salt_fl wombat%dic_vstf(:,:) = (wombat%dic_global / wombat%sal_global) * salt_flux_added(:,:) ! [mol/m2/s] wombat%p_dic_stf(:,:) = wombat%p_dic_stf(:,:) + wombat%dic_vstf(:,:) ! [mol/m2/s] - call g_tracer_get_pointer(tracer_list, 'adic', 'stf', wombat%p_adic_stf) - wombat%adic_vstf(:,:) = (wombat%adic_global / wombat%sal_global) * salt_flux_added(:,:) ! [mol/m2/s] - wombat%p_adic_stf(:,:) = wombat%p_adic_stf(:,:) + wombat%adic_vstf(:,:) ! [mol/m2/s] + call g_tracer_get_pointer(tracer_list, 'dicp', 'stf', wombat%p_dicp_stf) + wombat%dicp_vstf(:,:) = (wombat%dic_global / wombat%sal_global) * salt_flux_added(:,:) ! [mol/m2/s] + wombat%p_dicp_stf(:,:) = wombat%p_dicp_stf(:,:) + wombat%dicp_vstf(:,:) ! [mol/m2/s] call g_tracer_get_pointer(tracer_list, 'alk', 'stf', wombat%p_alk_stf) wombat%alk_vstf(:,:) = (wombat%alk_global / wombat%sal_global) * salt_flux_added(:,:) ! [mol/m2/s] @@ -2068,8 +2036,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_get_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=tau, & positive=.true.) - call g_tracer_get_values(tracer_list, 'adic', 'field', wombat%f_adic, isd, jsd, ntau=tau, & - positive=.true.) call g_tracer_get_values(tracer_list, 'no3', 'field', wombat%f_no3, isd, jsd, ntau=tau, & positive=.true.) call g_tracer_get_values(tracer_list, 'alk', 'field', wombat%f_alk, isd, jsd, ntau=tau, & @@ -2079,8 +2045,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & do j = jsc,jec; do i = isc,iec wombat%htotallo(i,j) = wombat%htotal_scale_lo * wombat%htotal(i,j,k) wombat%htotalhi(i,j) = wombat%htotal_scale_hi * wombat%htotal(i,j,k) - wombat%ahtotallo(i,j) = wombat%htotal_scale_lo * wombat%ahtotal(i,j,k) - wombat%ahtotalhi(i,j) = wombat%htotal_scale_hi * wombat%ahtotal(i,j,k) enddo; enddo if (k.eq.1) then !{ @@ -2096,27 +2060,14 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & zt=wombat%zw(:,:,k), & co2star=wombat%co2_csurf(:,:), alpha=wombat%co2_alpha(:,:), co3_ion=wombat%co3(:,:,k), & pCO2surf=wombat%pco2_csurf(:,:), omega_arag=wombat%omega_ara(:,:,k), omega_calc=wombat%omega_cal(:,:,k)) - - call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & - Temp(:,:,k), Salt(:,:,k), & - min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & - max(wombat%f_no3(:,:,k) / 16., 1e-9), & - wombat%sio2(:,:), & - min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg)), & - wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & - wombat%ahtotal(:,:,k), & - co2_calc=trim(co2_calc), & - zt=wombat%zw(:,:,k), & - co2star=wombat%aco2_csurf(:,:), alpha=wombat%aco2_alpha(:,:), & - pCO2surf=wombat%paco2_csurf(:,:)) call g_tracer_set_values(tracer_list, 'dic', 'alpha', wombat%co2_alpha, isd, jsd) call g_tracer_set_values(tracer_list, 'dic', 'csurf', wombat%co2_csurf, isd, jsd) - call g_tracer_set_values(tracer_list, 'adic', 'alpha', wombat%aco2_alpha, isd, jsd) - call g_tracer_set_values(tracer_list, 'adic', 'csurf', wombat%aco2_csurf, isd, jsd) - + call g_tracer_set_values(tracer_list, 'dicp', 'alpha', wombat%co2_alpha, isd, jsd) + call g_tracer_set_values(tracer_list, 'dicp', 'csurf', wombat%co2_csurf, isd, jsd) + wombat%co2_star(:,:,1) = wombat%co2_csurf(:,:) - + else call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & @@ -2131,17 +2082,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & co2star=wombat%co2_star(:,:,k), co3_ion=wombat%co3(:,:,k), & omega_arag=wombat%omega_ara(:,:,k), omega_calc=wombat%omega_cal(:,:,k)) - call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,k), & - Temp(:,:,k), Salt(:,:,k), & - min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,k), wombat%dic_min*mmol_m3_to_mol_kg)), & - max(wombat%f_no3(:,:,k) / 16., 1e-9), & - wombat%sio2(:,:), & - min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,k), wombat%alk_min*mmol_m3_to_mol_kg)), & - wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & - wombat%ahtotal(:,:,k), & - co2_calc=trim(co2_calc), & - zt=wombat%zw(:,:,k)) - endif !} if k.eq.1 enddo !} do k = 1,nk @@ -2150,7 +2090,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & !======================================================================= wombat%dic_correct(:,:,:) = 0.0 - wombat%adic_correct(:,:,:) = 0.0 wombat%alk_correct(:,:,:) = 0.0 wombat%pprod_gross(:,:,:) = 0.0 wombat%zprod_gross(:,:,:) = 0.0 @@ -2199,7 +2138,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%caldiss(:,:,:) = 0.0 wombat%export_prod(:,:) = 0.0 wombat%export_inorg(:,:) = 0.0 - wombat%adic_intmld(:,:) = 0.0 wombat%dic_intmld(:,:) = 0.0 wombat%o2_intmld(:,:) = 0.0 wombat%no3_intmld(:,:) = 0.0 @@ -2209,7 +2147,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%pprod_gross_intmld(:,:) = 0.0 wombat%npp_intmld(:,:) = 0.0 wombat%radbio_intmld(:,:) = 0.0 - wombat%adic_int100(:,:) = 0.0 wombat%dic_int100(:,:) = 0.0 wombat%o2_int100(:,:) = 0.0 wombat%no3_int100(:,:) = 0.0 @@ -2273,9 +2210,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & positive=.true.) ! [mol/kg] call g_tracer_get_values(tracer_list, 'fe', 'field', wombat%f_fe, isd, jsd, ntau=tau, & positive=.true.) ! [mol/kg] - call g_tracer_get_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=tau, & + call g_tracer_get_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=tau, & positive=.true.) ! [mol/kg] - call g_tracer_get_values(tracer_list, 'adic', 'field', wombat%f_adic, isd, jsd, ntau=tau, & + call g_tracer_get_values(tracer_list, 'dicr', 'field', wombat%f_dicr, isd, jsd, ntau=tau, & positive=.true.) ! [mol/kg] call g_tracer_get_values(tracer_list, 'alk', 'field', wombat%f_alk, isd, jsd, ntau=tau, & positive=.true.) ! [mol/kg] @@ -2874,9 +2811,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zoomort(i,j,k) * wombat%pic2poc(i,j,k) + & wombat%caldiss(i,j,k) ) - ! Equation for aDIC ! [molC/kg] + ! Equation for DICr ! [molC/kg] !----------------------------------------------------------------------- - wombat%f_adic(i,j,k) = wombat%f_adic(i,j,k) + dtsb * ( & + wombat%f_dicr(i,j,k) = wombat%f_dicr(i,j,k) + dtsb * ( & wombat%detremi(i,j,k) + & wombat%zooresp(i,j,k) + & wombat%zooexcrphy(i,j,k) + & @@ -3019,7 +2956,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%fesinks(i,j,k) = rdtts * wombat%fesinks(i,j,k) * grid_tmask(i,j,k) ! [mol/kg/s] if (wombat%zw(i,j,k) .le. hblt_depth(i,j)) then - wombat%adic_intmld(i,j) = wombat%adic_intmld(i,j) + wombat%f_adic(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%dic_intmld(i,j) = wombat%dic_intmld(i,j) + wombat%f_dic(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%o2_intmld(i,j) = wombat%o2_intmld(i,j) + wombat%f_o2(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%no3_intmld(i,j) = wombat%no3_intmld(i,j) + wombat%f_no3(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] @@ -3033,7 +2969,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & endif if (wombat%zw(i,j,k) .le. 100) then - wombat%adic_int100(i,j) = wombat%adic_int100(i,j) + wombat%f_adic(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%dic_int100(i,j) = wombat%dic_int100(i,j) + wombat%f_dic(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%o2_int100(i,j) = wombat%o2_int100(i,j) + wombat%f_o2(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] wombat%no3_int100(i,j) = wombat%no3_int100(i,j) + wombat%f_no3(i,j,k) * rho_dzt(i,j,k) ! [mol/m2] @@ -3067,11 +3002,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & - wombat%f_alk(i,j,k) ) * grid_tmask(i,j,k) wombat%dic_correct(i,j,k) = (max(wombat%dic_min * mmol_m3_to_mol_kg, wombat%f_dic(i,j,k) ) & - wombat%f_dic(i,j,k) ) * grid_tmask(i,j,k) - wombat%adic_correct(i,j,k) = (max(wombat%dic_min * mmol_m3_to_mol_kg, wombat%f_adic(i,j,k) ) & - - wombat%f_adic(i,j,k) ) * grid_tmask(i,j,k) wombat%f_alk(i,j,k) = wombat%f_alk(i,j,k) + wombat%alk_correct(i,j,k) wombat%f_dic(i,j,k) = wombat%f_dic(i,j,k) + wombat%dic_correct(i,j,k) - wombat%f_adic(i,j,k) = wombat%f_adic(i,j,k) + wombat%adic_correct(i,j,k) enddo; enddo; enddo ! Set tracers values @@ -3087,7 +3019,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_set_values(tracer_list, 'caco3', 'field', wombat%f_caco3, isd, jsd, ntau=tau) call g_tracer_set_values(tracer_list, 'fe', 'field', wombat%f_fe, isd, jsd, ntau=tau) call g_tracer_set_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=tau) - call g_tracer_set_values(tracer_list, 'adic', 'field', wombat%f_adic, isd, jsd, ntau=tau) + call g_tracer_set_values(tracer_list, 'dicr', 'field', wombat%f_dicr, isd, jsd, ntau=tau) call g_tracer_set_values(tracer_list, 'alk', 'field', wombat%f_alk, isd, jsd, ntau=tau) @@ -3138,7 +3070,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%b_no3(i,j) = -16./122. * wombat%det_sed_remin(i,j) ! [mol/m2/s] wombat%b_o2(i,j) = -172./16. * wombat%b_no3(i,j) ! [mol/m2/s] wombat%b_dic(i,j) = 122./16. * wombat%b_no3(i,j) - wombat%caco3_sed_remin(i,j) ! [mol/m2/s] - wombat%b_adic(i,j) = wombat%b_dic(i,j) ! [mol/m2/s] + wombat%b_dicr(i,j) = wombat%b_dic(i,j) ! [mol/m2/s] wombat%b_fe(i,j) = -1.0 * wombat%detfe_sed_remin(i,j) ! [mol/m2/s] wombat%b_alk(i,j) = -2.0 * wombat%caco3_sed_remin(i,j) - wombat%b_no3(i,j) ! [mol/m2/s] @@ -3158,7 +3090,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_set_values(tracer_list, 'no3', 'btf', wombat%b_no3, isd, jsd) call g_tracer_set_values(tracer_list, 'o2', 'btf', wombat%b_o2, isd, jsd) call g_tracer_set_values(tracer_list, 'dic', 'btf', wombat%b_dic, isd, jsd) - call g_tracer_set_values(tracer_list, 'adic', 'btf', wombat%b_adic, isd, jsd) + call g_tracer_set_values(tracer_list, 'dicr', 'btf', wombat%b_dicr, isd, jsd) call g_tracer_set_values(tracer_list, 'fe', 'btf', wombat%b_fe, isd, jsd) call g_tracer_set_values(tracer_list, 'alk', 'btf', wombat%b_alk, isd, jsd) @@ -3170,18 +3102,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_pco2, wombat%pco2_csurf, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_paco2 .gt. 0) & - used = g_send_data(wombat%id_paco2, wombat%paco2_csurf, model_time, & - rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_htotal .gt. 0) & used = g_send_data(wombat%id_htotal, wombat%htotal, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_ahtotal .gt. 0) & - used = g_send_data(wombat%id_ahtotal, wombat%ahtotal, model_time, & - rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_omega_ara .gt. 0) & used = g_send_data(wombat%id_omega_ara, wombat%omega_ara, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) @@ -3206,8 +3130,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_dic_vstf, wombat%dic_vstf, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_adic_vstf .gt. 0) & - used = g_send_data(wombat%id_adic_vstf, wombat%adic_vstf, model_time, & + if (wombat%id_dicp_vstf .gt. 0) & + used = g_send_data(wombat%id_dicp_vstf, wombat%dicp_vstf, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) if (wombat%id_alk_vstf .gt. 0) & @@ -3218,10 +3142,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_dic_correct, wombat%dic_correct, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_adic_correct .gt. 0) & - used = g_send_data(wombat%id_adic_correct, wombat%adic_correct, model_time, & - rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_alk_correct .gt. 0) & used = g_send_data(wombat%id_alk_correct, wombat%alk_correct, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) @@ -3451,10 +3371,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_zprod_gross, wombat%zprod_gross, model_time, & rmask=grid_tmask, is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) - if (wombat%id_adic_intmld .gt. 0) & - used = g_send_data(wombat%id_adic_intmld, wombat%adic_intmld, model_time, & - rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_dic_intmld .gt. 0) & used = g_send_data(wombat%id_dic_intmld, wombat%dic_intmld, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) @@ -3491,10 +3407,6 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_radbio_intmld, wombat%radbio_intmld, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_adic_int100 .gt. 0) & - used = g_send_data(wombat%id_adic_int100, wombat%adic_int100, model_time, & - rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_dic_int100 .gt. 0) & used = g_send_data(wombat%id_dic_int100, wombat%dic_int100, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) @@ -3630,8 +3542,6 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il ! Get necessary fields call g_tracer_get_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=1, & positive=.true.) - call g_tracer_get_values(tracer_list, 'adic', 'field', wombat%f_adic, isd, jsd, ntau=1, & - positive=.true.) call g_tracer_get_values(tracer_list, 'no3', 'field', wombat%f_no3, isd, jsd, ntau=1, & positive=.true.) call g_tracer_get_values(tracer_list, 'alk', 'field', wombat%f_alk, isd, jsd, ntau=1, & @@ -3640,8 +3550,6 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il do j = jsc, jec; do i = isc, iec wombat%htotallo(i,j) = wombat%htotal_scale_lo * wombat%htotal(i,j,1) wombat%htotalhi(i,j) = wombat%htotal_scale_hi * wombat%htotal(i,j,1) - wombat%ahtotallo(i,j) = wombat%htotal_scale_lo * wombat%ahtotal(i,j,1) - wombat%ahtotalhi(i,j) = wombat%htotal_scale_hi * wombat%ahtotal(i,j,1) enddo; enddo if ((trim(co2_calc) == 'mocsy') .and. (.not. present(dzt))) then @@ -3662,23 +3570,10 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il co2star=wombat%co2_csurf(:,:), alpha=wombat%co2_alpha(:,:), co3_ion=wombat%co3(:,:,1), & pCO2surf=wombat%pco2_csurf(:,:), omega_arag=wombat%omega_ara(:,:,1), omega_calc=wombat%omega_cal(:,:,1)) - call FMS_ocmip2_co2calc(CO2_dope_vec, grid_tmask(:,:,1), & - SST(:,:), SSS(:,:), & - min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%f_adic(:,:,1), wombat%dic_min*mmol_m3_to_mol_kg)), & - max(wombat%f_no3(:,:,1) / 16., 1e-9), & - wombat%sio2(:,:), & - min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%f_alk(:,:,1), wombat%alk_min*mmol_m3_to_mol_kg)), & - wombat%ahtotallo(:,:), wombat%ahtotalhi(:,:), & - wombat%ahtotal(:,:,1), & - co2_calc=trim(co2_calc), & - zt=dzt(:,:,1), & - co2star=wombat%aco2_csurf(:,:), alpha=wombat%aco2_alpha(:,:), & - pCO2surf=wombat%paco2_csurf(:,:)) - call g_tracer_set_values(tracer_list, 'dic', 'alpha', wombat%co2_alpha, isd, jsd) call g_tracer_set_values(tracer_list, 'dic', 'csurf', wombat%co2_csurf, isd, jsd) - call g_tracer_set_values(tracer_list, 'adic', 'alpha', wombat%aco2_alpha, isd, jsd) - call g_tracer_set_values(tracer_list, 'adic', 'csurf', wombat%aco2_csurf, isd, jsd) + call g_tracer_set_values(tracer_list, 'dicp', 'alpha', wombat%co2_alpha, isd, jsd) + call g_tracer_set_values(tracer_list, 'dicp', 'csurf', wombat%co2_csurf, isd, jsd) ! nnz: If source is called uncomment the following wombat%init = .false. !nnz: This is necessary since the above calls appear in source subroutine too. @@ -3686,8 +3581,6 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il call g_tracer_get_values(tracer_list, 'dic', 'alpha', wombat%co2_alpha ,isd, jsd) call g_tracer_get_values(tracer_list, 'dic', 'csurf', wombat%co2_csurf ,isd, jsd) - call g_tracer_get_values(tracer_list, 'adic', 'alpha', wombat%aco2_alpha ,isd, jsd) - call g_tracer_get_values(tracer_list, 'adic', 'csurf', wombat%aco2_csurf ,isd, jsd) do j=jsc,jec ; do i=isc,iec !----------------------------------------------------------------------- @@ -3700,8 +3593,6 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il wombat%co2_alpha(i,j) = wombat%co2_alpha(i,j) * wombat%Rho_0 !nnz: MOM has rho(i,j,1,tau) wombat%co2_csurf(i,j) = wombat%co2_csurf(i,j) * wombat%Rho_0 !nnz: MOM has rho(i,j,1,tau) - wombat%aco2_alpha(i,j) = wombat%aco2_alpha(i,j) * wombat%Rho_0 !nnz: MOM has rho(i,j,1,tau) - wombat%aco2_csurf(i,j) = wombat%aco2_csurf(i,j) * wombat%Rho_0 !nnz: MOM has rho(i,j,1,tau) enddo; enddo ! Set %csurf, %alpha and %sc_no for these tracers. This will mark them @@ -3709,9 +3600,10 @@ subroutine generic_WOMBATlite_set_boundary_values(tracer_list, SST, SSS, rho, il call g_tracer_set_values(tracer_list, 'dic', 'alpha', wombat%co2_alpha, isd, jsd) call g_tracer_set_values(tracer_list, 'dic', 'csurf', wombat%co2_csurf, isd, jsd) call g_tracer_set_values(tracer_list, 'dic', 'sc_no', wombat%co2_sc_no, isd, jsd) - call g_tracer_set_values(tracer_list, 'adic', 'alpha', wombat%aco2_alpha, isd, jsd) - call g_tracer_set_values(tracer_list, 'adic', 'csurf', wombat%aco2_csurf, isd, jsd) - call g_tracer_set_values(tracer_list, 'adic', 'sc_no', wombat%co2_sc_no, isd, jsd) + + call g_tracer_set_values(tracer_list, 'dicp', 'alpha', wombat%co2_alpha, isd, jsd) + call g_tracer_set_values(tracer_list, 'dicp', 'csurf', wombat%co2_csurf, isd, jsd) + call g_tracer_set_values(tracer_list, 'dicp', 'sc_no', wombat%co2_sc_no, isd, jsd) call g_tracer_get_values(tracer_list, 'o2', 'alpha', wombat%o2_alpha, isd, jsd) call g_tracer_get_values(tracer_list, 'o2', 'csurf', wombat%o2_csurf ,isd, jsd) @@ -3816,9 +3708,6 @@ subroutine user_allocate_arrays allocate(wombat%htotallo(isd:ied, jsd:jed)); wombat%htotallo(:,:)=0.0 allocate(wombat%htotalhi(isd:ied, jsd:jed)); wombat%htotalhi(:,:)=0.0 allocate(wombat%htotal(isd:ied, jsd:jed, 1:nk)); wombat%htotal(:,:,:)=wombat%htotal_in - allocate(wombat%ahtotallo(isd:ied, jsd:jed)); wombat%ahtotallo(:,:)=0.0 - allocate(wombat%ahtotalhi(isd:ied, jsd:jed)); wombat%ahtotalhi(:,:)=0.0 - allocate(wombat%ahtotal(isd:ied, jsd:jed, 1:nk)); wombat%ahtotal(:,:,:)=wombat%htotal_in allocate(wombat%omega_ara(isd:ied, jsd:jed, 1:nk)); wombat%omega_ara(:,:,:)=1.0 allocate(wombat%omega_cal(isd:ied, jsd:jed, 1:nk)); wombat%omega_cal(:,:,:)=1.0 allocate(wombat%co3(isd:ied, jsd:jed, 1:nk)); wombat%co3(:,:,:)=0.0 @@ -3828,19 +3717,17 @@ subroutine user_allocate_arrays allocate(wombat%co2_alpha(isd:ied, jsd:jed)); wombat%co2_alpha(:,:)=0.0 allocate(wombat%co2_sc_no(isd:ied, jsd:jed)); wombat%co2_sc_no(:,:)=0.0 allocate(wombat%pco2_csurf(isd:ied, jsd:jed)); wombat%pco2_csurf(:,:)=0.0 - allocate(wombat%aco2_csurf(isd:ied, jsd:jed)); wombat%aco2_csurf(:,:)=0.0 - allocate(wombat%aco2_alpha(isd:ied, jsd:jed)); wombat%aco2_alpha(:,:)=0.0 - allocate(wombat%paco2_csurf(isd:ied, jsd:jed)); wombat%paco2_csurf(:,:)=0.0 allocate(wombat%o2_csurf(isd:ied, jsd:jed)); wombat%o2_csurf(:,:)=0.0 allocate(wombat%o2_alpha(isd:ied, jsd:jed)); wombat%o2_alpha(:,:)=0.0 allocate(wombat%o2_sc_no(isd:ied, jsd:jed)); wombat%o2_sc_no(:,:)=0.0 allocate(wombat%no3_vstf(isd:ied, jsd:jed)); wombat%no3_vstf(:,:)=0.0 allocate(wombat%dic_vstf(isd:ied, jsd:jed)); wombat%dic_vstf(:,:)=0.0 - allocate(wombat%adic_vstf(isd:ied, jsd:jed)); wombat%adic_vstf(:,:)=0.0 + allocate(wombat%dicp_vstf(isd:ied, jsd:jed)); wombat%dicp_vstf(:,:)=0.0 allocate(wombat%alk_vstf(isd:ied, jsd:jed)); wombat%alk_vstf(:,:)=0.0 allocate(wombat%f_dic(isd:ied, jsd:jed, 1:nk)); wombat%f_dic(:,:,:)=0.0 - allocate(wombat%f_adic(isd:ied, jsd:jed, 1:nk)); wombat%f_adic(:,:,:)=0.0 + allocate(wombat%f_dicp(isd:ied, jsd:jed, 1:nk)); wombat%f_dicp(:,:,:)=0.0 + allocate(wombat%f_dicr(isd:ied, jsd:jed, 1:nk)); wombat%f_dicr(:,:,:)=0.0 allocate(wombat%f_alk(isd:ied, jsd:jed, 1:nk)); wombat%f_alk(:,:,:)=0.0 allocate(wombat%f_no3(isd:ied, jsd:jed, 1:nk)); wombat%f_no3(:,:,:)=0.0 allocate(wombat%f_phy(isd:ied, jsd:jed, 1:nk)); wombat%f_phy(:,:,:)=0.0 @@ -3857,12 +3744,11 @@ subroutine user_allocate_arrays allocate(wombat%b_no3(isd:ied, jsd:jed)); wombat%b_no3(:,:)=0.0 allocate(wombat%b_o2(isd:ied, jsd:jed)); wombat%b_o2(:,:)=0.0 allocate(wombat%b_dic(isd:ied, jsd:jed)); wombat%b_dic(:,:)=0.0 - allocate(wombat%b_adic(isd:ied, jsd:jed)); wombat%b_adic(:,:)=0.0 + allocate(wombat%b_dicr(isd:ied, jsd:jed)); wombat%b_dicr(:,:)=0.0 allocate(wombat%b_fe(isd:ied, jsd:jed)); wombat%b_fe(:,:)=0.0 allocate(wombat%b_alk(isd:ied, jsd:jed)); wombat%b_alk(:,:)=0.0 allocate(wombat%dic_correct(isd:ied, jsd:jed, 1:nk)); wombat%dic_correct(:,:,:)=0.0 - allocate(wombat%adic_correct(isd:ied, jsd:jed, 1:nk)); wombat%adic_correct(:,:,:)=0.0 allocate(wombat%alk_correct(isd:ied, jsd:jed, 1:nk)); wombat%alk_correct(:,:,:)=0.0 allocate(wombat%light_limit(isd:ied, jsd:jed)); wombat%light_limit(:,:)=0.0 allocate(wombat%radbio(isd:ied, jsd:jed, 1:nk)); wombat%radbio(:,:,:)=0.0 @@ -3929,7 +3815,6 @@ subroutine user_allocate_arrays allocate(wombat%zm(isd:ied, jsd:jed, 1:nk)); wombat%zm(:,:,:)=0.0 allocate(wombat%dic_intmld(isd:ied, jsd:jed)); wombat%dic_intmld(:,:)=0.0 - allocate(wombat%adic_intmld(isd:ied, jsd:jed)); wombat%adic_intmld(:,:)=0.0 allocate(wombat%o2_intmld(isd:ied, jsd:jed)); wombat%o2_intmld(:,:)=0.0 allocate(wombat%no3_intmld(isd:ied, jsd:jed)); wombat%no3_intmld(:,:)=0.0 allocate(wombat%fe_intmld(isd:ied, jsd:jed)); wombat%fe_intmld(:,:)=0.0 @@ -3940,7 +3825,6 @@ subroutine user_allocate_arrays allocate(wombat%radbio_intmld(isd:ied, jsd:jed)); wombat%radbio_intmld(:,:)=0.0 allocate(wombat%dic_int100(isd:ied, jsd:jed)); wombat%dic_int100(:,:)=0.0 - allocate(wombat%adic_int100(isd:ied, jsd:jed)); wombat%adic_int100(:,:)=0.0 allocate(wombat%o2_int100(isd:ied, jsd:jed)); wombat%o2_int100(:,:)=0.0 allocate(wombat%no3_int100(isd:ied, jsd:jed)); wombat%no3_int100(:,:)=0.0 allocate(wombat%fe_int100(isd:ied, jsd:jed)); wombat%fe_int100(:,:)=0.0 @@ -3964,9 +3848,6 @@ subroutine user_deallocate_arrays wombat%htotallo, & wombat%htotalhi, & wombat%htotal, & - wombat%ahtotallo, & - wombat%ahtotalhi, & - wombat%ahtotal, & wombat%omega_ara, & wombat%omega_cal, & wombat%co3, & @@ -3975,20 +3856,18 @@ subroutine user_deallocate_arrays wombat%co2_alpha, & wombat%co2_sc_no, & wombat%pco2_csurf, & - wombat%aco2_csurf, & - wombat%aco2_alpha, & - wombat%paco2_csurf, & wombat%o2_csurf, & wombat%o2_alpha, & wombat%o2_sc_no, & wombat%no3_vstf, & wombat%dic_vstf, & - wombat%adic_vstf, & + wombat%dicp_vstf, & wombat%alk_vstf) deallocate( & wombat%f_dic, & - wombat%f_adic, & + wombat%f_dicp, & + wombat%f_dicr, & wombat%f_alk, & wombat%f_no3, & wombat%f_phy, & @@ -4006,7 +3885,7 @@ subroutine user_deallocate_arrays wombat%b_no3, & wombat%b_o2, & wombat%b_dic, & - wombat%b_adic, & + wombat%b_dicr, & wombat%b_fe, & wombat%b_alk) @@ -4076,7 +3955,6 @@ subroutine user_deallocate_arrays deallocate( & wombat%dic_intmld, & - wombat%adic_intmld, & wombat%o2_intmld, & wombat%no3_intmld, & wombat%fe_intmld, & @@ -4086,7 +3964,6 @@ subroutine user_deallocate_arrays wombat%npp_intmld, & wombat%radbio_intmld, & wombat%dic_int100, & - wombat%adic_int100, & wombat%o2_int100, & wombat%no3_int100, & wombat%fe_int100, & From 991e993e8391470711a12bcc66480925cb506d30 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Mon, 16 Dec 2024 06:40:37 +1100 Subject: [PATCH 15/23] Added sedimentary dissolution of CaCO3 dependent on Omega. Also altered some of the parameters. --- generic_tracers/generic_WOMBATlite.F90 | 237 ++++++++++++++++++++++--- 1 file changed, 208 insertions(+), 29 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 71a4b93..ee9af7d 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -159,6 +159,7 @@ module generic_WOMBATlite ligand, & knano_dfe, & kscav_dfe, & + kcoag_dfe, & dt_npzd, & sal_global, & dic_global, & @@ -242,7 +243,17 @@ module generic_WOMBATlite pprod_gross_int100, & npp_int100, & radbio_int100, & - zeuphot + zeuphot, & + seddep, & + sedmask, & + sedtemp, & + sedsalt, & + sedno3, & + seddic, & + sedalk, & + sedhtotal, & + sedco3, & + sedomega_cal real, dimension(:,:,:), allocatable :: & f_dic, & @@ -426,7 +437,17 @@ module generic_WOMBATlite id_caco3_sed_remin = -1, & id_caco3_sed_depst = -1, & id_caco3_sed_bury = -1, & - id_zeuphot = -1 + id_zeuphot = -1, & + id_seddep = -1, & + id_sedmask = -1, & + id_sedtemp = -1, & + id_sedsalt = -1, & + id_sedno3 = -1, & + id_seddic = -1, & + id_sedalk = -1, & + id_sedhtotal = -1, & + id_sedco3 = -1, & + id_sedomega_cal = -1 end type generic_WOMBATlite_type @@ -1109,11 +1130,60 @@ subroutine generic_WOMBATlite_register_diag(diag_list) init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'zeuphot', 'Depth of the euphotic zone (defined as 1% of incident light)', & - 'h', '1', 's', 'm', 'f') + 'zeuphot', 'Depth of the euphotic zone (%1 incident light)', 'h', '1', 's', 'm', 'f') wombat%id_zeuphot = 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( & + 'seddep', 'Depth of the sediment', 'h', '1', 's', 'm', 'f') + wombat%id_seddep = 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( & + 'sedmask', 'Mask of active sediment points', 'h', '1', 's', ' ', 'f') + wombat%id_sedmask = 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( & + 'sedtemp', 'Temperature at the deepest grid cell', 'h', '1', 's', 'deg C', 'f') + wombat%id_sedtemp = 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( & + 'sedsalt', 'Salinity at the deepest grid cell', 'h', '1', 's', 'psu', 'f') + wombat%id_sedsalt = 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( & + 'sedno3', 'Nitrate at the deepest grid cell', 'h', '1', 's', 'mol/kg', 'f') + wombat%id_sedno3 = 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( & + 'seddic', 'Dissolved inorganic carbon at the deepest grid cell', 'h', '1', 's', 'mol/kg', 'f') + wombat%id_seddic = 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( & + 'sedalk', 'Alkalinity at the deepest grid cell', 'h', '1', 's', 'mol/kg', 'f') + wombat%id_sedalk = 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( & + 'sedhtotal', 'H+ ions at the deepest grid cell', 'h', '1', 's', 'mol/kg', 'f') + wombat%id_sedhtotal = 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( & + 'sedco3', 'CO3 ions at the deepest grid cell', 'h', '1', 's', 'mol/kg', 'f') + wombat%id_sedco3 = 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( & + 'sedomega_cal', 'Calcite saturation state at the deepest grid cell', 'h', '1', 's', ' ', 'f') + wombat%id_sedomega_cal = register_diag_field(package_name, vardesc_temp%name, axes(1:2), & + init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) + end subroutine generic_WOMBATlite_register_diag !####################################################################### @@ -1280,7 +1350,7 @@ subroutine user_add_params ! Zooplankton assimilation efficiency [1] !----------------------------------------------------------------------- - call g_tracer_add_param('zooassi', wombat%zooassi, 0.5) + call g_tracer_add_param('zooassi', wombat%zooassi, 0.4) ! Zooplankton half saturation coefficient for linear mortality !----------------------------------------------------------------------- @@ -1304,11 +1374,11 @@ subroutine user_add_params ! Zooplankton preference for detritus [0-1] !----------------------------------------------------------------------- - call g_tracer_add_param('zprefdet', wombat%zprefdet, 0.25) + call g_tracer_add_param('zprefdet', wombat%zprefdet, 0.50) ! Zooplankton respiration rate constant [1/s] !----------------------------------------------------------------------- - call g_tracer_add_param('zoolmor', wombat%zoolmor, 0.05/86400.0) + call g_tracer_add_param('zoolmor', wombat%zoolmor, 0.01/86400.0) ! Zooplankton quadratic mortality rate constant [m3/mmolN/s] !----------------------------------------------------------------------- @@ -1318,7 +1388,7 @@ subroutine user_add_params !----------------------------------------------------------------------- ! Detritus remineralisation rate for (>=180 m) is hard-coded to be ! detlrem/2 - call g_tracer_add_param('detlrem', wombat%detlrem, 0.09/86400.0) + call g_tracer_add_param('detlrem', wombat%detlrem, 0.1/86400.0) ! Detritus sinking rate coefficient [m/s] !----------------------------------------------------------------------- @@ -1333,7 +1403,7 @@ subroutine user_add_params ! This would normally equal detlrem, but we set the default value to be ! consistent with what is in ACCESS-ESM1.5 (undocumented in Ziehn et al ! 2020) - call g_tracer_add_param('detlrem_sed', wombat%detlrem_sed, 0.02/86400.0) + call g_tracer_add_param('detlrem_sed', wombat%detlrem_sed, 0.005/86400.0) ! Phytoplankton biomass threshold to scale recycling [mmolC/m3] !----------------------------------------------------------------------- @@ -1355,7 +1425,7 @@ subroutine user_add_params ! CaCO3 remineralization rate constant in sediments [1/s] !----------------------------------------------------------------------- - call g_tracer_add_param('caco3lrem_sed', wombat%caco3lrem_sed, 0.0035/86400.0) + call g_tracer_add_param('caco3lrem_sed', wombat%caco3lrem_sed, 0.01/86400.0) ! CaCO3 inorganic fraction [1] !----------------------------------------------------------------------- @@ -1363,7 +1433,7 @@ subroutine user_add_params ! Background concentration of iron-binding ligand [umol/m3] !----------------------------------------------------------------------- - call g_tracer_add_param('ligand', wombat%ligand, 0.6) + call g_tracer_add_param('ligand', wombat%ligand, 0.5) ! Precipitation of Fe` as nanoparticles (in excess of solubility) [/d] !----------------------------------------------------------------------- @@ -1373,6 +1443,10 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('kscav_dfe', wombat%kscav_dfe, 5e-2) + ! Coagulation of dFe onto organic particles [(mmolC/m3)-1 d-1] + !----------------------------------------------------------------------- + call g_tracer_add_param('kcoag_dfe', wombat%kcoag_dfe, 5e-8) + ! Nested timestep for the ecosystem model [s] !----------------------------------------------------------------------- call g_tracer_add_param('dt_npzd', wombat%dt_npzd, 900.) @@ -1922,6 +1996,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: phy_pisl, phy_pisl2 real :: pchl_pisl, pchl_mumin, pchl_muopt real, dimension(:,:), allocatable :: ek_bgr, par_bgr_mid, par_bgr_top + !real, dimension(:,:), allocatable :: seddep, sedmask real, dimension(:), allocatable :: wsink real, dimension(4,61) :: zbgr real :: ztemk, fe_keq, fe_par, fe_sfe, fe_tfe, partic @@ -2034,6 +2109,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! and pco2surf, so it makes sense to set these values here rather than ! recalculating them in set_boundary_values. + !allocate(sedmask(isc:iec,jsc:jec)); sedmask(:,:)=0.0 + !allocate(seddep(isc:iec,jsc:jec)); seddep(:,:)=0.0 + call g_tracer_get_values(tracer_list, 'dic', 'field', wombat%f_dic, isd, jsd, ntau=tau, & positive=.true.) call g_tracer_get_values(tracer_list, 'no3', 'field', wombat%f_no3, isd, jsd, ntau=tau, & @@ -2083,7 +2161,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & omega_arag=wombat%omega_ara(:,:,k), omega_calc=wombat%omega_cal(:,:,k)) endif !} if k.eq.1 - enddo !} do k = 1,nk + enddo !} do k = 1,nk !======================================================================= ! Calculate the source terms @@ -2157,6 +2235,16 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%npp_int100(:,:) = 0.0 wombat%radbio_int100(:,:) = 0.0 wombat%zeuphot(:,:) = 0.0 + wombat%seddep(:,:) = 0.0 + wombat%sedmask(:,:) = 0.0 + wombat%sedtemp(:,:) = 0.0 + wombat%sedsalt(:,:) = 0.0 + wombat%sedno3(:,:) = 0.0 + wombat%seddic(:,:) = 0.0 + wombat%sedalk(:,:) = 0.0 + wombat%sedhtotal(:,:) = 0.0 + wombat%sedco3(:,:) = 0.0 + wombat%sedomega_cal(:,:) = 0.0 ! Allocate and initialise some multi-dimensional variables allocate(wsink(nk)); wsink(:)=0.0 @@ -2556,11 +2644,11 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Coagulation of colloidal Fe (umol/m3) to form sinking particles (mmol/m3) ! Following Tagliabue et al. (2023), make coagulation rate dependent on DOC and Phytoplankton biomass biof = max(1/3., biophy / (biophy + 0.03)) - biodoc = 2.0 + (1.0 - min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k))) * 38.0 ! proxy of DOC (mmol/m3) + biodoc = 10.0 + (1.0 - min(wombat%phy_lnit(i,j,k), wombat%phy_lfer(i,j,k))) * 40.0 ! proxy of DOC (mmol/m3) if (wombat%zw(i,j,k).le.hblt_depth(i,j)) then - zval = ( (12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-6 + zval = ( (12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*wombat%kcoag_dfe else - zval = ( 0.01*(12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*1e-6 + zval = ( 0.01*(12.*biof*biodoc + 9.*biodet) + 2.5*biodet + 128.*biof*biodoc + 725.*biodet )*wombat%kcoag_dfe endif wombat%fecoag2det(i,j,k) = wombat%fecol(i,j,k) * zval / 86400.0 @@ -3060,26 +3148,57 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & do j = jsc,jec; do i = isc,iec; k = grid_kmt(i,j) if (k .gt. 0) then - fbc = wombat%bbioh ** (Temp(i,j,k)) ! [1] - wombat%det_sed_remin(i,j) = wombat%detlrem_sed * fbc * wombat%p_det_sediment(i,j,1) ! [mol/m2/s] - wombat%detfe_sed_remin(i,j) = wombat%detlrem_sed * fbc * wombat%p_detfe_sediment(i,j,1) ! [mol/m2/s] - wombat%caco3_sed_remin(i,j) = wombat%caco3lrem_sed * fbc * wombat%p_caco3_sediment(i,j,1) ! [mol/m2/s] - - ! Remineralisation of sediments to supply nutrient fields. - ! btf values are positive from the water column into the sediment. - wombat%b_no3(i,j) = -16./122. * wombat%det_sed_remin(i,j) ! [mol/m2/s] - wombat%b_o2(i,j) = -172./16. * wombat%b_no3(i,j) ! [mol/m2/s] - wombat%b_dic(i,j) = 122./16. * wombat%b_no3(i,j) - wombat%caco3_sed_remin(i,j) ! [mol/m2/s] - wombat%b_dicr(i,j) = wombat%b_dic(i,j) ! [mol/m2/s] - wombat%b_fe(i,j) = -1.0 * wombat%detfe_sed_remin(i,j) ! [mol/m2/s] - wombat%b_alk(i,j) = -2.0 * wombat%caco3_sed_remin(i,j) - wombat%b_no3(i,j) ! [mol/m2/s] + ! Get bottom conditions: mask, PO4, temp, salt, DIC, Alk, H+ ion + wombat%seddep(i,j) = wombat%zw(i,j,k) + wombat%sedmask(i,j) = grid_tmask(i,j,k) + wombat%sedtemp(i,j) = Temp(i,j,k) + wombat%sedsalt(i,j) = Salt(i,j,k) + wombat%sedno3(i,j) = wombat%f_no3(i,j,k) + wombat%seddic(i,j) = wombat%f_dic(i,j,k) + wombat%p_det_sediment(i,j,1) / wombat%Rho_0 + wombat%sedalk(i,j) = wombat%f_alk(i,j,k) + wombat%sedhtotal(i,j) = wombat%htotal(i,j,k) + endif + enddo; enddo + + call FMS_ocmip2_co2calc(CO2_dope_vec, wombat%sedmask(:,:), & + wombat%sedtemp(:,:), wombat%sedsalt(:,:), & + min(wombat%dic_max*mmol_m3_to_mol_kg, max(wombat%seddic(:,:), wombat%dic_min*mmol_m3_to_mol_kg)), & + max(wombat%sedno3(:,:) / 16., 1e-9), & + wombat%sio2(:,:), & + min(wombat%alk_max*mmol_m3_to_mol_kg, max(wombat%sedalk(:,:), wombat%alk_min*mmol_m3_to_mol_kg)), & + wombat%sedhtotal(:,:)*wombat%htotal_scale_lo, & + wombat%sedhtotal(:,:)*wombat%htotal_scale_hi, & + wombat%sedhtotal(:,:), & + co2_calc=trim(co2_calc), zt=wombat%seddep(:,:), & + co3_ion=wombat%sedco3(:,:), & + omega_calc=wombat%sedomega_cal(:,:)) + do j = jsc,jec; do i = isc,iec; + fbc = wombat%bbioh ** (wombat%sedtemp(i,j)) + wombat%det_sed_remin(i,j) = wombat%detlrem_sed * fbc * wombat%p_det_sediment(i,j,1) ! [mol/m2/s] + wombat%detfe_sed_remin(i,j) = wombat%detlrem_sed * fbc * wombat%p_detfe_sediment(i,j,1) ! [mol/m2/s] + if (wombat%caco3_dynamics) then + wombat%caco3_sed_remin(i,j) = wombat%caco3lrem_sed * fbc * wombat%p_caco3_sediment(i,j,1) * & + max(0.1, (1.0 - wombat%sedomega_cal(i,j)))**(4.5) + else + wombat%caco3_sed_remin(i,j) = wombat%caco3lrem_sed * fbc * wombat%p_caco3_sediment(i,j,1) * & + max(0.1, (1.0 - 0.2081))**(4.5) endif + + ! Remineralisation of sediments to supply nutrient fields. + ! btf values are positive from the water column into the sediment. + wombat%b_no3(i,j) = -16./122. * wombat%det_sed_remin(i,j) ! [mol/m2/s] + wombat%b_o2(i,j) = -172./16. * wombat%b_no3(i,j) ! [mol/m2/s] + wombat%b_dic(i,j) = 122./16. * wombat%b_no3(i,j) - wombat%caco3_sed_remin(i,j) ! [mol/m2/s] + wombat%b_dicr(i,j) = wombat%b_dic(i,j) ! [mol/m2/s] + wombat%b_fe(i,j) = -1.0 * wombat%detfe_sed_remin(i,j) ! [mol/m2/s] + wombat%b_alk(i,j) = -2.0 * wombat%caco3_sed_remin(i,j) - wombat%b_no3(i,j) ! [mol/m2/s] enddo; enddo ! Apply remineralisation rates to sediment tracers !----------------------------------------------------------------------- do j = jsc,jec; do i = isc,iec; + if (grid_kmt(i,j) .gt. 0) then wombat%p_det_sediment(i,j,1) = wombat%p_det_sediment(i,j,1) - dt * wombat%det_sed_remin(i,j) ! [mol/m2] wombat%p_detfe_sediment(i,j,1) = wombat%p_detfe_sediment(i,j,1) - dt * wombat%detfe_sed_remin(i,j) ! [mol/m2] @@ -3459,6 +3578,46 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & used = g_send_data(wombat%id_zeuphot, wombat%zeuphot, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (wombat%id_seddep .gt. 0) & + used = g_send_data(wombat%id_seddep, wombat%seddep, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_sedmask .gt. 0) & + used = g_send_data(wombat%id_sedmask, wombat%sedmask, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_sedtemp .gt. 0) & + used = g_send_data(wombat%id_sedtemp, wombat%sedtemp, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_sedsalt .gt. 0) & + used = g_send_data(wombat%id_sedsalt, wombat%sedsalt, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_sedno3 .gt. 0) & + used = g_send_data(wombat%id_sedno3, wombat%sedno3, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_seddic .gt. 0) & + used = g_send_data(wombat%id_seddic, wombat%seddic, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_sedalk .gt. 0) & + used = g_send_data(wombat%id_sedalk, wombat%sedalk, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_sedhtotal .gt. 0) & + used = g_send_data(wombat%id_sedhtotal, wombat%sedhtotal, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_sedco3 .gt. 0) & + used = g_send_data(wombat%id_sedco3, wombat%sedco3, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (wombat%id_sedomega_cal .gt. 0) & + used = g_send_data(wombat%id_sedomega_cal, wombat%sedomega_cal, model_time, & + rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + deallocate(kmeuph, k100) end subroutine generic_WOMBATlite_update_from_source @@ -3834,6 +3993,16 @@ subroutine user_allocate_arrays allocate(wombat%npp_int100(isd:ied, jsd:jed)); wombat%npp_int100(:,:)=0.0 allocate(wombat%radbio_int100(isd:ied, jsd:jed)); wombat%radbio_int100(:,:)=0.0 allocate(wombat%zeuphot(isd:ied, jsd:jed)); wombat%zeuphot(:,:)=0.0 + allocate(wombat%seddep(isd:ied, jsd:jed)); wombat%seddep(:,:)=0.0 + allocate(wombat%sedmask(isd:ied, jsd:jed)); wombat%sedmask(:,:)=0.0 + allocate(wombat%sedtemp(isd:ied, jsd:jed)); wombat%sedtemp(:,:)=0.0 + allocate(wombat%sedsalt(isd:ied, jsd:jed)); wombat%sedsalt(:,:)=0.0 + allocate(wombat%sedno3(isd:ied, jsd:jed)); wombat%sedno3(:,:)=0.0 + allocate(wombat%seddic(isd:ied, jsd:jed)); wombat%seddic(:,:)=0.0 + allocate(wombat%sedalk(isd:ied, jsd:jed)); wombat%sedalk(:,:)=0.0 + allocate(wombat%sedhtotal(isd:ied, jsd:jed)); wombat%sedhtotal(:,:)=0.0 + allocate(wombat%sedco3(isd:ied, jsd:jed)); wombat%sedco3(:,:)=0.0 + allocate(wombat%sedomega_cal(isd:ied, jsd:jed)); wombat%sedomega_cal(:,:)=0.0 end subroutine user_allocate_arrays @@ -3974,7 +4143,17 @@ subroutine user_deallocate_arrays wombat%radbio_int100) deallocate( & - wombat%zeuphot) + wombat%zeuphot, & + wombat%seddep, & + wombat%sedmask, & + wombat%sedtemp, & + wombat%sedsalt, & + wombat%sedno3, & + wombat%seddic, & + wombat%sedalk, & + wombat%sedhtotal, & + wombat%sedco3, & + wombat%sedomega_cal) end subroutine user_deallocate_arrays From bab10352ccee7f0638b2664971b28119c5aa2418 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Thu, 19 Dec 2024 17:36:46 +1100 Subject: [PATCH 16/23] Included a hard floor for DICp tracer == to dic_min parameter --- generic_tracers/generic_WOMBATlite.F90 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index ee9af7d..330121e 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -2302,6 +2302,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & positive=.true.) ! [mol/kg] call g_tracer_get_values(tracer_list, 'dicr', 'field', wombat%f_dicr, isd, jsd, ntau=tau, & positive=.true.) ! [mol/kg] + call g_tracer_get_values(tracer_list, 'dicp', 'field', wombat%f_dicp, isd, jsd, ntau=tau, & + positive=.true.) ! [mol/kg] call g_tracer_get_values(tracer_list, 'alk', 'field', wombat%f_alk, isd, jsd, ntau=tau, & positive=.true.) ! [mol/kg] @@ -3092,6 +3094,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & - wombat%f_dic(i,j,k) ) * grid_tmask(i,j,k) wombat%f_alk(i,j,k) = wombat%f_alk(i,j,k) + wombat%alk_correct(i,j,k) wombat%f_dic(i,j,k) = wombat%f_dic(i,j,k) + wombat%dic_correct(i,j,k) + wombat%f_dicp(i,j,k) = max(wombat%dic_min * mmol_m3_to_mol_kg, wombat%f_dic(i,j,k)) enddo; enddo; enddo ! Set tracers values From ba65270b506a0d7ae5b270e74f6abea48e10ae67 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Thu, 9 Jan 2025 11:45:37 +1100 Subject: [PATCH 17/23] Included parameter control via the field_table on the dissolution of CaCO3 via saturation states (cal and ara) and detrius remin --- generic_tracers/generic_WOMBATlite.F90 | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 330121e..82c296b 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -156,6 +156,9 @@ module generic_WOMBATlite caco3lrem, & caco3lrem_sed, & f_inorg, & + disscal, & + dissara, & + dissdet, & ligand, & knano_dfe, & kscav_dfe, & @@ -1431,6 +1434,18 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('f_inorg', wombat%f_inorg, 0.04) + ! CaCO3 dissolution factor due to calcite undersaturation + !----------------------------------------------------------------------- + call g_tracer_add_param('disscal', wombat%disscal, 0.500) + + ! CaCO3 dissolution factor due to aragonite undersaturation + !----------------------------------------------------------------------- + call g_tracer_add_param('dissara', wombat%dissara, 0.100) + + ! CaCO3 dissolution factor due to detritus remineralisation creating anoxic microenvironment + !----------------------------------------------------------------------- + call g_tracer_add_param('dissdet', wombat%dissdet, 0.250) + ! Background concentration of iron-binding ligand [umol/m3] !----------------------------------------------------------------------- call g_tracer_add_param('ligand', wombat%ligand, 0.5) @@ -2709,9 +2724,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! The dissolution rate is a function of omegas for calcite and aragonite, as well the ! concentration of POC, following Kwon et al., 2024, Science Advances; Table S1 - diss_cal = (0.253 * max(0.0, 1.0 - wombat%omega_cal(i,j,k))**2.2) / 86400.0 - diss_ara = (0.090 * max(0.0, 1.0 - wombat%omega_ara(i,j,k))**1.5) / 86400.0 - diss_det = (0.250 * wombat%reminr(i,j,k) * biodet**2.0) + diss_cal = (wombat%disscal * max(0.0, 1.0 - wombat%omega_cal(i,j,k))**2.2) / 86400.0 + diss_ara = (wombat%dissara * max(0.0, 1.0 - wombat%omega_ara(i,j,k))**1.5) / 86400.0 + diss_det = (wombat%dissdet * wombat%reminr(i,j,k) * biodet**2.0) wombat%dissrat(i,j,k) = diss_cal + diss_ara + diss_det else From 8bb59eb6e45a83df538424664390e15e7504bc7e Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Thu, 16 Jan 2025 15:07:53 +1100 Subject: [PATCH 18/23] Major bug fix : implicit sinking scheme was incorrectly treating sinking when vertical_movement==.true. Also: * Added "zooexcr" as an input parameter * Added "fbury" as a diagnostic, rathern than outputting det_sed_bury, detfe_sed_bury and caco3_sed_bury * Fixed a minor bug in the "fbury" array, which involved the wrong units --- generic_tracers/generic_WOMBATlite.F90 | 126 ++++++++++------------- generic_tracers/generic_tracer_utils.F90 | 42 ++++---- 2 files changed, 79 insertions(+), 89 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 82c296b..f54b46e 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -140,6 +140,7 @@ module generic_WOMBATlite phylmor, & phyqmor, & zooassi, & + zooexcr, & zookz, & zoogmax, & zooepsmin, & @@ -153,6 +154,7 @@ module generic_WOMBATlite wdetbio, & wdetmax, & phybiot, & + wcaco3, & caco3lrem, & caco3lrem_sed, & f_inorg, & @@ -225,9 +227,7 @@ module generic_WOMBATlite det_sed_remin, & detfe_sed_remin, & caco3_sed_remin, & - det_sed_bury, & - detfe_sed_bury, & - caco3_sed_bury, & + fbury, & dic_intmld, & o2_intmld, & no3_intmld, & @@ -433,13 +433,11 @@ module generic_WOMBATlite id_radbio_int100 = -1, & id_det_sed_remin = -1, & id_det_sed_depst = -1, & - id_det_sed_bury = -1, & + id_fbury = -1, & id_detfe_sed_remin = -1, & id_detfe_sed_depst = -1, & - id_detfe_sed_bury = -1, & id_caco3_sed_remin = -1, & id_caco3_sed_depst = -1, & - id_caco3_sed_bury = -1, & id_zeuphot = -1, & id_seddep = -1, & id_sedmask = -1, & @@ -752,9 +750,9 @@ subroutine generic_WOMBATlite_register_diag(diag_list) init_time, vardesc_temp%longname, vardesc_temp%units, missing_value=missing_value1) vardesc_temp = vardesc( & - 'det_sed_bury', 'Rate of permanent burial of detrital carbon within sediment', & - 'h', '1', 's', 'mol/m^2/s', 'f') - wombat%id_det_sed_bury = register_diag_field(package_name, vardesc_temp%name, axes(1:2), & + 'fbury', 'Fraction of deposited detritus permanently buried beneath sediment', & + 'h', '1', 's', '[0-1]', 'f') + wombat%id_fbury = 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( & @@ -769,12 +767,6 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_detfe_sed_depst = 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( & - 'detfe_sed_bury', 'Rate of permanent burial of detrital iron within sediment', & - 'h', '1', 's', 'mol/m^2/s', 'f') - wombat%id_detfe_sed_bury = 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( & 'caco3_sed_remin', 'Rate of remineralisation of CaCO3 in accumulated sediment', & 'h', '1', 's', 'mol/m^2/s', 'f') @@ -787,12 +779,6 @@ subroutine generic_WOMBATlite_register_diag(diag_list) wombat%id_caco3_sed_depst = 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( & - 'caco3_sed_bury', 'Rate of permanent burial of CaCO3 within sediment', & - 'h', '1', 's', 'molFe/m^2/s', 'f') - wombat%id_caco3_sed_bury = 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( & 'wdet100', 'Detritus export at 100 m (det*sinking rate)', & 'h', '1', 's', 'mol/m^2/s', 'f') @@ -1355,6 +1341,10 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('zooassi', wombat%zooassi, 0.4) + ! Zooplankton excretion of unassimilated prey [0-1] + !----------------------------------------------------------------------- + call g_tracer_add_param('zooexcr', wombat%zooexcr, 0.75) + ! Zooplankton half saturation coefficient for linear mortality !----------------------------------------------------------------------- call g_tracer_add_param('zookz', wombat%zookz, 0.25) @@ -1393,7 +1383,7 @@ subroutine user_add_params ! detlrem/2 call g_tracer_add_param('detlrem', wombat%detlrem, 0.1/86400.0) - ! Detritus sinking rate coefficient [m/s] + ! Base detritus sinking rate coefficient [m/s] !----------------------------------------------------------------------- call g_tracer_add_param('wdetbio', wombat%wdetbio, 18.0/86400.0) @@ -1412,6 +1402,10 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('phybiot', wombat%phybiot, 0.6) + ! Base CaCO3 sinking rate coefficient [m/s] + !----------------------------------------------------------------------- + call g_tracer_add_param('wcaco3', wombat%wcaco3, 4.0/86400.0) + ! Do dynamic CaCO3 precipiation, dissolution and ballasting? !----------------------------------------------------------------------- call g_tracer_add_param('caco3_dynamics', wombat%caco3_dynamics, .true. ) @@ -1515,6 +1509,7 @@ subroutine user_add_tracers(tracer_list) ! Default value matches Ziehn et al 2020 but differs from Hayashida et ! al 2020 call g_tracer_add_param('wdetbio', wombat%wdetbio, 18.0/86400.0) + call g_tracer_add_param('wcaco3', wombat%wcaco3, 4.0/86400.0) ! Based on 10µm average size call g_tracer_add_param('ice_restart_file', wombat%ice_restart_file, 'ice_wombatlite.res.nc') call g_tracer_add_param('ocean_restart_file', wombat%ocean_restart_file, 'ocean_wombatlite.res.nc') @@ -1839,7 +1834,7 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim integer :: isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, i, j real, dimension(:,:,:), pointer :: grid_tmask - real :: orgflux, burfac + real :: orgflux logical :: used call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, & @@ -1852,31 +1847,26 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim call g_tracer_get_values(tracer_list, 'caco3', 'btm_reservoir', wombat%caco3_btm, isd, jsd) ! Calculate burial of deposited detritus (Dunne et al., 2007) + wombat%fbury(:,:) = 0.0 if (wombat%burial) then - do i = isc, iec - do j = jsc, jec - orgflux = wombat%det_btm(i,j) / dt * 86400 * 1e6 * 1e4 ! umol C cm-2 day-1 - burfac = 0.013 + 0.53 * orgflux**2.0 / (7.0 + orgflux)**2.0 - wombat%det_sed_bury(i,j) = wombat%det_btm(i,j) * burfac ! [mol/m2] - wombat%detfe_sed_bury(i,j) = wombat%detfe_btm(i,j) * burfac ! [mol/m2] - wombat%caco3_sed_bury(i,j) = wombat%caco3_btm(i,j) * burfac ! [mol/m2] + do i = isc, iec + do j = jsc, jec + orgflux = wombat%det_btm(i,j) / dt * 86400 * 1e3 ! mmol C m-2 day-1 + wombat%fbury(i,j) = 0.013 + 0.53 * orgflux**2.0 / (7.0 + orgflux)**2.0 ! Eq. 3 Dunne et al. 2007 + enddo enddo - enddo - wombat%det_btm = wombat%det_btm - wombat%det_sed_bury - wombat%detfe_btm = wombat%detfe_btm - wombat%detfe_sed_bury - wombat%caco3_btm = wombat%caco3_btm - wombat%caco3_sed_bury endif call g_tracer_get_pointer(tracer_list, 'det_sediment', 'field', wombat%p_det_sediment) - wombat%p_det_sediment(:,:,1) = wombat%p_det_sediment(:,:,1) + wombat%det_btm(:,:) ! [mol/m2] + wombat%p_det_sediment(:,:,1) = wombat%p_det_sediment(:,:,1) + wombat%det_btm(:,:) * (1.0-wombat%fbury(:,:)) ! [mol/m2] call g_tracer_set_values(tracer_list, 'det', 'btm_reservoir', 0.0) call g_tracer_get_pointer(tracer_list, 'detfe_sediment', 'field', wombat%p_detfe_sediment) - wombat%p_detfe_sediment(:,:,1) = wombat%p_detfe_sediment(:,:,1) + wombat%detfe_btm(:,:) ! [mol/m2] + wombat%p_detfe_sediment(:,:,1) = wombat%p_detfe_sediment(:,:,1) + wombat%detfe_btm(:,:) * (1.0-wombat%fbury(:,:)) ! [mol/m2] call g_tracer_set_values(tracer_list, 'detfe', 'btm_reservoir', 0.0) call g_tracer_get_pointer(tracer_list, 'caco3_sediment', 'field', wombat%p_caco3_sediment) - wombat%p_caco3_sediment(:,:,1) = wombat%p_caco3_sediment(:,:,1) + wombat%caco3_btm(:,:) ! [mol/m2] + wombat%p_caco3_sediment(:,:,1) = wombat%p_caco3_sediment(:,:,1) + wombat%caco3_btm(:,:) * (1.0-wombat%fbury(:,:)) ! [mol/m2] call g_tracer_set_values(tracer_list, 'caco3', 'btm_reservoir', 0.0) ! Send diagnostics @@ -1893,16 +1883,8 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim used = g_send_data(wombat%id_caco3_sed_depst, wombat%caco3_btm / dt, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - if (wombat%id_det_sed_bury .gt. 0) & - used = g_send_data(wombat%id_det_sed_bury, wombat%det_sed_bury / dt, model_time, & - rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - - if (wombat%id_detfe_sed_bury .gt. 0) & - used = g_send_data(wombat%id_detfe_sed_bury, wombat%detfe_sed_bury / dt, model_time, & - rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) - - if (wombat%id_caco3_sed_bury .gt. 0) & - used = g_send_data(wombat%id_caco3_sed_bury, wombat%caco3_sed_bury / dt, model_time, & + if (wombat%id_fbury .gt. 0) & + used = g_send_data(wombat%id_fbury, wombat%fbury, model_time, & rmask=grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) end subroutine generic_WOMBATlite_update_from_bottom @@ -1998,7 +1980,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: rdtts ! 1 / dt real, dimension(nbands) :: sw_pen real :: swpar - real :: u_npz, g_npz + real :: u_npz, g_npz, g_peffect, g_teffect real :: biophy, biozoo, biodet, biono3, biofer, biocaco3 real :: biophyfe, biophy1, zooprey real :: fbc @@ -2012,8 +1994,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: pchl_pisl, pchl_mumin, pchl_muopt real, dimension(:,:), allocatable :: ek_bgr, par_bgr_mid, par_bgr_top !real, dimension(:,:), allocatable :: seddep, sedmask - real, dimension(:), allocatable :: wsink + real, dimension(:), allocatable :: wsink, wsinkcal real, dimension(4,61) :: zbgr + real :: max_wsink real :: ztemk, fe_keq, fe_par, fe_sfe, fe_tfe, partic real :: fesol1, fesol2, fesol3, fesol4, fesol5, hp, fe3sol real :: biof, biodoc, zno3, zfermin @@ -2250,6 +2233,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%npp_int100(:,:) = 0.0 wombat%radbio_int100(:,:) = 0.0 wombat%zeuphot(:,:) = 0.0 + wombat%fbury(:,:) = 0.0 wombat%seddep(:,:) = 0.0 wombat%sedmask(:,:) = 0.0 wombat%sedtemp(:,:) = 0.0 @@ -2263,6 +2247,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! Allocate and initialise some multi-dimensional variables allocate(wsink(nk)); wsink(:)=0.0 + allocate(wsinkcal(nk)); wsinkcal(:)=0.0 allocate(ek_bgr(nk,3)); ek_bgr(:,:)=0.0 allocate(par_bgr_mid(nk,3)); par_bgr_mid(:,:)=0.0 allocate(par_bgr_top(nk,3)); par_bgr_top(:,:)=0.0 @@ -2696,9 +2681,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & ! - We add a temperature dependence that reduces epsilon in cool temperatures to enforce mesozooplankton at high lats ! - We add a temperature dependence that elevates the minimum epsilon in the tropics epsmin = wombat%zooepsmin * ( 1.5 * tanh(0.2*(Temp(i,j,k)-15.0)) + 2.5 ) - wombat%zooeps(i,j,k) = epsmin + (wombat%zooepsmax - epsmin) / & - (1. + exp(3.*(biophy - 2.*wombat%phybiot))) / & - (1. + exp(-(Temp(i,j,k)-10.0))) + g_peffect = 1.0 - (1.0 / (1.0 + exp(-3.0*(zooprey - 2.0*wombat%phybiot)))) + g_teffect = 1.0 / (1. + exp(-(Temp(i,j,k)-10.0))) + wombat%zooeps(i,j,k) = epsmin + (wombat%zooepsmax - epsmin) * g_peffect * g_teffect g_npz = wombat%zoogmax * fbc * (wombat%zooeps(i,j,k) * zooprey*zooprey) / & (wombat%zoogmax * fbc + (wombat%zooeps(i,j,k) * zooprey*zooprey)) @@ -2727,7 +2712,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & diss_cal = (wombat%disscal * max(0.0, 1.0 - wombat%omega_cal(i,j,k))**2.2) / 86400.0 diss_ara = (wombat%dissara * max(0.0, 1.0 - wombat%omega_ara(i,j,k))**1.5) / 86400.0 diss_det = (wombat%dissdet * wombat%reminr(i,j,k) * biodet**2.0) - wombat%dissrat(i,j,k) = diss_cal + diss_ara + diss_det + wombat%dissrat(i,j,k) = wombat%caco3lrem*0.25 + diss_cal + diss_ara + diss_det else @@ -2757,10 +2742,10 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%zoograzphy(i,j,k) = 0.0 wombat%zoograzdet(i,j,k) = 0.0 endif - wombat%zooexcrphy(i,j,k) = wombat%zoograzphy(i,j,k) * (1.0 - wombat%zooassi)*0.75 - wombat%zooexcrdet(i,j,k) = wombat%zoograzdet(i,j,k) * (1.0 - wombat%zooassi)*0.75 - wombat%zooslopphy(i,j,k) = wombat%zoograzphy(i,j,k) * (1.0 - wombat%zooassi)*0.25 - wombat%zooslopdet(i,j,k) = wombat%zoograzdet(i,j,k) * (1.0 - wombat%zooassi)*0.25 + wombat%zooexcrphy(i,j,k) = wombat%zoograzphy(i,j,k) * (1.0 - wombat%zooassi)*wombat%zooexcr + wombat%zooexcrdet(i,j,k) = wombat%zoograzdet(i,j,k) * (1.0 - wombat%zooassi)*wombat%zooexcr + wombat%zooslopphy(i,j,k) = wombat%zoograzphy(i,j,k) * (1.0 - wombat%zooassi)*(1.0-wombat%zooexcr) + wombat%zooslopdet(i,j,k) = wombat%zoograzdet(i,j,k) * (1.0 - wombat%zooassi)*(1.0-wombat%zooexcr) if (biophy.gt.1e-3) then wombat%phyresp(i,j,k) = wombat%phylmor * fbc * wombat%f_phy(i,j,k) ! [molC/kg/s] @@ -2942,7 +2927,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%caldiss(i,j,k) - & wombat%zooslopphy(i,j,k) * wombat%pic2poc(i,j,k) - & wombat%phymort(i,j,k) * wombat%pic2poc(i,j,k) - & - wombat%zoomort(i,j,k) * wombat%pic2poc(i,j,k) ) + wombat%zoomort(i,j,k) * wombat%pic2poc(i,j,k) ) ! Extra equation for iron ! [molFe/kg] !----------------------------------------------------------------------- @@ -3141,14 +3126,20 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & do j = jsc,jec; do i = isc,iec; if (grid_kmt(i,j).gt.0) then biophy1 = max(epsi, wombat%f_phy(i,j,1) ) / mmol_m3_to_mol_kg ![mmol/m3] - wsink(:) = wombat%wdetbio * max(1e-3, biophy1 - wombat%phybiot)**(0.21) + wsink(:) = wombat%wdetbio * max(0.0, biophy1 - wombat%phybiot)**(0.21) do k=1,nk - wsink(k) = wsink(k) + 30.0/86400.0 * min(1.0, (wombat%f_caco3(i,j,k) / (wombat%f_det(i,j,k) + epsi))) + !wsink(k) = wsink(k) + 10.0/86400.0 * min(1.0, (wombat%f_caco3(i,j,k) / (wombat%f_det(i,j,k) + epsi))) + ! Increase sinking rate with depth to achieve power law behaviour wsink(k) = wsink(k) + max(0.0, wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wsink(k))) + ! Ensure that we don't violate the CFL criterion + max_wsink = dzt(i,j,k) * 0.5 / dt ! [m/s] + wsink(k) = min(wsink(k), max_wsink) + ! CaCO3 sinks slower than general detritus because it tends to be smaller + wsinkcal(k) = wsink(k) * wombat%wcaco3/wombat%wdetbio enddo wombat%p_wdet(i,j,:) = wsink(:) wombat%p_wdetfe(i,j,:) = wsink(:) - wombat%p_wcaco3(i,j,:) = wsink(:) + wombat%p_wcaco3(i,j,:) = wsinkcal(:) else wombat%p_wdet(i,j,:) = 0.0 wombat%p_wdetfe(i,j,:) = 0.0 @@ -3157,7 +3148,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & enddo; enddo !----------------------------------------------------------------------- - ! Remineralisation and burial of sediment tracers + ! Remineralisation of sediment tracers !----------------------------------------------------------------------- call g_tracer_get_pointer(tracer_list, 'det_sediment', 'field', wombat%p_det_sediment) ! [mol/m2] call g_tracer_get_pointer(tracer_list, 'detfe_sediment', 'field', wombat%p_detfe_sediment) ! [mol/m2] @@ -3172,7 +3163,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%sedtemp(i,j) = Temp(i,j,k) wombat%sedsalt(i,j) = Salt(i,j,k) wombat%sedno3(i,j) = wombat%f_no3(i,j,k) - wombat%seddic(i,j) = wombat%f_dic(i,j,k) + wombat%p_det_sediment(i,j,1) / wombat%Rho_0 + wombat%seddic(i,j) = wombat%f_dic(i,j,k) + wombat%p_det_sediment(i,j,1) / wombat%Rho_0 ![mol/kg] wombat%sedalk(i,j) = wombat%f_alk(i,j,k) wombat%sedhtotal(i,j) = wombat%htotal(i,j,k) endif @@ -3213,6 +3204,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%b_alk(i,j) = -2.0 * wombat%caco3_sed_remin(i,j) - wombat%b_no3(i,j) ! [mol/m2/s] enddo; enddo + ! Apply remineralisation rates to sediment tracers !----------------------------------------------------------------------- do j = jsc,jec; do i = isc,iec; @@ -3981,13 +3973,11 @@ subroutine user_allocate_arrays allocate(wombat%caco3_prev(isd:ied, jsd:jed, 1:nk)); wombat%caco3_prev(:,:,:)=0.0 allocate(wombat%det_sed_remin(isd:ied, jsd:jed)); wombat%det_sed_remin(:,:)=0.0 allocate(wombat%det_btm(isd:ied, jsd:jed)); wombat%det_btm(:,:)=0.0 - allocate(wombat%det_sed_bury(isd:ied, jsd:jed)); wombat%det_sed_bury(:,:)=0.0 + allocate(wombat%fbury(isd:ied, jsd:jed)); wombat%fbury(:,:)=0.0 allocate(wombat%detfe_sed_remin(isd:ied, jsd:jed)); wombat%detfe_sed_remin(:,:)=0.0 allocate(wombat%detfe_btm(isd:ied, jsd:jed)); wombat%detfe_btm(:,:)=0.0 - allocate(wombat%detfe_sed_bury(isd:ied, jsd:jed)); wombat%detfe_sed_bury(:,:)=0.0 allocate(wombat%caco3_sed_remin(isd:ied, jsd:jed)); wombat%caco3_sed_remin(:,:)=0.0 allocate(wombat%caco3_btm(isd:ied, jsd:jed)); wombat%caco3_btm(:,:)=0.0 - allocate(wombat%caco3_sed_bury(isd:ied, jsd:jed)); wombat%caco3_sed_bury(:,:)=0.0 allocate(wombat%zw(isd:ied, jsd:jed, 1:nk)); wombat%zw(:,:,:)=0.0 allocate(wombat%zm(isd:ied, jsd:jed, 1:nk)); wombat%zm(:,:,:)=0.0 @@ -4130,13 +4120,11 @@ subroutine user_deallocate_arrays wombat%caco3_prev, & wombat%det_sed_remin, & wombat%det_btm, & - wombat%det_sed_bury, & + wombat%fbury, & wombat%detfe_sed_remin, & wombat%detfe_btm, & - wombat%detfe_sed_bury, & wombat%caco3_sed_remin, & wombat%caco3_btm, & - wombat%caco3_sed_bury, & wombat%zw, & wombat%zm) diff --git a/generic_tracers/generic_tracer_utils.F90 b/generic_tracers/generic_tracer_utils.F90 index 0a03432..5a122e5 100644 --- a/generic_tracers/generic_tracer_utils.F90 +++ b/generic_tracers/generic_tracer_utils.F90 @@ -3180,37 +3180,34 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, nz=g_tracer_com%grid_kmt(i,j) + ! If a non-constant sinking rate were used, that would be incorprated here. if (g_tracer%move_vertical) then do k=2,nz; sink_dist(k) = (dt*g_tracer%vmove(i,j,k)) * m_to_H; enddo endif sfc_src = 0.0 ; btm_src = 0.0 - ! Find the sinking rates at all interfaces, limiting them if necesary - ! so that the characteristics do not cross within a timestep. - ! If a non-constant sinking rate were used, that would be incorprated - ! here. + ! Sinking of tracer into a sediment reservoir? if (_ALLOCATED(g_tracer%btm_reservoir)) then - do k=2,nz - sink(k) = sink_dist(k) ; h_minus_dsink(k) = h_old(i,j,k) - enddo sink(nz+1) = sink_dist(nz) !PJB [13th Nov 2024] to allow sinking into bottom reservoir else sink(nz+1) = 0.0 - ! Find the limited sinking distance at the interfaces. - do k=nz,2,-1 - if (sink(k+1) >= sink_dist(k)) then - sink(k) = sink_dist(k) - h_minus_dsink(k) = h_old(i,j,k) + (sink(k+1) - sink(k)) - elseif (sink(k+1) + h_old(i,j,k) < sink_dist(k)) then - sink(k) = sink(k+1) + h_old(i,j,k) - h_minus_dsink(k) = 0.0 - else - sink(k) = sink_dist(k) - h_minus_dsink(k) = (h_old(i,j,k) + sink(k+1)) - sink(k) - endif - enddo endif + ! Find the sinking rates at all interfaces, limiting them if necesary + ! so that the characteristics do not cross within a timestep. + do k=nz,2,-1 + if (sink(k+1) >= sink_dist(k)) then + sink(k) = sink_dist(k) + h_minus_dsink(k) = h_old(i,j,k) + (sink(k+1) - sink(k)) + elseif (sink(k+1) + h_old(i,j,k) < sink_dist(k)) then + sink(k) = sink(k+1) + h_old(i,j,k) + h_minus_dsink(k) = 0.0 + else + sink(k) = sink_dist(k) + h_minus_dsink(k) = (h_old(i,j,k) + sink(k+1)) - sink(k) + endif + enddo + sink(1) = 0.0 ; h_minus_dsink(1) = (h_old(i,j,1) + sink(2)) !Avoid sinking tracers with negative concentrations @@ -3231,6 +3228,11 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, do k=2,nz-1 c1(k) = eb(i,j,k-1) * b1 b_denom_1 = h_minus_dsink(k) + d1 * (ea(i,j,k) + sink(k)) + if (b_denom_1.le.0.0) then + print*, "Warning: b_denom_1 <= 0 at (i, j, k):", i, j, k + print*, "Values: h_minus_dsink =", h_minus_dsink(k), "d1 =", d1, "ea =", ea(i,j,k), "sink =", sink(k) + stop "Error: Diagonal value b_denom_1 must be > 0.0" + endif b1 = 1.0 / (b_denom_1 + eb(i,j,k)) d1 = b_denom_1 * b1 From ffdf20b469ef9d74c28e3645421f0b229785314e Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Thu, 16 Jan 2025 15:31:49 +1100 Subject: [PATCH 19/23] Added ballasting of CaCO3 to sinking rate --- generic_tracers/generic_WOMBATlite.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index f54b46e..e571d14 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -3128,7 +3128,8 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & biophy1 = max(epsi, wombat%f_phy(i,j,1) ) / mmol_m3_to_mol_kg ![mmol/m3] wsink(:) = wombat%wdetbio * max(0.0, biophy1 - wombat%phybiot)**(0.21) do k=1,nk - !wsink(k) = wsink(k) + 10.0/86400.0 * min(1.0, (wombat%f_caco3(i,j,k) / (wombat%f_det(i,j,k) + epsi))) + wsink(k) = wsink(k) + 10.0/86400.0 * min(1.0, & + (wombat%f_caco3(i,j,k) / (wombat%f_det(i,j,k) + wombat%f_caco3(i,j,k)))) ! Increase sinking rate with depth to achieve power law behaviour wsink(k) = wsink(k) + max(0.0, wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wsink(k))) ! Ensure that we don't violate the CFL criterion From 4779c63d8b61c191152823404015bdfe963ff92a Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Thu, 16 Jan 2025 15:54:34 +1100 Subject: [PATCH 20/23] * Increased the CFL criterion for vertically variable sinking, and made small edits to: * remove background dissolution of CaCO3 in absence of detritus --- generic_tracers/generic_WOMBATlite.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index e571d14..0e19967 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -2712,7 +2712,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & diss_cal = (wombat%disscal * max(0.0, 1.0 - wombat%omega_cal(i,j,k))**2.2) / 86400.0 diss_ara = (wombat%dissara * max(0.0, 1.0 - wombat%omega_ara(i,j,k))**1.5) / 86400.0 diss_det = (wombat%dissdet * wombat%reminr(i,j,k) * biodet**2.0) - wombat%dissrat(i,j,k) = wombat%caco3lrem*0.25 + diss_cal + diss_ara + diss_det + wombat%dissrat(i,j,k) = diss_cal + diss_ara + diss_det else @@ -3129,11 +3129,11 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wsink(:) = wombat%wdetbio * max(0.0, biophy1 - wombat%phybiot)**(0.21) do k=1,nk wsink(k) = wsink(k) + 10.0/86400.0 * min(1.0, & - (wombat%f_caco3(i,j,k) / (wombat%f_det(i,j,k) + wombat%f_caco3(i,j,k)))) + (wombat%f_caco3(i,j,k) / (wombat%f_det(i,j,k) + wombat%f_caco3(i,j,k) + epsi))) ! Increase sinking rate with depth to achieve power law behaviour wsink(k) = wsink(k) + max(0.0, wombat%zw(i,j,k)/5000.0 * (wombat%wdetmax - wsink(k))) ! Ensure that we don't violate the CFL criterion - max_wsink = dzt(i,j,k) * 0.5 / dt ! [m/s] + max_wsink = dzt(i,j,k) * 0.5 / (dt * 2) ! [m/s] wsink(k) = min(wsink(k), max_wsink) ! CaCO3 sinks slower than general detritus because it tends to be smaller wsinkcal(k) = wsink(k) * wombat%wcaco3/wombat%wdetbio From 07233051dfb939dcfa056b2c0b57c10fe301419c Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Tue, 21 Jan 2025 11:40:14 +1100 Subject: [PATCH 21/23] "conservetracers" logical option now active. Setting this to true means that any NO3 and Alkalinity that is lost through burial is added back to the ocean budget via a surface flux in exactly the same location. --- generic_tracers/generic_WOMBATlite.F90 | 57 +++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index 0e19967..ffbedea 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -124,6 +124,7 @@ module generic_WOMBATlite init, & caco3_dynamics, & burial, & + conservetracers, & force_update_fluxes ! Set in generic_tracer_nml real :: & @@ -331,7 +332,8 @@ module generic_WOMBATlite real, dimension(:,:,:), pointer :: & p_det_sediment, & p_detfe_sediment, & - p_caco3_sediment + p_caco3_sediment, & + p_detbury, p_caco3bury real, dimension(:,:,:), pointer :: & p_wdet, & @@ -1414,6 +1416,10 @@ subroutine user_add_params !----------------------------------------------------------------------- call g_tracer_add_param('burial', wombat%burial, .true. ) + ! Add back the lost NO3 and Alk due to burial to surface? + !----------------------------------------------------------------------- + call g_tracer_add_param('conservetracers', wombat%conservetracers, .true. ) + ! CaCO3 remineralisation rate constant [1/s] !----------------------------------------------------------------------- ! Default value matches 0.001714 day-1 in Ziehn et al 2020; differs from @@ -1430,7 +1436,7 @@ subroutine user_add_params ! CaCO3 dissolution factor due to calcite undersaturation !----------------------------------------------------------------------- - call g_tracer_add_param('disscal', wombat%disscal, 0.500) + call g_tracer_add_param('disscal', wombat%disscal, 0.250) ! CaCO3 dissolution factor due to aragonite undersaturation !----------------------------------------------------------------------- @@ -1438,7 +1444,7 @@ subroutine user_add_params ! CaCO3 dissolution factor due to detritus remineralisation creating anoxic microenvironment !----------------------------------------------------------------------- - call g_tracer_add_param('dissdet', wombat%dissdet, 0.250) + call g_tracer_add_param('dissdet', wombat%dissdet, 0.100) ! Background concentration of iron-binding ligand [umol/m3] !----------------------------------------------------------------------- @@ -1736,6 +1742,20 @@ subroutine user_add_tracers(tracer_list) units = 'mol m-2', & prog = .false.) + ! pjb: included here so included in restart + call g_tracer_add(tracer_list, package_name, & + name = 'detbury', & + longname = 'Amount of detritus lost to burial', & + units = 'mol m-2 s-1', & + prog = .false.) + + ! pjb: included here so included in restart + call g_tracer_add(tracer_list, package_name, & + name = 'caco3bury', & + longname = 'Amount of CaCO3 lost to burial', & + units = 'mol m-2 s-1', & + prog = .false.) + end subroutine user_add_tracers !####################################################################### @@ -1857,6 +1877,16 @@ subroutine generic_WOMBATlite_update_from_bottom(tracer_list, dt, tau, model_tim enddo endif + call g_tracer_get_pointer(tracer_list, 'detbury', 'field', wombat%p_detbury) + call g_tracer_get_pointer(tracer_list, 'caco3bury', 'field', wombat%p_caco3bury) + if (wombat%conservetracers) then + wombat%p_detbury(:,:,1) = wombat%det_btm(:,:) / dt * wombat%fbury(:,:) + wombat%p_caco3bury(:,:,1) = wombat%caco3_btm(:,:) / dt * wombat%fbury(:,:) + else + wombat%p_detbury(:,:,1) = 0.0 + wombat%p_caco3bury(:,:,1) = 0.0 + endif + call g_tracer_get_pointer(tracer_list, 'det_sediment', 'field', wombat%p_det_sediment) wombat%p_det_sediment(:,:,1) = wombat%p_det_sediment(:,:,1) + wombat%det_btm(:,:) * (1.0-wombat%fbury(:,:)) ! [mol/m2] call g_tracer_set_values(tracer_list, 'det', 'btm_reservoir', 0.0) @@ -2464,7 +2494,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & n_pools(:,:,:,:) = 0.0 c_pools(:,:,:,:) = 0.0 - do tn = 1,ts_npzd + do tn = 1,ts_npzd !{ n_pools(:,:,:,1) = n_pools(:,:,:,2) c_pools(:,:,:,1) = c_pools(:,:,:,2) @@ -3030,7 +3060,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & enddo; enddo; enddo - enddo + enddo !} nested timestep (ts_npzd) ! Add biotically induced tendency to biotracers !----------------------------------------------------------------------- @@ -3095,7 +3125,9 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & wombat%f_alk(i,j,k) = wombat%f_alk(i,j,k) + wombat%alk_correct(i,j,k) wombat%f_dic(i,j,k) = wombat%f_dic(i,j,k) + wombat%dic_correct(i,j,k) wombat%f_dicp(i,j,k) = max(wombat%dic_min * mmol_m3_to_mol_kg, wombat%f_dic(i,j,k)) - enddo; enddo; enddo + enddo + enddo; enddo + ! Set tracers values call g_tracer_set_values(tracer_list, 'no3', 'field', wombat%f_no3, isd, jsd, ntau=tau) @@ -3224,6 +3256,19 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_set_values(tracer_list, 'fe', 'btf', wombat%b_fe, isd, jsd) call g_tracer_set_values(tracer_list, 'alk', 'btf', wombat%b_alk, isd, jsd) + + ! Apply back burial loss of nitrogen and alkalinity to surface + !----------------------------------------------------------------------- + if (wombat%conservetracers) then + call g_tracer_get_pointer(tracer_list, 'detbury', 'field', wombat%p_detbury) ! [mol/m2/s] + call g_tracer_get_pointer(tracer_list, 'caco3bury', 'field', wombat%p_caco3bury) ! [mol/m2/s] + call g_tracer_get_pointer(tracer_list, 'no3', 'stf', wombat%p_no3_stf) + call g_tracer_get_pointer(tracer_list, 'alk', 'stf', wombat%p_alk_stf) + wombat%p_no3_stf(:,:) = wombat%p_no3_stf(:,:) + wombat%p_detbury(:,:,1)*16.0/122.0 ! [mol/m2/s] + wombat%p_alk_stf(:,:) = wombat%p_alk_stf(:,:) - wombat%p_detbury(:,:,1)*16.0/122.0 & + + wombat%p_caco3bury(:,:,1) * 2.0 ! [mol/m2/s] + endif + !======================================================================= ! Send diagnostics !======================================================================= From 2c21bd8e1a8903eac581e4448854779248da3306 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Tue, 21 Jan 2025 15:43:11 +1100 Subject: [PATCH 22/23] Updated the redistribution of tracer to be spread over the tile in question, rather than at the same exact lon,lat location. --- generic_tracers/generic_WOMBATlite.F90 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index ffbedea..a1fdbeb 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -2034,6 +2034,7 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & real :: phy_minqfe, phy_maxqfe real :: zoo_slmor, epsmin real :: hco3, diss_cal, diss_ara, diss_det + real :: avedetbury, avecaco3bury real, dimension(:,:,:,:), allocatable :: n_pools, c_pools logical :: used @@ -3264,9 +3265,11 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_get_pointer(tracer_list, 'caco3bury', 'field', wombat%p_caco3bury) ! [mol/m2/s] call g_tracer_get_pointer(tracer_list, 'no3', 'stf', wombat%p_no3_stf) call g_tracer_get_pointer(tracer_list, 'alk', 'stf', wombat%p_alk_stf) - wombat%p_no3_stf(:,:) = wombat%p_no3_stf(:,:) + wombat%p_detbury(:,:,1)*16.0/122.0 ! [mol/m2/s] - wombat%p_alk_stf(:,:) = wombat%p_alk_stf(:,:) - wombat%p_detbury(:,:,1)*16.0/122.0 & - + wombat%p_caco3bury(:,:,1) * 2.0 ! [mol/m2/s] + ! Spread the addition around to all grid cells + avedetbury = sum(wombat%p_detbury(:,:,1) * grid_dat(:,:)) / sum(grid_dat(:,:) * grid_tmask(:,:,1)) ! [mol/m2/s] + avecaco3bury = sum(wombat%p_caco3bury(:,:,1) * grid_dat(:,:)) / sum(grid_dat(:,:) * grid_tmask(:,:,1)) ! [mol/m2/s] + wombat%p_no3_stf(:,:) = wombat%p_no3_stf(:,:) + avedetbury*16.0/122.0 ! [mol/m2/s] + wombat%p_alk_stf(:,:) = wombat%p_alk_stf(:,:) - avedetbury*16.0/122.0 + avecaco3bury*2.0 ! [mol/m2/s] endif !======================================================================= From 9bf0d6d7c72918eaa96d94e68463bf70f6065985 Mon Sep 17 00:00:00 2001 From: Pearse Buchanan Date: Wed, 22 Jan 2025 09:14:46 +1100 Subject: [PATCH 23/23] Added if statement to ensure no division by zero during conservetracers option (line 3269 in generic_WOMBATlite.F90) --- generic_tracers/generic_WOMBATlite.F90 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/generic_tracers/generic_WOMBATlite.F90 b/generic_tracers/generic_WOMBATlite.F90 index a1fdbeb..76e30e7 100644 --- a/generic_tracers/generic_WOMBATlite.F90 +++ b/generic_tracers/generic_WOMBATlite.F90 @@ -3266,10 +3266,12 @@ subroutine generic_WOMBATlite_update_from_source(tracer_list, Temp, Salt, & call g_tracer_get_pointer(tracer_list, 'no3', 'stf', wombat%p_no3_stf) call g_tracer_get_pointer(tracer_list, 'alk', 'stf', wombat%p_alk_stf) ! Spread the addition around to all grid cells - avedetbury = sum(wombat%p_detbury(:,:,1) * grid_dat(:,:)) / sum(grid_dat(:,:) * grid_tmask(:,:,1)) ! [mol/m2/s] - avecaco3bury = sum(wombat%p_caco3bury(:,:,1) * grid_dat(:,:)) / sum(grid_dat(:,:) * grid_tmask(:,:,1)) ! [mol/m2/s] - wombat%p_no3_stf(:,:) = wombat%p_no3_stf(:,:) + avedetbury*16.0/122.0 ! [mol/m2/s] - wombat%p_alk_stf(:,:) = wombat%p_alk_stf(:,:) - avedetbury*16.0/122.0 + avecaco3bury*2.0 ! [mol/m2/s] + if (sum(grid_tmask(:,:,1)).gt.0.0) then + avedetbury = sum(wombat%p_detbury(:,:,1) * grid_dat(:,:)) / sum(grid_dat(:,:) * grid_tmask(:,:,1)) ! [mol/m2/s] + avecaco3bury = sum(wombat%p_caco3bury(:,:,1) * grid_dat(:,:)) / sum(grid_dat(:,:) * grid_tmask(:,:,1)) ! [mol/m2/s] + wombat%p_no3_stf(:,:) = wombat%p_no3_stf(:,:) + avedetbury*16.0/122.0 ! [mol/m2/s] + wombat%p_alk_stf(:,:) = wombat%p_alk_stf(:,:) - avedetbury*16.0/122.0 + avecaco3bury*2.0 ! [mol/m2/s] + endif endif !=======================================================================