summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Peter <blendoit@gmail.com>2019-06-21 15:49:04 -0700
committerMarius Peter <blendoit@gmail.com>2019-06-21 15:49:04 -0700
commit43d8b1a738eef259063febd9e5c591a10610a043 (patch)
tree414177eba1d401354a31ad1d9981e542a962b72c
parent7fdc7e586e1c2125eef533af77dcb5ee8930b702 (diff)
evaluator.Airfoil class & class methods
-rw-r--r--creator.py1
-rw-r--r--evaluator.py171
-rw-r--r--main.py21
3 files changed, 125 insertions, 68 deletions
diff --git a/creator.py b/creator.py
index 07720e8..15c090f 100644
--- a/creator.py
+++ b/creator.py
@@ -75,6 +75,7 @@ class Coordinates:
This function's output is piped to the 'save_coord' function below.
"""
print('============================')
+ print(' CREATOR DATA ')
print('Component:', str(self))
print('Chord length:', self.chord)
print('Semi-span:', self.semi_span)
diff --git a/evaluator.py b/evaluator.py
index 2b61348..6965895 100644
--- a/evaluator.py
+++ b/evaluator.py
@@ -13,60 +13,129 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+import sys
+import os.path
+import numpy as np
from math import sin, cos, atan, sqrt
-def get_total_mass(*component):
- total_mass = float()
- for _ in component:
- total_mass += _.mass
- return total_mass
+class Airfoil:
+ '''Performs structural evaluations for the airfoil passed as argument.'''
+
+ def __init__(self, airfoil):
+ self.airfoil = airfoil
+ # Global dimensions
+ self.chord = airfoil.chord
+ self.semi_span = airfoil.semi_span
+ # mass and area
+ self.mass_total = float()
+ self.mass_dist = []
+
+ self.lift_rectangular = []
+ self.lift_elliptical = []
+ self.lift = []
+
+ self.drag = []
+
+ def __str__(self):
+ return type(self).__name__
+
+ def print_info(self, round):
+ """
+ Print all the component's evaluated data to the terminal.
+
+ This function's output is piped to the 'save_data' function below.
+ """
+ print('============================')
+ print(' EVALUATOR DATA ')
+ print('Evaluating:', str(self.airfoil))
+ print('Chord length:', self.chord)
+ print('Semi-span:', self.semi_span)
+ print('Total airfoil mass:', self.mass_total)
+ print('============================')
+ print('Rectangular lift:\n', np.around(self.lift_rectangular, round))
+ print('Elliptical lift:\n', np.around(self.lift_elliptical, round))
+ print('Combined lift:\n', np.around(self.lift, round))
+ print('Distribution of mass:\n', np.around(self.mass_dist, round))
+ print('Drag:\n', np.around(self.drag, round))
+ return None
+
+ def save_info(self, save_dir_path, number):
+ """
+ Save all the object's coordinates (must be full path).
+ """
+
+ file_name = '{}_{}.txt'.format(self, number)
+ full_path = os.path.join(save_dir_path, file_name)
+ try:
+ with open(full_path, 'w') as sys.stdout:
+ self.print_info(2)
+ # 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 get_mass_total(airfoil):
+ total_mass = airfoil.mass + airfoil.spar.mass + airfoil.stringer.mass
+ return total_mass
+
+ # All these functions take integer arguments and return lists.
+
+ def get_lift_rectangular(airfoil, lift):
+ L_prime = [lift / (airfoil.semi_span * 2)
+ for x in range(airfoil.semi_span)]
+ return L_prime
+
+ def get_lift_elliptical(airfoil, L_0):
+ L_prime = [L_0 * sqrt(1 - (y / airfoil.semi_span) ** 2)
+ for y in range(airfoil.semi_span)]
+ return L_prime
+
+ def get_lift(rectangular, elliptical):
+ F_z = [(rectangular[_] + elliptical[_]) / 2
+ for _ in range(len(rectangular))]
+ return F_z
+
+ def get_mass_distribution(airfoil, total_mass):
+ F_z = [total_mass / airfoil.semi_span
+ for x in range(0, airfoil.semi_span)]
+ return F_z
+
+ def get_drag(airfoil, drag):
+ # Transform semi-span integer into list
+ semi_span = [x for x in range(0, airfoil.semi_span)]
+
+ # Drag increases after 80% of the semi_span
+ cutoff = round(0.8 * airfoil.semi_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 evaluate(self):
+ self.drag = self.get_drag(self.airfoil, 10)
+
+ self.lift_rectangular = self.get_lift_rectangular(10)
+ self.lift_elliptical = self.get_lift_elliptical(15)
+ self.lift = self.get_lift(self.lift_rectangular, self.lift_elliptical)
+
+ self.mass_total = self.get_mass_total()
+ self.mass_dist = self.get_mass_distribution(self.total_mass)
+ return None
+
+# def get_centroid(airfoil):
+# area = airfoil.stringer.area
+# top_stringers = airfoil.stringer
+# bottom_stringers =
+# nose_top_stringers =
+# nose_bottom_stringers =
+# for _ in airfoil.stringer[1]:
+# centroid.x +=
-
-# All these functions take integer arguments and return lists.
-
-def get_lift_rectangular(airfoil, lift):
- L_prime = [lift / (airfoil.semi_span * 2)
- for x in range(airfoil.semi_span)]
- return L_prime
-
-
-def get_lift_elliptical(airfoil, L_0):
- L_prime = [L_0 * sqrt(1 - (y / airfoil.semi_span) ** 2)
- for y in range(airfoil.semi_span)]
- return L_prime
-
-
-def get_lift(rectangular, elliptical):
- F_z = [(rectangular[_] + elliptical[_]) / 2
- for _ in range(len(rectangular))]
- return F_z
-
-
-def get_mass_distribution(airfoil, total_mass):
- F_z = [total_mass / airfoil.semi_span
- for x in range(0, airfoil.semi_span)]
- return F_z
-
-
-def get_drag(airfoil, drag):
- # Transform semi-span integer into list
- semi_span = [x for x in range(0, airfoil.semi_span)]
- cutoff = round(0.8 * airfoil.semi_span)
-
- F_x = [drag for x in semi_span[0:cutoff]]
- F_x.extend([1.25 * drag for x in semi_span[cutoff:]])
- # for x in semi_span[cutoff:]:
- # drag_distribution.append(1.25 * drag)
- return F_x
-
-
-def get_centroid(airfoil):
- area = airfoil.stringer.area
- numerator = float()
- for _ in airfoil.stringer.x_u:
- numerator += _ * area
- for _ in airfoil.stringer.x_l:
- numerator += _ * area
# denominator
# z_c =
diff --git a/main.py b/main.py
index a23c3f0..e5360ff 100644
--- a/main.py
+++ b/main.py
@@ -76,21 +76,6 @@ def main():
af.stringer.add_mass(STRINGER_MASS)
# af.stringer.print_info(2)
- # print(evaluator.get_total_mass(af, af.spar, af.stringer))
- drag = evaluator.get_drag(af, 10)
-
- lift_rectangular = evaluator.get_lift_rectangular(af, 10)
- lift_elliptical = evaluator.get_lift_elliptical(af, 15)
- lift = evaluator.get_lift(lift_rectangular, lift_elliptical)
-
- total_mass = evaluator.get_total_mass(af, af.spar, af.stringer)
- dist_mass = evaluator.get_mass_distribution(af, total_mass)
- print('rect', len(lift_rectangular))
- print('ellipse', len(lift_elliptical))
- print('lift', len(lift))
- print(len(drag))
- print(len(dist_mass))
-
# Plot components with matplotlib
# creator.plot(af, af.spar, af.stringer)
@@ -99,8 +84,10 @@ def main():
# af.spar.save_info(SAVE_PATH, _)
# af.stringer.save_info(SAVE_PATH, _)
- # Evaluate previously created airfoil(s).
- # total_mass = evaluator.get_total_mass(af, af.spar, af.stringer)
+ # evaluator.Airfoil instance contains the results of the airfoil analysis.
+ # The analysis itself takes place in the evaluator.py module.
+ eval = evaluator.Airfoil(af)
+ eval.print_info(2)
# Print final execution time
print("--- %s seconds ---" % (time.time() - start_time))
Copyright 2019--2024 Marius PETER