def bd_vars(M, sol, varname, morevars): colnames = ["Value", "Units", "Margin", "Margin Sens", "Label"] data = {} for sv in sol(varname): name = max(list(sv.keys), key=len) data[name] = [sol(sv).magnitude] data[name].append(unitstr(sv.units)) for mfac in sol("m_{fac}"): if not sv.models == mfac.models: continue data[name].append(sol(mfac).magnitude) data[name].append(sol["sensitivities"]["constants"][mfac]) if len(data[name]) != 4: data[name] += [""] * 2 data[name].append(sv.label) for name in morevars: sv = sol(name) data[name] = [sv.magnitude] data[name].append(unitstr(M[name].descr["units"])) for mfac in sol("m_{fac}"): if not M[name].descr["models"] == mfac.models: continue data[name].append(sol(mfac).magnitude) data[name].append(sol["sensitivities"]["constants"][mfac]) if len(data[name]) != 4: data[name] += [""] * 2 data[name].append(M[name].descr["label"]) df = pd.DataFrame(data) df = df.transpose() df.columns = colnames return df
def test_unitstr(self): x = gpkit.Variable("x", "ft") # pint issue 356 self.assertEqual(unitstr(gpkit.Variable("n", "count")), "count") self.assertEqual(unitstr(x), "ft") self.assertEqual(unitstr(x.key), "ft") self.assertEqual(unitstr(gpkit.Variable("y"), dimless="---"), "---") self.assertEqual(unitstr(None, dimless="--"), "")
def plot_sweep(model, xvarname, xsweep, yvarnames=None, ylim=None, fig=None, axis=None): """ Takes model with sweep input and returns figure with desired output var Arguments --------- model: Model xvarname: String - variable name of sweep var xsweep: np.array - sweep values yvarname: String - variable name of desired output ylim: 2D array - plotting limits on y axis; x axis defaults are sweep min and max Returns ------- fig, ax: figure and axis of subplot """ oldsub = model.substitutions[xvarname] model.substitutions.update({xvarname: ("sweep", xsweep)}) sol = model.solve("mosek", skipsweepfailures=True) if not fig and not axis: fig, axis = plt.subplots(len(yvarnames)) if not isinstance(axis, np.ndarray) == 1: axis = [axis] for yvarname, ax in zip(yvarnames, axis): if yvarname: if yvarname not in model.substitutions: ax.plot(sol(xvarname), sol(yvarname)) else: ax.plot(sol(xvarname), [sol(yvarname).magnitude] * len(sol(xvarname))) ax.set_ylabel("%s [%s]" % (model[yvarname].descr["label"], unitstr(model[yvarname].units))) else: ax.plot(sol(xvarname), sol["sensitivities"]["constants"][xvarname]) ax.set_ylabel("%s sens" % model[xvarname].descr["label"]) ax.set_xlabel( "%s [%s]" % (model[xvarname].descr["label"], unitstr(model[xvarname].units))) if ylim: ax.set_ylim((ylim[0], ylim[1])) plt.grid() model.substitutions.update({xvarname: oldsub}) return fig, axis
def test_unitstr(self): x = gpkit.Variable("x", "ft") # pint issue 356 footstrings = ("ft", "foot") # backwards compatibility with pint 0.6 self.assertEqual(unitstr(gpkit.Variable("n", "count")), "count") self.assertIn(unitstr(x), footstrings) self.assertIn(unitstr(x.key), footstrings) self.assertEqual(unitstr(gpkit.Variable("y"), dimless="---"), "---") self.assertEqual(unitstr(None, dimless="--"), "")
def sketch_params(M, sol, varnames, othervars=None, pointmasses=None): data = {} for vname in varnames: uts = unitstr(M[vname].descr["units"]) if "ft" not in uts and uts != "": spt = uts.split("*") spt[0] = "ft" uts = "".join(spt) data[vname.replace(", ", "-").replace("\\", "")] = [sol(vname).to(uts).magnitude, uts, M[vname].descr["label"]] if othervars: data.update(othervars) if hasattr(M, "get_cgs"): xnp, xcg, SM = M.get_cgs() data["x_{np}"] = [xnp.magnitude, xnp.units, "neutral point"] data["x_{cg}"] = [xcg.magnitude, xcg.units, "center of gravity"] data["SM"] = [SM.magnitude, "-", "static margin"] if pointmasses: for pm in pointmasses: data[pm] = [] df = pd.DataFrame(data) df = df.transpose() df.columns = ["Value", "Units", "Label"] return df
def sketch_params(M, sol, varnames, othervars=None, pointmasses=None): data = {} for vname in varnames: data[vname] = [ sol(vname).magnitude, unitstr(M[vname].descr["units"]), M[vname].descr["label"] ] if othervars: data.update(othervars) if hasattr(M, "get_cgs"): xnp, xcg, SM = M.get_cgs() data["x_{np}"] = [xnp.magnitude, xnp.units, "neutral point"] data["x_{cg}"] = [xcg.magnitude, xcg.units, "center of gravity"] data["SM"] = [SM.magnitude, "-", "static margin"] if pointmasses: for pm in pointmasses: data[pm] = [] df = pd.DataFrame(data) df = df.transpose() df.columns = ["Value", "Units", "Label"] return df
def gen_model_tex(model, modelname, texname=None): if texname: filename = texname else: filename = modelname with open('tex/%s.vars.generated.tex' % filename, 'w') as f: f.write("\\begin{longtable}{llll}\n \\toprule\n") f.write("\\toprule\n") f.write("Variables & Value & Units & Description \\\\ \n") f.write("\\midrule\n") #f.write("\\multicolumn{3}{l}\n") varnames = ["firstname"] for var in model.varkeys: if var.name not in varnames: if var.models[-1] == modelname: varnames.append(var.name) unitstring = unitstr(var.units) unitstring = "$[%s]$" % unitstring if unitstring else "" val = "%0.3f" % var.value if var.value else "" f.write("$%s$ & %s & %s & %s \\\\\n" % (var.name, val, unitstring, var.label)) else: pass f.write("\\bottomrule\n") f.write("\\end{longtable}\n") with open('tex/%s.cnstrs.generated.tex' % filename, 'w') as f: ltex = cleaned_latex(model) for i in range(5): ltex = ltex.replace("_{(%d)}" % i, "") f.write("$ %s $" % ltex)
def plot_altitude_sweeps(hvals, yvarnames, vars_to_fix): """ Plots sweeps of yvarnames vs altitude. Only runs GasMALEFixedEngine(). Arguments --------- hvals : array, desired altitude sweep yvarnames : dict {variable name}, desired y variable for plotting vars_to_fix: dict - name of variable to fix and tolerance fixing CLIMB: boolean - True if using gasmale.py, False if using gas_male_fixCDR.py Output ------ Saves plot in pdf format. Number of plots equal to number of values in yvarnames. Plot names = "altitude_vs_%s.pdf" """ vals = np.zeros([len(hvals), len(yvarnames)]) M_fix = GasMALE(DF70=True) M_fix.substitutions.update({"t_{loiter}": 6}) M_fix.cost = M_fix["MTOW"] sol_fix = M_fix.solve("mosek", verbosity=0) for i, h in enumerate(hvals): M = GasMALE(h_station=h, DF70=True) fix_vars(M, sol_fix, vars_to_fix) sol = M.solve("mosek", verbosity=0) for j, yvarname in enumerate(yvarnames): vals[i, j] = sol(yvarname).magnitude figures = [] axis = [] hvar = M_fix.variables_byname("h")[0] for j, yvarname in enumerate(yvarnames): fig, ax = plt.subplots() ax.plot(hvals, vals[:, j]) ax.set_xlabel("%s [%s]" % (hvar.descr["label"], unitstr(hvar.units))) ax.set_ylabel( "%s [%s]" % (M_fix[yvarname].descr["label"], unitstr(M_fix[yvarname].units))) ax.set_title("CRD " + yvarname + " vs h_{station}") plt.grid() figures.append(fig) axis.append(ax) return figures, axis
def model_params(subM, sol): data = {} for v in subM.varkeys: if "idx" not in v.descr or v.idx == (0, ): if "Cruise" not in v.descr["models"]: if "TailAero" not in v.descr["models"]: data[v] = [ sol(v.name + "_" + ", ".join(v.models)).magnitude ] data[v].append(unitstr(M[v].units)) data[v].append(v.descr["label"]) if data: df = pd.DataFrame(data) df = df.transpose() df.columns = ["Value", "Units", "Label"] else: df = None return df
def gen_fixvars_tex(model, solution, fixvars, filename=None): if filename: texname = "%s.table.generated.tex" % filename else: texname = "tex/fixvars.table.generated.tex" with open(texname, 'w') as f: f.write("\\begin{longtable}{lllll}\n \\toprule\n") f.write("\\toprule\n") f.write("Variables & Value & Units & Description \\\\ \n") f.write("\\midrule\n") for varname in fixvars: name = model[varname].descr["name"] val = "%0.3f" % solution(varname).magnitude unitstring = unitstr(model[varname].units) label = model[varname].descr["label"] if varname in solution["sensitivities"]["constants"]: sens = "%0.3f" % solution["sensitivities"]["constants"][varname] else: sens = "" f.write("$%s$ & %s & %s & %s & %s \\\\\n" % (name, val, unitstring, sens, label)) f.write("\\bottomrule\n") f.write("\\end{longtable}\n")
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"))
def plot_mission_var(model, sol, yvarname, ylim=False, yaxis_name=None): """ Plots a mission varible against mission time. Arguments --------- model: must be GasPoweredMALE from gasmale.py yvarname: String - variable string name Returns: fig, ax: matplotlib figure and axis - time not to scale, labeled by mission profile inhereint in model. """ y = [] flightseg = [] shape = [0] for subm in model.submodels: if subm.__class__.__name__ == "Mission": for i, fs in enumerate(subm.submodels): if "/" in yvarname: vname1 = yvarname.split("/")[0] vname2 = yvarname.split("/")[1] value = (sol(fs[vname1]) / sol(fs[vname2])) yunits = "%s/%s" % (unitstr( fs[vname1].units), unitstr(fs[vname2].units)) ylabel = yvarname name = vname1 else: value = sol(fs[yvarname]) yunits = unitstr(fs[yvarname].units) ylabel = (fs[yvarname][0].descr["label"] if not isinstance(fs[yvarname], Variable) else fs[yvarname].descr["label"]) name = yvarname shape.append(shape[i] + (fs[name][0].descr["shape"][0] if not isinstance(fs[name], Variable) else 1)) flightseg.append(fs.__class__.__name__ + "%s" % fs.num) y.append(value.magnitude) y = np.hstack(np.array(y)) shape[2:] = [x - 1 for x in shape[2:]] # define tick step on plot N = range(len(y)) # create plot fig, ax = plt.subplots() line, = ax.plot(N, y) # label time axis ax.xaxis.set_ticks(np.arange(0, len(y) - 1, 1)) labels = [item.get_text() for item in ax.get_xticklabels()] for i, seg in enumerate(flightseg): labels[shape[i]] = seg ax.set_xticklabels(labels, rotation=-45) # mark mission profile changes if not ylim: ylim = [min(y), max(y)] ax.set_ylim([ylim[0], ylim[1]]) if yaxis_name: ax.set_ylabel(yaxis_name) else: ax.set_ylabel("%s [%s]" % (ylabel, yunits)) ax.grid() for s in shape: ax.plot([s, s], [ylim[0], ylim[1]], '--', color='r') return fig, ax
def sol_table(sols, models, varnames, filename, ttype, latns=[], title="Design Variables", label="vals"): with open(filename, "w") as f: f.write("\\begin{longtable}{lccccccccccccc}\n") f.write("\\caption{%s}\\\\\n" % title) f.write("\\toprule\n") f.write("\\toprule\n") f.write("\\label{t:%s}\n" % label) if ttype == "solar": f.write("\\multirow{2}{*}{Variable} & 25$^{\circ}$ Latitude & " "30$^{\circ}$ Latitude & 25$^{\circ}$ Latitude & " "30$^{\circ}$ Latitude \\\\\n") f.write("& $p_{\\mathrm{wind}}=0.85$& $p_{\\mathrm{wind}}=0.85$ & " "$p_{\\mathrm{wind}}=0.90$ & " "$p_{\\mathrm{wind}}=0.90$ \\\\\n") elif ttype == "tbflex": f.write("\\multirow{2}{*}{Variable} & " "\\multicolumn{2}{c}{Without Tail Boom Flex} & " "\\multicolumn{2}{c}{With Tail Boom Flex} \\\\\n") f.write("& 25$^{\circ}$ Latitude & 30$^{\circ}$ Latitude & " "25$^{\circ}$ Latitude & 30$^{\circ}$ Latitude \\\\\n") elif ttype == "tbflexg": f.write("\\multirow{2}{*}{Variable} & Without Tail Boom Flex & " "With Tail Boom Flex \\\\\n") f.write("& 9 Day Endurance & 9 Day Endurance \\\\\n") elif ttype == "gas": f.write("Variable & 5 Day Endurance & 7 Day Endurance & 9 Day " "Endurance\\\\\n") else: raise ValueError("Invalid ttype. Valid inputs are " "[solar, tbflex, gas]") f.write("\\midrule\n") for vnm, ltnm in zip(varnames, latns): vals = [] for s, m in zip(sols, models): if isinstance(s(vnm), float): val = s(vnm) units = "" elif not hasattr(s(vnm), "magnitude"): if ttype == "solar": mn = [max(m[sv].descr["modelnums"]) for sv in s("(E/S)_{irr}") if abs( s["sensitivities"]["constants"][sv]) > 0.01][0] val = [s(vk) for vk in m.varkeys[vnm] if max(vk.modelnums) == mn][0] elif ttype == "gas": val = [s(sv) for sv in s(vnm) if "Loiter" in sv.models][0][1] if hasattr(val, "magnitude"): units = " [" + unitstr(val) + "]" val = val.magnitude else: units = "" if vnm == "\\rho": val = altitude(val)*0.3048 units = " [m]" else: val = s(vnm).magnitude units = " [" + unitstr(s(vnm)) + "]" if "**" in units: sp = units.split("**") units = sp[0] + "$^{" + sp[-1].replace("]", "") + "}$]" vals.append(val) row = ltnm + units + "&" + " & ".join(["%.3g" % x for x in vals]) f.write(row + "\\\\\n") f.write("\\bottomrule\n") f.write("\\end{longtable}")
def test_pint_366(self): # test for https://github.com/hgrecco/pint/issues/366 if gpkit.units: self.assertEqual(unitstr(gpkit.units("nautical_mile")), "nmi") self.assertEqual(gpkit.units("nautical_mile"), gpkit.units("nmi"))
def mission_vars(M, sol): """ This ouputs variables relevant accross a mission """ mission = ["Climb", "Cruise", "Loiter"] mns = [10, 1, 5, 1] data = {} vks = [] for m in M.varkeys: for fs in mission: if fs in m.models and "shape" in m.descr: data[m.name + "_" + ", ".join([mname for mname in m.models if mname != fs])] = [unitstr(m.descr["units"])] + [""]*17 \ + [m.descr["label"]] vks.append(m) for vk in vks: fs = [m for m in vk.models if m in mission][0] mn = vk.modelnums[vk.models.index(fs)] if mn == 1: ind = -2 else: if fs == "Climb": ind = 1 + vk.idx[0] elif fs == "Cruise": ind = 11 elif fs == "Loiter": ind = 12 + vk.idx[0] data[vk.name + "_" + ", ".join( [mname for mname in vk.models if mname != fs])][ind] = sol(vk).magnitude colnames = ["Units"] + ["Climb%d" % i for i in range(10)] + ["Cruise"] + [ "Loiter%d" % i for i in range(5) ] + ["Cruise"] + ["Label"] df = pd.DataFrame(data) df = df.transpose() df.columns = colnames return df