del_H_cat, del_S_cat) #### Shipping return h**o, cat, nu_homo_index, nu_cat_index if __name__ == '__main__': import constants react_system = 'OCM_two_reaction.txt' catalyst = 'La_Ce' homo_basis = 'mole_fraction' cat_basis = 'mole_fraction' const, thermo_object = constants.fixed_parameters(react_system) h**o, cat, \ homo_index, cat_index = instantiate(react_system, const, catalyst) print(h**o.n_r) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print(species_ID) inlet_species = 'CH4' inlet_ratio = 4 F_A_in = inlet_ratio / (inlet_ratio + 1) F_B_in = 1 / (inlet_ratio + 1)
def bif_dia_solver(fixed_dict, bif_par_dict, react_system, system, catalyst, rate_basis, rate_units, inlet_species, break_val, step_change, max_val, options): ''' This function solves for the bifurcation diagram. fixed_dict= Dictionary of fixed variables and values. bif_par_dict= Dictionary of Bifurcation variable and value. react_system= Describes the reaction system chosen, e.g: 'OCM_three_reaction.txt'. system= Whether the system is catalytic only, homogeneous only, or homogeneous-heterogeneous coupled. inlet_species= The hydrocarbon species, as of now just hydrocarbon and O2 is taken as inlet. break_val= break value of the bifurcation parameter. step_change= step_change value of the bifurcation parameter, necessary in Pseudo-Arc Length Continuation. max_val= maximum value of the bifurcation parameter. options= Solver Options. ''' #### Constant parameters involved with the system const, thermo_object = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print(species_ID) #### Manipulation of input variables all_dict = dict(fixed_dict, **bif_par_dict) bif_par_var = list(bif_par_dict.keys())[0] bif_par_val = bif_par_dict.get(bif_par_var) #### Initial guess inlet_ratio = all_dict['inlet_ratio'] N2 = 0 # For the time being, we use pure O2 F_A_in = inlet_ratio / (N2 + inlet_ratio + 1) F_B_in = 1 / (N2 + inlet_ratio + 1) F_in = 1e-08 * np.ones(no_of_species) A_index = species_ID[inlet_species] B_index = species_ID['O2'] F_in[A_index] = F_A_in F_in[B_index] = F_B_in state_var_val = np.r_[F_in, F_in, all_dict['T_f_in'], all_dict['T_f_in'], bif_par_val] #### Generating the reaction data h**o, cat, homo_index, cat_index = react.instantiate( react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] #### Function name func = bif_dia_func jac = bif_dia_jacobian if options['Testing']: #### Just testing the function(s) Ysol = func(state_var_val, bif_par_val, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, 0) return Ysol else: if options['continuation'] == 'arc_length': raise Exception( 'This is not the correct solver to solve the problem') else: #### Solving for the bifurcation diagram iter_count = 0 _run = True rand_count = 0 while (_run): _run = False #### First Intial Guess while (True): if (iter_count != 0): rand_count += 1 print(rand_count) if (rand_count == 1): print( 'Working on generating the next initial guess') ### Guessing the initial point through random number generation T_s = np.random.randint(T_bd[-3, -1], 3000) T_f = np.random.randint(T_bd[-2, -1], T_s) state_var_val = np.r_[1e-01 * np.ones(2 * no_of_species), T_s, T_s] bif_par_val = break_val # while(True): # #### Generating the new initial guess after the break point # print('The last solution point is:\n{}'.format(T_bd[:,-1])) # # state_var_str = (input('Enter an initial guess close to this first point ' # '[comma-separeted]: ')).split(',') # state_var_list = [] # for elem in state_var_str: # try: # elem_float = float(elem) # except ValueError: # print('Enter a valid float-type data input') # else: # state_var_list.append(elem_float) # # if len(state_var_list) == (2*no_of_species + 2): # state_var_val = np.array(state_var_list) # #### Checking the validity of the input # if (any(state_var_val < 0)) or (state_var_val[-1] < T_bd[-2, -1]): # print('Enter a valid input') # else: # bif_par_val -= step_change # break ### Solving with first initial guess sol0 = root(func, state_var_val, args=(bif_par_val, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units)) act_sol = sol0.x #### Checking the validity of the solution if (iter_count != 0): delta = func(act_sol, bif_par_val, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units) if any(act_sol < 0) or any(act_sol.imag != 0) or any( abs(delta) > 1e-03): print( 'Didn\'t get a perfect solution, trying again!!!' ) elif (abs(act_sol[-1] - bif_par_val) <= 1): print('Oops!!! Got the first point, trying again.') # elif (abs(act_sol[-1] - T_bd[-2,-1]) <= 5): # print('Got the previous point, trying again.') else: print('The last solution point is:\n{}'.format( T_bd[:, -1])) sol_check = input( 'Do you think this is the solution: \n{}'. format(act_sol)) else: sol_check = 'y' if (sol_check == 'y'): iter_count += 1 sol_check = 'n' Y0 = np.r_[act_sol, bif_par_val] try: T_bd = np.c_[T_bd, Y0[:]] except NameError: T_bd = Y0[:] finally: break print('We got the first point, moving on now!') #### Second initial guess bif_par_val += step_change ### Solving with second initial guess sol0 = root(func, state_var_val, args=(bif_par_val, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units)) act_sol = sol0.x print('We got the second point too') iter_count += 1 Y1 = np.r_[act_sol, bif_par_val] T_bd = np.c_[T_bd, Y1[:]] # print(T_bd) #### Calculation of the suitable delta_s value if bif_par_var == 'tau': plot_flag = 'log' delta_s = np.log10(Y1[-1] / Y0[-1]) else: plot_flag = 'norm' delta_s = np.linalg.norm(Y1 - Y0) #### Continuation method while (Y1[-1] <= max_val): print(Y1[-1]) iter_count += 1 Y_guess = 2 * Y1 - Y0 delta_s = np.linalg.norm(Y1 - Y0) sol2 = root(func, Y_guess, args=(Y1, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, delta_s)) Y2 = sol2.x T_bd = np.c_[T_bd, Y2] Y0[:] = Y1[:] Y1[:] = Y2[:] if (Y1[-1] < break_val): print('Extinction point is lower than the ' 'break point ({}).'.format(break_val)) while (True): A = input( 'Do you want to start the calculation ' 'with a different initial guess [y/n]?: ') if (A.lower() == 'y') or (A.lower() == 'n'): break else: print('Enter \'y\' for a yes and \'n\' for a ' 'no, no other input will be considered') if (A.lower() == 'y'): _run = True break #### Plotting the figure fig = plt.figure() if plot_flag == 'log': plt.semilogx(T_bd[-1, :], T_bd[-2, :]) else: plt.plot(T_bd[-1, :], T_bd[-2, :]) plt.show #### Storing data data_vals = [value for (key, value) in sorted(fixed_dict.items())] n = len(data_vals) filename = 'bif_dia' for i in range(n): filename += '_{}'.format(data_vals[i]) print(filename) if options['save']: #### Saving Data react_filename, ext = os.path.splitext(react_system) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Data', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower() + '/' \ + '/Data/' + system os.makedirs(New_Folder) FullfileName = os.path.join(Target_folder, filename) np.savez(FullfileName, T_bd, Y_in, species_ID) #### Saving Diagrams (Why I don't know) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Diagram', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower() + '/' \ + '/Diagram/' + system os.makedirs(New_Folder) dia_filename = filename + '.png' FullfileName = os.path.join(Target_folder, dia_filename) fig.savefig(FullfileName) #### Returning the final result return T_bd
def bif_set_solver(fixed_dict, bif_par_dict, react_system, system, catalyst, rate_basis, rate_units, inlet_species, break_dict, step_change, max_val, options): ''' This function solves for the bifurcation set (or ignition-extinction locus) The significance of different arguments are same as that of the bif_dia_solver. ''' # Constant parameters involved with the system const = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) # Manipulation of input variables all_dict = dict(fixed_dict, **bif_par_dict) bif_par_var = list(bif_par_dict.keys())[0] bif_par_val = bif_par_dict.get(bif_par_var) # Generating the reaction data h**o, cat, homo_index, cat_index = react.instantiate( react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] # First Dataset npzfile = _load_file(react_system, system, catalyst, all_dict) T_bd_arr, Y_in_arr, species_ID_arr = npzfile.files T_bd_0 = npzfile[T_bd_arr] index_0 = ig_ext_point_calculator(T_bd_0, system, 'T_f_in', break_dict, fulloutput=True) # Second Dataset all_dict[bif_par_var] += step_change npzfile = _load_file(react_system, system, catalyst, all_dict) T_bd_arr, Y_in_arr, species_ID_arr = npzfile.files T_bd_1 = npzfile[T_bd_arr] index_1 = ig_ext_point_calculator(T_bd_1, system, 'T_f_in', break_dict, fulloutput=True) # Function names func = bif_set_func # jac = bif_set_jacobian # Solving for ignition-extinction locus # First Ignition y0 = np.zeros(2 * (no_of_species + 1)) y0[1] = 1 x0 = T_bd_0[:, index_0[0]] x_init = np.r_[y0, x0] J_0 = func(x_init, bif_par_val, inlet_species, fixed_dict, const, react_const, system, rate_basis, rate_units, get_jacobian=True) y_sol_0 = root(null_space, y0, args=J_0, method='lm') X_init_0 = np.r_[y_sol_0.x, x0] sol0 = root(func, X_init_0, args=(bif_par_val, inlet_species, fixed_dict, const, react_const, system, rate_basis, rate_units)) Y0 = np.r_[sol0.x, bif_par_val] T_bs = Y0[:] # Second solution bif_par_val += step_change x1 = T_bd_1[:, index_1[0]] x_init = np.r_[y0, x1] J_1 = func(x_init, bif_par_val, inlet_species, fixed_dict, const, react_const, system, rate_basis, rate_units, get_jacobian=True) y_sol_1 = root(null_space, y0, args=J_1, method='lm') X_init_1 = np.r_[y_sol_1.x, x1] sol1 = root(func, X_init_1, args=(bif_par_val, inlet_species, fixed_dict, const, react_const, system, rate_basis, rate_units)) Y1 = np.r_[sol1.x, bif_par_val] T_bs = np.c_[T_bs, Y1[:]] plot_flag = 'norm' delta_s = np.linalg.norm(Y1 - Y0) # Continuation method while (Y1[-1] <= max_val and Y1[-1] >= break_dict[bif_par_var] and Y1[-2] >= break_dict['T_f_in']): print(Y1[-1]) Y_guess = 2 * Y1 - Y0 sol2 = root(func, Y_guess, args=(Y1, inlet_species, fixed_dict, const, react_const, system, rate_basis, rate_units, delta_s)) Y2 = sol2.x T_bs = np.c_[T_bs, Y2] Y0[:] = Y1[:] Y1[:] = Y2[:] #### Plotting the figure fig = plt.figure() if plot_flag == 'log': plt.semilogx(T_bs[-1, :], T_bs[-2, :]) else: plt.plot(T_bs[-1, :], T_bs[-2, :]) plt.show #### Storing data data_vals = [value for (key, value) in sorted(fixed_dict.items())] n = len(data_vals) filename = 'bif_set' for i in range(n): filename += '_{}'.format(data_vals[i]) print(filename) if options['save']: #### Saving Data react_filename, ext = os.path.splitext(react_system) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Data', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower( ) + '/' + '/Data/' + system os.makedirs(New_Folder) FullfileName = os.path.join(Target_folder, filename) np.savez(FullfileName, T_bs, Y_in, species_ID) #### Saving Diagrams (Why I don't know) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Diagram', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower( ) + '/' + '/Diagram/' + system os.makedirs(New_Folder) dia_filename = filename + '.png' FullfileName = os.path.join(Target_folder, dia_filename) fig.savefig(FullfileName) #### Returning the final result return T_bs
def low_D_Sh_phi_solver(fixed_dict, T_f_in_span, tspan, react_system, system, catalyst, rate_basis, rate_units, inlet_species, n, nT, options): ''' This function solves the low_D_Sh_phi function to generate the conversion vs Temperature curve. fixed_dict : Dictionary of fixed variables and values. T_f_in_span : Span of inlet temperature react_system : Name of the reaction system system : Whether the system is 'cat'-alytic, 'coup'-led, or 'h**o'-geneous catalyst : Name of the catalyst used rate_basis : Basis of the rate expressions, whether pressure, concentration, mole fraction rate_units : Units of the rate expressions inlet_species : Name of the fuel, e.g. 'CH4' n : No of discretized points in x options : Some options, like whether to save the result, or just to test the model. ''' #### Constant parameters involved with the system const, thermo_object = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print(species_ID) #### Generating the reaction objects h**o, cat, homo_index, cat_index = react.instantiate(react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] inlet_ratio = fixed_dict['inlet_ratio'] y_A_in = inlet_ratio/(inlet_ratio + 1) y_B_in = 1/(inlet_ratio + 1) #### Function names func = low_D_Sh_phi T_f_in = np.linspace(T_f_in_span[0], T_f_in_span[1], nT) conv_A = np.zeros_like(T_f_in) conv_B = np.zeros_like(T_f_in) if options['model'] is 'both': conv_A_inf = np.zeros_like(T_f_in) conv_B_inf = np.zeros_like(T_f_in) for i in range(len(T_f_in)): #### Inlet values c_A_in = y_A_in * 101325 * fixed_dict['pressure']/(8.314 * T_f_in[i]) c_B_in = y_B_in * 101325 * fixed_dict['pressure']/(8.314 * T_f_in[i]) C_f_in = 1e-03 * np.ones(no_of_species) A_index = species_ID[inlet_species] B_index = species_ID['O2'] C_f_in[A_index] = c_A_in C_f_in[B_index] = c_B_in C_f_0 = np.tile(C_f_in, n) C_w_0 = np.tile(C_f_in, n) C_0 = np.r_[C_f_0, C_w_0] if options['model'] is not 'both': #### Calculating for only one model try: count = i + 1 print('Solving for T_f_in = {0} with {1} model' .format(T_f_in[i], options['model'])) Y = odeint(func, C_0, tspan, args=(inlet_species, fixed_dict, C_f_in, T_f_in[i], const, thermo_object, react_const, system, rate_basis, rate_units, options['model'])) except RuntimeWarning as e: msg = ('The concentration of one of the reactants is going ' 'close to zero, hence further calculations can result ' 'in inaccurate results.') temp = msg + 'Calculated till {}'.format(T_f_in[i-1]) print(temp) count = i break elif options['model'] is 'both': #### Comparing two models print('Solving for T_f_in = {0} with {1} model' .format(T_f_in[i], 'Sh_phi')) Y = odeint(func, C_0, tspan, args=(inlet_species, fixed_dict, C_f_in, T_f_in[i], const, thermo_object, react_const, system, rate_basis, rate_units, 'Sh_phi')) print('Solving for T_f_in = {0} with {1} model' .format(T_f_in[i], 'Sh_inf')) Y_inf = odeint(func, C_0, tspan, args=(inlet_species, fixed_dict, C_f_in, T_f_in[i], const, thermo_object, react_const, system, rate_basis, rate_units, 'Sh_inf')) #### Calculating the conversion for Sh_inf model C_f_ss_inf = Y_inf[-1, :no_of_species*n] C_f_ss_mat_inf = C_f_ss_inf.reshape((no_of_species, n), order='F') CH4_exit_inf = C_f_ss_mat_inf[A_index, -1] O2_exit_inf = C_f_ss_mat_inf[B_index, -1] conv_A_inf[i] = (1 - CH4_exit_inf/c_A_in) conv_B_inf[i] = (1 - O2_exit_inf/c_B_in) else: raise Exception ('No such model exists!!!') #### Conversion calculations C_f_ss = Y[-1, :no_of_species*n] C_f_ss_mat = C_f_ss.reshape((no_of_species, n), order='F') CH4_exit = C_f_ss_mat[A_index, -1] O2_exit = C_f_ss_mat[B_index, -1] conv_A[i] = (1 - CH4_exit/c_A_in) conv_B[i] = (1 - O2_exit/c_B_in) #### Some random plotting if options['model'] is not 'both': fig, ax = plt.subplots() ax.plot(T_f_in[:count], conv_A[:count], color='b', label='CH4 conv') ax.plot(T_f_in[:count], conv_B[:count], color='r', label='O2 conv') ax.legend(loc='best') ax.set_xlim([0, 1]) ax.set_ylim(T_f_in_span) ax.set_xlabel('Inlet Temperature, in K') ax.set_ylabel('Conversions') else: fig, ax = plt.subplots() ax.plot(T_f_in, conv_A, color='b', label=r'$\mathbf{Sh_\phi}$ model') ax.plot(T_f_in, conv_A_inf, color='r', label=r'$\mathbf{Sh_\infty}$ model') ax.legend(loc='best') ax.set_ylim([0, 1]) ax.set_xlim(T_f_in_span) ax.set_xlabel('Inlet Temperature, in K') ax.set_ylabel(r'Conversion of $\mathbf{CH_4}$') fig, ax1 = plt.subplots() ax1.plot(T_f_in, conv_B, color='b', label= r'$\mathbf{Sh_\phi}$ model') ax1.plot(T_f_in, conv_B_inf, color='r', label= r'$\mathbf{Sh_\infty}$ model') ax1.legend(loc='best') ax1.set_ylim([0, 1]) ax1.set_xlim(T_f_in_span) ax1.set_xlabel('Inlet Temperature, in K') ax1.set_ylabel(r'Conversion of $\mathbf{O_2}$') plt.show() return Y
def low_D_Sh_phi_solver(fixed_dict, T_f_in_span, tspan, react_system, system, catalyst, rate_basis, rate_units, inlet_species, nT, options): ''' We will write this thing later ''' #### Constant parameters involved with the system const, thermo_object = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print(species_ID) #### Generating the reaction objects h**o, cat, homo_index, cat_index = react.instantiate( react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] inlet_ratio = fixed_dict['inlet_ratio'] y_A_in = inlet_ratio / (inlet_ratio + 1) y_B_in = 1 / (inlet_ratio + 1) #### Function names func = zero_D_sh_phi T_f_in = np.linspace(T_f_in_span[0], T_f_in_span[1], nT) conv_A = np.zeros_like(T_f_in) conv_B = np.zeros_like(T_f_in) if options['model'] is 'both': conv_A_inf = np.zeros_like(T_f_in) conv_B_inf = np.zeros_like(T_f_in) for i in range(len(T_f_in)): #### Inlet values c_A_in = y_A_in * 101325 * fixed_dict['pressure'] / (8.314 * T_f_in[i]) c_B_in = y_B_in * 101325 * fixed_dict['pressure'] / (8.314 * T_f_in[i]) C_f_in = 1e-03 * np.ones(no_of_species) A_index = species_ID[inlet_species] B_index = species_ID['O2'] C_f_in[A_index] = c_A_in C_f_in[B_index] = c_B_in C_0 = np.r_[C_f_in, C_f_in] if options['model'] is not 'both': #### Calculating for only one model try: count = i + 1 print('Solving for T_f_in = {0} with {1} model'.format( T_f_in[i], options['model'])) Y = odeint(func, C_0, tspan, args=(inlet_species, fixed_dict, C_f_in, T_f_in[i], const, thermo_object, react_const, system, rate_basis, rate_units, options['model'])) except RuntimeWarning as e: msg = ('The concentration of one of the reactants is going ' 'close to zero, hence further calculations can result ' 'in inaccurate results.') temp = msg + 'Calculated till {}'.format(T_f_in[i - 1]) print(temp) count = i break elif options['model'] is 'both': #### Comparing two models print('Solving for T_f_in = {0} with {1} model'.format( T_f_in[i], 'Sh_phi')) Y = odeint(func, C_0, tspan, args=(inlet_species, fixed_dict, C_f_in, T_f_in[i], const, thermo_object, react_const, system, rate_basis, rate_units, 'Sh_phi')) print('Solving for T_f_in = {0} with {1} model'.format( T_f_in[i], 'Sh_inf')) Y_inf = odeint(func, C_0, tspan, args=(inlet_species, fixed_dict, C_f_in, T_f_in[i], const, thermo_object, react_const, system, rate_basis, rate_units, 'Sh_inf')) #### Calculating the conversion for Sh_inf model C_f_ss_inf = Y_inf[-1, :no_of_species] CH4_exit_inf = C_f_ss_inf[A_index, ] O2_exit_inf = C_f_ss_inf[B_index] conv_A_inf[i] = (1 - CH4_exit_inf / c_A_in) conv_B_inf[i] = (1 - O2_exit_inf / c_B_in) else: raise Exception('No such model exists!!!') #### Conversion calculations C_f_ss = Y[-1, :no_of_species] CH4_exit = C_f_ss[A_index] O2_exit = C_f_ss[B_index] conv_A[i] = (1 - CH4_exit / c_A_in) conv_B[i] = (1 - O2_exit / c_B_in) #### Some random plotting if options['model'] is not 'both': fig, ax = plt.subplots() ax.plot(T_f_in[:count], conv_A[:count], color='b', label='CH4 conv') ax.plot(T_f_in[:count], conv_B[:count], color='r', label='O2 conv') ax.legend(loc='best') ax.set_xlabel('Inlet Temperature, in K') ax.set_ylabel('Conversions') else: fig, ax = plt.subplots() ax.plot(T_f_in, conv_A, color='b', label='Sh(Phi)') ax.plot(T_f_in, conv_A_inf, color='r', label='Sh_inf') ax.legend(loc='best') ax.set_xlabel('Inlet Temperature, in K') ax.set_ylabel('Conversion of CH4') fig, ax1 = plt.subplots() ax1.plot(T_f_in, conv_B, color='b', label='Sh(Phi)') ax1.plot(T_f_in, conv_B_inf, color='r', label='Sh_inf') ax1.legend(loc='best') ax1.set_xlabel('Inlet Temperature, in K') ax1.set_ylabel('Conversion of O2') plt.show() return Y
def bif_dia_plot(fixed_dict, bif_par_var, react_system, system, catalyst, inlet_species, b_options, a_options): ''' This function will load the correct file in order to plot the different bifurcation diagrams.''' #### Specifying linestyles and colors lines = [':', '-', '--', ':', '-.'] no_of_lines = len(lines) units = { 'inlet_ratio': '', 'pressure': ' atm', 'tau': 's', 'R_omega': 'mm', 'R_omega_wc': r'$\mathbf{\mu m}$', 'particle_density': 'kg/m3' } symbol = { 'inlet_ratio': r'$\mathbf{CH_4/O_2}$', 'pressure': r'$\mathbf{P}$', 'tau': r'$\mathbf{\tau}$', 'R_omega': r'$\mathbf{R_\Omega}$', 'R_omega_wc': r'$\mathbf{R_{\Omega, wc}}$', 'particle_density': r'$\mathbf{\rho}$' } #### Identifying the variable with multiple inputs count = 0 multiple = False multiple_variable = 'inlet_ratio' for key, val in fixed_dict.items(): try: len(val) except TypeError: continue else: multiple = True multiple_variable = key break if multiple: values = fixed_dict[multiple_variable] else: values = [] values.append(fixed_dict[multiple_variable]) for val in values: count += 1 fixed_dict[multiple_variable] = val if multiple_variable == 'R_omega': fixed_dict[ 'R_omega_wc'] = fixed_dict['R_omega'] / 0.25e-03 * 100e-06 style_index = count % no_of_lines #### Retreiving the data from .npz file npzfile = _load_file(react_system, system, catalyst, fixed_dict) T_bd_arr, F_in_arr, species_ID_arr = npzfile.files T_bd = npzfile[T_bd_arr] F_in = npzfile[F_in_arr] species_ID = npzfile[species_ID_arr].item() n, m = T_bd.shape if multiple_variable == 'R_omega': label = (symbol[multiple_variable] + ' = ' + str(val * 1e03) + units[multiple_variable]) else: label = (symbol[multiple_variable] + ' = ' + str(val) + units[multiple_variable]) if b_options['basic_plot']: #### Retrieving the species_specific data from T_bd hc_index = species_ID[inlet_species] conv_hc = 1 - T_bd[hc_index, :] / F_in[hc_index] O2_index = species_ID['O2'] conv_O2 = 1 - T_bd[O2_index, :] / F_in[O2_index] #### Plotting Area plot_dict = b_options['plots'] if bif_par_var == 'tau': xplottype = 'log' x_axis = 'Residence Time (s)' else: xplottype = 'normal' x_axis = ('Inlet Fluid Temperature, ' + r'$\mathbf{T_{f,in}}$' + ' (K)') #### Exit Fluid Temperature vs Inlet Fluid Temperature if plot_dict['fluid_temp']: if count == 1: fig, ax1 = plt.subplots() fig.subplots_adjust(left=0.145, bottom=0.11) ax1.set_xlabel(x_axis) ax1.set_ylabel(('Exit Fluid Temperature, ' + r'$\mathbf{T_f}$' + ' (K)')) axis_limits = (b_options['xaxis_lim'] + b_options['yaxis_lim']) ax1.axis(axis_limits) if xplottype == 'log': ax1.semilogx(T_bd[-1, :], T_bd[-2, :], linestyle=lines[style_index], label=label) else: ax1.plot(T_bd[-1, :], T_bd[-2, :], linestyle=lines[style_index], label=label) ax1.legend(loc='lower right') plt.show() #### Solid Temperature vs Inlet Fluid Temperature if plot_dict['solid_temp']: if count == 1: fig, ax2 = plt.subplots() ax2.set_xlabel(x_axis, fontsize=14, fontweight='bold') ax2.set_ylabel(('Catalyst Surface Temperature ' + r'$\mathbf{T_s}$' + ' (K)')) axis_limits = (b_options['xaxis_lim'] + b_options['yaxis_lim']) ax2.axis(axis_limits) if xplottype == 'log': ax2.semilogx(T_bd[-1, :], T_bd[-3, :], linestyle=lines[style_index], label=label) else: ax2.plot(T_bd[-1, :], T_bd[-3, :], linestyle=lines[style_index], label=label) ax2.legend(loc='best') #### Conversion of Hydrocarbon and O2 if plot_dict['conversion']: if count == 1: fig31, ax31 = plt.subplots() fig32, ax32 = plt.subplots() axis_limits_CH4 = b_options['xaxis_lim'] + [0, 0.5] ax31.set_xlabel(x_axis) ax31.set_ylabel(('Conversion of ' + r'$\mathbf{CH_4}$')) ax31.axis(axis_limits_CH4) axis_limits = b_options['xaxis_lim'] + [0, 1] ax32.set_xlabel(x_axis) ax32.set_ylabel(('Conversion of ' + r'$\mathbf{O_2}$')) ax32.axis(axis_limits) if xplottype == 'log': ax31.semilogx(T_bd[-1, :], conv_hc, linestyle=lines[style_index], label=label) ax32.semilogx(T_bd[-1, :], conv_O2, linestyle=lines[style_index], label=label) else: ax31.plot(T_bd[-1, :], conv_hc, linestyle=lines[style_index], label=label) ax32.plot(T_bd[-1, :], conv_O2, linestyle=lines[style_index], label=label) ax31.legend(loc='best') ax32.legend(loc='best') #### Combined Selectivities and Yields if (plot_dict['select_comb'] or plot_dict['yield_comb']): elem_comb = ['CO', 'CO2', 'C2H6', 'C2H4', 'C2H2'] selectivity = [np.zeros(m)] * 5 select_dict = dict(zip(elem_comb, selectivity)) yield_dict = dict(zip(elem_comb, selectivity)) for elem in elem_comb: elem_index = species_ID.get(elem, None) carbon_no = species_identifier(elem) if (elem_index != None) and (carbon_no != 0): yield_elem = (T_bd[elem_index, :] - F_in[elem_index]) \ * carbon_no/F_in[hc_index] selectivity_elem = (T_bd[elem_index, :] - F_in[elem_index]) \ * carbon_no \ / (F_in[hc_index] - T_bd[hc_index, :]) select_dict[elem] = selectivity_elem yield_dict[elem] = yield_elem selectivity_COx = select_dict['CO'] + select_dict['CO2'] selectivity_C2 = select_dict['C2H6'] + select_dict['C2H4'] \ + select_dict['C2H2'] #selectivity_C2 = np.where(np.isnan(selectivity_C2), 0.0, selectivity_C2) #selectivity_C2 = np.where(np.isinf(selectivity_C2), 0.0, selectivity_C2) #selectivity_C2 = np.where(selectivity_C2 < 0.0, 0.0, selectivity_C2) #selectivity_C2 = np.where(selectivity_C2 > 1.0, 0.0, selectivity_C2) if fixed_dict['inlet_ratio'] == 4: selectivity_C2[: 1500] = 0.0 # Didn't find any better method, selectivity_COx[:1500] = 1.0 else: selectivity_C2[: 1000] = 0.0 # Didn't find any better method, selectivity_COx[:1000] = 1.0 if plot_dict['select_comb']: if (count == 1): fig61, ax6_sc1 = plt.subplots() fig62, ax6_sc2 = plt.subplots() axis_limits = b_options['xaxis_lim'] + [0, 1] ax6_sc1.set_xlabel(x_axis) ax6_sc1.set_ylabel(('Selectivity of (' + r'$\mathbf{CO + CO_{2}}$' + ')')) ax6_sc1.axis(axis_limits) ax6_sc2.set_xlabel(x_axis) ax6_sc2.set_ylabel( ('Selectivity of (' + r'$\mathbf{C_{2}H_{6} + C_{2}H_{4}}$' + ')')) ax6_sc2.axis(axis_limits) if xplottype == 'log': ax6_sc1.semilogx(T_bd[-1, :], selectivity_COx, linestyle=lines[style_index], label=label) ax6_sc2.semilogx(T_bd[-1, :], selectivity_C2, linestyle=lines[style_index], label=label) else: ax6_sc1.plot(T_bd[-1, :], selectivity_COx, linestyle=lines[style_index], label=label) ax6_sc2.plot(T_bd[-1, :], selectivity_C2, linestyle=lines[style_index], label=label) ax6_sc1.legend(loc='best') ax6_sc2.legend(loc='best') if plot_dict['yield_comb']: yield_COx = yield_dict['CO'] + yield_dict['CO2'] yield_C2 = yield_dict['C2H6'] + yield_dict['C2H4']\ + yield_dict['C2H2'] if (count == 1): fig71, ax7_yc1 = plt.subplots() fig71.subplots_adjust(left=0.145, bottom=0.11) fig72, ax7_yc2 = plt.subplots() fig72.subplots_adjust(left=0.145, bottom=0.11) axis_limits = b_options['xaxis_lim'] + [0, 0.3] ax7_yc1.set_xlabel(x_axis) ax7_yc1.set_ylabel( ('Yields of (' + r'$\mathbf{CO + CO_{2}}$' + ')')) ax7_yc1.axis(axis_limits) ax7_yc2.set_xlabel(x_axis) ax7_yc2.set_ylabel( ('Yield of (' + r'$\mathbf{C_{2}H_{6} + C_{2}H_{4}}$' + ')')) ax7_yc2.axis(axis_limits) if xplottype == 'log': ax7_yc1.semilogx(T_bd[-1, :], yield_COx, linestyle=lines[style_index], label=label) ax7_yc2.semilogx(T_bd[-1, :], yield_C2, linestyle=lines[style_index], label=label) else: ax7_yc1.plot(T_bd[-1, :], yield_COx, linestyle=lines[style_index], label=label) ax7_yc2.plot(T_bd[-1, :], yield_C2, linestyle=lines[style_index], label=label) ax7_yc1.legend(loc='best') ax7_yc2.legend(loc='best') #### Yields of all 'products', (Identifying the compound and then #### identifying limiting reactant is #### important, we will do it later) if plot_dict['yield_all']: products = b_options['products'] if products: fig4, ax4_y = plt.subplots() label = [] not_calc_elem = [] for elem in products: elem_index = species_ID.get(elem, None) carbon_no = species_identifier(elem) if (elem_index != None) and (carbon_no != 0): yield_elem = T_bd[elem_index, :] \ * carbon_no/F_in[hc_index] if xplottype == 'log': ax4_y.semilogx(T_bd[-1, :], yield_elem) else: ax4_y.plot(T_bd[-1, :], yield_elem) label.append(elem) else: not_calc_elem.append(elem) ax4_y.set_xlabel(x_axis) ax4_y.set_ylabel(('Yield of Products')) ax4_y.legend(tuple(label), loc='best') axis_limits = b_options['xaxis_lim'] + [0, 0.5] ax4_y.axis(axis_limits) title = ('Inlet ratio = ' + str(fixed_dict['inlet_ratio']) + ', tau = ' + str(fixed_dict['tau']) + 's, Radius = ' + str(fixed_dict['R_omega'] * 1e03) + 'mm.') ax4_y.set_title(title) if not_calc_elem: print('The yields of {} are not calculated, ' 'the program thinks they are ' 'unimportant'.format(not_calc_elem)) #### Selectivity of all products if plot_dict['select_all']: products = b_options['products'] if products: fig5, ax5_s = plt.subplots() label = [] not_calc_elem = [] for elem in products: elem_index = species_ID.get(elem, None) carbon_no = species_identifier(elem) if (elem_index != None) and (carbon_no != 0): yield_elem = (T_bd[elem_index, :] - F_in[elem_index]) \ * carbon_no/F_in[hc_index] selectivity_elem = (T_bd[elem_index, :] - F_in[elem_index]) \ * carbon_no \ / (F_in[hc_index] - T_bd[hc_index, :]) if xplottype == 'log': ax5_s.semilogx(T_bd[-1, :], selectivity_elem, linewidth=2.0) else: ax5_s.plot(T_bd[-1, :], selectivity_elem, linewidth=2.0) label.append(elem) else: not_calc_elem.append(elem) ax5_s.set_xlabel(x_axis) ax5_s.set_ylabel(('Selectivity of Products')) ax5_s.legend(tuple(label), loc='best') axis_limits = b_options['xaxis_lim'] + [0, 1] ax5_s.axis(axis_limits) title = ('Inlet ratio = ' + str(fixed_dict['inlet_ratio']) + ', tau = ' + str(fixed_dict['tau']) + 's, Radius = ' + str(fixed_dict['R_omega'] * 1e03) + 'mm.') ax5_s.set_title(title) if not_calc_elem: print('The yields of {} are not calculated, ' 'the program thinks they are ' 'unimportant'.format(not_calc_elem)) if a_options['analysis_plot']: #### Retrieving the species_specific data from T_bd const, thermo_object = constants.fixed_parameters(react_system) h**o, cat, homo_index, cat_index = react.instantiate( react_system, const, catalyst) #### The local species ID is useful in Thiele Modulus calculations local_species = const['species'] no_of_local_species = len(local_species) local_ID = np.arange(no_of_local_species) local_species_ID = dict(zip(local_species, local_ID)) hc_local_index = local_species_ID[inlet_species] O2_local_index = local_species_ID['O2'] #### This is the species_ID of the actual calculation coming from #### the calling function no_of_species = len(species_ID) species = list(species_ID.keys()) hc_index = species_ID[inlet_species] O2_index = species_ID['O2'] #### User-requested plots plot_dict = a_options['plots'] if bif_par_var == 'tau': xplottype = 'log' x_axis = 'Residence Time (s)' else: xplottype = 'normal' x_axis = ('Inlet Fluid Temperature ' + r'$\mathbf{T_{f,in}}$' + ' (K)') #### Calculation of reaction rates #### Unpacking the matrix T_bd F_j = T_bd[:no_of_species, :] C_s = T_bd[no_of_species:2 * no_of_species, :] T_s = T_bd[2 * no_of_species, :] T_f = T_bd[2 * no_of_species + 1, :] bif_par = T_bd[-1, :] no_of_iter = T_bd.shape[1] T_f_in = T_bd[-1, :] #### Unpacking the constants P = fixed_dict['pressure'] R_omega = fixed_dict['R_omega'] R_omega_wc = fixed_dict['R_omega_wc'] R_omega_w = const['R_omega_w'] nu = const['nu'] nu_cat = nu.T[cat_index] nu_cat_inlet_species = nu_cat[:, hc_local_index] nu_cat_O2 = nu_cat[:, O2_local_index] eps_f = 4 * R_omega**2 / (2 * R_omega + R_omega_wc + R_omega_w)**2 #### Defining mole fractions and concentrations C_total = 101325 * P / (8.314 * T_f) Y_j = F_j / np.sum(F_j, axis=0) C_f = Y_j * C_total C_in = 101325 * P / (8.314 * T_f_in) #### Calculation of reaction rates [Fig. 1] if plot_dict['reaction_rates'] or plot_dict['thiele_modulus']: homo_basis, cat_basis = a_options['rate_basis'] homo_units, cat_units = a_options['rate_units'] all_homo_rate = np.zeros([len(homo_index), no_of_iter], dtype=float) all_cat_rate = np.zeros([len(cat_index), no_of_iter], dtype=float) for i in range(no_of_iter): if (system == 'cat'): homo_rate = np.zeros(len(homo_index)) cat_rate = cat.act_rate(C_s[:, i], species, cat_basis, T_s[i], P) elif (system == 'h**o'): cat_rate = np.zeros(len(cat_index)) homo_rate = h**o.act_rate(C_f[:, i], species, homo_basis, T_f[i], P) else: homo_rate = h**o.act_rate(C_f[:, i], species, homo_basis, T_f[i], P) cat_rate = cat.act_rate(C_s[:, i], species, cat_basis, T_s[i], P) all_homo_rate[:, i] = homo_rate[:] all_cat_rate[:, i] = cat_rate[:] #### This is not required for the time being # We got to check the units and perform subsequent calculations if homo_basis == 'mole_fraction': if homo_units != 'second': raise Exception('There is a discrepancy ' 'in the homogeneous reaction rate') if (cat_units == 'kg_sec'): all_cat_rate *= fixed_dict['particle_density'] elif (cat_units == 'gm_sec'): all_cat_rate *= fixed_dict['particle_density'] * 1000 # Here we make two separate variables for catalytic reactions #homo_rate_C0 = all_homo_rate/C_in cat_rate_C0 = all_cat_rate.copy() cat_rate_C0_surf = all_cat_rate.copy() all_cat_rate *= R_omega_wc * eps_f / R_omega #return all_cat_rate - cat_rate_C0 #### Plotting the reaction rates if plot_dict['reaction_rates'] and not multiple: #### Catalytic reaction rates fig, ax1 = plt.subplots() label_cat = () for i in range(len(cat_index)): if xplottype == 'log': ax1.loglog(bif_par, R_omega_wc * all_cat_rate[i, :]) else: ax1.plot(bif_par, R_omega_wc * all_cat_rate[i, :]) label = 'Reaction No.= ' + str(cat_index[i] + 1) label_cat += (label, ) ax1.set_xlabel(x_axis) ax1.set_ylabel(('Catalytic reaction rates (' + r'$\mathbf{mol/m^2 s}$' + ')')) ax1.axes.set_xlim(10, 1200) # Hardcoded ax1.legend(label_cat, loc='best') #### Homogeneous reaction rates fig, ax11 = plt.subplots() label_homo = () for i in range(len(homo_index)): if xplottype == 'log': ax11.loglog(bif_par, all_homo_rate[i, :]) else: ax11.plot(bif_par, all_homo_rate[i, :]) label = 'Reaction No.= ' + str(homo_index[i] + 1) label_homo += (label, ) ax11.set_xlabel(x_axis) ax11.set_ylabel(('Homogeneous reaction rates (' + r'$\mathbf{mol/m^3 s}$' + ')')) ax11.axes.set_xlim(10, 1200) # Hardcoded ax11.legend(label_homo, loc='best') #### Plotting Thiele Modulus if plot_dict['thiele_modulus']: #### Normal Thiele Modulus based on vol. cat. reac. rate inlet_species_cat_rate = np.dot(-nu_cat_inlet_species, cat_rate_C0) D_f = 9.8e-10 * T_f**1.75 D_e = 0.01 * D_f thiele_mod_inlet_species = (inlet_species_cat_rate / C_s[hc_index, :] * R_omega_wc**2 / D_e) #### Surface Thiele Modulus based on surf. cat. reac. rate cat_rate_C0_surf *= R_omega_wc inlet_species_surf_cat_rate = np.dot( -nu_cat_O2, cat_rate_C0_surf) surf_thiele_modulus = (inlet_species_surf_cat_rate / C_s[O2_index, :] * R_omega / D_f) #print(fixed_dict['tau']) #damkohler_second_type = 1/ (inlet_species_surf_cat_rate # / C_s[hc_index, :]) if multiple_variable == 'R_omega': label1 = (symbol['R_omega_wc'] + ' = ' + str(int(100 * val / 0.25e-03)) + units['R_omega_wc']) label2 = (symbol['R_omega'] + ' = ' + str(val * 1e03) + units['R_omega']) else: label1 = (symbol[multiple_variable] + ' = ' + str(val) + units[multiple_variable]) label2 = label1 if count == 1: fig, ax111 = plt.subplots() ax111.set_xlabel(x_axis) ax111.set_ylabel(('Thiele Modulus (' + r'$\mathbf{\phi_{wc}^2}$' + ')')) ax111.axes.set_xlim(10, 1200) # Hardcoded fig, ax112 = plt.subplots() ax112.set_xlabel(x_axis) ax112.set_ylabel(('External Damkohler No. (' + r'$\mathbf{Da_{ext}}$' + ')')) ax112.axes.set_xlim(10, 1200) # Hardcoded ax112.axes.set_ylim(1e-06, 1e06) ax111.plot(bif_par, thiele_mod_inlet_species, linestyle=lines[style_index], label=label1) ax112.semilogy(bif_par, surf_thiele_modulus, linestyle=lines[style_index], label=label2) ax111.legend(loc='best') ax112.legend(loc='best') #ax113.legend(loc='best') return T_bd
def _analysis(fixed_dict, bif_par_var, react_system, system, catalyst, inlet_species, T_bd, F_in, species_ID, multiple, count, a_options): #### LineStyles lines = ['-', '--', '-.', ':'] no_of_lines = len(lines) style_index = count % no_of_lines #linecycler = cycle(lines) #### Retrieving the species_specific data from T_bd const, thermo_object = constants.fixed_parameters(react_system) h**o, cat, homo_index, cat_index = react.instantiate( react_system, const, catalyst) #### The local species ID is useful in Thiele Modulus calculations local_species = const['species'] no_of_local_species = len(local_species) local_ID = np.arange(no_of_local_species) local_species_ID = dict(zip(local_species, local_ID)) hc_local_index = local_species_ID[inlet_species] O2_local_index = local_species_ID['O2'] #### This is the species_ID of the actual calculation coming from #### the calling function no_of_species = len(species_ID) species = list(species_ID.keys()) hc_index = species_ID[inlet_species] O2_index = species_ID['O2'] #### User-requested plots plot_dict = a_options['plots'] if bif_par_var == 'tau': xplottype = 'log' x_axis = 'Residence Time (s)' else: xplottype = 'normal' x_axis = ('Inlet Fluid Temperature ' + r'$\mathbf{T_{f,in}}$' + ' (K)') #### Calculation of reaction rates #### Unpacking the matrix T_bd F_j = T_bd[:no_of_species, :] C_s = T_bd[no_of_species:2 * no_of_species, :] T_s = T_bd[2 * no_of_species, :] T_f = T_bd[2 * no_of_species + 1, :] bif_par = T_bd[-1, :] no_of_iter = T_bd.shape[1] T_f_in = T_bd[-1, :] #### Unpacking the constants R_omega = fixed_dict['R_omega'] R_omega_wc = fixed_dict['R_omega_wc'] R_omega_w = const['R_omega_w'] nu = const['nu'] nu_cat = nu.T[cat_index] nu_cat_inlet_species = nu_cat[:, hc_local_index] nu_cat_O2 = nu_cat[:, O2_local_index] eps_f = 4 * R_omega**2 / (2 * R_omega + R_omega_wc + R_omega_w)**2 #### Defining mole fractions and concentrations C_total = 101325 / (8.314 * T_f) Y_j = F_j / np.sum(F_j, axis=0) C_f = Y_j * C_total C_in = 101325 / (8.314 * T_f_in) #### Calculation of reaction rates [Fig. 1] if plot_dict['reaction_rates'] or plot_dict['thiele_modulus']: homo_basis, cat_basis = a_options['rate_basis'] homo_units, cat_units = a_options['rate_units'] all_homo_rate = np.zeros([len(homo_index), no_of_iter], dtype=float) all_cat_rate = np.zeros([len(cat_index), no_of_iter], dtype=float) for i in range(no_of_iter): if (system == 'cat'): homo_rate = np.zeros(len(homo_index)) cat_rate = cat.act_rate(species, cat_basis, C_s[:, i], T_s[i]) elif (system == 'h**o'): cat_rate = np.zeros(len(cat_index)) homo_rate = h**o.act_rate(species, homo_basis, C_f[:, i], T_f[i]) else: homo_rate = h**o.act_rate(species, homo_basis, C_f[:, i], T_f[i]) cat_rate = cat.act_rate(species, cat_basis, C_s[:, i], T_s[i]) all_homo_rate[:, i] = homo_rate[:] all_cat_rate[:, i] = cat_rate[:] #### This is not required for the time being # We got to check the units and perform subsequent calculations if homo_basis == 'mole_fraction': if homo_units != 'second': raise Exception('There is a discrepancy ' 'in the homogeneous reaction rate') if (cat_units == 'kg_sec'): all_cat_rate *= fixed_dict['particle_density'] elif (cat_units == 'gm_sec'): all_cat_rate *= fixed_dict['particle_density'] * 1000 # Here we make two separate variables for catalytic reactions #homo_rate_C0 = all_homo_rate/C_in cat_rate_C0 = all_cat_rate.copy() all_cat_rate *= R_omega_wc * eps_f / R_omega #return all_cat_rate - cat_rate_C0 #### Plotting the reaction rates if plot_dict['reaction_rates'] and not multiple: #### Catalytic reaction rates fig, ax1 = plt.subplots() label_cat = () for i in range(len(cat_index)): if xplottype == 'log': ax1.loglog(bif_par, all_cat_rate[i, :], linestyle=next(linecycler)) else: ax1.plot(bif_par, all_cat_rate[i, :], linestyle=next(linecycler)) label = 'Reaction No.= ' + str(cat_index[i] + 1) label_cat += (label, ) ax1.set_xlabel(x_axis) ax1.set_ylabel( ('Catalytic reaction rates (' + r'$\mathbf{mol/m^3 s}$' + ')')) ax1.axes.set_xlim(10, 1200) # Hardcoded ax1.legend(label_cat, loc='best') #### Homogeneous reaction rates fig, ax11 = plt.subplots() label_homo = () for i in range(len(homo_index)): if xplottype == 'log': ax11.loglog(bif_par, all_homo_rate[i, :], linestyle=next(linecycler)) else: ax11.plot(bif_par, all_homo_rate[i, :], linestyle=next(linecycler)) label = 'Reaction No.= ' + str(homo_index[i] + 1) label_homo += (label, ) ax11.set_xlabel(x_axis) ax11.set_ylabel(('Homogeneous reaction rates (' + r'$\mathbf{mol/m^3 s}$' + ')')) ax11.axes.set_xlim(10, 1200) # Hardcoded ax11.legend(label_homo, loc='best') #### Plotting Thiele Modulus based on volumetric cat. reaction rates if plot_dict['thiele_modulus']: inlet_species_cat_rate = np.dot(-nu_cat_inlet_species, cat_rate_C0) thiele_mod_inlet_species = (inlet_species_cat_rate / C_s[hc_index, :] * R_omega_wc**2 / 1e-06) inlet_species_surf_cat_rate = np.dot(-nu_cat_inlet_species, all_cat_rate) surf_thiele_modulus = (inlet_species_surf_cat_rate / C_s[hc_index, :] * R_omega**2 / 1e-08) if count == 1: fig, ax111 = plt.subplots() ax111.set_xlabel(x_axis) ax111.set_ylabel( ('Thiele Modulus (' + r'$\mathbf{\phi^2}$' + ')')) ax111.axes.set_xlim(10, 1200) # Hardcoded fig, ax112 = plt.subplots() ax112.set_xlabel(x_axis) ax112.set_ylabel(('Surface Thiele Modulus (' + r'$\mathbf{\phi_{s}^2}$' + ')')) ax112.axes.set_xlim(10, 1200) # Hardcoded ax111.plot(bif_par, thiele_mod_inlet_species, linestyle=lines[style_index]) ax112.plot(bif_par, surf_thiele_modulus, linestyle=lines[style_index]) #### Calculation of ratio at the surface [Fig. 2] if plot_dict['ratio_surface'] or plot_dict['surface_to_bulk']: conc_surf_hc = C_s[hc_index, :] conc_surf_O2 = C_s[O2_index, :] surface_ratio = conc_surf_hc / conc_surf_O2 if plot_dict['ratio_surface']: fig, ax2 = plt.subplots() if xplottype == 'log': ax2.loglog(bif_par, surface_ratio) else: ax2.semilogy(bif_par, surface_ratio) ax2.set_xlabel(x_axis) ax2.set_ylabel(('HC to O2 ratio at surface')) #axis_limits = b_options['xaxis_lim'] + b_options['yaxis_lim'] #ax1.axis(axis_limits) #### Calculation of ratio in bulk [Fig. 3] if plot_dict['ratio_bulk'] or plot_dict['surface_to_bulk']: molar_rate_hc = F_j[hc_index, :] molar_rate_O2 = F_j[O2_index, :] bulk_ratio = molar_rate_hc / molar_rate_O2 if plot_dict['ratio_bulk']: fig, ax3 = plt.subplots() if xplottype == 'log': ax3.loglog(bif_par, bulk_ratio) else: ax3.semilogy(bif_par, bulk_ratio) ax3.set_xlabel(x_axis) ax3.set_ylabel('HC to O2 ratio at bulk') #axis_limits = b_options['xaxis_lim'] + b_options['yaxis_lim'] #ax1.axis(axis_limits) #### Calculation of ratio of HC to O2 in surface to that in bulk [Fig. 4] if plot_dict['surface_to_bulk']: surface_to_bulk = surface_ratio / bulk_ratio fig, ax4 = plt.subplots() if xplottype == 'log': ax4.loglog(bif_par, surface_to_bulk, color='b', linewidth=2.0) else: ax4.semilogy(bif_par, surface_to_bulk, color='b', linewidth=2.0) ax4.set_xlabel(x_axis) ax4.set_ylabel('HC to O2 ratio at surface to that in bulk') #axis_limits = b_options['xaxis_lim'] + b_options['yaxis_lim'] #ax1.axis(axis_limits) if plot_dict['C2H4_C2H6_ratio']: ethylene_index = species_ID['C2H4'] ethane_index = species_ID['C2H6'] ethylene_ethane_ratio = F_j[ethylene_index, :] / F_j[ethane_index, :] fig, ax5 = plt.subplots() if xplottype == 'log': ax5.loglog(bif_par, ethylene_ethane_ratio) else: ax5.semilogy(bif_par, ethylene_ethane_ratio) ax5.set_xlabel(x_axis) ax5.set_ylabel('Ethylene to Ethane ratio in bulk')
def low_D_non_iso_model_solver(fixed_dict, react_system, system, catalyst, rate_basis, rate_units, inlet_species, n, options): ''' This function solves the low_D_Sh_phi function to generate the conversion vs Temperature curve. fixed_dict : Dictionary of fixed variables and values. react_system : Name of the reaction system system : Whether the system is 'cat'-alytic, 'coup'-led, or 'h**o'-geneous catalyst : Name of the catalyst used rate_basis : Basis of the rate expressions, whether pressure, concentration, mole fraction rate_units : Units of the rate expressions inlet_species : Name of the fuel, e.g. 'CH4' n : No of discretized points in x options : Some options, like whether to save the result, or just to test the model. ''' #### Constant parameters involved with the system const, thermo_object = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print(species_ID) #### Generating the reaction objects h**o, cat, homo_index, cat_index = react.instantiate( react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] inlet_ratio = fixed_dict['inlet_ratio'] y_A_in = inlet_ratio / (inlet_ratio + 1) y_B_in = 1 / (inlet_ratio + 1) T_f_in = 300 #### Function names func = low_D_non_iso_model tspan = np.linspace(0, 8000, 1000000) #### Inlet values c_A_in = y_A_in * 101325 * fixed_dict['pressure'] / (8.314 * T_f_in) c_B_in = y_B_in * 101325 * fixed_dict['pressure'] / (8.314 * T_f_in) C_f_in = 1e-03 * np.ones(no_of_species) A_index = species_ID[inlet_species] B_index = species_ID['O2'] C_f_in[A_index] = c_A_in C_f_in[B_index] = c_B_in C_f_0 = np.tile(C_f_in, n) C_w_0 = np.tile(C_f_in, n) T_f_0 = np.tile(T_f_in, n) # T_f_0 = np.linspace(300, 600, n) T_s_0 = np.tile(T_f_in, n) C_0 = np.r_[C_f_0, C_w_0, T_f_0, T_s_0] #### Testing if options['Testing']: Y = func(C_0, 4200, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options['model']) return Y else: #### Integration Y = odeint(func, C_0, tspan, args=(inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options['model'])) ### Conversion calculations T_f_in = np.array(list(map(temp_ramp_func, tspan))) C_in = 101325 * fixed_dict['pressure'] / (8.314 * T_f_in) CH4_in = y_A_in * C_in O2_in = y_B_in * C_in print(no_of_species * (n - 1)) print(no_of_species * n) C_f_exit = Y[:, no_of_species * (n - 1):no_of_species * n] CH4_exit = C_f_exit[:, A_index] O2_exit = C_f_exit[:, B_index] conv_A = (1 - CH4_exit / CH4_in) conv_B = (1 - O2_exit / O2_in) print(n * (no_of_species * 2 + 1) - 1) T_f_exit = Y[:, n * (no_of_species * 2 + 1) - 1] #### Plotting fig, ax = plt.subplots() ax.plot(T_f_in, conv_B) ax.set_xlabel('Inlet Fluid Temperature (K)') ax.set_ylabel(r'Conversion of $\mathbf{O_2}$') ax.set_xlim([0, 1]) fig, ax1 = plt.subplots() ax1.plot(T_f_in, T_f_exit) ax1.set_xlabel('Inlet fluid Temperature (K)') ax1.set_ylabel('Exit fluid Temperature (K)') plt.show() return Y
def hys_locus_solver(fixed_dict, bif_par_dict, react_system, system, catalyst, rate_basis, rate_units, inlet_species, break_dict, step_change, max_val, options): ''' This function solves for the hysteresis locus. (Region of multiplicities) We will write other details later. Just to point out one important difference between hys_locus_solver and bif_dia_solver is that, here we take in the entire break_dict It is similar to bif_set_solver in that respect. ''' #### Generating the constant parameters const, thermo_object = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print('This is the new species ID',species_ID) #### Manipulation of input variables all_dict = dict(bif_par_dict, **fixed_dict) bif_par_var = list(bif_par_dict.keys())[0] bif_par_val = bif_par_dict.get(bif_par_var) break_val = break_dict[bif_par_var] #y_A_in_max_val = max_dict['y_A_in'] # Generating the reaction objects h**o, cat, homo_index, cat_index = react.instantiate(react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] ##### First dataset if options['occurence']: filename = 'bif_set_{0}_{1}'.format(options['limit_point'], options['occurence']) else: filename = 'bif_set_{0}'.fomat(options['limit_point']) npzfile = _load_file(react_system, system, catalyst, all_dict, filename=filename) T_bs_arr, species_ID_arr = npzfile.files T_bs = npzfile[T_bs_arr] species_ID_old = npzfile[species_ID_arr] index = ig_ext_point_calculator(T_bs, system, 'inlet_ratio', break_dict, fulloutput= False, tol=1e-02) limit_index = 0 #data_vals = [value for (key, value) in sorted(fixed_dict.items())] #n = len(data_vals) # #filename = 'hysteresis_locus_left_{}'.format(options['occurence']) #for i in range(n): # filename += '_{}'.format(data_vals[i]) #filename += '.npz' #print(filename) # #react_filename, ext = os.path.splitext(react_system) # #Target_folder = os.path.join(os.getcwd(), react_filename, # catalyst.lower(), 'Data', system) #FullfileName = os.path.join(Target_folder, filename) # #print(FullfileName) #npzfile = np.load(FullfileName) #T_hl_arr = npzfile.files #T_hl = npzfile[T_hl_arr[0]] #x = T_hl[4*(no_of_species+1):-1, -1] #bif_par_val = T_hl[-1, -1] #### Function name func = hys_locus_func jac = jacobian #### Initial guess of the left and right eigen vectors no_of_func = 2*(no_of_species + 1) y0 = np.zeros(no_of_func, dtype=float) v0 = np.zeros_like(y0) y0[1] = 1 v0[1] = 1 col_index = index[limit_index] if col_index == -1 or col_index == 0: raise Exception('Cusp point does not exist at this configuration') x_old = T_bs[:, col_index] #### Rearranging the species data (Because of different species IDs) fluid_f_old = x_old[:no_of_species] wc_f_old = x_old[no_of_species : 2*no_of_species] invariant = x_old[2*no_of_species : ] fluid_f_new = _rearrange_species(species_ID_old, species_ID, fluid_f_old) wc_f_new = _rearrange_species(species_ID_old, species_ID, wc_f_old) x = np.r_[fluid_f_new, wc_f_new, invariant] x_init = np.r_[y0, v0, x, bif_par_val] J, d2f = func(x_init, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options, get_jacobian=True, get_second_deriv=True) Y_init = np.r_[y0, v0] Y0 = root(left_right_eigen_vector, Y_init, args=(J, d2f), method='lm') state_var_val = np.r_[Y0.x, x, bif_par_val] if options['Testing']: print('\nThe eigen vectors are calculated under the following status') print('Status: {0}, msg: {1}'.format(Y0.status, Y0.message)) print('\nAll the varibles going into the function') print(state_var_val) F = func(state_var_val, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options) return F else: #### Solving for hysteresis locus no_of_var = len(state_var_val) pref = np.ones(no_of_var) no_of_func = 2*(no_of_species + 1) weights = np.ones(no_of_var) weights[:2*no_of_func] = 1e-04 weights[-5:-2] = 1e-03 weights[-2] = 1e-01 jac_eps = options['jac_eps'] T_hl = der.derpar(func, jac, state_var_val, pref, max_val, break_val, weights, jac_eps, initial=False, hh=step_change, maxout=5000, hhmax=10*step_change, ncorr=5, args=(inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options), kwargs=()) ##### Plotting if bif_par_var == 'T_f_in' or bif_par_var == 'inlet_species': plot_flag = 'norm' else: plot_flag = 'log' fig = plt.figure() if plot_flag == 'log': plt.semilogx(T_hl[-1, :], 1/T_hl[-2, :]) else: plt.plot(T_hl[-1, :], 1/T_hl[-2, :]) plt.show() #### Storing data data_vals = [value for (key, value) in sorted(fixed_dict.items())] n = len(data_vals) if options['occurence']: filename = 'hysteresis_locus_left_{0}'.format(options['occurence']) else: filename = 'hysteresis_locus_left' for i in range(n): filename += '_{}'.format(data_vals[i]) print(filename) if options['save']: #### Saving Data react_filename, ext = os.path.splitext(react_system) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Data', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower() + '/' \ + '/Data/' + system os.makedirs(New_Folder) FullfileName = os.path.join(Target_folder, filename) np.savez(FullfileName, T_hl[2*no_of_func:, :], species_ID) #### Saving Diagrams (Why I don't know) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Diagram', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower() + '/' \ + '/Diagram/' + system os.makedirs(New_Folder) dia_filename = filename + '.png' FullfileName = os.path.join(Target_folder, dia_filename) fig.savefig(FullfileName) #### Returning the final result return T_hl
def bif_set_solver(fixed_dict, bif_par_dict, react_system, system, catalyst, rate_basis, rate_units, inlet_species, break_dict, step_change, max_val, options): ''' This function solves for the bifurcation set (ignition-extinction locus). we will write other details later Just to point out one important difference between bif_set_solver and bif_dia_solver is that, here we take in the entire break_dict ''' # Constant parameters involved with the system const, thermo_object = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print('This is the new species ID',species_ID) # Manipulation of input variables all_dict = dict(fixed_dict, **bif_par_dict) bif_par_var = list(bif_par_dict.keys())[0] bif_par_val = bif_par_dict.get(bif_par_var) break_val = break_dict[bif_par_var] temp_break_val = break_dict['T_f_in'] # Generating the reaction objects h**o, cat, homo_index, cat_index = react.instantiate(react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] # First Dataset npzfile = _load_file(react_system, system, catalyst, all_dict) T_bd_arr, Y_in_arr, species_ID_arr = npzfile.files T_bd = npzfile[T_bd_arr] species_ID_old = npzfile[species_ID_arr] T_bd_wo_noise = T_bd[:, 1000:] index = ig_ext_point_calculator(T_bd_wo_noise, system, 'T_f_in', break_dict, fulloutput=True) #### Fixing the starting point (ignition/extinction, first/second) if options['limit_point'] == 'ignition': if options['occurence'] == 'first': limit_index = 0 elif options['occurence'] == 'second': limit_index = 2 else: raise Exception('Wrong value of occurence') elif options['limit_point'] == 'extinction': if options['occurence'] == 'first': limit_index = 1 elif options['occurence'] == 'second': limit_index = 3 else: raise Exception('Wrong value of occurence') else: raise Exception('Wrong value of limit_point') #### Function names func = bif_set_func jac = jacobian #### Initial guess no_of_func = 2*(no_of_species + 1) y0 = np.zeros(no_of_func) y0[1] = 1 col_index = index[limit_index] if col_index == -1 or col_index == 0: raise Exception('Limit point does not exist at this configuration') x_old = T_bd_wo_noise[:, col_index] #### Rearranging the species data (Because of different species IDs) fluid_f_old = x_old[:no_of_species] wc_f_old = x_old[no_of_species : 2*no_of_species] invariant = x_old[2*no_of_species : ] fluid_f_new = _rearrange_species(species_ID_old, species_ID, fluid_f_old) wc_f_new = _rearrange_species(species_ID_old, species_ID, wc_f_old) x = np.r_[fluid_f_new, wc_f_new, invariant] x_init = np.r_[y0, x, bif_par_val] J = func(x_init, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options, get_jacobian=True) y0_sol = root(null_space, y0, args= J, method= 'lm') state_var_val = np.r_[y0_sol.x, x, bif_par_val] if options['Testing']: print('\nThe eigen vectors are calculated under the following status') print('Status: {0}, msg: {1}'.format(y0_sol.status, y0_sol.message)) print('\nAll the varibles going into the function') print(state_var_val) print('\nAnd the fixed variables are:') print(fixed_dict) Ysol = func(state_var_val, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options) return Ysol else: #### Solving for ignition-extinction locus no_of_var = len(state_var_val) pref = np.ones(no_of_var) weights = np.ones(no_of_var) # weights[:2*(no_of_species + 1)] = 1e-03 # weights[-4:-1] = 1e-03 # weights[-1] = 1e-01 jac_eps = options['jac_eps'] T_bs = der.derpar(func, jac, state_var_val, pref, max_val, break_val, weights, jac_eps, initial=False, hh=step_change, maxout=100000, hhmax= 10*step_change, ncorr=5, args=(inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options), kwargs=(temp_break_val)) #### Plotting the figure if bif_par_var == 'T_f_in' or bif_par_var == 'inlet_ratio': plot_flag = 'norm' else: plot_flag = 'log' fig = plt.figure() if plot_flag == 'log': plt.semilogx(T_bs[-1, :], T_bs[-2, :]) else: plt.plot(T_bs[-1, :], T_bs[-2, :]) plt.show() #### Storing data data_vals = [value for (key, value) in sorted(fixed_dict.items())] n = len(data_vals) filename = 'bif_set_{}_{}'.format(options['limit_point'], options['occurence']) for i in range(n): filename += '_{}'.format(data_vals[i]) print(filename) if options['save']: #### Saving Data react_filename, ext = os.path.splitext(react_system) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Data', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower() + '/' \ + '/Data/' + system os.makedirs(New_Folder) FullfileName = os.path.join(Target_folder, filename) np.savez(FullfileName, T_bs[no_of_func:, :], species_ID) #### Saving Diagrams (Why I don't know) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Diagram', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower() + '/' \ + '/Diagram/' + system os.makedirs(New_Folder) dia_filename = filename + '.png' FullfileName = os.path.join(Target_folder, dia_filename) fig.savefig(FullfileName) #### Returning the final result return T_bs
def bif_dia_solver(fixed_dict, bif_par_dict, react_system, system, catalyst, rate_basis, rate_units, inlet_species, break_val, step_change, max_val, options): ''' This function solves for the bifurcation diagram. fixed_dict= Dictionary of fixed variables and values. bif_par_dict= Dictionary of Bifurcation variable and value. react_system= Describes the reaction system chosen, e.g: 'OCM_three_reaction.txt'. system= Whether the system is catalytic only, homogeneous only, or homogeneous-heterogeneous coupled. inlet_species= The hydrocarbon species, as of now just hydrocarbon and O2 is taken as inlet. break_val= break value of the bifurcation parameter. step_change= step_change value of the bifurcation parameter, necessary in Pseudo-Arc Length Continuation. max_val= maximum value of the bifurcation parameter. options= Solver Options. ''' #### Constant parameters involved with the system const, thermo_object = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print(species_ID) #### Manipulation of input variables all_dict = dict(fixed_dict, **bif_par_dict) bif_par_var = list(bif_par_dict.keys())[0] bif_par_val = bif_par_dict.get(bif_par_var) #### Initial guess inlet_ratio = all_dict['inlet_ratio'] N2 = 0 # For the time being, we use pure O2 F_A_in = inlet_ratio/(N2 + inlet_ratio + 1) F_B_in = 1/(N2 + inlet_ratio + 1) F_in = 1e-08 * np.ones(no_of_species) A_index = species_ID[inlet_species] B_index = species_ID['O2'] F_in[A_index] = F_A_in F_in[B_index] = F_B_in state_var_val = np.r_[F_in, F_in, all_dict['T_f_in'], all_dict['T_f_in'], bif_par_val] #### Generating the reaction objects h**o, cat, homo_index, cat_index = react.instantiate(react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] #### Function name func = bif_dia_func jac = jacobian plot_flag = 'norm' if options['Testing']: #### Just testing the function(s) print('\nAll the varibles going into the function') print(state_var_val) print('\nAnd the fixed valriables going into the function') print(fixed_dict) Ysol = func(state_var_val, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units) return Ysol elif options['solver'] == 'python': #### Solving the set of equations using Arc-Length method in Python no_of_var = len(state_var_val) pref = np.ones(no_of_var) weights = np.ones(no_of_var) weights[-2:] = 1e-03 jac_eps = options['jac_eps'] T_bd = der.derpar(func, jac, state_var_val, pref, max_val, break_val, weights, jac_eps, initial= False, hh = step_change, maxout = 200000, hhmax = 10*step_change, args=(inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units)) else: #### Solving the set of equations using Arc-Length method in Fortran eps = 1e-08 w = np.ones(no_of_var, dtype=float, order='F') initial = 0 itin = 50 hh = 0.05 hmax = 0.1 * np.ones(no_of_var, dtype=float, order='F') ndir = np.ones(no_of_var, dtype=np.int64, order='F') e = 1e-06 mxadms = 4 ncorr = 4 ncrad = 0 maxout = 4 nout, out = arc_length.derpar(func, jac, state_var_val, break_val, max_val, eps, w, initial, itin, hh, hmax, pref, ndir, e, mxadms, ncorr, ncrad, maxout, func_extra_args=(inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units), jac_extra_args=(inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units)) out_act = out[:nout,:-1] T_bd = out_act.T #### Plotting the figure fig = plt.figure() if plot_flag == 'log': plt.semilogx(T_bd[-1, :], T_bd[-2, :]) else: plt.plot(T_bd[-1, :], T_bd[-2, :]) plt.show() #### Storing data data_vals = [value for (key, value) in sorted(fixed_dict.items())] n = len(data_vals) filename = 'bif_dia' for i in range(n): filename += '_{}'.format(data_vals[i]) print(filename) if options['save']: #### Saving Data react_filename, ext = os.path.splitext(react_system) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Data', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower() + '/' \ + '/Data/' + system os.makedirs(New_Folder) FullfileName = os.path.join(Target_folder, filename) np.savez(FullfileName, T_bd, F_in, species_ID) #### Saving Diagrams (Why I don't know) Target_folder = os.path.join(os.getcwd(), react_filename, catalyst.lower(), 'Diagram', system) if os.path.isdir(Target_folder) == False: New_Folder = react_filename + '/' + catalyst.lower() + '/' \ + '/Diagram/' + system os.makedirs(New_Folder) dia_filename = filename + '.png' FullfileName = os.path.join(Target_folder, dia_filename) fig.savefig(FullfileName) #### Returning the final result return T_bd
def bif_dia_solver(fixed_dict, bif_par_dict, react_system, system, catalyst, rate_basis, rate_units, inlet_species, break_val, step_change, max_val, options): ''' We will write this thing later ''' #### Constant parameters involved with the system const, thermo_object = constants.fixed_parameters(react_system) species = const['species'] no_of_species = len(species) ID = np.arange(no_of_species) species_ID = dict(zip(species, ID)) print(species_ID) #### Manipulation of input variables all_dict = dict(fixed_dict, **bif_par_dict) bif_par_var = list(bif_par_dict.keys())[0] bif_par_val = bif_par_dict.get(bif_par_var) #### Initial guess T_f_in = all_dict['T_f_in'] inlet_ratio = all_dict['inlet_ratio'] N2 = 0 # For the time being, we use pure O2 F_A_in = inlet_ratio / (N2 + inlet_ratio + 1) F_B_in = 1 / (N2 + inlet_ratio + 1) F_in = 1e-08 * np.ones(no_of_species) A_index = species_ID[inlet_species] B_index = species_ID['O2'] F_in[A_index] = F_A_in F_in[B_index] = F_B_in state_var_val = np.r_[F_in, F_in, T_f_in, T_f_in, bif_par_val] #### Generating the reaction objects h**o, cat, homo_index, cat_index = react.instantiate( react_system, const, catalyst) react_const = [h**o, cat, homo_index, cat_index] #### Function name func = bif_dia_func jac = jacobian plot_flag = 'norm' if options['Testing']: #### Just testing the function(s) print('\nAll the varibles going into the function') print(state_var_val) print('\nAnd the fixed valriables going into the function') print(fixed_dict) Ysol = func(state_var_val, inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options) return Ysol else: #### Solving the set of equations using Arc-Length method in Python no_of_var = len(state_var_val) pref = np.ones(no_of_var) weights = np.ones(no_of_var) weights[-2:] = 1e-03 jac_eps = options['jac_eps'] max_iter = options['max_iter'] data_vals = [value for (key, value) in sorted(fixed_dict.items())] n = len(data_vals) react_filename, ext = os.path.splitext(react_system) if options['model'] is 'sh_phi' and options['write_eig_val']: #### Filename file = react_filename + '_' + catalyst.lower() + '_' + system for i in range(n): file += '_{}'.format(data_vals[i]) file += '.txt' #### Directory folder = os.path.join(os.getcwd(), 'EigenValues') if not os.path.isdir(folder): os.mkdir('EigenValues') fullfilename = os.path.join(folder, file) print(fullfilename) #### Creating the file with open(fullfilename, "w") as fh: fh.write(react_system) fh.write('\n') options.update({'eig_val_filename': fullfilename}) T_bd = der.derpar(func, jac, state_var_val, pref, max_val, break_val, weights, jac_eps, eps=1e-04, initial=False, maxIter=50, hh=step_change, maxout=max_iter, hhmax=10 * step_change, ncorr=6, args=(inlet_species, fixed_dict, const, thermo_object, react_const, system, rate_basis, rate_units, options)) #### Plotting the figure fig = plt.figure() if plot_flag == 'log': plt.semilogx(T_bd[-1, :], T_bd[-2, :]) else: plt.plot(T_bd[-1, :], T_bd[-2, :]) plt.show() #### Storing data filename = 'bif_dia_{}'.format(options['model'].lower()) for i in range(n): filename += '_{}'.format(data_vals[i]) print(filename) if options['save']: #### Saving Data Target_folder = os.path.join(os.getcwd(), 'Washcoat', react_filename, catalyst.lower(), 'Data', system) if os.path.isdir(Target_folder) == False: New_Folder = 'Washcoat/' + react_filename + '/' + catalyst.lower() + '/' \ + '/Data/' + system os.makedirs(New_Folder) FullfileName = os.path.join(Target_folder, filename) np.savez(FullfileName, T_bd, F_in, species_ID) #### Saving Diagrams (Why I don't know) Target_folder = os.path.join(os.getcwd(), 'Washcoat', react_filename, catalyst.lower(), 'Diagram', system) if os.path.isdir(Target_folder) == False: New_Folder = 'Washcoat/' + react_filename + '/' + catalyst.lower() + '/' \ + '/Diagram/' + system os.makedirs(New_Folder) dia_filename = filename + '.png' FullfileName = os.path.join(Target_folder, dia_filename) fig.savefig(FullfileName) #### Returning the final result return T_bd