hello everynyan i hope this fixed the issues, i am worried there might be issues with the RF calculation for the column buckling due to what I got on the feedback, but ill see tomorrow (I am hoping its just a fluke rn)
344 lines
No EOL
12 KiB
Python
344 lines
No EOL
12 KiB
Python
import math
|
|
import csv
|
|
from colorama import just_fix_windows_console
|
|
just_fix_windows_console()
|
|
from colorama import Fore, Back, Style
|
|
|
|
#
|
|
# HELLO MODIFY THIS!
|
|
#
|
|
#Hello there! Modify this!
|
|
#INITIAL SET UP
|
|
Ebasis = 65500.00
|
|
mass_limit = 28.000
|
|
|
|
#MODIFY THIS EVERY NEW ITERATION
|
|
modAmount = 2 # amount of results you want to iterate through (starts at panel_val_0 and goes to this value minus one)
|
|
# So the highest x of panel_val_x with one added to it. (modAmount = 1 only runs panel_val_0, modAmount = 3 runs through panel_val_0, 1 and 2)
|
|
|
|
# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16
|
|
pThickness_01 = [ 4, 5] # panel 1 and 10
|
|
pThickness_02 = [ 4, 5] # panel 2 and 9
|
|
pThickness_03 = [ 4, 5] # panel 3 and 8
|
|
pThickness_04 = [ 4, 5] # panel 4 and 7
|
|
pThickness_05 = [ 4, 6] # panel 5 and 6
|
|
|
|
# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16
|
|
dim1_0 = [25,70]
|
|
dim2_0 = [ 2, 2]
|
|
dim3_0 = [20,10]
|
|
dim4_0 = [15,15]
|
|
|
|
|
|
# BELOW THIS NOTHING NEEDS TO BE MODIFIED
|
|
|
|
def GetValueofElement(ElementID, Loadcase, Valuetype, Fileadress):
|
|
FindTitle = False
|
|
intiated = False
|
|
with open(Fileadress, newline='') as csvfile:
|
|
reader = csv.reader(csvfile, delimiter=',', quotechar="'")
|
|
for row in reader:
|
|
values = row
|
|
#print(values)
|
|
if intiated:
|
|
if str(values[ElemID_ID]) == str(ElementID) and str(values[Loadcase_ID])==str(Loadcase):
|
|
return float(values[Value_ID])*1.5 #Safety Factor here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
if FindTitle:
|
|
#print(str(values))
|
|
Header = values
|
|
ElemID_ID = Header.index("Elements")
|
|
Loadcase_ID = Header.index("Loadcase")
|
|
Value_ID = Header.index(Valuetype)
|
|
FindTitle = False
|
|
intiated = True
|
|
if len(values)==0:
|
|
FindTitle=True
|
|
return None
|
|
|
|
#CONSTANTS
|
|
axial = 'Element Stresses (1D):CBAR/CBEAM Axial Stress'
|
|
# material properties
|
|
sUlt = 530
|
|
sYield = 490
|
|
density = 2.7 * (10 ** -6) #2.7*10^-9 in t/mm^3
|
|
|
|
pWidth_0 = [200,200,200,200,200,200,200,200,200,200,200,200,200,200]
|
|
pLength_0 = [750,750,750,750,750,750,750,750,750,750,750,750,750]
|
|
|
|
def GetAvgStressofPanel(panelNo, Loadcase, ValueType):
|
|
id = panelNo * 3 - 2
|
|
return (GetValueofElement(id, Loadcase, ValueType, panel) + GetValueofElement(id+1, Loadcase, ValueType, panel) + GetValueofElement(id+2, Loadcase, ValueType, panel))/(3*1.5)
|
|
|
|
|
|
def GetCombAvgStressofStringer(stringerNo, Loadcase):
|
|
id = stringerNo * 3 - 3 + 40
|
|
avgStringerStress = (GetValueofElement(id, Loadcase, axial, stringer) + GetValueofElement(id+1, Loadcase, axial, stringer) + GetValueofElement(id+2, Loadcase, axial, stringer))/(3*1.5)
|
|
leftPID = stringerNo
|
|
rightPID = stringerNo + 1
|
|
leftPStress = GetAvgStressofPanel(leftPID, Loadcase, 'XX')
|
|
rightPStress = GetAvgStressofPanel(rightPID, Loadcase, 'XX')
|
|
return((leftPStress * 0.5 * pThickness[stringerNo - 1] * pWidth + rightPStress * 0.5 * pThickness[stringerNo]*pWidth + avgStringerStress * areaStringer) / (areaStringer + 0.5*pThickness[stringerNo-1] * pWidth + 0.5 * pThickness[stringerNo]*pWidth))
|
|
|
|
def GetAlpha(x):
|
|
if(0.4 <= x <= 1.095):
|
|
alpha = 1.4 - 0.628 * x
|
|
elif(1.095 < x <= 1.633):
|
|
alpha = 0.78/x
|
|
elif(x > 1.633):
|
|
alpha = 0.69/(x**0.75)
|
|
else:
|
|
alpha = 0
|
|
return(alpha)
|
|
|
|
def GetSigCrip(stringerNo, Loadcase): ## unfinished, need to understand x claulcation still a bit
|
|
#use b1 and b2 for calc
|
|
#E_c = Ebasis
|
|
#no alpha = 1 it is none -> what do then? -> ignore that element in averaging
|
|
#averaging only with elements that cripple
|
|
#if nothing cripples, use yield strength
|
|
b1 = dim1 - dim2
|
|
b2 = dim3 - dim2
|
|
|
|
x1 = (b1/dim2)*math.sqrt(sYield/(3.60*Ebasis))
|
|
|
|
alpha1 = GetAlpha(x1)
|
|
|
|
#print("x12: " + str(x))
|
|
sigCrip1 = alpha1 * sYield
|
|
|
|
x2 = (b2/dim2)*math.sqrt(sYield/(3.60*Ebasis))
|
|
|
|
alpha2 = GetAlpha(x2)
|
|
|
|
sigCrip2 = alpha2 * sYield
|
|
|
|
if(alpha1 != 0 and alpha2 != 0):
|
|
sigCripAVG = (sigCrip1 * b1 * dim2 + sigCrip2 * b2 * dim2 * 2)/(b1 * dim2 + b2 * dim2 * 2)
|
|
elif(alpha1 != 0):
|
|
sigCripAVG = (sigCrip1 * b1 * dim2)/(b1 * dim2)
|
|
elif(alpha2 != 0):
|
|
sigCripAVG = (sigCrip2 * b2 * dim2)/(b2 * dim2)
|
|
else:
|
|
sigCripAVG = sYield
|
|
|
|
# average only over what can buckle!!! F/A, A = sumOf(bi*ti)
|
|
return min(sigCripAVG, sYield)
|
|
|
|
|
|
def kBiax(panelNo,Loadcase):
|
|
beta = GetAvgStressofPanel(panelNo, Loadcase, 'YY')/GetAvgStressofPanel(panelNo, Loadcase, 'XX')
|
|
kSigX = 100000000
|
|
for m in range(1, 10):
|
|
for n in range(1, 100):
|
|
kTemp = (m*m+n*n*alpha*alpha)*(m*m+n*n*alpha*alpha)/(alpha*alpha*(m*m+beta*n*n*alpha*alpha))
|
|
if(0 < kTemp < kSigX):
|
|
kSigX = kTemp
|
|
return(kSigX)
|
|
|
|
|
|
def RF_panel(panelNo, Loadcase):
|
|
sE = ((pThickness[panelNo-1]/pWidth)**2) * Ebasis * math.pi * math.pi / (12*(1-(0.34*0.34)))
|
|
#print(sE)
|
|
rfBiax = (kBiax(panelNo, Loadcase)*sE)/abs(1.5*GetAvgStressofPanel(panelNo, Loadcase, 'XX'))
|
|
rfShear = (kShear*sE)/abs(1.5*GetAvgStressofPanel(panelNo, Loadcase, 'XY'))
|
|
result = 1 / ( (1 / rfBiax) + (1 / (rfShear*rfShear)))
|
|
#print(rfBiax)
|
|
#print(rfShear)
|
|
return(result)
|
|
|
|
|
|
def GetLambda(stringerNo):
|
|
I_comb = GetIcomb(i)
|
|
r_gyr = math.sqrt(I_comb/(areaStringer + 0.5 * pThickness[i] * pWidth + 0.5 * pThickness[i+1] * pWidth))
|
|
c = 1
|
|
return(1*pLength/r_gyr)
|
|
|
|
|
|
def GetSigCRIT(stringerNo, Loadcase):
|
|
sLambda_crit = math.sqrt((2*math.pi*math.pi*Ebasis)/GetSigCrip(i,0))
|
|
if(GetLambda(stringerNo)<sLambda_crit):
|
|
return(GetSigCrip(stringerNo, Loadcase) - ((1/Ebasis)*((GetSigCrip(stringerNo, Loadcase)/(2*math.pi))**2)*(GetLambda(stringerNo)**2)))
|
|
else:
|
|
return((math.pi**2)*Ebasis / (GetLambda(stringerNo) ** 2))
|
|
|
|
|
|
def GetRFstringer(stringerNo, Loadcase):
|
|
return(abs(GetSigCRIT(stringerNo, Loadcase)/(1.5*GetCombAvgStressofStringer(stringerNo, Loadcase))))
|
|
|
|
def GetCrosssectionValues(i):
|
|
I_comb = GetIcomb(i)
|
|
r_gyr = math.sqrt(I_comb/(areaStringer + 0.5 * pThickness[i] * pWidth + 0.5 * pThickness[i+1] * pWidth))
|
|
c = 1
|
|
sLambda = c*pLength/r_gyr
|
|
sLambda_crit = math.sqrt((2*math.pi*math.pi*Ebasis)/GetSigCrip(i, 0)) # IMPORTANT THIS IS ONLY FOR S crip above 490
|
|
return(str(I_comb) + "," + str(r_gyr) + "," + str(sLambda) + "," + str(sLambda_crit))
|
|
|
|
|
|
def GetIcomb(i):
|
|
wing_1_w = pWidth/2
|
|
wing_2_w = pWidth/2
|
|
|
|
wing_1_t = pThickness[i]
|
|
wing_2_t = pThickness[i+1]
|
|
|
|
|
|
z1 = -dim1/2
|
|
z3 = -(dim1-(dim2/2))
|
|
z4 = -dim2/2
|
|
|
|
y1 = ((dim3/2)-(dim2/2))
|
|
y3 = 0
|
|
y4 = dim3+(dim4/2)
|
|
|
|
zw_1 = wing_1_t/2
|
|
zw_2 = wing_2_t/2
|
|
|
|
yw_1 = 50
|
|
yw_2 = -50
|
|
|
|
|
|
a1 = dim1*dim2
|
|
a3 = dim2*(dim3-dim2-dim2)
|
|
a4 = dim4*dim2
|
|
|
|
aw_1 = wing_1_w * wing_1_t
|
|
aw_2 = wing_2_t * wing_2_w
|
|
|
|
Iyy1 = (dim2*(dim1**3))/12
|
|
Izz1 = (dim1*(dim2**3))/12
|
|
|
|
Iyy3 = ((dim3-dim2-dim2)*(dim2**3))/12
|
|
Izz3 = (((dim3-dim2-dim2)**3)*(dim2))/12
|
|
|
|
Iyy4 = (dim4*(dim2**3))/12
|
|
Izz4 = (dim2*(dim4**3))/12
|
|
|
|
Iw_1_yy = (wing_1_w*(wing_1_t**3))/12
|
|
Iw_1_zz = (wing_1_t*(wing_1_w**3))/12
|
|
|
|
Iw_2_yy = (wing_2_w*(wing_2_t**3))/12
|
|
Iw_2_zz = (wing_2_t*(wing_2_w**3))/12
|
|
|
|
|
|
z_c = (z1*a1+z1*a1+z3*a3+z4*a4+z4*a4+zw_1*aw_1+zw_1*aw_2)/(a1+a1+a3+a4+a4+aw_1+aw_2)
|
|
y_c = (-y1*a1+y1*a1+y3*a3+(-y4*a4)+y4*a4+yw_1*aw_1+yw_2*aw_2)/(a1+a1+a3+a4+a4+aw_1+aw_2)
|
|
|
|
Iyy = (Iyy1+((z1-z_c)**2)*a1)+(Iyy1+((z1-z_c)**2)*a1)+(Iyy3+((z3-z_c)**2)*a3)+(Iyy4+((z4-z_c)**2)*a4)+(Iyy4+((z4-z_c)**2)*a4)+(Iw_1_yy+((zw_1-z_c)**2)*aw_1)+(Iw_2_yy+((zw_2-z_c)**2)*aw_2)
|
|
Izz = (Izz1+((y1-y_c)**2)*a1)+(Izz1+((-y1-y_c)**2)*a1)+(Izz3+((y3-y_c)**2)*a3)+(Izz4+((y4-y_c)**2)*a4)+(Izz4+((-y4-y_c)**2)*a4)+(Iw_1_zz+((yw_1-y_c)**2)*aw_1)+(Iw_2_zz+((yw_2-y_c)**2)*aw_2)
|
|
|
|
|
|
if(Iyy > Izz):
|
|
return(Izz)
|
|
else:
|
|
return(Iyy)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for u in range(modAmount):
|
|
isWithinRF = 1
|
|
|
|
panel = 'panel_val_' + str(u) +'.csv'
|
|
stringer = 'stringer_val_' + str(u) + '.csv'
|
|
|
|
# dimensions
|
|
pThickness = [pThickness_01[u], pThickness_02[u], pThickness_03[u], pThickness_04[u], pThickness_05[u], pThickness_05[u], pThickness_04[u], pThickness_03[u], pThickness_02[u], pThickness_01[u]]
|
|
pWidth = pWidth_0[u]
|
|
pLength = pLength_0[u]
|
|
|
|
dim1 = dim1_0[u]
|
|
dim2 = dim2_0[u]
|
|
dim3 = dim3_0[u]
|
|
dim4 = dim4_0[u]
|
|
|
|
areaStringer = dim4 * dim2 * 2 + (dim1 - dim2) * dim2 * 2 + dim3 * dim2
|
|
|
|
print("\n\n" + Back.CYAN + "Calculations for iteration " + str(u) + Style.RESET_ALL)
|
|
print("\n Panel Thickness 1 & 10: " + str(pThickness[0]) + "\n Panel Thickness 2 & 9: " + str(pThickness[1]) + "\n Panel Thickness 3 & 8: " + str(pThickness[2]) + "\n Panel Thickness 4 & 7: " + str(pThickness[3]) + "\n Panel Thickness 5 & 6: " + str(pThickness[4]) + "\n Panel Width: " + str(pWidth) + "\n Panel Length: " + str(pLength) + "\n\n Dim 1: " + str(dim1) + "\n Dim2: " + str(dim2) + "\n Dim 3: "+ str(dim3) + "\n Dim 4: "+ str(dim4))
|
|
|
|
#print("\n Panel Offset: " + str(pThickness/2) + "\n Stringer Offset: " + str(dim1/2))
|
|
|
|
mass = density*(areaStringer*pLength*9) # + 10*pWidth*pThickness*pLength)
|
|
for i in range(10):
|
|
mass = mass + pWidth*pThickness[i]*density*pLength
|
|
if(mass<mass_limit):
|
|
print("\n\n Mass: " + Back.GREEN + str(mass) + Style.RESET_ALL)
|
|
else:
|
|
print("\n\n Mass: " + Back.RED + str(mass) + Style.RESET_ALL)
|
|
isWithinRF = 0
|
|
|
|
# REMEMBER SAFETY FACTOR OF 1.5 ALREADY INCLUDED
|
|
# RF calculator for panels
|
|
for c in range(1,4):
|
|
print("\nPanel RF for loadcase " + str(c))
|
|
for i in range(1, 31):
|
|
w = sUlt/GetValueofElement(i,c,'vonMises',panel)
|
|
if(w>1):
|
|
print(Back.GREEN + str(w) + Style.RESET_ALL)
|
|
else:
|
|
print(Back.RED + str(w) + Style.RESET_ALL)
|
|
isWithinRF = 0
|
|
|
|
print(" ")
|
|
# RF calculator for stringers
|
|
for c in range(1,4):
|
|
print("\nStringer RF for loadcase " + str(c))
|
|
for i in range(40,67):
|
|
w = abs(sUlt/GetValueofElement(i,c,axial,stringer))
|
|
if(w>1):
|
|
print(Back.GREEN + str(w) + Style.RESET_ALL)
|
|
else:
|
|
print(Back.RED + str(w) + Style.RESET_ALL)
|
|
isWithinRF = 0
|
|
|
|
# Stability Analysis
|
|
print("\n\nStability Analysis\nPanel buckling")
|
|
# Panel buckling
|
|
# sig_aa,avg calculator
|
|
alpha = pLength/pWidth
|
|
kShear = 5.34 + 4/(alpha*alpha)
|
|
for c in range(1,4):
|
|
print("\nLoadcase " + str(c) + "\nAverage stress for panels 1 to 5 - XX, YY, XY - k_shear, k_biax, RF_panelbuckl")
|
|
for i in range(1,6):
|
|
w = RF_panel(i,c)
|
|
if(w>1):
|
|
w = Back.GREEN + str(w) + Style.RESET_ALL
|
|
else:
|
|
w = Back.RED + str(w) + Style.RESET_ALL
|
|
isWithinRF = 0
|
|
|
|
print(str(GetAvgStressofPanel(i, c, 'XX')) + "," + str(GetAvgStressofPanel(i, c, 'YY')) + "," + str(GetAvgStressofPanel(i, c, 'XY')) + "," + str(kShear) + "," + str(kBiax(i, c)) + "," + str(w))
|
|
|
|
# Stringer buckling
|
|
print("\n\nStringer buckling")
|
|
for c in range(1,4):
|
|
print("\nLoadcase " + str(c) + "\nCombined, average axial stress for stringers 1 to 5")
|
|
for i in range(1,6):
|
|
w = GetRFstringer(i,c)
|
|
if(w>1):
|
|
w = Back.GREEN + str(w) + Style.RESET_ALL
|
|
else:
|
|
w = Back.RED + str(w) + Style.RESET_ALL
|
|
isWithinRF = 0
|
|
|
|
|
|
print(str(GetCombAvgStressofStringer(i,c)) + "," + str(GetSigCrip(i, c)) + "," + str(w)) # no longer slightly off, RF stringer calc still wrong?
|
|
|
|
# combined crosssection properties for combined buckling mode
|
|
print("\n\nCombined crosssection properties for combined buckling")
|
|
for i in range(5):
|
|
print(GetCrosssectionValues(i))
|
|
|
|
if(isWithinRF == 1):
|
|
print("\n\n" + Back.GREEN + str(u) + " WORKS!" + Style.RESET_ALL)
|
|
else:
|
|
print("\n\n" + Back.RED + str(u) + " FAILURE!" + Style.RESET_ALL)
|
|
|
|
#print(GetIcomb())
|
|
|
|
|
|
## OVERVIEW OF TODO:
|
|
# - improve some sections of code with TODO |