def get_minmax(data, deg=2): """ returns the interpolated extremum and position (in fractions of frames) :args: data (iterable): data to be fitted with a <deg> degree polynomial deg (int): degree of polynomial to fit :returns: val, pos: a tuple of floats indicating the position """ x = arange(len(data)) p = polyfit(x, data, deg) d = (arange(len(p))[::-1] * p)[:-1] r = roots(d) cnt = 0 idx = None for nr, rx in enumerate(r): if isreal(r): idx = nr cnt +=1 if cnt > 1: raise ValueError("Too many real roots found." + "Reduce order of polynomial!") x0 = r[nr].real return x0, polyval(p, x0)
def get_minmax(data, deg=2): """ returns the interpolated extremum and position (in fractions of frames) :args: data (iterable): data to be fitted with a <deg> degree polynomial deg (int): degree of polynomial to fit :returns: val, pos: a tuple of floats indicating the position """ x = arange(len(data)) p = polyfit(x, data, deg) d = (arange(len(p))[::-1] * p)[:-1] r = roots(d) cnt = 0 idx = None for nr, rx in enumerate(r): if isreal(r): idx = nr cnt += 1 if cnt > 1: raise ValueError("Too many real roots found." + "Reduce order of polynomial!") x0 = r[nr].real return x0, polyval(p, x0)
def find_solid_p(rho): sigma=1. p=pl.arange(10,20,0.01 ) v0=sigma**3/pl.sqrt(2) v=1./rho y=(p*sigma**3)**-1 coeffs=pl.zeros(7) coeffs[0]=19328.09 coeffs[1]=-2609.26 coeffs[2]=141.6000 coeffs[3]=11.56350 coeffs[4]=-1.807846 coeffs[5]=3 coeffs[6]=-v+v0 def find_real_positive(roots): for root in roots: if root.imag==0 and root.real>0: return root.real # print coeffs roots=1./pl.roots(coeffs) # f=3-1.807846*y+11.56350*y**2+141.6000*y**3-2609.260*y**4+19328.09*y**5-(v-v0)/y # # print pl.polyval(coeffs,1./p) # polynomial= pl.poly1d(coeffs) P=find_real_positive(roots) return P
def Cretaceous_cc( y, t0, cl_sens, deep_grad, PG, change_out, F_outgass, W_plus_1, F_carbw, CWF, CO2_dep, Te, n, coef_for_diss, beta, Ebas ): #inputs include DIC and ALK for ocean and pore space, time, and key parameters global pK1, pK2, H_CO2, Pore_mod, k_d, k_w, k_c, k_o, Mp, ppCO2_o, Ea, Mo, ko1, ko2 # Perscribed evolution of ocean and pore-space calcium molality (Fig. S6): Ca = 7.00658e-27 * abs(t0)**3 - 1.9847e-18 * (t0)**2 + 2.4016e-10 * ( t0) + 0.0100278 #ocean variables s = 1.8e20 / Mo #Constant for ensuring mass conversation [c, d] = pylab.roots([ y[1] / (10**-pK2 * 10**-pK1) * (1 + s / H_CO2), (y[1] - y[0]) / (10**-pK2), (y[1] - 2 * y[0]) ]) EM_H_o = numpy.max([c, d]) ## Evolving model ocean hydrogen molality EM_pH_o = -pylab.log10(EM_H_o) ## Evolving model ocean pH EM_co3_o = y[1] / (2 + EM_H_o / (10**-pK2)) ## Evolving model ocean carbonate molality EM_hco3_o = y[ 1] - 2 * EM_co3_o ## Evolving model ocean bicarbonate molality EM_co2aq_o = (EM_hco3_o * EM_H_o / (10**-pK1) ) ## Evolving model ocean aqueous CO2 molality EM_ppCO2_o = EM_co2aq_o / H_CO2 ## Evolving model atmospheric pCO2 EM_Ca_o = Ca #Perscribed ocean Ca molality #pore space variables [c, d] = pylab.roots([ y[3] / (10**-pK2 * 10**-pK1), (y[3] - y[2]) / (10**-pK2), (y[3] - 2 * y[2]) ]) EM_H_p = numpy.max([c, d]) ## Evolving model pore space hydrogen molality EM_pH_p = -pylab.log10(EM_H_p) ## Evolving model pore space pH EM_co3_p = y[3] / (2 + EM_H_p / (10**-pK2) ) ## Evolving model pore space carbonate molality EM_hco3_p = y[ 3] - 2 * EM_co3_p ## Evolving model pore space bicarbonate molality EM_co2aq_p = (EM_hco3_p * EM_H_p / (10**-pK1) ) ## Evolving model pore space aqueous CO2 molality EM_ppCO2_p = EM_co2aq_p / H_CO2 ## Evolving model pore space pCO2 (unused) EM_Ca_p = Ca #Percribed pore space Ca molality # Perscribed evolution of continental shelf area (Fig. S5): area = (.540e-23 * abs(t0)**3 - 3.072e-15 * abs(t0)**2 + 2.9997e-07 * abs(t0) + 16.089) / 16.089 # Apply climate model to calculate surface temperature (equation 5): T_surface_diff = (cl_sens / numpy.log(2)) * numpy.log( EM_ppCO2_o / ppCO2_o) - cl_sens * abs(t0) / (0.181e9 * 1.26) + PG * abs(t0) / 1e8 T_surface = T_surface_diff + 285 # Calculate pore space temperature (equation 11): interc = 274.037 - deep_grad * 285 buffer_T = deep_grad * T_surface + interc F_outg = F_outgass + change_out * F_outgass * ( abs(t0) / 1e8) #Outgassing as a function of time, equation 9 Relative_outgassing = F_outg / F_outgass #Relative outgassing weatherability = weatherability_func( abs(t0), W_plus_1) #Weatherability as a functino of time #Calculate saturation state of ocean and pore space (equation 19): EM_omega_o = EM_Ca_o * EM_co3_o / (Sol_prod(T_surface)) EM_omega_p = EM_Ca_p * EM_co3_p / (Sol_prod(buffer_T + Pore_mod)) # Carbonate weathering flux (equartion 7) carb_weath = F_carbw * (1 + CWF * abs(t0) / 1e8) * ( EM_ppCO2_o / ppCO2_o)**(CO2_dep) * numpy.exp( (T_surface_diff) / Te) * weatherability # Ocean carbonate precipitation flux (equation 17) Precip_ocean = ko1 * area * (EM_omega_o - 1)**n + ko2 * ( EM_omega_o**2.84) #shelf + pelagic # Pore space carbonate precipitation flux (equation 18) Precip_pore = k_c * (EM_omega_p - 1)**n #seafloor dissolution flux (equation 12) F_diss = k_d * 2.88 * 10**-14 * 10**( -coef_for_diss * EM_pH_p) * Relative_outgassing**beta * numpy.exp( -Ebas / (8.314 * (buffer_T + Pore_mod))) #continental silicate weathering flux (equation 2) F_silic = k_w * weatherability * (EM_ppCO2_o / ppCO2_o)**CO2_dep * numpy.exp( (T_surface_diff) / Te) return [ Ca, EM_H_o, EM_pH_o, EM_co3_o, EM_hco3_o, EM_co2aq_o, EM_ppCO2_o, EM_Ca_o, EM_H_p, EM_pH_p, EM_co3_p, EM_hco3_p, EM_co2aq_p, EM_ppCO2_p, EM_Ca_p, area, T_surface, T_surface_diff, buffer_T, EM_omega_o, EM_omega_p, Relative_outgassing, weatherability, F_outg, carb_weath, Precip_ocean, Precip_pore, F_diss, F_silic ]
def forward_model(W, F_outgass, n, CO2_dep, Te, mod_sea, alt_frac, Mp_frac, W_plus_1, cl_sens, change_out, F_carbw, frac_pel, CWF, deep_grad, coef_for_diss, beta, Ebas, PG): #import pdb #pdb.set_trace() # Make carbon chemistry constants and other parameters global variables: global pK1, pK2, H_CO2, Pore_mod, k_d, k_w, k_c, k_o, Mp, ppCO2_o, Ea, Mo, ko1, ko2 # Constants for carbon chemisty T = 18 + 273 #Temperature held constant for the purposes of calculating equilibrium constants (see manuscript) pK1 = 17.788 - .073104 * T - .0051087 * 35 + 1.1463 * 10**-4 * T**2 pK2 = 20.919 - .064209 * T - .011887 * 35 + 8.7313 * 10**-5 * T**2 H_CO2 = pylab.exp( 9345.17 / T - 167.8108 + 23.3585 * pylab.log(T) + (.023517 - 2.3656 * 10**-4 * T + 4.7036 * 10**-7 * T**2) * 35) Mo = 1.35e21 #Mass of ocean (kg) W = Mo / W #convert timescale of circulation (yr) to water flux through pore space (kg/yr) Mp = Mp_frac * Mo #Calculate mass of ocean in pore space partition = mod_sea / F_outgass #seafloor precipitation as a fraction of total carbon sink (used to initialize) ############################################################################ ## Compute initial conditions (i.e. fluxes and ocean chemistry for modern carbon cycle): F_diss0 = alt_frac * partition * F_outgass # Modern seafloor dissolution flux in pore space F_silic0 = (1 - partition) * F_outgass + ( 1 - alt_frac ) * partition * F_outgass #Modern continental silicaet weathering Precip_pore0 = partition * F_outgass # Modern carbonate precipitation in pore-space ### Initial conditions for modern atmosphere and ocean pH_o = 8.2 #pH of modern ocean ppCO2_o = .000280 #preindustrial pCO2 (ppm) CO2_aq_o = H_CO2 * ppCO2_o #modern ocean aqueous pCO2 molality hco3_o = (10**-pK1) * CO2_aq_o / (10**-pH_o ) #modern ocean bicarbonate molality co3_o = (10**-pK2) * hco3_o / (10**-pH_o ) # modern ocean carbonate molality DIC_o = co3_o + hco3_o + CO2_aq_o #modern ocean dissolved inorganic carbon ALK_o = 2 * co3_o + hco3_o # modern ocean alkalinity Ca_o = 0.0100278 # modern oceanic calcium molality (mol/kg) salt = ALK_o - 2 * Ca_o ## set salt to ensure ALK is consistent with Ca T_surface_diff = 0 T_surface = T_surface_diff + 285 # Modern average surface temperature (K) interc = 274.037 - deep_grad * 285 # Calculate intercept for surface vs. deep ocean temperature relationship buffer_T = deep_grad * T_surface + interc # Calculate modern deep ocean temperature (K) Pore_mod = 9.0 # Constant difference between deep ocean temperature and pore space temperature (K) ## Use these constants and steady state assumption to calculate remaining initial conditions: b1 = 2 * F_diss0 + W * ALK_o - 2 * W * DIC_o b2 = 2 * F_silic0 - W * ALK_o - 2 * F_outgass + 2 * W * DIC_o a1 = W a2 = -2 * W a3 = -W a4 = 2 * W # Solving system of equations for pore space properties DIC_p = DIC_o - Precip_pore0 / W #Modern dissolved inorganic carbon in pore space ALK_p = (b1 - a2 * DIC_p) / a1 #Modern alkalinity in pore space Precip_ocean0 = (F_outgass + F_carbw ) - (DIC_o - DIC_p) * W #Carbonate precipitation in ocean if DIC_p < 0: print("WARNING: NO PHYSIAL STEADY STATE EXISTS! DIC is negative") #Solve quadratic ignoring H in ALK but including CO2aq [vv, xx] = pylab.roots([ ALK_p / (10**-pK1 * 10**-pK2), (ALK_p - DIC_p) / (10**-pK2), ALK_p - 2 * DIC_p ]) H_p = numpy.max([vv, xx]) # Modern hydrogen molality in pore space pH_p = -pylab.log10(H_p) # Modern pH of pore space #Find remaining carbon chemistry from equilibrium conditions: CO2aq_p = DIC_p / ((10**-pK1) * (10**-pK2) / H_p**2 + 10**-pK1 / H_p + 1 ) # Modern aqueous CO2 in pore space co3_p = ALK_p - DIC_p - H_p + CO2aq_p # Modern carbonate alkalinity in pore space hco3_p = co3_p * 10**-pH_p / ( 10**-pK2) #Modern bicarbonate alkalinity in pore space (not used) Ca_p = 0.5 * (ALK_p - salt) #Modern calcium molality in pore space omega_p = Ca_p * co3_p / Sol_prod( buffer_T + Pore_mod) #Modern saturation state pore space omega_o = Ca_o * co3_o / Sol_prod( T_surface) #Modern saturatino state of ocean ## All initital conditions have been calculated ############################################################################ ############ Calculate proportionality constants ########################### # Given modern precipitation fluxes and saturation states, calculate proportionality constants k_c = Precip_pore0 / (omega_p - 1)**n k_o = Precip_ocean0 / (omega_o - 1)**n ## Partition ocean carbonate sink into shelf precipitation and carbonate precipitation ko1 = (1 - frac_pel) * Precip_ocean0 / (omega_o - 1)**n #Modern shelf precipitation ko2 = frac_pel * Precip_ocean0 / (omega_o**2.84 ) #Modern pelagic precipitation # Calculate remaining proportionality constants k_d = F_diss0 / (2.88 * 10**-14 * 10**(-coef_for_diss * pH_p) * numpy.exp(-Ebas / (8.314 * (buffer_T + Pore_mod)))) k_w = F_silic0 ##### all proportionality constants have been calculated ################### time = numpy.linspace( 0, 1e8, 100) # Time array for outputs, 100 timesteps between 0 and 100 Ma #print ('IC new',DIC_o+1.8e20/Mo*ppCO2_o,ALK_o,DIC_p,ALK_p) # Given initial conditions, unknown parameters, and system of ODEs (below), solve for time evolution of DIC and ALK of ocean and pore space: [out, mes] = scipy.integrate.odeint( system_of_equations, [DIC_o + 1.8e20 / Mo * ppCO2_o, ALK_o, DIC_p, ALK_p], time, args=(W, F_outgass, n, CO2_dep, Te, mod_sea, alt_frac, Mp_frac, W_plus_1, cl_sens, change_out, F_carbw, CWF, deep_grad, coef_for_diss, beta, Ebas, PG), full_output=1) # Create empty arrays for storing model outputs pH_array_o = 0 * time # pH of ocean CO2_array_o = 0 * time # pCO2 of ocean pH_array_p = 0 * time # pH of pore space CO2_array_p = 0 * time # pCO2 pore space Ca_array_o = 0 * time # Ca molality ocean Ca_array_p = 0 * time # Ca molality pore space CO3_array_o = 0 * time # Carbonate molality ocean CO3_array_p = 0 * time # Carbonate molality pore space HCO3_array_o = 0 * time # Bicarbonate molaity ocean HCO3_array_p = 0 * time # Bicarbonate molality pore space omega_o = 0 * time # Saturation state ocean omega_p = 0 * time # Saturation state pore space Tsurf_array = 0 * time # Surface temperature Tdeep_array = 0 * time # Pore space temperature Fd_array = 0 * time # Seafloor dissolution flux Fs_array = 0 * time # Continental silicate weathering flux Precip_ocean_array = 0 * time # Carbonate precipitaion ocean flux Precip_pore_array = 0 * time # Carbonate precipitation pore space flux volc_array = 0 * time # Volcanic outgassing flux carbw_ar = 0 * time # Carbonate weathering flux co2_aq_o = 0 * time # aqueous CO2 ocean molality co2_aq_p = 0 * time # aqueous CO2 pore space molality ### Step through time, and fill output arrays with solution calculated above for i in range(0, len(time)): # Given time evolution of DIC and ALK for ocean and pore space, calculate time evolution for other carbon cycle variables (fluxes and equilibrium chemistry): [ Ca, EM_H_o, EM_pH_o, EM_co3_o, EM_hco3_o, EM_co2aq_o, EM_ppCO2_o, EM_Ca_o, EM_H_p, EM_pH_p, EM_co3_p, EM_hco3_p, EM_co2aq_p, EM_ppCO2_p, EM_Ca_p, area, T_surface, T_surface_diff, buffer_T, EM_omega_o, EM_omega_p, Relative_outgassing, weatherability, F_outg, carb_weath, Precip_ocean, Precip_pore, F_diss, F_silic ] = Cretaceous_cc([out[i, 0], out[i, 1], out[i, 2], out[i, 3]], time[i], cl_sens, deep_grad, PG, change_out, F_outgass, W_plus_1, F_carbw, CWF, CO2_dep, Te, n, coef_for_diss, beta, Ebas) array_of_outputs = [ EM_pH_o, EM_co3_o, EM_hco3_o, EM_co2aq_o, EM_ppCO2_o, EM_Ca_o, EM_omega_o, T_surface, buffer_T, F_diss, F_silic, Precip_ocean, Precip_pore, EM_omega_p, carb_weath, EM_co3_p, EM_hco3_p, EM_co2aq_p, EM_pH_p, EM_Ca_p, EM_co2aq_p ] # Fill output array with appropriate model outputs: co2_aq_o[i] = array_of_outputs[3] pH_array_o[i] = array_of_outputs[0] CO2_array_o[i] = array_of_outputs[4] co2_aq_p[i] = array_of_outputs[17] pH_array_p[i] = array_of_outputs[18] CO2_array_p[i] = array_of_outputs[20] Ca_array_o[i] = array_of_outputs[5] Ca_array_p[i] = array_of_outputs[19] CO3_array_o[i] = array_of_outputs[1] CO3_array_p[i] = array_of_outputs[15] HCO3_array_o[i] = array_of_outputs[2] HCO3_array_p[i] = array_of_outputs[16] omega_o[i] = array_of_outputs[6] omega_p[i] = array_of_outputs[13] carbw_ar[i] = array_of_outputs[14] Tsurf_array[i] = array_of_outputs[7] Tdeep_array[i] = array_of_outputs[8] Fd_array[i] = array_of_outputs[9] Fs_array[i] = array_of_outputs[10] Precip_ocean_array[i] = array_of_outputs[11] Precip_pore_array[i] = array_of_outputs[12] volc_array[i] = F_outgass + change_out * F_outgass * (time[i] / 1e8) ############################################################################ #### Checking for mass balance ############################################################################ #max_el=numpy.size(time)-1 #tstep=numpy.max(time)/max_el #duration of timestep #sources=numpy.sum(volc_array[2:]+carbw_ar[2:])*tstep #sinks=numpy.sum(Precip_ocean_array[2:]+Precip_pore_array[2:])*tstep #flux_bal=sources-sinks #res_change=1.8e20*(CO2_array_o[max_el]-CO2_array_o[2])+Mo*(HCO3_array_o[max_el]+CO3_array_o[max_el]+co2_aq_o[max_el]-co2_aq_o[2]-CO3_array_o[2]-HCO3_array_o[2])+Mp*(HCO3_array_p[max_el]+CO3_array_p[max_el]+co2_aq_p[max_el]-co2_aq_p[2]-CO3_array_p[2]-HCO3_array_p[2]) #res_change2=(out[max_el,0]-out[2,0])*Mo+(out[max_el,2]-out[2,2])*Mp #print flux_bal,res_change,res_change2,Mo*(HCO3_array_o[max_el]+CO3_array_o[max_el]+co2_aq_o[max_el]-co2_aq_o[2]-CO3_array_o[2]-HCO3_array_o[2])+Mp*(HCO3_array_p[max_el]+CO3_array_p[max_el]+co2_aq_p[max_el]-co2_aq_p[2]-CO3_array_p[2]-HCO3_array_p[2]) #imbalance=(flux_bal-res_change)/(out[max_el,0]*Mo) #print imbalance imbalance = 0 ## Comment out if wish to calculate mass imbalance ############################################################################ # Return selected outputs to Main_code.py for plotting return [ out[:, 0], out[:, 1], out[:, 2], out[:, 3], time, pH_array_o, CO2_array_o, pH_array_p, CO2_array_p, Ca_array_o, Ca_array_p, CO3_array_o, CO3_array_p, HCO3_array_o, HCO3_array_p, omega_o, omega_p, Tsurf_array, Tdeep_array, Fd_array, Fs_array, Precip_ocean_array, Precip_pore_array ], imbalance
def soln(mchirp): return pylab.roots([1., 0., -mchirp**(5./3), -1])[0]**3
def carbon_cycle(y, t0, Bio_f, ppCO2_00, n, climp, tdep_weath, F_meta_mod, F_out_mantle_mod, pH_00, lfrac, R_carb_00, del_carb0, F_carbw, R_mantle_00, F_sub_mod, coef_for_diss, beta, n_out, mm, growth_timing, new_add_Ca, Ebas, e1, protero_O2, del_org0, e2, j1, j2, j3, org_weath_mod0, thermo_weath, multplic, Mantle_temp_mod): Ca_cofactor = new_add_Ca / 5000.0 * ( (1 - abs(t0) / (4.5e9))**-0.5 - 1) #Redundant global pK1, pK2, H_CO2, salt, Pore_mod, T_surface0, ALK_o, ALK_p, Ca_p, Ca_o, Rcrust0, Rorg0, k_meta0_carb, k_meta0_org, k_sub0_carb, k_sub0_org, F_orgB0, imply_forg0, org_weath0, carb_minus_org, carb_minus_AO global landf_vary, lum_vary, salt0, k_w, k_c, k_o, k_r, Mp, ppCO2_o, Mo, ko1, ko2, k_meta0, k_sub0, k_mantle0, k_sub_arc0 global mantle_mod, Rcrust_mod, Rorg_mod, F_meta_mod_carb, F_meta_mod_org global F_sub_mod_carb, F_sub_mod_org, ppCO2_mod, deep_grad s = 1.8e20 / Mo [c, d] = pylab.roots([ y[1] / (10**-pK2 * 10**-pK1) * (1 + s / H_CO2), (y[1] - y[0]) / (10**-pK2), (y[1] - 2 * y[0]) ]) EE_H_o = numpy.max([c, d]) EE_pH_o = -pylab.log10(EE_H_o) EE_co3_o = y[1] / (2 + EE_H_o / (10**-pK2)) EE_hco3_o = y[1] - 2 * EE_co3_o EE_co2aq_o = (EE_hco3_o * EE_H_o / (10**-pK1)) EE_ppCO2_o = EE_co2aq_o / H_CO2 EE_Ca_o = Ca_o + 0.5 * (y[1] - ALK_o) + Ca_cofactor #pore space EE_H_p = EE_H_o EE_pH_p = EE_pH_o EE_co3_p = EE_co3_o EE_hco3_p = EE_hco3_o EE_co2aq_p = EE_co2aq_o EE_ppCO2_p = EE_ppCO2_o EE_Ca_p = EE_Ca_o bio_now = 1 - 1 / (1 / (1 - Bio_f) + numpy.exp(-5 * (abs(t0) - 1e9) / 1e9)) bio_Archean = 1 - 1 / (1 / (1 - Bio_f) + numpy.exp(-5 * (abs(4.1e9) - 1e9) / 1e9)) biology_modern = 1 - 1 / (1 / (1 - Bio_f) + numpy.exp(-5 * (abs(0.0) - 1e9) / 1e9)) biology = bio_now / bio_Archean biology_mod = biology_modern / bio_Archean Q0 = (1 - abs(4.1e9) / (4.5e9))**-n_out Q = (1 - abs(t0) / (4.5e9))**-n_out spread = Q**beta Mantle_temp = Mantle_temp_mod * (Q)**0.1 Ccrit = (3.125e-3 * 80.0 + 835.5 - 285.0) / (Mantle_temp - 285.0) carb_eff_modifier = numpy.min([1.0, (Ccrit - 0.3) / (0.6 - 0.3)]) if carb_eff_modifier < 0.0: carb_eff_modifier = 0.0 F_out_mantle = F_out_mantle_mod * (Q**mm) * (y[5] / mantle_mod) F_meta_carb = F_meta_mod_carb * (Q**mm) * (y[4] / Rcrust_mod) F_meta_org = F_meta_mod_org * (Q**mm) * (y[6] / Rorg_mod) F_meta = F_meta_carb + F_meta_org F_sub_carb = F_sub_mod_carb * (Q**beta) * (y[4] / Rcrust_mod) F_sub_org = F_sub_mod_org * (Q**beta) * (y[6] / Rorg_mod) F_sub = F_sub_carb + F_sub_org F_sub_arc = F_sub_carb * (1 - carb_eff_modifier) + F_sub_org * e1 F_outg = F_out_mantle + F_meta + F_sub_arc #isotopes del_sub = (F_sub_carb * y[8] + F_sub_org * y[7]) / F_sub_arc del_arc_volc = (F_sub_carb * (1 - carb_eff_modifier) * y[8] + e1 * F_sub_org * y[7]) / F_sub_arc del_meta_volc = (F_meta_carb * y[8] + F_meta_org * y[7]) / F_meta del_crust = (y[4] * y[8] + y[6] * y[7]) / (y[4] + y[6]) del_out = (F_out_mantle * y[9] + F_meta_carb * y[8] + F_meta_org * y[7] + F_sub_carb * (1 - carb_eff_modifier) * y[8] + (e1) * F_sub_org * y[7]) / F_outg carb_minus_org = 0 carb_minus_AO = 0 if abs(t0) < 4.0e9: carb_minus_org = 28.0 carb_minus_AO = 2 del_carb_precip = y[10] + carb_minus_AO del_org_buried = del_carb_precip - carb_minus_org if landf_vary == "y": land = lf(t0, lfrac, growth_timing) land_mod = lf(0, lfrac, growth_timing) else: land = 1 land_mod = 1 if lum_vary == "y": L_over_Lo = 1 / (1 + 0.4 * (abs(t0) / 4.6e9)) T_surface = clim_fun(EE_ppCO2_o, L_over_Lo) else: L_over_Lo = 1 / (1 + 0.4 * (abs(4.1e9) / 4.6e9)) T_surface = clim_fun(EE_ppCO2_o, L_over_Lo) T_surface_mod = clim_fun(ppCO2_mod, 1 / (1 + 0.4 * (abs(0) / 4.6e9))) T_surface_diff_mod = T_surface - T_surface_mod T_surface_diff = T_surface - T_surface0 interc = 274.037 - deep_grad * 285.44411576277344 buffer_T = deep_grad * T_surface + interc buffer_Ti = numpy.max([deep_grad * T_surface + interc, 271.15]) buffer_T = numpy.min([buffer_Ti, T_surface]) EE_omega_o = EE_Ca_o * EE_co3_o / (Sol_prod(T_surface)) EE_omega_p = EE_Ca_p * EE_co3_p / (Sol_prod(buffer_T + Pore_mod)) #ocean carbonate sink Carb_sink = ko1 * (land / land_mod) * (EE_omega_o)**n + ko2 * (EE_omega_o** 2.84) Precip_ocean = Carb_sink Precip_pore = k_c * (EE_omega_p)**n # Carbonate weathering flux carb_weath = (y[4] / Rcrust_mod) * F_carbw * (biology / biology_mod) * ( EE_ppCO2_o / ppCO2_mod)**(climp) * numpy.exp( (T_surface_diff_mod) / tdep_weath) * (land / land_mod) F_diss = k_r * (2.88 * 10**-14 * 10**(-coef_for_diss * EE_pH_p) * numpy.exp(-Ebas / (8.314 * (buffer_T + Pore_mod)))) * spread F_silic = k_w * (biology / biology_mod) * (land / land_mod) * ( EE_ppCO2_o / ppCO2_mod)**climp * numpy.exp( (T_surface_diff_mod) / tdep_weath) aa = -0.5 * numpy.log10(protero_O2) bb = 4.5 + 0.5 * numpy.log10(protero_O2) cc = -4.5 pO2 = 10**(aa * numpy.tanh(-20 * (abs(t0) - 0.55e9) / 1e9) + bb * numpy.tanh(-20 * (abs(t0) - 2.45e9) / 1e9) + cc) org_weath = org_weath_mod0 * (y[6] / Rorg_mod) * (land / land_mod) * ( pO2)**0.30809 + thermo_weath * (y[6] / Rorg_mod ) ## This is running in retrieval total_carb_inputs = (carb_weath + org_weath + F_outg) if (abs(t0) > 4.0e9): F_orgB = 0 * total_carb_inputs if (abs(t0) < 4.0e9) and (abs(t0) > 3.9e9): F_orgB = j1 * total_carb_inputs * (-abs(t0) + 4.0e9) / 0.1e9 if (abs(t0) < 3.9e9) and (abs(t0) > 2.5e9): F_orgB = j1 * total_carb_inputs if (abs(t0) < 2.5e9) and (abs(t0) > 2.4e9): inbetween = (abs(t0) - 2.4e9) / 0.1e9 F_orgB = j1 * total_carb_inputs * inbetween + ( 1 - inbetween) * j2 * j1 * total_carb_inputs if (abs(t0) < 2.4e9) and (abs(t0) > 0.6e9): F_orgB = j2 * j1 * total_carb_inputs if (abs(t0) > 0.5e9) and (abs(t0) < 0.6e9): inbetween = (abs(t0) - 0.5e9) / 0.1e9 F_orgB = j1 * j2 * total_carb_inputs * inbetween + ( 1 - inbetween) * j3 * j2 * j1 * total_carb_inputs if (abs(t0) < 0.5e9): F_orgB = j3 * j2 * j1 * total_carb_inputs if (abs(t0) > 4.0e9): tempforg = 0 if (abs(t0) < 4.0e9) and (abs(t0) > 3.9e9): tempforg = j1 * (-abs(t0) + 4.0e9) / 0.1e9 if (abs(t0) < 3.9e9) and (abs(t0) > 2.5e9): tempforg = j1 if (abs(t0) < 2.5e9) and (abs(t0) > 2.4e9): inbetween = (abs(t0) - 2.4e9) / 0.1e9 tempforg = j1 * inbetween + (1 - inbetween) * j2 * j1 if (abs(t0) < 2.4e9) and (abs(t0) > 0.6e9): tempforg = j2 * j1 if (abs(t0) > 0.5e9) and (abs(t0) < 0.6e9): inbetween = (abs(t0) - 0.5e9) / 0.1e9 tempforg = j1 * j2 * inbetween + (1 - inbetween) * j3 * j2 * j1 if (abs(t0) < 0.5e9): tempforg = j3 * j2 * j1 current_volc = F_out_mantle_mod + F_meta_mod + F_sub_mod multiplicative = 1 + multplic * abs(t0) / 4.1e9 O2_fast_sink = multiplicative * 2.4e12 * F_outg / current_volc model_modern_forg = j1 * j2 * j3 reduced_early = (F_orgB + 5.15e12 * tempforg / model_modern_forg - org_weath - O2_fast_sink) del_inputs = (F_outg * del_out + org_weath * y[7] + carb_weath * y[8]) / (F_outg + org_weath + carb_weath) O2_source = F_orgB + 5.15e12 * (tempforg / model_modern_forg) Kox = O2_source / O2_fast_sink return [ EE_pH_o, EE_co3_o, EE_hco3_o, EE_co2aq_o, EE_ppCO2_o, EE_Ca_o, EE_omega_o, T_surface, buffer_T, F_diss, F_silic, Precip_ocean, Precip_pore, EE_omega_p, F_outg, carb_weath, EE_co3_p, EE_hco3_p, EE_co2aq_p, EE_pH_p, EE_ppCO2_p, EE_Ca_p, EE_H_o, EE_H_p, T_surface_diff, F_outg, F_meta, F_sub, F_out_mantle, F_meta_carb, F_sub_carb, F_meta_org, F_sub_org, org_weath, F_orgB, del_org_buried, del_carb_precip, del_crust, del_out, del_inputs, pO2, reduced_early, F_sub_arc, del_arc_volc, del_meta_volc, del_sub, 1 - carb_eff_modifier, Kox ]
def carbon_cycle(y, t0, W, F_outgass, n, climp, tdep_weath, mod_sea, alt_frac, Mp_frac, lfrac, carb_exp, sed_thick, F_carbw, CWF, deep_grad, coef_for_diss, beta, n_out, mm, growth_timing, new_add_Ca, Ebas): ## Ca_cofactor is only important for the sensitivity tests where a wide range of Archean Ca abundances are imposed Ca_cofactor = new_add_Ca / 1000.0 * numpy.exp( t0 / 1e9 - 4) # perscribed ocean Ca molality evolution global pK1, pK2, H_CO2, salt, Pore_mod, T_surface0, ALK_o, ALK_p, Ca_p, Ca_o, options_array global landf_vary, lum_vary, salt0, k_w, k_c, k_o, k_r, Mp, ppCO2_o, Mo, ko1, ko2 #,Mg_fun,Ca_Tfun,coef_for_diss #ocean variables s = 1.8e20 / Mo #correction factor for mass balance (see manuscript) #### Temperature loop #### # This loop is necessary because the carbon chemistry equilibrium constants are temperatue dependent, # but surface temperature is controlled by atmospheric pCO2, which is in turn modulated by # the carbon chemistry of the ocean. Therefore, several iterations are required to ensure the temperature # used to calculate equilibrium constants is the same as the surface climate. Sensitivity tests reveal # that three iterations are sufficient for accurate (within 1 degree) convergence. # Note that if Carbon_chem is set to 0 then the only a single iteration is executed and # the carbon chemistry constants are assumed to be fixed. This is faster and only slightly less # accurate than the full calculation. ## initial guesses for surface temperature and pore space, to be used to determine equilibrium carbon chemistry constants: T_upd = 273 + 18 # initial guess for surface temperature T_upd2 = 273 + 18 # initial guess for pore-space temperature T_surface = 100.0 # Filler value (T_surface will be calcauled within the loop) # Check to see if Carbon_chem is 0 or 1 if options_array[1] == 0: max_temp_iter = 1 # run single iteration else: max_temp_iter = 3 # run 3 iterations jk = 0 for jk in range(0, max_temp_iter): ## Calculate temperature-dependent carbon chemistry constants for the ocean: [pK1, pK2, H_CO2] = equil_cont(T_upd) # Calculate equilibrium carbon chemistry for the ocean: [c, d] = pylab.roots([ y[1] / (10**-pK2 * 10**-pK1) * (1 + s / H_CO2), (y[1] - y[0]) / (10**-pK2), (y[1] - 2 * y[0]) ]) #equation S15 EE_H_o = numpy.max([c, d]) ## make sure get right root! EE_pH_o = -pylab.log10(EE_H_o) # equation S16 EE_co3_o = y[1] / (2 + EE_H_o / (10**-pK2)) EE_hco3_o = y[1] - 2 * EE_co3_o EE_co2aq_o = (EE_hco3_o * EE_H_o / (10**-pK1)) # equation S13 EE_ppCO2_o = EE_co2aq_o / H_CO2 # equation S12 EE_Ca_o = Ca_o + 0.5 * (y[1] - ALK_o) + Ca_cofactor #equation S17 ## Calculate temperature-dependent carbon chemistry constants for the pore space: [pK1, pK2, H_CO2] = equil_cont(T_upd2) # Calculate equilibrium carbon chemistry for the pore space: [c, d] = pylab.roots([ y[3] / (10**-pK2 * 10**-pK1), (y[3] - y[2]) / (10**-pK2), (y[3] - 2 * y[2]) ]) # equation S15 EE_H_p = numpy.max([c, d]) ## make sure get right root! EE_pH_p = -pylab.log10(EE_H_p) # equation S16 EE_co3_p = y[3] / (2 + EE_H_p / (10**-pK2)) EE_hco3_p = y[3] - 2 * EE_co3_p EE_co2aq_p = (EE_hco3_p * EE_H_p / (10**-pK1)) #equation S14 EE_ppCO2_p = EE_co2aq_p / H_CO2 #equation S12 EE_Ca_p = Ca_p + 0.5 * (y[3] - ALK_p) + Ca_cofactor # equation S17 # Calculate biological modification of continental weathering using equation S7: fb_EE = 1 / (1 - CWF) biology_modifier = 1 - 1 / (fb_EE + numpy.exp(-10 * (t0 - 0.6e9) / 1e9)) #biology_modifier=1.0 # Calculate internal heatflow, outgassing, and spreading rate using equations S8-10: Q = (1 - t0 / (4.5e9))**-n_out #Q=1.0 #Q=1-(1-n_out)*(t0/4e9)**2.0 # alternative for lowering outgassing F_outg = F_outgass * Q**mm #F_outg=F_outgass*Q # alternative for lowering outgassing spread = Q if landf_vary == "y": land = lf(t0, lfrac, growth_timing) else: land = 1.0 if lum_vary == "y": L_over_Lo = 1 / ( 1 + 0.4 * (t0 / 4.6e9)) # Evolution of solar luminosity from Gough 1981. if options_array[ 2] == 1: # Check to see if methane option is on. If yes, use methane climate models: ### Weighting functions for Phanerozoic, Proterozoic, and Archean methane climates (only used high methane tests) ### Smooth weighting functions are required because sudden temperature jumps break the model. w0 = 1 - 1 / (1 + numpy.exp(-15 * (t0 / 1e9 - 0.541)) ) # 1 in the Phanerozoic, 0 elsewhere w1 = 1 / (1 + numpy.exp(-15 * (t0 / 1e9 - 0.541))) - 1 / ( 1 + numpy.exp(-15 * (t0 / 1e9 - 2.5)) ) # 1 in the Proterozoic, 0 elsewhere w2 = 1 / (1 + numpy.exp(-15 * (t0 / 1e9 - 2.5)) ) # 1 in the Archean, 0 elsewhere arch_temp = clim_fun_highCH4( EE_ppCO2_o, L_over_Lo) ## Archean temperature with high methane Protero_temp = clim_fun_lowCH4( EE_ppCO2_o, L_over_Lo) ## Proterozoic temperature with high methane ### Climate model for eleveated Proterozoic and Archean methane abundances: T_surface = (w0 * clim_fun_CO2_only(EE_ppCO2_o, L_over_Lo) + w1 * Protero_temp + w2 * arch_temp) / (w0 + w1 + w2) else: # methane option off -> use CO2 only climate model (nominal model) T_surface = clim_fun_CO2_only(EE_ppCO2_o, L_over_Lo) ###T_surface=clim_fun_CO2_only(EE_ppCO2_o,L_over_Lo)+30.0 * (1/(1+numpy.exp(-15*(t0/1e9-2.5)))) ## for +30 K sensitivity test else: T_surface = clim_fun_CO2_only( EE_ppCO2_o, 1.0) # For CO2-only, no evolution in solar luminosity ## Calculate deep ocean temperature T_surface_diff = T_surface - T_surface0 interc = 274.037 - deep_grad * T_surface0 # intercept chosen to reproduce initial (modern) temperature buffer_T = deep_grad * T_surface + interc buffer_Ti = numpy.max([deep_grad * T_surface + interc, 271.15]) # ensures deep ocean is not frozen buffer_T = numpy.min( [buffer_Ti, T_surface] ) # This is deep ocean temperature (cannot be warmer than the surface) ## Calculate pore space temperature, ## accounting for effect of sediment thickness and heatflow Pore_mod_dynamic = Pore_mod sed_depth = 700 - 700 * (1 - sed_thick) * t0 / 4e9 # equation S5 Pore_mod_dynamic = Q * sed_depth / 77.7777777 ## Difference is 9 K for Q=1 T_pore_space = buffer_T + Pore_mod_dynamic #T_pore_space=buffer_T+9.0 # sensitivity test constant temperature difference between pore space and deep ocean T_upd = T_surface #update surface temperature for next iteration T_upd2 = T_pore_space #update pore space temperature for next iteration # Calculate saturation state of ocean and pore space (equation S18): # combined activity coefficients for Ca and CO3. Assumed to be 1 except for Ca sensitiviy test where complexing is important act_o = 1.0 #-7.89*EE_Ca_o**3+10.847*EE_Ca_o**2-5.2246*EE_Ca_o+1.0551 #from Aspen polynomial fit Fig. S20, or 1.0 for nominal case act_p = 1.0 #-7.89*EE_Ca_p**3+10.847*EE_Ca_p**2-5.2246*EE_Ca_p+1.0551 #from Aspen polynomial fit Fig. S20, or 1.0 for nominal case EE_omega_o = act_o * EE_Ca_o * EE_co3_o / (Sol_prod(T_surface) ) # saturation state ocean EE_omega_p = act_p * EE_Ca_p * EE_co3_p / (Sol_prod(T_pore_space) ) # saturation state pore space #Calculate carbonate sinks Carb_sink = ko1 * land * (EE_omega_o - 1)**n + ko2 * ( EE_omega_o**2.84 ) # ocean carbonate from equation S19, noting that ko2 is 0 in this version of the model Precip_ocean = Carb_sink ## Precipitaion of carbonate in ocean Precip_pore = k_c * (EE_omega_p - 1)**n ## Precipitation of carbonate in pore space # Carbonate weathering flux carb_weath = F_carbw * biology_modifier * (EE_ppCO2_o / ppCO2_o)**( carb_exp) * numpy.exp( (T_surface_diff) / tdep_weath) * land # equation S2 ### Dissolution of seafloor flux: F_diss = k_r * 2.88 * 10**-14 * 10**(-coef_for_diss * EE_pH_p) * spread**beta * numpy.exp( -Ebas / (8.314 * (T_pore_space))) # equation S3 #F_diss=k_r*2.88*10**-14*10**(-coef_for_diss*8.57)*numpy.exp(-Ebas/(8.314*(283))) # sensitivity test holding dissolution artifically constant #Continetnal silicate weathering flux F_silic = k_w * biology_modifier * land * ( EE_ppCO2_o / ppCO2_o)**climp * numpy.exp( (T_surface_diff) / tdep_weath) # equation 1 #return selected carbon cycle variables and fluxes return [ EE_pH_o, EE_co3_o, EE_hco3_o, EE_co2aq_o, EE_ppCO2_o, EE_Ca_o, EE_omega_o, T_surface, buffer_T, F_diss, F_silic, Precip_ocean, Precip_pore, EE_omega_p, F_outg, carb_weath, EE_co3_p, EE_hco3_p, EE_co2aq_p, EE_pH_p, EE_ppCO2_p, EE_Ca_p, EE_H_o, EE_H_p, T_surface_diff, F_outg, spread, T_pore_space ] #T_pore_space
def Forward_Model(W, F_outgass, n, climp, tdep_weath, mod_sea, alt_frac, Mp_frac, lfrac, carb_exp, sed_thick, F_carbw, fpel, CWF, deep_grad, coef_for_diss, beta, n_out, mm, growth_timing, new_add_Ca, Ebas): # define global variables: global pK1, pK2, H_CO2, salt, Pore_mod, T_surface0, Ca_p, Ca_o, options_array global landf_vary, lum_vary, salt0, k_w, k_c, k_o, k_r, Mp, ppCO2_o, Mo, ko1, ko2, ALK_o, ALK_p # load options defined in main_code_parallel.py: options_array = numpy.load('options_array.npy') # Initial (modern) ocean pH and atmospheric pCO2 (bar) pH_o = 8.2 ppCO2_o = .000280 T = clim_fun_CO2_only(ppCO2_o, 1.0) # find initial (modern) temperature # Calculate equilibrium constants for carbon chemistry: [pK1, pK2, H_CO2] = equil_cont(T) Mo = 1.35e21 # Mass of ocean (kg) W = Mo / W # convert mixing time of ocean (yr) to mass flux (kg/yr) Mp = Mp_frac * Mo # Mass of water in pore space ############################################################## ############ Compute other initial conditions ################ # First, we use the assumed values for modern seafloor carbonate precipitation, outgassing, and seafloor dissolution to carbonate precipitation ratio # along with the carbon cycle steady state assumption to calculated the modern seafloor dissolution and continental silciate weathering partition = mod_sea / F_outgass F_diss0 = alt_frac * partition * F_outgass #initial seafloor dissolution flux i.e. dissolution = alt_frac*precip_seafloor F_sil0 = (1 - partition) * F_outgass + ( 1 - alt_frac ) * partition * F_outgass #initial continental silicate weathering flux Fprecip_p = partition * F_outgass #initial pore space carbonate precipation flux (reduntant) #vary solar luminosity? y or n (don't modify these options - better to change elsewhere). lum_vary = "y" landf_vary = "y" ### Initial conditions for modern atmosphere and ocean (equations S12 to S14) CO2_aq_o = H_CO2 * ppCO2_o #aqueous dissolved CO2 hco3_o = (10**-pK1) * CO2_aq_o / (10**-pH_o) # aqueous bicarbonate co3_o = (10**-pK2) * hco3_o / (10**-pH_o) #aqueous carbonate DIC_o = co3_o + hco3_o + CO2_aq_o #dissolved inorganic carbon ALK_o = 2 * co3_o + hco3_o #carbonate alkalinity Ca_o = 0.0100278 # initial (modern) calcium molality salt = ALK_o - 2 * Ca_o ## set salt to ensure ALK is consistent with Ca salt0 = salt # initial (modern) salt T_surface0 = clim_fun_CO2_only(ppCO2_o, 1.0) interc = 274.037 - deep_grad * T_surface0 buffer_T = deep_grad * T_surface0 + interc #initial deep ocean temperature Pore_mod = 9.0 #difference between pore space and deep ocean temperature for modern Earth ## Use these constants and steady state assumption to calculate remaining initial conditions: b1 = 2 * F_diss0 + W * ALK_o - 2 * W * DIC_o b2 = 2 * F_sil0 - W * ALK_o - 2 * F_outgass + 2 * W * DIC_o a1 = W a2 = -2 * W a3 = -W a4 = 2 * W # Solving system of equations for pore space properties DIC_p = DIC_o - Fprecip_p / W ALK_p = (b1 - a2 * DIC_p) / a1 Fprecip_o = (F_outgass + F_carbw) - (DIC_o - DIC_p) * W if DIC_p == 0: print "WARNING: NO PHYSIAL STEADY STATE EXISTS! DIC is negative" #Solve quadratic ignoring H in ALK but including CO2aq [vv, xx] = pylab.roots([ ALK_p / (10**-pK1 * 10**-pK2), (ALK_p - DIC_p) / (10**-pK2), ALK_p - 2 * DIC_p ]) #equation S15 H_p = numpy.max([vv, xx]) # take positive root pH_p = -pylab.log10(H_p) #Find remaining carbon chemistry from equilibrium conditions: CO2aq_p = DIC_p / ((10**-pK1) * (10**-pK2) / H_p**2 + 10**-pK1 / H_p + 1) co3_p = ALK_p - DIC_p - H_p + CO2aq_p ## only true for high pH, okay for fitting I think (actually should include CO2aq to get exact). hco3_p = co3_p * 10**-pH_p / ( 10**-pK2) #Modern bicarbonate alkalinity in pore space (not used) Ca_p = 0.5 * (ALK_p - salt) #initial calcium molality in pore space omega_p = Ca_p * co3_p / Sol_prod( buffer_T + Pore_mod) # saturation state pore space omega_o = Ca_o * co3_o / Sol_prod(T_surface0) # saturation state ocean ## All initital conditions have been calculated ############################ ############################################################################ ############ Calculate proportionality constants ########################### # Given modern precipitation fluxes and saturation states, calculate proportionality constants k_c = Fprecip_p / (omega_p - 1)**n k_o = Fprecip_o / (omega_o - 1)**n ## Partition ocean carbonate sink into shelf precipitation and carbonate precipitation frac_pel = fpel # no pelagic carbonates in this version of the code (i.e. default is fpel=0) ko1 = (1 - frac_pel) * Fprecip_o / (omega_o - 1)**n ko2 = frac_pel * Fprecip_o / (omega_o**2.84) ### remaining proportionality constants k_r = F_diss0 / (2.88 * 10**-14 * 10**(-coef_for_diss * pH_p) * numpy.exp( -Ebas / (8.314 * (buffer_T + Pore_mod)))) #for seafloor dissolution k_w = F_sil0 # for continental silicate weathering time = numpy.linspace( 0, 4e9, 100 ) #define time array from 0 to 4 Ga in 100 time steps. Number of time steps can be increased for greater precision (takes longer) # run ode solver with initial conditions defined above, and inputs from main_code_parallel.py. The ode solver will output the dissolved inorganic carbon and # alkalinities of the ocean and pore space through time (all containted in 'out'). The diagnostic 'mes' is also returned [out, mes] = scipy.integrate.odeint( system_of_equations, [DIC_o + 1.8e20 / Mo * ppCO2_o, ALK_o, DIC_p, ALK_p], time, args=(W, F_outgass, n, climp, tdep_weath, mod_sea, alt_frac, Mp_frac, lfrac, carb_exp, sed_thick, F_carbw, CWF, deep_grad, coef_for_diss, beta, n_out, mm, growth_timing, new_add_Ca, Ebas), full_output=1) # Given alkalinities and dissolved inorganic carbon, calculate time-evolution for other carbon cycle variables # define empty arrays for variables of interest: pH_array_o = 0 * time #ocean pH CO2_array_o = 0 * time # atmospheric CO2 pH_array_p = 0 * time # pore space pH CO2_array_p = 0 * time # pore space CO2 Ca_array_o = 0 * time # ocean calcium molality Ca_array_p = 0 * time # pore space calcium molality CO3_array_o = 0 * time # ocean carbonate molality CO3_array_p = 0 * time # pore space carbonate molality HCO3_array_o = 0 * time # ocean bicarbonate molality HCO3_array_p = 0 * time # pore space bicarbonate molality omega_o = 0 * time # saturation state ocean omega_p = 0 * time # saturation state pore space Tsurf_array = 0 * time # Surface temperature Tdeep_array = 0 * time # Deep ocean temperature Fd_array = 0 * time # Seafloor dissolution Fs_array = 0 * time # Continental silciate weathering Precip_ocean_array = 0 * time # ocean carbonate precipitation Precip_pore_array = 0 * time # pore space carbonate precipitation volc_array = 0 * time # volcanic outgassing carbw_ar = 0 * time # Continental carbonate weathering co2_aq_o = 0 * time # ocean aqueous CO2 co2_aq_p = 0 * time # pore space aqueous CO2 spread_ar = 0 * time # spreading rate relative to modern T_pore_space_ar = 0 * time # pore space temperature for i in range(0, len(time)): # using ode solution (alkalinities and DIC abundances) and input parameters, fill array pl1 with other carbon cycle evolution variables pl1 = carbon_cycle([out[i, 0], out[i, 1], out[i, 2], out[i, 3]], time[i], W, F_outgass, n, climp, tdep_weath, mod_sea, alt_frac, Mp_frac, lfrac, carb_exp, sed_thick, F_carbw, CWF, deep_grad, coef_for_diss, beta, n_out, mm, growth_timing, new_add_Ca, Ebas) #ocean # Fill in arrays define above pH_array_o[i] = pl1[0] co2_aq_o[i] = pl1[3] CO2_array_o[i] = pl1[4] pH_array_p[i] = pl1[19] CO2_array_p[i] = pl1[20] Ca_array_o[i] = pl1[5] Ca_array_p[i] = pl1[21] CO3_array_o[i] = pl1[1] CO3_array_p[i] = pl1[16] HCO3_array_o[i] = pl1[2] HCO3_array_p[i] = pl1[17] co2_aq_p[i] = pl1[18] omega_o[i] = pl1[6] omega_p[i] = pl1[13] Tsurf_array[i] = pl1[7] Tdeep_array[i] = pl1[8] Fd_array[i] = pl1[9] Fs_array[i] = pl1[10] Precip_ocean_array[i] = pl1[11] Precip_pore_array[i] = pl1[12] carbw_ar[i] = pl1[15] volc_array[i] = pl1[14] spread_ar[i] = pl1[26] T_pore_space_ar[i] = pl1[27] max_el = numpy.size(time) - 1 #number of elements in time array tstep = numpy.max(time) / max_el #time step (yrs) in time array # calculate mass imbalance flux_bal = numpy.sum(volc_array[2:] + carbw_ar[2:]) * tstep - numpy.sum( Precip_ocean_array[2:] + Precip_pore_array[2:] ) * tstep # integral of carbon inputs minus outpus over all timesteps res_change = 1.8e20 * (CO2_array_o[max_el] - CO2_array_o[2]) + Mo * ( HCO3_array_o[max_el] + CO3_array_o[max_el] + co2_aq_o[max_el] - co2_aq_o[2] - CO3_array_o[2] - HCO3_array_o[2] ) + Mp * ( HCO3_array_p[max_el] + CO3_array_p[max_el] + co2_aq_p[max_el] - co2_aq_p[2] - CO3_array_p[2] - HCO3_array_p[2] ) # final - initial carbon abundances (starting at second element to avoid transients) res_change2 = (out[max_el, 0] - out[2, 0]) * Mo + ( out[max_el, 2] - out[2, 2] ) * Mp # alternative way of calculating final - initial carbon abundances imbalance = (flux_bal - res_change) / ( out[max_el, 0] * Mo ) # difference between integrated flux balance and final-initial abundances (should be zero). # return selected carbon cycle outputs to main_code_parallel.py return [ out[:, 0], out[:, 1], out[:, 2], out[:, 3], time, pH_array_o, CO2_array_o, pH_array_p, CO2_array_p, Ca_array_o, Ca_array_p, CO3_array_o, CO3_array_p, HCO3_array_o, HCO3_array_p, omega_o, omega_p, Tsurf_array, Tdeep_array, Fd_array, Fs_array, Precip_ocean_array, Precip_pore_array, spread_ar, volc_array, T_pore_space_ar ], imbalance