def cantera_simulation_wrapper_example2(
        parametersArray):  #This takes in *only* the adjustable parameters.
    #Now we modify the 'initial' parameters array accordingly.
    #In this example, we're modifying reactions 2 and 4 which are indices 1 and 3.
    modified_reactions_parameters_array = copy.deepcopy(
        initial_reactions_parameters_array)

    #We now have... E_a1, E_a2, log_A1, log_A2, gamma_1, and gamma_2.
    #    E_a1 = parametersArray[0] #We are receiving in kJ/mol
    #    E_a2 =parametersArray[1] #We are receiving in kJ/mol
    #    log_A1 =parametersArray[2]
    #    log_A2 =parametersArray[3]
    #    gamma_1 =parametersArray[4] <-- this becomes small e in cantera.
    #    gamma_2 = parametersArray[5] <-- this becomes small e in cantera.
    modified_reactions_parameters_array[1][
        5] = parametersArray[0] * 1000  #convert from kJ/mol to J/mol
    modified_reactions_parameters_array[3][
        5] = parametersArray[1] * 1000  #convert from kJ/mol to J/mol
    modified_reactions_parameters_array[1][3] = 10**parametersArray[2]
    modified_reactions_parameters_array[3][3] = 10**parametersArray[3]
    modified_reactions_parameters_array[1][8] = 10**parametersArray[4]
    modified_reactions_parameters_array[3][8] = 10**parametersArray[5]

    #Now we do the simulation. The first time, we need to do a full simulation flow.  But second time and later we can just modify the cantera phases object and run again.
    global firstSimulation
    global canteraPhases  #need to make it global so the object sticks around for next function call.
    if firstSimulation == True:
        concentrationsArray, concentrationsArrayHeader, rates_all_array, rates_all_array_header, cantera_phase_rates, canteraPhases, cantera_phase_rates_headers, canteraSimulationsObject = \
        canteraSimulate.create_cti_and_SimulatePFRorTPRwithCantera(model_name, modified_reactions_parameters_array, ceO2_input_simulation_settings, cti_top_info_string = cti_top_info_string)
        firstSimulation = False
    elif firstSimulation == False:  #This must be an elif, otherwise it will always be executed. In this function, the cantera phases object will be created the first time the function is called. Then will exist for later.
        concentrationsArray, concentrationsArrayHeader, rates_all_array, rates_all_array_header, cantera_phase_rates, canteraPhases, cantera_phase_rates_headers, canteraSimulationsObject = \
        canteraSimulate.modify_reactions_and_SimulatePFRorTPRwithCantera(model_name, modified_reactions_parameters_array, ceO2_input_simulation_settings, canteraPhases=canteraPhases)

    #Now we parse the output.
    times = cantera_phase_rates['surf'][:, 1]  #This is in seconds.
    temperatures = ceO2_input_simulation_settings.heating_rate * times + ceO2_input_simulation_settings.T_surf
    totalAbsoluteRate = -1 * (cantera_phase_rates['surf'][:, 3] +
                              cantera_phase_rates['surf'][:, 4])

    #Now we convert units.
    totalAbsoluteRate = totalAbsoluteRate * 1000  #going from kmol/m^2/s to mol/m^2/s
    totalAbsoluteRate = totalAbsoluteRate * (
        1.0 / (100.0**2)
    )  # 1/m^2 * (1^2 m^2)/(100^2 cm^2)  gives mol/cm^2/s which is the units we want to compare to site density
    totalAbsoluteRate = totalAbsoluteRate / 2.72E-9  #now should be moles produced per moles of site, which is molecules per site per second.

    #Now we need to interpolate to the x_values that we need.
    #we use a global called x_values and assume that our output is a continuous function.
    global observed_x_values
    interpolatedRate = np.interp(observed_x_values, times, totalAbsoluteRate)

    return interpolatedRate
def cantera_simulation_wrapper_example5(
    parametersArray
):  #This takes in *only* the adjustable parameters. The modifiers for A and the modifiers for E are part of that.
    #Now we modify the 'initial' parameters array accordingly.
    #In this example, we're modifying reactions 2 and 4 which are indices 1 and 3.
    modified_reactions_parameters_array = copy.deepcopy(
        reactions_parameters_array)

    #We now have... E_a1, E_a2, log_A1, log_A2, gamma_1, and gamma_2.
    #    E_a1 = parametersArray[0] #We are receiving in kJ/mol
    #    E_a2 =parametersArray[1] #We are receiving in kJ/mol
    #    log_A1 =parametersArray[2]
    #    log_A2 =parametersArray[3]
    #    gamma_1 =parametersArray[4] <-- this becomes small e in cantera.
    #    gamma_2 = parametersArray[5] <-- this becomes small e in cantera.
    modified_reactions_parameters_array[1][
        5] = parametersArray[0] * 1000  #convert from kJ/mol to J/mol
    modified_reactions_parameters_array[3][
        5] = parametersArray[1] * 1000  #convert from kJ/mol to J/mol
    modified_reactions_parameters_array[1][3] = 10**parametersArray[2]
    modified_reactions_parameters_array[3][3] = 10**parametersArray[3]
    modified_reactions_parameters_array[1][8] = 10**parametersArray[4]
    modified_reactions_parameters_array[3][8] = 10**parametersArray[5]

    numIntervals = len(piecewise_coverage_intervals)
    numReactions = 4  #This is hard coded right now.
    num_modifiers_A = numIntervals
    num_modifiers_E = numIntervals
    #    modifiers_A_starting_index = 6
    #    modifiers_A_ending_index = modifiers_A_starting_index+num_modifiers_A
    new_modifiers_A = list(
        parametersArray[6:6 + num_modifiers_A]
    )  #The first 5 parameters are the original kinetic parameters.
    new_modifiers_E = list(parametersArray[6 + num_modifiers_A:6 +
                                           num_modifiers_A + num_modifiers_E])

    global modifiers_A_original
    global modifiers_E_original
    modifiers_A_list = list(
        modifiers_A_original)  #grabbing original values / last values
    modifiers_E_list = list(
        modifiers_E_original)  #grabbing original values / last values
    #    print("line 74", parametersArray)
    #    print("line 74", parametersArray[modifiers_A_starting_index:modifiers_A_ending_index])
    modifiers_A_list[
        1] = new_modifiers_A  #In this example, we're only modifying reaction at index 1.
    modifiers_E_list[
        1] = new_modifiers_E  #In this example, we're only modifying reaction at index 1.

    species_name = "Acetaldehyde1-Ce(S)"  #In this example we make the parameters depend only on the coverage of species Acetaldehyde1-Ce(S).
    kineticParameterName = "A"
    modifiers_A = tuple(modifiers_A_list)
    canteraKineticsParametersParser.populatePiecewiseCoverageDependence(
        ceO2_input_simulation_settings, reactions_parameters_array,
        species_name, kineticParameterName, piecewise_coverage_intervals,
        modifiers_A)
    species_name = "Acetaldehyde1-Ce(S)"  #In this example we make the parameters depend only on the coverage of species Acetaldehyde1-Ce(S).
    kineticParameterName = "E"
    modifiers_E = tuple(modifiers_E_list)
    canteraKineticsParametersParser.populatePiecewiseCoverageDependence(
        ceO2_input_simulation_settings, modified_reactions_parameters_array,
        species_name, kineticParameterName, piecewise_coverage_intervals,
        modifiers_E)

    #Now we do the simulation. The first time, we need to do a full simulation flow.  But second time and later we can just modify the cantera phases object and run again.
    global firstSimulation
    global canteraPhases  #need to make it global so the object sticks around for next function call.
    if firstSimulation == True:
        concentrationsArray, concentrationsArrayHeader, rates_all_array, rates_all_array_header, cantera_phase_rates, canteraPhases, cantera_phase_rates_headers, canteraSimulationsObject = \
        canteraSimulate.create_cti_and_SimulatePFRorTPRwithCantera(model_name, modified_reactions_parameters_array, ceO2_input_simulation_settings, cti_top_info_string = cti_top_info_string)
        firstSimulation = False
    elif firstSimulation == False:  #This must be an elif, otherwise it will always be executed. In this function, the cantera phases object will be created the first time the function is called. Then will exist for later.
        concentrationsArray, concentrationsArrayHeader, rates_all_array, rates_all_array_header, cantera_phase_rates, canteraPhases, cantera_phase_rates_headers, canteraSimulationsObject = \
        canteraSimulate.modify_reactions_and_SimulatePFRorTPRwithCantera(model_name, modified_reactions_parameters_array, ceO2_input_simulation_settings, canteraPhases=canteraPhases)

    #Now we parse the output.
    times = cantera_phase_rates['surf'][:, 1]  #This is in seconds.
    temperatures = ceO2_input_simulation_settings.heating_rate * times + ceO2_input_simulation_settings.T_surf
    totalAbsoluteRate = -1 * (cantera_phase_rates['surf'][:, 3] +
                              cantera_phase_rates['surf'][:, 4])

    #Now we convert units.
    totalAbsoluteRate = totalAbsoluteRate * 1000  #going from kmol/m^2/s to mol/m^2/s
    totalAbsoluteRate = totalAbsoluteRate * (
        1.0 / (100.0**2)
    )  # 1/m^2 * (1^2 m^2)/(100^2 cm^2)  gives mol/cm^2/s which is the units we want to compare to site density
    totalAbsoluteRate = totalAbsoluteRate / 2.72E-9  #now should be moles produced per moles of site, which is molecules per site per second.

    #Now we need to interpolate to the x_values that we need.
    #we use a global called x_values and assume that our output is a continuous function.
    global observed_x_values
    interpolatedRate = np.interp(observed_x_values, times, totalAbsoluteRate)

    return interpolatedRate
    #    print("Initial Reactions Parameters Array")
    #    print(reactions_parameters_array)
    #
    if checkResult == True:  #In this example, we are only proceeding if the coverage dependance is always decreasing with coverage.
        canteraKineticsParametersParser.populatePiecewiseCoverageDependence(
            ceO2_input_simulation_settings, reactions_parameters_array,
            species_name, kineticParameterName, piecewise_coverage_intervals,
            modifiers_E)

        cti_top_info_filename = model_location + model_name + "_cti_top_info.cti"
        with open(cti_top_info_filename, "r") as cti_top_info_file:
            cti_top_info_string = cti_top_info_file.read()

        modified_reactions_parameters_array = reactions_parameters_array
        concentrationsArray, concentrationsArrayHeader, rates_all_array, rates_all_array_header, cantera_phase_rates, canteraPhases, cantera_phase_rates_headers, canteraSimulationsObject = \
        canteraSimulate.create_cti_and_SimulatePFRorTPRwithCantera("ceO2", modified_reactions_parameters_array, ceO2_input_simulation_settings, cti_top_info_string = cti_top_info_string)

        #Playing with the variables we see we can get what we want from:
        #    print(cantera_phase_rates['surf'])
        times = cantera_phase_rates['surf'][:, 1]  #This is in seconds.
        temperatures = ceO2_input_simulation_settings.heating_rate * times + ceO2_input_simulation_settings.T_surf
        #    print(np.shape(cantera_phase_rates['surf']))
        totalAbsoluteRate = -1 * (cantera_phase_rates['surf'][:, 3] +
                                  cantera_phase_rates['surf'][:, 4])

        #To convert totalAbsoluteCoverages to relative coverages, we recognize that cantera uses rates of kmol/m^2/s
        #See this link for more information on cantera units: https://github.com/Cantera/cantera/issues/760
        #Surface site density: 2.72E-9 mol/cm**2 , so now we need to convert...
        #Let's make some conversion factors for convenience....
        totalAbsoluteRate = totalAbsoluteRate * 1000  #going from kmol/m^2/s to mol/m^2/s
        totalAbsoluteRate = totalAbsoluteRate * (