Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow for outboard loads on wing as signomial model #163

Merged
merged 9 commits into from
Apr 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions gpkitmodels/GP/aircraft/fuselage/elliptical_fuselage.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class FuselageAero(Model):
Cf [-] fuselage skin friction coefficient
Re [-] fuselage reynolds number
Cd [-] fuselage drag coefficient
mfac 1.0 [-] fuselage drag margin

"""
def setup(self, static, state):
Expand All @@ -26,7 +27,7 @@ def setup(self, static, state):
constraints = [
Re == V*rho*l/mu,
Cf >= 0.455/Re**0.3,
Cd >= Cf*k
Cd/mfac >= Cf*k
]

return constraints
Expand All @@ -47,6 +48,7 @@ class Fuselage(Model):
rhofuel 6.01 [lbf/gallon] density of 100LL
rhocfrp 1.6 [g/cm^3] density of CFRP
t [in] fuselage skin thickness
nply 2 [-] number of plys

"""
material = cfrpfabric
Expand All @@ -64,7 +66,7 @@ def setup(self):
3*(S/np.pi)**1.6075 >= 2*(l*R*2)**1.6075 + (2*R)**(2*1.6075),
Vol <= 4*np.pi/3*(l/2)*R**2,
W/mfac >= S*rhocfrp*t*g,
t >= 2*tmin,
t >= nply*tmin,
]

return constraints
Expand Down
21 changes: 6 additions & 15 deletions gpkitmodels/GP/aircraft/wing/gustloading.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,6 @@ class GustL(SparLoading):
agust [-] gust angle of attack
cosminus1 self.return_cosm1 [-] 1 minus cosine factor

Upper Unbounded
---------------
v, cl, wing.spar.I, wing.spar.tshear, wing.spar.Sy
J (if wingSparJ)
theta (if not wingSparJ), M (if not wingSparJ)

Lower Unbounded
---------------
Ww, wing.planform.b, wing.planform.cave
wing.planform.CM (if wingSparJ), qne (if wingSparJ)
theta (if not wingSparJ), M (if not wingSparJ)

LaTex Strings
-------------
vgust V_{\\mathrm{gust}}
Expand All @@ -53,12 +41,15 @@ class GustL(SparLoading):
return_cosm1 = lambda self, c: hstack(
[adnumber(1e-10), 1-array(cos(c[self.wing.planform.eta][1:]*pi/2))])

def setup(self, wing, state):
def setup(self, wing, state, sp=False):
exec parse_variables(GustL.__doc__)
self.load = SparLoading.setup(self, wing, state)
self.load = SparLoading.setup(self, wing, state, sp=sp)

cbar = self.wing.planform.cbar
W = self.W # from SparLoading
q = self.q
N = self.N
b = self.b

path = os.path.dirname(os.path.abspath(__file__))
df = pd.read_csv(path + os.sep + "arctan_fit.csv").to_dict(
Expand All @@ -67,7 +58,7 @@ def setup(self, wing, state):
constraints = [
# fit for arctan from 0 to 1, RMS = 0.044
FitCS(df, agust, [cosminus1*vgust/v]),
self.beam["\\bar{q}"] >= cbar*(1 + 2*pi*agust/cl*(1+Ww/W)),
q >= W*N/b*cbar*(1 + 2*pi*agust/cl*(1+Ww/W)),
]

return self.load, constraints
66 changes: 37 additions & 29 deletions gpkitmodels/GP/aircraft/wing/sparloading.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
" spar loading "
from gpkit import Model, parse_variables
from gpkit import Model, parse_variables, SignomialsEnabled
from gpkitmodels.GP.beam.beam import Beam
from gpkitmodels.GP.aircraft.tail.tail_boom import TailBoomState
from numpy import pi
Expand All @@ -16,24 +16,27 @@ class SparLoading(Model):
Nsafety 1.0 [-] safety load factor
kappa 0.2 [-] max tip deflection ratio
W [lbf] loading weight
N [-] loading factor
twmax 30.*pi/180 [-] max tip twist
Stip 1e-10 [N] tip loading
Mtip 1e-10 [N*m] tip moment
throot 1e-10 [-] root deflection angle
wroot 1e-10 [m] root deflection

Variables of length wing.N
--------------------------
q [N/m] distributed wing loading
S [N] shear along wing
M [N*m] wing section root moment
th [-] deflection angle
w [m] wing deflection

Variables of length wing.N-1
----------------------------
Mr [N*m] wing section root moment
M [N*m] local moment
Mtw [N*m] local moment due to twisting
theta [-] twist deflection

Upper Unbounded
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why'd you remove all the bounds? :p

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the bounds because it got really annoying as I was debugging

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think they're a useful feature overall? (during dev you can add SKIP VERIFICATION to disable checking)

---------------
I, Sy, J (if wingSparJ)
theta (if not wingSparJ), M (if not wingSparJ)

Lower Unbounded
---------------
b, W, cave
wing.planform.CM (if wingSparJ), qne (if wingSparJ)
theta (if not wingSparJ), M (if not wingSparJ)
EIbar [-] EIbar
Sout [N] outboard weights

LaTex Strings
-------------
Expand All @@ -49,29 +52,34 @@ def new_qbarFun(self, c):

new_SbarFun = None

def setup(self, wing, state):
def setup(self, wing, state, sp=False):
self.wing = wing
exec parse_variables(SparLoading.__doc__)

Beam.qbarFun = self.new_qbarFun
Beam.SbarFun = self.new_SbarFun
self.beam = Beam(self.wing.N)

b = self.b = self.wing.planform.b
I = self.I = self.wing.spar.I
Sy = self.Sy = self.wing.spar.Sy
cave = self.cave = self.wing.planform.cave
cbar = self.cbar = self.wing.planform.cbar
E = self.wing.spar.material.E
sigma = self.wing.spar.material.sigma
deta = self.wing.planform.deta

if sp:
with SignomialsEnabled():
shear = S[:-1] >= (S[1:] + 0.5*deta*(b/2.)*(q[:-1] + q[1:])
- Sout)
else:
shear = S[:-1] >= S[1:] + 0.5*deta*(b/2.)*(q[:-1] + q[1:])

constraints = [
# dimensionalize moment of inertia and young's modulus
self.beam["dx"] == deta,
self.beam["\\bar{EI}"] <= 8*E*I/Nmax/Nsafety/W/b**2,
Mr >= self.beam["\\bar{M}"][:-1]*W*Nmax*Nsafety*b/4,
sigma >= Mr/Sy,
self.beam["\\bar{\\delta}"][-1] <= kappa,
N == Nsafety*Nmax, q >= N*W/b*cbar,
shear, S[-1] >= Stip,
M[:-1] >= M[1:] + 0.5*deta*(b/2)*(S[:-1] + S[1:]), M[-1] >= Mtip,
th[0] >= throot,
th[1:] >= th[:-1] + 0.5*deta*(b/2)*(M[1:] + M[:-1])/E/I,
w[0] >= wroot, w[1:] >= w[:-1] + 0.5*deta*(b/2)*(th[1:] + th[:-1]),
sigma >= M[:-1]/Sy, w[-1]/(b/2) <= kappa,
]

self.wingSparJ = hasattr(self.wing.spar, "J")
Expand All @@ -82,9 +90,9 @@ def setup(self, wing, state):
G = self.wing.spar.shearMaterial.G
cm = self.wing.planform.CM
constraints.extend([
M >= cm*cave**2*qne*deta*b/2*Nsafety,
theta[0] >= M[0]/G/J[0]*deta[0]*b/2,
theta[1:] >= theta[:-1] + M[1:]/G/J[1:]*deta[1:]*b/2,
Mtw >= cm*cave**2*qne*deta*b/2*Nsafety,
theta[0] >= Mtw[0]/G/J[0]*deta[0]*b/2,
theta[1:] >= theta[:-1] + Mtw[1:]/G/J[1:]*deta[1:]*b/2,
twmax >= theta[-1]
])
return self.beam, constraints
return constraints
10 changes: 4 additions & 6 deletions gpkitmodels/GP/aircraft/wing/wing_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ def wing_test():
from gpkit import settings
if settings["default_solver"] == "cvxopt":
for l in loading:
for v in ["\\bar{M}_{tip}", "\\bar{S}_{tip}",
"\\bar{\\delta}_{root}", "\\theta_{root}"]:
l.substitutions[v] = 1e-3
for v in ["Mtip", "Stip", "wroot", "throot"]:
l.substitutions[v] = 1e-1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh why so much larger?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. But it gave me unknown at 1e-2 so...


m = Model(perf.Cd, [
loading[1].v == fs.V,
Expand All @@ -68,9 +67,8 @@ def box_spar():
from gpkit import settings
if settings["default_solver"] == "cvxopt":
for l in loading:
for v in ["\\bar{M}_{tip}", "\\bar{S}_{tip}",
"\\bar{\\delta}_{root}", "\\theta_{root}"]:
l.substitutions[v] = 1e-3
for v in ["Mtip", "Stip", "wroot", "throot"]:
l.substitutions[v] = 1e-2

m = Model(perf.Cd, [
loading[1].v == fs.V,
Expand Down