def setup(self, Nclimb1, Nclimb2, Ncruise, substitutions = None, **kwargs): eng = 0 # vectorize with Vectorize(Nclimb1 +Nclimb2 + Ncruise): enginestate = FlightState() #build the submodel ac = Aircraft(Nclimb1 + Nclimb2, Ncruise, enginestate, eng) #Vectorize with Vectorize(Nclimb1): climb1 = ClimbSegment(ac) #Vectorize with Vectorize(Nclimb2): climb2 = ClimbSegment(ac) with Vectorize(Ncruise): cruise = CruiseClimbSegment(ac) statelinking = StateLinking(climb1.state, climb2.state, cruise.state, enginestate, Nclimb1, Nclimb2, Ncruise) #declare new variables W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight') W_fclimb1 = Variable('W_{f_{climb1}}', 'N', 'Fuel Weight Burned in Climb 1') W_fclimb2 = Variable('W_{f_{climb2}}', 'N', 'Fuel Weight Burned in Climb 2') W_fcruise = Variable('W_{f_{cruise}}', 'N', 'Fuel Weight Burned in Cruise') W_total = Variable('W_{total}', 'N', 'Total Aircraft Weight') CruiseAlt = Variable('CruiseAlt', 'ft', 'Cruise Altitude [feet]') ReqRng = Variable('ReqRng', 'nautical_miles', 'Required Cruise Range') W_dry = Variable('W_{dry}', 'N', 'Aircraft Dry Weight') RCmin = Variable('RC_{min}', 'ft/min', 'Minimum allowed climb rate') dhftholdcl1 = Variable('dhftholdcl1', 'ft', 'Climb 1 Hold Variable') dhftholdcl2 = Variable('dhftholdcl2', 'ft', 'Climb 2 Hold Variable') dhftholdcr = Variable('dhftholdcr', 'ft', 'Cruise Hold Variable') h1 = climb1['h'] hftClimb1 = climb1['hft'] dhftcl1 = climb1['dhft'] h2 = climb2['h'] hftClimb2 = climb2['hft'] dhftcl2 = climb2['dhft'] dhftcr = cruise['dhft'] hftCruise = cruise['hft'] #make overall constraints constraints = [] with SignomialsEnabled(): constraints.extend([ #weight constraints TCS([ac['W_{e}'] + ac['W_{payload}'] + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_dry]), TCS([W_dry + W_ftotal <= W_total]), climb1['W_{start}'][0] == W_total, climb1['W_{end}'][-1] == climb2['W_{start}'][0], climb2['W_{end}'][-1] == cruise['W_{start}'][0], TCS([climb1['W_{start}'] >= climb1['W_{end}'] + climb1['W_{burn}']]), TCS([climb2['W_{start}'] >= climb2['W_{end}'] + climb2['W_{burn}']]), TCS([cruise['W_{start}'] >= cruise['W_{end}'] + cruise['W_{burn}']]), climb1['W_{start}'][1:] == climb1['W_{end}'][:-1], climb2['W_{start}'][1:] == climb2['W_{end}'][:-1], cruise['W_{start}'][1:] == cruise['W_{end}'][:-1], TCS([W_dry <= cruise['W_{end}'][-1]]), TCS([W_ftotal >= W_fclimb1 + W_fclimb2 + W_fcruise]), TCS([W_fclimb1 >= sum(climb1['W_{burn}'])]), TCS([W_fclimb2 >= sum(climb2['W_{burn}'])]), TCS([W_fcruise >= sum(cruise['W_{burn}'])]), #altitude constraints hftCruise[0] == CruiseAlt, ## TCS([hftCruise[1:Ncruise] >= hftCruise[:Ncruise-1] + dhftcr]), SignomialEquality(hftCruise[1:Ncruise], hftCruise[:Ncruise-1] + dhftholdcr), TCS([hftClimb2[1:Nclimb2] <= hftClimb2[:Nclimb2-1] + dhftholdcl2]), TCS([hftClimb2[0] <= dhftholdcl2 + 10000*units('ft')]), hftClimb2[-1] == hftCruise, TCS([hftClimb1[1:Nclimb1] >= hftClimb1[:Nclimb1-1] + dhftholdcl1]), TCS([hftClimb1[0] == dhftcl1[0]]), hftClimb1[-1] == 10000*units('ft'), #compute the dh2 dhftholdcl2 >= (hftCruise-10000*units('ft'))/Nclimb2, ## SignomialEquality(dhftholdcl2, (hftCruise-10000*units('ft'))/Nclimb2,), dhftholdcl2 == dhftcl2, #compute the dh1 dhftholdcl1 == 10000*units('ft')/Nclimb1, dhftholdcl1 == dhftcl1, dhftcr == dhftholdcr, sum(cruise['RngCruise']) + sum(climb2['RngClimb']) + sum(climb1['RngClimb']) >= ReqRng, #compute fuel burn from TSFC cruise['W_{burn}'] == ac['numeng']*ac.engine['TSFC'][Nclimb1 + Nclimb2:] * cruise['thr'] * ac.engine['F'][Nclimb1 + Nclimb2:], climb1['W_{burn}'] == ac['numeng']*ac.engine['TSFC'][:Nclimb1] * climb1['thr'] * ac.engine['F'][:Nclimb1], climb2['W_{burn}'] == ac['numeng']*ac.engine['TSFC'][Nclimb1:Nclimb1 + Nclimb2] * climb2['thr'] * ac.engine['F'][Nclimb1:Nclimb1 + Nclimb2], #min climb rate constraint ## climb1['RC'][0] >= RCmin, climb1['V'] <= 250*units('knots'), ]) M2 = .8 M25 = .6 M4a = .1025 Mexit = 1 M0 = .8 engineclimb1 = [ ac.engine.engineP['M_2'][:Nclimb1] == climb1['M'], ac.engine.engineP['M_{2.5}'] == M25, ac.engine.engineP['hold_{2}'] == 1+.5*(1.398-1)*M2**2, ac.engine.engineP['hold_{2.5}'] == 1+.5*(1.354-1)*M25**2, ac.engine.engineP['c1'] == 1+.5*(.401)*M0**2, #constraint on drag and thrust ac['numeng']*ac.engine['F_{spec}'][:Nclimb1] >= climb1['D'] + climb1['W_{avg}'] * climb1['\\theta'], #climb rate constraints TCS([climb1['excessP'] + climb1.state['V'] * climb1['D'] <= climb1.state['V'] * ac['numeng'] * ac.engine['F_{spec}'][:Nclimb1]]), ] M2 = .8 M25 = .6 M4a = .1025 Mexit = 1 M0 = .8 engineclimb2 = [ ac.engine.engineP['M_2'][Nclimb1:Nclimb1 + Nclimb2] == climb2['M'], #constraint on drag and thrust ac['numeng']*ac.engine['F_{spec}'][Nclimb1:Nclimb1 + Nclimb2] >= climb2['D'] + climb2['W_{avg}'] * climb2['\\theta'], #climb rate constraints TCS([climb2['excessP'] + climb2.state['V'] * climb2['D'] <= climb2.state['V'] * ac['numeng'] * ac.engine['F_{spec}'][Nclimb1:Nclimb1 + Nclimb2]]), ] M2 = .8 M25 = .6 M4a = .1025 Mexit = 1 M0 = .8 enginecruise = [ ac.engine.engineP['M_2'][Nclimb1 + Nclimb2:] == cruise['M'], ## cruise['M'] >= .7, #constraint on drag and thrust ac['numeng'] * ac.engine['F_{spec}'][Nclimb1 + Nclimb2:] >= cruise['D'] + cruise['W_{avg}'] * cruise['\\theta'], #climb rate constraints TCS([cruise['excessP'] + cruise.state['V'] * cruise['D'] <= cruise.state['V'] * ac['numeng'] * ac.engine['F_{spec}'][Nclimb1 + Nclimb2:]]), ] return constraints + ac + climb1 + climb2 + cruise + enginecruise + engineclimb1 + engineclimb2 + enginestate + statelinking
def setup(self, Nclimb, Ncruise, Nfleet, substitutions=None, **kwargs): eng = 0 #two level vectorization to make a fleet with Vectorize(Nfleet): # vectorize with Vectorize(Nclimb + Ncruise): enginestate = FlightState() ac = Aircraft(Nclimb, Ncruise, enginestate, eng, Nfleet) #two level vectorization to make a fleet with Vectorize(Nfleet): #Vectorize with Vectorize(Nclimb): climb = ClimbSegment(ac) with Vectorize(Ncruise): cruise = CruiseSegment(ac) statelinking = StateLinking(climb.state, cruise.state, enginestate, Nclimb, Ncruise) with Vectorize(Nfleet): #declare new variables W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight') W_fclimb = Variable('W_{f_{climb}}', 'N', 'Fuel Weight Burned in Climb') W_fcruise = Variable('W_{f_{cruise}}', 'N', 'Fuel Weight Burned in Cruise') W_total = Variable('W_{total}', 'N', 'Total Aircraft Weight') CruiseAlt = Variable('CruiseAlt', 'ft', 'Cruise Altitude [feet]') ReqRng = Variable('ReqRng', 'nautical_miles', 'Required Cruise Range') W_dry = Variable('W_{dry}', 'N', 'Aircraft Dry Weight') dhfthold = Variable('dhfthold', 'ft', 'Hold Variable') W_ffleet = Variable('W_{f_{fleet}}', 'N', 'Total Fleet Fuel Burn') h = climb['h'] hftClimb = climb['hft'] dhft = climb['dhft'] hftCruise = cruise['hft'] #make overall constraints constraints = [] constraints.extend([ #weight constraints TCS([ ac['W_{e}'] + ac['W_{payload}'] + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_dry ]), TCS([W_dry + W_ftotal <= W_total]), climb['W_{start}'][0] == W_total, climb['W_{end}'][-1] == cruise['W_{start}'][0], # similar constraint 1 TCS([climb['W_{start}'] >= climb['W_{end}'] + climb['W_{burn}']]), # similar constraint 2 TCS([ cruise['W_{start}'] >= cruise['W_{end}'] + cruise['W_{burn}'] ]), climb['W_{start}'][1:] == climb['W_{end}'][:-1], cruise['W_{start}'][1:] == cruise['W_{end}'][:-1], TCS([W_dry <= cruise['W_{end}'][-1]]), TCS([W_ftotal >= W_fclimb + W_fcruise]), TCS([W_fclimb >= sum(climb['W_{burn}'])]), TCS([W_fcruise >= sum(cruise['W_{burn}'])]), #altitude constraints hftCruise == CruiseAlt, TCS([ hftClimb[1:Nclimb] >= hftClimb[:Nclimb - 1] + dhft[:Nclimb - 1] ]), TCS([hftClimb[0] >= dhft[0]]), hftClimb[-1] <= hftCruise, #compute the dh dhfthold == hftCruise[0] / Nclimb, dhft == dhfthold, #set the range for each cruise segment, doesn't take credit for climb #down range disatnce covered cruise.cruiseP['Rng'] == ReqRng / (Ncruise), #compute fuel burn from TSFC cruise['W_{burn}'] == ac['numeng'] * ac.engine['TSFC'][Nclimb:] * cruise['thr'] * ac.engine['F'][Nclimb:], climb['W_{burn}'] == ac['numeng'] * ac.engine['TSFC'][:Nclimb] * climb['thr'] * ac.engine['F'][:Nclimb], CruiseAlt >= 30000 * units('ft'), #min climb rate constraint climb['RC'] >= 500 * units('ft/min'), ]) fleetfuel = [ #compute the fleet fuel burn W_ffleet >= .375 * W_ftotal[0] + .375 * W_ftotal[1] + .125 * W_ftotal[2] + .125 * W_ftotal[3], ] M2 = .8 M25 = .6 M4a = .1025 M0 = .8 engineclimb = [ ac.engine.engineP['M_2'][:Nclimb] == climb['M'], ac.engine.engineP['M_{2.5}'][:Nclimb] == M25, ac.engine.engineP['hold_{2}'] == 1 + .5 * (1.398 - 1) * M2**2, ac.engine.engineP['hold_{2.5}'] == 1 + .5 * (1.354 - 1) * M25**2, ac.engine.engineP['c1'] == 1 + .5 * (.401) * M0**2, #constraint on drag and thrust ac['numeng'] * ac.engine['F_{spec}'][:Nclimb] >= climb['D'] + climb['W_{avg}'] * climb['\\theta'], #climb rate constraints TCS([ climb['excessP'] + climb.state['V'] * climb['D'] <= climb.state['V'] * ac['numeng'] * ac.engine['F_{spec}'][:Nclimb] ]), ] M25 = .6 enginecruise = [ ac.engine.engineP['M_2'][Nclimb:] == cruise['M'], ac.engine.engineP['M_{2.5}'][Nclimb:] == M25, #steady level flight constraint on D cruise['D'] == ac['numeng'] * ac.engine['F_{spec}'][Nclimb:], #breguet range eqn TCS([ cruise['z_{bre}'] >= (ac.engine['TSFC'][Nclimb:] * cruise['thr'] * cruise['D']) / cruise['W_{avg}'] ]), ] ranges = [ ReqRng[0] == 500 * units('nautical_miles'), ReqRng[1] == 1000 * units('nautical_miles'), ReqRng[2] == 1500 * units('nautical_miles'), ReqRng[3] == 2000 * units('nautical_miles'), ] return constraints + ac + climb + cruise + enginecruise + engineclimb + enginestate + statelinking + ranges + fleetfuel
def setup(self, Nclimb, Ncruise, substitutions=None, **kwargs): eng = 0 # vectorize with Vectorize(Nclimb + Ncruise): enginestate = FlightState() #build the submodel ac = Aircraft(Nclimb, Ncruise, enginestate, eng) #Vectorize with Vectorize(Nclimb): climb = ClimbSegment(ac) with Vectorize(Ncruise): cruise = CruiseClimbSegment(ac) statelinking = StateLinking(climb.state, cruise.state, enginestate, Nclimb, Ncruise) #declare new variables W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight') W_fclimb = Variable('W_{f_{climb}}', 'N', 'Fuel Weight Burned in Climb') W_fcruise = Variable('W_{f_{cruise}}', 'N', 'Fuel Weight Burned in Cruise') W_total = Variable('W_{total}', 'N', 'Total Aircraft Weight') CruiseAlt = Variable('CruiseAlt', 'ft', 'Cruise Altitude [feet]') ReqRng = Variable('ReqRng', 'nautical_miles', 'Required Cruise Range') W_dry = Variable('W_{dry}', 'N', 'Aircraft Dry Weight') dhftholdcl = Variable('dhftholdcl', 'ft', 'Climb Hold Variable') dhftholdcr = Variable('dhftholdcr', 'ft', 'Cruise Hold Variable') RCmin = Variable('RC_{min}', 'ft/min', 'Minimum allowed climb rate') h = climb['h'] hftClimb = climb['hft'] dhftcl = climb['dhft'] dhftcr = cruise['dhft'] hftCruise = cruise['hft'] #make overall constraints constraints = [] with SignomialsEnabled(): constraints.extend([ #weight constraints TCS([ ac['W_{e}'] + ac['W_{payload}'] + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_dry ]), TCS([W_dry + W_ftotal <= W_total]), climb['W_{start}'][0] == W_total, climb['W_{end}'][-1] == cruise['W_{start}'][0], # similar constraint 1 TCS([ climb['W_{start}'] >= climb['W_{end}'] + climb['W_{burn}'] ]), # similar constraint 2 TCS([ cruise['W_{start}'] >= cruise['W_{end}'] + cruise['W_{burn}'] ]), climb['W_{start}'][1:] == climb['W_{end}'][:-1], cruise['W_{start}'][1:] == cruise['W_{end}'][:-1], TCS([W_dry <= cruise['W_{end}'][-1]]), TCS([W_ftotal >= W_fclimb + W_fcruise]), TCS([W_fclimb >= sum(climb['W_{burn}'])]), TCS([W_fcruise >= sum(cruise['W_{burn}'])]), #altitude constraints hftCruise[0] == CruiseAlt, ## TCS([hftCruise[1:Ncruise] >= hftCruise[:Ncruise-1] + dhftcr]), SignomialEquality(hftCruise[1:Ncruise], hftCruise[:Ncruise - 1] + dhftholdcr), TCS([hftClimb[1:Nclimb] >= hftClimb[:Nclimb - 1] + dhftholdcl ]), TCS([hftClimb[0] >= dhftcl[0]]), hftClimb[-1] <= hftCruise, #compute the dh dhftholdcl == hftCruise[0] / Nclimb, dhftcl == dhftholdcl, dhftcr == dhftholdcr, sum(cruise['RngCruise']) + sum(climb['RngClimb']) >= ReqRng, #compute fuel burn from TSFC cruise['W_{burn}'] == ac['numeng'] * ac.engine['TSFC'][Nclimb:] * cruise['thr'] * ac.engine['F'][Nclimb:], climb['W_{burn}'] == ac['numeng'] * ac.engine['TSFC'][:Nclimb] * climb['thr'] * ac.engine['F'][:Nclimb], #min climb rate constraint ## climb['RC'][0] >= RCmin, ]) M2 = .8 M25 = .6 M4a = .1025 Mexit = 1 M0 = .8 engineclimb = [ ac.engine.engineP['M_2'][:Nclimb] == climb['M'], ac.engine.engineP['M_{2.5}'] == M25, ac.engine.engineP['hold_{2}'] == 1 + .5 * (1.398 - 1) * M2**2, ac.engine.engineP['hold_{2.5}'] == 1 + .5 * (1.354 - 1) * M25**2, ac.engine.engineP['c1'] == 1 + .5 * (.401) * M0**2, #constraint on drag and thrust ac['numeng'] * ac.engine['F'][:Nclimb] >= climb['D'] + climb['W_{avg}'] * climb['\\theta'], #climb rate constraints TCS([ climb['excessP'] + climb.state['V'] * climb['D'] <= climb.state['V'] * ac['numeng'] * ac.engine['F'][:Nclimb] ]), ] M2 = .8 M25 = .6 M4a = .1025 Mexit = 1 M0 = .8 enginecruise = [ ac.engine.engineP['M_2'][Nclimb:] == cruise['M'], ## cruise['M'] == .8, cruise['M'] >= .76, ac.engine.engineP['M_{2.5}'][2] == M25, ac.engine.engineP['M_{2.5}'][3] == M25, #constraint on drag and thrust ac['numeng'] * ac.engine['F'][Nclimb:] >= cruise['D'] + cruise['W_{avg}'] * cruise['\\theta'], #climb rate constraints TCS([ cruise['excessP'] + cruise.state['V'] * cruise['D'] <= cruise.state['V'] * ac['numeng'] * ac.engine['F'][Nclimb:] ]), ] return constraints + ac + climb + cruise + enginecruise + engineclimb + enginestate + statelinking