def configure(self): """ Set it all up. """ # Place all design variables on the Assembly boundary. self.add('S', Float(0.0, iotype='in', desc='Wing Area')) self.add('ac_w', Float(0.0, iotype='in', desc='Weight of aircraft + payload')) self.add('SFCSL', Float(0.0, iotype='in', desc='sea-level SFC value')) self.add('thrust_sl', Float(0.0, iotype='in', desc='Maximum sea-level thrust')) self.add('AR', Float(0.0, iotype='in', desc='Aspect Ratio')) self.add('oswald', Float(0.0, iotype='in', desc="Oswald's efficiency")) # Splines self.add( 'SysXBspline', SysXBspline(num_elem=self.num_elem, num_pt=self.num_pt, x_init=self.x_pts, jac_h=self.jac_h)) self.SysXBspline.x_pt = self.x_pts self.add( 'SysHBspline', SysHBspline(num_elem=self.num_elem, num_pt=self.num_pt, x_init=self.x_pts, jac_h=self.jac_h)) self.add( 'SysMVBspline', SysMVBspline(num_elem=self.num_elem, num_pt=self.num_pt, x_init=self.x_pts, jac_h=self.jac_h)) self.add( 'SysGammaBspline', SysGammaBspline(num_elem=self.num_elem, num_pt=self.num_pt, x_init=self.x_pts, jac_gamma=self.jac_gamma)) # Atmospherics self.add('SysSFC', SysSFC(num_elem=self.num_elem)) self.add('SysTemp', SysTemp(num_elem=self.num_elem)) self.add('SysRho', SysRho(num_elem=self.num_elem)) self.add('SysSpeed', SysSpeed(num_elem=self.num_elem)) self.connect('SFCSL', 'SysSFC.SFCSL') self.connect('SysHBspline.h', 'SysSFC.h') self.connect('SysHBspline.h', 'SysTemp.h') self.connect('SysHBspline.h', 'SysRho.h') self.connect('SysTemp.temp', 'SysRho.temp') self.connect('SysTemp.temp', 'SysSpeed.temp') self.connect('SysMVBspline.M', 'SysSpeed.M') self.connect('SysMVBspline.v_spline', 'SysSpeed.v_spline') # ----------------------------------- # Comps for Coupled System begin here # ----------------------------------- # Vertical Equilibrium self.add('SysCLTar', SysCLTar(num_elem=self.num_elem)) self.connect('S', 'SysCLTar.S') self.connect('ac_w', 'SysCLTar.ac_w') self.connect('SysRho.rho', 'SysCLTar.rho') self.connect('SysGammaBspline.Gamma', 'SysCLTar.Gamma') self.connect('SysSpeed.v', 'SysCLTar.v') # Tripan Alpha self.add( 'SysTripanCLSurrogate', SysTripanCLSurrogate(num_elem=self.num_elem, num=self.num, CL=self.CL_arr)) self.connect('SysMVBspline.M', 'SysTripanCLSurrogate.M') self.connect('SysHBspline.h', 'SysTripanCLSurrogate.h') self.connect('SysCLTar.CL', 'SysTripanCLSurrogate.CL_tar') # Tripan Eta self.add( 'SysTripanCMSurrogate', SysTripanCMSurrogate(num_elem=self.num_elem, num=self.num, CM=self.CM_arr)) self.connect('SysMVBspline.M', 'SysTripanCMSurrogate.M') self.connect('SysHBspline.h', 'SysTripanCMSurrogate.h') self.connect('SysTripanCLSurrogate.alpha', 'SysTripanCMSurrogate.alpha') # Tripan Drag self.add( 'SysTripanCDSurrogate', SysTripanCDSurrogate(num_elem=self.num_elem, num=self.num, CD=self.CD_arr)) self.connect('SysMVBspline.M', 'SysTripanCDSurrogate.M') self.connect('SysHBspline.h', 'SysTripanCDSurrogate.h') self.connect('SysTripanCMSurrogate.eta', 'SysTripanCDSurrogate.eta') self.connect('SysTripanCLSurrogate.alpha', 'SysTripanCDSurrogate.alpha') # Horizontal Equilibrium self.add('SysCTTar', SysCTTar(num_elem=self.num_elem)) self.connect('SysGammaBspline.Gamma', 'SysCTTar.Gamma') self.connect('SysTripanCDSurrogate.CD', 'SysCTTar.CD') self.connect('SysTripanCLSurrogate.alpha', 'SysCTTar.alpha') self.connect('SysRho.rho', 'SysCTTar.rho') self.connect('SysSpeed.v', 'SysCTTar.v') self.connect('S', 'SysCTTar.S') self.connect('ac_w', 'SysCTTar.ac_w') # Weight self.add('SysFuelWeight', SysFuelWeight(num_elem=self.num_elem)) self.SysFuelWeight.fuel_w = np.linspace(1.0, 0.0, self.num_elem + 1) self.connect('SysSpeed.v', 'SysFuelWeight.v') self.connect('SysGammaBspline.Gamma', 'SysFuelWeight.Gamma') self.connect('SysCTTar.CT_tar', 'SysFuelWeight.CT_tar') self.connect('SysXBspline.x', 'SysFuelWeight.x') self.connect('SysSFC.SFC', 'SysFuelWeight.SFC') self.connect('SysRho.rho', 'SysFuelWeight.rho') self.connect('S', 'SysFuelWeight.S') # ------------------------------------------------ # Coupled Analysis - Newton for outer loop # TODO: replace with GS/Newton cascaded solvers when working # ----------------------------------------------- self.add('coupled_solver', NewtonSolver()) # Direct connections (cycles) are faster. self.connect('SysFuelWeight.fuel_w', 'SysCLTar.fuel_w') self.connect('SysCTTar.CT_tar', 'SysCLTar.CT_tar') self.connect('SysTripanCLSurrogate.alpha', 'SysCLTar.alpha') self.connect('SysTripanCMSurrogate.eta', 'SysTripanCLSurrogate.eta') self.connect('SysFuelWeight.fuel_w', 'SysCTTar.fuel_w') #self.coupled_solver.add_parameter('SysCLTar.fuel_w') #self.coupled_solver.add_constraint('SysFuelWeight.fuel_w = SysCLTar.fuel_w') #self.coupled_solver.add_parameter('SysCLTar.CT_tar') #self.coupled_solver.add_constraint('SysCTTar.CT_tar = SysCLTar.CT_tar') #self.coupled_solver.add_parameter('SysCLTar.alpha') #self.coupled_solver.add_constraint('SysTripanCLSurrogate.alpha = SysCLTar.alpha') #self.coupled_solver.add_parameter('SysTripanCLSurrogate.eta') #self.coupled_solver.add_constraint('SysTripanCMSurrogate.eta = SysTripanCLSurrogate.eta') #self.coupled_solver.add_parameter('SysCTTar.fuel_w') #self.coupled_solver.add_constraint('SysFuelWeight.fuel_w = SysCTTar.fuel_w') # (Implicit comps) self.coupled_solver.add_parameter('SysTripanCLSurrogate.alpha') self.coupled_solver.add_constraint( 'SysTripanCLSurrogate.alpha_res = 0') self.coupled_solver.add_parameter('SysTripanCMSurrogate.eta') self.coupled_solver.add_constraint('SysTripanCMSurrogate.CM = 0') # -------------------- # Downstream of solver # -------------------- # Functionals (i.e., components downstream of the coupled system.) self.add('SysTau', SysTau(num_elem=self.num_elem)) self.add('SysTmin', SysTmin(num_elem=self.num_elem)) self.add('SysTmax', SysTmax(num_elem=self.num_elem)) #self.add('SysSlopeMin', SysSlopeMin(num_elem=self.num_elem)) #self.add('SysSlopeMax', SysSlopeMax(num_elem=self.num_elem)) self.add('SysFuelObj', SysFuelObj(num_elem=self.num_elem)) self.add('SysHi', SysHi(num_elem=self.num_elem)) self.add('SysHf', SysHf(num_elem=self.num_elem)) self.add('SysMi', SysMi(num_elem=self.num_elem)) self.add('SysMf', SysMf(num_elem=self.num_elem)) self.add('SysBlockTime', SysBlockTime(num_elem=self.num_elem)) self.connect('S', 'SysTau.S') self.connect('thrust_sl', 'SysTau.thrust_sl') self.connect('SysRho.rho', 'SysTau.rho') self.connect('SysCTTar.CT_tar', 'SysTau.CT_tar') self.connect('SysHBspline.h', 'SysTau.h') self.connect('SysSpeed.v', 'SysTau.v') self.connect('SysTau.tau', 'SysTmin.tau') self.connect('SysTau.tau', 'SysTmax.tau') #self.connect('SysGammaBspline.Gamma', 'SysSlopeMin.Gamma') #self.connect('SysGammaBspline.Gamma', 'SysSlopeMax.Gamma') self.connect('SysFuelWeight.fuel_w', 'SysFuelObj.fuel_w') self.connect('SysHBspline.h', 'SysHi.h') self.connect('SysHBspline.h', 'SysHf.h') self.connect('SysMVBspline.M', 'SysMi.M') self.connect('SysMVBspline.M', 'SysMf.M') self.connect('SysXBspline.x', 'SysBlockTime.x') self.connect('SysSpeed.v', 'SysBlockTime.v') self.connect('SysGammaBspline.Gamma', 'SysBlockTime.Gamma') # Promote useful variables to the boundary. self.create_passthrough('SysHBspline.h_pt') self.connect('h_pt', 'SysGammaBspline.h_pt') self.create_passthrough('SysMVBspline.v_pt') self.create_passthrough('SysMVBspline.M_pt') self.create_passthrough('SysTmin.Tmin') self.create_passthrough('SysTmax.Tmax') self.create_passthrough('SysFuelObj.fuelburn') self.create_passthrough('SysHi.h_i') self.create_passthrough('SysHf.h_f') #------------------------- # Iteration Hierarchy #------------------------- #self.driver.workflow.add(['SysXBspline', 'SysHBspline', #'SysMVBspline', 'SysGammaBspline', #'SysSFC', 'SysTemp', 'SysRho', 'SysSpeed', #'coupled_solver', #'SysTau', 'SysTmin', 'SysTmax', #'SysFuelObj', 'SysHi', 'SysHf', 'SysMi', 'SysMf', 'SysBlockTime']) self.add('bsplines', Driver()) self.add('atmosphere', Driver()) self.add('SysCLTar_Sub', Driver()) self.add('SysTripanCLSurrogate_Sub', Driver()) self.add('SysTripanCMSurrogate_Sub', Driver()) self.add('SysTripanCDSurrogate_Sub', Driver()) self.add('SysCTTar_Sub', Driver()) self.add('SysFuelWeight_Sub', Driver()) self.driver.workflow.add([ 'bsplines', 'atmosphere', 'coupled_solver', 'SysTau', 'SysTmin', 'SysTmax', 'SysFuelObj', 'SysHi', 'SysHf', 'SysMi', 'SysMf', 'SysBlockTime' ]) self.bsplines.workflow.add( ['SysXBspline', 'SysHBspline', 'SysMVBspline', 'SysGammaBspline']) self.atmosphere.workflow.add( ['SysSFC', 'SysTemp', 'SysRho', 'SysSpeed']) self.coupled_solver.workflow.add([ 'SysCLTar_Sub', 'SysTripanCLSurrogate_Sub', 'SysTripanCMSurrogate_Sub', 'SysTripanCDSurrogate_Sub', 'SysCTTar_Sub', 'SysFuelWeight_Sub' ]) self.SysCLTar_Sub.workflow.add(['SysCLTar']) self.SysTripanCLSurrogate_Sub.workflow.add(['SysTripanCLSurrogate']) self.SysTripanCMSurrogate_Sub.workflow.add(['SysTripanCMSurrogate']) self.SysTripanCDSurrogate_Sub.workflow.add(['SysTripanCDSurrogate']) self.SysCTTar_Sub.workflow.add(['SysCTTar']) self.SysFuelWeight_Sub.workflow.add(['SysFuelWeight']) #------------------------- # Driver Settings #------------------------- self.driver.gradient_options.lin_solver = "linear_gs" self.driver.gradient_options.maxiter = 1 self.driver.gradient_options.derivative_direction = 'adjoint' self.coupled_solver.atol = 1e-9 self.coupled_solver.rtol = 1e-9 self.coupled_solver.max_iteration = 15 self.coupled_solver.gradient_options.atol = 1e-14 self.coupled_solver.gradient_options.rtol = 1e-20 self.coupled_solver.gradient_options.maxiter = 50 self.coupled_solver.iprint = 1
def configure(self): """ Set it all up. """ # Place all design variables on the Assembly boundary. self.add('S', Float(0.0, iotype='in', desc='Wing Area')) self.add('ac_w', Float(0.0, iotype='in', desc='Weight of aircraft + payload')) self.add('SFCSL', Float(0.0, iotype='in', desc='sea-level SFC value')) self.add('thrust_sl', Float(0.0, iotype='in', desc='Maximum sea-level thrust')) self.add('AR', Float(0.0, iotype='in', desc='Aspect Ratio')) self.add('oswald', Float(0.0, iotype='in', desc="Oswald's efficiency")) # Splines self.add( 'SysXBspline', SysXBspline(num_elem=self.num_elem, num_pt=self.num_pt, x_init=self.x_pts, jac_h=self.jac_h)) self.SysXBspline.x_pt = self.x_pts self.add( 'SysHBspline', SysHBspline(num_elem=self.num_elem, num_pt=self.num_pt, x_init=self.x_pts, jac_h=self.jac_h)) self.add( 'SysMVBspline', SysMVBspline(num_elem=self.num_elem, num_pt=self.num_pt, x_init=self.x_pts, jac_h=self.jac_h)) self.add( 'SysGammaBspline', SysGammaBspline(num_elem=self.num_elem, num_pt=self.num_pt, x_init=self.x_pts, jac_gamma=self.jac_gamma)) # Atmospherics self.add('SysSFC', SysSFC(num_elem=self.num_elem)) self.add('SysTemp', SysTemp(num_elem=self.num_elem)) self.add('SysRho', SysRho(num_elem=self.num_elem)) self.add('SysSpeed', SysSpeed(num_elem=self.num_elem)) self.connect('SFCSL', 'SysSFC.SFCSL') self.connect('SysHBspline.h', 'SysSFC.h') self.connect('SysHBspline.h', 'SysTemp.h') self.connect('SysHBspline.h', 'SysRho.h') self.connect('SysTemp.temp', 'SysRho.temp') self.connect('SysTemp.temp', 'SysSpeed.temp') self.connect('SysMVBspline.M', 'SysSpeed.M') self.connect('SysMVBspline.v_spline', 'SysSpeed.v_spline') # ----------------------------------- # Comps for Coupled System begin here # ----------------------------------- # Vertical Equilibrium self.add('SysCLTar', SysCLTar(num_elem=self.num_elem)) self.connect('S', 'SysCLTar.S') self.connect('ac_w', 'SysCLTar.ac_w') self.connect('SysRho.rho', 'SysCLTar.rho') self.connect('SysGammaBspline.Gamma', 'SysCLTar.Gamma') self.connect('SysSpeed.v', 'SysCLTar.v') # Drag self.add('SysAeroSurrogate', SysAeroSurrogate(num_elem=self.num_elem)) self.connect('AR', 'SysAeroSurrogate.AR') self.connect('oswald', 'SysAeroSurrogate.oswald') # Horizontal Equilibrium self.add('SysCTTar', SysCTTar(num_elem=self.num_elem)) self.connect('S', 'SysCTTar.S') self.connect('ac_w', 'SysCTTar.ac_w') self.connect('SysRho.rho', 'SysCTTar.rho') self.connect('SysGammaBspline.Gamma', 'SysCTTar.Gamma') self.connect('SysSpeed.v', 'SysCTTar.v') self.connect('SysAeroSurrogate.CD', 'SysCTTar.CD') self.connect('SysAeroSurrogate.alpha', 'SysCTTar.alpha') # Moment Equilibrium self.add('SysCM', SysCM(num_elem=self.num_elem)) self.connect('SysAeroSurrogate.alpha', 'SysCM.alpha') self.SysCM.eval_only = True # Weight self.add('SysFuelWeight', SysFuelWeight(num_elem=self.num_elem)) self.SysFuelWeight.fuel_w = np.linspace(1.0, 0.0, self.num_elem + 1) self.connect('S', 'SysFuelWeight.S') self.connect('SysRho.rho', 'SysFuelWeight.rho') self.connect('SysXBspline.x', 'SysFuelWeight.x') self.connect('SysGammaBspline.Gamma', 'SysFuelWeight.Gamma') self.connect('SysSpeed.v', 'SysFuelWeight.v') self.connect('SysSFC.SFC', 'SysFuelWeight.SFC') self.connect('SysCTTar.CT_tar', 'SysFuelWeight.CT_tar') # ---------------------------------------- # Drag subsystem - Newton for inner loop # ---------------------------------------- self.add('drag_solver', NewtonSolver()) self.drag_solver.add_parameter(('SysAeroSurrogate.alpha')) self.drag_solver.add_constraint('SysAeroSurrogate.CL = SysCLTar.CL') self.drag_solver.iprint = 1 self.drag_solver.atol = 1e-9 self.drag_solver.rtol = 1e-9 self.drag_solver.max_iteration = 15 self.drag_solver.gradient_options.atol = 1e-10 self.drag_solver.gradient_options.rtol = 1e-10 self.drag_solver.gradient_options.maxiter = 15 # ------------------------------------------------ # Coupled Analysis - Newton for outer loop # TODO: replace with GS/Newton cascaded solvers when working # ----------------------------------------------- self.add('coupled_solver', NewtonSolver()) # Old way, using params and eq-constraints # self.coupled_solver.add_parameter('SysCLTar.CT_tar') # self.coupled_solver.add_parameter('SysCLTar.fuel_w') # self.coupled_solver.add_parameter('SysCLTar.alpha') # self.coupled_solver.add_parameter('SysAeroSurrogate.eta') # self.coupled_solver.add_parameter('SysCTTar.fuel_w') #self.coupled_solver.add_constraint('SysCLTar.CT_tar = SysCTTar.CT_tar') #self.coupled_solver.add_constraint('SysCLTar.fuel_w = SysFuelWeight.fuel_w') #self.coupled_solver.add_constraint('SysCLTar.alpha = SysAeroSurrogate.alpha') #self.coupled_solver.add_constraint('SysAeroSurrogate.eta = SysCM.eta') #self.coupled_solver.add_constraint('SysCTTar.fuel_w = SysFuelWeight.fuel_w') # Direct connections (cycles) are faster. self.connect('SysCTTar.CT_tar', 'SysCLTar.CT_tar') self.connect('SysFuelWeight.fuel_w', 'SysCLTar.fuel_w') self.connect('SysAeroSurrogate.alpha', 'SysCLTar.alpha') self.connect('SysCM.eta', 'SysAeroSurrogate.eta') self.connect('SysFuelWeight.fuel_w', 'SysCTTar.fuel_w') # (Only non-GS pair) self.coupled_solver.add_parameter('SysCM.eta') self.coupled_solver.add_constraint('SysCM.eta_res = 0') self.coupled_solver.atol = 1e-9 self.coupled_solver.rtol = 1e-9 self.coupled_solver.max_iteration = 15 self.coupled_solver.gradient_options.atol = 1e-14 self.coupled_solver.gradient_options.rtol = 1e-14 self.coupled_solver.gradient_options.maxiter = 18 self.coupled_solver.iprint = 1 # -------------------- # Downstream of solver # -------------------- # Functionals (i.e., components downstream of the coupled system.) self.add('SysTau', SysTau(num_elem=self.num_elem)) self.add('SysTmin', SysTmin(num_elem=self.num_elem)) self.add('SysTmax', SysTmax(num_elem=self.num_elem)) self.add('SysSlopeMin', SysSlopeMin(num_elem=self.num_elem)) self.add('SysSlopeMax', SysSlopeMax(num_elem=self.num_elem)) self.add('SysFuelObj', SysFuelObj(num_elem=self.num_elem)) self.add('SysHi', SysHi(num_elem=self.num_elem)) self.add('SysHf', SysHf(num_elem=self.num_elem)) self.connect('S', 'SysTau.S') self.connect('thrust_sl', 'SysTau.thrust_sl') self.connect('SysRho.rho', 'SysTau.rho') self.connect('SysCTTar.CT_tar', 'SysTau.CT_tar') self.connect('SysHBspline.h', 'SysTau.h') self.connect('SysSpeed.v', 'SysTau.v') self.connect('SysTau.tau', 'SysTmin.tau') self.connect('SysTau.tau', 'SysTmax.tau') self.connect('SysGammaBspline.Gamma', 'SysSlopeMin.Gamma') self.connect('SysGammaBspline.Gamma', 'SysSlopeMax.Gamma') self.connect('SysFuelWeight.fuel_w', 'SysFuelObj.fuel_w') self.connect('SysHBspline.h', 'SysHi.h') self.connect('SysHBspline.h', 'SysHf.h') # Promote useful variables to the boundary. self.create_passthrough('SysHBspline.h_pt') self.connect('h_pt', 'SysGammaBspline.h_pt') self.create_passthrough('SysMVBspline.M_pt') self.create_passthrough('SysTmin.Tmin') self.create_passthrough('SysTmax.Tmax') self.create_passthrough('SysFuelObj.fuelburn') self.create_passthrough('SysHi.h_i') self.create_passthrough('SysHf.h_f') #------------------------- # Iteration Hieararchy #------------------------- self.driver.workflow.add([ 'SysXBspline', 'SysHBspline', 'SysMVBspline', 'SysGammaBspline', 'SysSFC', 'SysTemp', 'SysRho', 'SysSpeed', 'coupled_solver', 'SysTau', 'SysTmin', 'SysTmax', 'SysSlopeMin', 'SysSlopeMax', 'SysFuelObj', 'SysHi', 'SysHf' ]) self.coupled_solver.workflow.add( ['SysCLTar', 'drag_solver', 'SysCTTar', 'SysCM', 'SysFuelWeight']) self.drag_solver.workflow.add(['SysAeroSurrogate']) # Change some scaling parameters so that we match what they were when # the pickle was created. self.SysTau.thrust_scale = 0.072 self.SysCLTar.fuel_scale = 1e6 self.SysCTTar.fuel_scale = 1e6 self.SysFuelWeight.fuel_scale = 1e6