StoveOpt.post_processor — StoveOpt documentation

# Source code for StoveOpt.post_processor

    # -*- coding: utf-8 -*-
    """
    Created on Sun May 19 18:18:31 2019

    @author: Lee
    """

    # Modules will pull all of the temperature versus time data from the original runs

    # Should put the data into HDF5 tables as discussed in class

    # Create a rank of the maximum average temperature (on full pot body)

    # This needs to be a more dynamic module with values stored for future iteration

    #Data import test: for 3 example files, pull expected first value, last value, and middle value

    import os
    from os import walk
    from os import path
    from sys import path
    import numpy as np
    from numpy import hstack, vstack, sort, transpose, argsort, append
    import matplotlib.pyplot as plt
    #import h5py

    def data_import():
        """input a list of filenames to be pulled, put out an array of temperature data. search the foamfiles directory for fnames that start with case_ and tally the number for looping through the file. loop through each and pull data from the files (3) convert to numpy arrays (4) store.

        Parameters
        ----------

        dir_list
            Dictionary of directory titles in the 'foamfiles' directory that begin with string 'case_'

        case_list
            Dictionary of case file paths. Appended iteratively with dir_list entries.

        length_case_list
            Type: integer. Number of excecuted case files existing in foamfiles directory

        list_temps
            Type: float array. Populated with results from probing the CFD simulation around entire pot geometry

        list_velocities
            Type: float array. Populated with velocity values written to "details" file in individual case files

        """
        # navigate to the foamfiles directory
        current_directory = os.getcwd()
        #foamfile_steps = "foamfiles\counterFlowFlame2D\"
        #foamfile_path = current_directory + foamfile_steps
        foamfile_path = "C:\\Oregon_State\\Spring_2019\\Soft_dev_eng\\StoveOpt\\foamfiles\\counterFlowFlame2D\\"
        dir_list = [directory for directory in os.listdir(foamfile_path) if os.path.isdir(foamfile_path+directory)]
        print(dir_list)
        length_dir_list = len(dir_list)
        print("The length of the dir list: " + str(length_dir_list))
        detect_prefix = 'case' # look for case prefix

        i = 0 # for looping
        case_counter = 0
        case_list = [None] # empty vector
        print(case_list)
        k = 0 # case list indices
        while i < length_dir_list:
            if dir_list[i].startswith(detect_prefix):
                print(dir_list[i])
                #case_counter = case_counter  + 1
                case_list_append = dir_list[i]
                case_list[k] = case_list.append(str(dir_list[i]))
                print("here is k: " + str(k))
                print("here is i: " + str(i))

                case_list[k] = dir_list[i]
                print("case list k")
                print(case_list[k])
                k = k+1
                #print(case_list, sep = ", ")
            i = i+1

        # remove the final entry of the case_list vector
        case_list_length = len(case_list)
        print("case_list_length")
        print(case_list_length)
        omitted_value= case_list.pop(case_list_length-1)
        print("omitted value")
        print(omitted_value)
        print("Updated case list")
        print(case_list)

        # extract and go read data from each of the files
        """(1) Loop through the case_list produced, (2) pull the strings and
        (3) add to the correct file extension. (4) open and read the data in.
        (5) create tables in numpy (potentially). (6) return the arrays in the overall function"""

        length_case_list = len(case_list)
        print("case list length: " + str(length_case_list))
        j = 0
        Temps = []
        Velocities = [] # reading in the 25-150 velocities
        list_temps = []
        list_velocities = []
        while j < length_case_list:
            fname = str(case_list[j]) # pull the case file name
            dir_steps = "\\postProcessing\\probes\\0\\"
            U_dir_steps = "\\0\\"
            U_fname = "details"
            Temp_fname = "T"
            full_path = foamfile_path + fname + dir_steps + Temp_fname # this will need to be edited for a more advanced file loc
            U_full_path = foamfile_path + fname + U_dir_steps + U_fname # varies for the cases (fname)
            with open(U_full_path, 'r') as f:
                f.seek(10) # position 10 is the beginning of line 2
                Velocity = f.readlines() # read line 2nd line
                print("Here is your velocity")
                print(Velocity) # seems to be working
                globals()['Velocities%s' % j] = Velocity # putting this into the Velocity matrix, renaming based on j to match cases
                list_velocities.append(globals()['Velocities%s' % j])

            globals()['Temps%s' % j] = np.loadtxt(fname = full_path)
            list_temps.append(globals()['Temps%s' % j])
            j = j+1
        print("here are the list temps: ")
        print(list_temps)
        print(Temps1)
        type_Temps1 = type(Temps1)
        print(type_Temps1)
        shape_Temp1 = Temps1.shape
        print("Temps1 size (rows by cols): " + str(shape_Temp1))
        print("Here is the velocity matrix for case 1")
        print(Velocities0) # solid

        # Concatenate all the temperatures
        """while the index is under the length of case list (# of temp vars)
                add the temperature arrays to a list  (list temps)"""

        # Create list of the arrays
        """Temp_array_list = []
        while x < length_case_list:"""

        # Validates the list_temp is a group of the arrays
        first_temp_list_entry = list_temps[0]
        print("This is the 0-entry in the list_temps situaton")
        print(first_temp_list_entry)
        print("Velocity matrix")
        print(list_velocities)
        return dir_list, case_list, length_case_list, list_temps, list_velocities

    #dir_list, case_list, length_case_list, list_temps, list_velocities = data_import()

    def average_pot_temperature(list_temps, length_case_list, list_velocities, case_list):
        """
        Compute average temperatures of each of the case temperature arrays previously extracted with data_import()

        Parameters
        ----------

        new_recarr
            Numpy array where column 1 is case title (str), second column is velocites for respective case, and third column is computed average pot temperature for specific case

        """
        #(1) loop through the Temperature probe data and pull the final row of the array. The first entry is the time step associated with the final row
        # Convert the list_velocities to numpy array
        list_velocities_array = np.asarray(list_velocities)
        print("List velocities as array: ")
        print(list_velocities_array)

        list_velocities_array_transpose = list_velocities_array.transpose()

        # convert case list to array
        case_list_array_empty = np.empty([length_case_list,1], dtype = "U10")
        shape_case_list_array_empty = case_list_array_empty.shape
        print("Shape case list array empty: ")
        print(case_list_array_empty)

        l = 0
        while l < length_case_list:
            case_list_array_empty[l] = case_list[l]
            l = l +1
            print("case list array empty")
            print(case_list_array_empty)
            #case_list_array = np.ndarray.transpose(case_list_array_empty)
            case_list_array = case_list_array_empty
            print("Case list array")
            print(case_list_array)

        case_list_array_shape = case_list_array.shape
        print("Case list array shape")
        print(case_list_array_shape)

        final_temp_row = [] # empty vector to be filled  with the bottom row temperatures iteratively
        final_temp_row_matrix = [] # filling the full matrix with bottom rows iteratively
        final_temp_row_averages = [] # to be filled with the average temperatures of the final rows
        case_size = length_case_list # how many cases are included (-1 due to the 0 counting in python)
        number_properties = 3 # case#, velocity, avg temps to be included in the matrix

        final_temp_averages_empty = np.empty([length_case_list, 1], dtype = float)
        # Pulling the bottom row from the individual case
        x = 0 # setting loop condition
        while x < length_case_list:
            print("list temps before error")
            print(list_temps)
            # Pull the individual temperature array, pull dimensions
            Temp_array = list_temps[x]
            print("Temp array right before the error")
            print(Temp_array)
            [rows, cols] = Temp_array.shape
            final_row = rows - 1 # navigating to the final row of temperature array
            print("Final_row")
            print(final_row)
            final_col_entry = cols # last column of the array
            first_col_entry = 1 # skip the time stamp

            # pull the final row of the temperature matrix
            final_temp_row = Temp_array[final_row, first_col_entry:final_col_entry]

            # Add to the final_temp_row_matrix
            if x == 0:
                final_temp_row_matrix = final_temp_row
            else:
                final_temp_row_matrix = np.append(final_temp_row_matrix, final_temp_row)

            # Compute average
            temp_average = np.average(final_temp_row)

            final_temp_averages_empty[x] = temp_average
            final_temp_averages = final_temp_averages_empty
            print("final temp row averages")
            print(final_temp_averages)

            # Checking functionality
            if x == 0:
                print("here is the temp_array")
                print(Temp_array)
                print("print final_temp_row")
                print(final_temp_row)
                print("average temperature")
                print(temp_average)
                print("final_temp_row_matrix")
                print(final_temp_row_matrix)
            else:
                print("moving on from 0")

            x = x +1
            print("x equals: ")
            print(x)
        # Append the temperature single column matrix with the corresponding velocities
        # Float results
        #float_cols = 2
        #results_float_matrix = np.empty(case_size, float_cols)

        # String column (cases)
        #string_cols = 1
        #results_string_matrix = np.empty(case_size, float_cols)

        # Data types for array
        dt = np.dtype([('col0', 'U10'), ('col1', float), ('col2', float)]) # first col is cases, then velocities, then temps

        final_temp_row_averages_array = np.asarray(final_temp_row_averages)
        print("final temp row avg array")
        print(final_temp_row_averages_array)
        final_temp_row_averages_array_transpose = final_temp_row_averages_array.transpose()

        new_recarr = np.empty([length_case_list,3], dtype=dt)
        new_recarr['col0'] = case_list_array
        new_recarr['col1'] = list_velocities_array
        new_recarr['col2'] = final_temp_averages

        print("new_recarr")
        print(new_recarr)

        test_value = new_recarr[2, 2]
        print("value (2,2) :")
        print(test_value)

        # This makes sense
        test_value_velocity = test_value[1] # take the center value from the list
        print("Test velocity pulling :")
        print(test_value_velocity)

        test_first_index = new_recarr[1]
        print("index 1:")
        print(test_first_index)

        test_column = new_recarr[:,1]
        print("cases: ")
        print(test_column)
        return new_recarr

    #new_recarr = average_pot_temperature(list_temps, length_case_list, list_velocities, case_list)

    #def average_composition_outlets(list_GHG)
    """Take in a list of GHGs from a separate data import for the outlet nodes"""

    def parse_and_sort_array(new_recarr, length_case_list):
        """
        Sort new_recarr array based on velocities, return the array with a new name

        Parameters
        ----------

        array_sorted
            Numpy array. Same data as new_recarr, but sorted based on velocities (least to greatest along column 2)

        """
        # Algorithm:
        # (1) parse the array and create a parsed version

        case_vector = np.empty([length_case_list], dtype = "U10")
        velocity_vector = np.empty([length_case_list], dtype = float)
        temperature_vector = np.empty([length_case_list], dtype = float)

        print("shape of case vector")
        print(case_vector.shape)

        case_column = 0
        temperature_column = 2
        velocity_column = 1

        #dtype='S10,f4,f4,f4'
        # Add the cases to column 1
        # Loop through the new_recarr array, extract the case names and add them to column 1
        x = 0 # looping index
        while x < length_case_list:
            entry = new_recarr[x, 1]
            print("Entry")
            print(entry)
            case_name= str(entry[case_column])
            velocity_entry = entry[velocity_column]
            temperature_entry = entry[temperature_column]

            # Add the values to the empty vectors.
            case_vector[x] = case_name
            velocity_vector[x] = velocity_entry
            temperature_vector[x] = temperature_entry

            x = x + 1

        print("case vector")
        print(case_vector)

        print("velocity vector")
        print(velocity_vector)

        print("temperature vector")
        print(temperature_vector)

        parsed_new_recarr = hstack((case_vector, velocity_vector, temperature_vector))
        parsed_new_recarr_no_case_transposed = vstack((transpose(velocity_vector), transpose(temperature_vector)))
        parsed_new_recarr_no_case = vstack((velocity_vector,temperature_vector))

        print("parsed new recarr after column assignments")
        print(parsed_new_recarr)

        print("parsed new recarr, no cases, not transposed")
        print(parsed_new_recarr_no_case)

        print("shape of parsed new recarr after vectors added")
        print(parsed_new_recarr_no_case.shape)

        """print("shape of parsed new recarr, no cases, transpose")
        print(parsed_new_recarr_no_case_transposed.shape)"""

        #arr[arr[:, 1].argsort()]

        array_transpose = transpose(parsed_new_recarr_no_case)
        print("array transposed")
        print(array_transpose)

        array_sorted = array_transpose[array_transpose[:,0].argsort()]
        print("array sorted")
        print(array_sorted)

        return array_sorted

    #array_sorted = parse_and_sort_array(new_recarr)

    def evaluate_optimal(array_sorted, length_case_list):
        """
        The function evaluates the temperature and velocity data, and uses the information to identify where the optimals live within the range analayzed

        Parameters
        ----------

        array_sorted
            Numpy array of sorted velocities (column 1), and average pot temperatures (column 2)

        T_max
            Maximum average pot temperature of all analyzed cases within foamfiles directory

        case_max
            Case title associated with maximum average pot temp

        U_optimal
            Secondary air flow velocity associated with maximum average pot temperature

        """

        # Find maximum temperature
        Temp_col = 1 # column with temperature data
        velocity_col = 0 # column with the velocity data

        # Find the maximum average temperature
        T_max = np.max(array_sorted[:,1]) # second column of the sorted array
        #T_max_index = np.where(temperature_vector == T_max)
        T_max_index = np.argmax(array_sorted[:,1])
        print("Maximum Temperature: ")
        print(T_max)
        print("Index with maximum temperature: ")
        print(T_max_index)

        # finding cases and velocites associated with maximum temperatures
        velocity_max = array_sorted[:,0][T_max_index]
        print("velocity_max")
        print(velocity_max)

        print("max velocity entry: ")
        print(velocity_max)

        # velocity column
        velocity_column = array_sorted[:,0]

        # temperature column
        temperature_column = array_sorted[:,1]

        return T_max, velocity_max, T_max_index, velocity_column, temperature_column

    #T_max, velocity_max, T_max_index, velocity_column, temperature_column = evaluate_optimal(array_sorted, length_case_list)

    def plot_variables(array_sorted, T_max, velocity_max, T_max_index, velocity_column, temperature_column):
        """
        create a matplot lib of the data extracted

        """
        #fig, axs = plt.subplots(1, 3, figsize=(5,5)) # figure with multiple plots

        plt.figure(1)
        plt.scatter(velocity_column, temperature_column) # Temperature versus velocity
        plt.title("Temperature versus Case No.")
        plt.xlabel("Seconday Air Average Flow Velocity")
        plt.ylabel("Average Pot Temperature (Celsius)")
        plt.show()

    #plot_variables(array_sorted, T_max, velocity_max, T_max_index, velocity_column, temperature_column)

    def compute_neighboring_velocities(array_sorted, T_max, velocity_max, T_max_index, length_case_list, velocity_column, temperature_column):
        """
        Use the maximum data solved for previously to compute 4 new neighboring velocities

        Parameters
        ----------

        v_cases_total_vector
            Numpy array listing four velocities to be added to the case queue

        """
        # Algorithm ==>
        # sort the new_recarr array
        # (1) Find the location of the maximum velocity within the case list
        # (2) Solve for 4 additional velocities with the following logic:
            # (a) If the maximum temp is based on an interior velocity value, add two new velocities greater than and lesser than the max
            # (b) If the max temp is associated with the lower limit velocity, compute three greater velocities, and one lesser
            # (c) If the maximum temp is associated with the maximum velocity in the list, compute 3 lesser velocities, and one greater

        # empty four velocity addition
        v_cases_added = np.empty([4,1], dtype = float)
        shape_v_cases_added = v_cases_added.shape
        print("shape of the added velocity vector")
        print(shape_v_cases_added)

        # (a) interior logic
        if (T_max_index != 0 and T_max_index != length_case_list):
            # 2 new velocities on either side of interior
            print("MAXIMUM TEMP IS WITHIN THE INTERIOR OF THE DESIGN SPACE")
            lower_velocity = velocity_column[T_max_index - 1]
            upper_velocity = velocity_column[T_max_index + 1]
            velocity_spacing = velocity_column[T_max_index] - lower_velocity
            num_values_between = 2 # number of velocities on each side of maximum
            delta_V = velocity_spacing/(num_values_between+1) # spacing
            # Lesser velocities
            v_1 = velocity_max - delta_V
            v_2 = velocity_max - 2*delta_V

            # greater velocities
            v_3 = velocity_max + delta_V
            v_4 = velocity_max + 2*delta_V

            v_cases_added[0,0] = v_1
            v_cases_added[1,0] = v_2
            v_cases_added[2,0] = v_3
            v_cases_added[3,0] = v_4
            print("Interior V-cases added")
            print(v_cases_added)
            v_cases_total_vector = v_cases_added

        if T_max_index == 0:
            print("MAXIMUM TEMP IS ON THE LOWER LIMIT OF THE DESIGN SPACE")
            # Lower limit maximum velocity--make sure we don't approach zero on the lower side
            # Greater side
            upper_velocity = velocity_column[T_max_index + 1]
            num_values_greater = 3
            velocity_spacing = upper_velocity - velocity_column[T_max_index]
            delta_V = velocity_spacing/(num_values_greater+1) # spacing on the greater side
            v_1 = velocity_max + delta_V
            v_2 = velocity_max + 2*delta_V
            v_3 = velocity_max + 3*delta_V

            # lesser side---halfway between zero and minimum velocity
            velocity_spacing_lower = velocity_max - 0
            num_values_lesser = 1
            delta_V_lower = velocity_spacing_lower/(num_values_lesser + 1)
            v_4 = velocity_max - delta_V_lower

            v_cases_added[0,0] = v_1
            v_cases_added[1,0] = v_2
            v_cases_added[2,0] = v_3
            v_cases_added[3,0] = v_4
            print("LOWER LIMIT V-cases added")
            print(v_cases_added)
            v_cases_total_vector = v_cases_added

        if T_max_index == length_case_list:
            print("MAXIMUM TEMP IS ON THE UPPER LIMIT OF THE DESIGN SPACE")
            lower_velocity = velocity_column[T_max_index - 1]
            num_values_lesser = 3
            velocity_spacing = velocity_column[T_max_index] - lower_velocity
            delta_V = delta_V = velocity_spacing/(num_values_lesser+1) # spacing on the lower side
            v_1 = velocity_max - delta_V
            v_2 = velocity_max - 2*delta_V
            v_3 = velocity_max - 3*delta_V

            # Greater side -- simply adding the delta_V
            v_4 = velocity_max + delta_V

            v_cases_added[0,0] = v_1
            v_cases_added[1,0] = v_2
            v_cases_added[2,0] = v_3
            v_cases_added[3,0] = v_4
            print("UPPER LIMIT V-cases added")
            print(v_cases_added)
            v_cases_total_vector = v_cases_added

        return v_cases_added, v_cases_total_vector