def bfm50_rate_eqns(time, conc, seasonal_cycle=True): """ Calculates the change in concentration for the 50 state variables NOTE: iron dynamics are not included, this is to compare to the standalone pelagic system """ #-------------------------------------------------------------------------- # import parameters from json file with open("bfm50_parameters.json", "r") as read_parameters: parameters = json.load(read_parameters) constant_parameters = parameters["constants"] environmental_parameters = parameters["environmental_parameters"] bacteria_parameters = parameters["bacteria_parameters"] phyto1_prameters = parameters["phyto1_parameters"] phyto2_prameters = parameters["phyto2_parameters"] phyto3_prameters = parameters["phyto3_parameters"] phyto4_prameters = parameters["phyto4_parameters"] mesozoo3_parameters = parameters["mesozoo3_parameters"] mesozoo4_parameters = parameters["mesozoo4_parameters"] microzoo5_parameters = parameters["microzoo5_parameters"] microzoo6_parameters = parameters["microzoo6_parameters"] zoo_availability_parameters = parameters["zoo_availability_parameters"] pel_chem_parameters = parameters["pel_chem_parameters"] co2_flux_parameters = parameters["co2_flux_parameters"] oxygen_reaeration_parameters = parameters["oxygen_reaeration_parameters"] #-------------------------------------------------------------------------- # Seasonal wind, temp, salinity, and radiation values if seasonal_cycle: t = time # Wind w_win = environmental_parameters["w_win"] # Winter wind speed w_sum = environmental_parameters["w_sum"] # Summer wind speed wind = get_wind(t, w_win, w_sum) # Yearly wind cylce # Temperature t_win = environmental_parameters["t_win"] # Winter temp value t_sum = environmental_parameters["t_sum"] # Summer temp value tde = environmental_parameters[ "tde"] # Sinusoidal temperature daily excursion degC temper = get_temperature(t, t_win, t_sum, tde) # Yearly temp cycle # Salinity s_win = environmental_parameters["s_win"] # Winter salinity value s_sum = environmental_parameters["s_sum"] # Summer salinity value salt = get_salinity(t, s_win, s_sum) # Yearly salinity cycle # Short wave irradiance flux (W/m^2) qs_win = environmental_parameters["qs_win"] # Winter irradiance value qs_sum = environmental_parameters["qs_sum"] # Summer irradiance value qs = get_sunlight(t, qs_win, qs_sum) # Yearly irradiance cycle else: wind = environmental_parameters["w_win"] temper = environmental_parameters["t_win"] salt = environmental_parameters["s_win"] qs = environmental_parameters["qs_win"] #-------------------------------------------------------------------------- # State variables o2o = conc[0] # Dissolved oxygen (mg O_2 m^-3) n1p = conc[1] # Phosphate (mmol P m^-3) n3n = conc[2] # Nitrate (mmol N m^-3) n4n = conc[3] # Ammonium (mmol N m^-3) o4n = conc[4] # Nitrogen sink (mmol N m^-3) n5s = conc[5] # Silicate (mmol Si m^-3) n6r = conc[6] # Reduction equivalents (mmol S m^-3) b1c = conc[7] # Pelagic bacteria carbon (mg C m^-3) b1n = conc[8] # Pelagic bacteria nitrogen (mmol N m^-3) b1p = conc[9] # Pelagic bacteria phosphate (mmol P m^-3) p1c = conc[10] # Diatoms carbon (mg C m^-3) p1n = conc[11] # Diatoms nitrogen (mmol N m^-3) p1p = conc[12] # Diatoms phosphate (mmol P m^-3) p1l = conc[13] # Diatoms chlorophyll (mg Chl-a m^-3) p1s = conc[14] # Diatoms silicate (mmol Si m^-3) p2c = conc[15] # NanoFlagellates carbon (mg C m^-3) p2n = conc[16] # NanoFlagellates nitrogen (mmol N m^-3) p2p = conc[17] # NanoFlagellates phosphate (mmol P m^-3) p2l = conc[18] # NanoFlagellates chlorophyll (mg Chl-a m^-3) p3c = conc[19] # Picophytoplankton carbon (mg C m^-3) p3n = conc[20] # Picophytoplankton nitrogen (mmol N m^-3) p3p = conc[21] # Picophytoplankton phosphate (mmol P m^-3) p3l = conc[22] # Picophytoplankton chlorophyll (mg Chl-a m^-3) p4c = conc[23] # Large phytoplankton carbon (mg C m^-3) p4n = conc[24] # Large phytoplankton nitrogen (mmol N m^-3) p4p = conc[25] # Large phytoplankton phosphate (mmol P m^-3) p4l = conc[26] # Large phytoplankton chlorophyll (mg Chl-a m^-3) z3c = conc[27] # Carnivorous mesozooplankton carbon (mg C m^-3) z3n = conc[28] # Carnivorous mesozooplankton nitrogen (mmol N m^-3) z3p = conc[29] # Carnivorous mesozooplankton phosphate (mmol P m^-3) z4c = conc[30] # Omnivorous mesozooplankton carbon (mg C m^-3) z4n = conc[31] # Omnivorous mesozooplankton nitrogen (mmol N m^-3) z4p = conc[32] # Omnivorous mesozooplankton phosphate (mmol P m^-3) z5c = conc[33] # Microzooplankton carbon (mg C m^-3) z5n = conc[34] # Microzooplankton nitrogen (mmol N m^-3) z5p = conc[35] # Microzooplankton phosphate (mmol P m^-3) z6c = conc[36] # Heterotrophic flagellates carbon (mg C m^-3) z6n = conc[37] # Heterotrophic flagellates nitrogen (mmol N m^-3) z6p = conc[38] # Heterotrophic flagellates phosphate (mmol P m^-3) r1c = conc[39] # Labile dissolved organic carbon (mg C m^-3) r1n = conc[40] # Labile dissolved organic nitrogen (mmol N m^-3) r1p = conc[41] # Labile dissolved organic phosphate (mmol P m^-3) r2c = conc[42] # Semi-labile dissolved organic carbon (mg C m^-3) r3c = conc[43] # Semi-refractory Dissolved Organic Carbon (mg C m^-3) r6c = conc[44] # Particulate organic carbon (mg C m^-3) r6n = conc[45] # Particulate organic nitrogen (mmol N m^-3) r6p = conc[46] # Particulate organic phosphate (mmol P m^-3) r6s = conc[47] # Particulate organic silicate (mmol Si m^-3) o3c = conc[48] # Dissolved inorganic carbon(mg C m^-3) o3h = conc[49] # Total alkalinity (mmol Eq m^-3) #-------------------------------------------------------------------------- # concentration ratios p1n_p1c = get_concentration_ratio(p1n, p1c, constant_parameters["p_small"]) p1p_p1c = get_concentration_ratio(p1p, p1c, constant_parameters["p_small"]) p1l_p1c = get_concentration_ratio(p1l, p1c, constant_parameters["p_small"]) p1s_p1c = get_concentration_ratio(p1s, p1c, constant_parameters["p_small"]) p2n_p2c = get_concentration_ratio(p2n, p2c, constant_parameters["p_small"]) p2p_p2c = get_concentration_ratio(p2p, p2c, constant_parameters["p_small"]) p2l_p2c = get_concentration_ratio(p2l, p2c, constant_parameters["p_small"]) p3n_p3c = get_concentration_ratio(p3n, p3c, constant_parameters["p_small"]) p3p_p3c = get_concentration_ratio(p3p, p3c, constant_parameters["p_small"]) p3l_p3c = get_concentration_ratio(p3l, p3c, constant_parameters["p_small"]) p4n_p4c = get_concentration_ratio(p4n, p4c, constant_parameters["p_small"]) p4p_p4c = get_concentration_ratio(p4p, p4c, constant_parameters["p_small"]) p4l_p4c = get_concentration_ratio(p4l, p4c, constant_parameters["p_small"]) bp_bc = get_concentration_ratio(b1p, b1c, constant_parameters["p_small"]) bn_bc = get_concentration_ratio(b1n, b1c, constant_parameters["p_small"]) z3n_z3c = get_concentration_ratio(z3n, z3c, constant_parameters["p_small"]) z3p_z3c = get_concentration_ratio(z3p, z3c, constant_parameters["p_small"]) z4n_z4c = get_concentration_ratio(z4n, z4c, constant_parameters["p_small"]) z4p_z4c = get_concentration_ratio(z4p, z4c, constant_parameters["p_small"]) z5n_z5c = get_concentration_ratio(z5n, z5c, constant_parameters["p_small"]) z5p_z5c = get_concentration_ratio(z5p, z5c, constant_parameters["p_small"]) z6n_z6c = get_concentration_ratio(z6n, z6c, constant_parameters["p_small"]) z6p_z6c = get_concentration_ratio(z6p, z6c, constant_parameters["p_small"]) r1p_r1c = get_concentration_ratio(r1p, r1c, constant_parameters["p_small"]) r6p_r6c = get_concentration_ratio(r6p, r6c, constant_parameters["p_small"]) r1n_r1c = get_concentration_ratio(r1n, r1c, constant_parameters["p_small"]) r6n_r6c = get_concentration_ratio(r6n, r6c, constant_parameters["p_small"]) #-------------------------------------------------------------------------- #---------------------- Phytoplankton Equations --------------------------- #-------------------------------------------------------------------------- # P1: Diatoms terms (dP1cdt_gpp_o3c, dP1cdt_rsp_o3c, dP1cdt_lys_r1c, dP1cdt_lys_r6c, dP1cdt_exu_r2c, dP1ndt_upt_n3n, dP1ndt_upt_n4n, extra_n1, dP1ndt_lys_r1n, dP1ndt_lys_r6n, dP1pdt_upt_n1p, dP1pdt_upt_r1p, dP1pdt_lys_r1p, dP1pdt_lys_r6p, dP1ldt_syn, dP1sdt_upt_n5s, dP1sdt_lys_r6s) = phyto_eqns( conc, phyto1_prameters, environmental_parameters, constant_parameters, 1, p1c, p1n, p1p, p1l, qs, temper, time) # P2: Flagellates terms (dP2cdt_gpp_o3c, dP2cdt_rsp_o3c, dP2cdt_lys_r1c, dP2cdt_lys_r6c, dP2cdt_exu_r2c, dP2ndt_upt_n3n, dP2ndt_upt_n4n, extra_n2, dP2ndt_lys_r1n, dP2ndt_lys_r6n, dP2pdt_upt_n1p, dP2pdt_upt_r1p, dP2pdt_lys_r1p, dP2pdt_lys_r6p, dP2ldt_syn, dP2sdt_upt_n5s, dP2sdt_lys_r6s) = phyto_eqns( conc, phyto2_prameters, environmental_parameters, constant_parameters, 2, p2c, p2n, p2p, p2l, qs, temper, time) # P3: PicoPhytoplankton terms (dP3cdt_gpp_o3c, dP3cdt_rsp_o3c, dP3cdt_lys_r1c, dP3cdt_lys_r6c, dP3cdt_exu_r2c, dP3ndt_upt_n3n, dP3ndt_upt_n4n, extra_n3, dP3ndt_lys_r1n, dP3ndt_lys_r6n, dP3pdt_upt_n1p, dP3pdt_upt_r1p, dP3pdt_lys_r1p, dP3pdt_lys_r6p, dP3ldt_syn, dP3sdt_upt_n5s, dP3sdt_lys_r6s) = phyto_eqns( conc, phyto3_prameters, environmental_parameters, constant_parameters, 3, p3c, p3n, p3p, p3l, qs, temper, time) # P4: Large Phytoplankton terms (dP4cdt_gpp_o3c, dP4cdt_rsp_o3c, dP4cdt_lys_r1c, dP4cdt_lys_r6c, dP4cdt_exu_r2c, dP4ndt_upt_n3n, dP4ndt_upt_n4n, extra_n4, dP4ndt_lys_r1n, dP4ndt_lys_r6n, dP4pdt_upt_n1p, dP4pdt_upt_r1p, dP4pdt_lys_r1p, dP4pdt_lys_r6p, dP4ldt_syn, dP4sdt_upt_n5s, dP4sdt_lys_r6s) = phyto_eqns( conc, phyto4_prameters, environmental_parameters, constant_parameters, 4, p4c, p4n, p4p, p4l, qs, temper, time) #-------------------------------------------------------------------------- #------------------------- Bacteria Equations ----------------------------- #-------------------------------------------------------------------------- (dBcdt_lys_r1c, dBcdt_lys_r1n, dBcdt_lys_r1p, dBcdt_lys_r6c, dBcdt_lys_r6n, dBcdt_lys_r6p, dBcdt_upt_r1c, dBcdt_upt_r6c, dBpdt_upt_rel_n1p, dBndt_upt_rel_n4n, dBcdt_upt_r2c, dBcdt_upt_r3c, dBcdt_rel_r2c, dBcdt_rel_r3c, dBcdt_rsp_o3c, flPTN6r, f_B_O, f_B_n, f_B_p) = bacteria_eqns(conc, bacteria_parameters, constant_parameters, environmental_parameters, temper) #-------------------------------------------------------------------------- #----------------------- Zooplankton Equations ---------------------------- #-------------------------------------------------------------------------- # Mesozooplankton predation terms dZ3cdt_prd, dZ4cdt_prd, ic3, in3, ip3, ic4, in4, ip4 = get_mesozoo_predation_terms( conc, mesozoo3_parameters, mesozoo4_parameters, zoo_availability_parameters, environmental_parameters, constant_parameters, temper) # Microzooplankton predation terms dZ5cdt_prd, dZ6cdt_prd, ic5, in5, ip5, ic6, in6, ip6 = get_microzoo_predation_terms( conc, microzoo5_parameters, microzoo6_parameters, zoo_availability_parameters, environmental_parameters, constant_parameters, temper) # Z3: Carnivorous Mesozooplankton terms (dZ3cdt_rel_r1c, dZ3cdt_rel_r6c, dZ3cdt_rsp_o3c, dZ3ndt_rel_r1n, dZ3ndt_rel_r6n, dZ3pdt_rel_r1p, dZ3pdt_rel_r6p, dZ3pdt_rel_n1p, dZ3ndt_rel_n4n) = mesozoo_eqns(conc, mesozoo3_parameters, constant_parameters, environmental_parameters, z3c, z3n, z3p, ic3, in3, ip3, temper) # Z4: Omnivorous Mesozooplankton terms (dZ4cdt_rel_r1c, dZ4cdt_rel_r6c, dZ4cdt_rsp_o3c, dZ4ndt_rel_r1n, dZ4ndt_rel_r6n, dZ4pdt_rel_r1p, dZ4pdt_rel_r6p, dZ4pdt_rel_n1p, dZ4ndt_rel_n4n) = mesozoo_eqns(conc, mesozoo4_parameters, constant_parameters, environmental_parameters, z4c, z4n, z4p, ic4, in4, ip4, temper) # Z5: Microzooplankton terms (dZ5cdt_rel_r1c, dZ5cdt_rel_r6c, dZ5cdt_rsp_o3c, dZ5ndt_rel_r1n, dZ5ndt_rel_r6n, dZ5pdt_rel_r1p, dZ5pdt_rel_r6p, dZ5pdt_rel_n1p, dZ5ndt_rel_n4n) = microzoo_eqns(conc, microzoo5_parameters, constant_parameters, environmental_parameters, z5c, z5n, z5p, ic5, in5, ip5, temper) # Z6: Heterotrophic Nanoflagellates terms (dZ6cdt_rel_r1c, dZ6cdt_rel_r6c, dZ6cdt_rsp_o3c, dZ6ndt_rel_r1n, dZ6ndt_rel_r6n, dZ6pdt_rel_r1p, dZ6pdt_rel_r6p, dZ6pdt_rel_n1p, dZ6ndt_rel_n4n) = microzoo_eqns(conc, microzoo6_parameters, constant_parameters, environmental_parameters, z6c, z6n, z6p, ic6, in6, ip6, temper) #-------------------------------------------------------------------------- #------------------------ Non-living components --------------------------- #-------------------------------------------------------------------------- (dn4ndt_nit_n3n, dn3ndt_denit, dn6rdt_reox, dr6sdt_rmn_n5s) = pel_chem_eqns(pel_chem_parameters, environmental_parameters, constant_parameters, temper, conc, flPTN6r) #---------------------- Oxygen airation by wind --------------------------- dOdt_wind = calculate_oxygen_reaeration(oxygen_reaeration_parameters, environmental_parameters, constant_parameters, conc, temper, salt, wind) #------------------------------- CO_2 Flux -------------------------------- do3cdt_air_sea_flux = calculate_co2_flux(co2_flux_parameters, environmental_parameters, constant_parameters, conc, temper, wind, salt) #-------------------------------------------------------------------------- #----------------------------- Rate Equations ----------------------------- #-------------------------------------------------------------------------- # Dissolved oxygen [mmol O_2 m^-3 s^-1] do2o_dt = ( constant_parameters["omega_c"] * ((dP1cdt_gpp_o3c - dP1cdt_rsp_o3c) + (dP2cdt_gpp_o3c - dP2cdt_rsp_o3c) + (dP3cdt_gpp_o3c - dP3cdt_rsp_o3c) + (dP4cdt_gpp_o3c - dP4cdt_rsp_o3c)) - constant_parameters["omega_c"] * f_B_O * dBcdt_rsp_o3c - constant_parameters["omega_c"] * (dZ3cdt_rsp_o3c + dZ4cdt_rsp_o3c + dZ5cdt_rsp_o3c + dZ6cdt_rsp_o3c) - constant_parameters["omega_n"] * dn4ndt_nit_n3n - (1.0 / constant_parameters["omega_r"]) * dn6rdt_reox) + dOdt_wind # Dissolved inorganic nutrient equations dn1p_dt = -(dP1pdt_upt_n1p + dP2pdt_upt_n1p + dP3pdt_upt_n1p + dP4pdt_upt_n1p) + (dBpdt_upt_rel_n1p * insw_vector(dBpdt_upt_rel_n1p)) - ( (-1) * f_B_p * dBpdt_upt_rel_n1p * insw_vector(-dBpdt_upt_rel_n1p)) + ( dZ3pdt_rel_n1p + dZ4pdt_rel_n1p + dZ5pdt_rel_n1p + dZ6pdt_rel_n1p) dn3n_dt = -(dP1ndt_upt_n3n + dP2ndt_upt_n3n + dP3ndt_upt_n3n + dP4ndt_upt_n3n) + dn4ndt_nit_n3n - dn3ndt_denit dn4n_dt = -(dP1ndt_upt_n4n + dP2ndt_upt_n4n + dP3ndt_upt_n4n + dP4ndt_upt_n4n) + ( dBndt_upt_rel_n4n * insw_vector(dBndt_upt_rel_n4n)) - ( (-1) * f_B_n * dBndt_upt_rel_n4n * insw_vector(-dBndt_upt_rel_n4n)) + ( dZ3ndt_rel_n4n + dZ4ndt_rel_n4n + dZ5ndt_rel_n4n + dZ6ndt_rel_n4n) - dn4ndt_nit_n3n do4n_dt = dn3ndt_denit dn5s_dt = -dP1sdt_upt_n5s + dr6sdt_rmn_n5s # Reduction equivalents dn6r_dt = constant_parameters["omega_r"] * constant_parameters[ "omega_c"] * (1.0 - f_B_O) * dBcdt_rsp_o3c - constant_parameters[ "omega_r"] * constant_parameters[ "omega_dn"] * dn3ndt_denit * insw_vector( -(o2o - n6r) / constant_parameters["omega_r"]) - dn6rdt_reox # Bacterioplankton db1c_dt = dBcdt_upt_r1c + dBcdt_upt_r6c - dBcdt_rsp_o3c - dBcdt_lys_r1c - dBcdt_lys_r6c - ( dZ5cdt_prd["b1"] + dZ6cdt_prd["b1"]) db1n_dt = -dBcdt_lys_r1n - dBcdt_lys_r6n + (r1n_r1c * dBcdt_upt_r1c) + ( r6n_r6c * dBcdt_upt_r6c ) - (dBndt_upt_rel_n4n * insw_vector(dBndt_upt_rel_n4n)) + ( (-1) * f_B_n * dBndt_upt_rel_n4n * insw_vector(-dBndt_upt_rel_n4n)) - ( bn_bc * (dZ5cdt_prd["b1"] + dZ6cdt_prd["b1"])) db1p_dt = (r1p_r1c * dBcdt_upt_r1c) + (r6p_r6c * dBcdt_upt_r6c) - ( dBpdt_upt_rel_n1p * insw_vector(dBpdt_upt_rel_n1p)) + ( (-1) * f_B_p * dBpdt_upt_rel_n1p * insw_vector(-dBpdt_upt_rel_n1p) ) - dBcdt_lys_r1p - dBcdt_lys_r6p - ( bp_bc * (dZ5cdt_prd["b1"] + dZ6cdt_prd["b1"])) # Phytoplankton dp1c_dt = dP1cdt_gpp_o3c - dP1cdt_exu_r2c - dP1cdt_rsp_o3c - dP1cdt_lys_r1c - dP1cdt_lys_r6c - dZ3cdt_prd[ "p1"] - dZ4cdt_prd["p1"] - dZ5cdt_prd["p1"] - dZ6cdt_prd["p1"] dp1n_dt = dP1ndt_upt_n3n + dP1ndt_upt_n4n - extra_n1 - dP1ndt_lys_r1n - dP1ndt_lys_r6n - ( p1n_p1c * (dZ3cdt_prd["p1"] + dZ4cdt_prd["p1"] + dZ5cdt_prd["p1"] + dZ6cdt_prd["p1"])) dp1p_dt = dP1pdt_upt_n1p - dP1pdt_upt_r1p - dP1pdt_lys_r1p - dP1pdt_lys_r6p - ( p1p_p1c * (dZ3cdt_prd["p1"] + dZ4cdt_prd["p1"] + dZ5cdt_prd["p1"] + dZ6cdt_prd["p1"])) dp1l_dt = dP1ldt_syn - (p1l_p1c * (dZ3cdt_prd["p1"] + dZ4cdt_prd["p1"] + dZ5cdt_prd["p1"] + dZ6cdt_prd["p1"])) dp1s_dt = dP1sdt_upt_n5s - dP1sdt_lys_r6s - ( p1s_p1c * (dZ3cdt_prd["p1"] + dZ4cdt_prd["p1"] + dZ5cdt_prd["p1"] + dZ6cdt_prd["p1"])) dp2c_dt = dP2cdt_gpp_o3c - dP2cdt_exu_r2c - dP2cdt_rsp_o3c - dP2cdt_lys_r1c - dP2cdt_lys_r6c - dZ3cdt_prd[ "p2"] - dZ4cdt_prd["p2"] - dZ5cdt_prd["p2"] - dZ6cdt_prd["p2"] dp2n_dt = dP2ndt_upt_n3n + dP2ndt_upt_n4n - extra_n2 - dP2ndt_lys_r1n - dP2ndt_lys_r6n - ( p2n_p2c * (dZ3cdt_prd["p2"] + dZ4cdt_prd["p2"] + dZ5cdt_prd["p2"] + dZ6cdt_prd["p2"])) dp2p_dt = dP2pdt_upt_n1p - dP2pdt_upt_r1p - dP2pdt_lys_r1p - dP2pdt_lys_r6p - ( p2p_p2c * (dZ3cdt_prd["p2"] + dZ4cdt_prd["p2"] + dZ5cdt_prd["p2"] + dZ6cdt_prd["p2"])) dp2l_dt = dP2ldt_syn - (p2l_p2c * (dZ3cdt_prd["p2"] + dZ4cdt_prd["p2"] + dZ5cdt_prd["p2"] + dZ6cdt_prd["p2"])) dp3c_dt = dP3cdt_gpp_o3c - dP3cdt_exu_r2c - dP3cdt_rsp_o3c - dP3cdt_lys_r1c - dP3cdt_lys_r6c - dZ3cdt_prd[ "p3"] - dZ4cdt_prd["p3"] - dZ5cdt_prd["p3"] - dZ6cdt_prd["p3"] dp3n_dt = dP3ndt_upt_n3n + dP3ndt_upt_n4n - extra_n3 - dP3ndt_lys_r1n - dP3ndt_lys_r6n - ( p3n_p3c * (dZ3cdt_prd["p3"] + dZ4cdt_prd["p3"] + dZ5cdt_prd["p3"] + dZ6cdt_prd["p3"])) dp3p_dt = dP3pdt_upt_n1p - dP3pdt_upt_r1p - dP3pdt_lys_r1p - dP3pdt_lys_r6p - ( p3p_p3c * (dZ3cdt_prd["p3"] + dZ4cdt_prd["p3"] + dZ5cdt_prd["p3"] + dZ6cdt_prd["p3"])) dp3l_dt = dP3ldt_syn - (p3l_p3c * (dZ3cdt_prd["p3"] + dZ4cdt_prd["p3"] + dZ5cdt_prd["p3"] + dZ6cdt_prd["p3"])) dp4c_dt = dP4cdt_gpp_o3c - dP4cdt_exu_r2c - dP4cdt_rsp_o3c - dP4cdt_lys_r1c - dP4cdt_lys_r6c - dZ3cdt_prd[ "p4"] - dZ4cdt_prd["p4"] - dZ5cdt_prd["p4"] - dZ6cdt_prd["p4"] dp4n_dt = dP4ndt_upt_n3n + dP4ndt_upt_n4n - extra_n4 - dP4ndt_lys_r1n - dP4ndt_lys_r6n - ( p4n_p4c * (dZ3cdt_prd["p4"] + dZ4cdt_prd["p4"] + dZ5cdt_prd["p4"] + dZ6cdt_prd["p4"])) dp4p_dt = dP4pdt_upt_n1p - dP4pdt_upt_r1p - dP4pdt_lys_r1p - dP4pdt_lys_r6p - ( p4p_p4c * (dZ3cdt_prd["p4"] + dZ4cdt_prd["p4"] + dZ5cdt_prd["p4"] + dZ6cdt_prd["p4"])) dp4l_dt = dP4ldt_syn - (p4l_p4c * (dZ3cdt_prd["p4"] + dZ4cdt_prd["p4"] + dZ5cdt_prd["p4"] + dZ6cdt_prd["p4"])) # mesozooplankton dz3c_dt = dZ3cdt_prd["p1"] + dZ3cdt_prd["p2"] + dZ3cdt_prd[ "p3"] + dZ3cdt_prd["p4"] + dZ3cdt_prd["z4"] + dZ3cdt_prd[ "z5"] + dZ3cdt_prd["z6"] - dZ4cdt_prd[ "z3"] - dZ3cdt_rel_r1c - dZ3cdt_rel_r6c - dZ3cdt_rsp_o3c dz3n_dt = p1n_p1c * dZ3cdt_prd["p1"] + p2n_p2c * dZ3cdt_prd[ "p2"] + p3n_p3c * dZ3cdt_prd["p3"] + p4n_p4c * dZ3cdt_prd[ "p4"] + z4n_z4c * dZ3cdt_prd["z4"] + z5n_z5c * dZ3cdt_prd[ "z5"] + z6n_z6c * dZ3cdt_prd["z6"] - z3n_z3c * dZ4cdt_prd[ "z3"] - dZ3ndt_rel_r1n - dZ3ndt_rel_r6n - dZ3ndt_rel_n4n dz3p_dt = p1p_p1c * dZ3cdt_prd["p1"] + p2p_p2c * dZ3cdt_prd[ "p2"] + p3p_p3c * dZ3cdt_prd["p3"] + p4p_p4c * dZ3cdt_prd[ "p4"] + z4p_z4c * dZ3cdt_prd["z4"] + z5p_z5c * dZ3cdt_prd[ "z5"] + z6p_z6c * dZ3cdt_prd["z6"] - z3p_z3c * dZ4cdt_prd[ "z3"] - dZ3pdt_rel_r1p - dZ3pdt_rel_r6p - dZ3pdt_rel_n1p dz4c_dt = dZ4cdt_prd["p1"] + dZ4cdt_prd["p2"] + dZ4cdt_prd[ "p3"] + dZ4cdt_prd["p4"] + dZ4cdt_prd["z3"] + dZ4cdt_prd[ "z5"] + dZ4cdt_prd["z6"] - dZ3cdt_prd[ "z4"] - dZ4cdt_rel_r1c - dZ4cdt_rel_r6c - dZ4cdt_rsp_o3c dz4n_dt = p1n_p1c * dZ4cdt_prd["p1"] + p2n_p2c * dZ4cdt_prd[ "p2"] + p3n_p3c * dZ4cdt_prd["p3"] + p4n_p4c * dZ4cdt_prd[ "p4"] + z3n_z3c * dZ4cdt_prd["z3"] + z5n_z5c * dZ4cdt_prd[ "z5"] + z6n_z6c * dZ4cdt_prd["z6"] - z4n_z4c * dZ3cdt_prd[ "z4"] - dZ4ndt_rel_r1n - dZ4ndt_rel_r6n - dZ4ndt_rel_n4n dz4p_dt = p1p_p1c * dZ4cdt_prd["p1"] + p2p_p2c * dZ4cdt_prd[ "p2"] + p3p_p3c * dZ4cdt_prd["p3"] + p4p_p4c * dZ4cdt_prd[ "p4"] + z3p_z3c * dZ4cdt_prd["z3"] + z5p_z5c * dZ4cdt_prd[ "z5"] + z6p_z6c * dZ4cdt_prd["z6"] - z4p_z4c * dZ3cdt_prd[ "z4"] - dZ4pdt_rel_r1p - dZ4pdt_rel_r6p - dZ4pdt_rel_n1p # microzooplankton dz5c_dt = dZ5cdt_prd["b1"] + dZ5cdt_prd["p1"] + dZ5cdt_prd[ "p2"] + dZ5cdt_prd["p3"] + dZ5cdt_prd["p4"] + dZ5cdt_prd[ "z6"] - dZ3cdt_prd["z5"] - dZ4cdt_prd["z5"] - dZ6cdt_prd[ "z5"] - dZ5cdt_rel_r1c - dZ5cdt_rel_r6c - dZ5cdt_rsp_o3c dz5n_dt = bn_bc * dZ5cdt_prd["b1"] + p1n_p1c * dZ5cdt_prd[ "p1"] + p2n_p2c * dZ5cdt_prd["p2"] + p3n_p3c * dZ5cdt_prd[ "p3"] + p4n_p4c * dZ5cdt_prd["p4"] + z6n_z6c * dZ5cdt_prd[ "z6"] - z5n_z5c * dZ3cdt_prd["z5"] - z5n_z5c * dZ4cdt_prd[ "z5"] - z5n_z5c * dZ6cdt_prd[ "z5"] - dZ5ndt_rel_r1n - dZ5ndt_rel_r6n - dZ5ndt_rel_n4n dz5p_dt = bp_bc * dZ5cdt_prd["b1"] + p1p_p1c * dZ5cdt_prd[ "p1"] + p2p_p2c * dZ5cdt_prd["p2"] + p3p_p3c * dZ5cdt_prd[ "p3"] + p4p_p4c * dZ5cdt_prd["p4"] + z6p_z6c * dZ5cdt_prd[ "z6"] - z5p_z5c * dZ3cdt_prd["z5"] - z5p_z5c * dZ4cdt_prd[ "z5"] - z5p_z5c * dZ6cdt_prd[ "z5"] - dZ5pdt_rel_r1p - dZ5pdt_rel_r6p - dZ5pdt_rel_n1p dz6c_dt = dZ6cdt_prd["b1"] + dZ6cdt_prd["p1"] + dZ6cdt_prd[ "p2"] + dZ6cdt_prd["p3"] + dZ6cdt_prd["p4"] + dZ6cdt_prd[ "z5"] - dZ3cdt_prd["z6"] - dZ4cdt_prd["z6"] - dZ5cdt_prd[ "z6"] - dZ6cdt_rel_r1c - dZ6cdt_rel_r6c - dZ6cdt_rsp_o3c dz6n_dt = bn_bc * dZ6cdt_prd["b1"] + p1n_p1c * dZ6cdt_prd[ "p1"] + p2n_p2c * dZ6cdt_prd["p2"] + p3n_p3c * dZ6cdt_prd[ "p3"] + p4n_p4c * dZ6cdt_prd["p4"] + z5n_z5c * dZ6cdt_prd[ "z5"] - z6n_z6c * dZ3cdt_prd["z6"] - z6n_z6c * dZ4cdt_prd[ "z6"] - z6n_z6c * dZ5cdt_prd[ "z6"] - dZ6ndt_rel_r1n - dZ6ndt_rel_r6n - dZ6ndt_rel_n4n dz6p_dt = bp_bc * dZ6cdt_prd["b1"] + p1p_p1c * dZ6cdt_prd[ "p1"] + p2p_p2c * dZ6cdt_prd["p2"] + p3p_p3c * dZ6cdt_prd[ "p3"] + p4p_p4c * dZ6cdt_prd["p4"] + z5p_z5c * dZ6cdt_prd[ "z5"] - z6p_z6c * dZ3cdt_prd["z6"] - z6p_z6c * dZ4cdt_prd[ "z6"] - z6p_z6c * dZ5cdt_prd[ "z6"] - dZ6pdt_rel_r1p - dZ6pdt_rel_r6p - dZ6pdt_rel_n1p # DOM dr1c_dt = (dP1cdt_lys_r1c + dP2cdt_lys_r1c + dP3cdt_lys_r1c + dP4cdt_lys_r1c) + dBcdt_lys_r1c - dBcdt_upt_r1c + ( dZ5cdt_rel_r1c + dZ6cdt_rel_r1c) dr1n_dt = (dP1ndt_lys_r1n + dP2ndt_lys_r1n + dP3ndt_lys_r1n + dP4ndt_lys_r1n) + ( extra_n1 + extra_n2 + extra_n3 + extra_n4) + dBcdt_lys_r1n - dBcdt_upt_r1c * r1n_r1c + ( dZ5ndt_rel_r1n + dZ6ndt_rel_r1n) dr1p_dt = ( dP1pdt_lys_r1p + dP2pdt_lys_r1p + dP3pdt_lys_r1p + dP4pdt_lys_r1p) + ( dP1pdt_upt_r1p + dP2pdt_upt_r1p + dP3pdt_upt_r1p + dP4pdt_upt_r1p) + dBcdt_lys_r1p - dBcdt_upt_r1c * r1p_r1c + ( dZ5pdt_rel_r1p + dZ6pdt_rel_r1p) dr2c_dt = (dP1cdt_exu_r2c + dP2cdt_exu_r2c + dP3cdt_exu_r2c + dP4cdt_exu_r2c) - dBcdt_upt_r2c + dBcdt_rel_r2c dr3c_dt = dBcdt_rel_r3c - dBcdt_upt_r3c # POM dr6c_dt = (dP1cdt_lys_r6c + dP2cdt_lys_r6c + dP3cdt_lys_r6c + dP4cdt_lys_r6c) + dBcdt_lys_r6c - dBcdt_upt_r6c + ( dZ3cdt_rel_r6c + dZ4cdt_rel_r6c + dZ5cdt_rel_r6c + dZ6cdt_rel_r6c) dr6n_dt = (dP1ndt_lys_r6n + dP2ndt_lys_r6n + dP3ndt_lys_r6n + dP4ndt_lys_r6n) + dBcdt_lys_r6n - dBcdt_upt_r6c * r6n_r6c + ( dZ3ndt_rel_r6n + dZ4ndt_rel_r6n + dZ5ndt_rel_r6n + dZ6ndt_rel_r6n) dr6p_dt = (dP1pdt_lys_r6p + dP2pdt_lys_r6p + dP3pdt_lys_r6p + dP4pdt_lys_r6p) + dBcdt_lys_r6p - dBcdt_upt_r6c * r6p_r6c + ( dZ3pdt_rel_r6p + dZ4pdt_rel_r6p + dZ5pdt_rel_r6p + dZ6pdt_rel_r6p) dr6s_dt = dP1sdt_lys_r6s - dr6sdt_rmn_n5s + ( p1s_p1c * (dZ3cdt_prd["p1"] + dZ4cdt_prd["p1"] + dZ5cdt_prd["p1"] + dZ6cdt_prd["p1"])) # Dissolved inorganic carbon do3c_dt = (-dP1cdt_gpp_o3c + dP1cdt_rsp_o3c) + ( -dP2cdt_gpp_o3c + dP2cdt_rsp_o3c ) + (-dP3cdt_gpp_o3c + dP3cdt_rsp_o3c) + ( -dP4cdt_gpp_o3c + dP4cdt_rsp_o3c ) + dBcdt_rsp_o3c + dZ3cdt_rsp_o3c + dZ4cdt_rsp_o3c + dZ5cdt_rsp_o3c + dZ6cdt_rsp_o3c + do3cdt_air_sea_flux # Total alkalinity (from Alkalinity.F90) if pel_chem_parameters["calc_alkalinity"] and o3c > 0.0: do3h_dt = -dn3n_dt + dn4n_dt else: do3h_dt = 0.0 return [ do2o_dt, dn1p_dt, dn3n_dt, dn4n_dt, do4n_dt, dn5s_dt, dn6r_dt, db1c_dt, db1n_dt, db1p_dt, dp1c_dt, dp1n_dt, dp1p_dt, dp1l_dt, dp1s_dt, dp2c_dt, dp2n_dt, dp2p_dt, dp2l_dt, dp3c_dt, dp3n_dt, dp3p_dt, dp3l_dt, dp4c_dt, dp4n_dt, dp4p_dt, dp4l_dt, dz3c_dt, dz3n_dt, dz3p_dt, dz4c_dt, dz4n_dt, dz4p_dt, dz5c_dt, dz5n_dt, dz5p_dt, dz6c_dt, dz6n_dt, dz6p_dt, dr1c_dt, dr1n_dt, dr1p_dt, dr2c_dt, dr3c_dt, dr6c_dt, dr6n_dt, dr6p_dt, dr6s_dt, do3c_dt, do3h_dt ]
def bacteria_eqns(conc, bacteria_parameters, constant_parameters, environmental_parameters, temper): """ Calculates the terms needed for the bacteria biological rate equations Equations come from the BFM user manual """ # State variables o2o = conc[0] # Dissolved oxygen (mg O_2 m^-3) n1p = conc[1] # Phosphate (mmol P m^-3) n4n = conc[3] # Ammonium (mmol N m^-3) b1c = conc[7] # Pelagic bacteria carbon (mg C m^-3) b1n = conc[8] # Pelagic bacteria nitrogen (mmol N m^-3) b1p = conc[9] # Pelagic bacteria phosphate (mmol P m^-3) r1c = conc[39] # Labile dissolved organic carbon (mg C m^-3) r1n = conc[40] # Labile dissolved organic nitrogen (mmol N m^-3) r1p = conc[41] # Labile dissolved organic phosphate (mmol P m^-3) r2c = conc[42] # Semi-labile dissolved organic carbon (mg C m^-3) r3c = conc[43] # Semi-refractory Dissolved Organic Carbon (mg C m^-3) r6c = conc[44] # Particulate organic carbon (mg C m^-3) r6n = conc[45] # Particulate organic nitrogen (mmol N m^-3) r6p = conc[46] # Particulate organic phosphate (mmol P m^-3) # concentration ratios bp_bc = get_concentration_ratio(b1p, b1c, constant_parameters["p_small"]) bn_bc = get_concentration_ratio(b1n, b1c, constant_parameters["p_small"]) r1p_r1c = get_concentration_ratio(r1p, r1c, constant_parameters["p_small"]) r6p_r6c = get_concentration_ratio(r6p, r6c, constant_parameters["p_small"]) r1n_r1c = get_concentration_ratio(r1n, r1c, constant_parameters["p_small"]) r6n_r6c = get_concentration_ratio(r6n, r6c, constant_parameters["p_small"]) # Temperature effect on pelagic bacteria fTB = eTq_vector(temper, environmental_parameters["basetemp"], environmental_parameters["q10b"]) # oxygen non-dimensional regulation factor[-] # Oxygen environment: bacteria are both aerobic and anaerobic f_B_O = max(constant_parameters["p_small"], o2o)**3 / (max(constant_parameters["p_small"], o2o)**3 + bacteria_parameters["h_B_O"]**3) # external nutrient limitation f_B_n = n4n / (n4n + bacteria_parameters["h_B_n"]) f_B_p = n1p / (n1p + bacteria_parameters["h_B_p"]) # Bacteria mortality (lysis) process [mg C m^-3 s^-1] dBcdt_lys = (bacteria_parameters["d_0B"] * fTB + bacteria_parameters["d_B_d"] * b1c) * b1c dBcdt_lys_r1c = dBcdt_lys * constant_parameters["epsilon_c"] dBcdt_lys_r1n = dBcdt_lys * bn_bc * constant_parameters["epsilon_n"] dBcdt_lys_r1p = dBcdt_lys * bp_bc * constant_parameters["epsilon_p"] dBcdt_lys_r6c = dBcdt_lys * (1.0 - constant_parameters["epsilon_c"]) dBcdt_lys_r6n = dBcdt_lys * bn_bc * (1.0 - constant_parameters["epsilon_n"]) dBcdt_lys_r6p = dBcdt_lys * bp_bc * (1.0 - constant_parameters["epsilon_p"]) # Substrate availability if bacteria_parameters["bact_version"] == 1 or bacteria_parameters[ "bact_version"] == 2: # nutrient limitation (intracellular) nut_lim_n = min(1.0, max(0.0, bn_bc / bacteria_parameters["n_B_opt"])) # Nitrogen nut_lim_p = min(1.0, max(0.0, bp_bc / bacteria_parameters["p_B_opt"])) # Phosphorus f_B_n_P = min(nut_lim_n, nut_lim_p) # Potential uptake by bacteria potential_upt = f_B_n_P * fTB * bacteria_parameters["r_0B"] * b1c # correction of substrate quality depending on nutrient content f_r1_n_P = min(1.0, r1p_r1c / bacteria_parameters["p_B_opt"], r1n_r1c / bacteria_parameters["n_B_opt"]) f_r6_n_P = min(1.0, r6p_r6c / bacteria_parameters["p_B_opt"], r6n_r6c / bacteria_parameters["n_B_opt"]) else: sys.exit( 'This code does not support this parameterization option, only bact_version=1' ) # Calculate the realized substrate uptake rate depending on the type of detritus and quality upt_R1c = (bacteria_parameters["v_B_r1"] * f_r1_n_P + bacteria_parameters["v_0B_r1"] * (1.0 - f_r1_n_P)) * r1c upt_R2c = bacteria_parameters["v_B_r2"] * r2c upt_R3c = bacteria_parameters["v_B_r3"] * r3c upt_R6c = bacteria_parameters["v_B_r6"] * f_r6_n_P * r6c realized_upt = constant_parameters[ "p_small"] + upt_R1c + upt_R2c + upt_R3c + upt_R6c # Actual uptake by bacteria actual_upt = min(potential_upt, realized_upt) # Carbon fluxes into bacteria dBcdt_upt_r1c = actual_upt * upt_R1c / realized_upt dBcdt_upt_r2c = actual_upt * upt_R2c / realized_upt dBcdt_upt_r3c = actual_upt * upt_R3c / realized_upt dBcdt_upt_r6c = actual_upt * upt_R6c / realized_upt # Organic Nitrogen and Phosphrous uptake dBcdt_upt_r1n = r1n_r1c * dBcdt_upt_r1c dBcdt_upt_r6n = r6n_r6c * dBcdt_upt_r6c dBcdt_upt_r1p = r1p_r1c * dBcdt_upt_r1c dBcdt_upt_r6p = r6p_r6c * dBcdt_upt_r6c # Bacteria respiration [mc C m^-3 s^-1] dBcdt_rsp_o3c = ( bacteria_parameters["gamma_B_a"] + bacteria_parameters["gamma_B_O"] * (1.0 - f_B_O)) * actual_upt + bacteria_parameters["b_B"] * b1c * fTB # Fluxes from bacteria if bacteria_parameters["bact_version"] == 1: # There is no Carbon excretion dBcdt_rel_r2c = 0.0 dBcdt_rel_r3c = 0.0 # Dissolved Nitrogen dynamics dBndt_upt_rel_n4n = (bn_bc - bacteria_parameters["n_B_opt"] ) * b1c * bacteria_parameters["v_B_n"] # Dissolved Phosphorus dynamics dBpdt_upt_rel_n1p = (bp_bc - bacteria_parameters["p_B_opt"] ) * b1c * bacteria_parameters["v_B_p"] # BACT2 parameterization if bacteria_parameters["bact_version"] == 2: print( 'This code does not support this parameterization option, only bact_version=1' ) # BACT3 parameterization if bacteria_parameters["bact_version"] == 3: print( 'This code does not support this parameterization option, only bact_version=1' ) # Term needed for denitrification flux (dn3ndt_denit) (from PelBac.F90 line 352) flPTN6r = (1.0 - f_B_O) * dBcdt_rsp_o3c * constant_parameters[ "omega_c"] * constant_parameters["omega_r"] return (dBcdt_lys_r1c, dBcdt_lys_r1n, dBcdt_lys_r1p, dBcdt_lys_r6c, dBcdt_lys_r6n, dBcdt_lys_r6p, dBcdt_upt_r1c, dBcdt_upt_r6c, dBpdt_upt_rel_n1p, dBndt_upt_rel_n4n, dBcdt_upt_r2c, dBcdt_upt_r3c, dBcdt_rel_r2c, dBcdt_rel_r3c, dBcdt_rsp_o3c, flPTN6r, f_B_O, f_B_n, f_B_p)
def microzoo_eqns(conc, microzoo_parameters, constant_parameters, environmental_parameters, zc, zn, zp, i_c, i_n, i_p, temp): """ Calculates the micorzooplankton (Z5 & Z6) terms needed for the zooplankton biological rate equations Equations come from the BFM user manual and the fortran code MicroZoo.F90 """ # Dissolved oxygen concentration (mg O_2 m^-3) o2o = conc[0] # Concentration ratios zn_zc = get_concentration_ratio(zn, zc, constant_parameters["p_small"]) zp_zc = get_concentration_ratio(zp, zc, constant_parameters["p_small"]) # Temperature regulating factor fTZ = eTq_vector(temp, environmental_parameters["basetemp"], environmental_parameters["q10z"]) # Oxygen dependent regulation factor fZO = min(1.0, (o2o / (o2o + microzoo_parameters["z_o2o"]))) #---------------------- Microzooplankton Respiration ---------------------- # Zooplankton total repiration rate (eqn. 2.4.8, and matches fortran code) rrac = i_c * (1.0 - microzoo_parameters["etaZ"] - microzoo_parameters["betaZ"]) rrsc = microzoo_parameters["bZ"] * fTZ * zc dZcdt_rsp_o3c = rrac + rrsc #------------- Microzooplankton mortality and activity excretion ---------- # From fortran code MesoZoo.F90 lines 327-331 rdc = ((1.0 - fZO) * microzoo_parameters["d_ZO"] + microzoo_parameters["d_Z"]) * zc reac = i_c * (1.0 - microzoo_parameters["etaZ"]) * microzoo_parameters["betaZ"] rric = reac + rdc dZcdt_rel_r1c = rric * constant_parameters["epsilon_c"] dZcdt_rel_r6c = rric * (1.0 - constant_parameters["epsilon_c"]) #------------------- Microzooplankton nutrient dynamics ------------------- # Organic Nitrogen dynamics (from fortran code) [mmol N m^-3 s^-1] rrin = i_n * microzoo_parameters["betaZ"] + rdc * zn_zc dZndt_rel_r1n = rrin * constant_parameters["epsilon_n"] dZndt_rel_r6n = rrin - dZndt_rel_r1n # Organic Phosphorus dynamics (from fortran code) [mmol P m^-3 s^-1] rrip = i_p * microzoo_parameters["betaZ"] + rdc * zp_zc dZpdt_rel_r1p = rrip * constant_parameters["epsilon_p"] dZpdt_rel_r6p = rrip - dZpdt_rel_r1p #--------------- Microzooplankton Dissolved nutrient dynamics ------------- # Equations from fortran code (MicroZoo.F90 line 368-371) runc = max(0.0, i_c * (1.0 - microzoo_parameters["betaZ"]) - rrac) runn = max(0.0, i_n * (1.0 - microzoo_parameters["betaZ"]) + rrsc * zn_zc) runp = max(0.0, i_p * (1.0 - microzoo_parameters["betaZ"]) + rrsc * zp_zc) dZpdt_rel_n1p = max( 0.0, runp / (constant_parameters["p_small"] + runc) - microzoo_parameters["p_Zopt"]) * runc dZndt_rel_n4n = max( 0.0, runn / (constant_parameters["p_small"] + runc) - microzoo_parameters["n_Zopt"]) * runc return dZcdt_rel_r1c, dZcdt_rel_r6c, dZcdt_rsp_o3c, dZndt_rel_r1n, dZndt_rel_r6n, dZpdt_rel_r1p, dZpdt_rel_r6p, dZpdt_rel_n1p, dZndt_rel_n4n
def mesozoo_eqns(conc, mesozoo_parameters, constant_parameters, environmental_parameters, zc, zn, zp, i_c, i_n, i_p, temp): """ Calculates the mesozooplankton (Z3 & Z4) terms needed for the zooplankton biological rate equations Equations come from the BFM user manual and the fortran code MesoZoo.F90 """ # Dissolved oxygen concentration (mg O_2 m^-3) o2o = conc[0] # Dissolved oxygen (mg O_2 m^-3) # Concentration ratios zn_zc = get_concentration_ratio(zn, zc, constant_parameters["p_small"]) zp_zc = get_concentration_ratio(zp, zc, constant_parameters["p_small"]) # Temperature regulating factor fTZ = eTq_vector(temp, environmental_parameters["basetemp"], environmental_parameters["q10z"]) # Oxygen dependent regulation factor fZO = (max(constant_parameters["p_small"], o2o)** 3) / (max(constant_parameters["p_small"], o2o)**3 + mesozoo_parameters["z_o2o"]**3) # energy cost of ingestion prI = 1.0 - mesozoo_parameters["etaZ"] - mesozoo_parameters["betaZ"] # Zooplankton total repiration rate (from 'MesoZoo.F90' line 343) dZcdt_rsp_o3c = prI * i_c + mesozoo_parameters["bZ"] * fTZ * zc # Specific rates of low oxygen mortality and Density dependent mortality # from fortran code MesoZoo.F90 lines 343-344 rdo_c = mesozoo_parameters["d_Zdns"] * (1.0 - fZO) * fTZ * zc rd_c = mesozoo_parameters["d_Z"] * zc**mesozoo_parameters["gammaZ"] # Total egestion including pellet production (from MesoZoo.F90 line 359 - 361) dZcdt_rel_r6c = mesozoo_parameters["betaZ"] * i_c + rdo_c + rd_c dZndt_rel_r6n = mesozoo_parameters["betaZ"] * i_n + zn_zc * (rdo_c + rd_c) dZpdt_rel_r6p = mesozoo_parameters["betaZ"] * i_p + zp_zc * (rdo_c + rd_c) # Check the assimilation rate for Carbon, Nitrogen and Phosphorus # compute P:C and N:C ratios in the assimilation rate # from MesoZoo.F90 lines 371-375 ru_c = mesozoo_parameters["etaZ"] * i_c ru_n = (mesozoo_parameters["etaZ"] + prI) * i_n ru_p = (mesozoo_parameters["etaZ"] + prI) * i_p pu_e_n = ru_n / (constant_parameters["p_small"] + ru_c) pu_e_p = ru_p / (constant_parameters["p_small"] + ru_c) # Eliminate the excess of the non-limiting constituent # Determine whether C, P or N is the limiting element and assign the value to variable limiting_nutrient # from MesoZoo.F90 lines limiting_nutrient = 'carbon' temp_p = pu_e_p / (zp_zc + constant_parameters["p_small"]) temp_n = pu_e_n / (zn_zc + constant_parameters["p_small"]) if temp_p < temp_n or abs(temp_p - temp_n) < constant_parameters["p_small"]: if pu_e_p < zp_zc: limiting_nutrient = 'phosphorus' else: if pu_e_n < zn_zc: limiting_nutrient = 'nitrogen' # Compute the correction terms depending on the limiting constituent if limiting_nutrient == 'carbon': q_Zc = 0.0 q_Zp = max(0.0, (1.0 - mesozoo_parameters["betaZ"]) * i_p - mesozoo_parameters["p_Zopt"] * ru_c) q_Zn = max(0.0, (1.0 - mesozoo_parameters["betaZ"]) * i_n - mesozoo_parameters["n_Zopt"] * ru_c) elif limiting_nutrient == 'phosphorus': q_Zp = 0.0 q_Zc = max( 0.0, ru_c - (1.0 - mesozoo_parameters["betaZ"]) * i_p / mesozoo_parameters["p_Zopt"]) q_Zn = max(0.0, (1.0 - mesozoo_parameters["betaZ"]) * i_n - mesozoo_parameters["n_Zopt"] * (ru_c - q_Zc)) elif limiting_nutrient == 'nitrogen': q_Zn = 0.0 q_Zc = max( 0.0, ru_c - (1.0 - mesozoo_parameters["betaZ"]) * i_n / mesozoo_parameters["n_Zopt"]) q_Zp = max(0.0, (1.0 - mesozoo_parameters["betaZ"]) * i_p - mesozoo_parameters["p_Zopt"] * (ru_c - q_Zc)) # Nutrient remineralization basal metabolism + excess of non-limiting nutrients dZpdt_rel_n1p = mesozoo_parameters["bZ"] * fZO * fTZ * zp + q_Zp dZndt_rel_n4n = mesozoo_parameters["bZ"] * fZO * fTZ * zn + q_Zn # Fluxes to particulate organic matter # Add the correction term for organic carbon release based on the limiting constituent dZcdt_rel_r6c += q_Zc # mesozooplankton are assumed to have no dissolved products dZcdt_rel_r1c = 0.0 dZndt_rel_r1n = 0.0 dZpdt_rel_r1p = 0.0 return dZcdt_rel_r1c, dZcdt_rel_r6c, dZcdt_rsp_o3c, dZndt_rel_r1n, dZndt_rel_r6n, dZpdt_rel_r1p, dZpdt_rel_r6p, dZpdt_rel_n1p, dZndt_rel_n4n
def get_mesozoo_predation_terms(conc, mesozoo3_parameters, mesozoo4_parameters, zoo_availability_parameters, environmental_parameters, constant_parameters, temp): """ Calculates the predation terms for mesozooplankton """ # Species concentrations p1c = conc[10] # Diatoms carbon (mg C m^-3) p1n = conc[11] # Diatoms nitrogen (mmol N m^-3) p1p = conc[12] # Diatoms phosphate (mmol P m^-3) p1l = conc[13] # Diatoms chlorophyll (mg Chl-a m^-3) p1s = conc[14] # Diatoms silicate (mmol Si m^-3) p2c = conc[15] # NanoFlagellates carbon (mg C m^-3) p2n = conc[16] # NanoFlagellates nitrogen (mmol N m^-3) p2p = conc[17] # NanoFlagellates phosphate (mmol P m^-3) p2l = conc[18] # NanoFlagellates chlorophyll (mg Chl-a m^-3) p3c = conc[19] # Picophytoplankton carbon (mg C m^-3) p3n = conc[20] # Picophytoplankton nitrogen (mmol N m^-3) p3p = conc[21] # Picophytoplankton phosphate (mmol P m^-3) p3l = conc[22] # Picophytoplankton chlorophyll (mg Chl-a m^-3) p4c = conc[23] # Large phytoplankton carbon (mg C m^-3) p4n = conc[24] # Large phytoplankton nitrogen (mmol N m^-3) p4p = conc[25] # Large phytoplankton phosphate (mmol P m^-3) p4l = conc[26] # Large phytoplankton chlorophyll (mg Chl-a m^-3) z3c = conc[27] # Carnivorous mesozooplankton carbon (mg C m^-3) z3n = conc[28] # Carnivorous mesozooplankton nitrogen (mmol N m^-3) z3p = conc[29] # Carnivorous mesozooplankton phosphate (mmol P m^-3) z4c = conc[30] # Omnivorous mesozooplankton carbon (mg C m^-3) z4n = conc[31] # Omnivorous mesozooplankton nitrogen (mmol N m^-3) z4p = conc[32] # Omnivorous mesozooplankton phosphate (mmol P m^-3) z5c = conc[33] # Microzooplankton carbon (mg C m^-3) z5n = conc[34] # Microzooplankton nitrogen (mmol N m^-3) z5p = conc[35] # Microzooplankton phosphate (mmol P m^-3) z6c = conc[36] # Heterotrophic flagellates carbon (mg C m^-3) z6n = conc[37] # Heterotrophic flagellates nitrogen (mmol N m^-3) z6p = conc[38] # Heterotrophic flagellates phosphate (mmol P m^-3) # concentration ratios conc_ratio_n = { "p1": get_concentration_ratio(p1n, p1c, constant_parameters["p_small"]), "p2": get_concentration_ratio(p2n, p2c, constant_parameters["p_small"]), "p3": get_concentration_ratio(p3n, p3c, constant_parameters["p_small"]), "p4": get_concentration_ratio(p4n, p4c, constant_parameters["p_small"]), "z3": get_concentration_ratio(z3n, z3c, constant_parameters["p_small"]), "z4": get_concentration_ratio(z4n, z4c, constant_parameters["p_small"]), "z5": get_concentration_ratio(z5n, z5c, constant_parameters["p_small"]), "z6": get_concentration_ratio(z6n, z6c, constant_parameters["p_small"]) } conc_ratio_p = { "p1": get_concentration_ratio(p1p, p1c, constant_parameters["p_small"]), "p2": get_concentration_ratio(p2p, p2c, constant_parameters["p_small"]), "p3": get_concentration_ratio(p3p, p3c, constant_parameters["p_small"]), "p4": get_concentration_ratio(p4p, p4c, constant_parameters["p_small"]), "z3": get_concentration_ratio(z3p, z3c, constant_parameters["p_small"]), "z4": get_concentration_ratio(z4p, z4c, constant_parameters["p_small"]), "z5": get_concentration_ratio(z5p, z5c, constant_parameters["p_small"]), "z6": get_concentration_ratio(z6p, z6c, constant_parameters["p_small"]) } # Zooplankton temperature regulating factor fTZ = eTq_vector(temp, environmental_parameters["basetemp"], environmental_parameters["q10z"]) # Calculate total potential food given the non-dim prey availability # There is no parameter for capture efficiency in mesozooplankton # From MesoZoo.F90 lines 247-259 # Phytoplankton LFG: Food availability of prey Phytoplankton for predator Z3 and Z4 available_phyto_c3 = (zoo_availability_parameters["del_z3p1"] * p1c) + ( zoo_availability_parameters["del_z3p2"] * p2c) + (zoo_availability_parameters["del_z3p3"] * p3c) + (zoo_availability_parameters["del_z3p4"] * p4c) available_phyto_c4 = (zoo_availability_parameters["del_z4p1"] * p1c) + ( zoo_availability_parameters["del_z4p2"] * p2c) + (zoo_availability_parameters["del_z4p3"] * p3c) + (zoo_availability_parameters["del_z4p4"] * p4c) # Mesozooplankton LFG available_mesozoo_c3 = (zoo_availability_parameters["del_z3z3"] * z3c) + ( zoo_availability_parameters["del_z3z4"] * z4c) available_mesozoo_c4 = (zoo_availability_parameters["del_z4z3"] * z3c) + ( zoo_availability_parameters["del_z4z4"] * z4c) # Microzooplankton LFG available_microzoo_c3 = (zoo_availability_parameters["del_z3z5"] * z5c) + ( zoo_availability_parameters["del_z3z6"] * z6c) available_microzoo_c4 = (zoo_availability_parameters["del_z4z5"] * z5c) + ( zoo_availability_parameters["del_z4z6"] * z6c) # sys.exit(available_microzoo_c4) # Total potential food (from Meso.F90 'rumc') f_c3 = available_phyto_c3 + available_mesozoo_c3 + available_microzoo_c3 f_c4 = available_phyto_c4 + available_mesozoo_c4 + available_microzoo_c4 # Calculate total food uptake rate (from Meso.F90 'rugc') total_uptake_rate_z3 = fTZ * mesozoo3_parameters["r_Z0"] * ( mesozoo3_parameters["nu_z"] * f_c3 / ((mesozoo3_parameters["nu_z"] * f_c3) + mesozoo3_parameters["r_Z0"])) * z3c total_uptake_rate_z4 = fTZ * mesozoo4_parameters["r_Z0"] * ( mesozoo4_parameters["nu_z"] * f_c4 / ((mesozoo4_parameters["nu_z"] * f_c4) + mesozoo4_parameters["r_Z0"])) * z4c # Calculate specific uptake rate considering potentially available food (from Meso.F90 'sut') specific_uptake_rate_z3 = total_uptake_rate_z3 / ( constant_parameters["p_small"] + f_c3) specific_uptake_rate_z4 = total_uptake_rate_z4 / ( constant_parameters["p_small"] + f_c4) # Total Gross Uptakes from every LFG dZ3cdt_prd = { "p1": specific_uptake_rate_z3 * zoo_availability_parameters["del_z3p1"] * p1c, "p2": specific_uptake_rate_z3 * zoo_availability_parameters["del_z3p2"] * p2c, "p3": specific_uptake_rate_z3 * zoo_availability_parameters["del_z3p3"] * p3c, "p4": specific_uptake_rate_z3 * zoo_availability_parameters["del_z3p4"] * p4c, "z3": specific_uptake_rate_z3 * zoo_availability_parameters["del_z3z3"] * z3c, "z4": specific_uptake_rate_z3 * zoo_availability_parameters["del_z3z4"] * z4c, "z5": specific_uptake_rate_z3 * zoo_availability_parameters["del_z3z5"] * z5c, "z6": specific_uptake_rate_z3 * zoo_availability_parameters["del_z3z6"] * z6c } dZ4cdt_prd = { "p1": specific_uptake_rate_z4 * zoo_availability_parameters["del_z4p1"] * p1c, "p2": specific_uptake_rate_z4 * zoo_availability_parameters["del_z4p2"] * p2c, "p3": specific_uptake_rate_z4 * zoo_availability_parameters["del_z4p3"] * p3c, "p4": specific_uptake_rate_z4 * zoo_availability_parameters["del_z4p4"] * p4c, "z3": specific_uptake_rate_z4 * zoo_availability_parameters["del_z4z3"] * z3c, "z4": specific_uptake_rate_z4 * zoo_availability_parameters["del_z4z4"] * z4c, "z5": specific_uptake_rate_z4 * zoo_availability_parameters["del_z4z5"] * z5c, "z6": specific_uptake_rate_z4 * zoo_availability_parameters["del_z4z6"] * z6c } # Total ingestion rate ic3 = 0.0 in3 = 0.0 ip3 = 0.0 for key in dZ3cdt_prd: ic3 += dZ3cdt_prd[key] in3 += dZ3cdt_prd[key] * conc_ratio_n[key] ip3 += dZ3cdt_prd[key] * conc_ratio_p[key] ic4 = 0.0 in4 = 0.0 ip4 = 0.0 for key in dZ4cdt_prd: ic4 += dZ4cdt_prd[key] in4 += dZ4cdt_prd[key] * conc_ratio_n[key] ip4 += dZ4cdt_prd[key] * conc_ratio_p[key] return dZ3cdt_prd, dZ4cdt_prd, ic3, in3, ip3, ic4, in4, ip4
def get_microzoo_predation_terms(conc, microzoo5_parameters, microzoo6_parameters, zoo_availability_parameters, environmental_parameters, constant_parameters, temp): """ Calculates the predation terms for microzooplankton """ # Species concentrations b1c = conc[7] # Pelagic bacteria carbon (mg C m^-3) b1n = conc[8] # Pelagic bacteria nitrogen (mmol N m^-3) b1p = conc[9] # Pelagic bacteria phosphate (mmol P m^-3) p1c = conc[10] # Diatoms carbon (mg C m^-3) p1n = conc[11] # Diatoms nitrogen (mmol N m^-3) p1p = conc[12] # Diatoms phosphate (mmol P m^-3) p1l = conc[13] # Diatoms chlorophyll (mg Chl-a m^-3) p1s = conc[14] # Diatoms silicate (mmol Si m^-3) p2c = conc[15] # NanoFlagellates carbon (mg C m^-3) p2n = conc[16] # NanoFlagellates nitrogen (mmol N m^-3) p2p = conc[17] # NanoFlagellates phosphate (mmol P m^-3) p2l = conc[18] # NanoFlagellates chlorophyll (mg Chl-a m^-3) p3c = conc[19] # Picophytoplankton carbon (mg C m^-3) p3n = conc[20] # Picophytoplankton nitrogen (mmol N m^-3) p3p = conc[21] # Picophytoplankton phosphate (mmol P m^-3) p3l = conc[22] # Picophytoplankton chlorophyll (mg Chl-a m^-3) p4c = conc[23] # Large phytoplankton carbon (mg C m^-3) p4n = conc[24] # Large phytoplankton nitrogen (mmol N m^-3) p4p = conc[25] # Large phytoplankton phosphate (mmol P m^-3) p4l = conc[26] # Large phytoplankton chlorophyll (mg Chl-a m^-3) z3c = conc[27] # Carnivorous mesozooplankton carbon (mg C m^-3) z3n = conc[28] # Carnivorous mesozooplankton nitrogen (mmol N m^-3) z3p = conc[29] # Carnivorous mesozooplankton phosphate (mmol P m^-3) z4c = conc[30] # Omnivorous mesozooplankton carbon (mg C m^-3) z4n = conc[31] # Omnivorous mesozooplankton nitrogen (mmol N m^-3) z4p = conc[32] # Omnivorous mesozooplankton phosphate (mmol P m^-3) z5c = conc[33] # Microzooplankton carbon (mg C m^-3) z5n = conc[34] # Microzooplankton nitrogen (mmol N m^-3) z5p = conc[35] # Microzooplankton phosphate (mmol P m^-3) z6c = conc[36] # Heterotrophic flagellates carbon (mg C m^-3) z6n = conc[37] # Heterotrophic flagellates nitrogen (mmol N m^-3) z6p = conc[38] # Heterotrophic flagellates phosphate (mmol P m^-3) # concentration ratios conc_ratio_n = { "b1": get_concentration_ratio(b1n, b1c, constant_parameters["p_small"]), "p1": get_concentration_ratio(p1n, p1c, constant_parameters["p_small"]), "p2": get_concentration_ratio(p2n, p2c, constant_parameters["p_small"]), "p3": get_concentration_ratio(p3n, p3c, constant_parameters["p_small"]), "p4": get_concentration_ratio(p4n, p4c, constant_parameters["p_small"]), "z5": get_concentration_ratio(z5n, z5c, constant_parameters["p_small"]), "z6": get_concentration_ratio(z6n, z6c, constant_parameters["p_small"]) } conc_ratio_p = { "b1": get_concentration_ratio(b1p, b1c, constant_parameters["p_small"]), "p1": get_concentration_ratio(p1p, p1c, constant_parameters["p_small"]), "p2": get_concentration_ratio(p2p, p2c, constant_parameters["p_small"]), "p3": get_concentration_ratio(p3p, p3c, constant_parameters["p_small"]), "p4": get_concentration_ratio(p4p, p4c, constant_parameters["p_small"]), "z5": get_concentration_ratio(z5p, z5c, constant_parameters["p_small"]), "z6": get_concentration_ratio(z6p, z6c, constant_parameters["p_small"]) } # Zooplankton temperature regulating factor fTZ = eTq_vector(temp, environmental_parameters["basetemp"], environmental_parameters["q10z"]) # Capture efficiencies capture_efficiencies_z5 = { "b1": b1c / (b1c + microzoo5_parameters["mu_z"]), "p1": p1c / (p1c + microzoo5_parameters["mu_z"]), "p2": p2c / (p2c + microzoo5_parameters["mu_z"]), "p3": p3c / (p3c + microzoo5_parameters["mu_z"]), "p4": p4c / (p4c + microzoo5_parameters["mu_z"]), "z5": z5c / (z5c + microzoo5_parameters["mu_z"]), "z6": z6c / (z6c + microzoo5_parameters["mu_z"]) } capture_efficiencies_z6 = { "b1": b1c / (b1c + microzoo6_parameters["mu_z"]), "p1": p1c / (p1c + microzoo6_parameters["mu_z"]), "p2": p2c / (p2c + microzoo6_parameters["mu_z"]), "p3": p3c / (p3c + microzoo6_parameters["mu_z"]), "p4": p4c / (p4c + microzoo6_parameters["mu_z"]), "z5": z5c / (z5c + microzoo6_parameters["mu_z"]), "z6": z6c / (z6c + microzoo6_parameters["mu_z"]) } # Calculate total potential food given the non-dim prey availability and capture efficiency # From MicroZoo.F90 lines 209-237 # Bacteria LFG: Food availability of prey Bacteria for predator Z5 and Z6 available_bact_c5 = zoo_availability_parameters[ "del_z5b1"] * b1c * capture_efficiencies_z5["b1"] available_bact_n5 = zoo_availability_parameters[ "del_z5b1"] * b1c * capture_efficiencies_z5["b1"] * conc_ratio_n["b1"] available_bact_p5 = zoo_availability_parameters[ "del_z5b1"] * b1c * capture_efficiencies_z5["b1"] * conc_ratio_p["b1"] available_bact_c6 = zoo_availability_parameters[ "del_z6b1"] * b1c * capture_efficiencies_z6["b1"] available_bact_n6 = zoo_availability_parameters[ "del_z6b1"] * b1c * capture_efficiencies_z6["b1"] * conc_ratio_n["b1"] available_bact_p6 = zoo_availability_parameters[ "del_z6b1"] * b1c * capture_efficiencies_z6["b1"] * conc_ratio_p["b1"] # Phytoplankton LFG: Food availability of prey Phytoplankton for predator Z5 and Z6 available_phyto_c5 = ((zoo_availability_parameters["del_z5p1"] * p1c * capture_efficiencies_z5["p1"]) + (zoo_availability_parameters["del_z3p2"] * p2c * capture_efficiencies_z5["p2"]) + (zoo_availability_parameters["del_z3p3"] * p3c * capture_efficiencies_z5["p3"]) + (zoo_availability_parameters["del_z3p4"] * p4c * capture_efficiencies_z5["p4"])) available_phyto_n5 = ( (zoo_availability_parameters["del_z5p1"] * p1c * capture_efficiencies_z5["p1"] * conc_ratio_n["p1"]) + (zoo_availability_parameters["del_z3p2"] * p2c * capture_efficiencies_z5["p2"] * conc_ratio_n["p2"]) + (zoo_availability_parameters["del_z3p3"] * p3c * capture_efficiencies_z5["p3"] * conc_ratio_n["p3"]) + (zoo_availability_parameters["del_z3p4"] * p4c * capture_efficiencies_z5["p4"] * conc_ratio_n["p4"])) available_phyto_p5 = ( (zoo_availability_parameters["del_z5p1"] * p1c * capture_efficiencies_z5["p1"] * conc_ratio_p["p1"]) + (zoo_availability_parameters["del_z3p2"] * p2c * capture_efficiencies_z5["p2"] * conc_ratio_p["p2"]) + (zoo_availability_parameters["del_z3p3"] * p3c * capture_efficiencies_z5["p3"] * conc_ratio_p["p3"]) + (zoo_availability_parameters["del_z3p4"] * p4c * capture_efficiencies_z5["p4"] * conc_ratio_p["p4"])) available_phyto_c6 = ((zoo_availability_parameters["del_z6p1"] * p1c * capture_efficiencies_z6["p1"]) + (zoo_availability_parameters["del_z6p2"] * p2c * capture_efficiencies_z6["p2"]) + (zoo_availability_parameters["del_z6p3"] * p3c * capture_efficiencies_z6["p3"]) + (zoo_availability_parameters["del_z6p4"] * p4c * capture_efficiencies_z6["p4"])) available_phyto_n6 = ( (zoo_availability_parameters["del_z6p1"] * p1c * capture_efficiencies_z6["p1"] * conc_ratio_n["p1"]) + (zoo_availability_parameters["del_z6p2"] * p2c * capture_efficiencies_z6["p2"] * conc_ratio_n["p2"]) + (zoo_availability_parameters["del_z6p3"] * p3c * capture_efficiencies_z6["p3"] * conc_ratio_n["p3"]) + (zoo_availability_parameters["del_z6p4"] * p4c * capture_efficiencies_z6["p4"] * conc_ratio_n["p4"])) available_phyto_p6 = ( (zoo_availability_parameters["del_z6p1"] * p1c * capture_efficiencies_z6["p1"] * conc_ratio_p["p1"]) + (zoo_availability_parameters["del_z6p2"] * p2c * capture_efficiencies_z6["p2"] * conc_ratio_p["p2"]) + (zoo_availability_parameters["del_z6p3"] * p3c * capture_efficiencies_z6["p3"] * conc_ratio_p["p3"]) + (zoo_availability_parameters["del_z6p4"] * p4c * capture_efficiencies_z6["p4"] * conc_ratio_p["p4"])) # Phytoplankton LFG: Food availability of prey Microzooplankton for predator Z5 and Z6 available_microzoo_c5 = (zoo_availability_parameters["del_z5z5"] * z5c * capture_efficiencies_z5["z5"]) + ( zoo_availability_parameters["del_z5z6"] * z6c * capture_efficiencies_z5["z6"]) available_microzoo_n5 = (zoo_availability_parameters["del_z5z5"] * z5c * capture_efficiencies_z5["z5"] * conc_ratio_n["z5"] ) + (zoo_availability_parameters["del_z5z6"] * z6c * capture_efficiencies_z5["z6"] * conc_ratio_n["z6"]) available_microzoo_p5 = (zoo_availability_parameters["del_z5z5"] * z5c * capture_efficiencies_z5["z5"] * conc_ratio_p["z5"] ) + (zoo_availability_parameters["del_z5z6"] * z6c * capture_efficiencies_z5["z6"] * conc_ratio_p["z6"]) available_microzoo_c6 = (zoo_availability_parameters["del_z6z5"] * z5c * capture_efficiencies_z6["z5"]) + ( zoo_availability_parameters["del_z6z6"] * z6c * capture_efficiencies_z6["z6"]) available_microzoo_n6 = ( zoo_availability_parameters["del_z6z5"] * z5c * capture_efficiencies_z6["z5"]**conc_ratio_n["z5"]) + ( zoo_availability_parameters["del_z6z6"] * z6c * capture_efficiencies_z6["z6"]**conc_ratio_n["z6"]) available_microzoo_p6 = ( zoo_availability_parameters["del_z6z5"] * z5c * capture_efficiencies_z6["z5"]**conc_ratio_p["z5"]) + ( zoo_availability_parameters["del_z6z6"] * z6c * capture_efficiencies_z6["z6"]**conc_ratio_p["z6"]) # Total potential food (from MicroZoo.F90 'rumc', 'rumn', 'rump') f_c5 = available_bact_c5 + available_phyto_c5 + available_microzoo_c5 f_n5 = available_bact_n5 + available_phyto_n5 + available_microzoo_n5 f_p5 = available_bact_p5 + available_phyto_p5 + available_microzoo_p5 f_c6 = available_bact_c6 + available_phyto_c6 + available_microzoo_c6 f_n6 = available_bact_n6 + available_phyto_n6 + available_microzoo_n6 f_p6 = available_bact_p6 + available_phyto_p6 + available_microzoo_p6 # Calculate total food uptake rate (from MicroZoo.F90 line 243 'rugc') total_uptake_rate_z5 = fTZ * microzoo5_parameters["r_Z0"] * ( f_c5 / (f_c5 + microzoo5_parameters["h_Z_F"])) * z5c total_uptake_rate_z6 = fTZ * microzoo6_parameters["r_Z0"] * ( f_c6 / (f_c6 + microzoo6_parameters["h_Z_F"])) * z6c # Calculate specific uptake rate considering potentially available food (from MicroZoo.F90 line 244 'sut') specific_uptake_rate_z5 = total_uptake_rate_z5 / ( f_c5 + constant_parameters["p_small"]) specific_uptake_rate_z6 = total_uptake_rate_z6 / ( f_c6 + constant_parameters["p_small"]) # Total Gross Uptakes from every LFG dZ5cdt_prd = { "b1": specific_uptake_rate_z5 * zoo_availability_parameters["del_z5b1"] * b1c * capture_efficiencies_z5["b1"], "p1": specific_uptake_rate_z5 * zoo_availability_parameters["del_z5p1"] * p1c * capture_efficiencies_z5["p1"], "p2": specific_uptake_rate_z5 * zoo_availability_parameters["del_z5p2"] * p2c * capture_efficiencies_z5["p2"], "p3": specific_uptake_rate_z5 * zoo_availability_parameters["del_z5p3"] * p3c * capture_efficiencies_z5["p3"], "p4": specific_uptake_rate_z5 * zoo_availability_parameters["del_z5p4"] * p4c * capture_efficiencies_z5["p4"], "z5": specific_uptake_rate_z5 * zoo_availability_parameters["del_z5z5"] * z5c * capture_efficiencies_z5["z5"], "z6": specific_uptake_rate_z5 * zoo_availability_parameters["del_z5z6"] * z6c * capture_efficiencies_z5["z6"] } dZ6cdt_prd = { "b1": specific_uptake_rate_z6 * zoo_availability_parameters["del_z6b1"] * b1c * capture_efficiencies_z6["b1"], "p1": specific_uptake_rate_z6 * zoo_availability_parameters["del_z6p1"] * p1c * capture_efficiencies_z6["p1"], "p2": specific_uptake_rate_z6 * zoo_availability_parameters["del_z6p2"] * p2c * capture_efficiencies_z6["p2"], "p3": specific_uptake_rate_z6 * zoo_availability_parameters["del_z6p3"] * p3c * capture_efficiencies_z6["p3"], "p4": specific_uptake_rate_z6 * zoo_availability_parameters["del_z6p4"] * p4c * capture_efficiencies_z6["p4"], "z5": specific_uptake_rate_z6 * zoo_availability_parameters["del_z6z5"] * z5c * capture_efficiencies_z6["z5"], "z6": specific_uptake_rate_z6 * zoo_availability_parameters["del_z6z6"] * z6c * capture_efficiencies_z6["z6"] } # Total ingestion rate ic5 = 0.0 in5 = 0.0 ip5 = 0.0 for key in dZ5cdt_prd: ic5 += dZ5cdt_prd[key] in5 += dZ5cdt_prd[key] * conc_ratio_n[key] ip5 += dZ5cdt_prd[key] * conc_ratio_p[key] ic6 = 0.0 in6 = 0.0 ip6 = 0.0 for key in dZ6cdt_prd: ic6 += dZ6cdt_prd[key] in6 += dZ6cdt_prd[key] * conc_ratio_n[key] ip6 += dZ6cdt_prd[key] * conc_ratio_p[key] return dZ5cdt_prd, dZ6cdt_prd, ic5, in5, ip5, ic6, in6, ip6
def phyto_eqns(conc, phyto_parameters, env_parameters, constant_parameters, group, pc, pn, pp, pl, qs, temp, time): """ Calculates the terms needed for the phytoplnaktion biological rate equations Equations come from the BFM user manual """ # Species concentrations n1p = conc[1] # Phosphate (mmol P m^-3) n3n = conc[2] # Nitrate (mmol N m^-3) n4n = conc[3] # Ammonium (mmol N m^-3) n5s = conc[5] # Silicate (mmol Si m^-3) p1l = conc[13] # Diatoms chlorophyll (mg Chl-a m^-3) p1s = conc[14] # Diatoms silicate (mmol Si m^-3) p2l = conc[18] # NanoFlagellates chlorophyll (mg Chl-a m^-3) p3l = conc[22] # Picophytoplankton chlorophyll (mg Chl-a m^-3) p4l = conc[26] # Large phytoplankton chlorophyll (mg Chl-a m^-3) r6c = conc[44] # Particulate organic carbon (mg C m^-3) # Concentration ratios (constituents quota in phytoplankton) pn_pc = get_concentration_ratio(pn, pc, constant_parameters["p_small"]) pp_pc = get_concentration_ratio(pp, pc, constant_parameters["p_small"]) pl_pc = get_concentration_ratio(pl, pc, constant_parameters["p_small"]) #-------------------------------------------------------------------------- # Temperature response of Phytoplankton Include cut-off at low temperature if p_temp>0 et = eTq_vector(temp, env_parameters["basetemp"], env_parameters["q10z"]) fTP = max(0.0, et - phyto_parameters["p_temp"]) #-------------------------------------------------------------------------- # Nutrient limitations (intracellular and extracellular) fpplim is the # combined non-dimensional factor limiting photosynthesis # from Phyto.F90 lines 268-308 in1p = min(1.0, max(constant_parameters["p_small"], (pp_pc - phyto_parameters["phi_Pmin"])/(phyto_parameters["phi_Popt"] - phyto_parameters["phi_Pmin"]))) in1n = min(1.0, max(constant_parameters["p_small"], (pn_pc - phyto_parameters["phi_Nmin"])/(phyto_parameters["phi_Nopt"] - phyto_parameters["phi_Nmin"]))) if group == 1: fpplim = min(1.0, n5s/(n5s + phyto_parameters["h_Ps"] + (phyto_parameters["rho_Ps"]*p1s))) else: fpplim = 1.0 #-------------------------------------------------------------------------- # multiple nutrient limitation, Liebig rule (from Phyto.F90 line ~318, iN) multiple_nut_lim = min(in1p, in1n) #-------------------------------------------------------------------------- # Total extinction coef (m^-1) suspended_sediments = 0.0 # from CalcVerticalExtinction.F90 line 82 xEPS = env_parameters["p_eps0"] + env_parameters["p_epsESS"]*suspended_sediments + env_parameters["p_epsR6"]*r6c # from CalcVerticalExtinction.F90 line 101 (ChlAttenFlag=1, ChlDynamicsFlag=2) xEPS = xEPS + p1l + p2l*2 + p3l*3 + p4l*4 #-------------------------------------------------------------------------- # Light limitation with Chl dynamics # irradiance (uE m^-2 s^-1) from Phyto.F90 lines 353-355 irradiance = qs*env_parameters["epsilon_PAR"]/constant_parameters["e2w"] r = xEPS * env_parameters["del_z"] r = irradiance/xEPS/env_parameters["del_z"]*(1.0 - numpy.exp(-r)) irr = max(constant_parameters["p_small"], r) # Compute exponent E_PAR/E_K = alpha0/PBmax (part of eqn. 2.2.4) exponent = pl_pc*phyto_parameters["alpha_chl"]/phyto_parameters["rP0"]*irr # light limitation factor (from Phyto.f90 line 374, eiPPY) light_lim = (1.0 - numpy.exp(-exponent)) #-------------------------------------------------------------------------- # total photosynthesis (from Phyto.F90 line ~380, sum) photosynthesis = phyto_parameters["rP0"]*fTP*light_lim*fpplim #-------------------------------------------------------------------------- # Lysis nad excretion # nutr. -stress lysis (from Phyto.F90 lines ~385-387, sdo) nut_stress_lysis = (phyto_parameters["h_Pnp"]/(multiple_nut_lim + phyto_parameters["h_Pnp"]))*phyto_parameters["d_P0"] nut_stress_lysis += phyto_parameters["p_seo"]*pc/(pc + phyto_parameters["p_sheo"] + constant_parameters["p_small"]) # activity excretion (Phyto.F90 line 389) activity_excretion = photosynthesis*phyto_parameters["betaP"] # nutrient stress excretion from Phyto.F90 line 396 nut_stress_excretion = photosynthesis*(1.0 - phyto_parameters["betaP"])*(1.0 - multiple_nut_lim) #-------------------------------------------------------------------------- # Apportioning over R1 and R6: Cell lysis generates both DOM and POM pe_R6 = min(phyto_parameters["phi_Pmin"]/(pp_pc + constant_parameters["p_small"]), phyto_parameters["phi_Nmin"]/(pn_pc + constant_parameters["p_small"])) pe_R6 = min(1.0, pe_R6) rr6c = pe_R6*nut_stress_lysis*pc rr1c = (1.0 - pe_R6)*nut_stress_lysis*pc #-------------------------------------------------------------------------- # Respiration rate # activity (from Phyto.F90 line 416) activity_rsp = phyto_parameters["gammaP"]*(photosynthesis - activity_excretion - nut_stress_excretion) # basal (from Phyto.F90 line 417) basal_rsp = fTP*phyto_parameters["bP"] # total (from Phyto.F90 line 418) total_rsp = activity_rsp + basal_rsp # total actual respiration dPcdt_rsp_o3c = total_rsp*pc #-------------------------------------------------------------------------- # Production, productivity and C flows # Phytoplankton gross primary production [mg C m^-3 s^-1] dPcdt_gpp_o3c = photosynthesis*pc # specific loss terms (from Phyto.F90 line 428) specific_loss_terms = activity_excretion + nut_stress_excretion + total_rsp + nut_stress_lysis # All activity excretions are assigned to R1 # p_switchDOC=1 and P_netgrowth=FLASE: [mg C m^-3 s^-1] rr1c += activity_excretion*pc + nut_stress_excretion*pc dPcdt_exu_r2c = 0.0 # Phytoplankton DOM cell lysis- carbon lost to DOM [mg C m^-3 s^-1] dPcdt_lys_r1c = rr1c # Phytoplankton POM cell lysis- carbon lost to POM (eqn. 2.2.9) [mg C m^-3 s^-1] dPcdt_lys_r6c = rr6c #-------------------------------------------------------------------------- # Potential-Net primary production # from Phyto.F90 line 455 sadap = fTP*phyto_parameters["rP0"] # Net production (from Phyto.F90 line 457, 'run') net_production = max(0.0, (photosynthesis - specific_loss_terms)*pc) #-------------------------------------------------------------------------- # Nutrient Uptake: calculate maximum uptake of N, P based on affinity cqun3 = phyto_parameters["h_Pn"]/(constant_parameters["p_small"] + phyto_parameters["h_Pn"] + n4n) # max potential uptake of N3 (from Phyto.F90 'rumn3') max_upt_n3n = phyto_parameters["a_N"]*n3n*pc*cqun3 # max potential uptake of N4 (from Phyto.F90 'rumn4') max_upt_n4n = phyto_parameters["a_N"]*n4n*pc # max potential uptake of DIN (from Phyto.F90 'rumn') max_upt_DIN = max_upt_n3n + max_upt_n4n # max pot. uptake of PO4 (from Phyto.F90 line 468) rump = phyto_parameters["a_P"]*n1p*pc #-------------------------------------------------------------------------- # Nutrient dynamics: NITROGEN # Intracellular missing amount of N (from Phyto.F90) misn = sadap*(phyto_parameters["phi_Nmax"]*pc - pn) # N uptake based on net assimilat. C (from Phyto.F90) rupn = phyto_parameters["phi_Nmax"]*net_production # actual uptake of NI (from Phyto.F90, 'runn') dPndt_upt = min(max_upt_DIN, rupn + misn) # if nitrogen uptake rate is positive, then uptake is divided between coming from the nitrate and ammonium reservoir # if nitrogen uptake is negative, all nitrogen goes to the DOM pool upt_switch_n = insw_vector(dPndt_upt) # actual uptake of N3n (from Phyto.F90, 'runn3') dPndt_upt_n3n = upt_switch_n*dPndt_upt*max_upt_n3n/(constant_parameters["p_small"] + max_upt_DIN) # actual uptake of N4n (from Phyto.F90, 'runn4') dPndt_upt_n4n = upt_switch_n*dPndt_upt*max_upt_n4n/(constant_parameters["p_small"] + max_upt_DIN) extra_n = -dPndt_upt*(1.0 - upt_switch_n) #-------------------------------------------------------------------------- # Nutrient dynamics: PHOSPHORUS # intracellular missing amount of P (from Phyto.F90 line 514) misp = sadap*(phyto_parameters["phi_Pmax"]*pc-pp) # P uptake based on C uptake (from Phyto.F90 line 517) rupp = phyto_parameters["phi_Pmax"]*net_production # Actual uptake runp = min(rump, rupp + misp) upt_switch_p = insw_vector(runp) dPpdt_upt_n1p = runp*upt_switch_p # is uptake is negative flux goes to DIP (R1P) pool dPpdt_upt_r1p = -runp*(1.0 - upt_switch_p) #-------------------------------------------------------------------------- # Excretion of N and P to PON and POP dPndt_lys_r6n = pe_R6*nut_stress_lysis*pn dPndt_lys_r1n = nut_stress_lysis*pn - dPndt_lys_r6n dPpdt_lys_r6p = pe_R6*nut_stress_lysis*pp dPpdt_lys_r1p = nut_stress_lysis*pp - dPpdt_lys_r6p #-------------------------------------------------------------------------- # Nutrient dynamics: SILICATE if group == 1: # Gross uptake of silicate excluding respiratory costs (from Phyto.F90, 'runs') dPsdt_upt_n5s = max(0.0, phyto_parameters["phi_Sopt"]*pc*(photosynthesis - basal_rsp)) # losses of Si (from Phyto.F90) dPsdt_lys_r6s = nut_stress_lysis*p1s else: dPsdt_upt_n5s = 0.0 dPsdt_lys_r6s = 0.0 #-------------------------------------------------------------------------- # Chl-a synthesis and photoacclimation if phyto_parameters["chl_switch"] == 1: # dynamical chl:c ratio from Fortran code Phyto.F90 rho_chl = phyto_parameters["theta_chl0"]*min(1.0, phyto_parameters["rP0"]*light_lim*pc/(phyto_parameters["alpha_chl"]*(pl + constant_parameters["p_small"])*irr)) # Chlorophyll synthesis from Fortran code Phyto.F90, rate_chl dPldt_syn = rho_chl*(photosynthesis - nut_stress_excretion - activity_excretion - activity_rsp)*pc - nut_stress_lysis*pl else: sys.exit("Warning: This code does not support other chl systhesis parameterizations") #-------------------------------------------------------------------------- return (dPcdt_gpp_o3c, dPcdt_rsp_o3c, dPcdt_lys_r1c, dPcdt_lys_r6c, dPcdt_exu_r2c, dPndt_upt_n3n, dPndt_upt_n4n, extra_n, dPndt_lys_r1n, dPndt_lys_r6n, dPpdt_upt_n1p, dPpdt_upt_r1p, dPpdt_lys_r1p, dPpdt_lys_r6p, dPldt_syn, dPsdt_upt_n5s, dPsdt_lys_r6s)