def setup(self, substitutions=None, **kwargs): eng = 0 #define the number of each flight segment Ncruise = 2 # vectorize with Vectorize(Ncruise): enginestate = FlightState() ac = Aircraft(0, Ncruise, enginestate, eng) #Vectorize with Vectorize(Ncruise): cruise = CruiseSegment(ac) statelinking = StateLinking(cruise.state, enginestate, Ncruise) #declare new variables W_ftotal = Variable('W_{f_{total}}', 'N', 'Total Fuel Weight') 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') hftCruise = cruise['hft'] #make overall constraints constraints = [] constraints.extend([ #weight constraints TCS([ ac['W_{e}'] + ac['W_{payload}'] + W_ftotal + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= W_total ]), cruise['W_{start}'][0] == W_total, TCS([ cruise['W_{start}'] >= cruise['W_{end}'] + cruise['W_{burn}'] ]), cruise['W_{start}'][1:] == cruise['W_{end}'][:-1], TCS([ ac['W_{e}'] + ac['W_{payload}'] + ac['numeng'] * ac['W_{engine}'] + ac['W_{wing}'] <= cruise['W_{end}'][-1] ]), TCS([W_ftotal >= W_fcruise]), TCS([W_fcruise >= sum(cruise['W_{burn}'])]), #altitude constraints hftCruise == CruiseAlt, CruiseAlt >= 30000 * units('ft'), #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'] * cruise['thr'] * ac.engine['F'], ]) M2 = .8 M25 = .6 M4a = .1025 M0 = .8 enginecruise = [ ac.engine.engineP['M_2'][0] == cruise['M'][0], ac.engine.engineP['M_2'][1] == cruise['M'][1], ac.engine.engineP['M_{2.5}'][1] == M25, ac.engine.engineP['M_{2.5}'][0] == 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, #steady level flight constraint on D cruise['D'] == ac['numeng'] * ac.engine['F'], #breguet range eqn TCS([ cruise['z_{bre}'] >= (ac.engine['TSFC'] * cruise['thr'] * cruise['D']) / cruise['W_{avg}'] ]), ] # Model.setup(self, W_ftotal + s*units('N'), constraints + ac + climb + cruise, subs) return constraints + ac + cruise + enginecruise + 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