def test_united_dimensionless(self): "Check dimensionless unit-ed variables work" x = Variable('x') y = Variable('y', 'hr/day') c = MonomialEquality(x, y) self.assertTrue(isinstance(c, MonomialEquality))
"Example Vectorize usage, from gpkit/tests/t_vars.py" from gpkit import Variable, Vectorize, VectorVariable with Vectorize(3): with Vectorize(5): y = Variable("y") x = VectorVariable(2, "x") z = VectorVariable(7, "z") assert (y.shape == (5, 3)) assert (x.shape == (2, 5, 3)) assert (z.shape == (7, 3))
"Show autosweep_1d functionality" import pickle import numpy as np import gpkit from gpkit import units, Variable, Model from gpkit.tools.autosweep import autosweep_1d from gpkit.small_scripts import mag A = Variable("A", "m**2") l = Variable("l", "m") m1 = Model(A**2, [A >= l**2 + units.m**2]) tol1 = 1e-3 bst1 = autosweep_1d(m1, tol1, l, [1, 10], verbosity=0) print("Solved after %2i passes, cost logtol +/-%.3g" % (bst1.nsols, bst1.tol)) # autosweep solution accessing l_vals = np.linspace(1, 10, 10) sol1 = bst1.sample_at(l_vals) print("values of l: %s" % l_vals) print("values of A: %s" % sol1("A")) cost_estimate = sol1["cost"] cost_lb, cost_ub = sol1.cost_lb(), sol1.cost_ub() print("cost lower bound:\n%s\n" % cost_lb) print("cost estimate:\n%s\n" % cost_estimate) print("cost upper bound:\n%s\n" % cost_ub) # you can evaluate arbitrary posynomials np.testing.assert_allclose(mag(2*sol1(A)), mag(sol1(2*A))) assert (sol1["cost"] == sol1(A**2)).all() # the cost estimate is the logspace mean of its upper and lower bounds np.testing.assert_allclose((np.log(mag(cost_lb)) + np.log(mag(cost_ub)))/2, np.log(mag(cost_estimate)))
def test_parse_variables(self): Fuselage(Variable("Wfueltot", 5, "lbf"))
def setup(self, alt, **kwargs): p_sl = Variable("p_{sl}", 101325, "Pa", "Pressure at sea level") T_sl = Variable("T_{sl}", 288.15, "K", "Temperature at sea level") L_atm = Variable("L_{atm}", .0065, "K/m", "Temperature lapse rate") M_atm = Variable("M_{atm}", .0289644, "kg/mol", "Molar mass of dry air") p_atm = Variable("P_{atm}", "Pa", "air pressure") R_atm = Variable("R_{atm}", 8.31447, "J/mol/K", "air specific heating value") TH = 5.257386998354459 #(g*M_atm/R_atm/L_atm).value rho = self.rho = Variable('\\rho', 'kg/m^3', 'Density of air') T_atm = self.T_atm = Variable("T_{atm}", "K", "air temperature") h = self.h = alt['h'] """ Dynamic viscosity (mu) as a function of temperature References: http://www-mdp.eng.cam.ac.uk/web/library/enginfo/aerothermal_dvd_only/aero/ atmos/atmos.html http://www.cfd-online.com/Wiki/Sutherland's_law """ mu = Variable('\\mu', 'kg/(m*s)', 'Dynamic viscosity') T_s = Variable('T_s', 110.4, "K", "Sutherland Temperature") C_1 = Variable('C_1', 1.458E-6, "kg/(m*s*K^0.5)", 'Sutherland coefficient') with SignomialsEnabled(): constraints = [ # Pressure-altitude relation (p_atm / p_sl)**(1 / 5.257) == T_atm / T_sl, # Ideal gas law rho == p_atm / (R_atm / M_atm * T_atm), #temperature equation SignomialEquality(T_sl, T_atm + L_atm * h), #constraint on mu mu == C_1 * T_atm**1.5 / (6.64 * units('K^.28') * T_s**0.72), ] #like to use a local subs here in the future subs = None return constraints
def setup(self, aircraft, sp=False): fs = FlightState() A = Variable("A", "m/s**2", "log fit equation helper 1") B = Variable("B", "1/m", "log fit equation helper 2") g = Variable("g", 9.81, "m/s**2", "gravitational constant") mu = Variable("\\mu_b", 0.025, "-", "coefficient of friction") T = Variable("T", "lbf", "take off thrust") cda = Variable("CDA", 0.024, "-", "parasite drag coefficient") CLg = Variable("C_{L_g}", "-", "ground lift coefficient") CDg = Variable("C_{D_g}", "-", "grag ground coefficient") cdp = Variable("c_{d_{p_{stall}}}", 0.025, "-", "profile drag at Vstallx1.2") Kg = Variable("K_g", 0.04, "-", "ground-effect induced drag parameter") CLto = Variable("C_{L_{TO}}", 3.5, "-", "max lift coefficient") Vstall = Variable("V_{stall}", "knots", "stall velocity") e = Variable("e", 0.8, "-", "span efficiency") zsto = Variable("z_{S_{TO}}", "-", "take off distance helper variable") Sto = Variable("S_{TO}", "ft", "take off distance") Sground = Variable("S_{ground}", "ft", "ground roll") etaprop = Variable("\\eta_{prop}", 0.8, "-", "propellor efficiency") msafety = Variable("m_{fac}", 1.4, "-", "safety margin") path = os.path.dirname(os.path.abspath(__file__)) df = pd.read_csv(path + os.sep + "logfit.csv") fd = df.to_dict(orient="records")[0] constraints = [ T / aircraft.topvar("W") >= A / g + mu, T <= aircraft["P_{shaft-max}"] * etaprop / fs["V"], CDg >= 0.024 + cdp + CLto**2 / pi / aircraft["AR"] / e, Vstall == (2 * aircraft.topvar("W") / fs["\\rho"] / aircraft.wing["S"] / CLto)**0.5, fs["V"] == 1.3 * Vstall, FitCS(fd, zsto, [A / g, B * fs["V"]**2 / g]), Sground >= 1.0 / 2.0 / B * zsto, Sto / msafety >= Sground ] if sp: with SignomialsEnabled(): constraints.extend([ (B * aircraft.topvar("W") / g + 0.5 * fs["\\rho"] * aircraft.wing["S"] * mu * CLto >= 0.5 * fs["\\rho"] * aircraft.wing["S"] * CDg) ]) else: constraints.extend([ B >= (g / aircraft.topvar("W") * 0.5 * fs["\\rho"] * aircraft.wing["S"] * CDg) ]) return constraints, fs
"Debug examples" from gpkit import Variable, Model, units x = Variable("x", "ft") x_min = Variable("x_min", 2, "ft") x_max = Variable("x_max", 1, "ft") y = Variable("y", "volts") m = Model(x / y, [x <= x_max, x >= x_min]) m.debug() print("# Now let's try a model unsolvable with relaxed constants\n") m2 = Model(x, [x <= units("inch"), x >= units("yard")]) m2.debug() print("# And one that's only unbounded\n") # the value of x_min was used up in the previous model! x_min = Variable("x_min", 2, "ft") m3 = Model(x / y, [x >= x_min]) m3.debug()
def setup(self): x = Variable("x") return [x >= 1]
def test_bad_gp_sub(self): x = Variable("x") y = Variable("y") m = Model(x, [y >= 1], {y: x}) with self.assertRaises(ValueError): m.solve()
def setup(self,aircraft,Nsegments): self.aircraft = aircraft W_f_m = Variable('W_{f_m}','N','total mission fuel') t_m = Variable('t_m','hr','total mission time') with Vectorize(Nsegments): Wavg = Variable('W_{avg}','N','segment average weight') Wstart = Variable('W_{start}', 'N', 'weight at the beginning of flight segment') Wend = Variable('W_{end}', 'N', 'weight at the end of flight segment') h = Variable('h','m','final segment flight altitude') havg = Variable('h_{avg}','m','average segment flight altitude') dhdt = Variable('\\frac{dh}{dt}','m/hr','climb rate') W_f_s = Variable('W_{f_s}','N', 'segment fuel burn') t_s = Variable('t_s','hr','time spent in flight segment') R_s = Variable('R_s','km','range flown in segment') state = Atmosphere() self.aircraftP = self.aircraft.dynamic(state) # Mission variables hcruise = Variable('h_{cruise_m}', 'm', 'minimum cruise altitude') Range = Variable("Range_m", "km", "aircraft range") W_p = Variable("W_{p_m}", "N", "payload weight", pr=20.) rho_p = Variable("\\rho_{p_m}", "kg/m^3", "payload density", pr = 10.) V_min = Variable("V_{min_m}", "m/s", "takeoff speed", pr=20.) TOfac = Variable('T/O factor_m', '-','takeoff thrust factor') cost_index = Variable("C_m", '1/hr','hourly cost index') constraints = [] # Setting up the mission with SignomialsEnabled(): constraints += [havg == state['h'], # Linking states h[1:Nsegments-1] >= hcruise, # Adding minimum cruise altitude # Weights at beginning and end of mission Wstart[0] >= W_p + self.aircraft.wing['W_w'] + self.aircraft.engine['W_e'] + self.aircraft.fuse['W_{fuse}'] + W_f_m, Wend[Nsegments-1] >= W_p + self.aircraft.wing['W_w'] + self.aircraft.engine['W_e'] + self.aircraft.fuse['W_{fuse}'], # Lift, and linking segment start and end weights Wavg <= 0.5 * state['\\rho'] * self.aircraft['S'] * self.aircraftP.wingP['C_L'] * self.aircraftP['V'] ** 2, Wstart >= Wend + W_f_s, # Making sure fuel gets burnt! Wstart[1:Nsegments] == Wend[:Nsegments-1], Wavg == Wstart ** 0.5 * Wend ** 0.5, # Altitude changes h[0] == t_s[0]*dhdt[0], # Starting altitude dhdt >= 1.*units('m/hr'), havg[0] == 0.5*h[0], havg[1:Nsegments] == (h[1:Nsegments]*h[0:Nsegments-1])**(0.5), SignomialEquality(h[1:Nsegments],h[:Nsegments-1] + t_s[1:Nsegments]*dhdt[1:Nsegments]), # Thrust and fuel burn W_f_s >= self.aircraftP.engineP['BSFC'] * self.aircraftP.engineP['P_{shaft}'] * t_s, self.aircraftP.engineP['T'] * self.aircraftP['V'] >= self.aircraftP['D'] * self.aircraftP['V'] + Wavg * dhdt, # Max MSL thrust at least 2*climb thrust self.aircraft.engine['P_{shaft,max}'] >= TOfac*self.aircraftP.engineP['P_{shaft}'][0], # Flight time t_s == R_s/self.aircraftP['V'], # Aggregating segment variables self.aircraft['W_f'] >= W_f_m, R_s == Range/Nsegments, # Dividing into equal range segments W_f_m >= sum(W_f_s), t_m >= sum(t_s) ] # Maximum takeoff weight constraints += [self.aircraft['W'] >= W_p + self.aircraft.wing['W_w'] + self.aircraft['W_f'] + self.aircraft.engine['W_e'] + self.aircraft.fuse['W_{fuse}']] # Stall constraint constraints += [self.aircraft['W'] <= 0.5 * state['\\rho'] * self.aircraft['S'] * self.aircraft['C_{L,max}'] * V_min ** 2] # Wing weight model constraints += [self.aircraft.wing['W_{w_{strc}}']**2. >= self.aircraft.wing['W_{w_{coeff1}}']**2. / self.aircraft.wing['\\tau']**2. * (self.aircraft.wing['N_{ult}']**2. * self.aircraft.wing['A'] ** 3. * ((W_p + self.aircraft.fuse['W_{fuse}'] + self.aircraft['W_e'] + self.aircraft.fuse['V_{f_{fuse}}']*self.aircraft['g']*self.aircraft['\\rho_f']) * self.aircraft['W'] * self.aircraft.wing['S']))] # Fuselage volume and weight constraints += [self.aircraft.fuse['V_{fuse}'] >= self.aircraft.fuse['V_{f_{fuse}}'] + W_p/(rho_p*self.aircraft['g']), self.aircraft.fuse['W_{fuse}'] == self.aircraft.fuse['S_{fuse}']*self.aircraft.wing['W_{w_{coeff2}}'], ] # Upper bounding variables constraints += [t_m <= 100000*units('hr'), W_f_m <= 1e10*units('N'), cost_index >= 1e-10*units('1/hr')] return constraints, state, self.aircraft, self.aircraftP
def setup(self): B = Variable('B', 'm', 'Landing gear base') E = Variable('E', 'GPa', 'Modulus of elasticity, 4340 steel') Eland = Variable('E_{land}', 'J', 'Max KE to be absorbed in landing') Fwm = Variable('F_{w_m}', '-', 'Weight factor (main)') Fwn = Variable('F_{w_n}', '-', 'Weight factor (nose)') I_m = Variable('I_m', 'm^4', 'Area moment of inertia (main strut)') I_n = Variable('I_n', 'm^4', 'Area moment of inertia (nose strut)') K = Variable('K', '-', 'Column effective length factor') L_m = Variable('L_m', 'N', 'Max static load through main gear') L_n = Variable('L_n', 'N', 'Min static load through nose gear') L_n_dyn = Variable('L_{n_{dyn}}', 'N', 'Dyn. braking load, nose gear') Lwm = Variable('L_{w_m}', 'N', 'Static load per wheel (main)') Lwn = Variable('L_{w_n}', 'N', 'Static load per wheel (nose)') N_s = Variable('N_s', '-', 'Factor of safety') S_sa = Variable('S_{sa}', 'm', 'Stroke of the shock absorber') ## S_t = Variable('S_t', 'm', 'Tire deflection') T = Variable('T', 'm', 'Main landing gear track') WAWm = Variable('W_{wa,m}', 'lbf', 'Wheel assembly weight for single main gear wheel') WAWn = Variable('W_{wa,n}', 'lbf', 'Wheel assembly weight for single nose gear wheel') ## W_0 = Variable('W_{0_{lg}}', 'N', ## 'Weight of aircraft excluding landing gear') Clg = Variable('C_{lg}', 1, '-', 'Landing Gear Weight Margin/Sens Factor') W_lg = Variable('W_{lg}', 'N', 'Weight of landing gear') W_mg = Variable('W_{mg}', 'N', 'Weight of main gear') W_ms = Variable('W_{ms}', 'N', 'Weight of main struts') W_mw = Variable('W_{mw}', 'N', 'Weight of main wheels (per strut)') W_ng = Variable('W_{ng}', 'N', 'Weight of nose gear') W_ns = Variable('W_{ns}', 'N', 'Weight of nose strut') W_nw = Variable('W_{nw}', 'N', 'Weight of nose wheels (total)') d_oleo = Variable('d_{oleo}', 'm', 'Diameter of oleo shock absorber') dtm = Variable('d_{t_m}', 'in', 'Diameter of main gear tires') dtn = Variable('d_{t_n}', 'in', 'Diameter of nose gear tires') dxm = Variable('\\Delta x_m', 'm', 'Distance b/w main gear and CG') dxn = Variable('\\Delta x_n', 'm', 'Distance b/w nose gear and CG') eta_s = Variable('\\eta_s', '-', 'Shock absorber efficiency') faddm = Variable('f_{add,m}', '-', 'Proportional added weight, main') faddn = Variable('f_{add,n}', '-', 'Proportional added weight, nose') g = Variable('g', 9.81, 'm/s^2', 'Gravitational acceleration') h_nac = Variable('h_{nacelle}', 'm', 'Min. nacelle clearance') hhold = Variable('h_{hold}', 'm', 'Hold height') l_m = Variable('l_m', 'm', 'Length of main gear') l_n = Variable('l_n', 'm', 'Length of nose gear') l_oleo = Variable('l_{oleo}', 'm', 'Length of oleo shock absorber') lam = Variable('\\lambda_{LG}', '-', 'Ratio of max to static load') # Torenbeek p360 n_mg = Variable('n_{mg}', '-', 'Number of main gear struts') nwps = Variable('n_{wps}', '-', 'Number of wheels per strut') p_oleo = Variable('p_{oleo}', 'lbf/in^2', 'Oleo pressure') #p_t = Variable('p_t', 170, 'lbf/in^2', 'Tyre pressure') r_m = Variable('r_m', 'm', 'Radius of main gear struts') r_n = Variable('r_n', 'm', 'Radius of nose gear struts') rho_st = Variable('\\rho_{st}', 'kg/m^3', 'Density of 4340 Steel') sig_y_c = Variable('\\sigma_{y_c}', 'Pa', 'Compressive yield strength 4340 steel') # AZOM t_m = Variable('t_m', 'm', 'Thickness of main gear strut wall') t_n = Variable('t_n', 'm', 'Thickness of nose gear strut wall') t_nac = Variable('t_{nacelle}', 'm', 'Nacelle thickness') tan_15 = Variable('\\tan(\\phi_{min})', '-', 'Lower bound on phi') tan_63 = Variable('\\tan(\\psi_{max})', '-', 'Upper bound on psi') tan_gam = Variable('\\tan(\\gamma)', '-', 'Dihedral angle') tan_phi = Variable('\\tan(\\phi)', '-', 'Angle b/w main gear and CG') tan_psi = Variable('\\tan(\\psi)', '-', 'Tip over angle') tan_th = Variable('\\tan(\\theta_{max})', '-', 'Max rotation angle') w_ult = Variable('w_{ult}', 'ft/s', 'Ultimate velocity of descent') wtm = Variable('w_{t_m}', 'm', 'Width of main tires') wtn = Variable('w_{t_n}', 'm', 'Width of nose tires') x_m = Variable('x_m', 'm', 'x-location of main gear') x_n = Variable('x_n', 'm', 'x-location of nose gear') x_upswp = Variable('x_{up}', 'm', 'Fuselage upsweep point') xcglg = Variable('x_{CG_{lg}}', 'm', 'Landing gear CG') y_m = Variable('y_m', 'm', 'y-location of main gear (symmetric)') z_CG_0 = Variable('z_{CG}', 'm', 'CG height relative to bottom of fuselage') zwing = Variable('z_{wing}', 'm', 'Height of wing relative to base of fuselage') d_nac = Variable('d_{nacelle}', 'm', 'Nacelle diameter') with SignomialsEnabled(): objective = W_lg constraints = [ # Track and Base geometry definitions TCS([l_n+zwing+y_m*tan_gam>=l_m], reltol=1E-3), #[SP] T == 2*y_m, TCS([x_n + B <= x_m]), x_n >= 5*units.m, # nose gear after nose # Longitudinal tip over (static) tan_phi == tan_15, # Lateral tip over in turn (dynamic) # www.dept.aoe.vt.edu/~mason/Mason_f/M96SC03.pdf # stricter constraint uses forward CG # cos(arctan(y/x))) = x/sqrt(x^2 + y^2) 1 >= (z_CG_0 + l_m)**2 * (y_m**2 + B**2) / (dxn * y_m * tan_psi)**2, tan_psi <= tan_63, # Tail strike: Longitudinal ground clearance in # takeoff, landing (Raymer says 10-15 degrees) # TODO?: 2 cases:(i) upsweep angle > rotation angle, # (ii) upsweep angle < rotation ang x_upswp - x_m <= l_m/tan_th, # [SP] # Size/Volume for retraction y_m >= l_m, # Brake sizing for stopping aircraft # Hard landing # http://www.boeing.com/commercial/aeromagazine/... # articles/qtr_3_07/AERO_Q307_article3.pdf # sink rate of 10 feet per second at the maximum # design landing weight # Landing condition from Torenbeek p360 ## Eland >= W/(2*g)*w_ult**2, # Torenbeek (10-26) # S_t == 0.5*lam*Lwm/(p*(dtm*bt)**0.5), # (10-30) S_sa == (1/eta_s)*(Eland/(L_m*lam)),# - eta_t*S_t), # [SP] Torenbeek (10-28) l_oleo == 2.5*S_sa, # Raymer 244 d_oleo == 1.3*(4*lam*L_m/n_mg/(np.pi*p_oleo))**0.5, l_m >= l_oleo + dtm/2, # Wheel weights Fwm == Lwm*dtm/(1000*Lwm.units*dtm.units), WAWm == 1.2*Fwm**0.609*units.lbf,# Currey p145 Fwn == Lwn*dtn/(1000*units.lbf*units.inches), WAWn == 1.2*Fwn**0.609*units.lbf,# Currey p145 Lwm == L_m/(n_mg*nwps), Lwn == L_n/nwps, # Main wheel diameter/width (Raymer p233) dtm == 1.63*(Lwm/(4.44*units.N))**0.315*units.inch, wtm == 0.1043*(Lwm/(4.44*units.N))**0.48*units.inch, dtn == 0.8*dtm, wtn == 0.8*wtm, # TODO: Beam sizing and max bending (limits track, # downward pressure on y_m) # Weight is a function of height and load through # each strut as well as tyre size (and obviously # number of struts) # Main gear strut weight (for a single strut) is a # function of length and load passing through strut W_ms >= 2*np.pi*r_m*t_m*l_m * rho_st * g, # Compressive yield in hard landing condition N_s * lam * L_m/n_mg <= sig_y_c * (2*np.pi*r_m*t_m), W_mw == nwps*WAWm, # Nose gear strut weight is a function of length and # load passing through strut W_ns >= 2*np.pi*r_n*t_n*l_n * rho_st * g, # find cross sectional area based on compressive yield N_s * (L_n + L_n_dyn) <= sig_y_c*(2*np.pi*r_n*t_n), W_nw >= nwps*WAWn, # Buckling constraint on main gear L_m <= np.pi**2*E*I_m/(K*l_m)**2, I_m == np.pi*r_m**3*t_m, # Buckling constraint on nose gear # source: https://en.wikipedia.org/wiki/Buckling L_n <= np.pi**2*E*I_n/(K*l_n)**2, I_n == np.pi*r_n**3*t_n, # Machining constraint # p89 Mason # www.dept.aoe.vt.edu/~mason/Mason_f/M96SC08.pdf 2*r_m/t_m <= 40, 2*r_m/t_n <= 40, # Retraction constraint on strut diameter 2*wtm + 2*r_m <= hhold, 2*wtn + 2*r_n <= 0.8*units.m, #TODO improve this # Weight accounting W_mg >= n_mg*(W_ms + W_mw*(1 + faddm)),# Currey p264 W_ng >= W_ns + W_nw*(1 + faddn), W_lg >= Clg * (W_mg + W_ng), #LG CG accounting TCS([W_lg*xcglg >= W_ng*x_n + W_mg*x_m], reltol=1E-2, raiseerror=False), x_m >= xcglg, ] return constraints
def setup(self): # Non-dimensional constants C_Lmax = Variable("C_{L,max}", 1.6, "-", "lift coefficient at stall", pr=5.) e = Variable("e", 0.92, "-", "Oswald efficiency factor", pr=3.) # k = Variable("k", "-", "form factor") N_ult = Variable("N_{ult}", 3, "-", "ultimate load factor", pr=15.) # S_wetratio = Variable("(\\frac{S}{S_{wet}})", "-", "wetted area ratio") tau = Variable("\\tau", "-", "airfoil thickness to chord ratio") tau_ref = Variable("\\tau_{ref}", 0.12, "-", "reference airfoil thickness to chord ratio") # Dimensional constants W_w_coeff1 = Variable("W_{w_{coeff1}}", 2e-5, "1/m", "wing weight coefficient 1", pr= 30.) #orig 12e-5 W_w_coeff2 = Variable("W_{w_{coeff2}}", 60., "Pa", "wing weight coefficient 2", pr=10.) # Free Variables (fixed for performance eval.) A = Variable("A", "-", "aspect ratio",fix = True) S = Variable("S", "m^2", "total wing area", fix = True) W_w = Variable("W_w", "N", "wing weight") W_w_strc = Variable('W_{w_{strc}}','N','wing structural weight', fix = True) W_w_surf = Variable('W_{w_{surf}}','N','wing skin weight', fix = True) V_f_wing = Variable("V_{f_{wing}}",'m^3','fuel volume in the wing', fix = True) constraints = [] # Structural model constraints += [W_w_surf >= W_w_coeff2 * S, W_w >= W_w_surf + W_w_strc] # Wing fuel and form factor model constraints += [V_f_wing**2 <= 0.0009*S**3/A*tau**2, # linear with b and tau, quadratic with chord tau >= 0.08, tau <= 0.23, ] # Form factor model return constraints
def test_equality_relaxation(self): x = Variable("x") m = Model(x, [x == 3, x == 4]) rc = ConstraintsRelaxed(m) m2 = Model(rc.relaxvars.prod() * x**0.01, rc) self.assertAlmostEqual(m2.solve(verbosity=0)(x), 3, places=3)
def test_becomes_posy_sensitivities(self): # pylint: disable=invalid-name # model from #1165 ujet = Variable("ujet") PK = Variable("PK") Dp = Variable("Dp", 0.662) fBLI = Variable("fBLI", 0.4) fsurf = Variable("fsurf", 0.836) mdot = Variable("mdot", 1 / 0.7376) with SignomialsEnabled(): m = Model(PK, [ mdot * ujet + fBLI * Dp >= 1, PK >= 0.5 * mdot * ujet * (2 + ujet) + fBLI * fsurf * Dp ]) var_senss = m.solve(verbosity=0)["sensitivities"]["variables"] self.assertAlmostEqual(var_senss[Dp], -0.16, 2) self.assertAlmostEqual(var_senss[fBLI], -0.16, 2) self.assertAlmostEqual(var_senss[fsurf], 0.19, 2) self.assertAlmostEqual(var_senss[mdot], -0.17, 2) # Linked variable Dp = Variable("Dp", 0.662) mDp = Variable("-Dp", lambda c: -c[Dp]) fBLI = Variable("fBLI", 0.4) fsurf = Variable("fsurf", 0.836) mdot = Variable("mdot", 1 / 0.7376) m = Model(PK, [ mdot * ujet >= 1 + fBLI * mDp, PK >= 0.5 * mdot * ujet * (2 + ujet) + fBLI * fsurf * Dp ]) var_senss = m.solve(verbosity=0)["sensitivities"]["variables"] self.assertAlmostEqual(var_senss[Dp], -0.16, 2) self.assertAlmostEqual(var_senss[fBLI], -0.16, 2) self.assertAlmostEqual(var_senss[fsurf], 0.19, 2) self.assertAlmostEqual(var_senss[mdot], -0.17, 2) # fixed negative variable Dp = Variable("Dp", 0.662) mDp = Variable("-Dp", -0.662) fBLI = Variable("fBLI", 0.4) fsurf = Variable("fsurf", 0.836) mdot = Variable("mdot", 1 / 0.7376) m = Model(PK, [ mdot * ujet >= 1 + fBLI * mDp, PK >= 0.5 * mdot * ujet * (2 + ujet) + fBLI * fsurf * Dp ]) var_senss = m.solve(verbosity=0)["sensitivities"]["variables"] self.assertAlmostEqual(var_senss[Dp] + var_senss[mDp], -0.16, 2) self.assertAlmostEqual(var_senss[fBLI], -0.16, 2) self.assertAlmostEqual(var_senss[fsurf], 0.19, 2) self.assertAlmostEqual(var_senss[mdot], -0.17, 2)
def test_setattr(self): kd = KeyDict() x = Variable("x", lineage=(("test", 0),)) kd[x] = 1 self.assertIn(x, kd) self.assertEqual(set(kd), set([x.key]))
def setup(self): x = self.x = Variable("x", "ft") x_max = Variable("x_{max}", 1, "yard") self.cost = 1 / x return [x <= x_max]
def setup(self): Wing.fillModel = None self.wing = Wing() W = Variable("W", "lbf", "aircraft weight") WS = Variable("W/S", "lbf/ft^2", "Aircraft wing loading") PW = Variable("P/W", "hp/lbf", "Aircraft shaft hp/weight ratio") Wpay = Variable("W_{pay}", 2 * 195, "lbf", "payload weight") hbatt = Variable("h_{batt}", 210, "W*hr/kg", "battery specific energy") etae = Variable("\\eta_{e}", 0.9, "-", "total electrical efficiency") Wbatt = Variable("W_{batt}", "lbf", "battery weight") Wwing = Variable("W_{wing}", "lbf", "wing weight") Pshaftmax = Variable("P_{shaft-max}", "W", "max shaft power") sp_motor = Variable("sp_{motor}", 7. / 9.81, "kW/N", 'Motor specific power') Wmotor = Variable("W_{motor}", "lbf", "motor weight") Wcent = Variable("W_{cent}", "lbf", "aircraft center weight") fstruct = Variable("f_{struct}", 0.2, "-", "structural weight fraction") Wstruct = Variable("W_{struct}", "lbf", "structural weight") e = Variable("e", 0.8, "-", "span efficiency factor") CL_max_clean = Variable("CL_{max_{clean}}", 1.6, "-", "Clean CL max") CL_max_to = Variable("CL_{max_{to}}", 2.0, "-", "Clean CL max") CL_max_aprch = Variable("CL_{max_{aprch}}", 2.4, "-", "Clean CL max") fbattmax = Variable("f_{batt,max}", 1.0, "-", "max battery fraction") loading = self.wing.spar.loading(self.wing) loading.substitutions.update({ loading.kappa: 0.05, self.wing.spar.material.sigma: 1.5e9, loading.Nmax: 6, self.wing.skin.material.tmin: 0.012 * 4, self.wing.mfac: 1.4, self.wing.spar.mfac: 0.8 }) constraints = [ Wcent == loading.W, WS == W / self.wing.planform.S, PW == Pshaftmax / W, TCS([W >= Wbatt + Wpay + self.wing.W + Wmotor + Wstruct]), Wcent >= Wbatt + Wpay + Wmotor + Wstruct, Wstruct >= fstruct * W, Wmotor >= Pshaftmax / sp_motor, Wbatt / W <= fbattmax, ] return constraints, self.wing, loading
def setup(self): x = self.x = Variable("x", "m") x_min = Variable("x_{min}", 1, "cm") self.cost = x return [x >= x_min]
"Minimizes cylindrical tank surface area for a particular volume." from gpkit import Variable, VectorVariable, Model M = Variable("M", 100, "kg", "Mass of Water in the Tank") rho = Variable("\\rho", 1000, "kg/m^3", "Density of Water in the Tank") A = Variable("A", "m^2", "Surface Area of the Tank") V = Variable("V", "m^3", "Volume of the Tank") d = VectorVariable(3, "d", "m", "Dimension Vector") constraints = (A >= 2 * (d[0] * d[1] + d[0] * d[2] + d[1] * d[2]), V == d[0] * d[1] * d[2], M == V * rho) m = Model(A, constraints) sol = m.solve(verbosity=0) print sol.table()
def setup(self): y = self.y = Variable('y') s = Sub() sy = s["y"] self.cost = y return [s, y >= sy, sy >= 1]
from gpkit import Variable g = Variable("g", 9.81, "m/s^2", "earth surface gravitational acceleration")
def setup(self): sub = Sub() x = self.x = Variable("x") self.cost = x return sub, [x >= sub["y"], sub["y"] >= 1]
def SimPleAC(): "Creates SimpleAC model" # Env. constants g = Variable("g", 9.81, "m/s^2", "gravitational acceleration") mu = Variable("\\mu", 1.775e-5, "kg/m/s", "viscosity of air") rho = Variable("\\rho", 1.23, "kg/m^3", "density of air") rho_f = Variable("\\rho_f", 817, "kg/m^3", "density of fuel") # Non-dimensional constants C_Lmax = Variable("C_{L,max}", 1.6, "-", "max CL with flaps down") e = Variable("e", 0.92, "-", "Oswald efficiency factor") k = Variable("k", 1.17, "-", "form factor") N_ult = Variable("N_{ult}", 3.3, "-", "ultimate load factor") S_wetratio = Variable("(\\frac{S}{S_{wet}})", 2.075, "-", "wetted area ratio") tau = Variable("\\tau", 0.12, "-", "airfoil thickness to chord ratio") W_W_coeff1 = Variable("W_{W_{coeff1}}", 2e-5, "1/m", "wing weight coefficent 1") # 12e-5 originally W_W_coeff2 = Variable("W_{W_{coeff2}}", 60, "Pa", "wing weight coefficent 2") # Dimensional constants Range = Variable("Range", 3000, "km", "aircraft range") TSFC = Variable("TSFC", 0.6, "1/hr", "thrust specific fuel consumption") V_min = Variable("V_{min}", 25, "m/s", "takeoff speed") W_0 = Variable("W_0", 6250, "N", "aircraft weight excluding wing") # Free Variables LoD = Variable("L/D", "-", "lift-to-drag ratio") D = Variable("D", "N", "total drag force") V = Variable("V", "m/s", "cruising speed") W = Variable("W", "N", "total aircraft weight") Re = Variable("Re", "-", "Reynold's number") CDA0 = Variable("(CDA0)", "m^2", "fuselage drag area") # 0.035 originally C_D = Variable("C_D", "-", "drag coefficient") C_L = Variable("C_L", "-", "lift coefficient of wing") C_f = Variable("C_f", "-", "skin friction coefficient") W_f = Variable("W_f", "N", "fuel weight") V_f = Variable("V_f", "m^3", "fuel volume") V_f_avail = Variable("V_{f_{avail}}", "m^3", "fuel volume available") T_flight = Variable("T_{flight}", "hr", "flight time") # Free variables (fixed for performance eval.) A = Variable("A", "-", "aspect ratio") S = Variable("S", "m^2", "total wing area") W_w = Variable("W_w", "N", "wing weight") W_w_strc = Variable("W_w_strc", "N", "wing structural weight") W_w_surf = Variable("W_w_surf", "N", "wing skin weight") V_f_wing = Variable("V_f_wing", "m^3", "fuel volume in the wing") V_f_fuse = Variable("V_f_fuse", "m^3", "fuel volume in the fuselage") objective = W_f constraints = [] # Weight and lift model constraints += [ W >= W_0 + W_w + W_f, W_0 + W_w + 0.5 * W_f <= 0.5 * rho * S * C_L * V**2, W <= 0.5 * rho * S * C_Lmax * V_min**2, T_flight >= Range / V, LoD == C_L / C_D ] # Thrust and drag model C_D_fuse = CDA0 / S C_D_wpar = k * C_f * S_wetratio C_D_ind = C_L**2 / (np.pi * A * e) constraints += [ W_f >= TSFC * T_flight * D, D >= 0.5 * rho * S * C_D * V**2, C_D >= C_D_fuse + C_D_wpar + C_D_ind, V_f_fuse <= 10 * units("m") * CDA0, Re <= (rho / mu) * V * (S / A)**0.5, C_f >= 0.074 / Re**0.2 ] # Fuel volume model with SignomialsEnabled(): constraints += [ V_f == W_f / g / rho_f, # linear with b and tau, quadratic with chord V_f_wing**2 <= 0.0009 * S**3 / A * tau**2, V_f_avail <= V_f_wing + V_f_fuse, # [SP] Tight([V_f_avail >= V_f]) ] # Wing weight model constraints += [ W_w_surf >= W_W_coeff2 * S, W_w_strc**2 >= W_W_coeff1**2 / tau**2 * N_ult**2 * A**3 * (V_f_fuse * g * rho_f + W_0) * W * S, W_w >= W_w_surf + W_w_strc ] m = Model(objective, constraints) return m
def setup(self): y = self.y = Variable('y') self.cost = y return [y >= 2]
def setup(self, ac, substitutions=None, **kwargs): #define the number of each flight segment Nclimb = 2 Ncruise = 2 #Vectorize with Vectorize(Nclimb): climb = ClimbSegment(ac) with Vectorize(Ncruise): cruise = CruiseSegment(ac) #declare new variables W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight') W_fclimb = Variable('W_{f_{climb}}', 'N', 'Fuel Weight Burned in Climb') W_fcruise = Variable('W_{f_{cruise}}', 'N', 'Fuel Weight Burned in Cruise') W_total = Variable('W_{total}', 'N', 'Total Aircraft Weight') CruiseAlt = Variable('CruiseAlt', 'ft', 'Cruise Altitude [feet]') ReqRng = Variable('R_{req}', 'nautical_miles', 'Required Cruise Range') h = climb['h'] hftClimb = climb['hft'] dhft = climb['dhft'] hftCruise = cruise['hft'] #make overall constraints constraints = [] constraints.extend([ #weight constraints TCS([ ac['W_{e}'] + ac['W_{payload}'] + W_ftotal + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_total ]), climb['W_{start}'][0] == W_total, climb['W_{end}'][-1] == cruise['W_{start}'][0], # similar constraint 1 TCS([climb['W_{start}'] >= climb['W_{end}'] + climb['W_{burn}']]), # similar constraint 2 TCS([ cruise['W_{start}'] >= cruise['W_{end}'] + cruise['W_{burn}'] ]), climb['W_{start}'][1:] == climb['W_{end}'][:-1], cruise['W_{start}'][1:] == cruise['W_{end}'][:-1], TCS([ ac['W_{e}'] + ac['W_{payload}'] + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= cruise['W_{end}'][-1] ]), TCS([W_ftotal >= W_fclimb + W_fcruise]), TCS([W_fclimb >= sum(climb['W_{burn}'])]), TCS([W_fcruise >= sum(cruise['W_{burn}'])]), #altitude constraints hftCruise == CruiseAlt, TCS([hftClimb[1:Ncruise] >= hftClimb[:Ncruise - 1] + dhft]), TCS([hftClimb[0] >= dhft[0]]), hftClimb[-1] <= hftCruise, #compute the dh dhft == hftCruise / Nclimb, #constrain the thrust climb['thrust'] <= 2 * max(cruise['thrust']), #set the range for each cruise segment, doesn't take credit for climb #down range disatnce covered cruise.cruiseP['Rng'] == ReqRng / (Ncruise), #set the TSFC climb['TSFC'] == .7 * units('1/hr'), cruise['TSFC'] == .5 * units('1/hr'), ]) # Model.setup(self, W_ftotal + s*units('N'), constraints + ac + climb + cruise, subs) return constraints + ac + climb + cruise
def test_dimensionless_units(self): x = Variable('x', 3, 'ft') y = Variable('y', 1, 'm') if x.units is not None: # units are enabled self.assertAlmostEqual((x / y).value, 0.9144)
"Another simple primal infeasible example" from gpkit import Variable, Model #Make the necessary Variables x = Variable("x") y = Variable("y", 2) #make the constraints constraints = [x >= 1, 0.5 <= x * y, x * y <= 1.5] #declare the objective objective = x * y #construct the model m = Model(objective, constraints) #solve the model #raises RuntimeWarning uknown on cvxopt and RuntimeWarning #PRIM_INFES_CER with mosek #m.solve()
def test_unitless_monomial_sub(self): "Tests that dimensionless and undimensioned subs can interact." x = Variable("x", "-") y = Variable("y") self.assertEqual(x.sub({x: y}), y)
def test_setattr(self): kd = KeyDict() x = Variable("x", models=["test"]) kd[x] = 1 self.assertIn(x, kd) self.assertEqual(set(kd), set([x.key]))
def test_str(self): "Test that MonomialEquality.__str__ returns a string" x = Variable('x') y = Variable('y') mec = (x == y) self.assertEqual(type(mec.str_without()), str)