!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! !! GNU General Public License !! !! !! !! This file is part of the Flexible Modeling System (FMS). !! !! !! !! FMS is free software; you can redistribute it and/or modify !! !! it and are expected to follow the terms of the GNU General Public !! !! License as published by the Free Software Foundation. !! !! !! !! FMS is distributed in the hope that it will be useful, !! !! but WITHOUT ANY WARRANTY; without even the implied warranty of !! !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! !! GNU General Public License for more details. !! !! !! !! You should have received a copy of the GNU General Public License !! !! along with FMS; if not, write to: !! !! Free Software Foundation, Inc. !! !! 59 Temple Place, Suite 330 !! !! Boston, MA 02111-1307 USA !! !! or see: !! !! http://www.gnu.org/licenses/gpl.txt !! !! !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !---------------------------------------------------------------- ! Eric D. Galbraith ! ! ! John P. Dunne ! ! ! Anand Gnanandesikan ! ! ! Niki Zadeh ! ! ! Rick Slater ! ! ! ! This module contains the generic version of BLING. ! It is designed so that both GFDL Ocean models, GOLD and MOM, can use it. ! ! WARNING: although the core components of the model (PO4, Fed, DOP, O2) ! have been quite well tested, the other components should be viewed as ! developmental at this point. There may still be some bugs, particularly ! in the CaCO3 burial scheme. EDG June 4, 2009 ! ! ! ! Biogeochemistry with Light, Iron, Nutrient and Gas (BLING) includes an ! implicit ecological model of growth limitation by light, ! temperature, phosphate and iron, along with dissolved organic ! phosphorus and O2 pools. ! Food web processing in the euphotic zone and remineralization/ ! dissolution through the ocean interior are handled as in Dunne et al. ! (2005). O2 equilibria and gas exchange follow OCMIP2 protocols. ! Additional functionality comes from an optional carbon cycle that is ! non-interactive, i.e. does not change the core BLING behaviour, as ! well as tracers for radiocarbon (14c), a decomposition of carbon ! components by gas exchange and remineralization (carbon_pre), and a ! decomposition of phosphate as preformed and remineralized (po4_pre). ! ! ! ! ! This model is available for public use. ! The current version is BLING.0. The version number refers to the core ! model behaviour; additional tracers exist in different iterations of the ! module. In publications it should be referenced as: ! Galbraith, E.D., Gnanadesikan, A., Dunne, J. and Hiscock, M. 2009. ! Regional impacts of iron-light colimitation in a global ! biogeochemical model. Biogeosciences Discussions, 6, 1-47. ! ! All parameter values are as described in this paper. ! Note that this reference is only for the core model components, and ! does not include any of the additional functionalities, which remain ! undocumented. Please contact Eric Galbraith (eric.galbraith@mcgill.ca) ! for more information. ! ! ! ! This code was developed based on the template of Perth generic TOPAZ code. ! ! ! ! ! ! ! If true, then simulate radiocarbon. Includes 2 prognostic tracers, DI14C ! and DO14C. Requires that do_carbon = .true. Note that 14C is not taken up ! by CaCO3 at the current time, but cycles only through the soft tissue. ! This is a mistake that will be fixed later. ! ! ! ! If true, then simulate the carbon cycle based on strict stoichiometry ! of C:P. Includes 1 prognostic tracer, DIC. ! ! ! ! If true, then simulate the carbon cycle based on strict stoichiometry ! of C:P. Includes 3 prognostic tracers, DIC, ALK and ALK_pre. Requires ! that do_carbon = .true. ! ! ! ! If true, then simulate preformed PO4, a useful theoretical construct ! equal to PO4 in the surface layer and subject only to passive transport ! everywhere else. 1 prognostic tracer, PO4_pre. ! ! ! ! If true, then allow CaCO3 to be buried in sediments as a function ! of sinking CaCO3 flux and bottom water saturation state, and allow ! a river input of alkalinity to compensate. Caution: this will cause ! the alkalinity to have a long term drift, which will produce a long ! term drift in the carbon cycle. Should be considered highly ! experimental at this point. Requires that do_carbon=.true. ! ! ! ! If true, names the BLING diagnostic chlorophyll field 'chl'. Thus, ! if read_chl=.false. in the shortwave namelist, BLING chlorophyll will ! be used to calculate sw absorption. Set this to false in order to ! have the chlorophyll field named chl_b, preventing conflict with the ! TOPAZ chlorophyll field, so that the two modules can run ! simultaneously. ! ! ! ! !---------------------------------------------------------------- module generic_BLING use coupler_types_mod, only: coupler_2d_bc_type use field_manager_mod, only: fm_string_len, fm_path_name_len use mpp_mod, only: mpp_error, stdlog, NOTE, WARNING, FATAL, stdout, mpp_chksum use fms_mod, only: open_namelist_file, check_nml_error, close_file use fms_mod, only: field_exist, file_exist use time_manager_mod, only: time_type use fm_util_mod, only: fm_util_start_namelist, fm_util_end_namelist use diag_manager_mod, only: register_diag_field, send_data use constants_mod, only: WTMCO2, WTMO2 use g_tracer_utils, only : g_tracer_type,g_tracer_start_param_list,g_tracer_end_param_list use g_tracer_utils, only : g_tracer_add,g_tracer_add_param, g_tracer_set_files use g_tracer_utils, only : g_tracer_set_values,g_tracer_get_pointer use g_tracer_utils, only : g_tracer_get_common,g_tracer_set_common use g_tracer_utils, only : g_tracer_coupler_set,g_tracer_coupler_get use g_tracer_utils, only : g_tracer_send_diag, g_tracer_get_values use FMS_ocmip2_co2calc_mod, only : FMS_ocmip2_co2calc, CO2_dope_vector implicit none ; private character(len=fm_string_len), parameter :: mod_name = 'generic_BLING' character(len=fm_string_len), parameter :: package_name = 'generic_bling' public do_generic_BLING public generic_BLING_register public generic_BLING_init public generic_BLING_register_diag public generic_BLING_update_from_coupler public generic_BLING_update_from_source public generic_BLING_update_from_bottom public generic_BLING_set_boundary_values public generic_BLING_end !The following logical for using this module is overwritten ! generic_tracer_nml namelist logical, save :: do_generic_BLING = .false. real, parameter :: sperd = 24.0 * 3600.0 real, parameter :: spery = 365.25 * sperd real, parameter :: epsln=1.0e-30 ! Namelist Options logical :: do_14c = .true. ! Requires do_carbon = .true. logical :: do_carbon = .true. logical :: do_carbon_pre = .true. ! Requires do_carbon = .true. logical :: do_po4_pre = .true. logical :: bury_caco3 = .false. ! Requires do_carbon = .true. logical :: use_bling_chl = .false. ! Must be false to run with TOPAZ namelist /generic_bling_nml/ do_14c, do_carbon, do_carbon_pre, & do_po4_pre, bury_caco3, use_bling_chl ! !The following two types contain all the parameters and arrays used in this module. type generic_BLING_type logical :: & init, & ! If tracers should be initializated prevent_neg_o2, & tracer_debug real :: & alpha_max, & ! Quantum yield under low light, Fe-replete alpha_min, & ! Quantum yield under low light, Fe-limited c_2_p, & ! Carbon to Phosphorus ratio ca_2_p, & ! CaCO3 to Phosphorus ratio (of small phytoplankton) ca_remin_depth, & ! CaCO3 dissolution length scale (subject to omega) chl_min, & ! Minimum chl concentration allowed (for numerical stability) def_fe_min, & ! Minimum value for iron deficiency term fast_gasex, & ! Gas exchange rate multiplier for DIC_sat fe_2_p_max, & ! Iron to Phosphate uptake ratio scaling fe_2_p_sed, & ! Iron to Phosphorus ratio in sediments felig_bkg, & ! Iron ligand concentration gamma_biomass, & ! Biomass adjustment timescale gamma_dop, & ! Dissolved organic phosphorus decay gamma_irr_mem, & ! Photoadaptation timescale gamma_pop, & ! Patriculate Organic Phosphorus decay gamma_tag, & ! Restoring time constant for nutrient source tracers half_life_14c, & ! Radiocarbon half-life k_fe_2_p, & ! Fe:P half-saturation constant k_fe_uptake, & ! Iron half-saturation concentration k_o2, & ! Oxygen half-saturation concentration k_po4, & ! Phosphate half-saturation concentration kappa_eppley, & ! Temperature dependence kappa_remin, & ! Temperature dependence for particle fractionation kfe_inorg, & ! Iron scavenging, 2nd order kfe_eq_lig_max, & ! Maximum light-dependent iron ligand stability constant kfe_eq_lig_min, & ! Minimum light-dependent iron ligand stability constant kfe_eq_lig_irr, & ! Irradiance scaling for iron ligand stability constant kfe_eq_lig_femin, & ! Low-iron threshold for ligand stability constant kfe_org, & ! Iron scavenging, 1st order lambda0, & ! Total mortality rate constant lambda_14c, & ! Radiocarbon decay rate resp_frac, & ! Biomass maintenace requirement as fraction of pc_0 mass_2_p, & ! Organic matter mass to Phosphorus ratio n_2_p, & ! Nitrogen to Phosphorus ratio o2_2_p, & ! Oxygen to Phosphorus ratio o2_min, & ! Anaerobic respiration threshold P_star, & ! Pivotal phytoplankton concentration pc_0, & ! Maximum carbon-specific growth rate phi_dop, & ! Dissolved organic phosphorus fraction of uptake phi_lg, & ! Fraction of small phytoplankton converted to detritus phi_sm, & ! Fraction of large phytoplankton converted to detritus remin_min, & ! Minimum remineralization under low O2 rho_dense, & ! Deep boundary density for exposure tracers rho_light, & ! Shallow boundary density for exposure tracers sed_flux, & ! Seafloor sedimentary flux (globally constant) thetamax_hi, & ! Maximum Chl:C ratio when iron-replete thetamax_lo, & ! Maximum Chl:C ratio when iron-limited wsink_acc, & ! Sinking rate acceleration with depth wsink0, & ! Sinking rate at surface wsink0_z, & ! Depth to which sinking rate remains constant z_sed ! Thickness of active sediment layer real :: htotal_scale_lo, htotal_scale_hi, htotal_in real :: Rho_0, a_0, a_1, a_2, a_3, a_4, a_5, b_0, b_1, b_2, b_3, c_0 real :: a1_co2, a2_co2, a3_co2, a4_co2, a1_o2, a2_o2, a3_o2, a4_o2 ! ! The prefixes "f_" refers to a "field" and "j" to a volumetric rate, and ! "b_" to a bottom flux. The prefix "p_" refers to a "pointer". ! real, dimension(:,:,:), ALLOCATABLE :: & alpha,& biomass_p_ts,& def_fe,& expkT,& f_biomass_p,& f_cased,& f_chl,& f_dop,& f_fed,& f_htotal,& f_htotal_sat,& f_irr_mem,& f_o2,& f_po4,& f_po4_pre,& fe_2_p_uptake,& feprime,& fpofe,& fpop,& frac_lg,& frac_pop,& irr_inst,& irr_mix,& irrk,& jdop,& jfe_ads_inorg,& jfe_ads_org,& jfe_recycle,& jfe_reminp,& jfe_uptake,& jo2,& jp_recycle,& jp_reminp,& jp_uptake,& jpo4,& jpofe,& jpop,& kfe_eq_lig,& pc_m,& mu,& pc_tot,& theta,& thetamax_fe,& wsink,& zremin,& zt real, dimension(:,:,:), ALLOCATABLE :: & f_dop_n,& f_dop_nx,& f_dop_s,& f_dop_sx,& f_po4_n,& f_po4_nx,& f_po4_s,& f_po4_sx,& f_po4_pre_n,& f_po4_pre_s,& fpop_n,& fpop_nx,& fpop_s,& fpop_sx,& jpn_reminp,& jpnx_reminp,& jps_reminp,& jpsx_reminp real, dimension(:,:,:), ALLOCATABLE :: & c14_2_p,& co3_solubility,& f_alk,& f_alk_pre,& f_co3_ion,& f_di14c,& f_dic,& f_dic_pre,& f_dic_sat,& f_do14c,& fcaco3,& fpo14c,& j14c_decay_dic,& j14c_decay_doc,& j14c_reminp,& jca_reminp,& jca_uptake,& jdi14c,& jdo14c,& zremin_caco3 real, dimension(:,:), ALLOCATABLE :: & fe_burial,& ffe_sed,& b_fed,& b_o2,& b_po4 real, dimension(:,:), ALLOCATABLE :: & b_po4_n,& b_po4_nx,& b_po4_s,& b_po4_sx real, dimension(:,:), ALLOCATABLE :: & co2_csurf,pco2_surf,co2_alpha,& c14o2_csurf,c14o2_alpha,co2_sat_csurf,pco2_sat_surf,& htotallo, htotalhi,& htotal_satlo, htotal_sathi,& b_alk,& b_di14c,& b_dic,& fcaco3_to_sed,& fcased_burial,& fcased_redis real, dimension(:,:,:,:), pointer :: & p_dop,& p_fed,& p_o2,& p_po4,& p_po4_pre real, dimension(:,:,:,:), pointer :: & p_dop_n,& p_dop_nx,& p_dop_s,& p_dop_sx,& p_po4_n,& p_po4_nx,& p_po4_s,& p_po4_sx,& p_po4_pre_n,& p_po4_pre_s real, dimension(:,:,:,:), pointer :: & p_alk,& p_alk_pre,& p_di14c,& p_dic,& p_dic_pre,& p_do14c integer :: nkml character(len=fm_string_len) :: file character(len=fm_string_len) :: ice_restart_file character(len=fm_string_len) :: ocean_restart_file,IC_file integer :: & id_alpha = -1, & ! Iron-limited initial slope of P-I curve id_b_alk = -1, & ! Bottom flux of alkalinity id_b_dic = -1, & ! Bottom flux of DIC id_b_di14c = -1, & ! Bottom flux of DI14C id_b_fed = -1, & ! Bottom flux of Fe id_b_o2 = -1, & ! Bottom flux of O2 id_b_po4 = -1, & ! Bottom flux of PO4 id_b_po4_n = -1, & ! Bottom flux of PO4_n id_b_po4_nx = -1, & ! Bottom flux of PO4_nx id_b_po4_s = -1, & ! Bottom flux of PO4_s id_b_po4_sx = -1, & ! Bottom flux of PO4_sx id_biomass_p_ts = -1, & ! Instantaneous P concentration in biomass id_c14_2_p = -1, & ! DI14C to PO4 uptake ratio id_c14o2_csurf = -1, & ! Surface water 14CO2* id_c14o2_alpha = -1, & ! Surface water 14CO2* solubility id_co2_csurf = -1, & ! Surface water CO2* id_co2_alpha = -1, & ! Surface water CO2* solubility id_co2_sat_csurf = -1, & ! Surface water CO2* for DIC_sat id_co3_solubility= -1, & ! Calcite solubility id_def_fe = -1, & ! Iron deficiency term id_expkT = -1, & ! Temperature dependence id_fcaco3 = -1, & ! CaCO3 sinking flux id_fcaco3_to_sed = -1, & ! CaCO3 sinking flux in bottom layer id_fcased_burial = -1, & ! CaCO3 permanent burial flux id_fcased_redis = -1, & ! CaCO3 dissolution flux from active sediment layer id_fe_2_p_uptake = -1, & ! Fed:PO4 of instantaneous uptake id_feprime = -1, & ! Free (unbound) iron concentration id_fe_burial = -1, & ! Flux of iron to sediment as particulate id_ffe_sed = -1, & ! Sediment iron efflux id_fpofe = -1, & ! POFe sinking flux id_fpo14c = -1, & ! PO14C sinking flux id_fpop = -1, & ! POP sinking flux id_fpop_n = -1, & ! POP_N sinking flux id_fpop_nx = -1, & ! POP_Nx sinking flux id_fpop_s = -1, & ! POP_S sinking flux id_fpop_sx = -1, & ! POP_Sx sinking flux id_frac_lg = -1, & ! Fraction of production by large phytoplankton id_frac_pop = -1, & ! Fraction of uptake converted to particulate id_irr_inst = -1, & ! Instantaneous irradiance id_irr_mix = -1, & ! Mixed layer irradiance id_irrk = -1, & ! Effective susceptibility to light limitation id_j14c_decay_dic= -1, & ! Radioactive decay of DI14C id_j14c_decay_doc= -1, & ! Radioactive decay of DO14C id_j14c_reminp = -1, & ! 14C particle remineralization layer integral id_jca_reminp = -1, & ! CaCO3 dissolution layer integral id_jca_uptake = -1, & ! CaCO3 formation layer integral id_jdi14c = -1, & ! DI14C source layer integral id_jdo14c = -1, & ! Semilabile DO14C source layer integral id_jdop = -1, & ! Semilabile DOP source layer integral id_jfe_ads_inorg = -1, & ! Iron adsorption (2nd order) layer integral id_jfe_ads_org = -1, & ! Iron adsorption to fpop layer integral id_jfe_recycle = -1, & ! Iron fast recycling layer integral id_jfe_reminp = -1, & ! Iron particle remineralization layer integral id_jfe_uptake = -1, & ! Iron uptake layer integral id_jo2 = -1, & ! O2 source layer integral id_jp_recycle = -1, & ! Phosphorus fast recycling layer integral id_jp_reminp = -1, & ! Phosphorus particle remineralization layer integral id_jpn_reminp = -1, & ! Northern phosphorus particle remineralization layer integral id_jpnx_reminp = -1, & ! Northern exposure phosphorus particle remineralization layer integral id_jps_reminp = -1, & ! Southern phosphorus particle remineralization layer integral id_jpsx_reminp = -1, & ! Southern exposure phosphorus particle remineralization layer integral id_jp_uptake = -1, & ! Phosphorus uptake layer integral id_jpo4 = -1, & ! PO4 source layer integral id_jpofe = -1, & ! Particulate organic iron source layer integral id_jpop = -1, & ! Particulate organic phosphorus source layer integral id_kfe_eq_lig = -1, & ! Iron-ligand stability constant id_pc_m = -1, & ! Light-saturated maximum photosynthesis rate (carbon specific) id_mu = -1, & ! Growth rate after respiratory loss(carbon specific) id_pc_tot = -1, & ! Fully-limited photosynthesis rate (carbon specific) id_pco2_surf = -1, & ! Surface water pCO2 id_pco2_sat_surf = -1, & ! Surface water pCO2 for DIC_sat id_theta = -1, & ! Chl:C ratio id_thetamax_fe = -1, & ! Iron-limited maximum Chl:C ratio id_wsink = -1, & ! Sinking rate id_zremin = -1, & ! Remineralization length scale id_zremin_caco3 = -1, & ! CaCO3 remineralization length scale id_alk = -1, & ! Alkalinity Prognostic tracer id_alk_pre = -1, & ! Preformed Alkalinity Prognostic tracer id_di14c = -1, & ! Dissolved inorganic radiocarbon Prognostic tracer id_dic = -1, & ! Dissolved inorganic carbon Prognostic tracer id_dic_pre = -1, & ! Preformed DIC Prognostic tracer id_dic_sat = -1, & ! Saturation DIC Prognostic tracer id_do14c = -1, & ! Semi-labile DO radiocarbon Prognostic tracer id_dop = -1, & ! Semi-labile dissolved organic P Prognostic tracer id_dop_n = -1, & ! Semi-labile dissolved organic P Prognostic tracer id_dop_nx = -1, & ! Semi-labile dissolved organic P Prognostic tracer id_dop_s = -1, & ! Semi-labile dissolved organic P Prognostic tracer id_dop_sx = -1, & ! Semi-labile dissolved organic P Prognostic tracer id_fed = -1, & ! Dissolved Iron Prognostic tracer id_o2 = -1, & ! Oxygen Prognostic tracer id_po4 = -1, & ! Phosphate Prognostic tracer id_po4_n = -1, & ! Phosphate Prognostic tracer id_po4_nx = -1, & ! Phosphate Prognostic tracer id_po4_s = -1, & ! Phosphate Prognostic tracer id_po4_sx = -1, & ! Phosphate Prognostic tracer id_po4_pre = -1, & ! Preformed Phosphate Prognostic tracer id_po4_pre_n = -1, & ! Preformed Phosphate Prognostic tracer id_po4_pre_s = -1, & ! Preformed Phosphate Prognostic tracer id_htotal = -1, & ! Hydrogen ion Diagnostic tracer id_htotal_sat = -1, & ! Hydrogen ion for DIC_sat Diagnostic tracer id_co3_ion = -1, & ! CO3= ion Diagnostic tracer id_cased = -1, & ! Active sediment CaCO3 concentration Diagnostic tracer id_chl = -1, & ! Chlorophyll Diagnostic tracer id_biomass_p = -1, & ! Biomass Diagnostic tracer id_irr_mem = -1 ! Irradiance Memory Diagnostic tracer end type generic_BLING_type !An auxiliary type for storing varible names type, public :: vardesc character(len=fm_string_len) :: name ! The variable name in a NetCDF file. character(len=fm_string_len) :: longname ! The long name of that variable. character(len=1) :: hor_grid ! The hor. grid: u, v, h, q, or 1. character(len=1) :: z_grid ! The vert. grid: L, i, or 1. character(len=1) :: t_grid ! The time description: s, a, m, or 1. character(len=fm_string_len) :: units ! The dimensions of the variable. character(len=1) :: mem_size ! The size in memory: d or f. end type vardesc type(generic_BLING_type) :: bling type(CO2_dope_vector) :: CO2_dope_vec contains !####################################################################### subroutine generic_BLING_register(tracer_list) type(g_tracer_type), pointer :: tracer_list integer :: ioun integer :: ierr integer :: io_status character(len=fm_string_len) :: name !----------------------------------------------------------------------- ! local parameters !----------------------------------------------------------------------- ! character(len=fm_string_len), parameter :: sub_name = 'generic_bling_register' character(len=256), parameter :: error_header = & '==>Error from ' // trim(mod_name) // '(' // trim(sub_name) // '): ' character(len=256), parameter :: warn_header = & '==>Warning from ' // trim(mod_name) // '(' // trim(sub_name) // '): ' character(len=256), parameter :: note_header = & '==>Note from ' // trim(mod_name) // '(' // trim(sub_name) // '): ' ! provide for namelist over-ride ! This needs to go before the add_tracers in order to allow the namelist ! settings to switch tracers on and off. ! ioun = open_namelist_file() read (ioun, generic_bling_nml,iostat=io_status) write (stdout(),'(/)') write (stdout(), generic_bling_nml) write (stdlog(), generic_bling_nml) ierr = check_nml_error(io_status,'generic_bling_nml') call close_file (ioun) if ((do_14c) .and. (do_carbon)) then write (stdout(),*) trim(note_header), 'Simulating radiocarbon' else if ((do_14c) .and. .not. (do_carbon)) then call mpp_error(FATAL, trim(error_header) // & 'Do_14c requires do_carbon' // trim(name)) endif if ((do_carbon_pre) .and. (do_carbon)) then write (stdout(),*) trim(note_header), 'Calculating DIC_pre and DIC_sat' else if ((do_carbon_pre) .and. .not. (do_carbon)) then call mpp_error(FATAL, trim(error_header) // & 'Do_carbon_pre requires do_carbon' // trim(name)) endif if ((bury_caco3) .and. (do_carbon)) then write (stdout(),*) trim(note_header), & 'CAUTION: burying CaCO3, are you sure you want to do this?' else if ((bury_caco3) .and. .not. (do_carbon)) then call mpp_error(FATAL, trim(error_header) // & 'Bury_caco3 requires do_carbon' // trim(name)) endif !Specify all prognostic and diagnostic tracers of this modules. call user_add_tracers(tracer_list) end subroutine generic_BLING_register !####################################################################### ! ! ! Initialize the generic BLING module ! ! ! This subroutine: ! Adds all the BLING Tracers to the list of generic Tracers passed ! to it via utility subroutine g_tracer_add(). Adds all the parameters ! used by this module via utility subroutine g_tracer_add_param(). ! Allocates all work arrays used in the module. ! ! ! ! Pointer to the head of generic tracer list. ! ! subroutine generic_BLING_init(tracer_list) type(g_tracer_type), pointer :: tracer_list !Specify and initialize all parameters used by this package call user_add_params !Allocate all the private work arrays used by this module. call user_allocate_arrays end subroutine generic_BLING_init !####################################################################### ! Register diagnostic fields to be used in this module. ! Note that the tracer fields are automatically registered in user_add_tracers ! User adds only diagnostics for fields that are not a member of g_tracer_type ! subroutine generic_BLING_register_diag real,parameter :: missing_value1=-1.0e+10 type(vardesc) :: vardesc_temp integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau, axes(3) type(time_type):: init_time call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,axes=axes,init_time=init_time) ! The following vardesc types contain a package of metadata about each tracer, ! including, in order, the following elements: name; longname; horizontal ! staggering ('h') for collocation with thickness points ; vertical staggering ! ('L') for a layer variable ; temporal staggering ('s' for snapshot) ; units ; ! and precision in non-restart output files ('f' for 32-bit float or 'd' for ! 64-bit doubles). For most tracers, only the name, longname and units should ! be changed. ! ! Register Diagnostics !=========================================================== ! ! Core diagnostics vardesc_temp = vardesc& ("alpha","Fe-limitated initial slope of P-I curve",'h','L','s','g C g Chl-1 m2 W-1 s-1','f') bling%id_alpha = 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& ("b_fed","Bottom flux of Fe into sediment",'h','1','s','mol m-2 s-1','f') bling%id_b_fed = 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& ("b_o2","Bottom flux of O2 into sediment",'h','1','s','mol m-2 s-1','f') bling%id_b_o2 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc& ("b_po4","Bottom flux of PO4 into sediment",'h','1','s','mol m-2 s-1','f') bling%id_b_po4 = 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& ("biomass_p_ts","Instantaneous P concentration in biomass",'h','L','s','mol kg-1','f') bling%id_biomass_p_ts = 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& ("def_Fe","Iron deficiency term",'h','L','s','unitless','f') bling%id_def_fe = 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& ("expkT","Temperature dependence",'h','L','s','unitless','f') bling%id_expkT = 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& ("fe_2_p_uptake","Uptake ratio of Fed:PO4",'h','L','s','mol Fe mol P-1','f') bling%id_fe_2_p_uptake = 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& ("fe_burial","Sedimenting iron flux",'h','1','s','mol m-2 s-1','f') bling%id_fe_burial = 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& ("feprime","Concentration of free, unbound iron",'h','L','s','mol kg-1','f') bling%id_feprime = 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& ("ffe_sed","Sediment iron efflux",'h','1','s','mol m-2 s-1','f') bling%id_ffe_sed = 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& ("fpofe","POFe sinking flux at layer bottom",'h','L','s','mol m-2 s-1','f') bling%id_fpofe = 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& ("fpop","POP sinking flux at layer bottom",'h','L','s','mol m-2 s-1','f') bling%id_fpop = 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& ("frac_lg","Fraction of production by large phytoplankton",'h','L','s','unitless','f') bling%id_frac_lg = 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& ("frac_pop","Particulate fraction of total uptake",'h','L','s','unitless','f') bling%id_frac_pop = 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& ("irr_inst","Instantaneous light",'h','L','s','W m-2','f') bling%id_irr_inst = 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& ("irr_mix","Mixed layer light",'h','L','s','W m-2','f') bling%id_irr_mix = 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& ("irrk","Tendency to light limitation",'h','L','s','W m-2','f') bling%id_irrk = 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& ("jdop","DOP source layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jdop = 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& ("jfe_ads_inorg","Iron adsorption (2nd order) layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jfe_ads_inorg = 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& ("jfe_ads_org","Iron adsorption to FPOP layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jfe_ads_org = 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& ("jfe_recycle","Fast recycling of iron layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jfe_recycle = 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& ("jfe_reminp","Sinking particulate Fe decay layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jfe_reminp = 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& ("jfe_uptake","Iron production layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jfe_uptake = 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& ("jp_recycle","Fast recycling of PO4 layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jp_recycle = 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& ("jp_reminp","Sinking particulate P decay layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jp_reminp = 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& ("jp_uptake","PO4 uptake layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jp_uptake = 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& ("jo2","O2 source layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jo2 = 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& ("jpo4","PO4 source layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jpo4 = 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& ("jpop","Particulate P source layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jpop = 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& ("jpofe","Particulate Fe source layer integral",'h','L','s','mol m-2 s-1','f') bling%id_jpofe = 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& ("kfe_eq_lig","Iron ligand stability constant",'h','L','s','mol-1 kg','f') bling%id_kfe_eq_lig = 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& ("pc_m","Light-saturated photosynthesis rate (carbon specific)",'h','L','s','s-1','f') bling%id_pc_m = 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& ("mu","Net growth rate after respiratory loss",'h','L','s','s-1','f') bling%id_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& ("pc_tot","Photosynthesis rate (carbon specific)",'h','L','s','s-1','f') bling%id_pc_tot = 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& ("theta","Chl:C ratio",'h','L','s','g Chl g C-1','f') bling%id_theta = 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& ("thetamax_fe","Fe-limited max Chl:C",'h','L','s','g Chl g C-1','f') bling%id_thetamax_fe = 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& ("wsink","Sinking rate",'h','L','s','m s-1','f') bling%id_wsink = 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& ("zremin","Remineralization lengthscale",'h','L','s','m','f') bling%id_zremin = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) if (do_carbon) then !<> if (do_14c) then !<> if (do_carbon_pre) then !<> endif !CARBON CYCLE>> end subroutine generic_BLING_register_diag !####################################################################### ! ! This is an internal sub, not a public interface. ! Add all the parameters to be used in this module. ! subroutine user_add_params !Specify all parameters used in this modules. !============================================================== !User adds one call for each parameter below! !User also adds the definition of each parameter in generic_BLING_params type !============================================================== !============= !Block Starts: g_tracer_add_param !============= !Add the known experimental parameters used for calculations !in this module. !All the g_tracer_add_param calls must happen between !g_tracer_start_param_list and g_tracer_end_param_list calls. !This implementation enables runtime overwrite via field_table. ! call g_tracer_start_param_list(package_name) ! g_tracer_add_param(name , variable , default_value) !call g_tracer_add_param('', bling%, ) ! call g_tracer_add_param('init', bling%init, .false. ) ! ! Rho_0 is used in the Boussinesq ! approximation to calculations of pressure and ! pressure gradients, in units of kg m-3. call g_tracer_add_param('RHO_0', bling%Rho_0, 1035.0) call g_tracer_add_param('NKML' , bling%nkml, 1) ! !----------------------------------------------------------------------- ! Gas exchange !----------------------------------------------------------------------- ! coefficients for O2 saturation !----------------------------------------------------------------------- call g_tracer_add_param('a_0', bling%a_0, 2.00907) call g_tracer_add_param('a_1', bling%a_1, 3.22014) call g_tracer_add_param('a_2', bling%a_2, 4.05010) call g_tracer_add_param('a_3', bling%a_3, 4.94457) call g_tracer_add_param('a_4', bling%a_4, -2.56847e-01) call g_tracer_add_param('a_5', bling%a_5, 3.88767) call g_tracer_add_param('b_0', bling%b_0, -6.24523e-03) call g_tracer_add_param('b_1', bling%b_1, -7.37614e-03) call g_tracer_add_param('b_2', bling%b_2, -1.03410e-02 ) call g_tracer_add_param('b_3', bling%b_3, -8.17083e-03) call g_tracer_add_param('c_0', bling%c_0, -4.88682e-07) !----------------------------------------------------------------------- ! Schmidt number coefficients !----------------------------------------------------------------------- ! Compute the Schmidt number of CO2 in seawater using the ! formulation presented by Wanninkhof (1992, J. Geophys. Res., 97, ! 7373-7382). !----------------------------------------------------------------------- !New Wanninkhof numbers call g_tracer_add_param('a1_co2', bling%a1_co2, 2068.9) call g_tracer_add_param('a2_co2', bling%a2_co2, -118.63) call g_tracer_add_param('a3_co2', bling%a3_co2, 2.9311) call g_tracer_add_param('a4_co2', bling%a4_co2, -0.027) !--------------------------------------------------------------------- ! Compute the Schmidt number of O2 in seawater using the ! formulation proposed by Keeling et al. (1998, Global Biogeochem. ! Cycles, 12, 141-163). !--------------------------------------------------------------------- !New Wanninkhof numbers call g_tracer_add_param('a1_o2', bling%a1_o2, 1929.7) call g_tracer_add_param('a2_o2', bling%a2_o2, -117.46) call g_tracer_add_param('a3_o2', bling%a3_o2, 3.116) call g_tracer_add_param('a4_o2', bling%a4_o2, -0.0306) call g_tracer_add_param('htotal_scale_lo', bling%htotal_scale_lo, 0.01) call g_tracer_add_param('htotal_scale_hi', bling%htotal_scale_hi, 100.0) ! Fast gas exchange multiplier for DIC_sat ! Should be >30, but can be reduced during spinup to prevent instability call g_tracer_add_param('fast_gasex', bling%fast_gasex, 30.) ! mol Fed mol PO4-1 !----------------------------------------------------------------------- ! Uptake !----------------------------------------------------------------------- ! ! Phytoplankton growth altered from Geider et al (1997) ! and Moore et al (2002). ! The factor of 6.022e17 is to convert ! from umol to quanta and 2.77e18 to convert from quanta/sec ! to Watts given the average energy spectrum for underwater ! PAR from the Seabird sensor. ! call g_tracer_add_param('alpha_max', bling%alpha_max, 1.6e-5 *2.77e18/6.022e17) ! g C g Chl-1 m2 W-1 s-1 call g_tracer_add_param('alpha_min', bling%alpha_min, 0.4e-5 *2.77e18/6.022e17) ! g C g Chl-1 m2 W-1 s-1 call g_tracer_add_param('kappa_eppley', bling%kappa_eppley, 0.063) ! deg C-1 call g_tracer_add_param('resp_frac', bling%resp_frac, 0.0) ! dimensionless call g_tracer_add_param('pc_0', bling%pc_0, 1.0e-5) ! s-1 !chd originally 1.0e-5 call g_tracer_add_param('thetamax_hi', bling%thetamax_hi, 0.040) ! g Chl g C-1 call g_tracer_add_param('thetamax_lo', bling%thetamax_lo, 0.010) ! g Chl g C-1 ! ! Chl:C response rate constant for phytoplankton calibrated to 1 d-1 ! after Owens et al (1980, Diel Periodicity in cellular Chlorophyll ! content of marine diatoms, Mar. Biol, 59, 71-77). ! call g_tracer_add_param('gamma_irr_mem', bling%gamma_irr_mem, 1.0 / sperd) ! s-1 ! Introduce a minimum chlorophyll concentration for numerical stability. ! Value is an order of magnitude less than the minimum produced in topaz. ! call g_tracer_add_param('chl_min', bling%chl_min, 1.e-5) ! ug kg-1 ! ! The biomass reponds to changes in growth rate with an arbitrary 2 day lag. ! call g_tracer_add_param('gamma_biomass', bling%gamma_biomass, 0.5 / sperd) ! s-1 !----------------------------------------------------------------------- ! Monod half saturation coefficient for phosphate. Value of Aumont (JGR, 2002) ! used for large phytoplankton. call g_tracer_add_param('k_po4', bling%k_po4, 1.0e-7) ! mol PO4 kg-1 !----------------------------------------------------------------------- ! Fe uptake and limitation. ! The uptake ratio of Fe:P is determined from a Monod constant and a ! scaling factor. ! The k_Fe_uptake is high, to provide luxury uptake of iron as a ! relatively linear function of iron concentrations under open-ocean ! conditions, consistent with the results of Sunda and Huntsman (Fig 1, ! Nature, 1997). call g_tracer_add_param('k_fe_uptake', bling%k_fe_uptake, 0.8e-9) ! mol Fe kg-1 ! This Monod term, which is nearly linear with [Fe], is multiplied by a ! scaling term to provide the actual Fe:P uptake ratio such that, at ! [Fe] = k_fe_uptake, Fe:P = fe_2_p_max / 2. ! This maximum value was set in accordance with the range of ! open-ocean Fe:C ratios summarized by Boyd et al. (Science, 2007) and ! converted to a Fe:P ratio. ! As a tuning parameter, it affects the amount of Fe that cycles via the ! organic matter pathway, and its ratio to k_fe_2_p determines the ! degree of iron limitation (the larger this ratio, the less iron ! limitation there will be). call g_tracer_add_param('fe_2_p_max', bling%fe_2_p_max, 28.e-6 * 106.) ! mol Fed mol PO4-1 ! The k_fe_2_p is the Fe:P at which the iron-limitation term has a ! value of 0.5, chosen according to Sunda and Huntsman (Fig. 2, ! Nature, 1997). Converted from Fe:C ratio. call g_tracer_add_param('k_fe_2_p', bling%k_fe_2_p, 7.e-6 * 106.) ! mol Fe mol P-1 ! In order to represent enzymatic plasticity and the ability of plankton ! to make do with very low Fe supply - including by liberating recalcitrant ! iron - the def_fe should not approach zero, but instead some small ! positive number << 1, def_fe_min. This prevents unrealistically-strong ! limitation of phytoplankton under very low iron concentrations. call g_tracer_add_param('def_fe_min', bling%def_fe_min, 0.) ! mol Fe mol P-1 !----------------------------------------------------------------------- ! Mortality & Remineralization !----------------------------------------------------------------------- ! ! T=0 phytoplankton specific total-mortality rate from the global ! synthesis of Dunne et al. (2005) ! call g_tracer_add_param('lambda0', bling%lambda0, 0.19 / sperd) ! s-1 ! ! Pivot phytoplankton concentration for grazing-based ! variation in ecosystem structure from the global ! synthesis of Dunne et al. (2005). Converted from mol C m-3. ! call g_tracer_add_param('P_star', bling%P_star, 1.9e-3 / 1028. / 106.0) ! mol P kg-1 ! ! Temperature-dependence of fractional detritus production ! from the global synthesis of Dunne et al. (2005) ! call g_tracer_add_param('kappa_remin', bling%kappa_remin, -0.032) ! deg C-1 ! Phytoplankton fractional detritus production by size class, ! from the global synthesis of Dunne et al. (2005) call g_tracer_add_param('phi_lg', bling%phi_lg, 1.0) ! unitless call g_tracer_add_param('phi_sm', bling%phi_sm, 0.18) ! unitless ! !----------------------------------------------------------------------- ! Dissolved Organic Material remineralization rate constants ! and fractional production ratios, all to be consistent ! with the work of Abell et al. (2000, Distributions of TOP, TON and TOC ! in the North pacific subtropical gyre: Implications for nutrient supply ! in the surface ocean and remineralization in the upper thermocline, ! J. Mar. Res., 58, 203-222). ! Phi_dop is the fraction of non-sinking OM converted to DOP, and ! gamma_dop is the first-order decay rate constant for DOP. ! call g_tracer_add_param('phi_dop' , bling%phi_dop, 0.1) ! dimensionless call g_tracer_add_param('gamma_dop', bling%gamma_dop, 1.0 / (4.0 * spery)) ! s-1 ! ! !----------------------------------------------------------------------- ! Remineralization !----------------------------------------------------------------------- ! ! Stoichiometric ratios taken from Anderson (1995) as discussed in ! Sarmiento and Gruber (2008), and Sarmiento et al. (2002) for Ca:P. ! call g_tracer_add_param('c_2_p', bling%c_2_p, 106.0 ) ! mol C mol P-1 call g_tracer_add_param('ca_2_p', bling%ca_2_p, 106.0 * .015 ) ! mol C mol P-1 call g_tracer_add_param('n_2_p', bling%n_2_p, 16. ) ! mol C mol P-1 call g_tracer_add_param('o2_2_p', bling%o2_2_p, 150.0 ) ! mol O2 mol P-1 ! Convert from mol P m-3 to mg C l-1 call g_tracer_add_param('mass_2_p', bling%mass_2_p, 106. * 12.001 ) ! g C mol P-1 ! Radiocarbon call g_tracer_add_param('half_life_14c', bling%half_life_14c, 5730.0 ) ! a ! !----------------------------------------------------------------------- ! Remineralization length scales ! ! Values of parameters to approximate upper e-folding of the globally-tuned ! "Martin curve" used in the OCMIP-II Biotic configuration of (z/75)^-0.9 ! that gives a value of exp(-1) at 228 m from 75 m for an e-folding scale ! of 188 m. ! Here these are given as a linear function of depth, ! wsink = wsink0 + wsink_acc * (z - wsink0_z) call g_tracer_add_param('wsink_acc', bling%wsink_acc, 0.05 / sperd) ! s-1 call g_tracer_add_param('wsink0', bling%wsink0, 16.0 / sperd) ! m s-1 call g_tracer_add_param('wsink0_z', bling%wsink0_z, 80. ) ! m call g_tracer_add_param('gamma_pop', bling%gamma_pop, 0.12 / sperd ) ! s-1 ! Half saturation oxygen concentration for oxic remineralization rate. ! call g_tracer_add_param('k_o2', bling%k_o2, 20.0e-6) ! mol O2 kg-1 ! ! Remineralization rate under suboxic/anoxic conditions, as a fraction of the rate under ! fully oxidized conditions. ! call g_tracer_add_param('remin_min', bling%remin_min, 0.3) ! dimensionless ! ! Minimum oxygen concentration for oxic remineralization. ! At O2 less than this, anaerobic remineralization occurs at remin_min rate. ! call g_tracer_add_param('o2_min', bling%o2_min, 1.0e-06) ! mol O2 kg-1 ! ! Prevent oxygen from becoming negative. Setting to false allows negative ! oxygen in anoxic zones, which can be thought of as equivalent to ! denitrification plus H2S production. ! call g_tracer_add_param('prevent_neg_o2', bling%prevent_neg_o2, .true. ) ! CaCO3 remineralization length scale. From Station P calibration (Dunne). ! call g_tracer_add_param('ca_remin_depth', bling%ca_remin_depth, 1343. ) ! m ! Thickness of active sediment layer for CaCO3 dissolution calculation ! call g_tracer_add_param('z_sed', bling%z_sed, 0.1 ) ! m ! Global constant background (non-CaCO3) sedimentation flux, for CaCO3 ! burial calculation. Given as a flux in g cm-2 ky-1, but then converted ! to a 'mol lith m-2 a-1' flux, by dividing by 10, for consistency with ! the calculations (from TOPAZ). ! call g_tracer_add_param('sed_flux', bling%sed_flux, 0.14 * .1 ) ! mol m-2 a-1 !----------------------------------------------------------------------- ! Iron Cycling ! ! Global uniform iron ligand concentration. ! Taken from Parekh, P., M. J. Follows and E. A. Boyle (2005) Decoupling of iron ! and phosphate in the global ocean. Glob. Biogeochem. Cycles, 19, ! doi: 10.1029/2004GB002280. ! call g_tracer_add_param('felig_bkg', bling%felig_bkg, 1.0e-9) ! mol ligand kg-1 ! ! Ratio of iron efflux from bottom sediment boundaries to the sedimenting phosphorus flux. ! From Elrod et al. (2004), 0.68 mmol Fe mol C-1, after Moore et al (2008): ! call g_tracer_add_param('fe_2_p_sed', bling%fe_2_p_sed, 1.e-4 * 106.0 ) ! mol Fe mol P-1 ! ! 1.5-order iron scavenging in order to prevent high iron ! accumulations in high deposition regions (like the tropical ! Atlantic). This also helps prevent Fe accumulating in oligotrophic gyres and in ! the abyssal ocean, where organic fluxes are low. ! call g_tracer_add_param('kfe_inorg', bling%kfe_inorg, 1.e3/sperd) ! mol.5 Fe-.5 kg s-1 ! ! Equilibrium constant for (free and inorganically bound) iron binding with organic ! ligands taken from range similar to Parekh, P., M. J. Follows and E. A. Boyle ! (2005) Decoupling of iron and phosphate in the global ocean. Glob. Biogeochem. ! Cycles, 19, doi: 10.1029/2004GB002280. ! call g_tracer_add_param('kfe_eq_lig_max', bling%kfe_eq_lig_max, 8.e10) ! mol lig-1 kg ! ! Minimum ligand strength under high light, to represent photodissociation of ! ligand-Fe complexes. ! call g_tracer_add_param('kfe_eq_lig_min', bling%kfe_eq_lig_min, 0.8e10) ! mol lig-1 kg ! ! Photodecay irradiance scaling. ! call g_tracer_add_param('kfe_eq_lig_irr', bling%kfe_eq_lig_irr, 0.1) ! W m-2 ! ! Iron concentration near which photodecay is compensated by enhanced siderophore ! production. ! call g_tracer_add_param('kfe_eq_lig_femin', bling%kfe_eq_lig_femin, 0.05e-9) ! W m-2 ! ! Adsorption rate coefficient for detrital organic material. ! call g_tracer_add_param('kfe_org', bling%kfe_org, 0.5/sperd) ! g org-1 m3 s-1 ! !----------------------------------------------------------------------- ! Miscellaneous !----------------------------------------------------------------------- ! ! Debug flag to calculate global integrals for tracers ! call g_tracer_add_param('tracer_debug', bling%tracer_debug, .false.) ! call g_tracer_end_param_list(package_name) !=========== !Block Ends: g_tracer_add_param !=========== end subroutine user_add_params !####################################################################### ! ! This is an internal sub, not a public interface. ! Add all the tracers to be used in this module. ! subroutine user_add_tracers(tracer_list) type(g_tracer_type), pointer :: tracer_list character(len=fm_string_len), parameter :: sub_name = 'user_add_tracers' !Add here only the parameters that are required at the time of registeration !(to make flux exchanging Ocean tracers known for all PE's) ! call g_tracer_start_param_list(package_name) call g_tracer_add_param('ice_restart_file' , bling%ice_restart_file , 'ice_bling.res.nc') call g_tracer_add_param('ocean_restart_file' , bling%ocean_restart_file, 'ocean_bling.res.nc') call g_tracer_add_param('IC_file' , bling%IC_file , '') call g_tracer_end_param_list(package_name) ! Set Restart files call g_tracer_set_files(ice_restart_file = bling%ice_restart_file,& ocean_restart_file = bling%ocean_restart_file ) !All tracer fields shall be registered for diag output. !===================================================== !Specify all prognostic tracers of this modules. !===================================================== !User adds one call for each prognostic tracer below! !User should specify if fluxes must be extracted from boundary !by passing one or more of the following methods as .true. !and provide the corresponding parameters array !methods: flux_gas,flux_runoff,flux_wetdep,flux_drydep ! !Pass an init_value arg if the tracers should be initialized to a nonzero value everywhere !otherwise they will be initialized to zero. ! !=========================================================== !Prognostic Tracers !=========================================================== ! ! Dissolved Fe ! call g_tracer_add(tracer_list,package_name, & name = 'fed_b', & longname = 'Dissolved Iron', & units = 'mol/kg', & prog = .true., & flux_runoff = .false., & flux_wetdep = .true., & flux_drydep = .true., & flux_param = (/ 55.847e-03 /), & flux_bottom = .true. ) ! DOP (Dissolved organic phosphorus) ! call g_tracer_add(tracer_list,package_name, & name = 'dop_b', & longname = 'DOP', & units = 'mol/kg', & prog = .true.) ! ! O2 ! !NOTE: flux_gas_type = 'air_sea_gas_flux' is needed since the calculated alpha and csurf ! in this module include the Schmidt number. ! If you want to pass Schmidt number separately refer to the calculation in generic_TOPAZ.F90 ! which uses flux_gas_type = 'air_sea_gas_flux_generic' (which is default). ! call g_tracer_add(tracer_list,package_name, & name = 'o2_b', & longname = 'Oxygen', & units = 'mol/kg', & prog = .true., & flux_gas = .true., & flux_bottom = .true., & flux_gas_name = 'o2_b_flux', & flux_gas_type = 'air_sea_gas_flux', & flux_gas_molwt = WTMO2, & flux_gas_param = (/ 9.36e-07, 9.7561e-06 /), & flux_gas_restart_file = 'ocean_bling_airsea_flux.res.nc' ) ! ! PO4 ! call g_tracer_add(tracer_list,package_name,& name = 'po4_b', & longname = 'Phosphate', & units = 'mol/kg', & prog = .true., & flux_bottom = .true. ) if (do_po4_pre) then !<> !=========================================================== !Diagnostic Tracers !=========================================================== ! if (use_bling_chl) then ! Chl (Chlorophyll) ! call g_tracer_add(tracer_list,package_name,& name = 'chl', & longname = 'Chlorophyll', & units = 'ug kg-1', & prog = .false., & init_value = 0.08 ) else call g_tracer_add(tracer_list,package_name,& name = 'chl_b', & longname = 'Chlorophyll', & units = 'ug kg-1', & prog = .false., & init_value = 0.08 ) endif ! ! Biomass ! call g_tracer_add(tracer_list,package_name,& name = 'biomass_p', & longname = 'Biomass in P units', & units = 'mol P kg-1', & prog = .false.) ! Irr_mem (Irradiance Memory) ! call g_tracer_add(tracer_list,package_name,& name = 'irr_mem_b', & longname = 'Irradiance memory', & units = 'Watts/m^2', & prog = .false.) if (do_carbon) then !<> ! ! DIC (Dissolved inorganic carbon) ! call g_tracer_add(tracer_list,package_name, & name = 'dic_b', & longname = 'Dissolved Inorganic Carbon', & units = 'mol/kg', & prog = .true., & flux_gas = .true., & flux_gas_name = 'co2_b_flux', & flux_gas_type = 'air_sea_gas_flux', & flux_gas_molwt = WTMCO2, & flux_gas_param = (/ 9.36e-07, 9.7561e-06 /),& flux_gas_restart_file = 'ocean_bling_airsea_flux.res.nc', & flux_runoff = .false., & flux_param = (/12.011e-03 /), & flux_bottom = .true., & init_value = 0.001) ! !Diagnostic Tracers: ! ! CO3_ion (Carbonate ion) ! call g_tracer_add(tracer_list,package_name, & name = 'co3_ion_b', & longname = 'Carbonate ion', & units = 'mol/kg', & prog = .false. ) ! ! htotal (H+ ion concentration) ! call g_tracer_add(tracer_list,package_name, & name = 'htotal_b', & longname = 'H+ ion concentration', & units = 'mol/kg', & prog = .false., & init_value = bling%htotal_in) if (do_carbon_pre) then !<> if (do_14c) then !<> endif !CARBON CYCLE>> end subroutine user_add_tracers !####################################################################### ! ! ! Modify the values obtained from the coupler if necessary. ! ! ! Some tracer fields could be modified after values are obtained from the ! coupler. This subroutine is the place for specific tracer manipulations. ! BLING currently does not use this. ! ! ! ! Pointer to the head of generic tracer list. ! ! subroutine generic_BLING_update_from_coupler(tracer_list) type(g_tracer_type), pointer :: tracer_list character(len=fm_string_len), parameter :: sub_name = 'generic_BLING_update_from_coupler' end subroutine generic_BLING_update_from_coupler !####################################################################### ! ! ! Set values of bottom fluxes and reservoirs ! ! ! Some tracers could have bottom fluxes and reservoirs. ! This subroutine is the place for specific tracer manipulations. ! BLING currently does not use this. ! ! ! ! Pointer to the head of generic tracer list. ! ! ! Time step increment ! ! ! Time step index to be used for %field ! ! subroutine generic_BLING_update_from_bottom(tracer_list, dt, tau) type(g_tracer_type), pointer :: tracer_list real, intent(in) :: dt integer, intent(in) :: tau integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau real, dimension(:,:,:),pointer :: grid_tmask call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask) end subroutine generic_BLING_update_from_bottom !####################################################################### ! ! ! Update tracer concentration fields due to the source/sink contributions. ! ! ! This is the subroutine to contain most of the biogeochemistry for calculating the ! interaction of tracers with each other and with outside forcings. ! ! ! ! Pointer to the head of generic tracer list. ! ! ! Lower bounds of x and y extents of input arrays on data domain ! ! ! Ocean temperature ! ! ! Ocean salinity ! ! ! Ocean layer thickness (meters) ! ! ! Ocean opacity ! ! ! Shortwave peneteration ! ! ! ! ! ! Grid area ! ! ! Time step index of %field ! ! ! Time step increment ! ! subroutine generic_BLING_update_from_source(tracer_list,Temp,Salt,& rho_dzt,dzt,hblt_depth,ilb,jlb,tau,dt,grid_dat,model_time,nbands, & max_wavelength_band,sw_pen_band,opacity_band) type(g_tracer_type), pointer :: tracer_list real, dimension(ilb:,jlb:,:), intent(in) :: Temp,Salt,rho_dzt,dzt real, dimension(ilb:,jlb:), intent(in) :: hblt_depth integer, intent(in) :: ilb,jlb,tau real, intent(in) :: dt real, dimension(ilb:,jlb:), intent(in) :: grid_dat type(time_type), intent(in) :: model_time integer, intent(in) :: nbands real, dimension(:), intent(in) :: max_wavelength_band real, dimension(:,ilb:,jlb:), intent(in) :: sw_pen_band real, dimension(:,ilb:,jlb:,:), intent(in) :: opacity_band character(len=fm_string_len), parameter :: sub_name = 'generic_BLING_update_from_source' integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau, i, j, k , kblt,n real, dimension(:,:,:) ,pointer :: grid_tmask integer, dimension(:,:),pointer :: mask_coast,grid_kmt integer :: nb logical :: used real :: tmp_hblt, tmp_Irrad, tmp_irrad_ML, tmp_opacity real, dimension(:), Allocatable :: tmp_irr_band real :: s_over_p, fe_2_p real :: TK, PRESS, PKSPC !chd real :: cA0=2.00907, cA1=3.22014, cA2=4.05010, cA3=4.94457, cA4=-2.56847E-1 real :: cA5=3.88767, cB0=-6.24523E-3, cB1=-7.37614E-3, cB2=-1.03410E-2 real :: cB3=-8.17083E-3, cC0=-4.88682E-7 real :: TT, TS, TS2, TS3, TS4, TS5, CO, osa !echd call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,& grid_tmask=grid_tmask,grid_mask_coast=mask_coast,grid_kmt=grid_kmt) ! SURFACE GAS FLUXES ! ! This subroutine coordinates the calculation of gas concentrations and solubilities ! in the surface layer. The concentration of a gas is written as csurf, while the ! solubility (in mol kg-1 atm-1 or mol m-3 atm-1) is written as alpha. These two ! quantities are passed to the coupler, which multiplies their difference by the ! gas exchange piston velocity over the mixed layer depth to provide the gas ! exchange flux, ! Flux = Kw/dz * (alpha - csurf) ! In order to simplify code flow, the Schmidt number parameters, which are part of ! the piston velocity, are calculated here and applied to each of csurf and alpha ! before being sent to the coupler. ! ! For CO2 and 14CO2, the carbon solubility and speciation are calculated by the ! subroutine co2calc, following the OCMIP2 protocol. These calculations are both made ! using total CO2, following which the surface CO2 concentration (CO2*, also known as ! H2CO3*) is scaled by the DI14C/DIC ratio to give the surface 14CO2 concentration. ! The speciation calculation uses in situ temperature, salinity, ALK, PO4 and SiO4. ! ! Oxygen solubility is calculated here, using in situ temperature and salinity. !--------------------------------------------------------------------- ! Get positive tracer concentrations for carbon calculation !--------------------------------------------------------------------- call g_tracer_get_values(tracer_list,'po4_b' ,'field', bling%f_po4,isd,jsd,ntau=tau,positive=.true.) if (do_carbon) then !<> if (do_14c) then !<> endif !CARBON CYCLE>> !--------------------------------------------------------------------- ! Get positive concentrations for core tracers !--------------------------------------------------------------------- call g_tracer_get_values(tracer_list,'fed_b' ,'field',bling%f_fed ,isd,jsd,ntau=tau,positive=.true.) call g_tracer_get_values(tracer_list,'dop_b' ,'field',bling%f_dop ,isd,jsd,ntau=tau,positive=.true.) call g_tracer_get_values(tracer_list,'o2_b' ,'field',bling%f_o2 ,isd,jsd,ntau=tau,positive=.true.) call g_tracer_get_values(tracer_list,'biomass_p','field',bling%f_biomass_p ,isd,jsd,ntau=1) call g_tracer_get_values(tracer_list,'irr_mem_b','field',bling%f_irr_mem ,isd,jsd,ntau=1) if (do_po4_pre) & call g_tracer_get_values(tracer_list,'po4_pre' ,'field',bling%f_po4_pre ,isd,jsd,ntau=tau,positive=.true.) if (do_carbon) then call g_tracer_get_values(tracer_list,'co3_ion_b','field',bling%f_co3_ion ,isd,jsd,ntau=1,positive=.true.) if (bury_caco3) & call g_tracer_get_values(tracer_list,'cased_b' ,'field',bling%f_cased ,isd,jsd,ntau=1) endif bling%zt = 0.0 s_over_p = 0.0 !-------------------------------------------------------------------------- ! NUTRIENT UPTAKE !-------------------------------------------------------------------------- ! Available light calculation !----------------------------------------------------------------------- ! There are multiple types of light. ! irr_inst is the instantaneous irradiance field. ! irr_mix is the same, but with the irr_inst averaged throughout the ! mixed layer as defined in the KPP routine plus one more vertical box ! to account for mixing directly below the boundary layer. This quantity ! is intended to represent the light to which phytoplankton subject to ! turbulent transport in the mixed-layer would be exposed. ! irr_mem is a temporally smoothed field carried between timesteps, to ! represent photoadaptation. !----------------------------------------------------------------------- allocate(tmp_irr_band(nbands)) do j = jsc, jec ; do i = isc, iec !{ do nb=1,nbands !{ if (max_wavelength_band(nb) .lt. 710) then !{ tmp_irr_band(nb) = sw_pen_band(nb,i,j) else tmp_irr_band(nb) = 0.0 endif !} enddo !} kblt = 0 ; tmp_irrad_ML = 0.0 ; tmp_hblt = 0.0 do k = 1, nk !{ tmp_Irrad = 0.0 do nb=1,nbands !{ tmp_opacity = opacity_band(nb,i,j,k) tmp_Irrad = tmp_Irrad + tmp_irr_band(nb) * exp(-tmp_opacity * & dzt(i,j,k) * 0.5) ! Change tmp_irr_band from being the value atop layer k to the ! value at the bottom of layer k. tmp_irr_band(nb) = tmp_irr_band(nb) * exp(-tmp_opacity * & dzt(i,j,k)) enddo !} bling%irr_inst(i,j,k) = tmp_Irrad * grid_tmask(i,j,k) bling%irr_mix(i,j,k) = tmp_Irrad * grid_tmask(i,j,k) if ((k == 1) .or. (tmp_hblt .lt. hblt_depth(i,j))) then !{ kblt = kblt+1 tmp_irrad_ML = tmp_irrad_ML + bling%irr_mix(i,j,k) * dzt(i,j,k) tmp_hblt = tmp_hblt + dzt(i,j,k) endif !} enddo !} k-loop bling%irr_mix(i,j,1:kblt) = tmp_irrad_ML / max(1.0e-6,tmp_hblt) enddo; enddo !} i,j deallocate(tmp_irr_band) do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ !-------------------------------------------------------------------- ! Phytoplankton photoadaptation timescale bling%f_irr_mem(i,j,k) = (bling%f_irr_mem(i,j,k) + & (bling%irr_mix(i,j,k) - bling%f_irr_mem(i,j,k)) * min( 1.0 , & bling%gamma_irr_mem * dt)) * grid_tmask(i,j,k) !-------------------------------------------------------------------- ! Temperature functionality of growth and grazing ! NB The temperature effect of Eppley (1972) is used instead ! of that in Geider et al (1997) for both simplicity and ! to incorporate combined effects on uptake, incorporation ! into organic matter and photorespiration. Values of PCmax ! are normalized to 0C rather than 20C in Geider et al. (1997) bling%expkT(i,j,k) = exp(bling%kappa_eppley * Temp(i,j,k)) enddo; enddo ; enddo !} i,j,k !----------------------------------------------------------------------- ! Phytoplankton are assumed to grow according to the general properties ! described in Geider (1997). This formulation gives a biomass-specific ! growthrate as a function of light, nutrient limitation, and ! temperature. We modify this relationship slightly here, as described ! below, and also use the assumption of steady state growth vs. loss to ! derive a simple relationship between growth rate, biomass and uptake. ! !----------------------------------------------------------------------- ! First, we calculate the limitation terms for PO4 and Fe, and the ! Fe-limited Chl:C maximum. ! The light-saturated maximal photosynthesis rate term (pc_m) is simply ! the product of a prescribed maximal photosynthesis rate (pc_0), the ! Eppley temperature dependence, and a Liebig limitation (the minimum ! of Michaelis-Menton PO4-limitation, or iron-limitation). ! The iron limitation term has a lower limit of def_fe_min ! and is scaled by (k_fe_2_p + fe_2_p_max) / fe_2_p_max ! so that it approaches 1 as fed approaches infinity. Thus, ! it's of comparable magnitude to the PO4 limitation term. ! ! Fe limitation acts in two additional mechanisms: ! 1. By reducing the maximum achievable Chl:C ratio ! (theta) below a prescribed, Fe-replete maximum value (thetamax), to ! approach a prescribed minimum Chl:C (thetamin) under extreme ! Fe-limitation. ! 2. By reducing alpha (the initial slope of the P-I curve) under Fe- ! limitation. !----------------------------------------------------------------------- do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ bling%fe_2_p_uptake(i,j,k) = bling%fe_2_p_max * & bling%f_fed(i,j,k) / (bling%k_fe_uptake + bling%f_fed(i,j,k)) bling%def_fe(i,j,k) = bling%def_fe_min + & (1. - bling%def_fe_min) * bling%fe_2_p_uptake(i,j,k) / & (bling%k_fe_2_p + bling%fe_2_p_uptake(i,j,k)) * & (bling%k_fe_2_p + bling%fe_2_p_max) / bling%fe_2_p_max bling%pc_m(i,j,k) = bling%pc_0 * bling%expkT(i,j,k) * min( & bling%f_po4(i,j,k) / (bling%k_po4 + bling%f_po4(i,j,k)) , & bling%def_fe(i,j,k)) bling%thetamax_fe(i,j,k) = bling%thetamax_lo + & (bling%thetamax_hi - bling%thetamax_lo) * bling%def_fe(i,j,k) bling%alpha(i,j,k) = bling%alpha_min + & (bling%alpha_max - bling%alpha_min) * bling%def_fe(i,j,k) !----------------------------------------------------------------------- ! Next, the nutrient-limited efficiency of algal photosystems, Irrk, is ! calculated. This requires a prescribed quantum yield, alpha. ! The iron deficiency term is included here as a multiplier of the ! thetamax_fe to represent the importance of Fe in forming chlorophyll ! accessory antennae, which do not affect the Chl:C but still affect the ! phytoplankton ability to use light (eg Stzrepek & Harrison Nature ! 2004). bling%irrk(i,j,k) = (bling%pc_m(i,j,k) / ( epsln + & bling%alpha(i,j,k) * bling%thetamax_fe(i,j,k) )) + & bling%f_irr_mem(i,j,k) * 0.5 !----------------------------------------------------------------------- ! We also calculate the Chl:C ratio here, although it does not enter ! into the uptake calculation and is only used for the diagnostic ! chlorophyll concentration, below. bling%theta(i,j,k) = bling%thetamax_fe(i,j,k) / (1. + & bling%thetamax_fe(i,j,k) * bling%alpha(i,j,k) * & bling%f_irr_mem(i,j,k) / (epsln + 2. * bling%pc_m(i,j,k))) !----------------------------------------------------------------------- ! Now we can calculate the carbon-specific photosynthesis rate, pc_tot. bling%pc_tot(i,j,k) = bling%pc_m(i,j,k) * & (1. - exp(-bling%irr_mix(i,j,k) / (epsln + bling%irrk(i,j,k)))) !----------------------------------------------------------------------- ! Next, we account for the maintenance effort that phytoplankton must ! exert in order to combat decay. This is prescribed as a fraction of the ! light-saturated photosynthesis rate, resp_frac. The result of this is ! to set a level of energy availability below which net growth (and ! therefore nutrient uptake) is zero, given by resp_frac * pc_m. bling%mu(i,j,k) = max (0., & bling%pc_tot(i,j,k) - bling%resp_frac * bling%pc_m(i,j,k)) !----------------------------------------------------------------------- ! We now must convert this net carbon-specific growth rate to nutrient ! uptake rates, the quantities we are interested in. Since we have no ! explicit biomass tracer, we use the result of Dunne et al. (GBC, 2005) ! to calculate an implicit biomass from the uptake rate through the ! application of a simple idealized grazing law. This has the effect of ! reducing uptake in low growth-rate regimes and increasing uptake in ! high growth-rate regimes - essentially a non-linear amplification of ! the growth rate variability. The result is: bling%biomass_p_ts(i,j,k) = & ((bling%mu(i,j,k)/(bling%lambda0 * bling%expkT(i,j,k)))**3 & + (bling%mu(i,j,k)/(bling%lambda0 * bling%expkT(i,j,k)))) & * bling%p_star bling%f_biomass_p(i,j,k) = bling%f_biomass_p(i,j,k) + & (bling%biomass_p_ts(i,j,k) - bling%f_biomass_p(i,j,k)) * & min(1.0, bling%gamma_biomass * dt) * grid_tmask(i,j,k) bling%jp_uptake(i,j,k) = bling%f_biomass_p(i,j,k) * & bling%mu(i,j,k) ! We can now use the diagnostic biomass to calculate the chlorophyll ! concentration: bling%f_chl(i,j,k) = max(bling%chl_min, bling%f_biomass_p(i,j,k) & * bling%c_2_p * 12.011e6 * bling%theta(i,j,k)) * & grid_tmask(i,j,k) !----------------------------------------------------------------------- ! Iron is then taken up as a function of PO4 uptake and iron limitation, ! with a maximum Fe:P uptake ratio of fe2p_max: bling%jfe_uptake(i,j,k) = bling%jp_uptake(i,j,k) * & bling%fe_2_p_uptake(i,j,k) enddo; enddo ; enddo !} i,j,k !------------------------------------------------------------------------- ! PARTITIONING BETWEEN ORGANIC POOLS !------------------------------------------------------------------------- ! The uptake of nutrients is assumed to contribute to the growth of ! phytoplankton, which subsequently die and are consumed by heterotrophs. ! This can involve the transfer of nutrient elements between many ! organic pools, both particulate and dissolved, with complex histories. ! We take a simple approach here, partitioning the total uptake into two ! fractions - sinking and non-sinking - as a function of temperature, ! following Dunne et al. (2005). ! Then, the non-sinking fraction is further subdivided, such that the ! majority is recycled instantaneously to the inorganic nutrient pool, ! representing the fast turnover of labile dissolved organic matter via ! the microbial loop, and the remainder is converted to semi-labile ! dissolved organic matter. Iron and phosphorus are treated identically ! for the first step, but all iron is recycled instantaneously in the ! second step (i.e. there is no dissolved organic iron pool). !------------------------------------------------------------------------- do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ bling%frac_pop(i,j,k) = (bling%phi_sm + bling%phi_lg * & (bling%mu(i,j,k)/(bling%lambda0*bling%expkT(i,j,k)))**2.)/ & (1. + & (bling%mu(i,j,k)/(bling%lambda0*bling%expkT(i,j,k)))**2.)* & exp(bling%kappa_remin * Temp(i,j,k)) bling%jpop(i,j,k) = bling%frac_pop(i,j,k) * bling%jp_uptake(i,j,k) bling%jpofe(i,j,k) = bling%frac_pop(i,j,k)*bling%jfe_uptake(i,j,k) ! As a helpful diagnostic, the implied fraction of production by large ! phytoplankton is calculated, also following Dunne et al. 2005. This ! could be done more simply, but is done here in a complicated way as ! a sanity check. Looks fine. ! Note the calculation is made in P units, rather than C. ! This is also used for the CaCO3 production. s_over_p = ( -1. + ( 1. + 4. * bling%jp_uptake(i,j,k) / & (bling%expkT(i,j,k) * bling%lambda0 * bling%p_star))**0.5) * .5 bling%frac_lg(i,j,k) = s_over_p / (1 + s_over_p) !----------------------------------------------------------------------- ! Then the remainder is divided between instantaneously recycled and ! long-lived dissolved organic matter, bling%jdop(i,j,k) = bling%phi_dop * (bling%jp_uptake(i,j,k) - & bling%jpop(i,j,k)) bling%jp_recycle(i,j,k) = bling%jp_uptake(i,j,k) - & bling%jpop(i,j,k) - bling%jdop(i,j,k) bling%jfe_recycle(i,j,k) = bling%jfe_uptake(i,j,k) - & bling%jpofe(i,j,k) enddo; enddo ; enddo !} i,j,k if (do_carbon) then !<> endif !CARBON CYCLE>> !------------------------------------------------------------------------- ! SINKING AND REMINERALIZATION !------------------------------------------------------------------------- ! Calculate the depth of each grid cell (needs to be 3d for use with ! isopycnal co-ordinate model). do j = jsc, jec ; do i = isc, iec !{ bling%zt(i,j,1) = dzt(i,j,1) enddo; enddo !} i,j do k = 2, nk ; do j = jsc, jec ; do i = isc, iec !{ bling%zt(i,j,k) = bling%zt(i,j,k-1) + dzt(i,j,k) enddo; enddo ; enddo !} i,j,k !----------------------------------------------------------------------- ! Calculate the remineralization lengthscale matrix, zremin, a function ! of z. Sinking rate (wsink) is constant over the upper wsink0_z metres, ! then increases linearly with depth. ! The remineralization rate is a function of oxygen concentrations, ! following a Holling type 2 dependence, decreasing to a minimum value ! of remin_min. This is ad hoc, following work by Bianchi, Sarmiento, ! Galbraith and Kwon (unpublished). do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ if (bling%zt(i,j,k) .lt. bling%wsink0_z) then !{ bling%wsink(i,j,k) = bling%wsink0 else bling%wsink(i,j,k) = (bling%wsink_acc * (bling%zt(i,j,k) - & bling%wsink0_z) + bling%wsink0) endif !} bling%zremin(i,j,k) = bling%gamma_pop * (bling%f_o2(i,j,k)**2 / & (bling%k_o2**2 + bling%f_o2(i,j,k)**2) * (1. - bling%remin_min)+ & bling%remin_min) / (bling%wsink(i,j,k) + epsln) enddo; enddo ; enddo !} i,j,k if (do_carbon) then !< CO3solubility to zero at CO3 = 0. bling%zremin_caco3(i,j,k) = 1. / bling%ca_remin_depth * (1.0 - & min(1., bling%f_co3_ion(i,j,k) / (bling%co3_solubility(i,j,k) + & epsln))) enddo; enddo ; enddo !} i,j,k ! Generate CaCO3 sinking flux, and dissolve it through the water column. ! Same as for other elements - see below for more detailed explanation. do j = jsc, jec ; do i = isc, iec !{ bling%fcaco3(i,j,1) = bling%jca_uptake(i,j,1) * rho_dzt(i,j,1) / & (1.0 + dzt(i,j,1) * bling%zremin_caco3(i,j,1)) bling%jca_reminp(i,j,1) = & (bling%jca_uptake(i,j,1) * rho_dzt(i,j,1) - bling%fcaco3(i,j,1)) / & (epsln + rho_dzt(i,j,1)) enddo; enddo !} i,j do k = 2, nk ; do j = jsc, jec ; do i = isc, iec !{ bling%fcaco3(i,j,k) = (bling%fcaco3(i,j,k-1) + & bling%jca_uptake(i,j,k) * rho_dzt(i,j,k)) / & (1.0 + dzt(i,j,k) * bling%zremin_caco3(i,j,k)) bling%jca_reminp(i,j,k) = (bling%fcaco3(i,j,k-1) + & bling%jca_uptake(i,j,k) * rho_dzt(i,j,k) - bling%fcaco3(i,j,k)) / & (epsln + rho_dzt(i,j,k)) enddo; enddo ; enddo !} i,j,k if (do_14c) then !<> endif !CARBON CYCLE>> do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ !--------------------------------------------------------------------- ! Calculate free and inorganically associated iron concentration for ! scavenging. ! We assume that there is a ! spectrum of iron ligands present in seawater, with varying binding ! strengths and whose composition varies with light and iron ! concentrations. For example, photodissocation of ligand complexes ! occurs under bright light, weakening the binding strength ! (e.g. Barbeau et al., Nature 2001), while at very low iron ! concentrations (order kfe_eq_lig_femin), siderophores are thought ! to be produced as a response to extreme ! iron stress. ! In anoxic waters, iron should be reduced, and therefore mostly ! immune to scavenging. Easiest way to do this is to skip the feprime ! calculation if oxygen is less than 0. if (bling%f_o2(i,j,k) .gt. bling%o2_min) then !{ bling%kfe_eq_lig(i,j,k) = bling%kfe_eq_lig_max - & (bling%kfe_eq_lig_max - bling%kfe_eq_lig_min) * & (bling%irr_inst(i,j,k)**2. / (bling%irr_inst(i,j,k)**2. + & bling%kfe_eq_lig_irr **2.)) * max(0., min(1., (bling%f_fed(i,j,k) - & bling%kfe_eq_lig_femin) / (epsln + bling%f_fed(i,j,k)) * 1.2)) bling%feprime(i,j,k) = 1.0 + bling%kfe_eq_lig(i,j,k) * & (bling%felig_bkg - bling%f_fed(i,j,k)) bling%feprime(i,j,k) = (-bling%feprime(i,j,k) +(bling%feprime(i,j,k)* & bling%feprime(i,j,k) + 4.0 * bling%kfe_eq_lig(i,j,k) * & bling%f_fed(i,j,k))**(0.5)) /(2.0 * bling%kfe_eq_lig(i,j,k)) else bling%feprime(i,j,k) = 0. endif !} bling%jfe_ads_inorg(i,j,k) = min(0.5/dt, bling%kfe_inorg * & bling%feprime(i,j,k) ** 0.5) * bling%feprime(i,j,k) enddo; enddo ; enddo !} i,j,k !--------------------------------------------------------------------- ! In general, the flux at the bottom of a grid cell should equal ! Fb = (Ft + Prod*dz) / (1 + zremin*dz) ! where Ft is the flux at the top, and prod*dz is the integrated ! production of new sinking particles within the layer. ! Since Ft=0 in the first layer, do j = jsc, jec ; do i = isc, iec !{ bling%fpop(i,j,1) = bling%jpop(i,j,1) * rho_dzt(i,j,1) / & (1.0 + dzt(i,j,1) * bling%zremin(i,j,1)) !----------------------------------------------------------------------- ! Now, calculate the Fe adsorption using this fpop: ! The absolute first order rate constant is calculated from the ! concentration of organic particles, after Parekh et al. (2005). Never ! allowed to be greater than 1/2dt for numerical stability. bling%jfe_ads_org(i,j,1) = min (0.5/dt, & bling%kfe_org * (bling%fpop(i,j,1) / (epsln + bling%wsink(i,j,1)) * & bling%mass_2_p) ** 0.58) * bling%feprime(i,j,1) bling%fpofe(i,j,1) = (bling%jpofe(i,j,1) +bling%jfe_ads_inorg(i,j,1) & + bling%jfe_ads_org(i,j,1)) * rho_dzt(i,j,1) / & (1.0 + dzt(i,j,1) * bling%zremin(i,j,1)) !----------------------------------------------------------------------- ! Calculate remineralization terms bling%jp_reminp(i,j,1) = & (bling%jpop(i,j,1) * rho_dzt(i,j,1) - bling%fpop(i,j,1)) / & (epsln + rho_dzt(i,j,1)) bling%jfe_reminp(i,j,1) = & ((bling%jpofe(i,j,1) + bling%jfe_ads_org(i,j,1) + & bling%jfe_ads_inorg(i,j,1)) * rho_dzt(i,j,1) - & bling%fpofe(i,j,1)) / (epsln + rho_dzt(i,j,1)) enddo; enddo !} i,j !----------------------------------------------------------------------- ! Then, for the rest of water column, include Ft: do k = 2, nk ; do j = jsc, jec ; do i = isc, iec !{ bling%fpop(i,j,k) = (bling%fpop(i,j,k-1) + & bling%jpop(i,j,k) * rho_dzt(i,j,k)) / & (1.0 + dzt(i,j,k) * bling%zremin(i,j,k)) !----------------------------------------------------------------------- ! Again, calculate the Fe adsorption using this fpop: bling%jfe_ads_org(i,j,k) = min (0.5/dt, & bling%kfe_org * (bling%fpop(i,j,k) / (epsln + bling%wsink(i,j,k)) * & bling%mass_2_p) ** 0.58) * bling%feprime(i,j,k) bling%fpofe(i,j,k) = (bling%fpofe(i,j,k-1) + & (bling%jfe_ads_org(i,j,k) + bling%jfe_ads_inorg(i,j,k) + & bling%jpofe(i,j,k)) *rho_dzt(i,j,k)) / & (1.0 + dzt(i,j,k) * bling%zremin(i,j,k)) !--------------------------------------------------------------------- ! Calculate remineralization terms bling%jp_reminp(i,j,k) = (bling%fpop(i,j,k-1) + & bling%jpop(i,j,k) * rho_dzt(i,j,k) - bling%fpop(i,j,k)) / & (epsln + rho_dzt(i,j,k)) bling%jfe_reminp(i,j,k) = (bling%fpofe(i,j,k-1) + & (bling%jfe_ads_org(i,j,k) + bling%jfe_ads_inorg(i,j,k) + & bling%jpofe(i,j,k)) * rho_dzt(i,j,k) - & bling%fpofe(i,j,k)) / (epsln + rho_dzt(i,j,k)) enddo; enddo ; enddo !} i,j,k !--------------------------------------------------------------------- ! BOTTOM LAYER ! Account for remineralization in bottom box, and bottom fluxes do j = jsc, jec ; do i = isc, iec !{ k = grid_kmt(i,j) if (k .gt. 0) then !{ !--------------------------------------------------------------------- ! Calculate iron addition from sediments as a function of organic ! matter supply. bling%ffe_sed(i,j) = bling%fe_2_p_sed * bling%fpop(i,j,k) ! Added the burial flux of sinking particulate iron here as a ! diagnostic, needed to calculate mass balance of iron. bling%fe_burial(i,j) = bling%fpofe(i,j,k) !--------------------------------------------------------------------- ! Calculate external bottom fluxes for tracer_vertdiff. Positive fluxes ! are from the water column into the seafloor. For P, the bottom flux ! puts the sinking flux reaching the bottom cell into the water column ! through diffusion. For iron, the sinking flux disappears into the ! sediments if bottom waters are oxic (assumed adsorbed as oxides), ! while an efflux of dissolved iron occurs dependent on the supply of ! reducing organic matter (scaled by the org-P sedimentation rate). ! If bottom waters are anoxic, the sinking flux of Fe is returned to ! the water column. Note this is not appropriate for very long runs ! with an anoxic ocean (iron will keep accumulating forever). ! For oxygen, the consumption of oxidant required to respire ! the settling flux of organic matter (in support of the ! PO4 bottom flux) diffuses from the bottom water into the sediment. bling%b_po4(i,j) = - bling%fpop(i,j,k) if (bling%f_o2(i,j,k) .gt. bling%o2_min) then !{ bling%b_fed(i,j) = - bling%ffe_sed(i,j) else bling%b_fed(i,j) = - bling%ffe_sed(i,j) - bling%fpofe(i,j,k) endif !} bling%b_o2(i,j) = bling%o2_2_p * bling%fpop(i,j,k) endif !} enddo; enddo !} i, j call g_tracer_set_values(tracer_list,'fed_b', 'btf', bling%b_fed ,isd,jsd) call g_tracer_set_values(tracer_list,'po4_b', 'btf', bling%b_po4 ,isd,jsd) call g_tracer_set_values(tracer_list,'o2_b', 'btf', bling%b_o2 ,isd,jsd) if (do_carbon) then !<> endif !CARBON CYCLE>> !------------------------------------------------------------------------- ! CALCULATE SOURCE/SINK TERMS FOR EACH TRACER !------------------------------------------------------------------------- !Update the prognostics tracer fields via their pointers. call g_tracer_get_pointer(tracer_list,'fed_b' ,'field',bling%p_fed ) call g_tracer_get_pointer(tracer_list,'dop_b' ,'field',bling%p_dop ) call g_tracer_get_pointer(tracer_list,'o2_b' ,'field',bling%p_o2 ) call g_tracer_get_pointer(tracer_list,'po4_b' ,'field',bling%p_po4 ) if (do_po4_pre) & call g_tracer_get_pointer(tracer_list,'po4_pre','field',bling%p_po4_pre) if (do_carbon) then call g_tracer_get_pointer(tracer_list,'alk_b','field',bling%p_alk) call g_tracer_get_pointer(tracer_list,'dic_b','field',bling%p_dic) endif if (do_14c) then call g_tracer_get_pointer(tracer_list,'di14c','field',bling%p_di14c) call g_tracer_get_pointer(tracer_list,'do14c','field',bling%p_do14c) endif if (do_carbon_pre) then call g_tracer_get_pointer(tracer_list,'alk_pre','field',bling%p_alk_pre) call g_tracer_get_pointer(tracer_list,'dic_pre','field',bling%p_dic_pre) endif do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ ! ! PO4 ! Sum of fast recycling, decay of sinking POP, and decay of DOP, ! less uptake. ! bling%jpo4(i,j,k) = bling%jp_recycle(i,j,k) + & (1. - bling%phi_dop) * bling%jp_reminp(i,j,k) + & (bling%gamma_dop * bling%f_dop(i,j,k)) - bling%jp_uptake(i,j,k) bling%p_po4(i,j,k,tau) = bling%p_po4(i,j,k,tau) + & bling%jpo4(i,j,k) * dt * grid_tmask(i,j,k) ! ! Fed ! bling%p_fed(i,j,k,tau) = bling%p_fed(i,j,k,tau) + & (bling%jfe_recycle(i,j,k) + bling%jfe_reminp(i,j,k) - & bling%jfe_uptake(i,j,k) - bling%jfe_ads_org(i,j,k) - & bling%jfe_ads_inorg(i,j,k) ) * dt * grid_tmask(i,j,k) ! ! Dissolved Organic Phosphorus ! Add first-order decay and generation from sinking particles ! to jprod, initially produced in Uptake above. ! bling%jdop(i,j,k) = bling%jdop(i,j,k) + bling%phi_dop * & bling%jp_reminp(i,j,k) - bling%gamma_dop * bling%f_dop(i,j,k) bling%p_dop(i,j,k,tau) = bling%p_dop(i,j,k,tau)+bling%jdop(i,j,k) * & dt * grid_tmask(i,j,k) !----------------------------------------------------------------------- ! O2 ! Assuming constant P:O ratio. ! Optional prevention of negative oxygen (does not conserve ocean ! redox potential) or alternatively it can be allowed to go negative, ! keeping track of an implicit nitrate deficit ! plus sulfate reduction. !----------------------------------------------------------------------- if ( (bling%prevent_neg_o2) .and. & (bling%f_o2(i,j,k) .lt. bling%o2_min) ) then !{ bling%jo2(i,j,k) = 0. * grid_tmask(i,j,k) else bling%jo2(i,j,k) = - bling%o2_2_p * bling%jpo4(i,j,k) & * grid_tmask(i,j,k) endif !} bling%p_o2(i,j,k,tau) = bling%p_o2(i,j,k,tau) + bling%jo2(i,j,k) * & dt * grid_tmask(i,j,k) enddo; enddo ; enddo !} i,j,k !chd set to high value at the surface do j = jsc, jec ; do i = isc, iec !{ TT = 298.15-Temp(i,j,1); TK = 273.15+Temp(i,j,1); TS = log(TT/TK); TS2 = TS**2; TS3 = TS**3; TS4 = TS**4; TS5 = TS**5; CO = cA0 + cA1*TS + cA2*TS2 + cA3*TS3 + cA4*TS4 + cA5*TS5 & + Salt(i,j,1)*(cB0 + cB1*TS + cB2*TS2 + cB3*TS3) & + cC0*(Salt(i,j,1)*Salt(i,j,1)); osa = exp(CO); osa = osa/22391.6*1000.0*1000.0; !mmol/m^3 bling%p_o2(i,j,1,tau) = osa/1.e6 !mol/kg enddo; enddo ; !} i,j if (do_carbon) then !<> enddo; enddo ; enddo !} i,j,k endif !CARBON CYCLE>> ! ! PO4_pre ! Set equal to PO4 in surface layer only. if (do_po4_pre) then do j = jsc, jec ; do i = isc, iec !{ bling%p_po4_pre(i,j,1,tau) = bling%f_po4(i,j,1) enddo; enddo ; !} i,j endif ! ! DIC_pre and ALK_pre ! Set equal to DIC and ALK, respectively, in surface layer. if (do_carbon_pre) then do j = jsc, jec ; do i = isc, iec !{ bling%p_alk_pre(i,j,1,tau) = bling%f_alk(i,j,1) bling%p_dic_pre(i,j,1,tau) = bling%f_dic(i,j,1) enddo; enddo ; !} i,j endif ! !Set the diagnostics tracer fields. ! if (use_bling_chl) then call g_tracer_set_values(tracer_list,'chl', 'field',bling%f_chl ,isd,jsd,ntau=1) else call g_tracer_set_values(tracer_list,'chl_b', 'field',bling%f_chl ,isd,jsd,ntau=1) endif call g_tracer_set_values(tracer_list,'biomass_p', 'field',bling%f_biomass_p ,isd,jsd,ntau=1) call g_tracer_set_values(tracer_list,'irr_mem_b' , 'field',bling%f_irr_mem ,isd,jsd,ntau=1) if (bury_caco3) & call g_tracer_set_values(tracer_list,'cased_b', 'field',bling%f_cased ,isd,jsd,ntau=1) !----------------------------------------------------------------------- ! Save variables for diagnostics !----------------------------------------------------------------------- ! if (bling%id_alpha .gt. 0) & used = send_data(bling%id_alpha, bling%alpha, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_b_fed .gt. 0) & used = send_data(bling%id_b_fed, bling%b_fed, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_b_o2 .gt. 0) & used = send_data(bling%id_b_o2, bling%b_o2, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_b_po4 .gt. 0) & used = send_data(bling%id_b_po4, bling%b_po4, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_b_po4_n .gt. 0) & used = send_data(bling%id_b_po4_n, bling%b_po4_n, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_b_po4_nx .gt. 0) & used = send_data(bling%id_b_po4_nx, bling%b_po4_nx, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_b_po4_s .gt. 0) & used = send_data(bling%id_b_po4_s, bling%b_po4_s, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_b_po4_sx .gt. 0) & used = send_data(bling%id_b_po4_sx, bling%b_po4_sx, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_biomass_p_ts .gt. 0) & used = send_data(bling%id_biomass_p_ts, bling%biomass_p_ts, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_def_fe .gt. 0) & used = send_data(bling%id_def_fe, bling%def_fe, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_expkT .gt. 0) & used = send_data(bling%id_expkT, bling%expkT, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fe_2_p_uptake .gt. 0) & used = send_data(bling%id_fe_2_p_uptake, bling%fe_2_p_uptake, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_feprime .gt. 0) & used = send_data(bling%id_feprime, bling%feprime, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fe_burial .gt. 0) & used = send_data(bling%id_fe_burial, bling%fe_burial, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_ffe_sed .gt. 0) & used = send_data(bling%id_ffe_sed, bling%ffe_sed, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_fpofe .gt. 0) & used = send_data(bling%id_fpofe, bling%fpofe, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fpop .gt. 0) & used = send_data(bling%id_fpop, bling%fpop, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fpop_n .gt. 0) & used = send_data(bling%id_fpop_n, bling%fpop_n, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fpop_nx .gt. 0) & used = send_data(bling%id_fpop_nx, bling%fpop_nx, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fpop_s .gt. 0) & used = send_data(bling%id_fpop_s, bling%fpop_s, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fpop_sx .gt. 0) & used = send_data(bling%id_fpop_sx, bling%fpop_sx, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_frac_lg .gt. 0) & used = send_data(bling%id_frac_lg, bling%frac_lg, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_frac_pop .gt. 0) & used = send_data(bling%id_frac_pop, bling%frac_pop, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_irr_inst .gt. 0) & used = send_data(bling%id_irr_inst, bling%irr_inst, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_irr_mix .gt. 0) & used = send_data(bling%id_irr_mix, bling%irr_mix, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_irrk .gt. 0) & used = send_data(bling%id_irrk, bling%irrk, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jdop .gt. 0) & used = send_data(bling%id_jdop, bling%jdop*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jfe_ads_inorg .gt. 0) & used = send_data(bling%id_jfe_ads_inorg, bling%jfe_ads_inorg*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jfe_ads_org .gt. 0) & used = send_data(bling%id_jfe_ads_org, bling%jfe_ads_org*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jfe_recycle .gt. 0) & used = send_data(bling%id_jfe_recycle, bling%jfe_recycle*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jfe_reminp .gt. 0) & used = send_data(bling%id_jfe_reminp, bling%jfe_reminp*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jfe_uptake .gt. 0) & used = send_data(bling%id_jfe_uptake, bling%jfe_uptake*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jo2 .gt. 0) & used = send_data(bling%id_jo2, bling%jo2*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jp_recycle .gt. 0) & used = send_data(bling%id_jp_recycle, bling%jp_recycle*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jp_reminp .gt. 0) & used = send_data(bling%id_jp_reminp, bling%jp_reminp*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jpn_reminp .gt. 0) & used = send_data(bling%id_jpn_reminp, bling%jpn_reminp*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jpnx_reminp .gt. 0) & used = send_data(bling%id_jpnx_reminp, bling%jpnx_reminp*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jps_reminp .gt. 0) & used = send_data(bling%id_jps_reminp, bling%jps_reminp*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jpsx_reminp .gt. 0) & used = send_data(bling%id_jpsx_reminp, bling%jpsx_reminp*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jp_uptake .gt. 0) & used = send_data(bling%id_jp_uptake, bling%jp_uptake*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jpo4 .gt. 0) & used = send_data(bling%id_jpo4, bling%jpo4*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jpofe .gt. 0) & used = send_data(bling%id_jpofe, bling%jpofe*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jpop .gt. 0) & used = send_data(bling%id_jpop, bling%jpop*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_kfe_eq_lig .gt. 0) & used = send_data(bling%id_kfe_eq_lig, bling%kfe_eq_lig, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_pc_m .gt. 0) & used = send_data(bling%id_pc_m, bling%pc_m, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_mu .gt. 0) & used = send_data(bling%id_mu, bling%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 (bling%id_pc_tot .gt. 0) & used = send_data(bling%id_pc_tot, bling%pc_tot, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_theta .gt. 0) & used = send_data(bling%id_theta, bling%theta, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_thetamax_fe .gt. 0) & used = send_data(bling%id_thetamax_fe, bling%thetamax_fe, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_wsink .gt. 0) & used = send_data(bling%id_wsink, bling%wsink, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_zremin .gt. 0) & used = send_data(bling%id_zremin, bling%zremin, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_b_alk .gt. 0) & used = send_data(bling%id_b_alk, bling%b_alk, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_b_dic .gt. 0) & used = send_data(bling%id_b_dic, bling%b_dic, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_co2_csurf .gt. 0) & used = send_data(bling%id_co2_csurf, bling%co2_csurf, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_co2_alpha .gt. 0) & used = send_data(bling%id_co2_alpha, bling%co2_alpha, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_co3_solubility .gt. 0) & used = send_data(bling%id_co3_solubility, bling%co3_solubility, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fcaco3 .gt. 0) & used = send_data(bling%id_fcaco3, bling%fcaco3, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_fcaco3_to_sed .gt. 0) & used = send_data(bling%id_fcaco3_to_sed, bling%fcaco3_to_sed, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_fcased_burial .gt. 0) & used = send_data(bling%id_fcased_burial, bling%fcased_burial, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_fcased_redis .gt. 0) & used = send_data(bling%id_fcased_redis, bling%fcased_redis, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_jca_reminp .gt. 0) & used = send_data(bling%id_jca_reminp, bling%jca_reminp*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jca_uptake .gt. 0) & used = send_data(bling%id_jca_uptake, bling%jca_uptake*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_pco2_surf .gt. 0) & used = send_data(bling%id_pco2_surf, bling%pco2_surf, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_zremin_caco3 .gt. 0) & used = send_data(bling%id_zremin_caco3, bling%zremin_caco3, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_co2_sat_csurf .gt. 0) & used = send_data(bling%id_co2_sat_csurf, bling%co2_sat_csurf, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_pco2_sat_surf .gt. 0) & used = send_data(bling%id_pco2_sat_surf, bling%pco2_sat_surf, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_b_di14c .gt. 0) & used = send_data(bling%id_b_di14c, bling%b_di14c, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_c14_2_p .gt. 0) & used = send_data(bling%id_c14_2_p, bling%c14_2_p, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_c14o2_csurf .gt. 0) & used = send_data(bling%id_c14o2_csurf, bling%c14o2_csurf, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_c14o2_alpha .gt. 0) & used = send_data(bling%id_c14o2_alpha, bling%c14o2_alpha, & model_time, rmask = grid_tmask(:,:,1), & is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) if (bling%id_fpo14c .gt. 0) & used = send_data(bling%id_fpo14c, bling%fpo14c, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_j14c_decay_dic .gt. 0) & used = send_data(bling%id_j14c_decay_dic, bling%j14c_decay_dic*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_j14c_decay_doc .gt. 0) & used = send_data(bling%id_j14c_decay_doc, bling%j14c_decay_doc*rho_dzt, & model_time, rmask = grid_tmask,& is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_j14c_reminp .gt. 0) & used = send_data(bling%id_j14c_reminp, bling%j14c_reminp*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jdi14c .gt. 0) & used = send_data(bling%id_jdi14c, bling%jdi14c*rho_dzt, & model_time, rmask = grid_tmask,& is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) if (bling%id_jdo14c .gt. 0) & used = send_data(bling%id_jdo14c, bling%jdo14c*rho_dzt, & model_time, rmask = grid_tmask, & is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) end subroutine generic_BLING_update_from_source !####################################################################### ! ! ! Calculate and set coupler values at the surface / bottom ! ! ! ! ! ! ! Pointer to the head of generic tracer list. ! ! ! Lower bounds of x and y extents of input arrays on data domain ! ! ! Sea Surface Temperature ! ! ! Sea Surface Salinity ! ! ! Ocean density ! ! ! Time step index of %field ! ! !User must provide the calculations for these boundary values. subroutine generic_BLING_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau) type(g_tracer_type), pointer :: tracer_list real, dimension(ilb:,jlb:), intent(in) :: SST, SSS real, dimension(ilb:,jlb:,:,:), intent(in) :: rho integer, intent(in) :: ilb,jlb,tau integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau , i, j real :: sal,ST,sc_co2,sc_o2,sc_no_term,o2_saturation real :: tt,tk,ts,ts2,ts3,ts4,ts5 real, dimension(:,:,:) ,pointer :: grid_tmask real, dimension(:,:,:,:), pointer :: o2_field real, dimension(:,:), ALLOCATABLE :: co2_alpha,co2_csurf,o2_alpha,o2_csurf real, dimension(:,:), ALLOCATABLE :: co2_sat_alpha,co2_sat_csurf,c14o2_alpha,c14o2_csurf character(len=fm_string_len), parameter :: sub_name = 'generic_BLING_set_boundary_values' !Get the necessary properties call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask) call g_tracer_get_pointer(tracer_list,'o2_b' ,'field', o2_field) allocate( co2_alpha(isd:ied, jsd:jed)); co2_alpha=0.0 allocate( co2_csurf(isd:ied, jsd:jed)); co2_csurf=0.0 allocate(co2_sat_alpha(isd:ied, jsd:jed)); co2_sat_alpha=0.0 allocate(co2_sat_csurf(isd:ied, jsd:jed)); co2_sat_csurf=0.0 allocate( c14o2_alpha(isd:ied, jsd:jed)); c14o2_alpha=0.0 allocate( c14o2_csurf(isd:ied, jsd:jed)); c14o2_csurf=0.0 allocate( o2_alpha(isd:ied, jsd:jed)); o2_alpha=0.0 allocate( o2_csurf(isd:ied, jsd:jed)); o2_csurf=0.0 do j=jsc,jec ; do i=isc,iec !This calculation needs an input of SST and SSS sal = SSS(i,j) ; ST = SST(i,j) !nnz: !Note: In the following calculations in order to get results for o2 ! identical with bling code in MOM bling%Rho_0 must be replaced with rho(i,j,1,tau) ! This is achieved by uncommenting the following if desired. !! bling%Rho_0 = rho(i,j,1,tau) ! But since bling%Rho_0 plays the role of a unit conversion factor in this module ! it may be safer to keep it as a constant (1035.0) rather than the actual variable ! surface density rho(i,j,1,tau) !--------------------------------------------------------------------- ! O2 !--------------------------------------------------------------------- ! Compute the oxygen saturation concentration at 1 atm total ! pressure in mol/kg given the temperature (t, in deg C) and ! the salinity (s, in permil) ! ! From Garcia and Gordon (1992), Limnology and Oceonography. ! The formula used is from page 1310, eq (8). ! ! *** Note: the "a3*ts^2" term (in the paper) is incorrect. *** ! *** It shouldn't be there. *** ! ! o2_saturation is defined between T(freezing) <= T <= 40 deg C and ! 0 permil <= S <= 42 permil ! ! check value: T = 10 deg C, S = 35 permil, ! o2_saturation = 0.282015 mol m-3 !--------------------------------------------------------------------- ! tt = 298.15 - ST tk = 273.15 + ST ts = log(tt / tk) ts2 = ts * ts ts3 = ts2 * ts ts4 = ts3 * ts ts5 = ts4 * ts o2_saturation = (1000.0/22391.6) * grid_tmask(i,j,1) * & !convert from ml/l to mol m-3 exp( bling%a_0 + bling%a_1*ts + bling%a_2*ts2 + bling%a_3*ts3 + bling%a_4*ts4 + bling%a_5*ts5 + & (bling%b_0 + bling%b_1*ts + bling%b_2*ts2 + bling%b_3*ts3 + bling%c_0*sal)*sal) !--------------------------------------------------------------------- ! Compute the Schmidt number of O2 in seawater using the ! formulation proposed by Keeling et al. (1998, Global Biogeochem. ! Cycles, 12, 141-163). !--------------------------------------------------------------------- sc_o2 = bling%a1_o2 + ST * (bling%a2_o2 + ST * (bling%a3_o2 + ST * bling%a4_o2 )) * & grid_tmask(i,j,1) sc_no_term = sqrt(660.0 / (sc_o2 + epsln)) o2_alpha(i,j) = o2_saturation * sc_no_term !original code:o2_saturation * sc_no_term o2_csurf(i,j) = o2_field(i,j,1,tau) * sc_no_term * bling%Rho_0 !nnz: MOM has rho(i,j,1,tau) enddo; enddo ! !Set %csurf and %alpha for these tracers. This will mark them for sending fluxes to coupler ! call g_tracer_set_values(tracer_list,'o2_b', 'alpha',o2_alpha, isd,jsd) call g_tracer_set_values(tracer_list,'o2_b', 'csurf',o2_csurf, isd,jsd) !chd write (stdout(),*) o2_alpha(:,:) if (do_carbon) then !<> deallocate( & co2_alpha,co2_csurf, & co2_sat_alpha,co2_sat_csurf, & c14o2_alpha,c14o2_csurf, & o2_alpha,o2_csurf) end subroutine generic_BLING_set_boundary_values !####################################################################### ! ! ! End the module. ! ! ! Deallocate all work arrays ! ! ! subroutine generic_BLING_end character(len=fm_string_len), parameter :: sub_name = 'generic_BLING_end' call user_deallocate_arrays end subroutine generic_BLING_end !####################################################################### ! ! This is an internal sub, not a public interface. ! Allocate all the work arrays to be used in this module. ! subroutine user_allocate_arrays integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau, n call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau) allocate(bling%alpha(isd:ied, jsd:jed, 1:nk)); bling%alpha=0.0 allocate(bling%biomass_p_ts(isd:ied, jsd:jed, 1:nk)); bling%biomass_p_ts=0.0 allocate(bling%def_fe(isd:ied, jsd:jed, 1:nk)); bling%def_fe=0.0 allocate(bling%expkT(isd:ied, jsd:jed, 1:nk)); bling%expkT=0.0 allocate(bling%f_biomass_p(isd:ied, jsd:jed, 1:nk)); bling%f_biomass_p=0.0 allocate(bling%f_chl(isd:ied, jsd:jed, 1:nk)); bling%f_chl=0.0 allocate(bling%f_dop(isd:ied, jsd:jed, 1:nk)); bling%f_dop=0.0 allocate(bling%f_fed(isd:ied, jsd:jed, 1:nk)); bling%f_fed=0.0 allocate(bling%f_irr_mem(isd:ied, jsd:jed, 1:nk)); bling%f_irr_mem=0.0 allocate(bling%f_o2(isd:ied, jsd:jed, 1:nk)); bling%f_o2=0.0 allocate(bling%f_po4(isd:ied, jsd:jed, 1:nk)); bling%f_po4=0.0 allocate(bling%fe_2_p_uptake(isd:ied, jsd:jed, 1:nk)); bling%fe_2_p_uptake=0.0 allocate(bling%feprime(isd:ied, jsd:jed, 1:nk)); bling%feprime=0.0 allocate(bling%fpofe(isd:ied, jsd:jed, 1:nk)); bling%fpofe=0.0 allocate(bling%fpop(isd:ied, jsd:jed, 1:nk)); bling%fpop=0.0 allocate(bling%frac_lg(isd:ied, jsd:jed, 1:nk)); bling%frac_lg=0.0 allocate(bling%frac_pop(isd:ied, jsd:jed, 1:nk)); bling%frac_pop=0.0 allocate(bling%irr_inst(isd:ied, jsd:jed, 1:nk)); bling%irr_inst=0.0 allocate(bling%irr_mix(isd:ied, jsd:jed, 1:nk)); bling%irr_mix=0.0 allocate(bling%irrk(isd:ied, jsd:jed, 1:nk)); bling%irrk=0.0 allocate(bling%jdop(isd:ied, jsd:jed, 1:nk)); bling%jdop=0.0 allocate(bling%jfe_ads_org(isd:ied, jsd:jed, 1:nk)); bling%jfe_ads_org=0.0 allocate(bling%jfe_ads_inorg(isd:ied, jsd:jed, 1:nk)); bling%jfe_ads_inorg=0.0 allocate(bling%jfe_recycle(isd:ied, jsd:jed, 1:nk)); bling%jfe_recycle=0.0 allocate(bling%jfe_reminp(isd:ied, jsd:jed, 1:nk)); bling%jfe_reminp=0.0 allocate(bling%jfe_uptake(isd:ied, jsd:jed, 1:nk)); bling%jfe_uptake=0.0 allocate(bling%jo2(isd:ied, jsd:jed, 1:nk)); bling%jo2=0.0 allocate(bling%jp_recycle(isd:ied, jsd:jed, 1:nk)); bling%jp_recycle=0.0 allocate(bling%jp_reminp(isd:ied, jsd:jed, 1:nk)); bling%jp_reminp=0.0 allocate(bling%jp_uptake(isd:ied, jsd:jed, 1:nk)); bling%jp_uptake=0.0 allocate(bling%jpo4(isd:ied, jsd:jed, 1:nk)); bling%jpo4=0.0 allocate(bling%jpofe(isd:ied, jsd:jed, 1:nk)); bling%jpofe=0.0 allocate(bling%jpop(isd:ied, jsd:jed, 1:nk)); bling%jpop=0.0 allocate(bling%kfe_eq_lig(isd:ied, jsd:jed, 1:nk)); bling%kfe_eq_lig=0.0 allocate(bling%pc_m(isd:ied, jsd:jed, 1:nk)); bling%pc_m=0.0 allocate(bling%mu(isd:ied, jsd:jed, 1:nk)); bling%mu=0.0 allocate(bling%pc_tot(isd:ied, jsd:jed, 1:nk)); bling%pc_tot=0.0 allocate(bling%theta(isd:ied, jsd:jed, 1:nk)); bling%theta=0.0 allocate(bling%thetamax_fe(isd:ied, jsd:jed, 1:nk)); bling%thetamax_fe=0.0 allocate(bling%wsink(isd:ied, jsd:jed, 1:nk)); bling%wsink=0.0 allocate(bling%zremin(isd:ied, jsd:jed, 1:nk)); bling%zremin=0.0 allocate(bling%zt(isd:ied, jsd:jed, 1:nk)); bling%zt=0.0 allocate(bling%fe_burial (isd:ied, jsd:jed)); bling%fe_burial=0.0 allocate(bling%ffe_sed (isd:ied, jsd:jed)); bling%ffe_sed=0.0 allocate(bling%b_fed (isd:ied, jsd:jed)); bling%b_fed=0.0 allocate(bling%b_o2 (isd:ied, jsd:jed)); bling%b_o2=0.0 allocate(bling%b_po4 (isd:ied, jsd:jed)); bling%b_po4=0.0 if (do_po4_pre) then !<> if (do_carbon) then !<> if (do_carbon_pre) then !<> if (do_14c) then !<> endif !CARBON CYCLE>> end subroutine user_allocate_arrays !####################################################################### ! ! This is an internal sub, not a public interface. ! Deallocate all the work arrays allocated by user_allocate_arrays. ! subroutine user_deallocate_arrays deallocate(& bling%alpha,& bling%biomass_p_ts,& bling%def_fe,& bling%expkT,& bling%f_biomass_p,& bling%f_chl,& bling%f_dop,& bling%f_fed,& bling%f_irr_mem,& bling%f_o2,& bling%f_po4,& bling%fe_2_p_uptake,& bling%feprime,& bling%fpofe,& bling%fpop,& bling%frac_lg,& bling%frac_pop,& bling%irr_inst,& bling%irr_mix,& bling%irrk,& bling%jdop,& bling%jfe_ads_inorg,& bling%jfe_ads_org,& bling%jfe_recycle,& bling%jfe_reminp,& bling%jfe_uptake,& bling%jo2,& bling%jp_recycle,& bling%jp_reminp,& bling%jp_uptake,& bling%jpo4,& bling%jpofe,& bling%jpop,& bling%kfe_eq_lig,& bling%pc_m,& bling%mu,& bling%pc_tot,& bling%theta,& bling%thetamax_fe,& bling%wsink,& bling%zremin,& bling%zt,& bling%fe_burial,& bling%ffe_sed,& bling%b_fed,& bling%b_o2,& bling%b_po4 ) if (do_po4_pre) then !<> if (do_carbon) then !<> if (do_carbon_pre) then !<> if (do_14c) then !<> endif !CARBON CYCLE>> end subroutine user_deallocate_arrays end module generic_BLING