def setup(self): exec parse_variables(BoundsChecking.__doc__) self.cost = F return [ F >= D + T, D == rf * V**2 * Ap, Ap == nu, T == mf * V, mf >= mi + mb, mf == rf * V, Fs <= mi ]
def setup(self): exec parse_variables(Empennage.__doc__) self.htail = HorizontalTail() self.htail.substitutions.update({self.htail.mfac: 1.1}) lh = self.lh = self.htail.lh self.Vh = self.htail.Vh self.bh = self.htail.b self.mh = self.htail.mh self.vtail = VerticalTail() self.vtail.substitutions.update({self.vtail.mfac: 1.1}) lv = self.lv = self.vtail.lv self.Vv = self.vtail.Vv self.bv = self.vtail.b self.tailboom = TailBoom() self.components = [self.htail, self.vtail, self.tailboom] l = self.l = self.tailboom.l state = TailBoomState() loading = [ self.tailboom.hbending(self.tailboom, self.htail, state), self.tailboom.vbending(self.tailboom, self.vtail, state), self.tailboom.vtorsion(self.tailboom, self.vtail, state) ] constraints = [ W / mfac >= sum(c.W for c in self.components), l >= lh, l >= lv, ] return self.components, constraints, loading
def setup(self, htail, hbending, wing): exec parse_variables(TailBoomFlexibility.__doc__) mh = htail.mh mw = wing.mw Vh = htail.Vh th = hbending.th CLhmin = htail.CLhmin CLwmax = wing.planform.CLmax Sw = wing.planform.S bw = wing.planform.b lh = htail.lh CM = wing.planform.CM constraints = [ Fne >= 1 + mh * th, sph1 * (mw * Fne / mh / Vh) + deda <= 1, sph2 <= Vh * CLhmin / CLwmax, # (sph1 + sph2).mono_lower_bound({"sph1": .48, "sph2": .52}) >= ( # SMcorr + wing["C_M"]/wing["C_{L_{max}}"]), deda >= mw * Sw / bw / 4 / pi / lh ] with SignomialsEnabled(): constraints.extend([sph1 + sph2 >= SMcorr + CM / CLwmax]) return constraints
def setup(self, static, state, fitdata=dirname(abspath(__file__)) + sep + "jho_fitdata.csv"): self.state = state self.static = static exec parse_variables(WingAero.__doc__) df = pd.read_csv(fitdata) fd = df.to_dict(orient="records")[0] AR = static.planform.AR cmac = static.planform.cmac rho = state.rho V = state.V mu = state.mu # needed for Climb model in solar self.rhoValue = bool(rho.key.value) self.muValue = bool(mu.key.value) if fd["d"] == 2: independentvars = [CL, Re] elif fd["d"] == 3: independentvars = [CL, Re, static.planform.tau] return [ Cd >= cdp + CL**2 / np.pi / AR / e, Re == rho * V * cmac / mu, # XfoilFit(fd, cdp, [CL, Re], airfoil="jho1.dat"), XfoilFit(fd, cdp, independentvars, name="polar"), CL <= CLstall ]
def setup(self, N, surface): self.surface = surface exec parse_variables(BoxSpar.__doc__) b = self.b = surface.b cave = self.cave = surface.cave tau = self.tau = surface.tau deta = surface.deta rho = self.material.rho rhoshear = self.shearMaterial.rho rhocore = self.coreMaterial.rho tshearmin = self.shearMaterial.tmin tmin = self.material.tmin self.weight = W >= 2*dm.sum()*g constraints = [I/mfac <= w*t*hin**2, dm >= (rho*4*w*t + 4*tshear*rhoshear*(hin + w) + 2*rhocore*tcore*(w + hin))*b/2*deta, w <= wlim*cave, cave*tau >= hin + 4*t + 2*tcore, self.weight, t >= tmin, Sy*(hin/2 + 2*t + tcore) <= I, tshear >= tshearmin, tcore >= tcoret*cave*tau, d == w, ] return constraints
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 setup(self): exec parse_variables(Aircraft.__doc__) self.fuse = Fuselage() self.wing = Wing() self.components = [self.fuse, self.wing] return self.components, W >= sum(c.W for c in self.components)
def setup(self, static, state, N=5): exec parse_variables(BladeElementProp.__doc__) with Vectorize(N): blade = BladeElementPerf(static, state) constraints = [ blade.dr == static.R / (N), blade.omega == omega, blade.r[0] == static.R / (2. * N) ] for n in range(1, N): constraints += [ TCS([blade.r[n] >= blade.r[n - 1] + static.R / N]), blade.eta_i[n] == blade.eta_i[n - 1], ] constraints += [ TCS([Q >= sum(blade.dQ)]), eta == state.V * T / (omega * Q), blade.M[-1] <= Mtip, static.T_m >= T, omega <= omega_max ] with SignomialsEnabled(): constraints += [TCS([T <= sum(blade.dT)])] return constraints, blade
def setup(self, N=5): exec parse_variables(Wing.__doc__) self.wing = WingGP.setup(self, N=N) with SignomialsEnabled(): constraints = [mw * (1 + 2 / self.planform["AR"]) >= 2 * np.pi] return self.wing, constraints
def setup(self): exec parse_variables(Motor.__doc__) constraints = [W >= Qstar*Qmax*g, Kv >= Kv_min, Kv <= Kv_max] return constraints
def setup(self, surface): exec parse_variables(WingCore.__doc__) cave = self.cave = surface.cave b = self.b = surface.b deta = surface.deta rho = self.material.rho return [W >= 2*(g*rho*Abar*cave**2*b/2*deta).sum()]
def setup(self): exec parse_variables(Trip.__doc__) customer = Customer() constraints = [ cost >= Variable('cost_lim', 1, '-'), t >= Variable('t_lim', 10, 'minutes'), total_cost >= cost + t * customer.time_value ] return constraints, customer
def setup(self): exec parse_variables(TailBoom.__doc__) return [I0 <= np.pi*t0*d0**3/8.0, W/mfac >= np.pi*g*rhocfrp*d0*l*t0*kfac, t0 >= tmin, J <= np.pi/8.0*d0**3*t0, S == l*np.pi*d0, ]
def setup(self): exec parse_variables(Aircraft.__doc__) self.fuse = Fuselage() self.wing = Wing() self.components = [self.fuse, self.wing] return { "definition of W": W >= sum(c.W for c in self.components), "components": self.components }
def setup(self): exec parse_variables(Propulsor.__doc__) Propeller.flight_model = self.prop_flight_model self.prop = Propeller() self.motor = Motor() components = [self.prop, self.motor] return [self.W >= self.prop.W + self.motor.W], components
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, nt, nx): exec parse_variables(Rocket.__doc__) self.nt = nt self.nx = nx self.nozzle = Nozzle() with Vectorize(nt): self.nozzlePerformance = NozzlePerformance(self.nozzle) self.section = SRM(nx) constraints = [ # Limiting nozzle size to cross-sectional area # self.nozzle.A_e <= np.pi*r**2, # Equal time segments self.section.dt == t_T/nt, # All fuel is consumed self.section.A_p_out[:,-1] == 1e-20*np.ones(nx)*np.pi*r**2, A_fuel == self.section.A_p_in[:,0], T_target == self.nozzlePerformance.T, c_T == self.nozzlePerformance.c_T, # Fuel parameters self.section.k_comb_p == k_comb_p, self.section.rho_p == rho_p, ] for i in range(nt-1): constraints += [ # Decreasing fuel self.section.A_p_out[:, i] == self.section.A_p_in[:, i+1], # Decreasing sectional area self.section.A_in[:,i] <= self.section.A_in[:,i+1], self.section.A_out[:,i] <= self.section.A_out[:,i+1], ] for i in range(nt): constraints += [ # Rocket length is section length, self.section.radius[i] == r, self.section.l[i] == l, # Matching nozzle and section conditions self.nozzlePerformance.mdot[i] == self.section.mdot_out[i], self.nozzlePerformance.T_t[i] == self.section.T_t_out[i], # Maximum chamber pressure self.section.P_chamb[:, i] <= P_max, self.nozzlePerformance.P_star[i] <= P_max, ] with SignomialsEnabled(): constraints += [ # Matching nozzle stagnation pressure Tight([self.nozzlePerformance.P_t[i] <= s[i]*(self.section.P_out[i] + 0.5*self.section.rho_out[i]*self.section.u_out[i]**2)], name='PtNozzle', printwarning=True), s[i]*self.nozzlePerformance.P_t[i] >= self.section.P_out[i] + 0.5*self.section.rho_out[i]*self.section.u_out[i]**2, s[i] >= 1 ] return constraints, self.nozzle, self.nozzlePerformance, self.section
def setup(self, static, state): exec parse_variables(TailBoomAero.__doc__) l = self.l = static.l rho = self.rho = state.rho V = self.V = state.V mu = self.mu = state.mu return [Re == V*rho*l/mu, Cf >= 0.455/Re**0.3, ]
def setup(self, N=5): self.N = N exec parse_variables(TailBoom.__doc__) self.spar = super(TailBoom, self).setup(N, self) if self.secondaryWeight: self.weight.right += rhoA * g * S d0 = self.d0 = self.d[0] return self.spar, [S == l * pi * d0, b == 2 * l]
def setup(self): exec parse_variables(Aircraft.__doc__) self.fuse = Fuselage() self.wing = Wing() self.components = [self.fuse, self.wing] return { "definition of W": W >= sum(c.W for c in self.components), "components": self.components}
def setup(self): exec parse_variables(BoundsChecking.__doc__) self.cost = F return [ F >= D + T, D == rf*V**2*Ap, Ap == nu, T == mf*V, mf >= mi + mb, mf == rf*V, Fs <= mi ]
def setup(self, N=3): exec parse_variables(VerticalTail.__doc__) self.ascs = Wing.setup(self, N) self.planform.substitutions.update( {self.planform.tau: 0.08, self.planform.lam: 0.8, self.planform.AR: 4}) if self.fillModel: self.foam.substitutions.update({self.foam.Abar: 0.0548, self.foam.material.rho: 0.024}) return self.ascs
def setup(self, static, state): exec parse_variables(PropulsorPerf.__doc__) self.prop = static.prop.flight_model(static.prop, state) self.motor = static.motor.flight_model(static.motor, state) self.components = [self.prop, self.motor] constraints = [self.prop.Q == self.motor.Q, self.prop.omega == self.motor.omega ] return constraints, self.components
def setup(self, N, surface): exec parse_variables(BoxSpar.__doc__) self.boxspar = BoxSparGP.setup(self, N=N, surface=surface) cave = self.cave tau = self.tau w = self.w tshear = self.tshear with SignomialsEnabled(): constraints = [J <= cave * tau * w * tshear / 3 * (cave * tau + w)] return self.boxspar, constraints
def setup(self, surface): exec parse_variables(WingSkin.__doc__) croot = self.croot = surface.croot S = self.S = surface.S rho = self.material.rho tau = self.material.tau tmin = self.material.tmin return [ W >= rho * surface.S * 2 * t * g, t >= tmin, tau >= 1 / Jtbar / croot**2 / t * Cmw * S * rhosl * Vne**2 ]
def setup(self, wing, state): self.wing = wing self.state = state exec parse_variables(WingAero.__doc__) c = wing.c A = wing.A S = wing.S rho = state.rho V = state.V mu = state.mu return { "drag model": CD >= 0.074/Re**0.2 + CL**2/np.pi/A/e, "definition of Re": Re == rho*V*c/mu, "definition of D": D >= 0.5*rho*V**2*CD*S}
def setup(self, aircraft, state): self.aircraft = aircraft self.state = state exec parse_variables(AircraftP.__doc__) self.wing_aero = aircraft.wing.dynamic(aircraft.wing, state) self.perf_models = [self.wing_aero] W = aircraft.W S = aircraft.wing.S V = state.V rho = state.rho D = self.wing_aero.D CL = self.wing_aero.CL return { "lift": W + Wfuel <= 0.5*rho*CL*S*V**2, "fuel burn rate": Wburn >= 0.1*D, "performance": self.perf_models}
def setup(self): exec parse_variables(FlightState.__doc__)
def setup(self): exec parse_variables(Fuselage.__doc__)
def setup(self): exec parse_variables(Wing.__doc__) return {"parametrization of wing weight": W >= S*rho, "definition of mean chord": c == (S/A)**0.5}
def setup(self): exec parse_variables(Cube.__doc__) return [A >= 2*(s[0]*s[1] + s[1]*s[2] + s[2]*s[0]), s.prod() >= V, s[2] >= h]
Variables of length 3 --------------------- s [m] side length Let's introduce more variables: (any line ending in "Variables" is parsed) Zoning Variables ---------------- h 1 [m] minimum height Upper Unbounded --------------- A The ordering of these blocks doesn't affect anything; order them in the way that makes the most sense to someone else reading your model. """ def setup(self): exec parse_variables(Cube.__doc__) return [A >= 2*(s[0]*s[1] + s[1]*s[2] + s[2]*s[0]), s.prod() >= V, s[2] >= h] print parse_variables(Cube.__doc__) c = Cube() c.cost = c.A print c.solve(verbosity=0).table()
def setup(self): exec parse_variables(Box.__doc__) return [V == h*w*d]