|
5 | 5 | from os import sep
|
6 | 6 | from numpy import hstack
|
7 | 7 | import pandas as pd
|
8 |
| -import numpy as np |
9 | 8 | import gassolar.environment
|
10 | 9 | from ad.admath import exp
|
11 | 10 | from gassolar.environment.solar_irradiance import get_Eirr, twi_fits
|
12 | 11 | from gassolar.environment.wind_speeds import get_month
|
13 |
| -from gpkit import Model, parse_variables, Vectorize, Variable |
| 12 | +from gpkit import Model, parse_variables, Vectorize, SignomialsEnabled |
14 | 13 | from gpkit.tests.helpers import StdoutCaptured
|
15 | 14 | from gpkitmodels.GP.aircraft.wing.wing import Wing as WingGP
|
16 | 15 | from gpkitmodels.SP.aircraft.wing.wing import Wing as WingSP
|
17 |
| -from gpkitmodels.GP.aircraft.wing.boxspar import BoxSpar |
| 16 | +from gpkitmodels.GP.aircraft.wing.boxspar import BoxSpar as BoxSparGP |
| 17 | +from gpkitmodels.SP.aircraft.wing.boxspar import BoxSpar as BoxSparSP |
18 | 18 | from gpkitmodels.GP.aircraft.wing.wing_skin import WingSecondStruct
|
19 | 19 | from gpkitmodels.GP.aircraft.tail.empennage import Empennage
|
20 | 20 | from gpkitmodels.GP.aircraft.tail.horizontal_tail import HorizontalTail
|
|
28 | 28 | from gpkitmodels.GP.aircraft.motor.motor import Motor
|
29 | 29 | from gpkitmodels import g
|
30 | 30 | from gpfit.fit_constraintset import FitCS as FCS
|
| 31 | +from relaxed_constants import relaxed_constants, post_process |
31 | 32 |
|
32 | 33 | path = dirname(gassolar.environment.__file__)
|
33 | 34 |
|
@@ -122,7 +123,7 @@ def setup(self, static, state, onDesign = False):
|
122 | 123 |
|
123 | 124 | self.wing.substitutions[e] = 0.95
|
124 | 125 | self.wing.substitutions[self.wing.CLstall] = 4
|
125 |
| - |
| 126 | + |
126 | 127 | self.wing.substitutions[e] = 0.95
|
127 | 128 | dvars = [cdht*Sh/Sw, cdvt*Sv/Sw, cftb*Stb/Sw]
|
128 | 129 |
|
@@ -163,8 +164,8 @@ class Aircraft(Model):
|
163 | 164 | minvttau 0.09 [-] minimum vertical tail tau ratio
|
164 | 165 | minhttau 0.06 [-] minimum horizontal tail tau ratio
|
165 | 166 | maxtau 0.144 [-] maximum wing tau ratio
|
166 |
| - |
167 |
| - SKIP VERIFICATION |
| 167 | +
|
| 168 | + SKIP VERIFICATION |
168 | 169 |
|
169 | 170 | Upper Unbounded
|
170 | 171 | ---------------
|
@@ -210,27 +211,27 @@ def setup(self, Npod=0, sp=False):
|
210 | 211 | foamhd.substitutions.update({foamhd.rho: 0.03})
|
211 | 212 | materials = [cfrpud, cfrpfabric, foamhd]
|
212 | 213 |
|
213 |
| - HorizontalTail.sparModel = BoxSpar |
| 214 | + HorizontalTail.sparModel = BoxSparGP |
214 | 215 | HorizontalTail.fillModel = None
|
215 | 216 | HorizontalTail.skinModel = WingSecondStruct
|
216 |
| - VerticalTail.sparModel = BoxSpar |
| 217 | + VerticalTail.sparModel = BoxSparGP |
217 | 218 | VerticalTail.fillModel = None
|
218 | 219 | VerticalTail.skinModel = WingSecondStruct
|
219 |
| - TailBoom.__bases__ = (BoxSpar,) |
| 220 | + TailBoom.__bases__ = (BoxSparGP,) |
220 | 221 | TailBoom.secondaryWeight = True
|
221 | 222 | self.emp = Empennage(N=5)
|
222 | 223 | self.solarcells = SolarCells()
|
223 | 224 | self.battery = Battery()
|
224 | 225 | if sp:
|
225 |
| - WingSP.sparModel = BoxSpar |
| 226 | + WingSP.sparModel = BoxSparSP |
226 | 227 | WingSP.fillModel = None
|
227 | 228 | WingSP.skinModel = WingSecondStruct
|
228 |
| - self.wing = WingSP(N=10) |
| 229 | + self.wing = WingSP(N=20) |
229 | 230 | else:
|
230 |
| - WingGP.sparModel = BoxSpar |
| 231 | + WingGP.sparModel = BoxSparGP |
231 | 232 | WingGP.fillModel = None
|
232 | 233 | WingGP.skinModel = WingSecondStruct
|
233 |
| - self.wing = WingGP(N=10) |
| 234 | + self.wing = WingGP(N=20) |
234 | 235 | self.motor = Motor()
|
235 | 236 | Propeller.flight_model = ActuatorProp
|
236 | 237 | self.propeller = Propeller()
|
@@ -462,23 +463,20 @@ def setup(self, aircraft, latitude=35, day=355):
|
462 | 463 |
|
463 | 464 | self.aircraft = aircraft
|
464 | 465 | self.fs = FlightState(latitude=latitude, day=day)
|
465 |
| - self.aircraftPerf = self.aircraft.flight_model(aircraft, self.fs, True) |
| 466 | + self.aircraftPerf = self.aircraft.flight_model(aircraft, self.fs, False) |
466 | 467 | self.slf = SteadyLevelFlight(self.fs, self.aircraft,
|
467 | 468 | self.aircraftPerf)
|
468 | 469 |
|
469 |
| - if aircraft.Npod is not 0: |
470 |
| - if aircraft.Npod is not 1: |
471 |
| - assert self.aircraft.sp |
472 |
| - loadsp = self.aircraft.sp |
473 |
| - else: |
474 |
| - loadsp = False |
| 470 | + if aircraft.Npod is not 0 and aircraft.Npod is not 1: |
| 471 | + assert self.aircraft.sp |
| 472 | + loadsp = self.aircraft.sp |
475 | 473 | else:
|
476 | 474 | loadsp = False
|
477 | 475 |
|
478 | 476 | self.wingg = self.aircraft.wing.spar.loading(
|
479 |
| - self.aircraft.wing, self.fs, sp=loadsp) |
| 477 | + self.aircraft.wing, self.fs, out=loadsp) |
480 | 478 | self.winggust = self.aircraft.wing.spar.gustloading(
|
481 |
| - self.aircraft.wing, self.fs, sp=loadsp) |
| 479 | + self.aircraft.wing, self.fs, out=loadsp) |
482 | 480 | self.htailg = self.aircraft.emp.htail.spar.loading(
|
483 | 481 | self.aircraft.emp.htail, self.fs)
|
484 | 482 | self.vtailg = self.aircraft.emp.vtail.spar.loading(
|
@@ -524,17 +522,38 @@ def setup(self, aircraft, latitude=35, day=355):
|
524 | 522 | self.vtailg.W == qne*Sv*CLvmax,
|
525 | 523 | ]
|
526 | 524 |
|
527 |
| - if self.aircraft.Npod is not 0: |
528 |
| - if self.aircraft.Npod is not 1: |
529 |
| - z0 = Variable("z0", 1e-10, "N", "placeholder zero value") |
530 |
| - Nwing, Npod = self.aircraft.wing.N, self.aircraft.Npod |
531 |
| - ypod = Nwing/((Npod-1)/2 + 1) |
532 |
| - y0len = ypod-1 |
533 |
| - weight = self.aircraft.battery.W/Npod*self.wingg.Nsafety |
534 |
| - sout = np.hstack([[z0]*y0len + [weight]]*(Npod/2)) |
535 |
| - sout = list(sout) + [z0]*(Nwing - len(sout) - 1) |
536 |
| - constraints.extend([sout == self.wingg.Sout, |
537 |
| - sout == self.winggust.Sout]) |
| 525 | + if self.aircraft.Npod is not 0 and self.aircraft.Npod is not 1: |
| 526 | + Nwing, Npod = self.aircraft.wing.N, self.aircraft.Npod |
| 527 | + ypod = Nwing/((Npod-1)/2 + 1) |
| 528 | + ypods = [ypod*n for n in range(1, (Npod-1)/2+1)] |
| 529 | + Sgust, Mgust = self.winggust.S, self.winggust.M |
| 530 | + qgust, Sg, Mg = self.winggust.q, self.wingg.S, self.wingg.M |
| 531 | + qg = self.wingg.q |
| 532 | + deta = self.aircraft.wing.planform.deta |
| 533 | + b = self.aircraft.wing.planform.b |
| 534 | + weight = self.aircraft.battery.W/Npod*self.wingg.N |
| 535 | + for i in range(Nwing-1): |
| 536 | + if i in ypods: |
| 537 | + with SignomialsEnabled(): |
| 538 | + constraints.extend([ |
| 539 | + Sgust[i] >= (Sgust[i+1] + 0.5*deta[i]*(b/2) |
| 540 | + * (qgust[i] + qgust[i+1]) - weight), |
| 541 | + Sg[i] >= (Sg[i+1] + 0.5*deta[i]*(b/2) |
| 542 | + * (qg[i] + qg[i+1]) - weight), |
| 543 | + Mgust[i] >= (Mgust[i+1] + 0.5*deta[i]*(b/2) |
| 544 | + * (Sgust[i] + Sgust[i+1])), |
| 545 | + Mg[i] >= (Mg[i+1] + 0.5*deta[i]*(b/2) |
| 546 | + * (Sg[i] + Sg[i+1])) |
| 547 | + ]) |
| 548 | + else: |
| 549 | + constraints.extend([ |
| 550 | + Sgust[i] >= (Sgust[i+1] + 0.5*deta[i]*(b/2) |
| 551 | + * (qgust[i] + qgust[i+1])), |
| 552 | + Sg[i] >= Sg[i+1] + 0.5*deta[i]*(b/2)*(qg[i] + qg[i+1]), |
| 553 | + Mgust[i] >= (Mgust[i+1] + 0.5*deta[i]*(b/2) |
| 554 | + * (Sgust[i] + Sgust[i+1])), |
| 555 | + Mg[i] >= Mg[i+1] + 0.5*deta[i]*(b/2)*(Sg[i] + Sg[i+1]) |
| 556 | + ]) |
538 | 557 |
|
539 | 558 | self.submodels = [self.fs, self.aircraftPerf, self.slf, self.loading]
|
540 | 559 |
|
@@ -643,21 +662,31 @@ def setup(self, aircraft, latitude=range(1, 21, 1), day=355):
|
643 | 662 | def test():
|
644 | 663 | " test model for continuous integration "
|
645 | 664 | v = Aircraft(sp=False)
|
646 |
| - m = Mission(v, latitude=[15]) |
| 665 | + m = Mission(v, latitude=[20]) |
647 | 666 | m.cost = m[m.aircraft.Wtotal]
|
648 | 667 | m.solve()
|
649 | 668 | v = Aircraft(sp=True)
|
650 |
| - m = Mission(v, latitude=[15]) |
| 669 | + m = Mission(v, latitude=[20]) |
651 | 670 | m.cost = m[m.aircraft.Wtotal]
|
652 | 671 | m.localsolve()
|
653 |
| - v = Aircraft(Npod=5, sp=True) |
654 |
| - m = Mission(v, latitude=[15]) |
| 672 | + v = Aircraft(Npod=3, sp=True) |
| 673 | + m = Mission(v, latitude=[20]) |
655 | 674 | m.cost = m[m.aircraft.Wtotal]
|
656 |
| - m.localsolve() |
| 675 | + f = relaxed_constants(M) |
| 676 | + s = f.localsolve("mosek") |
| 677 | + post_process(s) |
657 | 678 |
|
658 | 679 | if __name__ == "__main__":
|
659 | 680 | SP = True
|
660 |
| - Vehicle = Aircraft(Npod=5, sp=SP) |
661 |
| - M = Mission(Vehicle, latitude=[15]) |
| 681 | + Vehicle = Aircraft(Npod=3, sp=SP) |
| 682 | + M = Mission(Vehicle, latitude=[20]) |
662 | 683 | M.cost = M[M.aircraft.Wtotal]
|
663 |
| - sol = (M.localsolve("mosek") if SP else M.solve("mosek")) |
| 684 | + try: |
| 685 | + sol = (M.localsolve("mosek") if SP else M.solve("mosek")) |
| 686 | + except RuntimeWarning: |
| 687 | + V2 = Aircraft(Npod=3, sp=SP) |
| 688 | + M2 = Mission(V2, latitude=[20]) |
| 689 | + M2.cost = M2[M2.aircraft.Wtotal] |
| 690 | + feas = relaxed_constants(M2) |
| 691 | + sol = feas.localsolve("mosek") |
| 692 | + vks = post_process(sol) |
0 commit comments