From 2680a82ed678434acf4fbada43f8836c33620441 Mon Sep 17 00:00:00 2001 From: blendoit Date: Sat, 5 Oct 2019 17:21:22 -0700 Subject: README PlantUML diagrams --- README.org | 15 +++++++------- creator/base.py | 40 ++++++++++++++++++++++++------------- creator/wing.py | 50 +++++++++++++++++++++++------------------------ doc/diagram.png | Bin 5111 -> 0 bytes doc/diagram.pum | 5 ----- doc/diagram.txt | 17 ---------------- doc/diagram2.png | Bin 6107 -> 0 bytes doc/sequence_program.png | Bin 0 -> 26958 bytes doc/sequence_program.pum | 25 ++++++++++++++++++++++++ example_airfoil.py | 18 ++++++++--------- 10 files changed, 92 insertions(+), 78 deletions(-) delete mode 100644 doc/diagram.png delete mode 100644 doc/diagram.pum delete mode 100644 doc/diagram.txt delete mode 100644 doc/diagram2.png create mode 100644 doc/sequence_program.png create mode 100644 doc/sequence_program.pum diff --git a/README.org b/README.org index 9ce7891..ba5fa66 100644 --- a/README.org +++ b/README.org @@ -9,13 +9,14 @@ With the final objective of designing a lightweight FAR 23 compliant airfoil. I adapted it from my own code for the UCLA MAE 154B final project (Spring 2019). -#+CAPTION: Test image for the README -#+NAME: fig:Test-Image -[[./doc/diagram.png]] - -#+CAPTION: Second test image for the README -#+NAME: fig:Test-Image2 -[[./doc/diagram2.png]] +#+BEGIN_UML +Alice -> Bob: Authentication Request +Bob --> Alice: Authentication Response +#+END_UML + +#+CAPTION: Program Flow Sequence +#+NAME: fig:sequence-program +[[./doc/sequence_program.png]] * Program Structure diff --git a/creator/base.py b/creator/base.py index 2566a6b..603bef7 100644 --- a/creator/base.py +++ b/creator/base.py @@ -1,4 +1,5 @@ """The base.py module contains parent classes for components.""" + import numpy as np import sys import os.path @@ -11,19 +12,23 @@ logging.basicConfig(filename='log.txt', class Aircraft: """This class tracks all sub-components and is fed to the evaluator.""" - pass + def __init__(self, parent): + self.parent = parent class Component: """Basic component providing coordinates and tools.""" - - # TODO: define defaults in separate module - def __init__(self): + def __init__(self, parent, name): + self.name = str() + self.parent = None self.x = np.array([]) self.z = np.array([]) - self.material = str() + self.material = None self.mass = float() + def __str__(self): + return self.name + def set_material(self, material): """Set the component bulk material.""" self.material = material @@ -36,23 +41,30 @@ class Component: print(name) for k, v in self.__dict__.items(): if type(v) != list: - print('{}:\n'.format(k), v) + print(f'{k}:\n', v) print(num_of_dashes * '-') for k, v in self.__dict__.items(): if type(v) == list: - print('{}:\n'.format(k), np.around(v, round)) + print(f'{k}:\n', np.around(v, round)) return None - def info_save(self, save_path, number): + def info_save(self, + save_path='/home/blendux/Projects/Aircraft_Studio/save'): """Save all the object's coordinates (must be full path).""" - file_name = f'{str(self).lower()}_{number}.txt' + file_name = f'{self.name}_info.txt' 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__ - logging.debug(f'Successfully wrote to file {full_path}') + with open(full_path, 'w') as f: + for k, v in self.__dict__.items(): + if type(v) != list: + f.write(f'{k}:\n') + f.write(str(v)) + # print(num_of_dashes * '-') + for k, v in self.__dict__.items(): + if type(v) == list: + f.write(f'{k}:\n') + f.write(str(v)) + 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?') diff --git a/creator/wing.py b/creator/wing.py index 8178366..59f5bbe 100644 --- a/creator/wing.py +++ b/creator/wing.py @@ -11,14 +11,15 @@ Functions: plot_geom(airfoil): generates a 2D plot of the airfoil & any components. """ -import creator.base as base - import logging import numpy as np from math import sin, cos, atan import bisect as bi import matplotlib.pyplot as plt +import creator.base as base +import resources.materials as mt + class Airfoil(base.Component): """This class represents a single NACA airfoil. @@ -32,23 +33,20 @@ class Airfoil(base.Component): to 3D CAD packages like SolidWorks, which can import such geometry as coordinates written in a CSV file. """ - - # TODO: default values in separate module - def __init__(self, chord, semi_span, material): - super().__init__() - # self.x = np.array([]) - # self.z = np.array([]) - # self.chord = chord - """Create airfoil from its chord and semi-span.""" - self.chord = chord if chord > 20 else 20 - if chord <= 20: + def __init__(self, + parent, + name, + chord=68, + semi_span=150, + material=mt.aluminium): + super().__init__(parent, name) + if chord > 20: + self.chord = chord + else: + self.chord = 20 logging.debug('Chord too small, using minimum value of 20.') self.semi_span = semi_span self.material = material - self.naca_num = int() - - def __str__(self): - return type(self).__name__ def add_naca(self, naca_num): """Generate surface geometry for a NACA airfoil. @@ -138,22 +136,22 @@ class Airfoil(base.Component): class Spar(base.Component): """Contains a single spar's data.""" - def __init__(self, airfoil, loc_percent, material): + def __init__(self, parent, name, loc_percent=0.30, material=mt.aluminium): """Set spar location as percent of chord length.""" - super().__init__() + super().__init__(parent, name) super().set_material(material) self.cap_area = float() - loc = loc_percent * airfoil.chord - # bi.bisect_left: returns index of first value in airfoil.x > loc + loc = loc_percent * parent.chord + # bi.bisect_left: returns index of first value in parent.x > loc # This ensures that spar geom intersects with airfoil geom. # Spar upper coordinates - spar_u = bi.bisect_left(airfoil.x, loc) - 1 - self.x = np.append(self.x, airfoil.x[spar_u]) - self.z = np.append(self.z, airfoil.z[spar_u]) + spar_u = bi.bisect_left(parent.x, loc) - 1 + self.x = np.append(self.x, parent.x[spar_u]) + self.z = np.append(self.z, parent.z[spar_u]) # Spar lower coordinates - spar_l = bi.bisect_left(airfoil.x[::-1], loc) - self.x = np.append(self.x, airfoil.x[-spar_l]) - self.z = np.append(self.z, airfoil.z[-spar_l]) + spar_l = bi.bisect_left(parent.x[::-1], loc) + self.x = np.append(self.x, parent.x[-spar_l]) + self.z = np.append(self.z, parent.z[-spar_l]) return None def set_cap_area(self, cap_area): diff --git a/doc/diagram.png b/doc/diagram.png deleted file mode 100644 index 142f1b6..0000000 Binary files a/doc/diagram.png and /dev/null differ diff --git a/doc/diagram.pum b/doc/diagram.pum deleted file mode 100644 index 6140981..0000000 --- a/doc/diagram.pum +++ /dev/null @@ -1,5 +0,0 @@ -hide footbox -title Sequence Diagram (Footer removed) - -Alice -> Bob: Authentication Request -Bob --> Alice: Authentication Response diff --git a/doc/diagram.txt b/doc/diagram.txt deleted file mode 100644 index 668ec61..0000000 --- a/doc/diagram.txt +++ /dev/null @@ -1,17 +0,0 @@ - ┌─────┐ ┌───┐ ┌────┐ - │Alice│ │Bob│ │John│ - └──┬──┘ └─┬─┘ └─┬──┘ - │Authentication Request │ │ - │───────────────────────>│ │ - │ │ │ - │Authentication Response │ │ - │<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│ │ - │ │ │ - │ another Authentication Request │ - │<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ - │ │ │ - │ another Authentication Response │ - │ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─>│ - ┌──┴──┐ ┌─┴─┐ ┌─┴──┐ - │Alice│ │Bob│ │John│ - └─────┘ └───┘ └────┘ diff --git a/doc/diagram2.png b/doc/diagram2.png deleted file mode 100644 index f15fa91..0000000 Binary files a/doc/diagram2.png and /dev/null differ diff --git a/doc/sequence_program.png b/doc/sequence_program.png new file mode 100644 index 0000000..6e69aaf Binary files /dev/null and b/doc/sequence_program.png differ diff --git a/doc/sequence_program.pum b/doc/sequence_program.pum new file mode 100644 index 0000000..d175cb3 --- /dev/null +++ b/doc/sequence_program.pum @@ -0,0 +1,25 @@ +@startuml +skin BlueModern +actor User +User -> evaluator: evaluator parameters +evaluator -> User: evaluator object + +User -> creator: specify desired a/c specs + +creator --> evaluator: inform evaluator of desired specs + +evaluator --> creator: request acceptable components + +creator -> User: acceptable initial a/c candidate + +User -> generator: specify genetic variability + +generator --> creator: request varied a/c +creator --> generator: varied a/c population +generator <--> evaluator: exchange population to evaluate\nwith new population based on\nfittest individuals +evaluator -> User: return individual a/c specs + +generator -> User: return population fitness and top candidates + +creator --> generator: return varied aircrafts +@enduml diff --git a/example_airfoil.py b/example_airfoil.py index e975483..0709734 100644 --- a/example_airfoil.py +++ b/example_airfoil.py @@ -42,21 +42,22 @@ NOSE_BOTTOM_STRINGERS = 5 SAVE_PATH = '/home/blendux/Projects/Aircraft_Studio/save' +eval = evaluator.Evaluator # Create aircraft instance -aircraft = creator.base.Aircraft +ac = creator.base.Aircraft(eval) # Create airfoil instance -af = creator.wing.Airfoil(68, 150, mt.aluminium) +af = creator.wing.Airfoil(ac, 'af') af.add_naca(NACA_NUM) -af.info_print(2) -# af.info_save(SAVE_PATH, 'foo_name') +# af.info_print(2) +af.info_save() # Create spar instances -af.spar1 = creator.wing.Spar(af, 0.23, mt.aluminium) -af.spar2 = creator.wing.Spar(af, 0.57, mt.aluminium) +af.spar1 = creator.wing.Spar(af, 'spar1') +af.spar2 = creator.wing.Spar(af, 'spar2', 0.57) # af.spar1.info_print(2) # af.spar2.info_print(2) -af.spar1.info_save(SAVE_PATH, 'spar1') -af.spar2.info_save(SAVE_PATH, 'spar2') +af.spar1.info_save() +af.spar2.info_save() # # Create stringer instance # af.stringer = wing.Stringer() @@ -72,7 +73,6 @@ af.spar2.info_save(SAVE_PATH, 'spar2') # creator.wing.plot_geom(af, [af.spar1, af.spar2], None) # Evaluator object contains airfoil analysis results. -eval = evaluator.Evaluator(aircraft) # The analysis is performed in the evaluator.py module. # eval.analysis(1, 1) # eval.info_print(2) -- cgit v1.2.3