def setup(self, aircraft, state, **kwargs): #make submodels self.aircraft = aircraft self.wingP = aircraft.wing.dynamic(state) self.fuseP = aircraft.fuse.dynamic(state) self.engineP = aircraft.engine.dynamic(state) self.Pmodels = [self.wingP, self.fuseP, self.engineP] #variable definitions Vstall = Variable('V_{stall}', 'knots', 'Aircraft Stall Speed') D = Variable('D', 'N', 'Total Aircraft Drag') W_avg = Variable('W_{avg}', 'N', 'Geometric Average of Segment Start and End Weight') W_start = Variable('W_{start}', 'N', 'Segment Start Weight') W_end = Variable('W_{end}', 'N', 'Segment End Weight') W_burn = Variable('W_{burn}', 'N', 'Segment Fuel Burn Weight') WLoadmax = Variable('W_{Load_{max}}', 'N/m^2', 'Max Wing Loading') WLoad = Variable('W_{Load}', 'N/m^2', 'Wing Loading') t = Variable('tmin', 'min', 'Segment Flight Time in Minutes') thours = Variable('thr', 'hour', 'Segment Flight Time in Hours') constraints = [] constraints.extend([ #speed must be greater than stall speed state['V'] >= Vstall, #Figure out how to delete Vstall == 120 * units('kts'), WLoadmax == 6664 * units('N/m^2'), #compute the drag TCS([D >= self.wingP['D_{wing}'] + self.fuseP['D_{fuse}']]), #constraint CL and compute the wing loading W_avg == .5 * self.wingP['C_{L}'] * self.aircraft['S'] * state.atm['\\rho'] * state['V']**2, WLoad == .5 * self.wingP['C_{L}'] * self.aircraft['S'] * state.atm['\\rho'] * state['V']**2 / self.aircraft.wing['S'], #set average weight equal to the geometric avg of start and end weight W_avg == (W_start * W_end)**.5, #constrain the max wing loading WLoad <= WLoadmax, #compute fuel burn from TSFC W_burn == aircraft['numeng'] * self.engineP['TSFC'] * thours * self.engineP['thrust'], #time unit conversion t == thours, #make lift equal weight --> small angle approx in climb self.wingP['L_{wing}'] == W_avg, ]) return constraints, self.wingP, self.engineP, self.fuseP
def setup(self): fs = FlightState() Propulsor.prop_flight_model = BladeElementProp p = Propulsor() pp = p.flight_model(p,fs) pp.substitutions[pp.prop.T] = 100 self.cost = pp.motor.Pelec/(1000*units('W')) + p.W/(1000*units('lbf')) return fs,p,pp
def test_constraint_creation_units(self): v = VectorVariable(2, "v", "m/s") c = (v >= 40*gpkit.units("ft/s")) c2 = (v >= [20, 30]*gpkit.units("ft/s")) if gpkit.units: self.assertTrue(c.right.units) self.assertTrue(c2.right.units) else: self.assertEqual(type(c.right), int) self.assertEqual(type(c2.right), list)
def test_constraint_creation_units(self): v = VectorVariable(2, "v", "m/s") c = (v >= 40*gpkit.units("ft/s")) c2 = (v >= np.array([20, 30])*gpkit.units("ft/s")) if gpkit.units: self.assertTrue(c.right.units) self.assertTrue(NomialArray(c2.right).units) else: self.assertEqual(type(c.right), int) self.assertEqual(type(c2.right), np.ndarray)
def test_constraint_creation_units(self): v = VectorVariable(2, "v", "m/s") c = (v >= 40 * gpkit.units("ft/s")) c2 = (v >= [20, 30] * gpkit.units("ft/s")) if gpkit.units: self.assertTrue(c.right.units) self.assertTrue(c2.right.units) else: self.assertEqual(type(c.right), int) self.assertEqual(type(c2.right), list)
def test_united_sub_sweep(self): A = Variable("A", "USD") h = Variable("h", "USD/count") Q = Variable("Q", "count") Y = Variable("Y", "USD") m = Model(Y, [Y >= h*Q + A/Q]) m.substitutions.update({A: 500*gpkit.units("USD"), h: 35*gpkit.units("USD"), Q: ("sweep", [50, 100, 500])}) firstcost = m.solve(verbosity=0)["cost"][0] self.assertAlmostEqual(1760*gpkit.ureg("USD")/firstcost, 1, 5)
def test_united_sub_sweep(self): A = Variable("A", "USD") h = Variable("h", "USD/count") Q = Variable("Q", "count") Y = Variable("Y", "USD") m = Model(Y, [Y >= h*Q + A/Q]) m.substitutions.update({A: 500*gpkit.units("USD"), h: 35*gpkit.units("USD"), Q: ("sweep", [50, 100, 500])}) firstcost = m.solve(verbosity=0)["cost"][0] self.assertAlmostEqual(firstcost, 1760, 3)
def test_Nozzle(): print "Testing Nozzle..." m = Rocket(1) m.substitutions.update({ 'k_A': 5, 'T_t': 1800 * units('K'), 'P_t': 5e8 * units('Pa'), # 'mdot': 150*units('kg/s'), }) m.cost = 1 / sum(m.nozzlePerformance.T) sol = m.localsolve(verbosity=0) print sol.table()
def setup(self, engine): self.engine = engine M2 = .6 M25 = .6 M0 = .8025 toclimb = [ engine['F'][0] == 94.971 * units('kN'), engine['F'][1] == 30.109 * units('kN'), engine['F'][2] == 22.182 * units('kN'), engine.state['P_{atm}'][1] == 23.84 * units('kPa'), #36K feet engine.state["T_{atm}"][1] == 218 * units('K'), engine.state['M'][1] == M0, engine.engineP['M_2'][1] == M2, engine.engineP['M_{2.5}'][1] == M25, engine.engineP['hold_{2}'][1] == 1 + .5 * (1.398 - 1) * M2**2, engine.engineP['hold_{2.5}'][1] == 1 + .5 * (1.354 - 1) * M25**2, engine.engineP['c1'][1] == 1 + .5 * (.401) * M0**2, ] M2 = .6 M25 = .6 M0 = .8 cruise = [ engine.state['P_{atm}'][2] == 23.92 * units('kPa'), #36K feet engine.state["T_{atm}"][2] == 219.4 * units('K'), engine.state['M'][2] == M0, engine.engineP['M_2'][2] == M2, engine.engineP['M_{2.5}'][2] == M25, engine.engineP['hold_{2}'][2] == 1 + .5 * (1.398 - 1) * M2**2, engine.engineP['hold_{2.5}'][2] == 1 + .5 * (1.354 - 1) * M25**2, engine.engineP['c1'][2] == 1 + .5 * (.401) * M0**2, ] M2 = .6 M25 = .6 M0 = .2201 rotation = [ engine.state['P_{atm}'][0] == 101.325 * units('kPa'), engine.state["T_{atm}"][0] == 288 * units('K'), engine.state['M'][0] == M0, engine.engineP['M_2'][0] == M2, engine.engineP['M_{2.5}'][0] == M25, engine.engineP['hold_{2}'][0] == 1 + .5 * (1.401 - 1) * M2**2, engine.engineP['hold_{2.5}'][0] == 1 + .5 * (1.401 - 1) * M25**2, engine.engineP['c1'][0] == 1 + .5 * (.401) * M0**2, engine['W_{engine}'] <= 1.1 * 7870.7 * units('lbf'), ] return rotation, toclimb, cruise
def run_M072_737(objective, fixedBPR, pRatOpt, mutategparg): # User definitions Nclimb = 3 Ncruise = 2 Nmission = 1 aircraft = 'M072_737' m = Mission(Nclimb, Ncruise, objective, aircraft, Nmission) substitutions = get_M072_737_subs() if Nmission > 1: substitutions.update({ 'R_{req}': [3000. * units('nmi'), 2500. * units('nmi')], 'n_{pass}': [180., 180.], }) else: substitutions.update({ 'R_{req}': 3000. * units('nmi'), 'n_{pass}': 180., }) if fixedBPR: substitutions.update({ '\\alpha_{max}': 6.97, }) if pRatOpt: del substitutions['\pi_{f_D}'] ## del substitutions['\pi_{lc_D}'] ## del substitutions['\pi_{hc_D}'] m.substitutions.update(substitutions) m = Model(m.cost, BCS(m)) m_relax = relaxed_constants(m, None, ['M_{takeoff}', '\\theta_{db}']) sol = m_relax.localsolve(verbosity=4, iteration_limit=200, reltol=0.01, mutategp=mutategparg) post_process(sol) percent_diff(sol, aircraft, Nclimb) post_compute(sol, Nclimb) return sol
def test_mul(self): "Test monomial multiplication" x = Monomial({'x': 1, 'y': -1}, 4) # test integer division self.assertEqual(x / 5, Monomial({'x': 1, 'y': -1}, 0.8)) # divide by scalar self.assertEqual(x * 9, Monomial({'x': 1, 'y': -1}, 36)) # divide by Monomial y = x * Variable('z') self.assertEqual(y, Monomial({'x': 1, 'y': -1, 'z': 1}, 4)) # make sure x unchanged self.assertEqual(x, Monomial({'x': 1, 'y': -1}, 4)) # mixed new and old vars z = x * Monomial({'x': -1, 't': 2}, .5) self.assertEqual(z, Monomial({'x': 0, 'y': -1, 't': 2}, 2)) x0 = Variable('x0') self.assertEqual(0.0, 0.0 * x0) x1 = Variable('x1') n_hat = [1, 0] p = n_hat[0] * x0 + n_hat[1] * x1 self.assertEqual(p, x0) if gpkit.units: self.assertNotEqual((x + 1), (x + 1) * gpkit.units("m"))
def test(): Nclimb = 3 # number of climb segments Ncruise = 2 # number of cruise segments Nmission = 1 # number of missions config = 'optimalD8' # String describing configuration: # currently one of: 'D8_eng_wing', 'optimal737', 'optimal777', 'optimalD8', 'D8_no_BLI', 'M072_737' m = Mission(Nclimb, Ncruise, config, Nmission) # Objective m.cost = m['W_{f_{total}}'].sum() # Inputs to the model substitutions = get_optimalD8_subs() substitutions.update({'R_{req}': 3000.*units('nmi'), #6000*units('nmi'), 'n_{pass}': 180.}) #450.,) # Additional options fixedBPR = False pRatOpt = True sol = optimize_aircraft(m, substitutions, fixedBPR, pRatOpt) percent_diff(sol, config, Nclimb) post_compute(sol, Nclimb) sol.savetxt() return sol
def setup(self, tailboom, htail, state): N = self.N = tailboom.N self.state = state self.htail = htail self.tailboom = tailboom exec parse_variables(TailBoomBending.__doc__) Beam.qbarFun = [1e-10] * N Beam.SbarFun = [1.] * N beam = self.beam = Beam(N) I = tailboom.I tailboom.I0 = I[0] l = tailboom.l S = htail.planform.S E = tailboom.material.E Sy = tailboom.Sy qne = state.qne CLmax = htail.planform.CLmax deta = tailboom.deta sigma = tailboom.material.sigma constraints = [ beam.dx == deta, F >= qne * S, beam["\\bar{EI}"] <= E * I / F / l**2 / 2, Mr >= beam["\\bar{M}"][:-1] * F * l, sigma >= Mr / Sy, th == beam["\\theta"][-1], beam["\\bar{\\delta}"][-1] * CLmax * Nsafety <= kappa ] self.tailboomJ = hasattr(tailboom, "J") if self.tailboomJ: constraints.append(tailboom.J >= 1e-10 * units("m^4")) return constraints, beam
def map_relaxations(groupedDict, nt, nx, decimals = 3): strkeys = groupedDict.keys() relaxDict = {i:None for i in strkeys} for i in strkeys: dim = len(groupedDict[i]) nd = groupedDict[i] # Mapping relaxations in time and space dim1, dim2 = [0,0] if dim == nx*nt: [dim1,dim2] = [nt,nx] elif dim == nt: [dim1,dim2] = [nt, 1] elif dim == nx: [dim1,dim2] = [1, nx] # Special cases where monomials (always tight) replace posys # in the first section elif dim == (nx-1)*nt and i == 'massCons': [dim1,dim2] = [nt, nx] a = np.array(nd)[:,0].reshape((nt, nx-1)) nd = np.concatenate((np.zeros((nt,1))*units(''), a), axis=1) nd = nd.reshape((nx*nt,1)) else: print 'Warning: tight constraint that does not' \ ' obey the specified relaxations detected.' nd = [mag(j) for j in np.array(nd)[:,0]] nd = np.array(nd).reshape((dim2, dim1)) relaxDict[i] = np.round(nd, decimals=decimals) return relaxDict
def setup(self, aircraft, state, **kwargs): #submodels self.aircraft = aircraft self.aircraftP = AircraftP(aircraft, state) self.wingP = self.aircraftP.wingP self.fuseP = self.aircraftP.fuseP #variable definitions theta = Variable('\\theta', '-', 'Aircraft Climb Angle') excessP = Variable('P_{excess}', 'W', 'Excess Power During Climb') RC = Variable('RC', 'feet/min', 'Rate of Climb/Decent') dhft = Variable('dhft', 'feet', 'Change in Altitude Per Climb Segment [feet]') RngClimb = Variable('R_{climb}', 'nautical_miles', 'Down Range Covered in Each Climb Segment') #constraints constraints = [] constraints.extend([ RC == excessP / self.aircraftP['W_{avg}'], RC >= 500 * units('ft/min'), #make the small angle approximation and compute theta theta * state['V'] == RC, dhft == self.aircraftP['tmin'] * RC, #makes a small angle assumption during climb RngClimb == self.aircraftP['thr'] * state['V'], self.aircraftP['W_{burn}'] == self.aircraft.engine['TSFC'][:2] * self.aircraft.engine['F'][:2] * self.aircraftP['thr'] ]) return constraints, self.aircraftP
def setup(self): fs = FlightState() p = Propulsor() pp = p.flight_model(p,fs) pp.substitutions[pp.prop.T] = 100 self.cost = 1./pp.motor.etam + p.W/(1000*units('lbf')) + 1./pp.prop.eta return fs,p,pp
def test(): Nmissions = 2 Nsegments = 4 aircraft = SimPleAC() m = Multimission(aircraft,Nmissions,Nsegments) m.substitutions.update({ 'h_{cruise_{mm}}':[5000*units('m'), 5000*units('m')], 'Range_{mm}' :[3000*units('km'), 2000*units('km')], 'W_{p_{mm}}' :[6250*units('N'), 8000*units('N')], 'C_{mm}' :[120*units('1/hr'), 360*units('1/hr')], }) #m.cost = m['W_{f_{mm}}']*units('1/N') + sum(m.missions[i]['C_m']*m.missions[i]['t_m'] for i in range(0,Nmissions)) m.cost = (m.missions[0]['W_{f_m}']*units('1/N') + m.missions[1]['C_m']*m.missions[1]['t_m']) sol = m.localsolve(verbosity = 2)
def setup(self, engine): self.engine = engine M2 = .6 M25 = .6 M0 = .5 engineclimb = [ engine['F'][1] == 13.798 * units('kN'), engine['F'][0] == 11.949 * units('kN'), engine.state['P_{atm}'][1] == 23.84 * units('kPa'), #36K feet engine.state["T_{atm}"][1] == 218 * units('K'), engine.state['M'][1] == M0, engine.engineP['M_{2.5}'][1] == M25, engine.engineP['hold_{2}'][1] == 1 + .5 * (1.398 - 1) * M2**2, engine.engineP['hold_{2.5}'][1] == 1 + .5 * (1.354 - 1) * M25**2, engine.engineP['c1'][1] == 1 + .5 * (.401) * M0**2, ] M2 = .6 M25 = .6 M0 = .72 enginecruise = [ engine.state['P_{atm}'][0] == 23.84 * units('kPa'), #36K feet engine.state["T_{atm}"][0] == 218 * units('K'), engine.state['M'][0] == M0, engine.engineP['M_2'][0] == M2, engine.engineP['M_{2.5}'][0] == M25, engine.engineP['hold_{2}'][0] == 1 + .5 * (1.398 - 1) * M2**2, engine.engineP['hold_{2.5}'][0] == 1 + .5 * (1.354 - 1) * M25**2, engine.engineP['c1'][0] == 1 + .5 * (.401) * M0**2, engine['W_{engine}'] <= 10502.8 * units('lbf'), ] return engineclimb, enginecruise
def setup(self): # Free Variables CDA0 = Variable("(CDA0)", "m^2", "fuselage drag area") #0.035 originally C_D_fuse = Variable('C_{D_{fuse}}', '-', 'fuselage drag coefficient') # Free variables (fixed for performance eval.) V_f_fuse = Variable('V_{f_{fuse}}', 'm^3', 'fuel volume in the fuselage', fix=True) constraints = [] constraints += [ V_f_fuse == 10 * units('m') * CDA0, V_f_fuse >= 1 * 10**-5 * units('m^3') ] return constraints
def setup(self): fs = FlightState() m = Motor() mp = MotorPerf(m,fs) self.mp = mp mp.substitutions[m.Qmax] = 100 mp.substitutions[mp.Q] = 10 self.cost = 1./mp.etam + m.W/(100.*units('lbf')) return self.mp, fs, m
def setup(self): exec parse_variables(Section.__doc__) constraints = [ # Taking averages, A_in * A_out == A_avg**2, # Volume of chamber V_chamb == A_avg * l, # Area ratio A_in / A_out == k_A, # Mass flow rate rho_in * u_in * A_in == mdot_in, rho_out * u_out * A_out == mdot_out, # Chamber pressure P_chamb**2 == P_in * P_out, # Product generation rate q == rho_p * A_b * r, A_b == l_b * l, A_p_out + r * l_b * dt <= A_p_in, # Stagnation quantities P_t_in >= P_in + 0.5 * rho_in * u_in**2, T_t_in >= T_in + u_in**2 / (2 * c_p), # Ideal gas law P_out == rho_out * R * T_out, # Pressure increase P_out + dP <= P_in, # Making sure burn surface length is feasible l_b >= 2 * np.pi**0.5 * (A_avg)**0.5, l_b <= l_b_max * 2 * np.pi**0.5 * (A_avg)**0.5, # Constraining areas Tight([A_avg + A_p_in <= np.pi * radius**2]), ] with SignomialsEnabled(): constraints += [ # Flow acceleration (conservation of momentum) # Note: assumes constant rate of burn through the chamber dP + rho_in * u_in**2 >= q * u_out / V_chamb * (2. / 3. * l) + rho_in * u_in * u_out, # Burn rate (Saint-Robert's Law, coefficients taken for Space Shuttle SRM) Tight([ r >= r_c * (P_chamb / 1e6 * units('1/Pa'))**0.35 * (1 + 0.5 * r_k * (u_in + u_out)) ]), # Mass flows Tight([mdot_in + q >= mdot_out]), mdot_out >= mdot_in, # Temperatures Tight([ T_t_out * mdot_out <= mdot_in * T_t_in + q * T_amb + q * k_comb_p / c_p ]), # Stagnation quantities Tight([P_t_out <= P_out + 0.5 * rho_out * u_out**2]), Tight([T_t_out <= T_out + u_out**2 / (2 * c_p)]), ] return constraints
def setup(self, engine): self.engine = engine M2 = .6 M25 = .6 M0 = .8 climb = [ engine['F'][0] == 5496.4 * 4.4 * units('N'), engine['F'][1] == 5961.9 * 4.4 * units('N'), engine.state["T_{atm}"] == 218 * units('K'), engine.state['P_{atm}'][0] == 23.84 * units('kPa'), #36K feet engine.state['M'][0] == M0, engine.engineP['M_2'][0] == M2, engine.engineP['M_{2.5}'][0] == M25, engine.engineP['hold_{2}'] == 1 + .5 * (1.398 - 1) * M2**2, engine.engineP['hold_{2.5}'] == 1 + .5 * (1.354 - 1) * M25**2, engine.engineP['c1'] == 1 + .5 * (.401) * M0**2, ] M2 = .6 M25 = .6 M0 = .8 cruise = [ engine.state['P_{atm}'][1] == 23.84 * units('kPa'), #36K feet engine.state['M'][1] == M0, engine.engineP['M_2'][1] == M2, engine.engineP['M_{2.5}'][1] == M25, engine['W_{engine}'] <= 5216 * units('lbf'), ] return climb, cruise
def test_quantity_sub(self): if gpkit.units: x = Variable("x", 1, "cm") y = Variable("y", 1) self.assertEqual(x.sub({x: 1*gpkit.units.m}).c.magnitude, 100) # NOTE: uncomment the below if requiring Quantity substitutions # self.assertRaises(ValueError, x.sub, x, 1) self.assertRaises(ValueError, x.sub, {x: 1*gpkit.ureg.N}) self.assertRaises(ValueError, y.sub, {y: 1*gpkit.ureg.N}) v = gpkit.VectorVariable(3, "v", "cm") subbed = v.sub({v: [1, 2, 3]*gpkit.ureg.m}) self.assertEqual([z.c.magnitude for z in subbed], [100, 200, 300]) v = VectorVariable(1, "v", "km") v_min = VectorVariable(1, "v_min", "km") m = Model(v.prod(), [v >= v_min], {v_min: [2*gpkit.units("nmi")]}) cost = m.solve(verbosity=0)["cost"] self.assertAlmostEqual(cost/(3.704*gpkit.ureg("km")), 1.0) m = Model(v.prod(), [v >= v_min], {v_min: np.array([2])*gpkit.units("nmi")}) cost = m.solve(verbosity=0)["cost"] self.assertAlmostEqual(cost/(3.704*gpkit.ureg("km")), 1.0)
def test_quantity_sub(self): if gpkit.units: x = Variable("x", 1, "cm") y = Variable("y", 1) self.assertEqual(x.sub({x: 1 * gpkit.units.m}).c.magnitude, 100) # NOTE: uncomment the below if requiring Quantity substitutions # self.assertRaises(ValueError, x.sub, x, 1) self.assertRaises(ValueError, x.sub, {x: 1 * gpkit.ureg.N}) self.assertRaises(ValueError, y.sub, {y: 1 * gpkit.ureg.N}) v = gpkit.VectorVariable(3, "v", "cm") subbed = v.sub({v: [1, 2, 3] * gpkit.ureg.m}) self.assertEqual([z.c.magnitude for z in subbed], [100, 200, 300]) v = VectorVariable(1, "v", "km") v_min = VectorVariable(1, "v_min", "km") m = Model(v.prod(), [v >= v_min], {v_min: [2 * gpkit.units("nmi")]}) cost = m.solve(verbosity=0)["cost"] self.assertAlmostEqual(cost / (3.704 * gpkit.ureg("km")), 1.0) m = Model(v.prod(), [v >= v_min], {v_min: np.array([2]) * gpkit.units("nmi")}) cost = m.solve(verbosity=0)["cost"] self.assertAlmostEqual(cost / (3.704 * gpkit.ureg("km")), 1.0)
def test(): m = Mission(SimPleAC(),4) m.substitutions.update({ 'h_{cruise_m}' :5000*units('m'), 'Range_m' :3000*units('km'), 'W_{p_m}' :3000*units('N'), '\\rho_{p_m}' :1500*units('kg/m^3'), 'C_m' :120*units('1/hr'), 'V_{min_m}' :35*units('m/s'), 'T/O factor_m' :2, }) m.cost = m['W_{f_m}']*units('1/N') + m['C_m']*m['t_m'] sol = m.localsolve(verbosity = 2)
def test_vector(self): v = VectorVariable(3, "v") kd = KeyDict() kd[v] = np.array([2, 3, 4]) self.assertTrue(all(kd[v] == kd[v.key])) self.assertTrue(all(kd["v"] == np.array([2, 3, 4]))) self.assertEqual(v[0].key.idx, (0,)) self.assertEqual(kd[v][0], kd[v[0]]) self.assertEqual(kd[v][0], 2) kd[v[0]] = 6 self.assertEqual(kd[v][0], kd[v[0]]) self.assertEqual(kd[v][0], 6) self.assertTrue(all(kd[v] == np.array([6, 3, 4]))) v = VectorVariable(3, "v", "m") kd[v] = np.array([2, 3, 4]) if gpkit.units: kd[v[0]] = gpkit.units("inch")
def test_vector(self): v = VectorVariable(3, "v") kd = KeyDict() kd[v] = np.array([2, 3, 4]) self.assertTrue(all(kd[v] == kd[v.key])) self.assertTrue(all(kd["v"] == np.array([2, 3, 4]))) self.assertEqual(v[0].key.idx, (0, )) self.assertEqual(kd[v][0], kd[v[0]]) self.assertEqual(kd[v][0], 2) kd[v[0]] = 6 self.assertEqual(kd[v][0], kd[v[0]]) self.assertEqual(kd[v][0], 6) self.assertTrue(all(kd[v] == np.array([6, 3, 4]))) v = VectorVariable(3, "v", "m") kd[v] = np.array([2, 3, 4]) if gpkit.units: kd[v[0]] = gpkit.units("inch")
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, state, **kwargs): #submodels self.aircraft = aircraft self.aircraftP = AircraftP(aircraft, state) self.wingP = self.aircraftP.wingP self.fuseP = self.aircraftP.fuseP self.engineP = self.aircraftP.engineP #variable definitions theta = Variable('\\theta', '-', 'Aircraft Climb Angle') excessP = Variable('P_{excess}', 'W', 'Excess Power During Climb') RC = Variable('RC', 'feet/min', 'Rate of Climb/Decent') dhft = Variable('dhft', 'feet', 'Change in Altitude Per Climb Segment [feet]') RngClimb = Variable('R_{climb}', 'nautical_miles', 'Down Range Distance Covered in Each Climb Segment') TotRngClimb = Variable('TotRngClimb', 'nautical_miles', 'Down Range Distance Covered in Climb') #constraints constraints = [] constraints.extend([ #constraint on drag and thrust self.aircraft['numeng']*self.engineP['thrust'] >= self.aircraftP['D'] + self.aircraftP['W_{avg}'] * theta, #climb rate constraints TCS([excessP + state['V'] * self.aircraftP['D'] <= state['V'] * aircraft['numeng'] * self.engineP['thrust']]), RC == excessP/self.aircraftP['W_{avg}'], RC >= 500*units('ft/min'), #make the small angle approximation and compute theta theta * state['V'] == RC, dhft == self.aircraftP['tmin'] * RC, #makes a small angle assumption during climb ## RngClimb == self.aircraftP['thr']*state['V'], ]) with SignomialsEnabled(): constraints.extend([ #time TCS([self.aircraftP['thr'] * state['V'] >= RngClimb + (.5*theta**2)*self.aircraftP['thr'] * state['V']]), ]) return constraints, self.aircraftP
def SimPleAC_setup(): a = SimPleAC() m = Mission(a, 4) subs = { 'h_{cruise_m}': 5000 * units('m'), 'Range_m': 3000 * units('km'), 'W_{p_m}': 3000 * units('N'), '\\rho_{p_m}': 1500 * units('kg/m^3'), 'C_m': 120 * units('1/hr'), 'V_{min_m}': 35 * units('m/s'), 'T/O factor_m': 2, } m.substitutions.update(subs) m.cost = m['W_{f_m}'] #+m['C_m']*m['t_m']*units('N') return m, subs
def setup(self): # Free Variables S = Variable('S_{fuse}', 'm^2', 'fuselage surface area') l = Variable('l_{fuse}', 'm', 'fuselage length') r = Variable('r_{fuse}', 'm', 'fuselage minor radius') f = Variable('f_{fuse}', '-', 'fuselage fineness ratio', fix = True) k = Variable('k_{fuse}', '-', 'fuselage form factor') # Free variables (fixed for performance eval.) V = Variable('V_{fuse}', 'm^3', 'total volume in the fuselage', fix = True) V_f_fuse = Variable('V_{f_{fuse}}','m^3','fuel volume in the fuselage') W_fuse = Variable('W_{fuse}', 'N', 'fuselage weight') p = 1.6075 constraints = [f == l/r/2, f <= 6, k >= 1 + 60/f**3 + f/400, 3*(S/np.pi)**p >= 2*(l*2*r)**p + (2*r)**(2*p), V == 4./6.*np.pi*r**2*l, V_f_fuse >= 1*10**-10*units('m^3'), ] return constraints
def setup(self,aircraft,Nmissions,Nsegments): self.aircraft = aircraft self.missions = [] for i in range(0,Nmissions): self.missions.append(Mission(self.aircraft,Nsegments)) # Multimission objective variables W_f_mm = Variable('W_{f_{mm}}','N','multimission fuel weight') with Vectorize(Nmissions): # Mission variables hcruise = Variable('h_{cruise_{mm}}', 'm', 'minimum cruise altitude') Range = Variable("Range_{mm}", "km", "aircraft range") W_p = Variable("W_{p_{mm}}", "N", "payload weight", pr=20.) V_min = Variable("V_{min_{mm}}", 25, "m/s", "takeoff speed", pr=20.) cost_index = Variable("C_{mm}", '1/hr','hourly cost index') TOfac = Variable('T/O factor_{mm}', 2.,'-','takeoff thrust factor') constraints = [] # Setting up the missions for i in range(0,Nmissions): constraints += [ self.missions[i]['h_{cruise_m}'] == hcruise[i], self.missions[i]['Range_m'] == Range[i], self.missions[i]['W_{p_m}'] == W_p[i], self.missions[i]['V_{min_m}'] == V_min[i], self.missions[i]['C_m'] == cost_index[i], self.missions[i]['T/O factor_m'] == TOfac[i], # Upper bounding relevant variables W_f_mm <= 1e11*units('N'), ] # Multimission constraints constraints += [W_f_mm >= sum(self.missions[i]['W_{f_m}'] for i in range(0,Nmissions))] return constraints, self.aircraft, self.missions
def setup(self, DF70=False): self.DF70 = DF70 W = Variable("W", "lbf", "Installed/Total engine weight") mfac = Variable("m_{fac}", 1.0, "-", "Engine weight margin factor") bsfc_min = Variable("BSFC_{min}", 0.3162, "kg/kW/hr", "minimum BSFC") Pref = Variable("P_{ref}", 10.0, "hp", "Reference shaft power") Wengref = Variable("W_{eng-ref}", 10.0, "lbf", "Reference engine weight") Weng = Variable("W_{eng}", "lbf", "engine weight") Pslmax = Variable("P_{sl-max}", "hp", "Max shaft power at sea level") path = os.path.dirname(__file__) df = pd.read_csv(path + os.sep + "power_lawfit.csv").to_dict( orient="records")[0] constraints = [ FitCS(df, Weng/Wengref, [Pslmax/Pref]), W/mfac >= 2.572*Weng**0.922*units("lbf")**0.078] return constraints
def test_mul(self): "Test monomial multiplication" x = Monomial({"x": 1, "y": -1}, 4) # test integer division self.assertEqual(x / 5, Monomial({"x": 1, "y": -1}, 0.8)) # divide by scalar self.assertEqual(x * 9, Monomial({"x": 1, "y": -1}, 36)) # divide by Monomial y = x * Variable("z") self.assertEqual(y, Monomial({"x": 1, "y": -1, "z": 1}, 4)) # make sure x unchanged self.assertEqual(x, Monomial({"x": 1, "y": -1}, 4)) # mixed new and old vars z = x * Monomial({"x": -1, "t": 2}, .5) self.assertEqual(z, Monomial({"x": 0, "y": -1, "t": 2}, 2)) x0 = Variable("x0") self.assertEqual(0.0, 0.0 * x0) x1 = Variable("x1") n_hat = [1, 0] p = n_hat[0] * x0 + n_hat[1] * x1 self.assertEqual(p, x0) self.assertNotEqual((x + 1), (x + 1) * gpkit.units("m"))
def setup(self): constraints = [] # Steady level flight relations CD = Variable('C_D', '-', 'Drag coefficient') CL = Variable('C_L', '-', 'Lift coefficient') P_shaft = Variable('P_{shaft}', 'W', 'Shaft power') S = Variable('S', 'm^2', 'Wing reference area') V = Variable('V', 'm/s', 'Cruise velocity') W = Variable('W', 'lbf', 'Aircraft weight') eta_prop = Variable(r'\eta_{prop}', 0.7, '-', 'Propulsive efficiency') rho = Variable(r'\rho', 'kg/m^3') constraints.extend([P_shaft == V*W*CD/CL/eta_prop, # eta*P = D*V W == 0.5*rho*V**2*CL*S]) # Aerodynamics model Cd0 = Variable('C_{d0}', 0.01, '-', "non-wing drag coefficient") CLmax = Variable('C_{L-max}', 1.5, '-', 'maximum lift coefficient') e = Variable('e', 0.9, '-', "spanwise efficiency") A = Variable('A', 20, '-', "aspect ratio") b = Variable('b', 'ft', 'span') mu = Variable(r'\mu', 1.5e-5, 'N*s/m^2', "dynamic viscosity") Re = Variable("Re", '-', "Reynolds number") Cf = Variable("C_f", "-", "wing skin friction coefficient") Kwing = Variable("K_{wing}", 1.3, "-", "wing form factor") cl_16 = Variable("cl_{16}", 0.0001, "-", "profile stall coefficient") constraints.extend([CD >= Cd0 + 2*Cf*Kwing + CL**2/(pi*e*A) + cl_16*CL**16, b**2 == S*A, CL <= CLmax, Re == rho*V/mu*(S/A)**0.5, Cf >= 0.074/Re**0.2]) # Engine Weight Model W_eng = Variable('W_{eng}', 'lbf', 'Engine weight') W_engmin = Variable('W_{min}', 1.3, 'lbf', 'min engine weight') W_engmax = Variable('W_{max}', 275, 'lbf', 'max engine weight') eta_t = Variable('\\eta_t', 0.75, '-', 'percent throttle') eng_cnst = Variable('eng_{cnst}', 0.0011, '-', 'engine constant based off of power weight model') constraints.extend([W_eng >= W_engmin, W_eng <= W_engmax, W_eng >= P_shaft*eng_cnst/eta_t * units('lbf/watt')]) # Weight model W_airframe = Variable('W_{airframe}', 'lbf', 'Airframe weight') W_pay = Variable(r'W_{pay}', 4, 'lbf', 'Payload weight') W_fuel = Variable('W_{fuel}', 'lbf', 'Fuel Weight') W_zfw = Variable('W_{zfw}', 'lbf', 'Zero fuel weight') wl = Variable('wl', 'lbf/ft^2', 'wing loading') f_airframe = Variable('f_{airframe}', 0.3, '-', 'Airframe weight fraction') g = Variable('g', 9.81, 'm/s^2', 'Gravitational acceleration') constraints.extend([W_airframe >= W*f_airframe, W_zfw >= W_airframe + W_eng + W_pay, wl == W/S, W >= W_pay + W_eng + W_airframe + W_fuel]) # Breguet Range z_bre = Variable("z_bre", "-", "breguet coefficient") h_fuel = Variable("h_{fuel}", 42e6, "J/kg", "heat of combustion") eta_0 = Variable("\\eta_0", 0.2, "-", "overall efficiency") t = Variable('t', 7, 'days', 'time on station') constraints.extend([z_bre >= g*t*V*CD/(h_fuel*eta_0*CL), W_fuel/W_zfw >= te_exp_minus1(z_bre, 3)]) # Atmosphere model h = Variable("h", "ft", "Altitude") 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}", 0.0065, "K/m", "Temperature lapse rate") T_atm = Variable("T_{atm}", "K", "air temperature") M_atm = Variable("M_{atm}", 0.0289644, "kg/mol", "Molar mass of dry air") R_atm = Variable("R_{atm}", 8.31447, "J/mol/K") TH = (g*M_atm/R_atm/L_atm).value.magnitude # dimensionless constraints.extend([h <= 20000*units.m, # Model valid to top of troposphere T_sl >= T_atm + L_atm*h, # Temp decreases w/ altitude rho <= p_sl*T_atm**(TH-1)*M_atm/R_atm/(T_sl**TH)]) # http://en.wikipedia.org/wiki/Density_of_air#Altitude # station keeping requirement footprint = Variable("d_{footprint}", 100, 'km', "station keeping footprint diameter") lu = Variable(r"\theta_{look-up}", 5, '-', "look up angle") R_earth = Variable("R_{earth}", 6371, "km", "Radius of earth") tan_lu = lu*pi/180. + (lu*pi/180.)**3/3. # Taylor series expansion # approximate earth curvature penalty as distance^2/(2*Re) constraints.extend([ h >= tan_lu*0.5*footprint + footprint**2/8./R_earth]) # wind speed model V_wind = Variable('V_{wind}', 'm/s', 'wind speed') wd_cnst = Variable('wd_{cnst}', [0.002, 0.0015], 'm/s/ft', 'wind speed constant predited by model') wd_ln = Variable('wd_{ln}', [13.009, 8.845], 'm/s', 'linear wind speed variable') h_min = Variable('h_{min}', 11800, 'ft', 'minimum height') h_max = Variable('h_{max}', 20800, 'ft', 'maximum height') constraints.extend([V_wind >= wd_cnst*h + wd_ln, # model predicting worse case scenario at 45 deg latitude V >= V_wind, h >= h_min, h <= h_max]) objective = W return objective, constraints
"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" Model(x, [x <= units("inch"), x >= units("yard")]).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") Model(x/y, [x >= x_min]).debug()
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 test_pint_366(self): # test for https://github.com/hgrecco/pint/issues/366 if gpkit.units: self.assertIn(unitstr(gpkit.units("nautical_mile")), ("nmi", "nautical_mile")) self.assertEqual(gpkit.units("nautical_mile"), gpkit.units("nmi"))