MECH3410-P1-Graphs/main.py
2024-08-29 00:47:40 +10:00

443 lines
21 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Mech3410-P1-Graphs
# Cal Wing - Aug 2024
#
import os, time
import numpy as np
import pandas as pd
from tqdm import tqdm
from numpy import sqrt
from makeGraph import makeGraph, pltKeyClose, UQ_COLOURS as UQC, uq_colour_cycler_factory as uqccf # Custom Graphing Lib
# Override Sin & Cos to use & return degrees
def sin(angle): return np.sin(np.deg2rad(angle))
def cos(angle): return np.cos(np.deg2rad(angle))
# Make sure the relevant folders folder exists
#folders = ["./images", "./tmp", "./data"]
folders = ["./images", './images/pressure', './images/cp']
for folder in folders:
if not os.path.isdir(folder): os.mkdir(folder)
INCH_TO_M = 0.0254
GRAVITY = 9.81 #m/s^2
CHORD_LEN = 1000 #90 #mm
PITOT_PLACEMENT = np.array((0,4,8,16,25,34,43,52,61,70,5,9,17,25,34,43,52,61,70)) # mm from base of chord
PITOT_PLACEMENT_CHORD_NORM = PITOT_PLACEMENT / CHORD_LEN
print("="*15, "Loading Data", "="*15)
data_508rpm = {
"rpm": 508,
"airSpeed": 10,
"data": pd.read_excel('.\\data\\508 RPM Results.xlsx', sheet_name=None, header=None),
"AoA": (0,1,2,3,4,5,6,7,8,9)
}
data_1000rpm = {
"rpm": 1000,
"airSpeed": 20.40408122,
"data": pd.read_excel('.\\data\\1000 RPM Results.xlsx', sheet_name=None, header=None),
"AoA": (1,2,4,6,8,10,12,14,16)
}
print("="*15, "Loaded Data", "="*15)
def make_pressure_graph(sheet1, aoa, rpm, air_speed, doGraph=True):
water_density = sheet1.iloc[0, 2] # kg/m^3
air_density = sheet1.iloc[1, 2] # kg/m^3
atm_presure_inch = sheet1.iloc[24, 12] # inch
pitot_height_inch = sheet1.iloc[4:23, 11]
pitot_height_m = (pitot_height_inch - atm_presure_inch)*INCH_TO_M
pressure = water_density * GRAVITY * pitot_height_m
#print(pressure)
#print(pressure.min(), pressure.max())
# Do the trapiztoal rule integration
da = []
for i, _ in enumerate(pressure):
if i in [0]: continue # Skip 0
if i in [10]: # Force tapping 11 to use tapping 1 rather then 0
da.append(((PITOT_PLACEMENT_CHORD_NORM[i] - PITOT_PLACEMENT_CHORD_NORM[0])/2) * (pressure.iloc[0] + pressure.iloc[i]))
continue
da.append(((PITOT_PLACEMENT_CHORD_NORM[i] - PITOT_PLACEMENT_CHORD_NORM[i-1])/2) * (pressure.iloc[i-1] + pressure.iloc[i]))
da = np.array(da)
#print("\n\n\n\n")
#print(da)
#print("\n\n\n\n")
upper_force = da[:10].sum()
lower_force = da[10 :].sum()
force = lower_force - upper_force # Upper Sum (1-10) less Lower Sum (11-19)
lift = force * cos(aoa)
drag = force * sin(aoa)
# Extrapolate Aerofoil Tip
p1 = (PITOT_PLACEMENT[9], pressure.iloc[9])
p2 = (PITOT_PLACEMENT[18], pressure.iloc[18])
pN = (1.1*max(PITOT_PLACEMENT), p2[1] + (p1[1]-p2[1])/2)
#print(aoa, rpm, p1[1], p2[1], (p1[1]-p2[1])/2, pN[1], pN[1] > p1[1])
graph = {
"title": f"Pressure vs Pitot Placement along Chord\nfor a Clark Y 14% Aerofoil at:\nα = {int(aoa):d}° at {rpm:d} RPM ({air_speed:.1f}m/s)",
"windowTitle": f"Pressure along Clark Y 14 Percent Airfoil - Alpha {int(aoa):d} Degrees - {rpm:d}rpm - {air_speed:.1f}m_s",
"xLabel": "Pitot Placement [mm]",
"yLabel": "Pressure [Pa]",
"grid": True,
"yLim": (pressure.min()-10, pressure.max()+10),
"plots": [
# Draw Lines
{"x": PITOT_PLACEMENT[:10], "y":pressure[:10], "colour": UQC["purple"]},
{"x": PITOT_PLACEMENT[10:], "y":pressure[10:], "colour": UQC["purple"]},
{"x": [PITOT_PLACEMENT[0], PITOT_PLACEMENT[10]], "y": [pressure.iloc[0], pressure.iloc[10]], "colour": UQC["purple"]},
#{"x": [PITOT_PLACEMENT[9], PITOT_PLACEMENT[18]], "y": [pressure.iloc[9], pressure.iloc[18]], "colour": UQC["purple"]},
# Draw Extrapolated Airfoil Tip
{"x": [PITOT_PLACEMENT[9], pN[0]], "y": [pressure.iloc[9], pN[1]], "colour": UQC["aqua"], "label": "Extrapolated Airfoil Tip"},
{"x": [PITOT_PLACEMENT[9], pN[0]], "y": [pressure.iloc[18], pN[1]], "colour": UQC["aqua"]},
# Draw Colour Shading
{"x": PITOT_PLACEMENT[:10], "y":pressure[:10], "colour": UQC["purple"], "alpha":0.2, "type":"fill"},
{"x": PITOT_PLACEMENT[10:], "y":pressure[10:], "colour": "w", "type":"fill"},
{"x":[PITOT_PLACEMENT[0], PITOT_PLACEMENT[10]], "y":[pressure.iloc[0], pressure.iloc[10]], "colour": "w", "type":"fill"},
{"x": [PITOT_PLACEMENT[9], pN[0]], "y": [pressure.iloc[9], pN[1]], "colour": UQC["aqua"], "type":"fill", "alpha":0.2},
{"x":[PITOT_PLACEMENT[9], pN[0]], "y": [pressure.iloc[18], pN[1]], "colour": "w", "type":"fill"},
# Draw Points & text
{"x":PITOT_PLACEMENT, "y":pressure, "label":"Pressure Data", "type":"scatter", "args":{"zorder":2}},
{"label":[str(i) for i in range(1, len(PITOT_PLACEMENT)+1)], "x":PITOT_PLACEMENT, "y":pressure, "type":"annotate"},
{"type":"text", "x": 0.98, "y": 0.02, "text": f"Min: {pressure.min():.3f} Pa\nMax: {pressure.max():.3f} Pa\nForce: {force:.3f}N\nLift: {lift:.3f}N\nDrag: {drag:.3f}N", "align": ('bottom', 'right')}
]
}
if doGraph:
makeGraph(graph, False, figSavePath=f'./images/pressure/{{0}}.png', closeFig=True)
return pressure, graph, (water_density, air_density, atm_presure_inch, pitot_height_inch), (p1, p2, pN), aoa, (force, lift, drag, da, upper_force, lower_force)
def make_cp_graph(pressure, aoa, rpm, air_speed, data, doGraph=True):
water_density, air_density, atm_presure_inch, pitot_height_inch = data
#print(pressure)
#print(pressure.min(), pressure.max())
# Calculate Cp
cp = pressure / (0.5 * air_density * (air_speed ** 2))
#print("force, lift, drag, upper_force, lower_force")
#print(force, lift, drag, upper_force, lower_force)
#print(f"{aoa}, ")
# Extrapolate Aerofoil Tip
p1 = (PITOT_PLACEMENT_CHORD_NORM[9], cp.iloc[9])
p2 = (PITOT_PLACEMENT_CHORD_NORM[18], cp.iloc[18])
pN = (1.1*max(PITOT_PLACEMENT_CHORD_NORM), p2[1] + (p1[1]-p2[1])/2)
#print(aoa, rpm, p1[1], p2[1], (p1[1]-p2[1])/2, pN[1], pN[1] > p1[1])
graph = {
"title": f"$C_p$ vs Pitot Placement along Chord\nfor a Clark Y 14% Aerofoil at:\nα = {int(aoa):d}° at {rpm:d} RPM ({air_speed:.1f}m/s)",
"windowTitle": f"Cp along Clark Y 14 Percent Airfoil - Alpha {int(aoa):d} Degrees - {rpm:d}rpm - {air_speed:.1f}m_s",
"xLabel": "Pitot Placement [m]",
"yLabel": "$C_p$",
"grid": True,
"yLim": (cp.min()-0.5, cp.max()+0.5),
"plots": [
# Draw Lines
{"x": PITOT_PLACEMENT_CHORD_NORM[:10], "y":cp[:10], "colour": UQC["purple"]},
{"x": PITOT_PLACEMENT_CHORD_NORM[10:], "y":cp[10:], "colour": UQC["purple"]},
{"x": [PITOT_PLACEMENT_CHORD_NORM[0], PITOT_PLACEMENT_CHORD_NORM[10]], "y": [cp.iloc[0], cp.iloc[10]], "colour": UQC["purple"]},
#{"x": [PITOT_PLACEMENT_CHORD_NORM[9], PITOT_PLACEMENT_CHORD_NORM[18]], "y": [cp.iloc[9], cp.iloc[18]], "colour": UQC["purple"]},
# Draw Extrapolated Airfoil Tip
{"x": [PITOT_PLACEMENT_CHORD_NORM[9], pN[0]], "y": [cp.iloc[9], pN[1]], "colour": UQC["aqua"], "label": "Extrapolated Airfoil Tip"},
{"x": [PITOT_PLACEMENT_CHORD_NORM[9], pN[0]], "y": [cp.iloc[18], pN[1]], "colour": UQC["aqua"]},
# Draw Colour Shading
{"x": PITOT_PLACEMENT_CHORD_NORM[:10], "y":cp[:10], "colour": UQC["purple"], "alpha":0.2, "type":"fill"},
{"x": PITOT_PLACEMENT_CHORD_NORM[10:], "y":cp[10:], "colour": "w", "type":"fill"},
{"x":[PITOT_PLACEMENT_CHORD_NORM[0], PITOT_PLACEMENT_CHORD_NORM[10]], "y":[cp.iloc[0], cp.iloc[10]], "colour": "w", "type":"fill"},
{"x": [PITOT_PLACEMENT_CHORD_NORM[9], pN[0]], "y": [cp.iloc[9], pN[1]], "colour": UQC["aqua"], "type":"fill", "alpha":0.2},
{"x":[PITOT_PLACEMENT_CHORD_NORM[9], pN[0]], "y": [cp.iloc[18], pN[1]], "colour": "w", "type":"fill"},
# Draw Points & text
{"x":PITOT_PLACEMENT_CHORD_NORM, "y":cp, "label":"cp Data", "type":"scatter", "args":{"zorder":2}},
{"label":[str(i) for i in range(1, len(PITOT_PLACEMENT_CHORD_NORM)+1)], "x":PITOT_PLACEMENT_CHORD_NORM, "y":cp, "type":"annotate"},
{"type":"text", "x": 0.98, "y": 0.02, "text": f"Min $C_p$: {cp.min():.3f}\nMax $C_p$: {cp.max():.3f}", "align": ('bottom', 'right')}
]
}
if doGraph:
makeGraph(graph, False, figSavePath=f'./images/cp/{{0}}.png', closeFig=True)
return cp, graph, (p1, p2, pN), aoa
def make_rpm_graph():
air_density = data_508rpm["data"]["0 AoA"].iloc[1, 2] # kg/m^3
rpm = np.concat((np.array([0]), np.array(data_508rpm["data"]["0 AoA"].iloc[4:14, 2])))
pressure = np.concat((np.array([0]), np.array(data_508rpm["data"]["0 AoA"].iloc[4:14, 4], dtype=np.float64)))
airSpeed = sqrt(-pressure * 2 / air_density)
x = np.linspace(rpm[0], rpm[-1], 1000)
y = 0.0212*x - 0.7751
graph = {
"title": f"RPM vs Velocity for Wind Tunnel 3",
"xLabel": "Fan RPM",
"yLabel": "Airspeed [m/s]",
"grid": True,
"plots": [
{"x": x, "y":y, "label":"Linear Estimate", "args":{"linestyle":"--"}, "colour": UQC["neutral"]},
{"type": "scatter", "x":rpm, "y": airSpeed, "label": "Measured Velocity", "colour":UQC["purple"], "args":{"zorder":2}},
{"type": "point", "x":508, "y": 10, "label": "Selected RPM (508)", "colour":UQC["red"], "zorder":3},
{"type":"text", "x": 0.98, "y": 0.02, "text": f"Velocity at 508 RPM: {10:.3f} m/s\nVelocity at 1000 RPM: {airSpeed[-1]:.3f} m/s", "align": ('bottom', 'right')},
{"type":"text", "x": 0.80, "y": 0.85, "text": f"$y = 0.0212 \\cdot x - 0.7751$", "align": ('bottom', 'right'), "facecolour": UQC["neutral"]}
]
}
makeGraph(graph, False, figSavePath='./images/{0}.png')
if __name__ == '__main__':
print("Generating RPM Graph")
#make_rpm_graph()
print("Generated")
print("Loading Data & Generating Pressure Graphs")
data = {}
for raw_data in tqdm((data_508rpm, data_1000rpm), position=0):
aoa_data = {}
cp_pain_data = []
for aoa in tqdm(raw_data["AoA"], position=1):
sheet = raw_data["data"][f"{aoa} AoA"]
aoa_data[aoa] = make_pressure_graph(sheet, aoa, raw_data["rpm"], raw_data["airSpeed"], True)
cp_pain_data.append(aoa_data[aoa])
data[raw_data["rpm"]] = aoa_data
if True:
# All
graph = {
"title": f"Pressure vs Pitot Placement along Chord\nfor a Clark Y 14% Aerofoil at:\n{raw_data["rpm"]:d} RPM ({raw_data["airSpeed"]:.1f}m/s)",
"windowTitle": f"All Pressure along Clark Y 14 Percent Airfoil - {raw_data["rpm"]:d}rpm - {raw_data["airSpeed"]:.1f}m_s",
"xLabel": "Pitot Placement [mm]",
"yLabel": "Pressure [Pa]",
"grid": True,
"ledgLoc": 1,
"plots": []
}
colour_cycle = uqccf()
for aoa, c in zip(aoa_data, colour_cycle):
#print(c["color"], c["color"].hex_lighten(1.4), c["color"].rgb(), c["color"].lighten(1.4))
#print(c["color"].hex_lighten(1), c["color"])
#exit()
this_data = aoa_data[aoa]
pressure = this_data[0]
# Extrapolate Aerofoil Tip
p1 = (PITOT_PLACEMENT[9], pressure.iloc[9])
p2 = (PITOT_PLACEMENT[18], pressure.iloc[18])
pN = (0.9*CHORD_LEN, p2[1] + (p1[1]-p2[1])/2)
plts = (
{"x": PITOT_PLACEMENT[:10], "y":pressure[:10], "colour": c["color"]},
{"x": PITOT_PLACEMENT[10:], "y":pressure[10:], "colour": c["color"]},
{"x": [PITOT_PLACEMENT[0], PITOT_PLACEMENT[10]], "y": [pressure.iloc[0], pressure.iloc[10]], "colour": c["color"]},
#{"x": [PITOT_PLACEMENT[9], PITOT_PLACEMENT[18]], "y": [pressure.iloc[9], pressure.iloc[18]], "colour": c["color"]},
{"x": [PITOT_PLACEMENT[9], pN[0]], "y": [pressure.iloc[9], pN[1]], "colour": c["color"], "args":{"alpha":0.3}},
{"x": [PITOT_PLACEMENT[9], pN[0]], "y": [pressure.iloc[18], pN[1]], "colour": c["color"], "args":{"alpha":0.3}},
{"x":PITOT_PLACEMENT, "y":pressure, "label":f"α = {int(aoa):d}°", "type":"scatter", "colour": c["color"], "args":{"zorder":2}},
)
for plt in plts:
graph["plots"].append(plt)
if raw_data["rpm"] == 508:
graph['xLim'] = (
min(PITOT_PLACEMENT) - 5,
max(PITOT_PLACEMENT) + 25
)
graph["figSize"] = (8, 6)
makeGraph(graph, False, figSavePath="./images/pressure/__{0}.png", closeFig=True)
graph["plots"] = []
graph["windowTitle"] = f"Pressure along Clark Y 14 Percent Airfoil - {raw_data["rpm"]:d}rpm - {raw_data["airSpeed"]:.1f}m_s"
colour_cycle = uqccf()
for aoa, c in list(zip(aoa_data, colour_cycle))[1::2]:
this_data = aoa_data[aoa]
pressure = this_data[0]
# Extrapolate Aerofoil Tip
p1 = (PITOT_PLACEMENT[9], pressure.iloc[9])
p2 = (PITOT_PLACEMENT[18], pressure.iloc[18])
pN = (0.9*CHORD_LEN, p2[1] + (p1[1]-p2[1])/2)
plts = (
{"x": PITOT_PLACEMENT[:10], "y":pressure[:10], "colour": c["color"]},
{"x": PITOT_PLACEMENT[10:], "y":pressure[10:], "colour": c["color"]},
{"x": [PITOT_PLACEMENT[0], PITOT_PLACEMENT[10]], "y": [pressure.iloc[0], pressure.iloc[10]], "colour": c["color"]},
#{"x": [PITOT_PLACEMENT[9], PITOT_PLACEMENT[18]], "y": [pressure.iloc[9], pressure.iloc[18]], "colour": c["color"]},
{"x": [PITOT_PLACEMENT[9], pN[0]], "y": [pressure.iloc[9], pN[1]], "colour": c["color"], "args":{"alpha":0.3}},
{"x": [PITOT_PLACEMENT[9], pN[0]], "y": [pressure.iloc[18], pN[1]], "colour": c["color"], "args":{"alpha":0.3}},
{"x":PITOT_PLACEMENT, "y":pressure, "label":f"α = {int(aoa):d}°", "type":"scatter", "colour": c["color"], "args":{"zorder":2}},
)
for plt in plts:
graph["plots"].append(plt)
makeGraph(graph, False, figSavePath="./images/pressure/__{0}.png")
if True:
aoa = [a[-2] for a in cp_pain_data][1::2]
forces = [a[-1] for a in cp_pain_data][1::2]
# Force Graphs
graph = {
"title": f"All Total, Lift & Drag Forces\nfor a Clark Y 14% Aerofoil at:\n{raw_data["rpm"]:d}rpm - {raw_data["airSpeed"]:.1f}m/s)",
"windowTitle": f"All Total, Lift and Drag Forces for a Clark Y 14 Percent Airfoil - {raw_data["rpm"]:d}rpm - {raw_data["airSpeed"]:.1f}m_s",
"xLabel": "Attack Angle [$\\alpha$]",
"yLabel": "Force [N]",
"grid": True,
"ledgLoc": 1,
"plots": [
{"x":aoa, "y":[f[0] for f in forces], "label":"Total Force"},
{"x":aoa, "y":[f[1] for f in forces], "label":"Lift"},
{"x":aoa, "y":[f[2] for f in forces], "label":"Drag"},
]
}
makeGraph(graph, False, figSavePath="./images/{0}.png", closeFig=True)
print("\n\n")
print(raw_data["rpm"])
print("AoA Total Lift Drag ---- Upper Force Lower Force ")
for aoa, force in [(a[-2], a[-1]) for a in cp_pain_data]:
print(f"{aoa:d}\\textdegree & {force[0]:.3f} & {force[1]:.3f} & {force[2]:.3f} -- {force[4]:.3f} {force[5]:.3f} \\\\")
print("-"*50)
print("\n\n")
print("Generating Cp Graphs")
cp_data = {}
for raw_data in tqdm((data_508rpm, data_1000rpm), position=0):
cp_pain_data = []
for aoa in tqdm(raw_data["AoA"], position=1):
this_data = data[raw_data["rpm"]][aoa]
cp_data_this = make_cp_graph(this_data[0], aoa, raw_data["rpm"], raw_data["airSpeed"], this_data[2], True)
cp_pain_data.append(cp_data_this)
cp_data[raw_data["rpm"]] = cp_pain_data
if True:
# All
graph = {
"title": f"All $C_p$ vs Pitot Placement along Chord\nfor a Clark Y 14% Aerofoil at:\n{raw_data["rpm"]:d}rpm - {raw_data["airSpeed"]:.1f}m/s)",
"windowTitle": f"All Cp along Clark Y 14 Percent Airfoil - {raw_data["rpm"]:d}rpm - {raw_data["airSpeed"]:.1f}m_s",
"xLabel": "Pitot Placement [m]",
"yLabel": "$C_p$",
"grid": True,
"ledgLoc": 1,
"plots": [],
}
colour_cycle = uqccf()
for this_data, c in zip(cp_pain_data, colour_cycle):
cp = this_data[0]
# Extrapolate Aerofoil Tip
p1, p2, pN = this_data[2]
plts = (
# Draw Lines
{"x": PITOT_PLACEMENT_CHORD_NORM[:10], "y":cp[:10], "colour": c["color"]},
{"x": PITOT_PLACEMENT_CHORD_NORM[10:], "y":cp[10:], "colour": c["color"]},
{"x": [PITOT_PLACEMENT_CHORD_NORM[0], PITOT_PLACEMENT_CHORD_NORM[10]], "y": [cp.iloc[0], cp.iloc[10]], "colour": c["color"]},
# Draw Extrapolated Airfoil Tip
{"x": [PITOT_PLACEMENT_CHORD_NORM[9], pN[0]], "y": [cp.iloc[9], pN[1]], "colour": c["color"], "args":{"alpha":0.3}},
{"x": [PITOT_PLACEMENT_CHORD_NORM[9], pN[0]], "y": [cp.iloc[18], pN[1]], "colour": c["color"], "args":{"alpha":0.3}},
# Draw Points & text
{"x":PITOT_PLACEMENT_CHORD_NORM, "y":cp, "label":f"α = {int(this_data[-1]):d}°", "type":"scatter", "args":{"zorder":2}, "colour": c["color"]},
)
for plt in plts:
graph["plots"].append(plt)
if raw_data["rpm"] == 508:
#graph['xLim'] = (
# min(PITOT_PLACEMENT_CHORD_NORM) - 0.5,
# max(PITOT_PLACEMENT_CHORD_NORM) + 0.5
#)
graph["figSize"] = (8, 6)
makeGraph(graph, False, figSavePath="./images/cp/__{0}.png", closeFig=True)
graph["title"] = f"$C_p$ vs Pitot Placement along Chord\nfor a Clark Y 14% Aerofoil at:\n{raw_data["rpm"]:d}rpm - {raw_data["airSpeed"]:.1f}m/s)"
graph["windowTitle"] = f"Cp along Clark Y 14 Percent Airfoil - {raw_data["rpm"]:d}rpm - {raw_data["airSpeed"]:.1f}m_s"
graph["plots"] = []
colour_cycle = uqccf()
for this_data, c in list(zip(cp_pain_data, colour_cycle))[1::2]:
cp = this_data[0]
# Extrapolate Aerofoil Tip
p1, p2, pN = this_data[2]
plts = (
# Draw Lines
{"x": PITOT_PLACEMENT_CHORD_NORM[:10], "y":cp[:10], "colour": c["color"]},
{"x": PITOT_PLACEMENT_CHORD_NORM[10:], "y":cp[10:], "colour": c["color"]},
{"x": [PITOT_PLACEMENT_CHORD_NORM[0], PITOT_PLACEMENT_CHORD_NORM[10]], "y": [cp.iloc[0], cp.iloc[10]], "colour": c["color"]},
# Draw Extrapolated Airfoil Tip
{"x": [PITOT_PLACEMENT_CHORD_NORM[9], pN[0]], "y": [cp.iloc[9], pN[1]], "colour": c["color"], "args":{"alpha":0.3}},
{"x": [PITOT_PLACEMENT_CHORD_NORM[9], pN[0]], "y": [cp.iloc[18], pN[1]], "colour": c["color"], "args":{"alpha":0.3}},
# Draw Points & text
{"x":PITOT_PLACEMENT_CHORD_NORM, "y":cp, "label":f"α = {int(this_data[-1]):d}°", "type":"scatter", "args":{"zorder":2}, "colour": c["color"]},
)
for plt in plts:
graph["plots"].append(plt)
makeGraph(graph, False, figSavePath="./images/cp/__{0}.png", closeFig=True)
print("Complete")