def graph_points(): """ Given a few points, makes a smooth curve :return: saves a file with the graph """ fig_name = 'lect2_num_solv' # given data x = np.array([0.0, 0.4, 0.6, 0.8]) ra = np.array([0.01, 0.0080, 0.005, 0.002]) design_eq = np.divide(2.0, ra) print("Generic example design equation points: {}".format( ["{:0.1f}".format(x) for x in design_eq])) # cubic spline x_new = np.linspace(0.0, 0.8, 101) # alternately, from interpolation y_interp = interpolate.interp1d(x, design_eq, kind='quadratic') make_fig( fig_name, x, design_eq, ls1='o', x2_array=x_new, y2_array=y_interp(x_new), x_label=r'conversion (X, unitless)', y_label=r'$\displaystyle\frac{F_{A0}}{-r_A} \left(L\right)$', x_lima=0.0, x_limb=0.8, y_lima=0.0, y_limb=1000, fig_width=4, color2='green', )
def graph_int(): """ Given a simple algebraic equation, makes a graph """ fig_name = 'lect3_frac_energy_at_least' # x-axis temp_start = 0.001 # initial temp in K temp_end = 1200.0 # final temp in K num_steps = 2001 # for solving/graphing temp_range = np.linspace(temp_start, temp_end, num_steps) # y-axis ea = 4.0 frac_e_approx = eq_3_23(temp_range, ea) frac_e_anal = eq_3_20integrated(temp_range, ea) make_fig( fig_name, temp_range, frac_e_anal, y1_label="analytical", y2_array=frac_e_approx, y2_label="approximate", color2="red", x_label=r'temperature (K)', y_label=r'fraction with E $>$ E$_A = 4.0$', x_lima=0.0, x_limb=temp_end, y_lima=0.0, y_limb=1.0, fig_width=8, fig_height=4, )
def graph_alg_eq(): """ Given a simple algebraic equation, makes a graph """ fig_name = 'lect2_hippo' # x-axis x_start = 0.0 # initial conversion x_end = 0.999 # final conversion; didn't choose 1 to avoid divide by zero error num_steps = 2001 # for solving/graphing conversion_scale = np.linspace(x_start, x_end, num_steps) # y-axis design_eq = np.divide((1.00 + 16.5 * (1.00 - conversion_scale)), 1.75 * (1 - conversion_scale)) make_fig( fig_name, conversion_scale, design_eq, x_label=r'conversion (X, unitless)', y_label=r'$\displaystyle\frac{C_{F0}}{-r_F}$ (hr)', x_lima=0.0, x_limb=1.0, y_lima=0.0, y_limb=24.0, )
def solve_ode(): """ Solve single ODE """ fig_name = "lect4" k = 0.2 # L/mol s k_c = 20.0 # L/mol cao = 0.2 # mol/L x0 = 0.0 # initial conversion t_start = 0.0 t_end = 60.0 time = np.linspace(t_start, t_end, 1001) # seconds conv = odeint(ode, x0, time, args=(k, k_c, cao)) # here, need to add the additional argument of "t" because of how "ode" was set up for "odeint" x_eq = fsolve(ode, 0.5, args=(t_end, k, k_c, cao)) make_fig( fig_name + "_conversion", time, conv, x_label=r'time (s)', y_label=r'conversion (unitless)', y1_label=r'X(t)', x2_array=[t_start, t_end], y2_array=[x_eq, x_eq], y2_label=r'X$_{eq}$', x_lima=0.0, x_limb=t_end, y_lima=0.0, y_limb=1.0, fig_width=8, fig_height=4, ) c_a = cao * (1.0 - conv) c_b = cao * conv * 0.5 make_fig( fig_name + "_concentration", time, c_a, y1_label="A", y2_array=c_b, y2_label="B", color2="red", x_label=r'time (s)', y_label=r'concentration (mol/L)', x_lima=0.0, x_limb=t_end, y_lima=0.0, y_limb=cao, fig_width=8, fig_height=4, )
def solve_ode_sys(): # initial values fa0 = 5.0 fb0 = 0.0 c0 = 0.0 p0 = 1.0 # "y" is our system of equations (a vector). "y0" are the initial values. I'm listing "X" first and "p" second y0 = [fa0, fb0, c0, p0] ka = 2.0 keq = 0.004 kc = 8.0 cto = 0.2 fto = 5.0 alpha = 0.015 # Give an initial weight through a final weight. We don't know the final weight needed yet; if we guess # too small and we don't get the conversion we want, we can always increase it and run the program again x_min = 0 x_max = 30.0 w_cat = np.linspace(x_min, x_max, 1001) sol = odeint(sys_odes, y0, w_cat, args=(ka, keq, kc, alpha, cto, fto)) a_w = sol[:, 0] b_w = sol[:, 1] c_w = sol[:, 2] p_w = sol[:, 3] name = 'lecture_9' make_fig(name + "flows", w_cat, a_w, y1_label="$F_A$(W)", y2_array=b_w, y2_label="$F_B$(W)", y3_array=c_w, y3_label="$F_C$(W)", x_label="catalyst mass (kg)", y_label="molar flow rates (mol/s)", x_lima=x_min, x_limb=x_max, y_lima=None, y_limb=None, loc=7) make_fig(name + "p", w_cat, p_w, x_label="catalyst mass (kg)", y_label="pressure ratio, p (unitless)", x_lima=x_min, x_limb=x_max, y_lima=0.0, y_limb=1.0, loc=7)
def prob1a(): """ Given a few points, makes a line :return: nothing--saves a file with the graph """ cao = 0.2 # mol / L nuo = 10.0 # L / s k_equil = 20.0 # L / mol k = 0.2 # L / mol s fao = cao * nuo vol = 600.0 # L tau = vol / nuo # s # x_in = 0.0 # x_out = 0.65 x_in = np.zeros(4) x_out = np.empty(4) print(x_in) x_begin = 0.0 x_end = 0.65 x_cstr = np.array([x_begin, x_end]) x_pfr = np.linspace(x_end, x_end, 10001) neg_ra = r_dis_a(k, cao, x_pfr, k_equil) leven_cstr = np.empty(2) leven_cstr.fill(fao / neg_ra[-1]) leven_pfr = fao / neg_ra fig_name = 'lect06_alt' volume_limit = 2000 make_fig( fig_name, x_pfr, leven_pfr, x_label=r'conversion (X, unitless)', y_label=r'$\displaystyle\frac{F_{A0}}{-r_A} \left(L\right)$', x_lima=0.0, x_limb=0.65, y_lima=0.0, y_limb=volume_limit, color1="black", x_fill=x_cstr, y_fill=leven_cstr, x2_fill=x_pfr, y2_fill=leven_pfr, # fill1_label="CSTR", fill2_label="PFR", ) print("yo")
def graph_smooth_from_pts(): """ Given a few points, interpolates a smooth curve :return: saves a file with the graph """ fig_name = 'lect2_isom' # given data x = np.array([0.0, 0.2, 0.4, 0.6, 0.65]) ra = np.array([39.0, 53.0, 59.0, 38.0, 25.0]) design_eq = np.divide(50.0, ra) print("Isom example design equation points: {}".format(design_eq)) # cubic spline tck = interpolate.splrep(x, design_eq, s=0) x_new = np.linspace(0.0, 0.7, 101) y_new = interpolate.splev(x_new, tck, der=0) # alternately, from interpolation cubic_interp = interpolate.interp1d(x, design_eq, kind='quadratic', fill_value="extrapolate") make_fig( fig_name, x, design_eq, ls1='o', x2_array=x_new, y2_array=y_new, x3_array=x_new, y3_array=cubic_interp(x_new), y1_label="data", y2_label="quadratic", y3_label="cubic", x_label=r'conversion (X, unitless)', y_label=r'$\displaystyle\frac{F_{A0}}{-r_A} \left(m^3\right)$', x_lima=0.0, x_limb=0.7, y_lima=0.0, y_limb=2.5, )
def graph_alg_eq(): """ Given a simple algebraic equation, makes a graph """ fig_name = 'lect3_frac_energy' # x-axis e_start = 0.00 # initial energy e_end = 10.0 # final energy num_steps = 2001 # for solving/graphing energy_range = np.linspace(e_start, e_end, num_steps) temps = [300.0, 450.0, 600.0, 750.0, 1000.0] # y-axis frac_e = [] for temp in temps: frac_e.append(eq_3_20(energy_range, temp)) make_fig( fig_name, energy_range, frac_e[0], y1_label=str(temps[0]), y2_array=frac_e[1], y2_label=str(temps[1]), y3_array=frac_e[2], y3_label=str(temps[2]), y4_array=frac_e[3], y4_label=str(temps[3]), y5_array=frac_e[4], y5_label=str(temps[4]), x_label=r'energy (kcal/mol)', y_label='fraction with E at temp in K', x_lima=0.0, x_limb=e_end, y_lima=0.0, y_limb=1.0, fig_width=8, fig_height=4, ) x_fill = np.linspace(4.0, 60.0) y_fill = eq_3_20(x_fill, 600.0) y2_fill = eq_3_20(x_fill, 1000.0) make_fig( fig_name + "fill", energy_range, frac_e[2], y1_label=str(temps[2]), color1="green", y2_array=frac_e[4], y2_label=str(temps[4]), color2="purple", x_label=r'energy (kcal/mol)', y_label='fraction with E at temp in K', x_lima=e_start, x_limb=e_end, y_lima=0.0, y_limb=0.5, fig_width=8, fig_height=4, x_fill=x_fill, y_fill=y_fill, x2_fill=x_fill, y2_fill=y2_fill, )
def graph_alg_eq(): """ Given a simple algebraic equation, makes a graph """ fig_name = 'lect8_cstrs_series' # x-axis x_start = 0.00 # initial conversion x_end = 0.8 # final conversion num_steps = 2001 # for solving/graphing x_range = np.linspace(x_start, x_end, num_steps) vol = 50.0 # L nu = 4.0 # L/s tau = vol / nu # s k = 0.0281 # min^-1 cao = 1.0 # mol/L volume = get_volume(cao, nu, k, x_range) x = {} for reactor in range(0, 5): x[reactor] = 1 - 1.0 / np.power(1. + tau * k, reactor) print("After reactor {}, the conversion is {:.2f}".format( reactor, x[reactor])) x_fill = {} y_fill = {} for reactor in range(1, 5): x_fill[reactor] = [x[reactor - 1], x[reactor]] vol = get_volume(cao, nu, k, x[reactor]) y_fill[reactor] = [vol, vol] make_fig( fig_name, x_range, volume, # x_range, volume, x_label=r'conversion (X, unitless)', y_label=r'$\frac{F_{A0}}{-r_A}$ (L)', x_lima=0.0, x_limb=0.5, y_lima=0.0, y_limb=600.0, fig_width=6, fig_height=4, x_fill=x_fill[1], y_fill=y_fill[1], x2_fill=x_fill[2], y2_fill=y_fill[2], ) fao = cao * nu fa1 = cao * (1 - x[1]) * nu print(fao, fa1, (fao - fa1) / fao) make_fig( fig_name + "1", x_range, volume, # x_range, volume, x_label=r'conversion (X, unitless)', y_label=r'$\frac{F_{A0}}{-r_A}$ (L)', x_lima=0.0, x_limb=0.5, y_lima=0.0, y_limb=600.0, fig_width=6, fig_height=4, x_fill=x_fill[1], y_fill=y_fill[1], # x2_fill=x_fill[2], y2_fill=y_fill[2], ) ca1 = cao * (1 - x[1]) volume = get_volume(ca1, nu, k, x_range) reactor = 1 print(x[reactor]) x_fill[reactor] = [x[reactor - 1], x[reactor]] vol = get_volume(ca1, nu, k, x[reactor]) y_fill[reactor] = [vol, vol] make_fig( fig_name + "2", x_range, volume, # x_range, volume, x_label=r'conversion (X, unitless)', y_label=r'$\frac{F_{A1}}{-r_A}$ (L)', x_lima=0.0, x_limb=0.5, y_lima=0.0, y_limb=600.0, fig_width=6, fig_height=4, # x_fill=x_fill[1], y_fill=y_fill[1], x2_fill=x_fill[1], y2_fill=y_fill[1], )
def solve_ode(): """ Solve single ODE """ fig_name = "lect5" k = 0.2 # L/mol s k_c = 20.0 # L/mol cao = 0.2 # mol/L x0 = 0.0 # initial conversion nu_0 = 1.0 # L / s v_start = 0.0 v_end = 60.0 volume = np.linspace(v_start, v_end, 1001) # L conv = odeint(ode, x0, volume, args=(k, k_c, cao, nu_0)) conv_liq = odeint(ode, x0, volume, args=(k, k_c, cao, nu_0, False)) # here, need to add the additional argument of "t" because of how "ode" was set up for "odeint" x_eq = fsolve(ode, 0.5, args=(v_end, k, k_c, cao, nu_0)) x_eq_liq = fsolve(ode, 0.5, args=(v_end, k, k_c, cao, nu_0, False)) make_fig( fig_name + "_conversion", volume, conv, x_label=r'volume (L)', y_label=r'conversion (unitless)', y1_label=r'X(V)', x2_array=[v_start, v_end], y2_array=[x_eq, x_eq], y2_label=r'X$_{eq}$', x_lima=0.0, x_limb=v_end, y_lima=0.0, y_limb=1.0, fig_width=8, fig_height=4, ) make_fig( fig_name + "_conversion_liq", volume, conv_liq, x_label=r'volume (L)', y_label=r'conversion (unitless)', y1_label=r'X(V)', x2_array=[v_start, v_end], y2_array=[x_eq_liq, x_eq_liq], y2_label=r'X$_{eq}$', x_lima=0.0, x_limb=v_end, y_lima=0.0, y_limb=1.0, fig_width=8, fig_height=4, ) vol_change = 1.0 - 0.5 * conv c_a_no_vol = cao * (1.0 - conv_liq) c_b_no_vol = cao * conv_liq * 0.5 c_a = cao * (1.0 - conv) / vol_change c_b = cao * conv * 0.5 / vol_change make_fig( fig_name + "_concentration", volume, c_a, y1_label="A", y2_array=c_b, y2_label="B", color2="red", x_label=r'volume (L)', y_label=r'concentration (mol/L)', x_lima=0.0, x_limb=v_end, y_lima=0.0, y_limb=cao, fig_width=8, fig_height=4, ) make_fig( fig_name + "_concentration_liq", volume, c_a_no_vol, y1_label="A", y2_array=c_b_no_vol, y2_label="B", color2="red", x_label=r'volume (L)', y_label=r'concentration (mol/L)', x_lima=0.0, x_limb=v_end, y_lima=0.0, y_limb=cao, fig_width=8, fig_height=4, ) conv_2 = odeint(ode, x0, volume, args=(k, k_c, cao, nu_0 * 0.5)) conv_3 = odeint(ode, x0, volume, args=(k, k_c, cao, nu_0 * 2.0)) make_fig( fig_name + "_clicker", volume, conv, x_label=r'volume (L)', y_label=r'conversion (unitless)', y1_label=r'A) No change', y2_array=conv * 2.0, y2_label=r'B) ', y3_array=conv * 0.5, y3_label=r'C) ', y4_array=conv_2, y4_label=r'D) ', y5_array=conv_3, y5_label=r'E) ', x_lima=0.0, x_limb=v_end, y_lima=0.0, y_limb=1.0, fig_width=8, fig_height=4, ) x_leven = np.linspace(0.0, 0.7, 1001) # conversion, unitless y2 = 1.0 / ode(x_leven, 1.0, k, k_c, cao, nu_0) # eps = -0.5 # y_leven = nu_0 * k_c/k * np.square(1 + eps * x_leven) / (2 * k_c * cao * np.square(1-x_leven) - # x_leven * (1 + eps * x_leven)) make_fig( fig_name + "_levenspiel", x_leven, y2, x_label=r'conversion (unitless)', y_label=r'$\frac{-F_{A0}}{r_A}$ (L)', y_lima=0.0, y_limb=150, x_lima=0.0, x_limb=0.8, fig_width=8, fig_height=4, )
def solve_original_semibatch(): # initial values xb_parts = [] name = 'lect_11_semibatch' # Give an initial independent variable through a final one. We don't know the final needed yet; if we guess # too small and we don't get the conversion we want, we can always increase it and run the program again t_min = 0 t_max = 400.0 time = np.linspace(t_min, t_max, 1001) for part_id, part in enumerate([A, B, C]): if part == A: vol_0 = 5. # L cb_0 = 0.05 # mol/L ca_0 = 0.0 ca_in = 0.025 # mol/L nu_in = 0.05 # L/s elif part == B: vol_0 = 15. # vol in L na_0 = 0.25 # mol nb_0 = 0.25 # mol ca_0 = na_0 / vol_0 cb_0 = nb_0 / vol_0 nu_in = 0.0 ca_in = 0.0 else: vol_0 = 10. # L cb_0 = 0.025 # mol/L ca_0 = 0.0 ca_in = 0.05 # mol/L nu_in = 0.05 # L/s if part == A: # show that both methods yield the same solution c_initial_all = [ca_0, cb_0, 0., 0.] # def sys_odes_ca(y_vector, time, vol_0, nu_in, ca_in): sol = odeint(sys_odes_ca, c_initial_all, time, args=(vol_0, nu_in, ca_in)) ca = sol[:, 0] cb = sol[:, 1] cc = sol[:, 2] cd = sol[:, 3] make_fig( name + "_ca" + part, time, ca, y1_label="$C_A$", y2_array=cb, y2_label="$C_B$", y3_array=cc, y3_label="$C_C$", y4_array=cd, y4_label="$C_D$", x_label="time (s)", y_label="concentration (mol/L)", x_lima=t_min, x_limb=t_max, y_lima=0.0, y_limb=1.0, ) # def sys_odes_na(y_vector, time, vol_0, nu_in, ca_in): na_0 = ca_0 * vol_0 nb_0 = cb_0 * vol_0 na_initial_all = [na_0, nb_0, 0., 0.] sol = odeint(sys_odes_na, na_initial_all, time, args=(vol_0, nu_in, ca_in)) na = sol[:, 0] nb = sol[:, 1] nc = sol[:, 2] nd = sol[:, 3] vol = vol_0 + nu_in * time ca = na / vol cb = nb / vol cc = nc / vol cd = nd / vol make_fig(name + "_na" + part, time, ca, y1_label="$C_A$", y2_array=cb, y2_label="$C_B$", y3_array=cc, y3_label="$C_C$", y4_array=cd, y4_label="$C_D$", x_label="time (s)", y_label="concentration (mol/L)", x_lima=t_min, x_limb=t_max, y_lima=0.0, y_limb=1.00) print("Part {}, na_in = {:.2f} moles, nb_in = {:.2f}".format( part, na_0, nb_0)) xb_parts.append((nb_0 - nb) / nb_0) vol_15_index = np.nonzero(np.abs(vol - 15.0) < 0.000001) print( " time at s the conversion of B at V = 15 L, which corresponds to time = {} s, " "and X_B = {:.2f}".format(time[vol_15_index], xb_parts[part_id][500])) make_fig( name + "_x", time, xb_parts[0], y1_label="$X_B$ original semibatch, $C_{B0} > C_{A_{in}}$", y2_array=xb_parts[1], y2_label="$X_B$ batch", color2="red", y3_array=xb_parts[2], y3_label="$X_B$ semibatch, $C_{B0} < C_{A_{in}}$", x_label="time (s)", y_label="conversion of B (unitless)", x_lima=t_min, x_limb=t_max, y_lima=0.0, y_limb=1.00, )