def test_sigeq(self): x = Variable("x") y = VectorVariable(1, "y") c = Variable("c") # test left vector input to sigeq with SignomialsEnabled(): m = Model(c, [ c >= (x + 0.25)**2 + (y - 0.5)**2, SignomialEquality(x**2 + x, y) ]) sol = m.localsolve(solver=self.solver, verbosity=0, mutategp=False) self.assertAlmostEqual(sol("x"), 0.1639472, self.ndig) self.assertAlmostEqual(sol("y")[0], 0.1908254, self.ndig) self.assertAlmostEqual(sol("c"), 0.2669448, self.ndig) # test right vector input to sigeq with SignomialsEnabled(): m = Model(c, [ c >= (x + 0.25)**2 + (y - 0.5)**2, SignomialEquality(y, x**2 + x) ]) sol = m.localsolve(solver=self.solver, verbosity=0) self.assertAlmostEqual(sol("x"), 0.1639472, self.ndig) self.assertAlmostEqual(sol("y")[0], 0.1908254, self.ndig) self.assertAlmostEqual(sol("c"), 0.2669448, self.ndig) # test scalar input to sigeq y = Variable("y") with SignomialsEnabled(): m = Model(c, [ c >= (x + 0.25)**2 + (y - 0.5)**2, SignomialEquality(x**2 + x, y) ]) sol = m.localsolve(solver=self.solver, verbosity=0) self.assertAlmostEqual(sol("x"), 0.1639472, self.ndig) self.assertAlmostEqual(sol("y"), 0.1908254, self.ndig) self.assertAlmostEqual(sol("c"), 0.2669448, self.ndig)
def test_sp_substitutions(self): x = Variable("x") y = Variable("y", 1) z = Variable("z", 4) from io import StringIO old_stdout = sys.stdout sys.stdout = stringout = StringIO() with SignomialsEnabled(): m1 = Model(x, [x + z >= y]) with self.assertRaises(UnnecessarySGP): m1.localsolve(verbosity=0, solver=self.solver) with self.assertRaises(UnboundedGP): m1.solve(verbosity=0, solver=self.solver) with SignomialsEnabled(): m2 = Model(x, [x + y >= z]) m2.substitutions[y] = 1 m2.substitutions[z] = 4 sol = m2.solve(self.solver, verbosity=0) self.assertAlmostEqual(sol["cost"], 3, self.ndig) sys.stdout = old_stdout self.assertEqual( stringout.getvalue(), ("Warning: SignomialConstraint %s became the tautological" " constraint 0 <= 3 + x after substitution.\n" "Warning: SignomialConstraint %s became the tautological" " constraint 0 <= 3 + x after substitution.\n" % (str(m1[0]), str(m1[0]))))
def test_sp_relaxation(self): w = Variable("w") x = Variable("x") y = Variable("y") z = Variable("z") with SignomialsEnabled(): m = Model(x, [x + y >= w, x + y <= z / 2, y <= x, y >= 1], { z: 3, w: 3 }) r1 = ConstantsRelaxed(m) self.assertEqual(len(r1.varkeys), 8) with self.assertRaises(ValueError): _ = Model(x * r1.relaxvars, r1) # no "prod" sp = Model(x * r1.relaxvars.prod()**10, r1).sp(use_pccp=False) cost = sp.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost / 1024, 1, self.ndig) m.debug(verbosity=0, solver=self.solver) with SignomialsEnabled(): m = Model(x, [x + y >= z, x + y <= z / 2, y <= x, y >= 1], {z: 3}) m.debug(verbosity=0, solver=self.solver) r2 = ConstraintsRelaxed(m) self.assertEqual(len(r2.varkeys), 7) sp = Model(x * r2.relaxvars.prod()**10, r2).sp(use_pccp=False) cost = sp.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost / 1024, 1, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= z, x + y <= z / 2, y <= x, y >= 1], {z: 3}) m.debug(verbosity=0, solver=self.solver) r3 = ConstraintsRelaxedEqually(m) self.assertEqual(len(r3.varkeys), 4) sp = Model(x * r3.relaxvar**10, r3).sp(use_pccp=False) cost = sp.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost / (32 * 0.8786796585), 1, self.ndig)
def test_sp_bounded(self): x = Variable("x") y = Variable("y") with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.1]) # solves cost = m.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost, 0.9, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= 1]) # dual infeasible with self.assertRaises(UnboundedGP): m.localsolve(verbosity=0, solver=self.solver) gp = m.sp(checkbounds=False).gp() self.assertRaises(DualInfeasible, gp.solve, solver=self.solver, verbosity=0) with SignomialsEnabled(): m = Model(x, Bounded([x + y >= 1], verbosity=0)) sol = m.localsolve(verbosity=0, solver=self.solver) boundedness = sol["boundedness"] # depends on solver, platform, whims of the numerical deities if "value near lower bound" in boundedness: # pragma: no cover self.assertIn(x.key, boundedness["value near lower bound"]) else: # pragma: no cover self.assertIn(y.key, boundedness["value near upper bound"])
def test_trivial_sp2(self): x = Variable("x") y = Variable("y") # converging from above with SignomialsEnabled(): constraints = [y + x >= 2, y >= x] objective = y x0 = 1 y0 = 2 m = Model(objective, constraints) sol1 = m.localsolve(x0={x: x0, y: y0}, verbosity=0, solver=self.solver) # converging from right with SignomialsEnabled(): constraints = [y + x >= 2, y <= x] objective = x x0 = 2 y0 = 1 m = Model(objective, constraints) sol2 = m.localsolve(x0={x: x0, y: y0}, verbosity=0, solver=self.solver) self.assertAlmostEqual(sol1["variables"]["x"], sol2["variables"]["x"], self.ndig) self.assertAlmostEqual(sol1["variables"]["y"], sol2["variables"]["x"], self.ndig)
def test_sp_bounded(self): x = Variable("x") y = Variable("y") with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.1]) # solves cost = m.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost, 0.9, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= 1]) # dual infeasible with self.assertRaises(UnboundedGP): m.localsolve(verbosity=0, solver=self.solver) gp = m.sp(allow_missingbounds=True).gp(allow_missingbounds=True) self.assertRaises(DualInfeasible, gp.solve, solver=self.solver, verbosity=0) with SignomialsEnabled(): m = Model(x, Bounded([x + y >= 1], verbosity=0)) sol = m.localsolve(verbosity=0, solver=self.solver) boundedness = sol["boundedness"] if "value near lower bound" in boundedness: self.assertIn(x.key, boundedness["value near lower bound"]) if "value near upper bound" in boundedness: self.assertIn(y.key, boundedness["value near upper bound"])
def test_sp_substitutions(self): x = Variable('x') y = Variable('y', 1) z = Variable('z', 4) from io import StringIO old_stdout = sys.stdout sys.stdout = stringout = StringIO() with SignomialsEnabled(): m = Model(x, [x + z >= y]) with self.assertRaises(ValueError): m.localsolve(verbosity=0, solver=self.solver) with SignomialsEnabled(): m = Model(x, [x + y >= z]) m.substitutions[y] = 1 m.substitutions[z] = 4 sol = m.solve(self.solver, verbosity=0) self.assertAlmostEqual(sol["cost"], 3, self.ndig) sys.stdout = old_stdout self.assertEqual( stringout.getvalue(), ("Warning: SignomialConstraint x + z >= y became the tautological" " constraint 0 <= 3 + x after substitution.\n" "Warning: SignomialConstraint x + z >= y became the tautological" " constraint 0 <= 3 + x after substitution.\n"))
def test_sp_relaxation(self): w = Variable('w') x = Variable('x') y = Variable('y') z = Variable('z') with SignomialsEnabled(): m = Model(x, [x+y >= w, x+y <= z/2, y <= x, y >= 1], {z: 3, w: 3}) r1 = ConstantsRelaxed(m) self.assertEqual(len(r1.varkeys), 8) with self.assertRaises(ValueError): mr1 = Model(x*r1.relaxvars, r1) # no 'prod' mr1 = Model(x*r1.relaxvars.prod()**10, r1) cost1 = mr1.localsolve(verbosity=0)["cost"] self.assertAlmostEqual(cost1/1024, 1, self.ndig) m.debug(verbosity=0) with SignomialsEnabled(): m = Model(x, [x+y >= z, x+y <= z/2, y <= x, y >= 1], {z: 3}) if self.solver != "cvxopt": m.debug(verbosity=0) r2 = ConstraintsRelaxed(m) self.assertEqual(len(r2.varkeys), 7) mr2 = Model(x*r2.relaxvars.prod()**10, r2) cost2 = mr2.localsolve(verbosity=0)["cost"] self.assertAlmostEqual(cost2/1024, 1, self.ndig) with SignomialsEnabled(): m = Model(x, [x+y >= z, x+y <= z/2, y <= x, y >= 1], {z: 3}) if self.solver != "cvxopt": m.debug(verbosity=0) r3 = ConstraintsRelaxedEqually(m) self.assertEqual(len(r3.varkeys), 4) mr3 = Model(x*r3.relaxvar**10, r3) cost3 = mr3.localsolve(verbosity=0)["cost"] self.assertAlmostEqual(cost3/(32*0.8786796585), 1, self.ndig)
def test_chop(self): "Test Signomial deconstruction" x = Variable('x') y = Variable('y') with SignomialsEnabled(): c = x + 5. * y**2 - 0.2 * x * y**0.78 monomials = c.chop() with self.assertRaises(InvalidPosynomial): c.chop() with SignomialsEnabled(): self.assertIn(-0.2 * x * y**0.78, monomials)
def test_trivial_sp(self): x = Variable('x') y = Variable('y') with SignomialsEnabled(): m = Model(x, [x >= 1 - y, y <= 0.1]) sol = m.localsolve(verbosity=0, solver=self.solver) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.1]) sol = m.localsolve(verbosity=0, solver=self.solver) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig)
def test_trivial_sp(self): x = Variable('x') y = Variable('y') with SignomialsEnabled(): m = Model(x, [x >= 1 - y, y <= 0.1]) with self.assertRaises(InvalidGPConstraint): m.solve(verbosity=0) sol = m.localsolve(self.solver, verbosity=0) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.1]) sol = m.localsolve(self.solver, verbosity=0) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig)
def test_sp_substitutions(self): x = Variable('x') y = Variable('y', 1) z = Variable('z', 4) with self.assertRaises(ValueError): with SignomialsEnabled(): m = Model(x, [x + z >= y]) m.localsolve() with SignomialsEnabled(): m = Model(x, [x + y >= z]) self.assertAlmostEqual(m.solve(self.solver, verbosity=0)["cost"], 3)
def test_trivial_sp(self): x = Variable('x') y = Variable('y') with SignomialsEnabled(): m = Model(x, [x >= 1 - y, y <= 0.1]) with self.assertRaises(ValueError): # solve should catch the TypeError raised by an SP constraints # and raise its own ValueError instead m.solve(verbosity=0) sol = m.localsolve(self.solver, verbosity=0) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.1]) sol = m.localsolve(self.solver, verbosity=0) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig)
def setup(self, N): edgeCost = VectorVariable([N, N], 'edgeCost') edgeMaxFlow = VectorVariable([N, N], 'edgeMaxFlow') connect = VectorVariable([N, N], 'connectivity') flow = VectorVariable([N, N], 'flow') source = VectorVariable(N, 'source') sink = VectorVariable(N, 'sink') totalCost = Variable('totalCost') constraints = [] with SignomialsEnabled(): for i in range(0, N): constraints.extend([ sink[i] + sum(flow[i, :]) <= source[i] + sum(flow[:, i]), ]) for j in range(0, N): constraints.extend( [flow[i, j] <= connect[i, j] * edgeMaxFlow[i, j]]) for i in range(0, N): for j in range(i + 1, N): constraints.extend([flow[i, j] * flow[j, i] <= 1e-5]) constraints.extend([totalCost >= sum(edgeCost * flow)]) return constraints
def test_tautological(self): x = Variable('x') y = Variable('y') z = Variable('z') from io import StringIO old_stdout = sys.stdout sys.stdout = stringout = StringIO() with SignomialsEnabled(): m1 = Model(x, [x + y >= z, x >= y]) m2 = Model(x, [x + 1 >= 0, x >= y]) m1.substitutions.update({'z': 0, 'y': 1}) m2.substitutions.update({'y': 1}) self.assertAlmostEqual( m1.solve(self.solver, verbosity=0)["cost"], m2.solve(self.solver, verbosity=0)["cost"]) sys.stdout = old_stdout self.assertEqual( stringout.getvalue(), ("Warning: SignomialConstraint x + y >= z became the tautological" " constraint 0 <= 1 + x after substitution.\n" "Warning: SignomialConstraint x + 1 >= 0 became the tautological" " constraint 0 <= 1 + x after substitution.\n"))
def setup(self): self.engine = Engine() self.wing = Wing() self.fuse = Fuselage() self.components = [self.engine, self.wing, self.fuse] # Environmental constants g = Variable("g", 9.81, "m/s^2", "gravitational acceleration") rho_f = Variable("\\rho_f", 817, "kg/m^3", "density of fuel") # Free Variables W = Variable("W", "N", "maximum takeoff weight") W_f = Variable("W_f", "N", "maximum fuel weight") V_f = Variable("V_f", "m^3", "maximum fuel volume") V_f_avail = Variable("V_{f_{avail}}", "m^3", "fuel volume available") constraints = [] # Thrust and drag model constraints += [ self.fuse['C_{D_{fuse}}'] == self.fuse['(CDA0)'] / self.wing['S'] ] # Fuel volume model with SignomialsEnabled(): constraints += [ V_f == W_f / g / rho_f, V_f_avail <= self.wing['V_{f_{wing}}'] + self.fuse['V_{f_{fuse}}'], #[SP] V_f_avail >= V_f ] return constraints, 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, engine, state): self.engine = engine # Dimensional constants # Free variables BSFC = Variable("BSFC", "lbf/(hp*hr)", "brake specific fuel consumption") P_shaft = Variable("P_{shaft}", "kW", "shaft power") P_shaft_alt = Variable("P_{shaft,alt}", "kW", 'maximum shaft power at altitude') Thrust = Variable("T", "N", "propeller thrust") L = Variable("L", "-", "power lapse percentage") constraints = [] with SignomialsEnabled(): constraints += [ P_shaft <= P_shaft_alt, L == (0.937 * (state['h'] / self.engine['h_{ref}'])**0.0922)**10, SignomialEquality( 1, L + P_shaft_alt / self.engine['P_{shaft,max}']), (BSFC / self.engine['BSFC_{ref}'])**(0.1) >= 0.984 * (P_shaft / P_shaft_alt)**-0.0346, BSFC / self.engine['BSFC_{ref}'] >= 1., ] return constraints
def setup(self): self.HTns = HorizontalTailNoStruct() self.wb = WingBox(self.HTns, "horizontal_tail") #HT system weight variable Wht = Variable('W_{ht}', 'N', 'HT System Weight') fht = Variable('f_{ht}' ,'-', 'Rudder etc. fractional weight') #margin and sensitivity Cht = Variable('C_{ht}', 1, '-', 'HT Weight Margin and Sensitivity Factor') #variables only used for the TASOPT tail drag formulation cdfh = Variable('c_{d_{fh}}', '-', 'VT friction drag coefficient') cdph = Variable('c_{d_{ph}}', '-', 'VT pressure drag coefficient') coslamcube = Variable('\\cos(\\Lambda_{ht})^3', '-', 'Cosine of tail sweep cubed') constraints = [] with SignomialsEnabled(): constraints.append([ self.wb['L_{ht_{rect}}'] >= self.HTns['L_{ht_{max}}']/2.*self.HTns['c_{tip_{ht}}']*self.HTns['b_{ht}']/self.HTns['S_{ht}'], self.wb['L_{ht_{tri}}'] >= self.HTns['L_{ht_{max}}']/4.*(1-self.wb['taper'])*self.HTns['c_{root_{ht}}']*self.HTns['b_{ht}']/self.HTns['S_{ht}'], #[SP] Wht >= Cht*(self.wb['W_{struct}'] + self.wb['W_{struct}'] * fht), ]) return self.HTns, self.wb, constraints
def test_tiny_sp_1(self): """ A signomial inequality constraint. """ from gpkit import Variable, Model, SignomialsEnabled # # Build GPKit model # x = Variable('x') y = Variable('y') with SignomialsEnabled(): constraints = [x >= 1 - y, y <= 0.5] gpkm = Model(x, constraints) # # Recover data for a sageopt model # som = gpkit_model_to_sageopt_model(gpkm) f = som['f'] gp_ineqs = som['gp_gts'] X = infer_domain(f, gp_ineqs, []) sp_ineqs = som['sp_gts'] prob = sig_constrained_relaxation(f, sp_ineqs, [], X) # # Solve the sageopt model and check optimality # prob.solve(solver='ECOS', verbose=False) self.assertAlmostEqual(prob.value, 0.5, places=3) soln = sig_solrec(prob)[0] soln = local_refine(f, sp_ineqs + gp_ineqs, [], x0=soln) self.assertAlmostEqual(f(soln), 0.5, places=3) pass
def setup(self, **kwargs): self.wns = WingNoStruct() self.wb = WingBox(self.wns, "wing") Wwing = Variable('W_{wing}', 'N', 'Wing System Weight') Cwing = Variable('C_{wing}', 1, '-', 'Wing Weight Margin and Sensitivity Factor') # w.r.t. the quarter chord of the root of the wing. dxACwing = Variable('\\Delta x_{AC_{wing}}','m','Wing Aerodynamic Center Shift') #wing induced drag reduction due to wing tip devices TipReduct = Variable('TipReduct', '-', 'Induced Drag Reduction Factor from Wing Tip Devices') constraints = [] with SignomialsEnabled(): constraints.extend([ self.wns['\\lambda'] == self.wb['taper'], TCS([Wwing >= Cwing * self.wb['W_{struct}'] + self.wb['W_{struct}']*(self.wns['f_{flap}'] + \ self.wns['f_{slat}'] + self.wns['f_{aileron}'] + self.wns['f_{lete}'] + self.wns['f_{ribs}'] + \ self.wns['f_{spoiler}'] + self.wns['f_{watt}'])]), TCS([dxACwing <= 1./24.*(self.wns['c_{root}'] + 5.*self.wns['c_{tip}'])/self.wns['S'] \ *self.wns['b']**2*self.wns['\\tan(\\Lambda)']]), ]) return self.wns, self.wb, constraints
def test_sp_initial_guess_sub(self): x = Variable("x") y = Variable("y") x0 = 1 y0 = 2 with SignomialsEnabled(): constraints = [y + x >= 2, y <= x] objective = x m = Model(objective, constraints) try: sol = m.localsolve(x0={x: x0, y: y0}, verbosity=0, solver=self.solver) except TypeError: self.fail("Call to local solve with only variables failed") self.assertAlmostEqual(sol(x), 1, self.ndig) self.assertAlmostEqual(sol["cost"], 1, self.ndig) try: sol = m.localsolve(x0={"x": x0, "y": y0}, verbosity=0, solver=self.solver) except TypeError: self.fail("Call to local solve with only variable strings failed") self.assertAlmostEqual(sol("x"), 1, self.ndig) self.assertAlmostEqual(sol["cost"], 1, self.ndig) try: sol = m.localsolve(x0={"x": x0, y: y0}, verbosity=0, solver=self.solver) except TypeError: self.fail("Call to local solve with a mix of variable strings " "and variables failed") self.assertAlmostEqual(sol["cost"], 1, self.ndig)
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, N): edgeCost = VectorVariable([N, N], 'edgeCost') edgeMaxFlow = VectorVariable([N, N], 'edgeMaxFlow') slackCost = Variable('slackCost', 1000) connect = VectorVariable([N, N], 'connectivity') flow = VectorVariable([N, N], 'flow') source = VectorVariable(N, 'source') sink = VectorVariable(N, 'sink') slack = VectorVariable(N, 'slack') constraints = [] with SignomialsEnabled(): for i in range(0, N): constraints.extend([ Tight([ sink[i] + sum(flow[i, :]) <= slack[i] * (source[i] + sum(flow[:, i])) ]), Tight([slack[i] >= 1]) ]) for j in range(0, N): constraints += [ flow[i, j] <= connect[i, j] * edgeMaxFlow[i, j], connect[i, j] <= 1., flow[i, j] >= 1e-20 ] for i in range(0, N): for j in range(i + 1, N): constraints.extend( [connect[i, j] * connect[j, i] <= 1e-20]) return constraints
def setup(self, ht, state, fitDrag): self.HT = ht #variables D = Variable('D_{ht}', 'N', 'Horizontal tail drag') Lh = Variable('L_{ht}', 'N', 'Horizontal tail downforce') Rec = Variable('Re_{c_h}', '-', 'Cruise Reynolds number (Horizontal tail)') CLah = Variable('C_{L_{\\alpha,ht}}', '-', 'Lift curve slope (htail)') CLah0 = Variable('C_{L_{\\alpha,ht_0}}', '-', 'Isolated lift curve slope (htail)') CLh = Variable('C_{L_{ht}}', '-', 'Lift coefficient (htail)') CDh = Variable('C_{D_{ht}}', '-', 'Horizontal tail drag coefficient') CD0h = Variable('C_{D_{0,ht}}', '-', 'Horizontal tail parasitic drag coefficient') alphah = Variable('\\alpha_{ht}', '-', 'Horizontal tail angle of attack') constraints = [] with SignomialsEnabled(): constraints.extend([ Lh == 0.5*state['\\rho']*state['V']**2*self.HT['S_{ht}']*CLh, # Angle of attack and lift slope constraints CLh == CLah*alphah, alphah <= self.HT['\\alpha_{ht,max}'], # Currently using TAT to approximate CLah0 == 2*3.14, # Drag D == 0.5*state['\\rho']*state['V']**2*self.HT['S_{ht}']*CDh, CDh >= CD0h + CLh**2/(pi*self.HT['e_{ht}']*self.HT['AR_{ht}']), #cruise Reynolds number Rec == state['\\rho']*state['V']*self.HT['\\bar{c}_{ht}']/state['\\mu'], ]) if fitDrag: constraints.extend([ #Martin's TASOPT tail drag fit CD0h**6.48983 >= (5.28751e-20 * (Rec)**0.900672 * (self.HT['\\tau_{ht}'])**0.912222 * (state['M'])**8.64547 + 1.67605e-28 * (Rec)**0.350958 * (self.HT['\\tau_{ht}'])**6.29187 * (state['M'])**10.2559 + 7.09757e-25 * (Rec)**1.39489 * (self.HT['\\tau_{ht}'])**1.96239 * (state['M'])**0.567066 + 3.73076e-14 * (Rec)**-2.57406 * (self.HT['\\tau_{ht}'])**3.12793 * (state['M'])**0.448159 + 1.44343e-12 * (Rec)**-3.91046 * (self.HT['\\tau_{ht}'])**4.66279 * (state['M'])**7.68852) #Philippe thesis drag fit ## CD0h**0.125 >= 0.19*(self.HT['\\tau_{ht}'])**0.0075 *(Rec)**0.0017 ## + 1.83e+04*(self.HT['\\tau_{ht}'])**3.54*(Rec)**-0.494 ## + 0.118*(self.HT['\\tau_{ht}'])**0.0082 *(Rec)**0.00165 ## + 0.198*(self.HT['\\tau_{ht}'])**0.00774*(Rec)**0.00168, ]) else: #HT drag constraints in AircraftP None return constraints
def test_sigs_not_allowed_in_cost(self): with SignomialsEnabled(): x = Variable('x') y = Variable('y') J = 0.01 * ((x - 1)**2 + (y - 1)**2) + (x * y - 1)**2 m = Model(J) with self.assertRaises(TypeError): m.localsolve(verbosity=0)
def test_init(self): "Test initialization and types" D = Variable('D', units="N") x1, x2, x3 = (Variable("x_%s" % i, units="N") for i in range(3)) with SignomialsEnabled(): sc = (D >= x1 + x2 - x3) self.assertTrue(isinstance(sc, SignomialInequality)) self.assertFalse(isinstance(sc, Posynomial))
def setup(self): x = Variable("x") y = Variable("y", 2.) z = Variable("z") with SignomialsEnabled(): constraints = [z <= x**2 + y, x * z == 2] self.cost = 1 / z return constraints
def test_posyslt1(self): x = Variable("x") y = Variable("y") with SignomialsEnabled(): sc = (x + y >= x * y) # make sure that the error type doesn't change on our users with self.assertRaises(InvalidGPConstraint): _ = sc.as_posyslt1()
def test_zeroing(self): L = Variable("L") k = Variable("k", 0) with SignomialsEnabled(): constr = [L - 5 * k <= 10] sol = Model(1 / L, constr).solve(self.solver, verbosity=0) self.assertAlmostEqual(sol(L), 10, self.ndig) self.assertAlmostEqual(sol["cost"], 0.1, self.ndig)