def test_model_composition_units(self): class Above(Model): """A simple upper bound on x Lower Unbounded --------------- x """ def setup(self): x = self.x = Variable("x", "ft") x_max = Variable("x_{max}", 1, "yard") self.cost = 1 / x return [x <= x_max] class Below(Model): """A simple lower bound on x Upper Unbounded --------------- x """ def setup(self): x = self.x = Variable("x", "m") x_min = Variable("x_{min}", 1, "cm") self.cost = x return [x >= x_min] a, b = Above(), Below() concatm = Model(a.cost * b.cost, [a, b]) concat_cost = concatm.solve(verbosity=0)["cost"] almostequal = self.assertAlmostEqual yard, cm = gpkit.ureg("yard"), gpkit.ureg("cm") if not isinstance(a["x"].key.units, str): almostequal(1 / yard / a.solve(verbosity=0)["cost"], 1, 5) almostequal(1 * cm / b.solve(verbosity=0)["cost"], 1, 5) almostequal(1 * cm / yard / concat_cost, 1, 5) reset_modelnumbers() a1, b1 = Above(), Below() self.assertEqual(a1["x"].key.modelnums, [0]) b1.subinplace({b1["x"]: a1["x"]}) m = Model(a1["x"], [a1, b1]) sol = m.solve(verbosity=0) if not isinstance(m["x"].key.units, str): almostequal(1 * cm / sol["cost"], 1, 5) a1, b1 = Above(), Below() self.assertEqual(a1["x"].key.modelnums, [1]) a1.subinplace({a1["x"]: b1["x"]}) m = Model(b1["x"], [a1, b1]) m.cost = m["x"] sol = m.solve(verbosity=0) if not isinstance(m["x"].key.units, str): almostequal(1 * gpkit.ureg.cm / sol["cost"], 1, 5) self.assertIn(m["x"], sol["variables"]) self.assertIn(a1["x"], sol["variables"]) self.assertIn(b1["x"], sol["variables"]) self.assertNotIn(a["x"], sol["variables"]) self.assertNotIn(b["x"], sol["variables"])
def test_model_composition_units(self): class Above(Model): """A simple upper bound on x Lower Unbounded --------------- x """ def setup(self): x = self.x = Variable("x", "ft") x_max = Variable("x_{max}", 1, "yard") self.cost = 1 / x return [x <= x_max] class Below(Model): """A simple lower bound on x Upper Unbounded --------------- x """ def setup(self): x = self.x = Variable("x", "m") x_min = Variable("x_{min}", 1, "cm") self.cost = x return [x >= x_min] a, b = Above(), Below() concatm = Model(a.cost * b.cost, [a, b]) concat_cost = concatm.solve(verbosity=0)["cost"] almostequal = self.assertAlmostEqual yard, cm = gpkit.ureg("yard"), gpkit.ureg("cm") ft, meter = gpkit.ureg("ft"), gpkit.ureg("m") if not isinstance(a["x"].key.units, str): almostequal(a.solve(verbosity=0)["cost"], ft / yard, 5) almostequal(b.solve(verbosity=0)["cost"], cm / meter, 5) almostequal(cm / yard, concat_cost, 5) NamedVariables.reset_modelnumbers() a1, b1 = Above(), Below() self.assertEqual(a1["x"].key.lineage, (("Above", 0), )) m = Model(a1["x"], [a1, b1, b1["x"] == a1["x"]]) sol = m.solve(verbosity=0) if not isinstance(a1["x"].key.units, str): almostequal(sol["cost"], cm / ft, 5) a1, b1 = Above(), Below() self.assertEqual(a1["x"].key.lineage, (("Above", 1), )) m = Model(b1["x"], [a1, b1, b1["x"] == a1["x"]]) sol = m.solve(verbosity=0) if not isinstance(b1["x"].key.units, str): almostequal(sol["cost"], cm / meter, 5) self.assertIn(a1["x"], sol["variables"]) self.assertIn(b1["x"], sol["variables"]) self.assertNotIn(a["x"], sol["variables"]) self.assertNotIn(b["x"], sol["variables"])
def test_model_composition_units(self): class Above(Model): """A simple upper bound on x Lower Unbounded --------------- x """ def setup(self): x = self.x = Variable("x", "ft") x_max = Variable("x_{max}", 1, "yard") self.cost = 1/x return [x <= x_max] class Below(Model): """A simple lower bound on x Upper Unbounded --------------- x """ def setup(self): x = self.x = Variable("x", "m") x_min = Variable("x_{min}", 1, "cm") self.cost = x return [x >= x_min] a, b = Above(), Below() concatm = Model(a.cost*b.cost, [a, b]) concat_cost = concatm.solve(verbosity=0)["cost"] almostequal = self.assertAlmostEqual yard, cm = gpkit.ureg("yard"), gpkit.ureg("cm") if not isinstance(a["x"].key.units, str): almostequal(1/yard/a.solve(verbosity=0)["cost"], 1, 5) almostequal(1*cm/b.solve(verbosity=0)["cost"], 1, 5) almostequal(1*cm/yard/concat_cost, 1, 5) reset_modelnumbers() a1, b1 = Above(), Below() self.assertEqual(a1["x"].key.modelnums, [0]) m = Model(a1["x"], [a1, b1, b1["x"] == a1["x"]]) sol = m.solve(verbosity=0) if not isinstance(a1["x"].key.units, str): almostequal(1*cm/sol["cost"], 1, 5) a1, b1 = Above(), Below() self.assertEqual(a1["x"].key.modelnums, [1]) m = Model(b1["x"], [a1, b1, b1["x"] == a1["x"]]) sol = m.solve(verbosity=0) if not isinstance(b1["x"].key.units, str): almostequal(1*gpkit.ureg.cm/sol["cost"], 1, 5) self.assertIn(a1["x"], sol["variables"]) self.assertIn(b1["x"], sol["variables"]) self.assertNotIn(a["x"], sol["variables"]) self.assertNotIn(b["x"], sol["variables"])
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(1760*gpkit.ureg("USD")/firstcost, 1, 5)
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 rotors_analysis_function(T=2000 * ureg("lbf"), VT="unconstrained", h=0 * ureg.ft, N=12, R=1.804 * ureg("ft"), s=0.1, Cl_mean_max=1.4, print_summary="No"): #Function uses GPKit models as the backend to analyze a rotor. testRotor = Rotors() testRotor.substitutions.update({ "R": R, "N": N, "s": s, "Cl_{mean_{max}}": Cl_mean_max }) testState = FlightState(h=h) testRotor_AeroAnalysis = testRotor.performance(testState) testRotor_AeroAnalysis.substitutions.update( {"T": T.to(ureg.lbf).magnitude}) if VT != "unconstrained": testRotor_AeroAnalysis.substitutions.update({"VT": VT}) testModel = Model(testRotor_AeroAnalysis["P"], [testRotor, testRotor_AeroAnalysis]) testSolution = testModel.solve(verbosity=0) if print_summary == "Yes": print testSolution.summary() VT = testSolution["variables"]["VT_RotorsAero"] P = testSolution["variables"]["P_RotorsAero"] FOM = testSolution["variables"]["FOM_RotorsAero"] Cl_mean = testSolution["variables"]["Cl_mean_RotorsAero"] SPL = 20 * np.log10(testSolution["variables"]["p_{ratio}_RotorsAero"]) return [VT, P, FOM, Cl_mean, SPL]
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)
import numpy as np from gpkit import Model, ureg from matplotlib import pyplot as plt from aircraft_models import OnDemandAircraft from aircraft_models import OnDemandSizingMission, OnDemandRevenueMission from aircraft_models import OnDemandDeadheadMission, OnDemandMissionCost from study_input_data import generic_data, configuration_data from noise_models import vortex_noise from scipy.interpolate import interp2d #Data from Boeing study boeing_data = {} boeing_data["Lift + cruise"] = {} boeing_data["Lift + cruise"]["L/D"] = 9.1 boeing_data["Lift + cruise"]["T/A"] = 7.3 * ureg("lbf") / ureg("ft")**2 boeing_data["Tilt rotor"] = {} boeing_data["Tilt rotor"]["L/D"] = 11.0 boeing_data["Tilt rotor"]["T/A"] = 12.8 * ureg("lbf") / ureg("ft")**2 ''' boeing_data["Helicopter"] = {} boeing_data["Helicopter"]["L/D"] = 7.26 boeing_data["Helicopter"]["T/A"] = 4.1*ureg("lbf")/ureg("ft")**2 ''' #Instantiate arrays numrows = 6 L_D_array = np.linspace(7, 15, numrows) T_A_array = np.linspace(4, 16, numrows) L_D_array, T_A_array = np.meshgrid(L_D_array, T_A_array)
elif output == "Hover SPL (A-weighted)": precision = "%0.1f" output_string += precision % configs[config]["SPL_A"] output_string += "\t\t" continue elif output == "Vortex peak frequency": precision = "%0.0f" output_string += precision % configs[config]["f_{peak}"].to( ureg(units)).magnitude output_string += "\t\t" continue output_string += precision % solution(var_string).to( ureg(units)).magnitude output_string += "\t\t" output_string += units + "\n" print "\n\n" print output_string text_file = open("config_trade_study_tabulatedData.txt", "w") text_file.write(output_string)
generic_data["sizing_mission"]["t_{hover}"] = 120 * ureg.s generic_data["revenue_mission"] = {} generic_data["revenue_mission"]["type"] = "piloted" generic_data["revenue_mission"]["N_passengers"] = 2 generic_data["revenue_mission"]["range"] = 30 * ureg.nautical_mile generic_data["revenue_mission"]["t_{hover}"] = 30 * ureg.s generic_data["deadhead_mission"] = {} generic_data["deadhead_mission"]["type"] = "autonomous" generic_data["deadhead_mission"]["N_passengers"] = 0.00001 generic_data["deadhead_mission"]["range"] = 30 * ureg.nautical_mile generic_data["deadhead_mission"]["t_{hover}"] = 30 * ureg.s configs_OutOfOrder["Multirotor"] = {} configs_OutOfOrder["Multirotor"]["V_{cruise}"] = 50 * ureg("mph") configs_OutOfOrder["Multirotor"]["L/D"] = 1.5 configs_OutOfOrder["Multirotor"]["T/A"] = 3.75 * ureg("lbf") / ureg("ft")**2 configs_OutOfOrder["Multirotor"]["Cl_{mean_{max}}"] = 0.6 configs_OutOfOrder["Multirotor"]["N"] = 8 configs_OutOfOrder["Multirotor"]["loiter_type"] = "level_flight" configs_OutOfOrder["Multirotor"]["tailRotor_power_fraction_hover"] = 0.0001 configs_OutOfOrder["Multirotor"][ "tailRotor_power_fraction_levelFlight"] = 0.0001 configs_OutOfOrder["Multirotor"]["weight_fraction"] = 0.43 configs_OutOfOrder["Autogyro"] = {} configs_OutOfOrder["Autogyro"]["V_{cruise}"] = 100 * ureg("mph") configs_OutOfOrder["Autogyro"]["L/D"] = 3.5 configs_OutOfOrder["Autogyro"]["T/A"] = 3.75 * ureg("lbf") / ureg("ft")**2 configs_OutOfOrder["Autogyro"]["Cl_{mean_{max}}"] = 0.8
from aircraft_models import OnDemandDeadheadMission, OnDemandMissionCost from study_input_data import generic_data, configuration_data from noise_models import vortex_noise #import matplotlib as mpl #mpl.style.use("classic") #Data from the Boeing study boeing_data = {} boeing_data["C_m"] = (400 / 0.8) * ureg.Wh / ureg.kg boeing_data["sizing_mission"] = {} boeing_data["sizing_mission"]["range"] = 87 * ureg.nautical_mile boeing_data["Lift + cruise"] = {} boeing_data["Lift + cruise"]["V_{cruise}"] = 150 * ureg("mph") boeing_data["Lift + cruise"]["L/D"] = 9.1 boeing_data["Lift + cruise"]["T/A"] = 7.3 * ureg("lbf") / ureg("ft")**2 boeing_data["Lift + cruise"]["TOGW"] = 3710 * ureg.lbf boeing_data["Lift + cruise"]["W_{battery}"] = 948 * ureg.lbf boeing_data["Lift + cruise"]["P_{cruise}"] = 199 * ureg.hp boeing_data["Lift + cruise"]["P_{hover}"] = 389 * ureg.hp boeing_data["Tilt rotor"] = {} boeing_data["Tilt rotor"]["V_{cruise}"] = 150 * ureg("mph") boeing_data["Tilt rotor"]["L/D"] = 11.0 boeing_data["Tilt rotor"]["T/A"] = 12.8 * ureg("lbf") / ureg("ft")**2 boeing_data["Tilt rotor"]["TOGW"] = 3930 * ureg.lbf boeing_data["Tilt rotor"]["W_{battery}"] = 965 * ureg.lbf boeing_data["Tilt rotor"]["P_{cruise}"] = 187 * ureg.hp boeing_data["Tilt rotor"]["P_{hover}"] = 542 * ureg.hp
# Performance variables t_hover = Variable('t_hover', 's') T_total = Variable('T_total', 'N') P_total = Variable('P_total', 'W') m_total = Variable('m_total', 'kg') # Environment rho = Variable('rho', 1.225, 'kg/m^3') g = Variable('g', 9.8, 'm/s/s') # Constraints constraints = [ battery_shopping, esc_power <= esc_specificPower * esc_mass, motor_shopping, esc_power >= motor_power, T_total <= 3.141 / 2 * rho * ureg('m^3/kg') * (propeller_efficiency * n_rotors * motor_power**(0.6) * propeller_d** (0.6) * ureg('(N/(W^0.6 * m^0.6))')), m_total >= n_rotors * (esc_mass + motor_mass) + battery_mass + payload_mass + structures_mass, P_total >= n_rotors * esc_power, T_total >= m_total * g, t_hover <= battery_energy / P_total, t_hover >= Variable('t_hoverLimit', 120, 's') ] # Objective (to minimize) # objective = 1/t_hover objective = (1 / t_hover)**0.0001 * ((m_total * g) / T_total)**5 # Formulate the Model m = Model(objective, constraints) # m.debug()
def does_it_fail(sol, W_W_coeff1): W_W_coeff1 *= ureg("1/m") W_W_coeff2 = sol("W_W_coeff2") tau = sol("tau") N_ult = sol("N_ult") W_0 = sol("W_0") V_f_fuse = sol("V_f_fuse") g = sol("g") e = sol("e") k = sol("k") S_wetratio = sol("S_wetratio") rho_f = sol("rho_f") rho = sol("rho") mu = sol("mu") TSFC = sol("TSFC") Range = sol("Range") C_Lmax = sol("C_Lmax") V_min = sol("V_{min}") # free variable A = sol("A") S = sol("S") V_f_fuse = sol("V_f_fuse") C_L = sol("C_L") # iterate V_cruisemax = sol("V") W = W_orig = sol("W") V_cruisemax_prev = W_prev = 0 # kinda changed W_f = sol("W_f") while abs((W - W_prev).magnitude) >= 0.1: W_w_surf = W_W_coeff2 * S W_w_strc = ((W_W_coeff1**2 / tau**2 * (N_ult**2 * A**3 * ((W_0 + V_f_fuse * g * rho_f) * W * S))))**0.5 W_w = W_w_surf + W_w_strc W_prev = W W = W_0 + W_w + W_f # so the above is for fully-loaded, but, # we may not be able to lift off with a full fuel load if (0.5 * rho * S * C_Lmax * V_min**2 < W - W_f): # cannot take off with any fuel! return True # full or partial fuel W_f = min(0.5 * rho * S * C_Lmax * V_min**2 - (W - W_f), W_f) V_f = W_f / g / rho_f V_f_wing = (0.0009 * S**3 / A * tau**2)**0.5 V_f_avail = V_f_wing + V_f_fuse CDA0 = V_f_fuse / (10 * ureg('m')) C_D_fuse = CDA0 / S while (V_cruisemax - V_cruisemax_prev).magnitude >= 0.1: Re = (rho / mu) * V_cruisemax * (S / A)**0.5 C_f = 0.074 / Re**0.2 C_D_wpar = k * C_f * S_wetratio C_D_ind = C_L**2 / (np.pi * A * e) C_D = C_D_fuse + C_D_wpar + C_D_ind V_cruisemax_prev = V_cruisemax V_cruisemax = 1 / (TSFC * Range * 0.5 * rho * S * C_D / W_f) V_cruisemin = ((W_0 + W_w + 0.5 * W_f) / (0.5 * rho * S * C_L))**0.5 if (V_cruisemin > V_cruisemax): return True
from mission_models import OnDemandSizingMission, OnDemandRevenueMission, OnDemandDeadheadMission from cost_models import OnDemandMissionCost from noise_models import vortex_noise from standard_substitutions import generic_data, configs from scipy.interpolate import interp2d configs = deepcopy(configs) del configs["Compound heli"] #Data from Boeing study boeing_data = {} boeing_data["Lift + cruise (Duffy et al.)"] = {} boeing_data["Lift + cruise (Duffy et al.)"]["L/D"] = 9.1 boeing_data["Lift + cruise (Duffy et al.)"]["T/A"] = 7.3*ureg("lbf")/ureg("ft")**2 boeing_data["Tilt rotor (Duffy et al.)"] = {} boeing_data["Tilt rotor (Duffy et al.)"]["L/D"] = 11.0 boeing_data["Tilt rotor (Duffy et al.)"]["T/A"] = 12.8*ureg("lbf")/ureg("ft")**2 ''' boeing_data["Helicopter"] = {} boeing_data["Helicopter"]["L/D"] = 7.26 boeing_data["Helicopter"]["T/A"] = 4.1*ureg("lbf")/ureg("ft")**2 ''' #Instantiate arrays numrows = 4 L_D_array = np.linspace(9, 15, numrows) T_A_max_array = np.linspace(4, 16, numrows)