def convert_chemkin_file(input_file, thermo_file, output_file): parser = ck2cti.Parser() parser.convertMech(input_file, thermoFile=thermo_file, outName=output_file, quiet=True, permissive=True) print('Done')
def loadChemkinModel(self, chemkinFile, transportFile=None, **kwargs): """ Convert a chemkin mechanism chem.inp file to a cantera mechanism file chem.cti and save it in the outputDirectory Then load it into self.model """ from cantera import ck2cti base = os.path.basename(chemkinFile) baseName = os.path.splitext(base)[0] outName = os.path.join(self.outputDirectory, baseName + ".cti") if os.path.exists(outName): os.remove(outName) parser = ck2cti.Parser() parser.convertMech(chemkinFile, transportFile=transportFile, outName=outName, **kwargs) self.model = ct.Solution(outName)
def convertMech(inputFile, outName=None, **kwargs): if os.path.exists(outName): os.remove(outName) parser = ck2cti.Parser() parser.convertMech(inputFile, outName=outName, **kwargs)
def write(solution): """Function to write cantera solution object to inp file. Parameters ---------- solution : obj Cantera solution object Returns : str Name of trimmed Mechanism file (.inp) Example ------- soln2ck.write(gas) """ trimmed_solution = solution input_file_name_stripped = trimmed_solution.name cwd = os.getcwd() output_file_name = os.path.join(cwd, 'pym_' + input_file_name_stripped + '.inp') f = open(output_file_name, 'w+') #Work functions calories_constant = 4184.0 #number of calories in 1000 Joules of energy def eliminate(input_string, char_to_replace, spaces='single'): """ Eliminate characters from a string :param input_string string to be modified :param char_to_replace array of character strings to be removed """ for char in char_to_replace: input_string = input_string.replace(char, "") if spaces == 'double': input_string = input_string.replace(" ", " ") return input_string def section_break(title): """ Insert break and new section title into cti file :param title: title string for next section_break """ f.write('!' + "-" * 75 + '\n') f.write('! ' + title + '\n') f.write('!' + "-" * 75 + '\n') def replace_multiple(input_string, replace_list): """ Replace multiple characters in a string :param input_string string to be modified :param replace list list containing items to be replaced (value replaces key) """ for original_character, new_character in replace_list.items(): input_string = input_string.replace(original_character, new_character) return input_string def build_arrhenius(equation_object, equation_type): """ Builds Arrhenius coefficient string :param equation_objects cantera equation object :param equation_type: string of equation type """ coeff_sum = sum(equation_object.reactants.values()) pre_exponential_factor = equation_object.rate.pre_exponential_factor temperature_exponent = '{:.3f}'.format( equation_object.rate.temperature_exponent) activation_energy = '{:.2f}'.format( equation_object.rate.activation_energy / calories_constant) if equation_type == 'ElementaryReaction': if coeff_sum == 1: pre_exponential_factor = str( '{:.3E}'.format(pre_exponential_factor)) if coeff_sum == 2: pre_exponential_factor = str('{:.3E}'.format( pre_exponential_factor * 10**3)) if coeff_sum == 3: pre_exponential_factor = str('{:.3E}'.format( pre_exponential_factor * 10**6)) if equation_type == 'ThreeBodyReaction': if coeff_sum == 1: pre_exponential_factor = str('{:.3E}'.format( pre_exponential_factor * 10**3)) if coeff_sum == 2: pre_exponential_factor = str('{:.3E}'.format( pre_exponential_factor * 10**6)) if (equation_type != 'ElementaryReaction' and equation_type != 'ThreeBodyReaction'): pre_exponential_factor = str( '{:.3E}'.format(pre_exponential_factor)) arrhenius = [ pre_exponential_factor, temperature_exponent, activation_energy ] return arrhenius def build_modified_arrhenius(equation_object, t_range): """ Builds Arrhenius coefficient strings for high and low temperature ranges :param equation_objects cantera equation object :param t_range: simple string ('high' or 'low') to designate temperature range """ coeff_sum = sum(equation_object.products.values()) if t_range == 'high': pre_exponential_factor = equation_object.high_rate.pre_exponential_factor temperature_exponent = '{:.3f}'.format( equation_object.high_rate.temperature_exponent) activation_energy = '{:.2f}'.format( equation_object.high_rate.activation_energy / calories_constant) if coeff_sum == 1: pre_exponential_factor = str('{:.5E}'.format( pre_exponential_factor * 10**3)) else: pre_exponential_factor = str( '{:.5E}'.format(pre_exponential_factor)) arrhenius_high = [ pre_exponential_factor, temperature_exponent, activation_energy ] return arrhenius_high if t_range == 'low': pre_exponential_factor = equation_object.low_rate.pre_exponential_factor temperature_exponent = '{:.3f}'.format( equation_object.low_rate.temperature_exponent) activation_energy = '{:.2f}'.format( equation_object.low_rate.activation_energy / calories_constant) if coeff_sum == 1: pre_exponential_factor = str('{:.5E}'.format( pre_exponential_factor * 10**6)) else: pre_exponential_factor = str('{:.5E}'.format( pre_exponential_factor * 10**3)) arrhenius_low = [ pre_exponential_factor, temperature_exponent, activation_energy ] return arrhenius_low def build_nasa(nasa_coeffs, row): """ Creates string of nasa polynomial coefficients :param nasa_coeffs cantera species thermo coefficients object :param row which row to write coefficients in """ line_coeffs = '' lines = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14]] line_index = lines[row - 2] for ix, c in enumerate(nasa_coeffs): if ix in line_index: if c >= 0: line_coeffs += ' ' line_coeffs += str('{:.8e}'.format(c)) return line_coeffs def build_species_string(): """ formats species string for writing """ species_list_string = '' line = 1 for sp_index, sp_string in enumerate(trimmed_solution.species_names): sp = ' ' #get length of string next species is added length_new = len(sp_string) length_string = len(species_list_string) total = length_new + length_string + 3 #if string will go over width, wrap to new line if total >= 70 * line: species_list_string += '\n' line += 1 species_list_string += sp_string + ((16 - len(sp_string)) * sp) return species_list_string #Write title block to file section_break('Chemkin File converted from Solution Object by pyMARS') #Write phase definition to file element_names = eliminate(str(trimmed_solution.element_names), ['[', ']', '\'', ',']) element_string = Template('ELEMENTS\n' + '$element_names\n' + 'END\n') f.write(element_string.substitute(element_names=element_names)) species_names = build_species_string() species_string = Template('SPECIES\n' + '$species_names\n' + 'END\n') f.write(species_string.substitute(species_names=species_names)) #Write species to file section_break('Species data') f.write('THERMO ALL' + '\n' + ' 300.000 1000.000 5000.000' + '\n') phase_unknown_list = [] #write data for each species in the Solution object for sp_index in xrange(len(trimmed_solution.species_names)): d = 3.33564e-30 #1 debye = d coulomb-meters species = trimmed_solution.species(sp_index) name = str(trimmed_solution.species(sp_index).name) nasa_coeffs = trimmed_solution.species(sp_index).thermo.coeffs #Species attributes from trimmed solution object t_low = '{0:.3f}'.format(species.thermo.min_temp) t_max = '{0:.3f}'.format(species.thermo.max_temp) t_mid = '{0:.3f}'.format(species.thermo.coeffs[0]) temp_range = str(t_low) + ' ' + str(t_max) + ' ' + t_mid species_comp = '' for atom in species.composition: species_comp += '{:<4}'.format(atom) species_comp += str(int(species.composition[atom])) if type(species.transport).__name__ == 'GasTransportData': species_phase = 'G' else: phase_unknown_list.append(name) species_phase = 'G' line_1 = ('{:<18}'.format(name) + '{:<6}'.format(' ') + '{:<20}'.format(species_comp) + '{:<4}'.format(species_phase) + '{:<31}'.format(temp_range) + '{:<1}'.format('1') + '\n') f.write(line_1) line_2_coeffs = build_nasa(nasa_coeffs, 2) line_2 = line_2_coeffs + ' 2\n' f.write(line_2) line_3_coeffs = build_nasa(nasa_coeffs, 3) line_3 = line_3_coeffs + ' 3\n' f.write(line_3) line_4_coeffs = build_nasa(nasa_coeffs, 4) line_4 = line_4_coeffs + ' 4\n' f.write(line_4) f.write('END\n') #Write reactions to file section_break('Reaction Data') f.write('REACTIONS\n') #write data for each reaction in the Solution Object for reac_index in xrange(len(trimmed_solution.reaction_equations())): equation_string = str(trimmed_solution.reaction_equation(reac_index)) equation_string = eliminate(equation_string, ' ', 'single') equation_object = trimmed_solution.reaction(reac_index) equation_type = type(equation_object).__name__ m = str(reac_index + 1) if equation_type == 'ThreeBodyReaction': arrhenius = build_arrhenius(equation_object, equation_type) main_line = ('{:<51}'.format(equation_string) + '{:>9}'.format(arrhenius[0]) + '{:>9}'.format(arrhenius[1]) + '{:>11}'.format(arrhenius[2]) + '\n') f.write(main_line) #trimms efficiencies list efficiencies = equation_object.efficiencies trimmed_efficiencies = equation_object.efficiencies for s in efficiencies: if s not in trimmed_solution.species_names: del trimmed_efficiencies[s] replace_list_2 = {'{': '', '}': '/', '\'': '', ':': '/', ',': '/'} efficiencies_string = replace_multiple(str(trimmed_efficiencies), replace_list_2) secondary_line = str(efficiencies_string) + '\n' if bool(efficiencies) is True: f.write(secondary_line) if equation_type == 'ElementaryReaction': arrhenius = build_arrhenius(equation_object, equation_type) main_line = ('{:<51}'.format(equation_string) + '{:>9}'.format(arrhenius[0]) + '{:>9}'.format(arrhenius[1]) + '{:>11}'.format(arrhenius[2]) + '\n') f.write(main_line) if equation_type == 'FalloffReaction': arr_high = build_modified_arrhenius(equation_object, 'high') main_line = ('{:<51}'.format(equation_string) + '{:>9}'.format(arr_high[0]) + '{:>9}'.format(arr_high[1]) + '{:>11}'.format(arr_high[2]) + '\n') f.write(main_line) arr_low = build_modified_arrhenius(equation_object, 'low') second_line = (' LOW /' + ' ' + arr_low[0] + ' ' + arr_low[1] + ' ' + arr_low[2] + '/\n') f.write(second_line) j = equation_object.falloff.parameters #If optional Arrhenius data included: try: third_line = (' TROE/' + ' ' + str(j[0]) + ' ' + str(j[1]) + ' ' + str(j[2]) + ' ' + str(j[3]) + ' /\n') f.write(third_line) except IndexError: pass #trimms efficiencies list efficiencies = equation_object.efficiencies trimmed_efficiencies = equation_object.efficiencies for s in efficiencies: if s not in trimmed_solution.species_names: del trimmed_efficiencies[s] replace_list_2 = {'{': '', '}': '/', '\'': '', ':': '/', ',': '/'} efficiencies_string = replace_multiple(str(trimmed_efficiencies), replace_list_2) fourth_line = str(efficiencies_string) + '\n' if bool(efficiencies) is True: f.write(fourth_line) #dupluicate option if equation_object.duplicate is True: duplicate_line = ' DUPLICATE' + '\n' f.write(duplicate_line) f.write('END') f.close() #Test mechanism file original_solution = solution #convert written chemkin file to cti, and get solution parser = ck2cti.Parser() outName = 'test_file.cti' parser.convertMech(output_file_name, outName=outName) new_solution = ct.Solution(outName) #test new solution vs original solutoin #test(original_solution, new_solution) os.remove(outName) return output_file_name """