def pfa_loop_control(solution_object, args, stored_error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array): target_species = args.target #run detailed mechanism and retain initial conditions species_retained = [] printout = '' print('Threshold Species in Mech Error') #run DRG and create new reduced solution pfa = trim_pfa(rate_edge_data, solution_object, threshold, args.keepers, done,target_species) #Find out what to cut from the model exclusion_list = pfa new_solution_objects = trim(solution_object, exclusion_list, args.data_file) #Cut the exclusion list from the model. species_retained.append(len(new_solution_objects[1].species())) #simulated reduced solution new_sim = helper.setup_simulations(conditions_array,new_solution_objects[1]) #Create simulation objects for reduced model for all conditions ignition_delay_reduced = helper.simulate(new_sim) #Run simulations and process results if (ignition_delay_detailed.all() == 0): #Ensure that ignition occured print("Original model did not ignite. Check initial conditions.") exit() #Calculate error error = (abs(ignition_delay_reduced-ignition_delay_detailed)/ignition_delay_detailed)*100 #Calculate error printout += str(threshold) + ' ' + str(len(new_solution_objects[1].species())) + ' '+ str(round(np.max(error), 2)) +'%' + '\n' print(printout) stored_error[0] = round(np.max(error), 2) #Return new model. new_solution_objects = new_solution_objects[1] return new_solution_objects
def run_pfa(args, solution_object,error,past): if len(args.target) == 0: #If the target species are not specified, puke and die. print("Please specify a target species.") exit() done = [] #Singleton to hold wether or not any more species can be cut from the simulation. done.append(False) threshold = .1 #Starting threshold value threshold_i = .1 n = 1 error = [10.0] #Singleton to hold the error value of the previously ran simulation. #Check to make sure that conditions exist if args.conditions_file: conditions_array = readin_conditions(str(args.conditions_file)) elif not args.conditions_file: print("Conditions file not found") exit() sim_array = helper.setup_simulations(conditions_array,solution_object) #Turn conditions array into unran simulation objects for the original solution ignition_delay_detailed = helper.simulate(sim_array) #Run simulations and process results rate_edge_data = get_rates_pfa(sim_array, solution_object) #Get edge weight calculation data. print("Testing for starting threshold value") pfa_loop_control(solution_object, args, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) #Trim the solution at that threshold and find the error. while error[0] != 0: #While the error for trimming with that threshold value is greater than allowed. threshold = threshold / 10 #Reduce the starting threshold value and try again. threshold_i = threshold_i / 10 n = n + 1 pfa_loop_control(solution_object, args, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) if error[0] <= .02: error[0] = 0 print("Starting with a threshold value of " + str(threshold)) sol_new = solution_object past[0] = 0 #An integer representing the error introduced in the past simulation. done[0] = False while not done[0] and error[0] < args.error: #Run the simulation until nothing else can be cut. sol_new = pfa_loop_control( solution_object, args, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) #Trim at this threshold value and calculate error. if args.error > error[0]: #If a new max species cut without exceeding what is allowed is reached, save that threshold. max_t = threshold #if (past == error[0]): #If error wasn't increased, increase the threshold at a higher rate. # threshold = threshold + (threshold_i * 4) past[0] = error[0] #if (threshold >= .01): # threshold_i = .01 threshold = threshold + threshold_i threshold = round(threshold, n) print("\nGreatest result: ") sol_new = pfa_loop_control( solution_object, args, error, max_t, done, rate_edge_data, ignition_delay_detailed, conditions_array) drgep_trimmed_file = soln2cti.write(sol_new) #Write the solution object with the greatest error that isn't over the allowed ammount. return sol_new[1]
def pfa_loop_control(solution_object, target_species, retained_species, model_file, stored_error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array): """ This function handles the reduction, simulation, and comparision for a single threshold value Parameters ---------- solution_object: object being reduced # target_species: target_species: The target species for reduction retained_species: A list of species to be retained even if they should be cut by the algorithm model_file: The path to the file where the solution object was generated from stored_error: Error from the previous reduction attempt threshold: current threshold value done: are we done reducing yet? Boolean rate_edge_data: the DICs for reduction ignition_delay_detailed: ignition delay of detailed model conditions_array: array holding information about initial conditions Returns ------- Returns the reduced solution object for this threshold and updates error value """ # Run detailed mechanism and retain initial conditions species_retained = [] printout = '' print('Threshold Species in Mech Error') # Run DRG and create new reduced solution exclusion_list = trim_pfa( rate_edge_data, solution_object, threshold, retained_species, done,target_species,model_file) # Find out what to cut from the model new_solution_objects = trim(solution_object, exclusion_list, model_file) # Cut the exclusion list from the model. species_retained.append(len(new_solution_objects[1].species())) # Simulated reduced solution new_sim = helper.setup_simulations(conditions_array,new_solution_objects[1]) # Create simulation objects for reduced model for all conditions ignition_delay_reduced = helper.simulate(new_sim) # Run simulations and process results if (ignition_delay_detailed.all() == 0): # Ensure that ignition occured print("Original model did not ignite. Check initial conditions.") exit() # Calculate error error = (abs(ignition_delay_reduced-ignition_delay_detailed)/ignition_delay_detailed)*100 # Calculate error printout += str(threshold) + ' ' + str(len(new_solution_objects[1].species())) + ' '+ str(round(np.max(error), 2)) +'%' + '\n' print(printout) stored_error[0] = round(np.max(error), 2) # Return new model new_solution_objects = new_solution_objects[1] return new_solution_objects
def get_limbo_dic(original_model, reduced_model, limbo, final_error, args, id_detailed, conditions_array): dic = {} og_excl = [ ] #For information on how this is set up, refer to run_sa function. keep = [] og_sn = [] new_sn = [] species_objex = reduced_model.species() for sp in species_objex: new_sn.append(sp.name) species_objex = original_model.species() for sp in species_objex: og_sn.append(sp.name) for sp in og_sn: if sp in new_sn: keep.append(sp) for sp in original_model.species(): if not (sp.name in keep): og_excl.append(sp.name) for sp in limbo: #For all species in limbo excluded = [sp] for p in og_excl: excluded.append(p) #Add that species to the list of exclusion. new_sol_obs = trim(original_model, excluded, "sa_trim.cti") #Remove species from the model. new_sol = new_sol_obs[1] #simulated reduced solution new_sim = helper.setup_simulations( conditions_array, new_sol ) #Create simulation objects for reduced model for all conditions id_new = helper.simulate(new_sim) #Run simulations and process results error = (abs(id_new - id_detailed) / id_detailed) * 100 error = round(np.max(error), 2) print(sp + ": " + str(error)) error = abs(error - final_error) dic[sp] = error #Add adjusted error to dictionary. return dic
def drg_loop_control(solution_object, target_species, retained_species, model_file, stored_error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array): """Handles the reduction, simulation, and comparision for a single threshold value. Parameters ---------- solution_object: object being reduced target_species : list of str List of target species retained_species : list of str List of species to always be retained model_file : string The path to the file where the solution object was generated from stored_error: signleton float Error of this reduced model simulation threshold : float current threshold value done : bool are we done reducing yet? rate_edge_data : information for calculating the DICs for reduction ignition_delay_detailed : ignition delay of detailed model conditions_array : array holding information about initial conditions Returns ------- Reduced solution object for this threshold and updates error value """ species_retained = [] printout = '' print('Threshold Species in Mech Error') # Run DRG and create new reduced solution # Find out what to cut from the model exclusion_list = trim_drg(rate_edge_data, solution_object, threshold, retained_species, done, target_species) # Cut the exclusion list from the model. new_solution_objects = trim(solution_object, exclusion_list, model_file) species_retained.append(len(new_solution_objects[1].species())) # Simulated reduced solution # Create simulation objects for reduced model for all conditions new_sim = helper.setup_simulations(conditions_array, new_solution_objects[1]) ignition_delay_reduced = helper.simulate( new_sim) # Run simulations and process results if ignition_delay_detailed.all() == 0: # Ensure that ignition occured print("Original model did not ignite. Check initial conditions.") exit() # Calculate error error = (abs(ignition_delay_reduced - ignition_delay_detailed) / ignition_delay_detailed) * 100 # Calculate error printout += str(threshold) + ' ' + str( len(new_solution_objects[1].species())) + ' ' + str( round(np.max(error), 2)) + '%' + '\n' print(printout) stored_error[0] = round(np.max(error), 2) # Return new model. new_solution_objects = new_solution_objects[1] return new_solution_objects
def run_drg(solution_object, conditions_file, error_limit, target_species, retained_species, model_file, final_error): """ Main function for running DRG reduction. Parameters ---------- solution_object : ~cantera.Solution A Cantera object of the solution to be reduced. conditions_file : str Name of file with list of autoignition initial conditions. error_limit : float Maximum allowable error level for reduced model. target_species : list of str List of target species retained_species : list of str List of species to always be retained model_file : string The path to the file where the solution object was generated from final_error: singleton float To hold the error level of simulation Returns ------- Writes reduced Cantera file and returns reduced Cantera solution object """ assert target_species, 'Need to specify at least one target species.' # Singleton to hold whether any more species can be cut from the simulation. done = [] done.append(False) threshold = 0.1 # Starting threshold value threshold_increment = 0.1 num_iterations = 1 error = [10.0] conditions_array = readin_conditions(conditions_file) # Turn conditions array into unrun simulation objects for the original solution sim_array = helper.setup_simulations(conditions_array, solution_object) # Run simulations and process results ignition_delay_detailed = helper.simulate(sim_array) # Get edge weight calculation data. rate_edge_data = get_rates_drg(sim_array, solution_object) print("Testing for starting threshold value") # Trim the solution at that threshold and find the error. drg_loop_control(solution_object, target_species, retained_species, model_file, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) # While the error for trimming with that threshold value is greater than allowed. while error[0] != 0: # Reduce the starting threshold value and try again. threshold /= 10 threshold_increment /= 10 num_iterations += 1 drg_loop_control(solution_object, target_species, retained_species, model_file, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) if error[0] <= 0.02: error[0] = 0 print("Starting with a threshold value of " + str(threshold)) sol_new = solution_object final_error[0] = 0 done[0] = False # Run the simulation until nothing else can be cut. while not done[0] and error[0] < error_limit: # Trim at this threshold value and calculate error. sol_new = drg_loop_control(solution_object, target_species, retained_species, model_file, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) # If a new max species cut without exceeding what is allowed is reached, save that threshold. if error_limit > error[0]: max_t = threshold final_error[0] = error[0] # if (final_error[0] == error[0]): #If error wasn't increased, increase the threshold at a higher rate. # threshold = threshold + (threshold_increment * 4) # if (threshold >= .01): # threshold_increment = .01 threshold += threshold_increment threshold = round(threshold, num_iterations) print("Greatest result: ") sol_new = drg_loop_control(solution_object, target_species, retained_species, model_file, error, max_t, done, rate_edge_data, ignition_delay_detailed, conditions_array) return sol_new
def run_sa(original_model, reduced_model, ep_star, final_error, args): print(final_error) if args.conditions_file: conditions_array = readin_conditions(str(args.conditions_file)) elif not args.conditions_file: print("Conditions file not found") exit() sim_array = helper.setup_simulations( conditions_array, original_model ) #Turn conditions array into unran simulation objects for the original solution id_detailed = helper.simulate( sim_array) #Run simulations and process results rate_edge_data = get_rates( sim_array, original_model) #Get edge weight calculation data. drgep_coeffs = make_dic_drgep( original_model, rate_edge_data, args.target) #Make a dictionary of overall interaction coefficients. if (id_detailed.all() == 0): #Ensure that ignition occured print("Original model did not ignite. Check initial conditions.") exit() old = reduced_model while True: og_sn = [] #Original species names new_sn = [] #Species names in current reduced model keep = [] #Species retained from removals og_excl = [ ] #Species that will be excluded from the final model (Reduction will be preformed on original model) species_objex = old.species() for sp in species_objex: new_sn.append(sp.name) species_objex = original_model.species() for sp in species_objex: og_sn.append(sp.name) for sp in og_sn: if sp in new_sn: keep.append(sp) for sp in original_model.species(): if not (sp.name in keep): og_excl.append(sp.name) limbo = create_limbo(old, ep_star, drgep_coeffs, args.keepers) #Find all the species in limbo. if len(limbo) == 0: return old print("In limbo:") print(limbo) dic = get_limbo_dic( original_model, old, limbo, final_error, args, id_detailed, conditions_array ) #Calculate error for removing each limbo species. rm = dic_lowest(dic) #Species that should be removed (Lowest error). exclude = [rm] for sp in og_excl: #Add to list of species that should be excluded from final model. exclude.append(sp) print() print("attempting to remove " + rm) new_sol_obs = trim( original_model, exclude, "sa_trim.cti") #Remove exclusion list from original model new_sol = new_sol_obs[1] #simulated reduced solution new_sim = helper.setup_simulations( conditions_array, new_sol ) #Create simulation objects for reduced model for all conditions id_new = helper.simulate(new_sim) #Run simulations and process results error = (abs(id_new - id_detailed) / id_detailed) * 100 error = round(np.max(error), 2) print("Error of: " + str(error)) print() if error > args.error: #If error is greater than allowed, previous reduced model was final reduction. print("Final Solution:") print(str(old.n_species) + " Species") return old else: #If error is still within allowed limit, loop through again to further reduce. old = new_sol
def run_pfa(solution_object, conditions_file, error_limit, target_species, retained_species, model_file, final_error): """" This is the MAIN top level function for running PFA Parameters ---------- solution_object: a Cantera object of the solution to be reduced conditions_file: The file holding the initial conditions to simulate error_limit: The highest allowed error percentage target_species: The target species for reduction retained_species: A list of species to be retained even if they should be cut by the algorithm model_file: The path to the file where the solution object was generated from final_error: To hold the error level of the simulation Returns ------- Writes reduced Cantera file and returns reduced Catnera solution object """ if len(target_species) == 0: # If the target species are not specified, puke and die. print("Please specify a target species.") exit() done = [] # Singleton to hold wether or not any more species can be cut from the simulation. done.append(False) threshold = .1 # Starting threshold value threshold_i = .1 n = 1 error = [10.0] # Singleton to hold the error value of the previously ran simulation. # Check to make sure that conditions exist if conditions_file: conditions_array = readin_conditions(str(conditions_file)) elif not conditions_file: print("Conditions file not found") exit() # Turn conditions array into unran simulation objects for the original solution sim_array = helper.setup_simulations(conditions_array,solution_object) ignition_delay_detailed = helper.simulate(sim_array) #Run simulations and process results rate_edge_data = get_rates_pfa(sim_array, solution_object) #Get edge weight calculation data. print("Testing for starting threshold value") # Trim the solution at that threshold and find the error. pfa_loop_control( solution_object, target_species, retained_species, model_file, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) while error[0] != 0: # While the error for trimming with that threshold value is greater than allowed. threshold = threshold / 10 # Reduce the starting threshold value and try again. threshold_i = threshold_i / 10 n = n + 1 pfa_loop_control( solution_object, target_species, retained_species, model_file, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) if error[0] <= .02: error[0] = 0 print("Starting with a threshold value of " + str(threshold)) sol_new = solution_object final_error[0] = 0 # An integer representing the error introduced in the final simulation. done[0] = False while not done[0] and error[0] < error_limit: # Run the simulation until nothing else can be cut. # Trim at this threshold value and calculate error. sol_new = pfa_loop_control( solution_object, target_species, retained_species, model_file, error, threshold, done, rate_edge_data, ignition_delay_detailed, conditions_array) if error_limit >= error[0]: # If a new max species cut without exceeding what is allowed is reached, save that threshold. max_t = threshold #if (final_error == error[0]): #If error wasn't increased, increase the threshold at a higher rate. # threshold = threshold + (threshold_i * 4) final_error[0] = error[0] #if (threshold >= .01): # threshold_i = .01 threshold = threshold + threshold_i threshold = round(threshold, n) print("\nGreatest result: ") sol_new = pfa_loop_control( solution_object, target_species, retained_species, model_file, error, max_t, done, rate_edge_data, ignition_delay_detailed, conditions_array) return sol_new
def drgep_loop_control(solution_object, target_species, retained_species, model_file, stored_error, threshold, done, max_dic, ignition_delay_detailed, conditions_array): """ This function handles the reduction, simulation, and comparision for a single threshold value. Parameters ---------- solution_object: object being reduced target_species: An array of the target species for reduction retained_species: An array of species that should not be removed from the model model_file: The path to the file holding the original model stored_error: past error threshold: current threshold value done: are we done reducing yet? Boolean max_dic: OIC dictionary for DRGEP ignition_delay_detailed: ignition delay of detailed model conditions_array: array holding information about initial conditions Returns ------- Returns the reduced solution object for this threshold and updates error value """ # Run detailed mechanism and retain initial conditions species_retained = [] printout = '' print('Threshold Species in Mech Error') # Run DRGEP and create new reduced solution exclusion_list = trim_drgep(max_dic, solution_object, threshold, retained_species, done) # Find out what to cut from the model new_solution_objects = trim( solution_object, exclusion_list, model_file) # Cut the exclusion list from the model. species_retained.append(len(new_solution_objects[1].species())) # Simulated reduced solution new_sim = helper.setup_simulations( conditions_array, new_solution_objects[1] ) # Create simulation objects for reduced model for all conditions ignition_delay_reduced = helper.simulate( new_sim) # Run simulations and process results if ignition_delay_detailed.all() == 0: # Ensure that ignition occured print("Original model did not ignite. Check initial conditions.") exit() # Calculate and print error. error = (abs(ignition_delay_reduced - ignition_delay_detailed) / ignition_delay_detailed) * 100 # Calculate error printout += str(threshold) + ' ' + str( len(new_solution_objects[1].species())) + ' ' + str( round(np.max(error), 2)) + '%' + '\n' print(printout) stored_error[0] = round(np.max(error), 2) # Return new model new_solution_objects = new_solution_objects[1] return new_solution_objects
def get_limbo_dic(original_model, reduced_model, limbo, final_error, id_detailed, conditions_array): """ Creates a dictionary of all of the species in limbo and their errors for sensitivity analysis. Parameters ---------- original_model: The original version of the model being reduced reduced_model: The model produced by the previous reduction limbo: A list of the species in limbo final_error: Error percentage between the reduced and origanal models id_detailed: The ignition delays for each simulation of the original model conditions_array: An array holding the initial conditions for simulations Returns ------- A dictionary with species error to be used for sensitivity anaylsis. """ dic = {} # For information on how this is set up, refer to run_sa function. og_excl = [] keep = [] og_sn = [] new_sn = [] species_objex = reduced_model.species() for sp in species_objex: new_sn.append(sp.name) species_objex = original_model.species() for sp in species_objex: og_sn.append(sp.name) for sp in og_sn: if sp in new_sn: keep.append(sp) for sp in original_model.species(): if not (sp.name in keep): og_excl.append(sp.name) for sp in limbo: # For all species in limbo excluded = [sp] for p in og_excl: excluded.append(p) # Add that species to the list of exclusion. # Remove species from the model. new_sol_obs = trim(original_model, excluded, "sa_trim.cti") new_sol = new_sol_obs[1] # Simulated reduced solution new_sim = helper.setup_simulations( conditions_array, new_sol ) # Create simulation objects for reduced model for all conditions id_new = helper.simulate( new_sim) # Run simulations and process results error = (abs(id_new - id_detailed) / id_detailed) * 100 error = round(np.max(error), 2) print(sp + ": " + str(error)) error = abs(error - final_error) dic[sp] = error # Add adjusted error to dictionary. return dic
def run_sa(original_model, reduced_model, ep_star, final_error, conditions_file, target, keepers, error_limit): """ Runs a sensitivity analysis on a resulting reduced model. Parameters ---------- original_model: The original version of the model being reduced reduced_model: The model produced by the previous reduction ep_star: The epsilon star value for the sensitivity analysis final_error: Error percentage between the reduced and origanal models conditions_file: The file holding the initial conditions for simulations target: The target species for the reduction keepers: A list of species that should be retained no matter what error_limit: The maximum allowed error between the reduced and original models Returns ------- The model after the sensitivity analysis has been preformed on it. """ if conditions_file: conditions_array = readin_conditions(str(conditions_file)) elif not conditions_file: print("Conditions file not found") exit() # Turn conditions array into unran simulation objects for the original solution sim_array = helper.setup_simulations(conditions_array, original_model) id_detailed = helper.simulate( sim_array) # Run simulations and process results rate_edge_data = get_rates( sim_array, original_model) # Get edge weight calculation data. # Make a dictionary of overall interaction coefficients. drgep_coeffs = make_dic_drgep(original_model, rate_edge_data, target) if (id_detailed.all() == 0): # Ensure that ignition occured print("Original model did not ignite. Check initial conditions.") exit() old = reduced_model while True: og_sn = [] # Original species names new_sn = [] # Species names in current reduced model keep = [] # Species retained from removals og_excl = [ ] # Species that will be excluded from the final model (Reduction will be preformed on original model) species_objex = old.species() for sp in species_objex: new_sn.append(sp.name) species_objex = original_model.species() for sp in species_objex: og_sn.append(sp.name) for sp in og_sn: if sp in new_sn: keep.append(sp) for sp in original_model.species(): if not (sp.name in keep): og_excl.append(sp.name) # Find all the species in limbo. limbo = create_limbo(old, ep_star, drgep_coeffs, keepers) if len(limbo) == 0: return old print("In limbo:") print(limbo) # Calculate error for removing each limbo species. dic = get_limbo_dic(original_model, old, limbo, final_error, id_detailed, conditions_array) rm = dic_lowest(dic) # Species that should be removed (Lowest error). exclude = [rm] for sp in og_excl: # Add to list of species that should be excluded from final model. exclude.append(sp) print() print("attempting to remove " + rm) # Remove exclusion list from original model new_sol_obs = trim(original_model, exclude, "sa_trim.cti") new_sol = new_sol_obs[1] # Simulated reduced solution new_sim = helper.setup_simulations( conditions_array, new_sol ) # Create simulation objects for reduced model for all conditions id_new = helper.simulate( new_sim) # Run simulations and process results error = (abs(id_new - id_detailed) / id_detailed) * 100 error = round(np.max(error), 2) print("Error of: " + str(error)) print() # If error is greater than allowed, previous reduced model was final reduction. if error > error_limit: print("Final Solution:") print(str(old.n_species) + " Species") return old else: # If error is still within allowed limit, loop through again to further reduce. old = new_sol