From 5e82dedea4c56eafc1bba4f3ec8677b15f51c03f Mon Sep 17 00:00:00 2001 From: blendoit Date: Sun, 20 Oct 2019 19:33:53 -0700 Subject: Commence declassification of Evaluator Pointless to have a separate object for the Evaluator when a collection of evaluator.py methods does the trick. --- Pipfile | 13 ++ Pipfile.lock | 124 +++++++++++++++++ creator/__init__.py | 4 - creator/base.py | 1 + evaluator.py | 353 ------------------------------------------------- evaluator/__init__.py | 1 + evaluator/dP.py | 18 +++ evaluator/drag.py | 16 +++ evaluator/evaluator.py | 206 +++++++++++++++++++++++++++++ evaluator/inertia.py | 64 +++++++++ evaluator/lift.py | 30 +++++ evaluator/mass.py | 8 ++ example_airfoil.py | 42 +++--- generator.py | 47 ------- generator/__init__.py | 1 + generator/generator.py | 47 +++++++ log_base.txt | 165 +++++++++++++++++++++++ 17 files changed, 716 insertions(+), 424 deletions(-) create mode 100644 Pipfile create mode 100644 Pipfile.lock delete mode 100644 evaluator.py create mode 100644 evaluator/__init__.py create mode 100644 evaluator/dP.py create mode 100644 evaluator/drag.py create mode 100644 evaluator/evaluator.py create mode 100644 evaluator/inertia.py create mode 100644 evaluator/lift.py create mode 100644 evaluator/mass.py delete mode 100644 generator.py create mode 100644 generator/__init__.py create mode 100644 generator/generator.py diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..309b2b0 --- /dev/null +++ b/Pipfile @@ -0,0 +1,13 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +numpy = "*" +matplotlib = "*" + +[requires] +python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..7ee8515 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,124 @@ +{ + "_meta": { + "hash": { + "sha256": "a67dca5f16ddc46fb13b6e907c6a3a310410154c905c1fbffcc496db0d7ccd87" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "cycler": { + "hashes": [ + "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d", + "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8" + ], + "version": "==0.10.0" + }, + "kiwisolver": { + "hashes": [ + "sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f", + "sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7", + "sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe", + "sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c", + "sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5", + "sha256:53eaed412477c836e1b9522c19858a8557d6e595077830146182225613b11a75", + "sha256:58e626e1f7dfbb620d08d457325a4cdac65d1809680009f46bf41eaf74ad0187", + "sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641", + "sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883", + "sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5", + "sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2", + "sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3", + "sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389", + "sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897", + "sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a", + "sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c", + "sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326", + "sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0", + "sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e", + "sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544", + "sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995", + "sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f", + "sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee", + "sha256:e3a21a720791712ed721c7b95d433e036134de6f18c77dbe96119eaf7aa08004", + "sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2", + "sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9", + "sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a", + "sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f" + ], + "version": "==1.1.0" + }, + "matplotlib": { + "hashes": [ + "sha256:1febd22afe1489b13c6749ea059d392c03261b2950d1d45c17e3aed812080c93", + "sha256:31a30d03f39528c79f3a592857be62a08595dec4ac034978ecd0f814fa0eec2d", + "sha256:4442ce720907f67a79d45de9ada47be81ce17e6c2f448b3c64765af93f6829c9", + "sha256:796edbd1182cbffa7e1e7a97f1e141f875a8501ba8dd834269ae3cd45a8c976f", + "sha256:934e6243df7165aad097572abf5b6003c77c9b6c480c3c4de6f2ef1b5fdd4ec0", + "sha256:bab9d848dbf1517bc58d1f486772e99919b19efef5dd8596d4b26f9f5ee08b6b", + "sha256:c1fe1e6cdaa53f11f088b7470c2056c0df7d80ee4858dadf6cbe433fcba4323b", + "sha256:e5b8aeca9276a3a988caebe9f08366ed519fff98f77c6df5b64d7603d0e42e36", + "sha256:ec6bd0a6a58df3628ff269978f4a4b924a0d371ad8ce1f8e2b635b99e482877a" + ], + "index": "pypi", + "version": "==3.1.1" + }, + "numpy": { + "hashes": [ + "sha256:0b0dd8f47fb177d00fa6ef2d58783c4f41ad3126b139c91dd2f7c4b3fdf5e9a5", + "sha256:25ffe71f96878e1da7e014467e19e7db90ae7d4e12affbc73101bcf61785214e", + "sha256:26efd7f7d755e6ca966a5c0ac5a930a87dbbaab1c51716ac26a38f42ecc9bc4b", + "sha256:28b1180c758abf34a5c3fea76fcee66a87def1656724c42bb14a6f9717a5bdf7", + "sha256:2e418f0a59473dac424f888dd57e85f77502a593b207809211c76e5396ae4f5c", + "sha256:30c84e3a62cfcb9e3066f25226e131451312a044f1fe2040e69ce792cb7de418", + "sha256:4650d94bb9c947151737ee022b934b7d9a845a7c76e476f3e460f09a0c8c6f39", + "sha256:4dd830a11e8724c9c9379feed1d1be43113f8bcce55f47ea7186d3946769ce26", + "sha256:4f2a2b279efde194877aff1f76cf61c68e840db242a5c7169f1ff0fd59a2b1e2", + "sha256:62d22566b3e3428dfc9ec972014c38ed9a4db4f8969c78f5414012ccd80a149e", + "sha256:669795516d62f38845c7033679c648903200980d68935baaa17ac5c7ae03ae0c", + "sha256:75fcd60d682db3e1f8fbe2b8b0c6761937ad56d01c1dc73edf4ef2748d5b6bc4", + "sha256:9395b0a41e8b7e9a284e3be7060db9d14ad80273841c952c83a5afc241d2bd98", + "sha256:9e37c35fc4e9410093b04a77d11a34c64bf658565e30df7cbe882056088a91c1", + "sha256:a0678793096205a4d784bd99f32803ba8100f639cf3b932dc63b21621390ea7e", + "sha256:b46554ad4dafb2927f88de5a1d207398c5385edbb5c84d30b3ef187c4a3894d8", + "sha256:c867eeccd934920a800f65c6068acdd6b87e80d45cd8c8beefff783b23cdc462", + "sha256:dd0667f5be56fb1b570154c2c0516a528e02d50da121bbbb2cbb0b6f87f59bc2", + "sha256:de2b1c20494bdf47f0160bd88ed05f5e48ae5dc336b8de7cfade71abcc95c0b9", + "sha256:f1df7b2b7740dd777571c732f98adb5aad5450aee32772f1b39249c8a50386f6", + "sha256:ffca69e29079f7880c5392bf675eb8b4146479d976ae1924d01cd92b04cccbcc" + ], + "index": "pypi", + "version": "==1.17.3" + }, + "pyparsing": { + "hashes": [ + "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", + "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" + ], + "version": "==2.4.2" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "version": "==2.8.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + } + }, + "develop": {} +} diff --git a/creator/__init__.py b/creator/__init__.py index 7662f94..818c7b2 100644 --- a/creator/__init__.py +++ b/creator/__init__.py @@ -2,7 +2,3 @@ from . import base from . import fuselage from . import propulsion from . import wing -# import creator.base -# import creator.fuselage -# import creator.propulsion -# import creator.wing diff --git a/creator/base.py b/creator/base.py index 75c58f9..ad4c443 100644 --- a/creator/base.py +++ b/creator/base.py @@ -19,6 +19,7 @@ class Aircraft: self.fuselage = None self.propulsion = None self.wing = None + self.results = {} def __str__(self): return self.name diff --git a/evaluator.py b/evaluator.py deleted file mode 100644 index 2adc702..0000000 --- a/evaluator.py +++ /dev/null @@ -1,353 +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 = np.array([ - lift / (aircraft.wing.semi_span * 2) - for _ in range(aircraft.wing.semi_span) - ]) - return L_prime - - def _get_lift_elliptical(aircraft, L_0=3.2): - L_prime = np.array([ - 0.5 * 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): - """Combination of rectangular and elliptical lift.""" - # F_z = self._get_lift_rectangular(aircraft) + self._get_lift_elliptical( - # aircraft) - # F_z = self._get_lift_rectangular( - # aircraft) + self._get_lift_elliptical(aircraft) / 2 - # F_z = [i + j for i, j in self._get_lift_rectangular] - # return F_z - return 420 - - 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_mass_total(self, aircraft): - """Get the total aircraft mass.""" - return 2000 - - 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_drag_total(self, aircraft): - """Get total drag force acting on the aircraft.""" - return 500 - - 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 analyze(self, aircraft): - """Analyze a single aircraft.""" - aircraft.results = {} - aircraft.results.update({'Lift': self.get_lift_total(aircraft)}) - aircraft.results.update({'Drag': self.get_drag_total(aircraft)}) - aircraft.results.update({'Mass': self.get_mass_total(aircraft)}) - print(aircraft.results) - return None - - def analyze_all(self): - """Perform all analysis calculations on a all aircraft in evaluator.""" - with concurrent.futures.ProcessPoolExecutor() as executor: - executor.map(self.analyze, self.aircrafts) - return None - - # 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, *aircrafts): - """Print the list of subcomponents.""" - name = f" TREE FOR {[i.name for i in aircrafts]} IN {self.name} " - num_of_dashes = len(name) - print(num_of_dashes * '-') - print(name) - for aircraft in 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, - *aircrafts, - save_path='/home/blendux/Projects/Aircraft_Studio/save'): - """Save the evaluator's tree to a file.""" - for aircraft in aircrafts: - file_name = f"{aircraft.name}_tree.txt" - full_path = os.path.join(save_path, file_name) - with open(full_path, 'w') as f: - try: - 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.', - '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/__init__.py b/evaluator/__init__.py new file mode 100644 index 0000000..6eedafc --- /dev/null +++ b/evaluator/__init__.py @@ -0,0 +1 @@ +from .evaluator import Evaluator diff --git a/evaluator/dP.py b/evaluator/dP.py new file mode 100644 index 0000000..b6aaa3b --- /dev/null +++ b/evaluator/dP.py @@ -0,0 +1,18 @@ +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 diff --git a/evaluator/drag.py b/evaluator/drag.py new file mode 100644 index 0000000..df79e6a --- /dev/null +++ b/evaluator/drag.py @@ -0,0 +1,16 @@ +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_drag_total(self, aircraft): + """Get total drag force acting on the aircraft.""" + return 500 diff --git a/evaluator/evaluator.py b/evaluator/evaluator.py new file mode 100644 index 0000000..b2b6e18 --- /dev/null +++ b/evaluator/evaluator.py @@ -0,0 +1,206 @@ +""" +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 matplotlib.pyplot as plt +import concurrent.futures +import logging + +from . import drag, inertia, lift, mass +import generator + +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 analyze(self, aircraft): + """Analyze a single aircraft.""" + aircraft.results.update({'Lift': lift.get_lift_total(aircraft)}) + aircraft.results.update({'Drag': drag.get_drag_total(aircraft)}) + aircraft.results.update({'Mass': mass.get_mass_total(aircraft)}) + aircraft.results.update({'Centroid': inertia.get_centroid(aircraft)}) + return aircraft.results + + def analyze_all(self): + """Perform all analysis calculations on a all aircraft in evaluator.""" + with concurrent.futures.ProcessPoolExecutor() as executor: + executor.map(self.analyze, self.aircrafts) + + return None + + # 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, *aircrafts): + """Print the list of subcomponents.""" + name = f" TREE FOR {[i.name for i in aircrafts]} IN {self.name} " + num_of_dashes = len(name) + print(num_of_dashes * '-') + print(name) + for aircraft in 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, + *aircrafts, + save_path='/home/blendux/Projects/Aircraft_Studio/save'): + """Save the evaluator's tree to a file.""" + for aircraft in aircrafts: + file_name = f"{aircraft.name}_tree.txt" + full_path = os.path.join(save_path, file_name) + with open(full_path, 'w') as f: + try: + 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.', + '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/inertia.py b/evaluator/inertia.py new file mode 100644 index 0000000..fea728c --- /dev/null +++ b/evaluator/inertia.py @@ -0,0 +1,64 @@ +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) diff --git a/evaluator/lift.py b/evaluator/lift.py new file mode 100644 index 0000000..6b4363e --- /dev/null +++ b/evaluator/lift.py @@ -0,0 +1,30 @@ +import numpy as np +from math import sqrt + + +def _get_lift_rectangular(aircraft, lift=50): + L_prime = np.array([ + lift / (aircraft.wing.semi_span * 2) + for _ in range(aircraft.wing.semi_span) + ]) + return L_prime + + +def _get_lift_elliptical(aircraft, L_0=3.2): + L_prime = np.array([ + 0.5 * 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): + """Combination of rectangular and elliptical lift.""" + # F_z = self._get_lift_rectangular(aircraft) + self._get_lift_elliptical( + # aircraft) + # F_z = self._get_lift_rectangular( + # aircraft) + self._get_lift_elliptical(aircraft) / 2 + # F_z = [i + j for i, j in self._get_lift_rectangular] + # return F_z + return 420 diff --git a/evaluator/mass.py b/evaluator/mass.py new file mode 100644 index 0000000..514c59b --- /dev/null +++ b/evaluator/mass.py @@ -0,0 +1,8 @@ +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_mass_total(self, aircraft): + """Get the total aircraft mass.""" + return 2000 diff --git a/example_airfoil.py b/example_airfoil.py index 6c69bf0..11fd4d5 100644 --- a/example_airfoil.py +++ b/example_airfoil.py @@ -42,24 +42,23 @@ SAVE_PATH = '/home/blendux/Projects/Aircraft_Studio/save' eval = evaluator.Evaluator("eval") -ac = creator.base.Aircraft(eval, "ac") -af = creator.wing.Airfoil(ac, 'af') -af.add_naca(2412) -spar1 = creator.wing.Spar(af, 'spar1') -spar2 = creator.wing.Spar(af, 'spar2', 0.57) -# spar2 = creator.wing.Spar(af, 'spar2', 0.7) -stringer = creator.wing.Stringer(af, 'stringer', 5, 6, 5, 4) -stringer.info_save(SAVE_PATH) - -ac2 = creator.base.Aircraft(eval, "ac2") -af2 = creator.wing.Airfoil(ac2, 'af2') -af2.add_naca(3412) -af2.info_save() -spar3 = creator.wing.Spar(af2, 'spar3', 0.23) -spar4 = creator.wing.Spar(af2, 'spar4', 0.67) -stringer2 = creator.wing.Stringer(af2, 'stringer2') -stringer2.info_save(SAVE_PATH) - +# ac = creator.base.Aircraft(eval, "ac") +# af = creator.wing.Airfoil(ac, 'af') +# af.add_naca(2412) +# spar1 = creator.wing.Spar(af, 'spar1') +# spar2 = creator.wing.Spar(af, 'spar2', 0.57) +# # spar2 = creator.wing.Spar(af, 'spar2', 0.7) +# stringer = creator.wing.Stringer(af, 'stringer', 5, 6, 5, 4) +# stringer.info_save(SAVE_PATH) + +# ac2 = creator.base.Aircraft(eval, "ac2") +# af2 = creator.wing.Airfoil(ac2, 'af2') +# af2.add_naca(3412) +# af2.info_save() +# spar3 = creator.wing.Spar(af2, 'spar3', 0.23) +# spar4 = creator.wing.Spar(af2, 'spar4', 0.67) +# stringer2 = creator.wing.Stringer(af2, 'stringer2') +# stringer2.info_save(SAVE_PATH) for _ in range(100): aircraft = generator.default_aircraft(eval) @@ -67,8 +66,11 @@ for _ in range(100): eval.analyze_all() -# creator.wing.plot_geom(generator.default_aircraft(eval).wing) -eval.tree_print(generator.default_aircraft(eval)) +# for i in eval.aircrafts: +# print(i.name) + +# for i in eval.aircrafts: +# print(i.results) # Final execution time final_time = time.time() - start_time diff --git a/generator.py b/generator.py deleted file mode 100644 index 30fc039..0000000 --- a/generator.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -The generator.py module contains classes describing genetic populations -and methods to generate default aircraft. -""" - -import random -import concurrent.futures - -import creator - - -def default_aircraft(evaluator): - """Generate a default aircraft with a random name.""" - name = 'default_aircraft_' + str(random.randrange(1000, 9999)) - aircraft = creator.base.Aircraft(evaluator, name) - airfoil = creator.wing.Airfoil(aircraft, 'default_airfoil') - airfoil.add_naca(2412) - soar1 = creator.wing.Spar(airfoil, 'default_spar_1', 0.30) - soar2 = creator.wing.Spar(airfoil, 'default_spar_2', 0.60) - stringer = creator.wing.Stringer(airfoil, 'default_stringer') - return aircraft - - -def default_fuselage(): - pass - - -def default_propulsion(): - pass - - -class Population(): - """Collection of random airfoils.""" - def __init__(self, size): - af = creator.Airfoil - # print(af) - self.size = size - self.gen_number = 0 # incremented for every generation - - def mutate(self, prob_mt): - """Randomly mutate the genes of prob_mt % of the population.""" - def crossover(self, prob_cx): - """Combine the genes of prob_cx % of the population.""" - def reproduce(self, prob_rp): - """Pass on the genes of the fittest prob_rp % of the population.""" - def fitness(): - """Rate the fitness of an individual on a relative scale (0-100)""" diff --git a/generator/__init__.py b/generator/__init__.py new file mode 100644 index 0000000..4f233cb --- /dev/null +++ b/generator/__init__.py @@ -0,0 +1 @@ +from .generator import * diff --git a/generator/generator.py b/generator/generator.py new file mode 100644 index 0000000..3af4850 --- /dev/null +++ b/generator/generator.py @@ -0,0 +1,47 @@ +""" +The generator.py module contains classes describing genetic populations +and methods to generate default aircraft. +""" + +import random + +import creator +import evaluator + + +def default_aircraft(evaluator_instance): + """Generate a default aircraft with a random name.""" + name = 'default_aircraft_' + str(random.randrange(1000, 9999)) + aircraft = creator.base.Aircraft(evaluator_instance, name) + airfoil = creator.wing.Airfoil(aircraft, 'default_airfoil') + airfoil.add_naca(2412) + soar1 = creator.wing.Spar(airfoil, 'default_spar_1', 0.30) + soar2 = creator.wing.Spar(airfoil, 'default_spar_2', 0.60) + stringer = creator.wing.Stringer(airfoil, 'default_stringer') + return aircraft + + +def default_fuselage(): + pass + + +def default_propulsion(): + pass + + +class Population(): + """Collection of random airfoils.""" + def __init__(self, size): + af = creator.Airfoil + # print(af) + self.size = size + self.gen_number = 0 # incremented for every generation + + def mutate(self, prob_mt): + """Randomly mutate the genes of prob_mt % of the population.""" + def crossover(self, prob_cx): + """Combine the genes of prob_cx % of the population.""" + def reproduce(self, prob_rp): + """Pass on the genes of the fittest prob_rp % of the population.""" + def fitness(): + """Rate the fitness of an individual on a relative scale (0-100)""" diff --git a/log_base.txt b/log_base.txt index e2e1c09..25e95fd 100644 --- a/log_base.txt +++ b/log_base.txt @@ -11168,3 +11168,168 @@ 2019-10-19 18:44:05,033 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt 2019-10-19 18:44:05,052 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt 2019-10-19 18:44:05,053 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 16:35:55,069 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 16:35:55,090 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 16:35:55,091 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 16:36:33,165 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 16:36:33,184 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 16:36:33,185 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:16:42,212 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:16:42,231 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:16:42,233 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:16:53,314 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:16:53,334 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:16:53,335 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:18:21,479 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:18:21,499 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:18:21,500 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:52:09,050 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:52:09,068 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:52:09,069 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:52:17,872 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:52:17,890 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:52:17,891 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:53:54,657 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:53:54,675 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:53:54,676 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:55:08,034 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:55:08,052 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:55:08,053 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:55:13,302 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:55:13,321 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:55:13,322 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:55:37,090 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:55:37,109 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:55:37,110 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 17:55:41,154 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 17:55:41,173 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 17:55:41,174 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:05:32,332 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:05:32,350 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:05:32,351 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:22:19,488 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:22:19,507 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:22:19,508 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:25:32,877 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:25:32,896 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:25:32,897 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:25:37,652 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:25:37,671 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:25:37,672 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:25:44,602 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:25:44,621 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:25:44,622 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:26:07,410 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:26:07,429 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:26:07,430 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:40:34,777 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:40:34,796 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:40:34,797 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:41:10,388 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:41:10,407 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:41:10,408 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:41:29,529 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:41:29,549 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:41:29,550 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:43:19,906 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:43:19,927 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:43:19,928 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:46:42,716 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:46:42,736 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:46:42,737 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:48:14,657 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:48:14,677 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:48:14,678 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:48:23,582 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:48:23,600 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:48:23,601 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:50:09,424 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:50:09,444 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:50:09,445 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:50:38,429 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:50:38,448 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:50:38,449 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:52:43,896 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:52:43,916 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:52:43,916 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:53:10,207 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:53:10,226 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:53:10,227 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:54:18,035 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:54:18,055 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:54:18,056 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:55:01,440 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:55:01,459 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:55:01,460 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:58:28,691 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:58:28,710 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:58:28,711 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:58:37,012 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:58:37,032 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:58:37,033 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:59:24,354 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:59:24,373 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:59:24,374 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:59:26,853 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:59:26,873 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:59:26,874 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:59:34,308 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:59:34,327 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:59:34,328 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 18:59:41,748 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 18:59:41,767 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 18:59:41,768 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:00:09,987 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:00:10,006 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:00:10,007 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:00:53,583 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:00:53,603 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:00:53,604 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:01:49,388 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:01:49,408 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:01:49,409 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:01:59,113 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:01:59,133 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:01:59,134 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:05:00,700 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:05:00,719 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:05:00,720 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:05:16,953 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:05:16,973 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:05:16,974 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:08:59,952 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:08:59,972 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:08:59,973 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:09:31,123 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:09:31,141 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:09:31,142 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:10:46,989 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:10:47,009 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:10:47,010 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:12:17,772 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:12:17,792 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:12:17,793 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:12:40,442 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:12:40,462 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:12:40,463 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:13:27,072 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:13:27,091 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:13:27,092 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:14:55,494 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:14:55,513 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:14:55,513 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:15:55,311 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:15:55,331 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:15:55,332 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:16:34,705 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:16:34,723 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:16:34,724 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:16:59,725 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:16:59,745 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:16:59,746 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:17:11,409 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:17:11,429 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:17:11,430 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt +2019-10-20 19:18:40,265 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer_info.txt +2019-10-20 19:18:40,285 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/af2_info.txt +2019-10-20 19:18:40,286 - DEBUG - Successfully wrote to file /home/blendux/Projects/Aircraft_Studio/save/stringer2_info.txt -- cgit v1.2.3