defget_stoichiometry_matrices(self): """ Go through elementary_rxns_list, return sites stoichiometry matrix and gas stoichiometry matrix. """ sites_names = ['*_'+site_name for site_name in self._owner.site_names] + \ list(self._owner.adsorbate_names) gas_names = list(self._owner.gas_names) #initialize matrices m = len(self._owner.elementary_rxns_list) n_s, n_g = len(sites_names), len(gas_names) site_matrix, gas_matrix = np.matrix(np.zeros((m, n_s))),\ np.matrix(np.zeros((m, n_g))) #go through all elementary equations for i in xrange(m): states_list = self._owner.elementary_rxns_list[i] for sp in states_list[0]: #for initial state stoichiometry, sp_name = self.split_species(sp) if sp_name in sites_names: j = sites_names.index(sp_name) site_matrix[i, j] += stoichiometry if sp_name in gas_names: j = gas_names.index(sp_name) gas_matrix[i, j] += stoichiometry for sp in states_list[-1]: #for final state stoichiometry, sp_name = self.split_species(sp) if sp_name in sites_names: j = sites_names.index(sp_name) site_matrix[i, j] -= stoichiometry if sp_name in gas_names: j = gas_names.index(sp_name) gas_matrix[i, j] -= stoichiometry
return site_matrix, gas_matrix
defget_total_rxn_equation(self): "Get total reaction expression of the kinetic model." site_matrix, gas_matrix = self.get_stoichiometry_matrices()
defnull(A, eps=1e-10): "get null space of transposition of site_matrix" u,s,vh = np.linalg.svd(A,full_matrices=1,compute_uv=1) null_space = np.compress(s <= eps, vh, axis=0) return null_space.T x = null(site_matrix.T) #basis of null space x = map(abs, x.T.tolist()[0]) #convert entries of x to integer min_x = min(x) x = [round(i/min_x, 1) for i in x] setattr(self._owner, 'trim_coeffients', x) x = np.matrix(x) total_coefficients = (x*gas_matrix).tolist()[0] #create total rxn expression reactants_list, products_list = [], [] for sp_name in self._owner.gas_names: idx = self._owner.gas_names.index(sp_name) coefficient = total_coefficients[idx] if coefficient < 0: #for products coefficient = abs(int(coefficient)) if coefficient == 1: coefficient = '' else: coefficient = str(coefficient) products_list.append(coefficient + sp_name) else: #for reactants coefficient = int(coefficient) if coefficient == 1: coefficient = '' else: coefficient = str(coefficient) reactants_list.append(coefficient + sp_name) reactants_expr = ' + '.join(reactants_list) products_expr = ' + '.join(products_list) total_rxn_equation = reactants_expr + ' -> ' + products_expr
#check conservation states_dict = self.parse_single_elementary_rxn(total_rxn_equation)[0] check_result = self.check_conservation(states_dict) ifnot check_result: setattr(self._owner, 'total_rxn_equation', total_rxn_equation) else: if check_result == 'mass_nonconservative': raise ValueError('Mass of total equation \''+ total_rxn_equation+'\' is not conservative!') if check_result == 'site_nonconservative': raise ValueError('Site of total equation \''+ total_rxn_equation+'\' is not conservative!')
#check conservation states_dict = self.parse_single_elementary_rxn(total_rxn_equation)[0] check_result = self.check_conservation(states_dict) ifnot check_result: setattr(self._owner, 'total_rxn_equation', total_rxn_equation) else: if check_result == 'mass_nonconservative': raise ValueError('Mass of total equation \''+ total_rxn_equation+'\' is not conservative!') if check_result == 'site_nonconservative': raise ValueError('Site of total equation \''+ total_rxn_equation+'\' is not conservative!')