def gen_737_plots(sol): """ function to generate plots of interesting values """ rng = np.cumsum(mag(sol('R_{segment}'))) alt = mag(sol('hft')) #generate an altitude profile plot tasrng = [ 0, 13.68, 31.34, 59.96, 115.05, 115.05, 2875.38, 2875.38, 2906.56, 2937.74, 2968.92, 3000 ] tasalt = [ 0, 8750, 17500, 26250, 35000, 35000, 39677.3, 39677.3, 29758., 19838.6, 9919.3, 0 ] plt.plot(rng, alt) plt.plot(tasrng, tasalt) plt.legend(['SP Model', 'TASOPT'], loc=4, fontsize=18) plt.ylabel('Altitude [ft]', fontsize=22) plt.xlabel('Down Range Distance [nm]', fontsize=22) plt.title('737 Altitude Profile', fontsize=22) plt.tick_params(axis='both', which='major', labelsize=16) plt.tick_params(axis='both', which='minor', labelsize=16) plt.savefig('737_altitude_profile.eps', bbox_inches="tight") plt.show()
def gen_D82_plots(sol): """ function to generate plots of interesting values """ #generate an altitude profile plot rng = mag(sol('R_{segment}')) alt = mag(sol('hft')) rng = np.cumsum(rng) tasrng = [ 0, 11.51, 27.36, 52.64, 103.28, 103.28, 2825.41, 2825.41, 2869.08, 2912.76, 2956.43, 3000 ] tasalt = [ 0, 9619.5, 19239.0, 28858.5, 38478.0, 38478.0, 41681.3, 41681.3, 32129.3, 21998.5, 11288.7, 0 ] plt.plot(rng, alt) plt.plot(tasrng, tasalt) plt.legend(['SP Model', 'TASOPT'], loc=4, fontsize=18) plt.ylabel('Altitude [ft]', fontsize=22) plt.xlabel('Down Range Distance [nm]', fontsize=22) plt.title('D8.2 Altitude Profile', fontsize=22) plt.ylim([0, 46000]) plt.tick_params(axis='both', which='major', labelsize=16) plt.tick_params(axis='both', which='minor', labelsize=16) plt.savefig('D8_altitude_profile.eps', bbox_inches="tight") plt.show()
def gen_777_plots(sol): """ function to generate plots of interesting values """ #generate an altitude profile plot tasrng = [ 0, 15.6, 33.24, 60.40, 107.98, 107.98, 5850.37, 5850.37, 5887.82, 5925.28, 5962.74, 6000 ] tasalt = [ 0, 7994.2, 15988.5, 23982.8, 31977.0, 31977.0, 39723.4, 39723.4, 31282.2, 21847.9, 11420.5, 0 ] rng = np.cumsum(mag(sol('R_{segment}'))) alt = mag(sol('hft')) plt.plot(rng, alt) plt.plot(tasrng, tasalt) plt.legend(['SP Model', 'TASOPT'], loc=4, fontsize=18) plt.ylabel('Altitude [ft]', fontsize=22) plt.xlabel('Down Range Distance [nm]', fontsize=22) plt.title('777 Altitude Profile', fontsize=22) plt.tick_params(axis='both', which='major', labelsize=16) plt.tick_params(axis='both', which='minor', labelsize=16) plt.savefig('777_altitude_profile.eps', bbox_inches="tight") plt.show()
def gen_D82_plots(sol): """ function to generate plots of interesting values """ #generate an altitude profile plot rng = [0] alt = [0] for i in range(len(sol('R_{climb}'))): rng.append(mag(sol('R_{climb}')[i][0])) for i in range(len(sol('R_{cruise}'))): rng.append(mag(sol('R_{cruise}')[i][0])) for i in range(len(sol('hft')['hft_Mission/FlightState/Altitude'])): alt.append(mag(sol('hft')['hft_Mission/FlightState/Altitude'][i][0])) rng = np.cumsum(rng) tasrng = [ 0, 11.51, 27.36, 52.64, 103.28, 103.28, 2825.41, 2825.41, 2869.08, 2912.76, 2956.43, 3000 ] tasalt = [ 0, 9619.5, 19239.0, 28858.5, 38478.0, 38478.0, 41681.3, 41681.3, 32129.3, 21998.5, 11288.7, 0 ] plt.plot(rng, alt) plt.plot(tasrng, tasalt) plt.legend(['SP Model', 'TASOPT'], loc=4) plt.ylabel('Altitude [ft]', fontsize=18) plt.xlabel('Down Range Distance [nm]', fontsize=18) plt.title('D8.2 Altitude Profile') plt.ylim([0, 46000]) plt.savefig('D8_altitude_profile.eps', bbox_inches="tight") plt.show()
def generate_radar_data(solutions, objectives, keyOrder, baseobj): # Generating data amenable to radar plotting data = [] data.append( [objectives[keyOrder[j]]['name'] for j in range(len(keyOrder))]) maxesindata = np.zeros(len(objectives)) minsindata = 10.**8 * np.ones(len(objectives)) counti = 0 for i in range(len(keyOrder)): case = objectives[keyOrder[i]]['name'] caseData = [[] for j in range(len(solutions[counti]))] for j in range(len(solutions[counti])): countk = 0 for k in range(len(keyOrder)): caseData[j].append(mag(solutions[counti][j](keyOrder[k]))) if mag(solutions[counti][j]( keyOrder[k])) >= maxesindata[countk]: maxesindata[countk] = mag(solutions[counti][j]( keyOrder[k])) if mag(solutions[counti][j]( keyOrder[k])) <= minsindata[countk]: minsindata[countk] = mag(solutions[counti][j](keyOrder[k])) countk += 1 data.append((case, caseData)) counti += 1
def gen_737_plots(sol): """ function to generate plots of interesting values """ #generate an altitude profile plot tasrng = [ 0, 13.68, 31.34, 59.96, 115.05, 115.05, 2875.38, 2875.38, 2906.56, 2937.74, 2968.92, 3000 ] tasalt = [ 0, 8750, 17500, 26250, 35000, 35000, 39677.3, 39677.3, 29758., 19838.6, 9919.3, 0 ] rng = [0] alt = [0] for i in range(len(sol('R_{climb}'))): rng.append(mag(sol('R_{climb}')[i][0])) for i in range(len(sol('R_{cruise}'))): rng.append(mag(sol('R_{cruise}')[i][0])) for i in range(len(sol('hft')['hft_Mission/FlightState/Altitude'])): alt.append(mag(sol('hft')['hft_Mission/FlightState/Altitude'][i][0])) rng = np.cumsum(rng) plt.plot(rng, alt) plt.plot(tasrng, tasalt) plt.legend(['SP Model', 'TASOPT'], loc=4) plt.ylabel('Altitude [ft]', fontsize=18) plt.xlabel('Down Range Distance [nm]', fontsize=18) plt.title('737 Altitude Profile', fontsize=18) plt.savefig('737_altitude_profile.eps', bbox_inches="tight") plt.show()
def post_compute(sol, Nclimb): eta_P_fan = 2 / ( 1 + 1.94384 * mag(sol('u_{8}')[Nclimb]) / mag(sol('V')[Nclimb])) print "Fan Propulsive Efficiency in Cruise Segment 1" print "---------------------" print eta_P_fan
def plot_star(nPoints, r_sol, l, title='Star'): fig = plt.figure() ax = plt.axes(projection='3d') nx = len(r_sol('A')) nt = len(r_sol('A')[0]) r_o = mag(r_sol('r_o')) r_i = mag(r_sol('r_i')) x = np.linspace(0, l, nx) theta = np.linspace(0, 2 * np.pi, 2 * nPoints + 1) X, Theta = np.meshgrid(x, theta) plt.rc('axes', prop_cycle=(cycler('color', ['r', 'g', 'b', 'y']) + cycler('linestyle', ['-', '--', ':', '-.']))) for i in range(nt): r_o_s = r_o[:, i] r_i_s = r_i[:, i] O, Theta = np.meshgrid(r_o_s, theta) I, Theta = np.meshgrid(r_i_s, theta) Z = I + np.ceil(np.mod(Theta, 2 * np.pi / nPoints)) * (O - I) ax.contour3D(X, Z * np.sin(Theta), Z * np.cos(Theta), 50, cmap='binary') plt.xlabel('Axial coordinate') plt.ylabel('Radial coordinate') plt.title(title) plt.show()
def gen_777_plots(sol): """ function to generate plots of interesting values """ #generate an altitude profile plot tasrng = [ 0, 15.6, 33.24, 60.40, 107.98, 107.98, 5850.37, 5850.37, 5887.82, 5925.28, 5962.74, 6000 ] tasalt = [ 0, 7994.2, 15988.5, 23982.8, 31977.0, 31977.0, 39723.4, 39723.4, 31282.2, 21847.9, 11420.5, 0 ] rng = [0] alt = [0] for i in range(len(sol('R_{climb}'))): rng.append(mag(sol('R_{climb}')[i][0])) for i in range(len(sol('R_{cruise}'))): rng.append(mag(sol('R_{cruise}')[i][0])) for i in range(len(sol('hft')['hft_Mission/FlightState/Altitude'])): alt.append(mag(sol('hft')['hft_Mission/FlightState/Altitude'][i][0])) rng = np.cumsum(rng) plt.plot(rng, alt) plt.plot(tasrng, tasalt) plt.legend(['SP Model', 'TASOPT'], loc=4) plt.ylabel('Altitude [ft]', fontsize=18) plt.xlabel('Down Range Distance [nm]', fontsize=18) plt.title('777 Altitude Profile') plt.savefig('777_altitude_profile.eps', bbox_inches="tight") plt.show()
def allocate_fuel(sol, m, relaxDict, nt, nx): """ :param sol: rocket solution :param m: rocket model :param relaxDict: dictionary of relaxations of model :param nt: time steps :param nx: spatial discretization :return: mass proportions of propellant, accelerant and filler material """ # Mapping solution values T_amb = sol(m.section.T_amb) T = sol(m.section.T) u = sol(m.section.u) c_p = sol(m.section.c_p) T_t = [[] for i in range(nx)] for i in range(nt): for j in range(nx): T_t[j].append((T[j, i] + u[j, i]**2 / (2 * c_p[i]))) mdot = sol(m.section.mdot) q = sol(m.section.q) k_comb_p = sol(m.section.k_comb_p) # Porosity of fuel porosity = relaxDict['massCons'] # Computing relative burn rate... q_comb = [[] for i in range(nx)] for i in range(nt): for j in range(nx): if j >= 1: q_comb[j].append( np.round(mag( ((T_t[j][i]) * mdot[j, i] - q[j, i] * T_amb[i] - T_t[j][i - 1] * mdot[j, i - 1]) * c_p[i] / k_comb_p[i]), decimals=2)) else: q_comb[j].append( np.round(mag( (T_t[j][i] * mdot[j, i] - q[j, i] * T_amb[i]) * c_p[i] / k_comb_p[i]), decimals=2)) # Since this isn't working properly, we hack and offset q_comb q_min = np.min(q_comb) qratmin = np.min(mag(q_comb / q)) q_comb = q_comb - (qratmin) * mag(q) qrat = mag(q_comb / q) # Sum of propellant+accelerant ratios beta_f = np.ones((nx, nt)) - qrat - porosity # Filler ratio # Use burn rate relaxation to obtain beta_a and beta_p beta_p = 1 / (np.ones((nx, nt)) + relaxDict['burnRate']) * qrat beta_a = np.ones((nx, nt)) - beta_p - beta_f return beta_p, beta_a, beta_f, porosity
def plot_general_solutions(solarray, var1, var2, var3): points = ["o","*","-"] count = 0 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') for i in solarray: ax.plot(mag(i(var1.key)), mag(i(var2.key)),mag(i(var3.key))) count+=1 ax.set_xlabel(var1.str_without()) ax.set_ylabel(var2.str_without()) ax.set_zlabel(var3.str_without()) plt.title('3D Flight envelope') plt.show()
def gen_plots(sol): """ function to generate plots of interesting values """ #generate an altitude profile plot rng = np.cumsum(mag(sol('R_{segment}'))) alt = mag(sol('hft')) plt.plot(rng, alt) plt.ylabel('Altitude [ft]', fontsize=18) plt.xlabel('Down Range Distance', fontsize=18) plt.title('Aircraft Altitude Profile') plt.show()
def make_initial_guess(model, newlist, guesstype='ones'): """Returns initial guess""" try: sol = model.solve(verbosity=0) except TypeError: sol = model.localsolve(verbosity=0) if guesstype == "ones": x0string = ["x0 = ones({0},1);\n".format(len(sol['freevariables']))] else: x0string = ["x0 = ["] i = 1 for vk in newlist: xf = mag(sol['freevariables'][vk]) if guesstype == "almost-exact-solution": x0 = round(xf, -int(floor(log10(abs(xf))))) # rounds to 1sf elif guesstype == "order-of-magnitude-floor": x0 = 10**floor(log10(xf)) elif guesstype == "order-of-magnitude-round": x0 = 10**round(log10(xf)) else: raise Exception("Unexpected guess type") x0string += [str(x0) + ", "] i += 1 x0string += ["];\n"] return "".join(x0string)
def test_simpleflight(self, example): self.assertTrue(example.sol.almost_equal(example.sol_loaded)) for sol in [example.sol, example.sol_loaded]: freevarcheck = { "A": 8.46, "C_D": 0.0206, "C_f": 0.0036, "C_L": 0.499, "Re": 3.68e+06, "S": 16.4, "W": 7.34e+03, "V": 38.2, "W_w": 2.40e+03 } # sensitivity values from p. 34 of W. Hoburg's thesis senscheck = { r"(\frac{S}{S_{wet}})": 0.4300, "e": -0.4785, "V_{min}": -0.3691, "k": 0.4300, r"\mu": 0.0860, "(CDA0)": 0.0915, "C_{L,max}": -0.1845, r"\tau": -0.2903, "N_{ult}": 0.2903, "W_0": 1.0107, r"\rho": -0.2275 } for key in freevarcheck: sol_rat = mag(sol["variables"][key])/freevarcheck[key] self.assertTrue(abs(1-sol_rat) < 1e-2) for key in senscheck: sol_rat = sol["sensitivities"]["variables"][key]/senscheck[key] self.assertTrue(abs(1-sol_rat) < 1e-2)
def test_simpleflight(self, example): sol = example.sol freevarcheck = dict(A=8.46, C_D=0.0206, C_f=0.0036, C_L=0.499, Re=3.68e+06, S=16.4, W=7.34e+03, V=38.2, W_w=2.40e+03) # sensitivity values from p. 34 of W. Hoburg's thesis consenscheck = {r"(\frac{S}{S_{wet}})": 0.4300, "e": -0.4785, "V_{min}": -0.3691, "k": 0.4300, r"\mu": 0.0860, "(CDA0)": 0.0915, "C_{L,max}": -0.1845, r"\tau": -0.2903, "N_{ult}": 0.2903, "W_0": 1.0107, r"\rho": -0.2275} for key in freevarcheck: sol_rat = mag(sol["variables"][key])/freevarcheck[key] self.assertTrue(abs(1-sol_rat) < 1e-2) for key in consenscheck: sol_rat = sol["sensitivities"]["constants"][key]/consenscheck[key] self.assertTrue(abs(1-sol_rat) < 1e-2)
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 test_simpleflight(self, example): self.assertTrue(example.sol.almost_equal(example.sol_loaded)) for sol in [example.sol, example.sol_loaded]: freevarcheck = { "A": 8.46, "C_D": 0.0206, "C_f": 0.0036, "C_L": 0.499, "Re": 3.68e+06, "S": 16.4, "W": 7.34e+03, "V": 38.2, "W_w": 2.40e+03 } # sensitivity values from p. 34 of W. Hoburg's thesis senscheck = { r"(\frac{S}{S_{wet}})": 0.4300, "e": -0.4785, "V_{min}": -0.3691, "k": 0.4300, r"\mu": 0.0860, "(CDA0)": 0.0915, "C_{L,max}": -0.1845, r"\tau": -0.2903, "N_{ult}": 0.2903, "W_0": 1.0107, r"\rho": -0.2275 } for key in freevarcheck: sol_rat = mag(sol["variables"][key])/freevarcheck[key] self.assertTrue(abs(1-sol_rat) < 1e-2) for key in senscheck: sol_rat = sol["sensitivities"]["constants"][key]/senscheck[key] self.assertTrue(abs(1-sol_rat) < 1e-2)
def draw_network(sol, coordinates): # Draws a general flow network (GI) N = len(coordinates) topology_list = [] n_edges = sum(sum(sol('x') > 1e-10)) prunedsol = {'q':[], 'D':[], '\dot{V}_+':[], '\dot{V}_-': []} for i in range(N): for j in range(N): if sol('x')[i][j] >= 1e-10: topology_list.append([i,j]) prunedsol['q'] = prunedsol['q'] + [mag(sol('q')[i][j])] prunedsol['D'] = prunedsol['D'] + [mag(sol('D')[i][j])] prunedsol['\dot{V}_+'] = sol('\dot{V}_+') prunedsol['\dot{V}_-'] = sol('\dot{V}_-') print(prunedsol) topology_dict = {i:topology_list[i] for i in range(len(topology_list))} draw_KT_network(prunedsol, coordinates, topology_dict)
def signomial_print(sig, sol, colorfn, paintby="constants", idx=None): "For pretty printing with Sympy" mstrs = [] for c, exp in zip(sig.cs, sig.exps): pos_vars, neg_vars = [], [] for var, x in exp.items(): varlatex = var.latex() if paintby == "constants": senss = (sol["sensitivities"]["constants"][var] if var in sol["sensitivities"]["constants"] else 0.0) colorstr = colorfn(senss) varlatex = "\\textcolor%s{%s}" % (colorstr, varlatex) if x > 0: pos_vars.append((varlatex, x)) elif x < 0: neg_vars.append((varlatex, x)) pvarstrs = [ '%s^{%.2g}' % (varl, x) if "%.2g" % x != "1" else varl for (varl, x) in pos_vars ] nvarstrs = [ '%s^{%.2g}' % (varl, -x) if "%.2g" % -x != "1" else varl for (varl, x) in neg_vars ] pvarstrs.sort() nvarstrs.sort() pvarstr = ' '.join(pvarstrs) nvarstr = ' '.join(nvarstrs) c = mag(c) cstr = "%.2g" % c if pos_vars and (cstr == "1" or cstr == "-1"): cstr = cstr[:-1] else: cstr = latex_num(c) if not pos_vars and not neg_vars: mstr = "%s" % cstr elif pos_vars and not neg_vars: mstr = "%s%s" % (cstr, pvarstr) elif neg_vars and not pos_vars: mstr = "\\frac{%s}{%s}" % (cstr, nvarstr) elif pos_vars and neg_vars: mstr = "%s\\frac{%s}{%s}" % (cstr, pvarstr, nvarstr) mstrs.append(mstr) if paintby == "monomials": mstrs_ = [] for mstr in mstrs: senss = sol["sensitivities"]["monomials"][idx] idx += 1 colorstr = colorfn(senss) mstrs_.append("\\textcolor%s{%s}" % (colorstr, mstr)) return " + ".join(sorted(mstrs_)), idx else: return " + ".join(sorted(mstrs))
def gen_D8_D8_no_BLI_plots(solD8, solno_BLI): """ function to generate plots of interesting values """ #generate an altitude profile plot rngD8 = np.cumsum(mag(solD8('R_{segment}'))) altD8 = mag(solD8('hft')) rngno_BLI = np.cumsum(mag(solno_BLI('R_{segment}'))) altno_BLI = mag(solno_BLI('hft')) plt.plot(rngD8, altD8) plt.plot(rngno_BLI, altno_BLI) plt.legend(['D8', 'D8 w/out BLI (rear podded engines)'], loc=4) plt.ylabel('Altitude [ft]', fontsize=18) plt.xlabel('Down Range Distance [nm]', fontsize=18) plt.title('D8 Altitude Profile with and without BLI') plt.savefig('D8_D8_no_BLI_altitude_profile.pdf', bbox_inches="tight") plt.show()
def signomial_print(sig, sol, colorfn, paintby="constants", idx=None): "For pretty printing with Sympy" mstrs = [] for c, exp in zip(sig.cs, sig.exps): pos_vars, neg_vars = [], [] for var, x in exp.items(): varlatex = var.latex() if paintby == "constants": senss = (sol["sensitivities"]["constants"][var] if var in sol["sensitivities"]["constants"] else 0.0) colorstr = colorfn(senss) varlatex = "\\textcolor%s{%s}" % (colorstr, varlatex) if x > 0: pos_vars.append((varlatex, x)) elif x < 0: neg_vars.append((varlatex, x)) pvarstrs = ['%s^{%.2g}' % (varl, x) if "%.2g" % x != "1" else varl for (varl, x) in pos_vars] nvarstrs = ['%s^{%.2g}' % (varl, -x) if "%.2g" % -x != "1" else varl for (varl, x) in neg_vars] pvarstrs.sort() nvarstrs.sort() pvarstr = ' '.join(pvarstrs) nvarstr = ' '.join(nvarstrs) c = mag(c) cstr = "%.2g" % c if pos_vars and (cstr == "1" or cstr == "-1"): cstr = cstr[:-1] else: cstr = latex_num(c) if not pos_vars and not neg_vars: mstr = "%s" % cstr elif pos_vars and not neg_vars: mstr = "%s%s" % (cstr, pvarstr) elif neg_vars and not pos_vars: mstr = "\\frac{%s}{%s}" % (cstr, nvarstr) elif pos_vars and neg_vars: mstr = "%s\\frac{%s}{%s}" % (cstr, pvarstr, nvarstr) mstrs.append(mstr) if paintby == "monomials": mstrs_ = [] for mstr in mstrs: senss = sol["sensitivities"]["monomials"][idx] idx += 1 colorstr = colorfn(senss) mstrs_.append("\\textcolor%s{%s}" % (colorstr, mstr)) return " + ".join(sorted(mstrs_)), idx else: return " + ".join(sorted(mstrs))
def update(self, solution): "Update the chart based upon a new solution" valuedict = solution["variables"] if self.updates == 0: # first update self.create_jsobj(valuedict) else: updates = "" for i, varname in enumerate(self.varnames): updates += ("%s.datasets[0].bars[%i].value = %f \n" % (self.name, i, mag(valuedict[varname]))) display(Javascript(updates + "%s.update()" % self.name)) self.updates += 1
def gen_plots(sol): """ function to generate plots of interesting values """ #generate an altitude profile plot rng = [] alt = [] for i in range(len(sol('R_{climb}'))): rng.append(mag(sol('R_{climb}')[i][0])) for i in range(len(sol('R_{cruise}'))): rng.append(mag(sol('R_{cruise}')[i][0])) for i in range(len(sol('hft')['hft_Mission/FlightState/Altitude'])): alt.append(mag(sol('hft')['hft_Mission/FlightState/Altitude'][i][0])) rng = np.cumsum(rng) plt.plot(rng, alt) plt.ylabel('Altitude [ft]', fontsize=18) plt.xlabel('Down Range Distance', fontsize=18) plt.title('Aircraft Altitude Profile') # plt.savefig('M08_D8_wing_profile_drag.pdf', bbox_inches="tight") plt.show()
def test(cls): b = cls(N=6, substitutions={"L": 6, "EI": 1.1e4, "q": 110*np.ones(10)}) b.zero_lower_unbounded_variables() sol = b.solve(verbosity=1) w_gp = sol("w") # deflection along beam L, EI, q = sol("L"), sol("EI"), sol("q") x = np.linspace(0, mag(L), len(q))*units.m # position along beam q = q[0] # assume uniform loading for the check below w_exact = q/(24.*EI) * x**2 * (x**2 - 4*L*x + 6*L**2) # analytic soln assert max(abs(w_gp - w_exact)) <= 1e-2*units.m
def generate_flight_envelope(m, var1, var2, var1range, rm = None, rmsol = None): """ Generates the flight envelope of an optimized aircraft This is a method to compare the objective trade-off performance of an already designed aircraft (nominal and robust) Want to MAXIMIZE both var1 and var2 (bigger envelope) :param m: already solved model :param var1: independent variable :param var2: dependent variable (should be maximized) :param var1range: the range of the independent var :param rm: robust version of m :param rmsol: solution of rm :return: nominal sweep solution, robust sweep solution """ dm = RobustGPTools.DesignedModel(m, m.solution, {}) if var2.key in list(m.substitutions.keys()): del dm.substitutions[var2.key] dm.cost = 1/var2 #*var2.units*dm.cost.units #dm.cost/var2 # dm.substitutions.update({var1.key:('sweep',var1range)}) sol = dm.localsolve(skipsweepfailures=True) if rm: drm = RobustGPTools.DesignedModel(m, rmsol, {}) if var2.key in list(rm.substitutions.keys()): del drm.substitutions[var2.key] drm.cost = 1/var2 #drm.cost + 1/var2*var2.units*drm.cost.units #drm.cost/var2 drm.substitutions.update({var1.key:('sweep',var1range)}) robustsol = drm.localsolve(skipsweepfailures=True) plt.plot(mag(sol(var1.key)),mag(sol(var2.key))) try: plt.plot(mag(robustsol(var1.key)),mag(robustsol(var2.key))) plt.legend(["Nominal", "Robust"]) except: pass plt.xlabel(var1.str_without()) plt.ylabel(var2.str_without()) plt.title(r'Flight envelope, $\Gamma = 1$') plt.grid() plt.show() return sol, robustsol
def gen_D8_737_plots(solD8, sol737): """ function to generate plots of interesting values """ #generate an altitude profile plot rngD8 = np.cumsum(mag(solD8('R_{segment}'))) altD8 = mag(solD8('hft')) rng73 = np.cumsum(mag(sol737('R_{segment}'))) alt73 = mag(sol737('hft')) tasrngD8 = [ 0, 11.51, 27.36, 52.64, 103.28, 103.28, 2825.41, 2825.41, 2869.08, 2912.76, 2956.43, 3000 ] tasaltD8 = [ 0, 9619.5, 19239.0, 28858.5, 38478.0, 38478.0, 41681.3, 41681.3, 32129.3, 21998.5, 11288.7, 0 ] tasrng73 = [ 0, 13.68, 31.34, 59.96, 115.05, 115.05, 2875.38, 2875.38, 2906.56, 2937.74, 2968.92, 3000 ] tasalt73 = [ 0, 8750, 17500, 26250, 35000, 35000, 39677.3, 39677.3, 29758., 19838.6, 9919.3, 0 ] plt.plot(rngD8, altD8) plt.plot(tasrngD8, tasaltD8) plt.plot(rng73, alt73) plt.plot(tasrng73, tasalt73) plt.legend(['D8 SP Model', 'D8 TASOPT', '737 SP Model', '737 TASOPT'], loc=4) plt.ylabel('Altitude [ft]', fontsize=18) plt.xlabel('Down Range Distance [nm]', fontsize=18) plt.title('737 and D8 Altitude Profile', fontsize=18) plt.savefig('737_D8_altitude_profile.eps', bbox_inches="tight") plt.show()
def draw_fuel(sol, m): fig = plt.figure() ax = plt.axes() nx = len(m.section.A_p_in) nt = len(m.section.A_p_in[0]) z = sol(m.section.A_p_in) fig, ax = plt.subplots(1, nx) for i in range(nx): ax[i].pie(z[i] / sum(z[i]), labels=np.linspace(1, nt, nt), radius=mag(z[i, 0]) / max(z.flat)) ax[i].axis('equal') plt.show()
def test_vector(self): x = Variable("x") y = Variable("y") z = VectorVariable(2, "z") p = x*y*z self.assertTrue(all(p.sub({x: 1, "y": 2}) == 2*z)) self.assertTrue(all(p.sub({x: 1, y: 2, "z": [1, 2]}) == z.sub(z, [2, 4]))) x = VectorVariable(3, "x", "m") xs = x[:2].sum() for x_ in ["x", x]: self.assertAlmostEqual(mag(xs.sub(x_, [1, 2, 3]).c), 3.0)
def test_vector(self): x = Variable("x") y = Variable("y") z = VectorVariable(2, "z") p = x*y*z self.assertTrue(all(p.sub({x: 1, "y": 2}) == 2*z)) self.assertTrue(all(p.sub({x: 1, y: 2, "z": [1, 2]}) == z.sub({z: [2, 4]}))) xvec = VectorVariable(3, "x", "m") xs = xvec[:2].sum() for x_ in ["x", xvec]: self.assertAlmostEqual(mag(xs.sub({x_: [1, 2, 3]}).c), 3.0)
def __init__(self, bounds, sols, sweptvar, costposy): if len(bounds) != 2: raise ValueError("bounds must be of length 2.") if bounds[1] <= bounds[0]: raise ValueError("bounds[0] must be smaller than bounds[1].") self.bounds = bounds self.sols = sols self.costs = log([mag(sol["cost"]) for sol in sols]) self.splits = None self.splitval = None self.splitlb = None self.splitub = None self.sweptvar = sweptvar self.costposy = costposy
def draw_2D_bar(sol, m, vectorvar, title): fig = plt.figure() ax = plt.axes(projection='3d') nx = len(m.section.A_p_in) nt = len(m.section.A_p_in[0]) x = np.linspace(1, nx, nx) y = np.linspace(1, nt, nt) X, Y = np.meshgrid(x, y) Z = sol(vectorvar) for i in range(nt): color = [0.5, 0., 1.0 * i / nt] ax.bar(x, mag(Z[:, i]), zs=i, zdir='y', alpha=0.5, color=color) plt.xlabel('Axial coordinate') plt.ylabel('Time step') plt.title(title) plt.show()
def test_scalar_units(self): x = Variable("x", "m") xvk = x.key y = Variable("y", "km") yvk = y.key units_exist = bool(x.units) for x_ in ["x", xvk, x]: for y_ in ["y", yvk, y]: if not isinstance(y_, str) and units_exist: expected = 0.001 else: expected = 1.0 self.assertAlmostEqual(expected, mag(x.sub(x_, y_).c)) if units_exist: z = Variable("z", "s") self.assertRaises(ValueError, y.sub, y, z)
def test_scalar_units(self): x = Variable("x", "m") xvk = x.key y = Variable("y", "km") yvk = y.key units_exist = bool(x.units) for x_ in ["x", xvk, x]: for y_ in ["y", yvk, y]: if not isinstance(y_, str) and units_exist: expected = 1000.0 else: expected = 1.0 self.assertAlmostEqual(expected, mag(x.sub({x_: y_}).c)) if units_exist: z = Variable("z", "s") self.assertRaises(ValueError, y.sub, {y: z})
def print_simulation_results(the_robust_model, the_robust_model_solution, the_robust_model_solve_time, the_nominal_model_solve_time, the_nominal_no_of_constraints, the_nominal_cost, the_simulation_results, the_file_id): the_file_id.write('\t\t\t' + 'Probability of failure: %s\n' % the_simulation_results[0]) the_file_id.write('\t\t\t' + 'Average performance: %s\n' % mag(the_simulation_results[1])) the_file_id.write( '\t\t\t' + 'Relative average performance: %s\n' % (mag(the_simulation_results[1]) / float(mag(the_nominal_cost)))) the_file_id.write('\t\t\t' + 'Worst-case performance: %s\n' % mag(the_robust_model_solution['cost'])) the_file_id.write('\t\t\t' + 'Relative worst-case performance: %s\n' % (mag(the_robust_model_solution['cost']) / float(mag(the_nominal_cost)))) try: number_of_constraints = \ len([cnstrnt for cnstrnt in the_robust_model.get_robust_model().flat(constraintsets=False)]) except AttributeError: number_of_constraints = \ len([cnstrnt for cnstrnt in the_robust_model.get_robust_model()[-1].flat(constraintsets=False)]) the_file_id.write('\t\t\t' + 'Number of constraints: %s\n' % number_of_constraints) the_file_id.write( '\t\t\t' + 'Relative number of constraints: %s\n' % (number_of_constraints / float(the_nominal_no_of_constraints))) the_file_id.write('\t\t\t' + 'Setup time: %s\n' % the_robust_model_solution['setuptime']) the_file_id.write('\t\t\t' + 'Relative setup time: %s\n' % (the_robust_model_solution['setuptime'] / float(the_nominal_model_solve_time))) the_file_id.write('\t\t\t' + 'Solve time: %s\n' % the_robust_model_solve_time) the_file_id.write( '\t\t\t' + 'Relative solve time: %s\n' % (the_robust_model_solve_time / float(the_nominal_model_solve_time))) the_file_id.write('\t\t\t' + 'Number of linear sections: %s\n' % the_robust_model_solution['numoflinearsections']) the_file_id.write('\t\t\t' + 'Upper lower relative error: %s\n' % mag(the_robust_model_solution['upperLowerRelError']))
def create_jsobj(self, data): "Create and display the javascript object for this chart" labels = ", ".join(['"%s"' % vn for vn in self.varnames]) datarray = ", ".join( [str(mag(data[varname])) for varname in self.varnames]) js_init = Template(""" var data = { labels: [$labels], datasets: [ { data: [$datarray], fillColor: "rgba(151,187,205,0.5)", strokeColor: "rgba(151,187,205,0.8)", highlightFill: "rgba(151,187,205,0.75)", highlightStroke: "rgba(151,187,205,1)", }]} var ctx = document.getElementById("$name").getContext("2d"); window.$name = new Chart(ctx).Bar(data, {animationSteps: 1} ); """).substitute(name=self.name, labels=labels, datarray=datarray) display(Javascript(js_init))
def create_jsobj(self, data): "Create and display the javascript object for this chart" labels = ", ".join(['"%s"' % vn for vn in self.varnames]) datarray = ", ".join([str(mag(data[varname])) for varname in self.varnames]) js_init = Template(""" var data = { labels: [$labels], datasets: [ { data: [$datarray], fillColor: "rgba(151,187,205,0.5)", strokeColor: "rgba(151,187,205,0.8)", highlightFill: "rgba(151,187,205,0.75)", highlightStroke: "rgba(151,187,205,1)", }]} var ctx = document.getElementById("$name").getContext("2d"); window.$name = new Chart(ctx).Bar(data, {animationSteps: 1} ); """).substitute(name=self.name, labels=labels, datarray=datarray) display(Javascript(js_init))
def gen_D8_D8_no_BLI_plots(solD8, solno_BLI): """ function to generate plots of interesting values """ #generate an altitude profile plot rngD8 = [] altD8 = [] for i in range(len(solD8('R_{climb}'))): rngD8.append(mag(solD8('R_{climb}')[i][0])) for i in range(len(solD8('Rng'))): rngD8.append(mag(solD8('Rng')[i][0])) for i in range(len(solD8('hft')['hft_Mission/FlightState/Altitude'])): altD8.append( mag(solD8('hft')['hft_Mission/FlightState/Altitude'][i][0])) rngD8 = np.cumsum(rngD8) rngno_BLI = [] altno_BLI = [] for i in range(len(solno_BLI('R_{climb}'))): rngno_BLI.append(mag(solno_BLI('R_{climb}')[i][0])) for i in range(len(solno_BLI('Rng'))): rngno_BLI.append(mag(solno_BLI('Rng')[i][0])) for i in range(len(solno_BLI('hft')['hft_Mission/FlightState/Altitude'])): altno_BLI.append( mag(solno_BLI('hft')['hft_Mission/FlightState/Altitude'][i][0])) rngno_BLI = np.cumsum(rngno_BLI) plt.plot(rngD8, altD8) plt.plot(rngno_BLI, altno_BLI) plt.legend(['D8', 'D8 w/out BLI (rear podded engines)'], loc=4) plt.ylabel('Altitude [ft]', fontsize=18) plt.xlabel('Down Range Distance [nm]', fontsize=18) plt.title('D8 Altitude Profile with and without BLI') plt.savefig('D8_D8_no_BLI_altitude_profile.pdf', bbox_inches="tight") plt.show()
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:", l_vals print "values of A:", sol1("A") cost_estimate = sol1["cost"] cost_lb, cost_ub = sol1.cost_lb(), sol1.cost_ub() print "cost lower bound:", cost_lb print "cost estimate: ", cost_estimate print "cost upper bound:", 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))) # save autosweep to a file and retrieve it bst1.save("autosweep.pkl") bst1_loaded = pickle.load(open("autosweep.pkl")) # this problem is two intersecting lines in logspace m2 = Model(A**2, [A >= (l/3)**2, A >= (l/3)**0.5 * units.m**1.5]) tol2 = {"mosek": 1e-12, "cvxopt": 1e-7, "mosek_cli": 1e-6}[gpkit.settings["default_solver"]] bst2 = autosweep_1d(m2, tol2, l, [1, 10], verbosity=0) print "Solved after %2i passes, cost logtol +/-%.3g" % (bst2.nsols, bst2.tol) print "Table of solutions used in the autosweep:"
theta_eq[0] = (th[0] >= th_base) # base boundary condition displ_eq = (w >= w.left + 0.5*dx*(th + th.left)) displ_eq[0] = (w[0] >= w_base) # minimize tip displacement (the last w) self.cost = self.w_tip = w[-1] return [shear_eq, moment_eq, theta_eq, displ_eq, L == (N-1)*dx] b = Beam(N=6, substitutions={"L": 6, "EI": 1.1e4, "q": 110*np.ones(6)}) sol = b.solve(verbosity=0) print sol.summary(maxcolumns=6) w_gp = sol("w") # deflection along beam L, EI, q = sol("L"), sol("EI"), sol("q") x = np.linspace(0, mag(L), len(q))*ureg.m # position along beam q = q[0] # assume uniform loading for the check below w_exact = q/(24.*EI) * x**2 * (x**2 - 4*L*x + 6*L**2) # analytic soln assert max(abs(w_gp - w_exact)) <= 1.1*ureg.cm PLOT = False if PLOT: import matplotlib.pyplot as plt x_exact = np.linspace(0, L, 1000) w_exact = q/(24.*EI) * x_exact**2 * (x_exact**2 - 4*L*x_exact + 6*L**2) plt.plot(x, w_gp, color='red', linestyle='solid', marker='^', markersize=8) plt.plot(x_exact, w_exact, color='blue', linestyle='dashed') plt.xlabel('x [m]') plt.ylabel('Deflection [m]')
def assert_logtol(first, second, logtol=1e-6): "Asserts that the logs of two arrays have a given abstol" np.testing.assert_allclose(log(mag(first)), log(mag(second)), atol=logtol, rtol=0)