diff options
Diffstat (limited to 'evaluator')
| -rw-r--r-- | evaluator/__init__.py | 1 | ||||
| -rw-r--r-- | evaluator/evaluator.py | 344 | ||||
| -rw-r--r-- | evaluator/log_eval.txt | 0 | 
3 files changed, 0 insertions, 345 deletions
| diff --git a/evaluator/__init__.py b/evaluator/__init__.py deleted file mode 100644 index 1561fb0..0000000 --- a/evaluator/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import evaluator diff --git a/evaluator/evaluator.py b/evaluator/evaluator.py deleted file mode 100644 index 53fab3b..0000000 --- a/evaluator/evaluator.py +++ /dev/null @@ -1,344 +0,0 @@ -""" -The evaluator.py module contains a single Evaluator class, -which knows all the attributes of a specified Aircraft instance, -and contains functions to analyse the airfoil's geometrical -& structural properties. -""" - -import sys -import os.path -import numpy as np -from math import sqrt -import matplotlib.pyplot as plt -import concurrent.futures -import logging - -logging.basicConfig(filename='log_eval.txt', -                    level=logging.DEBUG, -                    format='%(asctime)s - %(levelname)s - %(message)s') - - -class Evaluator: -    """Performs structural evaluations on aircrafts. -    Individual aircrafts must claim an Evaluator object as parent.""" -    def __init__(self, name): -        self.name = name -        self.aircrafts = [] -        self.results = [] - -        self.I_ = {'x': 0, 'z': 0, 'xz': 0} - -    def get_lift_rectangular(aircraft, lift=50): -        L_prime = [ -            lift / (aircraft.wing.semi_span * 2) -            for x in range(aircraft.wing.semi_span) -        ] -        return L_prime - -    def get_lift_elliptical(aircraft, L_0=3.2): -        L_prime = [ -            L_0 / (aircraft.wing.semi_span * 2) * -            sqrt(1 - (y / aircraft.wing.semi_span)**2) -            for y in range(aircraft.wing.semi_span) -        ] -        return L_prime - -    def get_lift_total(self, aircraft): -        F_z = [ -            self.get_lift_rectangular(aircraft) + -            self.get_lift_elliptical(aircraft) / 2 -            for _ in range(aircraft.wing.semi_span) -        ] -        return F_z - -    def get_mass_distribution(self, total_mass): -        F_z = [total_mass / self.semi_span for x in range(0, self.semi_span)] -        return F_z - -    def get_drag(aircraft, drag): -        # Transform semi-span integer into list -        semi_span = [x for x in range(0, aircraft.wing.semi_span)] - -        # Drag increases after 80% of the semi_span -        cutoff = round(0.8 * aircraft.wing.span) - -        # Drag increases by 25% after 80% of the semi_span -        F_x = [drag for x in semi_span[0:cutoff]] -        F_x.extend([1.25 * drag for x in semi_span[cutoff:]]) -        return F_x - -    def get_centroid(aircraft): -        """Return the coordinates of the centroid.""" -        stringer_area = aircraft.stringer.area -        cap_area = aircraft.spar.cap_area - -        caps_x = [value for spar in aircraft.spar.x for value in spar] -        caps_z = [value for spar in aircraft.spar.z for value in spar] -        stringers_x = aircraft.stringer.x -        stringers_z = aircraft.stringer.z - -        denominator = float( -            len(caps_x) * cap_area + len(stringers_x) * stringer_area) - -        centroid_x = float( -            sum([x * cap_area for x in caps_x]) + -            sum([x * stringer_area for x in stringers_x])) -        centroid_x = centroid_x / denominator - -        centroid_z = float( -            sum([z * cap_area for z in caps_z]) + -            sum([z * stringer_area for z in stringers_z])) -        centroid_z = centroid_z / denominator - -        return (centroid_x, centroid_z) - -    def get_inertia_terms(self): -        """Obtain all inertia terms.""" -        stringer_area = self.stringer.area -        cap_area = self.spar.cap_area - -        # Adds upper and lower components' coordinates to list -        x_stringers = self.stringer.x -        z_stringers = self.stringer.z -        x_spars = self.spar.x[:][0] + self.spar.x[:][1] -        z_spars = self.spar.z[:][0] + self.spar.z[:][1] -        stringer_count = range(len(x_stringers)) -        spar_count = range(len(self.spar.x)) - -        # I_x is the sum of the contributions of the spar caps and stringers -        # TODO: replace list indices with dictionary value -        I_x = sum([ -            cap_area * (z_spars[i] - self.centroid[1])**2 for i in spar_count -        ]) -        I_x += sum([ -            stringer_area * (z_stringers[i] - self.centroid[1])**2 -            for i in stringer_count -        ]) - -        I_z = sum([ -            cap_area * (x_spars[i] - self.centroid[0])**2 for i in spar_count -        ]) -        I_z += sum([ -            stringer_area * (x_stringers[i] - self.centroid[0])**2 -            for i in stringer_count -        ]) - -        I_xz = sum([ -            cap_area * (x_spars[i] - self.centroid[0]) * -            (z_spars[i] - self.centroid[1]) for i in spar_count -        ]) -        I_xz += sum([ -            stringer_area * (x_stringers[i] - self.centroid[0]) * -            (z_stringers[i] - self.centroid[1]) for i in stringer_count -        ]) -        return (I_x, I_z, I_xz) - -    def get_dx(self, component): -        return [x - self.centroid[0] for x in component.x_start] - -    def get_dz(self, component): -        return [x - self.centroid[1] for x in component.x_start] - -    def get_dP(self, xDist, zDist, V_x, V_z, area): -        I_x = self.I_['x'] -        I_z = self.I_['z'] -        I_xz = self.I_['xz'] -        denom = float(I_x * I_z - I_xz**2) -        z = float() -        for _ in range(len(xDist)): -            z += float(-area * xDist[_] * (I_x * V_x - I_xz * V_z) / denom - -                       area * zDist[_] * (I_z * V_z - I_xz * V_x) / denom) -        return z - -    def analysis(self): -        """Perform all analysis calculations and store in self.results.""" -        with concurrent.futures.ProcessPoolExecutor() as executor: -            f1 = executor.submit(self.get_lift_total) - -        for aircraft in self.aircrafts: -            # lift = self.get_lift_total(aircraft), -            # drag = self.get_drag(aircraft.wing), -            # centroid = self.get_centroid(aircraft.wing) -            results = {"Lift": 400, "Drag": 20, "Centroid": [0.2, 4.5]} -            self.results.append(results) -        #     results = { -        #         "Lift": self.get_lift_total(aircraft), -        #         "Drag": self.get_drag(aircraft), -        #         "Centroid": self.get_centroid(aircraft) -        #     } -        return results - -    # def analysis(self, V_x, V_z): -    #     """Perform all analysis calculations and store in class instance.""" - -    #     self.drag = self.get_drag(10) -    #     self.lift_rectangular = self.get_lift_rectangular(13.7) -    #     self.lift_elliptical = self.get_lift_elliptical(15) -    #     self.lift_total = self.get_lift_total() -    #     self.mass_dist = self.get_mass_distribution(self.mass_total) -    #     self.centroid = self.get_centroid() -    #     self.I_['x'] = self.get_inertia_terms()[0] -    #     self.I_['z'] = self.get_inertia_terms()[1] -    #     self.I_['xz'] = self.get_inertia_terms()[2] -    #     spar_dx = self.get_dx(self.spar) -    #     spar_dz = self.get_dz(self.spar) -    #     self.spar.dP_x = self.get_dP(spar_dx, spar_dz, V_x, 0, -    #                                  self.spar.cap_area) -    #     self.spar.dP_z = self.get_dP(spar_dx, spar_dz, 0, V_z, -    #                                  self.spar.cap_area) -    #     print("yayyyyy") -    #     return None - -    # print(f"Analysis results for {aircraft.name}:\n", results) -    # self.results = self.get_lift_total(aircraft) - -    # self.drag = self.get_drag(10) -    # self.lift_rectangular = self.get_lift_rectangular(13.7) -    # self.lift_elliptical = self.get_lift_elliptical(15) -    # self.lift_total = self.get_lift_total() -    # self.mass_dist = self.get_mass_distribution(self.mass_total) -    # self.centroid = self.get_centroid() -    # self.I_['x'] = self.get_inertia_terms()[0] -    # self.I_['z'] = self.get_inertia_terms()[1] -    # self.I_['xz'] = self.get_inertia_terms()[2] -    # spar_dx = self.get_dx(self.spar) -    # spar_dz = self.get_dz(self.spar) -    # self.spar.dP_x = self.get_dP(spar_dx, spar_dz, V_x, 0, -    #                              self.spar.cap_area) -    # self.spar.dP_z = self.get_dP(spar_dx, spar_dz, 0, V_z, -    #                              self.spar.cap_area) -    # return None - -    def tree_print(self): -        """Print the list of subcomponents.""" -        name = f"    TREE FOR {[_.name for _ in self.aircrafts]} IN {self.name}    " -        num_of_dashes = len(name) -        print(num_of_dashes * '-') -        print(name) -        for aircraft in self.aircrafts: -            print(".") -            print(f"`-- {aircraft}") -            print(f"    |--{aircraft.wing}") -            print(f"    |   |-- {aircraft.wing.stringers}") -            for spar in aircraft.wing.spars[:-1]: -                print(f"    |   |-- {spar}") -            print(f"    |   `-- {aircraft.wing.spars[-1]}") -            print(f"    |-- {aircraft.fuselage}") -            print(f"    `-- {aircraft.propulsion}") -        print(num_of_dashes * '-') -        return None - -    def tree_save(self, -                  save_path='/home/blendux/Projects/Aircraft_Studio/save'): -        """Save the evaluator's tree to a file.""" -        file_name = f"{self.name}_tree.txt" -        full_path = os.path.join(save_path, file_name) -        with open(full_path, 'w') as f: -            try: -                for aircraft in self.aircrafts: -                    f.write(".\n") -                    f.write(f"`-- {aircraft}\n") -                    f.write(f"    |--{aircraft.wing}\n") -                    for spar in aircraft.wing.spars[:-1]: -                        f.write(f"    |   |-- {spar}\n") -                    f.write(f"    |   `-- {aircraft.wing.spars[-1]}\n") -                    f.write(f"    |-- {aircraft.fuselage}\n") -                    f.write(f"    `-- {aircraft.propulsion}\n") -                logging.debug(f'Successfully wrote to file {full_path}') - -            except IOError: -                print(f'Unable to write {file_name} to specified directory.\n', -                      'Was the full path passed to the function?') -        return None - -    def info_save(self, save_path, number): -        """Save all the object's coordinates (must be full path).""" -        file_name = 'airfoil_{}_eval.txt'.format(number) -        full_path = os.path.join(save_path, file_name) -        try: -            with open(full_path, 'w') as sys.stdout: -                self.info_print(6) -                # This line required to reset behavior of sys.stdout -                sys.stdout = sys.__stdout__ -                print('Successfully wrote to file {}'.format(full_path)) -        except IOError: -            print( -                'Unable to write {} to specified directory.\n'.format( -                    file_name), 'Was the full path passed to the function?') -        return None - - -def plot_geom(evaluator): -    """This function plots analysis results over the airfoil's geometry.""" -    # Plot chord -    x_chord = [0, evaluator.chord] -    y_chord = [0, 0] -    plt.plot(x_chord, y_chord, linewidth='1') -    # Plot quarter chord -    plt.plot(evaluator.chord / 4, -             0, -             '.', -             color='g', -             markersize=24, -             label='Quarter-chord') -    # Plot airfoil surfaces -    x = [0.98 * x for x in evaluator.airfoil.x] -    y = [0.98 * z for z in evaluator.airfoil.z] -    plt.fill(x, y, color='w', linewidth='1', fill=False) -    x = [1.02 * x for x in evaluator.airfoil.x] -    y = [1.02 * z for z in evaluator.airfoil.z] -    plt.fill(x, y, color='b', linewidth='1', fill=False) - -    # Plot spars -    try: -        for _ in range(len(evaluator.spar.x)): -            x = (evaluator.spar.x[_]) -            y = (evaluator.spar.z[_]) -            plt.plot(x, y, '-', color='b') -    except AttributeError: -        print('No spars to plot.') -    # Plot stringers -    try: -        for _ in range(0, len(evaluator.stringer.x)): -            x = evaluator.stringer.x[_] -            y = evaluator.stringer.z[_] -            plt.plot(x, y, '.', color='y', markersize=12) -    except AttributeError: -        print('No stringers to plot.') - -    # Plot centroid -    x = evaluator.centroid[0] -    y = evaluator.centroid[1] -    plt.plot(x, y, '.', color='r', markersize=24, label='centroid') - -    # Graph formatting -    plt.xlabel('X axis') -    plt.ylabel('Z axis') - -    plot_bound = max(evaluator.airfoil.x) -    plt.xlim(-0.10 * plot_bound, 1.10 * plot_bound) -    plt.ylim(-(1.10 * plot_bound / 2), (1.10 * plot_bound / 2)) -    plt.gca().set_aspect('equal', adjustable='box') -    plt.gca().legend() -    plt.grid(axis='both', linestyle=':', linewidth=1) -    plt.show() -    return None - - -def plot_lift(evaluator): -    x = range(evaluator.semi_span) -    y_1 = evaluator.lift_rectangular -    y_2 = evaluator.lift_elliptical -    y_3 = evaluator.lift_total -    plt.plot(x, y_1, '.', color='b', markersize=4, label='Rectangular lift') -    plt.plot(x, y_2, '.', color='g', markersize=4, label='Elliptical lift') -    plt.plot(x, y_3, '.', color='r', markersize=4, label='Total lift') - -    # Graph formatting -    plt.xlabel('Semi-span location') -    plt.ylabel('Lift') - -    plt.gca().legend() -    plt.grid(axis='both', linestyle=':', linewidth=1) -    plt.show() -    return None diff --git a/evaluator/log_eval.txt b/evaluator/log_eval.txt deleted file mode 100644 index e69de29..0000000 --- a/evaluator/log_eval.txt +++ /dev/null | 
