def configure(self): comp = self.add('comp', Comp()) doe = self.add('doe', NeighborhoodDOEdriver()) doe.DOEgenerator = FullFactorial() doe.alpha = .1 doe.add_parameter('comp.x') doe.add_response('comp.y') doe.workflow.add('comp') meta = self.add('meta', MetaModel(params=('x', ), responses=('y', ))) meta.default_surrogate = ResponseSurface() self.connect('doe.case_inputs.comp.x', 'meta.params.x') self.connect('doe.case_outputs.comp.y', 'meta.responses.y') opt = self.add('opt', SLSQPdriver()) opt.add_parameter('meta.x', high=10., low=-10.) opt.add_objective('meta.y') opt.workflow.add('meta') drv = self.add('driver', FixedPointIterator()) drv.max_iteration = 2 drv.add_parameter('y') drv.add_constraint('y=meta.y') drv.workflow.add(['doe', 'opt'])
def configure(self): driver = self.add('driver', FixedPointIterator()) adapt = self.add('adapt', AdaptiveSampleDriver()) ei_opt = self.add('ei_opt', Genetic()) branin = self.add('branin', BraninComponent()) kwargs = {'params': ("x", "y"), 'responses': ('f_xy', )} meta = self.add('meta', MetaModel(**kwargs)) meta.default_surrogate = KrigingSurrogate() pareto = self.add('pareto', ParetoFilter(**kwargs)) ei = self.add('ei', ExpectedImprovement()) #initial training DOE adapt.DOEgenerator = OptLatinHypercube(num_samples=15) #adapt.DOEgenerator = Uniform(100) adapt.add_parameter('branin.x', low=-5, high=10) adapt.add_parameter('branin.y', low=0, high=15) adapt.add_response('branin.f_xy') #pass training data from sampler to metamodel and pareto filter self.connect('adapt.all_case_inputs.branin.x', ['meta.params.x', 'pareto.params.x']) self.connect('adapt.all_case_inputs.branin.y', ['meta.params.y', 'pareto.params.y']) self.connect('adapt.all_case_outputs.branin.f_xy', ['meta.responses.f_xy', 'pareto.responses.f_xy']) #connect meta and pareto to ei self.connect('meta.f_xy', 'ei.current') #this passes a normal distribution variable self.connect( 'pareto.pareto_outputs[0, 0]', 'ei.target' ) #for single objective, frontier is just a scalar value that is the minimum of the set #EI optimization to find next point ei_opt.opt_type = "maximize" ei_opt.population_size = 100 ei_opt.generations = 10 ei_opt.add_parameter('meta.x', low=-5, high=10) ei_opt.add_parameter('meta.y', low=0, high=15) ei_opt.add_objective('ei.PI') #could use ei.EI too #Iterative sampling process driver.add_parameter('adapt.adaptive_inputs.branin.x[0]') driver.add_parameter('adapt.adaptive_inputs.branin.y[0]') driver.add_constraint('adapt.adaptive_inputs.branin.x[0] = meta.x') driver.add_constraint('adapt.adaptive_inputs.branin.y[0] = meta.y') driver.max_iterations = 30 #Iteration Heirarchy driver.workflow.add(['adapt', 'pareto', 'ei_opt']) adapt.workflow.add(['branin']) ei_opt.workflow.add(['meta', 'ei']) #FPI now support stop conditions driver.add_stop_condition('ei.EI <= .0001')
def configure(self): driver = self.add('driver', FixedPointIterator()) adapt = self.add('adapt', AdaptiveSampleDriver()) MOEI_opt = self.add('MOEI_opt', Genetic()) self.add('spiral', SpiralComponent()) kwargs = {'params': ("x", "y"), 'responses': ('f1_xy', 'f2_xy')} meta = self.add('meta', MetaModel(**kwargs)) meta.default_surrogate = KrigingSurrogate() self.add('pareto', ParetoFilter(**kwargs)) self.add('MOEI', MultiObjExpectedImprovement()) # initial training DOE adapt.DOEgenerator = OptLatinHypercube(num_samples=25) adapt.add_parameter('spiral.x') adapt.add_parameter('spiral.y') adapt.add_response('spiral.f1_xy') adapt.add_response('spiral.f2_xy') # pass training data from sampler to metamodel and pareto filter self.connect('adapt.all_case_inputs.spiral.x', ['meta.params.x', 'pareto.params.x']) self.connect('adapt.all_case_inputs.spiral.y', ['meta.params.y', 'pareto.params.y']) self.connect('adapt.all_case_outputs.spiral.f1_xy', ['meta.responses.f1_xy', 'pareto.responses.f1_xy']) self.connect('adapt.all_case_outputs.spiral.f2_xy', ['meta.responses.f2_xy', 'pareto.responses.f2_xy']) # connect meta and pareto to ei self.connect('[meta.f1_xy, meta.f2_xy]', 'MOEI.current') self.connect('pareto.pareto_outputs', 'MOEI.target') # MOEI optimization to find next point MOEI_opt.opt_type = "maximize" MOEI_opt.population_size = 100 MOEI_opt.generations = 10 # MOEI_opt.selection_method = "tournament" MOEI_opt.add_parameter("meta.x", low=0.75, high=5. * pi) MOEI_opt.add_parameter("meta.y", low=0.75, high=5. * pi) MOEI_opt.add_objective("MOEI.PI") # Iterative sampling process driver.add_parameter('adapt.adaptive_inputs.spiral.x[0]') driver.add_parameter('adapt.adaptive_inputs.spiral.y[0]') driver.add_constraint('adapt.adaptive_inputs.spiral.x[0] = meta.x') driver.add_constraint('adapt.adaptive_inputs.spiral.y[0] = meta.y') driver.max_iterations = 30 # Iteration Heirarchy driver.workflow.add(['adapt', 'pareto', 'MOEI_opt']) adapt.workflow.add(['spiral']) MOEI_opt.workflow.add(['meta', 'MOEI']) # FPI now support stop conditions driver.add_stop_condition('MOEI.PI <= .0001')
def __init__(self): """ Creates a new Assembly with this problem Optimal Design at (1.9776, 0, 0) Optimal Objective = 3.18339""" super(SellarMDF, self).__init__() # create Optimizer instance self.add('driver', CONMINdriver()) # Outer Loop - Global Optimization self.add('solver', FixedPointIterator()) self.driver.workflow.add(['solver']) # Inner Loop - Full Multidisciplinary Solve via fixed point iteration self.add('dis1', sellar.Discipline1()) self.add('dis2', sellar.Discipline2()) self.solver.workflow.add(['dis1', 'dis2']) # Add Parameters to optimizer self.driver.add_parameter(('dis1.z1','dis2.z1'), low = -10.0, high = 10.0) self.driver.add_parameter(('dis1.z2','dis2.z2'), low = 0.0, high = 10.0) self.driver.add_parameter('dis1.x1', low = 0.0, high = 10.0) # Make all connections self.connect('dis1.y1','dis2.y1') # Iteration loop self.solver.add_parameter('dis1.y2', low=-9.e99, high=9.e99) self.solver.add_constraint('dis2.y2 = dis1.y2') # equivilent form # self.solver.add_constraint('dis2.y2 - dis1.y2 = 0') #Driver settings self.solver.max_iteration = 1000 self.solver.tolerance = .0001 # Optimization parameters self.driver.add_objective('(dis1.x1)**2 + dis1.z2 + dis1.y1 + math.exp(-dis2.y2)') self.driver.add_constraint('3.16 < dis1.y1') self.driver.add_constraint('dis2.y2 < 24.0') self.driver.cons_is_linear = [1, 1] self.driver.iprint = 0 self.driver.itmax = 30 self.driver.fdch = .001 self.driver.fdchm = .001 self.driver.delfun = .0001 self.driver.dabfun = .000001 self.driver.ctlmin = 0.0001
def configure(self): """ Creates a new Assembly with this problem Optimal Design at (1.9776, 0, 0) Optimal Objective = 3.18339""" # create Optimizer instance self.add('driver', SLSQPdriver()) # Outer Loop - Global Optimization self.add('dummy', Dummy()) self.dummy.force_execute = True self.add('solver', FixedPointIterator()) self.driver.workflow.add(['dummy', 'solver']) # Inner Loop - Full Multidisciplinary Solve via fixed point iteration self.add('dis1', sellar.Discipline1_WithDerivatives()) self.add('dis2', sellar.Discipline2_WithDerivatives()) self.solver.workflow.add(['dis1', 'dis2']) # Add Parameters to optimizer self.driver.add_parameter(('dis1.z1', 'dis2.z1'), low=-10.0, high=10.0) self.driver.add_parameter(('dis1.z2', 'dis2.z2'), low=0.0, high=10.0) self.driver.add_parameter('dis1.x1', low=0.0, high=10.0) # Make all connections self.connect('dis1.y1', 'dis2.y1') # Iteration loop self.solver.add_parameter('dis1.y2', low=-1.e99, high=1.e99) self.solver.add_constraint('dis2.y2 = dis1.y2') # Solver settings self.solver.max_iteration = 100 self.solver.tolerance = .00001 self.solver.print_convergence = False # Optimization parameters self.driver.add_objective( '(dis1.x1)**2 + dis1.z2 + dis1.y1 + math.exp(-dis2.y2)') self.driver.add_constraint('3.16 < dis1.y1') self.driver.add_constraint('dis2.y2 < 24.0') self.driver.iprint = 0
def configure(self): """ Creates a new Assembly with this problem Optimal Design at (1.9776, 0, 0) Optimal Objective = 3.18339""" # Disciplines self.add('dis1', sellar.Discipline1()) self.add('dis2', sellar.Discipline2()) objective = '(dis1.x1)**2 + dis1.z2 + dis1.y1 + exp(-dis2.y2)' constraint1 = 'dis1.y1 > 3.16' constraint2 = 'dis2.y2 < 24.0' # Top level is Fixed-Point Iteration self.add('driver', FixedPointIterator())
def configure(self): """ Creates a new Assembly with this problem Optimal Design at (1.9776, 0, 0) Optimal Objective = 3.18339""" #objective = '(dis1.x1)**2 + dis1.z2 + dis1.y1 + exp(-dis2.y2)' #constraint1 = 'dis1.y1 > 3.16' #constraint2 = 'dis2.y2 < 24.0' # Metamodel for sellar discipline 1 self.add("meta_model_dis1", MetaModel()) self.meta_model_dis1.surrogates = {"y1": ResponseSurface()} self.meta_model_dis1.model = SellarDiscipline1() self.meta_model_dis1.recorder = DBCaseRecorder() self.meta_model_dis1.force_execute = True # Metamodel for sellar discipline 2 self.add("meta_model_dis2", MetaModel()) self.meta_model_dis2.surrogates = {"y2": ResponseSurface()} self.meta_model_dis2.model = SellarDiscipline2() self.meta_model_dis2.recorder = DBCaseRecorder() self.meta_model_dis2.force_execute = True #training metalmodel for disc1 # self.add("DOE_Trainer_dis2",NeighborhoodDOEdriver()) # self.DOE_Trainer_dis2.DOEgenerator = CentralComposite() # self.DOE_Trainer_dis2.alpha = .1 # self.DOE_Trainer_dis2.add_parameter("meta_model_dis2.z1",low=-10,high=10,start=5.0) # self.DOE_Trainer_dis2.add_parameter("meta_model_dis2.z2",low=0,high=10,start=2.0) # self.DOE_Trainer_dis2.add_parameter("meta_model_dis2.y1",low=0,high=20) # self.DOE_Trainer_dis2.add_event("meta_model_dis2.train_next") # self.DOE_Trainer_dis2.force_execute = True #optimization of global objective function self.add('sysopt', SLSQPdriver()) self.sysopt.add_objective( '(meta_model_dis1.x1)**2 + meta_model_dis1.z2 + meta_model_dis1.y1 + math.exp(-meta_model_dis2.y2)' ) self.sysopt.add_parameter(['meta_model_dis1.z1', 'meta_model_dis2.z1'], low=-10, high=10.0, start=5.0) self.sysopt.add_parameter(['meta_model_dis1.z2', 'meta_model_dis2.z2'], low=0, high=10.0, start=2.0) self.sysopt.add_parameter('meta_model_dis1.y2', low=-1e99, high=1e99) self.sysopt.add_parameter('meta_model_dis2.y1', low=-1e99, high=1e99) #feasibility constraints self.sysopt.add_constraint('meta_model_dis1.y2 <= meta_model_dis2.y2') self.sysopt.add_constraint('meta_model_dis1.y2 >= meta_model_dis2.y2') self.sysopt.add_constraint('meta_model_dis2.y1 <= meta_model_dis1.y1') self.sysopt.add_constraint('meta_model_dis2.y1 >= meta_model_dis1.y1') self.sysopt.add_constraint('3.16 < meta_model_dis1.y1') self.sysopt.add_constraint('meta_model_dis2.y2 < 24.0') self.sysopt.force_execute = True #optimization of discipline 1 (discipline 2 of the sellar problem has no local variables) self.add('local_opt_dis1', SLSQPdriver()) self.local_opt_dis1.add_objective('meta_model_dis1.y1') self.local_opt_dis1.add_parameter('meta_model_dis1.x1', low=0, high=10.0) self.local_opt_dis1.add_constraint('3.16 < meta_model_dis1.y1') self.local_opt_dis1.add_event('meta_model_dis1.train_next') self.local_opt_dis1.force_execute = True self.local_opt_dis1.workflow.add(['meta_model_dis1']) #training metalmodel for disc1 self.add("DOE_Trainer_dis1", NeighborhoodDOEdriver()) self.DOE_Trainer_dis1.DOEgenerator = CentralComposite() self.DOE_Trainer_dis1.alpha = .1 self.DOE_Trainer_dis1.add_parameter("meta_model_dis1.z1", low=-10, high=10, start=5.0) self.DOE_Trainer_dis1.add_parameter("meta_model_dis1.z2", low=0, high=10, start=2.0) self.DOE_Trainer_dis1.add_parameter("meta_model_dis1.y2", low=-100, high=100) self.DOE_Trainer_dis1.add_event("meta_model_dis1.train_next") self.DOE_Trainer_dis1.force_execute = True self.DOE_Trainer_dis1.workflow.add("local_opt_dis1") self.add('reset_train', Driver()) self.reset_train.add_event('meta_model_dis1.reset_training_data') self.reset_train.add_event('meta_model_dis2.reset_training_data') self.reset_train.workflow.add(['meta_model_dis1', 'meta_model_dis2']) self.reset_train.force_execute = True #build workflow for bliss2000 self.add('driver', FixedPointIterator()) #self.add('main_driver', IterateUntil()) #self.main_driver.max_iterations = 1 self.driver.tolerance = .0001 # self.driver.workflow.add(['local_opt_dis1','reset_train','DOE_Trainer_dis1','DOE_Trainer_dis2','sysopt']) self.driver.workflow.add(['sysopt']) self.driver.add_parameter('x1_store', low=0, high=10.0) self.driver.add_constraint('meta_model_dis1.x1 = x1_store') self.driver.add_parameter('z1_store', low=0, high=10.0) self.driver.add_constraint('meta_model_dis1.z1 = z1_store') self.driver.add_parameter('z2_store', low=0, high=10.0) self.driver.add_constraint('meta_model_dis1.z2 = z2_store')
def configure(self): global_dvs = self.parent.get_global_des_vars() local_dvs = self.parent.get_local_des_vars_by_comp() objective = self.parent.get_objectives().items()[0] constraints = self.parent.list_constraints() coupling = self.parent.get_coupling_vars() self.parent.add('driver', FixedPointIterator()) self.parent.driver.max_iteration = 50 self.parent.driver.tolerance = .001 initial_conditions = [ self.parent.get(param.target) for comp, param in global_dvs ] self.parent.add_trait('global_des_vars', Array(initial_conditions)) for i, (comps, param) in enumerate(global_dvs): targets = param.targets self.parent.driver.add_parameter(targets, low=param.low, high=param.high) self.parent.driver.add_constraint("global_des_vars[%d]=%s" % (i, targets[0])) for comp, local_params in local_dvs.iteritems(): initial_conditions = [ self.parent.get(param.targets[0]) for param in local_params ] self.parent.add_trait('%s_local_des_vars' % comp, Array(initial_conditions)) for i, param in enumerate(local_params): self.parent.driver.add_parameter(param.targets, low=param.low, high=param.high) self.parent.driver.add_constraint('%s_local_des_vars[%d]=%s' % (comp, i, param.targets[0])) # Multidisciplinary Analysis mda = self.parent.add('mda', BroydenSolver()) self.parent.force_execute = True for key, couple in coupling.iteritems(): mda.add_parameter(couple.indep.target, low=-9.e99, high=9.e99) mda.add_constraint("%s=%s" % (couple.indep.target, couple.dep.target)) #Global Sensitivity Analysis ssa = self.parent.add("ssa", SensitivityDriver()) ssa.workflow.add("mda") ssa.differentiator = FiniteDifference() ssa.default_stepsize = 1.0e-6 ssa.force_execute = True ssa.add_objective(objective[1].text, name=objective[0]) for comps, param in global_dvs: ssa.add_parameter(param.targets, low=param.low, high=param.high) for constraint in constraints: ssa.add_constraint(constraint) #discipline sensitivity analyses sa_s = [] for comp, local_params in local_dvs.iteritems(): sa = self.parent.add('sa_%s' % comp, SensitivityDriver()) sa.default_stepsize = 1.0e-6 sa.force_execute = True sa_s.append('sa_%s' % comp) for param in local_params: sa.add_parameter(param.targets, low=param.low, high=param.high, fd_step=.001) for constraint in constraints: sa.add_constraint(constraint) sa.add_objective(objective[1].text, name=objective[0]) sa.differentiator = FiniteDifference() #Linear System Optimizations # Discipline Optimization # (Only discipline1 has an optimization input) delta_x = [] df = [] dg = [] bbopts = [] for comp, local_params in local_dvs.iteritems(): bbopt = self.parent.add('bbopt_%s' % comp, CONMINdriver()) bbopt.linobj = True bbopt.iprint = 0 bbopt.force_execute = True bbopts.append('bbopt_%s' % comp) x_store = "%s_local_des_vars" % comp for i, param in enumerate(local_params): x_store_i = "%s[%d]" % (x_store, i) bbopt.add_parameter(x_store_i, low=param.low, high=param.high) dx = "(%s-%s)" % (x_store_i, param.targets[0]) delta_x.append(dx) move_limit = (param.high - param.low) * 20.0 / 100.0 bbopt.add_constraint("%s < %f" % (dx, move_limit)) bbopt.add_constraint("%s > -%f" % (dx, move_limit)) df.append("sa_%s.dF[0][%d]*%s" % (comp, i, dx)) #build the linear constraint string for each constraint for j, const in enumerate(constraints): dg_j = [ "sa_%s.dG[%d][%d]*%s" % (comp, j, i, x) for i, x in enumerate(delta_x) ] constraint_parts = ["sa_%s.G[%d]" % (comp, j)] constraint_parts.extend(dg_j) lin_constraint = "%s < 0" % "+".join(constraint_parts) bbopt.add_constraint(lin_constraint) #build the linear objective string objective_parts = ["sa_%s.F[0]" % comp] objective_parts.extend(df) lin_objective = "+".join(objective_parts) bbopt.add_objective(lin_objective) # Global Optimization delta_z = [] df = [] dg = [] sysopt = self.parent.add('sysopt', CONMINdriver()) sysopt.linobj = True sysopt.iprint = 0 sysopt.force_execute = True for i, (comps, param) in enumerate(global_dvs): z_store = "global_des_vars[%d]" % i target = list(param.targets)[0] sysopt.add_parameter(z_store, low=param.low, high=param.high) dz = "(%s-%s)" % (z_store, target) delta_z.append(dz) move_limit = (param.high - param.low) * 20.00 / 100.0 sysopt.add_constraint("%s < %f" % (dz, move_limit)) sysopt.add_constraint("%s > -%f" % (dz, move_limit)) df.append("ssa.dF[0][%d]*%s" % (i, dz)) dg_j = [ "ssa.dG[%d][%d]*%s" % (j, i, dz) for j, const in enumerate(constraints) ] dg.append(dg_j) objective_parts = ["ssa.F[0]"] objective_parts.extend(df) lin_objective = "+".join(objective_parts) sysopt.add_objective(lin_objective) #build the linear constraint string for each constraint for j, const in enumerate(constraints): dg_j = [ "ssa.dG[%d][%d]*%s" % (j, i, x) for i, x in enumerate(delta_z) ] constraint_parts = ["ssa.G[%d]" % j] constraint_parts.extend(dg_j) lin_constraint = "%s < 0" % "+".join(constraint_parts) sysopt.add_constraint(lin_constraint) self.parent.driver.workflow = SequentialWorkflow() self.parent.driver.workflow.add("ssa") self.parent.driver.workflow.add(sa_s) self.parent.driver.workflow.add(bbopts) self.parent.driver.workflow.add("sysopt")
def configure(self): """ Creates a new Assembly with this problem Optimal Design at (1.9776, 0, 0) Optimal Objective = 3.18339""" # Sub assembly sub = self.add('sub', Assembly()) # Inner Loop - Full Multidisciplinary Solve via fixed point iteration sub.add('driver', FixedPointIterator()) sub.add('dis1', sellar.Discipline1()) sub.add('dis2', sellar.Discipline2()) sub.driver.workflow.add(['dis1', 'dis2']) # Make all connections sub.connect('dis1.y1', 'dis2.y1') sub.connect('dis1.z1', 'dis2.z1') # Iteration loop sub.driver.add_parameter('dis1.y2') sub.driver.add_constraint('dis2.y2 = dis1.y2') # Solver settings sub.driver.max_iteration = 100 sub.driver.tolerance = .00001 sub.driver.print_convergence = False # Subassy boundaries sub.add('globals', VarTree(Globals(), iotype='in')) sub.add('states', VarTree(States(), iotype='out')) sub.connect('globals.z1', 'dis1.z1') # Note, dis1.z2 is connected by input-input conn sub.connect('globals.z2', 'dis1.z2') sub.connect('globals.z2', 'dis2.z2') sub.create_passthrough('dis1.x1') sub.connect('dis1.y1', 'states.y[0]') sub.connect('dis2.y2', 'states.y[1]') # Global Optimization self.add('driver', SLSQPdriver()) self.driver.gradient_options.force_fd = True #self.driver.iprint = 3 # Extra comp self.add('half', Half()) self.connect('half.z2b', 'sub.globals.z2') self.driver.workflow.add(['half', 'sub']) # Add Parameters to optimizer self.driver.add_parameter('sub.globals.z1', low=-10.0, high=10.0) self.driver.add_parameter('half.z2a', low=0.0, high=10.0) self.driver.add_parameter('sub.x1', low=0.0, high=10.0) # Optimization parameters self.driver.add_objective( '(sub.x1)**2 + sub.globals.z2 + sub.states.y[0] + math.exp(-sub.states.y[1])' ) self.driver.add_constraint('3.16 < sub.states.y[0]') self.driver.add_constraint('sub.states.y[1] < 24.0') self.sub.globals.z1 = 5.0 self.half.z2a = 2.0 self.sub.x1 = 1.0
def configure_turbine_with_jacket(assembly, with_new_nacelle=False, flexible_blade=False, with_3pt_drive=False): """a stand-alone configure method to allow for flatter assemblies Parameters ---------- assembly : Assembly an openmdao assembly to be configured with_new_nacelle : bool False uses the default implementation, True uses an experimental implementation designed to smooth out discontinities making in amenable for gradient-based optimization flexible_blade : bool if True, internally solves the coupled aero/structural deflection using fixed point iteration. Note that the coupling is currently only in the flapwise deflection, and is primarily only important for highly flexible blades. If False, the aero loads are passed to the structure but there is no further iteration. """ # --- general turbine configuration inputs--- assembly.add( 'rho', Float(1.225, iotype='in', units='kg/m**3', desc='density of air', deriv_ignore=True)) assembly.add( 'mu', Float(1.81206e-5, iotype='in', units='kg/m/s', desc='dynamic viscosity of air', deriv_ignore=True)) assembly.add( 'shear_exponent', Float(0.2, iotype='in', desc='shear exponent', deriv_ignore=True)) assembly.add('hub_height', Float(90.0, iotype='in', units='m', desc='hub height')) assembly.add( 'turbine_class', Enum('I', ('I', 'II', 'III'), iotype='in', desc='IEC turbine class')) assembly.add( 'turbulence_class', Enum('B', ('A', 'B', 'C'), iotype='in', desc='IEC turbulence class class')) assembly.add( 'g', Float(9.81, iotype='in', units='m/s**2', desc='acceleration of gravity', deriv_ignore=True)) assembly.add( 'cdf_reference_height_wind_speed', Float( 90.0, iotype='in', desc= 'reference hub height for IEC wind speed (used in CDF calculation)' )) assembly.add('downwind', Bool(False, iotype='in', desc='flag if rotor is downwind')) assembly.add('tower_dt', Float(iotype='in', units='m', desc='tower top diameter')) # update for jacket assembly.add('generator_speed', Float(iotype='in', units='rpm', desc='generator speed')) assembly.add( 'machine_rating', Float(5000.0, units='kW', iotype='in', desc='machine rated power')) assembly.add( 'rna_weightM', Bool(True, iotype='in', desc='flag to consider or not the RNA weight effect on Moment')) assembly.add('rotor', RotorSE()) if with_new_nacelle: assembly.add('hub', HubSE()) if with_3pt_drive: assembly.add('nacelle', Drive3pt()) else: assembly.add('nacelle', Drive4pt()) else: assembly.add('nacelle', DriveWPACT()) assembly.add('hub', HubWPACT()) assembly.add('rna', RNAMass()) assembly.add('rotorloads1', RotorLoads()) assembly.add('rotorloads2', RotorLoads()) assembly.add('jacket', JacketSE()) assembly.add('maxdeflection', MaxTipDeflection()) if flexible_blade: assembly.add('fpi', FixedPointIterator()) assembly.fpi.workflow.add(['rotor']) assembly.fpi.add_parameter('rotor.delta_precurve_sub', low=-1.e99, high=1.e99) assembly.fpi.add_parameter('rotor.delta_bladeLength', low=-1.e99, high=1.e99) assembly.fpi.add_constraint( 'rotor.delta_precurve_sub = rotor.delta_precurve_sub_out') assembly.fpi.add_constraint( 'rotor.delta_bladeLength = rotor.delta_bladeLength_out') assembly.fpi.max_iteration = 20 assembly.fpi.tolerance = 1e-8 assembly.driver.workflow.add(['fpi']) else: assembly.driver.workflow.add(['rotor']) assembly.driver.workflow.add([ 'hub', 'nacelle', 'jacket', 'maxdeflection', 'rna', 'rotorloads1', 'rotorloads2' ]) # TODO: rotor drivetrain design should be connected to nacelle drivetrain design # connections to rotor assembly.connect('machine_rating', 'rotor.control.ratedPower') assembly.connect('rho', 'rotor.rho') assembly.connect('mu', 'rotor.mu') assembly.connect('shear_exponent', 'rotor.shearExp') assembly.connect('hub_height', 'rotor.hubHt') assembly.connect('turbine_class', 'rotor.turbine_class') assembly.connect('turbulence_class', 'rotor.turbulence_class') assembly.connect('g', 'rotor.g') assembly.connect('cdf_reference_height_wind_speed', 'rotor.cdf_reference_height_wind_speed') # connections to hub assembly.connect('rotor.mass_one_blade', 'hub.blade_mass') assembly.connect('rotor.root_bending_moment', 'hub.rotor_bending_moment') assembly.connect('rotor.diameter', 'hub.rotor_diameter') assembly.connect('rotor.hub_diameter', 'hub.blade_root_diameter') assembly.connect('rotor.nBlades', 'hub.blade_number') if with_new_nacelle: assembly.connect('nacelle.MB1_location', 'hub.MB1_location') assembly.connect('rotor.tilt', 'hub.gamma') assembly.connect('nacelle.L_rb', 'hub.L_rb') # connections to nacelle #TODO: fatigue option variables assembly.connect('rotor.diameter', 'nacelle.rotor_diameter') if not with_new_nacelle: assembly.connect( 'rotor.mass_all_blades + hub.hub_system_mass', 'nacelle.rotor_mass' ) #DODO: circular dependency if using DriveSE (nacelle csm --> hub, hub mass --> nacelle) if with_new_nacelle: assembly.connect('rotor.nBlades', 'nacelle.blade_number') assembly.connect('rotor.tilt', 'nacelle.shaft_angle') assembly.connect('333.3 * machine_rating / 1000.0', 'nacelle.shrink_disc_mass') assembly.connect('1.5 * rotor.ratedConditions.Q', 'nacelle.rotor_torque') assembly.connect('rotor.ratedConditions.T', 'nacelle.rotor_thrust') assembly.connect('rotor.ratedConditions.Omega', 'nacelle.rotor_speed') assembly.connect('machine_rating', 'nacelle.machine_rating') assembly.connect('rotor.root_bending_moment', 'nacelle.rotor_bending_moment') assembly.connect('generator_speed/rotor.ratedConditions.Omega', 'nacelle.gear_ratio') '''if with_new_nacelle: assembly.connect('rotor.g', 'nacelle.g')''' # Only drive smooth taking g from rotor; TODO: update when drive_smooth is updated assembly.connect( 'tower_dt', 'nacelle.tower_top_diameter' ) # OpenMDAO circular dependency issue # update for jacket input # connections to rna assembly.connect('rotor.mass_all_blades', 'rna.blades_mass') assembly.connect('rotor.I_all_blades', 'rna.blades_I') assembly.connect('hub.hub_system_mass', 'rna.hub_mass') assembly.connect('hub.hub_system_cm', 'rna.hub_cm') assembly.connect('hub.hub_system_I', 'rna.hub_I') assembly.connect('nacelle.nacelle_mass', 'rna.nac_mass') assembly.connect('nacelle.nacelle_cm', 'rna.nac_cm') assembly.connect('nacelle.nacelle_I', 'rna.nac_I') # connections to rotorloads1 assembly.connect('downwind', 'rotorloads1.downwind') assembly.connect('rna_weightM', 'rotorloads1.rna_weightM') assembly.connect('1.8 * rotor.ratedConditions.T', 'rotorloads1.F[0]') assembly.connect('rotor.ratedConditions.Q', 'rotorloads1.M[0]') assembly.connect('hub.hub_system_cm', 'rotorloads1.r_hub') assembly.connect('rna.rna_cm', 'rotorloads1.rna_cm') assembly.connect('rotor.tilt', 'rotorloads1.tilt') assembly.connect('g', 'rotorloads1.g') assembly.connect('rna.rna_mass', 'rotorloads1.m_RNA') # connections to rotorloads2 assembly.connect('downwind', 'rotorloads2.downwind') assembly.connect('rna_weightM', 'rotorloads2.rna_weightM') assembly.connect('rotor.T_extreme', 'rotorloads2.F[0]') assembly.connect('rotor.Q_extreme', 'rotorloads2.M[0]') assembly.connect('hub.hub_system_cm', 'rotorloads2.r_hub') assembly.connect('rna.rna_cm', 'rotorloads2.rna_cm') assembly.connect('rotor.tilt', 'rotorloads2.tilt') assembly.connect('g', 'rotorloads2.g') assembly.connect('rna.rna_mass', 'rotorloads2.m_RNA') # connections to jacket assembly.connect('rho', 'jacket.Windinputs.rho') # jacket input assembly.connect('mu', 'jacket.Windinputs.mu') # jacket input assembly.connect('-g', 'jacket.FrameAuxIns.gvector[2]') # jacket input assembly.connect('hub_height', 'jacket.Windinputs.HH') # jacket input assembly.connect('tower_dt', 'jacket.Twrinputs.Dt') # jacket input assembly.connect('rotor.yaw', 'jacket.RNAinputs.yawangle') # jacket input #assembly.connect('hub_height - nacelle.nacelle_cm[2]', 'jacket.Twrinputs.Htwr') # jacket input; TODO: probably irrelevant for this purpose, tower length is now determined in jacket assembly.connect('rna.rna_mass', 'jacket.RNAinputs.mass') # jacket input assembly.connect('rna.rna_cm', 'jacket.RNAinputs.CMoff') # jacket input assembly.connect('rna.rna_I_TT', 'jacket.RNAinputs.I') # jacket input # Rated rotor loads (Option 1) assembly.connect('rotor.ratedConditions.V', 'jacket.Windinputs.U50HH') # jacket input assembly.connect('rotorloads1.top_F', 'jacket.RNA_F[0:3]') # jacket input assembly.connect('rotorloads1.top_M', 'jacket.RNA_F[3:6]') # jacket input # Survival rotor loads (Option 2) #assembly.connect('rotor.V_extreme', 'tower.Windinputs.U50HH') # jacket input #assembly.connect('rotorloads2.top_F', 'jacket.RNA_F') # jacket input #assembly.connect('rotorloads2.top_M', 'jacket.RNA_M') # jacket input # connections to maxdeflection assembly.connect('rotor.Rtip', 'maxdeflection.Rtip') assembly.connect('rotor.precurveTip', 'maxdeflection.precurveTip') assembly.connect('rotor.presweepTip', 'maxdeflection.presweepTip') assembly.connect('rotor.precone', 'maxdeflection.precone') assembly.connect('rotor.tilt', 'maxdeflection.tilt') assembly.connect('hub.hub_system_cm', 'maxdeflection.hub_tt') assembly.connect( 'jacket.Twrouts.nodes[2,:]', 'maxdeflection.tower_z' ) # jacket input, had to make array dimensions explicit on instantiation for this connect to work ---THIS is the z at CMzoff, not necessarily the top flange assembly.connect('jacket.Twrouts', 'maxdeflection.Twrouts' ) # TODO: jacket input - doesnt recognize logobj assembly.connect('jacket.Twrouts.Htwr', 'maxdeflection.towerHt') # jacket input
def configure(self): """Setup a BLISS2000 architecture inside this assembly. """ global_dvs = self.parent.get_global_des_vars() des_vars=self.parent.get_des_vars_by_comp() local_dvs_by_comp = self.parent.get_local_des_vars_by_comp() global_dvs_by_comp = self.parent.get_global_des_vars_by_comp() locals=self.parent.get_local_des_vars() objective = self.parent.get_objectives().items()[0] comp_constraints = self.parent.get_constraints_by_comp() coupling = self.parent.list_coupling_vars() couple_deps = self.parent.get_coupling_deps_by_comp() couple_indeps = self.parent.get_coupling_indeps_by_comp() driver=self.parent.add("driver",FixedPointIterator()) driver.workflow = SequentialWorkflow() driver.max_iteration=15 #should be enough to converge driver.tolerance = .005 meta_models = {} self.sub_system_opts = {} system_var_map = {} for comp in des_vars: mm_name = "meta_model_%s"%comp meta_model = self.parent.add(mm_name,MetaModel()) #metamodel now replaces old component with same name driver.add_event("%s.reset_training_data"%mm_name) meta_models[comp] = meta_model meta_model.default_surrogate = ResponseSurface() #if there are locals, you need to make a SubSystemOpt assembly comp_obj = self.parent.get(comp) sso = self.parent.add('sub_system_opt_%s'%comp, SubSystemOpt(comp_obj, global_dvs_by_comp.get(comp), local_dvs_by_comp.get(comp), couple_deps.get(comp), couple_indeps.get(comp), comp_constraints.get(comp))) self.sub_system_opts[comp] = sso meta_model.model = sso for name,mapped_name in sso.var_map.iteritems(): system_var_map[name] = "%s.%s"%(mm_name,mapped_name) meta_model.recorder = DBCaseRecorder() #add a doe trainer for each metamodel dis_doe=self.parent.add("DOE_Trainer_%s"%comp,NeighborhoodDOEdriver()) for couple in couple_indeps[comp] : mapped_name = system_var_map[couple.indep.target] dis_doe.add_parameter(mapped_name,low=-1e99,high=1e99) #change to -1e99/1e99 for dv in global_dvs_by_comp[comp]: dis_doe.add_parameter(system_var_map[dv.target],low=dv.low, high=dv.high,start=dv.start) if local_dvs_by_comp.get(comp): #add weights if they are there for w in meta_model.model.weights: dis_doe.add_parameter("meta_model_%s.%s"%(comp,w),low=-3,high=3) num_params = len(dis_doe.get_parameters()) dis_doe.DOEgenerator = LatinHypercube((num_params**2+3*num_params+2)/2) dis_doe.alpha= .1 dis_doe.beta = .01 dis_doe.add_event("meta_model_%s.train_next"%comp) dis_doe.force_execute = True driver.workflow.add(dis_doe.name) #run all doe training before system optimziation #optimization of system objective function using the discipline meta models sysopt=self.parent.add('sysopt', SLSQPdriver()) sysopt.recorders = self.data_recorders sysopt.iprint = 0 sysopt.differentiator = FiniteDifference() obj2= objective[1].text #for comp in objective[1].get_referenced_compnames(): # obj2=obj2.replace(comp,"meta_model_%s"%comp) for var_name, mapped_name in system_var_map.iteritems(): obj2=obj2.replace(var_name,mapped_name) sysopt.add_objective(obj2) #add global design variables as parameters for param,group in global_dvs: plist=[system_var_map[t] for t in group.targets] sysopt.add_parameter(plist, low=group.low, high=group.high,start=group.start) #add the subsytem weights to the system optimization for comp,sso in self.sub_system_opts.iteritems(): mm_name = "meta_model_%s"%comp for w in sso.weights: sysopt.add_parameter("%s.%s"%(mm_name,w),low=-3,high=3) for key,couple in coupling.iteritems(): s=couple.indep.target mapped_name = system_var_map[s] sysopt.add_parameter(mapped_name, low=-1e99, high=1e99) #feasibility constraints, referenced to metamodels s1,s2= system_var_map[couple.dep.target], system_var_map[couple.indep.target] sysopt.add_constraint('(%s-%s)**2<=0.0001'%(s2,s1)) #sysopt.add_constraint('%s>=%s'%(s2,s1)) #add constraints, referenced to metamodels for comp,constraints in comp_constraints.iteritems(): for c in constraints: new_c = str(c) for var,mapped_name in system_var_map.iteritems(): new_c = new_c.replace(var,mapped_name) sysopt.add_constraint(new_c) driver.workflow.add('sysopt') #setup paramter for fixedpointiterator comp=des_vars.keys()[0] mm='meta_model_%s'%comp #create some placeholder variables for the fixed point iteration for l in locals: s=system_var_map[l[0]].replace(".","_") s2='%s_store'%s self.parent.add(s2,Float(0.0)) driver.add_parameter(s2 , low=l[1].low, high=l[1].high) driver.add_constraint('%s = %s'%(system_var_map[l[1].target],s2)) for i,g in enumerate(global_dvs): s2='global%d_store'%i self.parent.add(s2,Float(0.0)) driver.add_parameter(s2 , low=g[1].low, high=g[1].high) driver.add_constraint('%s = %s'%(system_var_map[g[1].target],s2))
def configure(self): """ Creates a new Assembly with this problem Optimal Design at (1.9776, 0, 0) Optimal Objective = 3.18339""" # Disciplines self.add('dis1', sellar.Discipline1()) self.add('dis2', sellar.Discipline2()) objective = '(dis1.x1)**2 + dis1.z2 + dis1.y1 + exp(-dis2.y2)' constraint1 = 'dis1.y1 > 3.16' constraint2 = 'dis2.y2 < 24.0' # Top level is Fixed-Point Iteration self.add('driver', FixedPointIterator()) self.driver.add_parameter('dis1.x1', low=0.0, high=10.0, start=1.0) self.driver.add_parameter(['dis1.z1', 'dis2.z1'], low=-10.0, high=10.0, start=5.0) self.driver.add_parameter(['dis1.z2', 'dis2.z2'], low=0.0, high=10.0, start=2.0) self.driver.add_constraint('x1_store = dis1.x1') self.driver.add_constraint('z_store[0] = dis1.z1') self.driver.add_constraint('z_store[1] = dis1.z2') self.driver.max_iteration = 50 self.driver.tolerance = .001 # Multidisciplinary Analysis self.add('mda', BroydenSolver()) self.mda.add_parameter('dis1.y2', low=-9.e99, high=9.e99, start=0.0) self.mda.add_constraint('dis2.y2 = dis1.y2') self.mda.add_parameter('dis2.y1', low=-9.e99, high=9.e99, start=3.16) self.mda.add_constraint('dis2.y1 = dis1.y1') # Discipline 1 Sensitivity Analysis self.add('sa_dis1', SensitivityDriver()) self.sa_dis1.workflow.add(['dis1']) self.sa_dis1.add_parameter('dis1.x1', low=0.0, high=10.0, fd_step=.001) self.sa_dis1.add_constraint(constraint1) self.sa_dis1.add_constraint(constraint2) self.sa_dis1.add_objective(objective, name='obj') # Discipline 2 Sensitivity Analysis # dis2 has no local parameter, so there is no need to treat it as # a subsystem. # System Level Sensitivity Analysis # Note, we cheat here and run an MDA instead of solving the # GSE equations. Have to put this on the TODO list. self.add('ssa', SensitivityDriver()) self.ssa.workflow.add(['mda']) self.ssa.add_parameter(['dis1.z1', 'dis2.z1'], low=-10.0, high=10.0) self.ssa.add_parameter(['dis1.z2', 'dis2.z2'], low=0.0, high=10.0) self.ssa.add_constraint(constraint1) self.ssa.add_constraint(constraint2) self.ssa.add_objective(objective, name='obj') # Discipline Optimization # (Only discipline1 has an optimization input) self.add('bbopt1', CONMINdriver()) self.bbopt1.add_parameter('x1_store', low=0.0, high=10.0, start=1.0) self.bbopt1.add_objective( 'sa_dis1.F[0] + sa_dis1.dF[0][0]*(x1_store-dis1.x1)') self.bbopt1.add_constraint( 'sa_dis1.G[0] + sa_dis1.dG[0][0]*(x1_store-dis1.x1) < 0') #this one is technically unncessary self.bbopt1.add_constraint( 'sa_dis1.G[1] + sa_dis1.dG[1][0]*(x1_store-dis1.x1) < 0') self.bbopt1.add_constraint('(x1_store-dis1.x1)<.5') self.bbopt1.add_constraint('(x1_store-dis1.x1)>-.5') self.bbopt1.iprint = 0 self.bbopt1.linobj = True # Global Optimization self.add('sysopt', CONMINdriver()) self.sysopt.add_parameter('z_store[0]', low=-10.0, high=10.0, start=5.0) self.sysopt.add_parameter('z_store[1]', low=0.0, high=10.0, start=2.0) self.sysopt.add_objective( 'ssa.F[0]+ ssa.dF[0][0]*(z_store[0]-dis1.z1) + ssa.dF[0][1]*(z_store[1]-dis1.z2)' ) self.sysopt.add_constraint( 'ssa.G[0] + ssa.dG[0][0]*(z_store[0]-dis1.z1) + ssa.dG[0][1]*(z_store[1]-dis1.z2) < 0' ) self.sysopt.add_constraint( 'ssa.G[1] + ssa.dG[1][0]*(z_store[0]-dis1.z1) + ssa.dG[1][1]*(z_store[1]-dis1.z2) < 0' ) self.sysopt.add_constraint('z_store[0]-dis1.z1<.5') self.sysopt.add_constraint('z_store[0]-dis1.z1>-.5') self.sysopt.add_constraint('z_store[1]-dis1.z2<.5') self.sysopt.add_constraint('z_store[1]-dis1.z2>-.5') self.sysopt.iprint = 0 self.sysopt.linobj = True self.driver.workflow.add(['ssa', 'sa_dis1', 'bbopt1', 'sysopt'])
def __init__(self, Ns): super(AeroStructural, self).__init__() # configuration self.add('config', AtlasConfiguration(Ns)) # Take parameterized properties and get property for each element self.add('discrete', DiscretizeProperties(Ns)) self.connect('config.Ns', 'discrete.Ns') self.connect('config.ycmax', 'discrete.ycmax') self.connect('config.R', 'discrete.R') self.connect('config.c', 'discrete.c_in') self.connect('config.Cl', 'discrete.Cl_in') self.connect('config.Cm', 'discrete.Cm_in') self.connect('config.t', 'discrete.t_in') self.connect('config.xtU', 'discrete.xtU_in') self.connect('config.xtL', 'discrete.xtL_in') self.connect('config.xEA', 'discrete.xEA_in') self.connect('config.yWire', 'discrete.yWire') self.connect('config.d', 'discrete.d_in') self.connect('config.theta', 'discrete.theta_in') self.connect('config.nTube', 'discrete.nTube_in') self.connect('config.nCap', 'discrete.nCap_in') self.connect('config.lBiscuit', 'discrete.lBiscuit_in') # First run Aero calc with simple blade-element model. Lift is # accurate with this simple model since Cl is pre-defined self.add('aero', Aero(Ns)) self.connect('config.b', 'aero.b') self.connect('config.R', 'aero.R') self.connect('config.Ns', 'aero.Ns') self.connect('discrete.yN', 'aero.yN') self.connect('config.dr', 'aero.dr') self.connect('config.r', 'aero.r') self.connect('config.h', 'aero.h') self.connect('config.ycmax[0]', 'aero.ycmax') self.connect('config.rho', 'aero.rho') self.connect('config.visc', 'aero.visc') self.connect('config.vw', 'aero.vw') self.connect('config.vc', 'aero.vc') self.connect('config.Omega', 'aero.Omega') self.connect('discrete.cE', 'aero.c') self.connect('discrete.Cl', 'aero.Cl') self.connect('discrete.d', 'aero.d') self.connect('config.yWire', 'aero.yWire') self.connect('config.zWire', 'aero.zWire') self.connect('config.tWire', 'aero.tWire') self.connect('discrete.Cm', 'aero.Cm') self.connect('discrete.xtU', 'aero.xtU') self.connect('discrete.xtL', 'aero.xtL') # Then run Aero calc with more accurate Vortex method self.add('aero2', Aero2(Ns)) self.connect('config.b', 'aero2.b') self.connect('config.R', 'aero2.R') self.connect('config.Ns', 'aero2.Ns') self.connect('discrete.yN', 'aero2.yN') self.connect('config.dr', 'aero2.dr') self.connect('config.r', 'aero2.r') self.connect('config.h', 'aero2.h') self.connect('config.ycmax[0]', 'aero2.ycmax') self.connect('config.rho', 'aero2.rho') self.connect('config.visc', 'aero2.visc') self.connect('config.vw', 'aero2.vw') self.connect('config.vc', 'aero2.vc') self.connect('config.Omega', 'aero2.Omega') self.connect('discrete.cE', 'aero2.c') self.connect('discrete.Cl', 'aero2.Cl') self.connect('discrete.d', 'aero2.d') self.connect('config.yWire', 'aero2.yWire') self.connect('config.zWire', 'aero2.zWire') self.connect('config.tWire', 'aero2.tWire') self.connect('discrete.Cm', 'aero2.Cm') self.connect('discrete.xtU', 'aero2.xtU') self.connect('discrete.xtL', 'aero2.xtL') self.connect('config.anhedral', 'aero2.anhedral') # Structures calc self.add('struc', Structures(Ns)) self.connect('config.flags', 'struc.flags') self.connect('discrete.yN', 'struc.yN') self.connect('discrete.d', 'struc.d') self.connect('discrete.theta', 'struc.theta') self.connect('discrete.nTube', 'struc.nTube') self.connect('discrete.nCap', 'struc.nCap') self.connect('discrete.lBiscuit', 'struc.lBiscuit') self.connect('config.Jprop', 'struc.Jprop') self.connect('config.b', 'struc.b') self.connect('discrete.cE', 'struc.cE') self.connect('discrete.xEA', 'struc.xEA') self.connect('discrete.xtU', 'struc.xtU') self.connect('config.dQuad', 'struc.dQuad') self.connect('config.thetaQuad', 'struc.thetaQuad') self.connect('config.nTubeQuad', 'struc.nTubeQuad') self.connect('config.lBiscuitQuad', 'struc.lBiscuitQuad') self.connect('config.RQuad', 'struc.RQuad') self.connect('config.hQuad', 'struc.hQuad') self.connect('config.ycmax[0]', 'struc.ycmax') self.connect('config.yWire', 'struc.yWire') self.connect('config.zWire', 'struc.zWire') self.connect('config.tWire', 'struc.tWire') self.connect('config.TWire', 'struc.TWire') self.connect('config.TEtension', 'struc.TEtension') self.connect('config.mElseRotor', 'struc.mElseRotor') self.connect('config.mElseCentre', 'struc.mElseCentre') self.connect('config.mElseR', 'struc.mElseR') self.connect('config.R', 'struc.R') self.connect('config.mPilot', 'struc.mPilot') self.connect('config.presLoad', 'struc.presLoad') # converge aero and structures via fixed point iteration self.add('switch', Switch(Ns)) self.connect('aero.Fblade', 'switch.fblade_initial') self.connect('aero2.Fblade', 'switch.fblade_updated') self.connect('switch.fblade', 'struc.fblade') # self.connect('struc.q', 'aero2.q') # via constraint self.add('iterate', FixedPointIterator()) # self.iterate.max_iteration = 2 # 2 passes to emulate MATLAB code self.iterate.tolerance = 1e-10 self.iterate.add_parameter('aero2.q', low=-1e999, high=1e999) self.iterate.add_constraint('aero2.q = struc.q') # make sure we have a valid parameter value for first iteration q_dim = 6 * (self.config.Ns + 1) self.aero2.q = np.zeros((q_dim, 1)) # calculate results self.add('results', Results(Ns)) self.connect('config.b', 'results.b') self.connect('config.Ns', 'results.Ns') self.connect('discrete.yN', 'results.yN') self.connect('discrete.yE', 'results.yE') self.connect('discrete.cE', 'results.cE') self.connect('discrete.Cl', 'results.Cl') self.connect('struc.q', 'results.q') self.connect('struc.Mtot', 'results.Mtot') self.connect('aero2.phi', 'results.phi') self.connect('config.collective', 'results.collective') self.connect('aero2.Fblade', 'results.fblade') self.driver.workflow.add('config') self.driver.workflow.add('discrete') self.driver.workflow.add('aero') self.driver.workflow.add('iterate') self.driver.workflow.add('results')
def configure(self): # rename options nTurbines = self.nTurbines nDirections = self.nDirections optimize_position = self.optimize_position optimize_yaw = self.optimize_yaw datasize = self.datasize nSamples = self.nSamples nSpeeds = self.nSpeeds maxiter = self.maxiter # add driver so the workflow is not overwritten later if optimize_position or optimize_yaw: self.add('driver', SLSQPdriver()) # add AEP component first so it can be connected to F6 = self.add('floris_AEP', AEP(nDirections=nDirections)) F6.missing_deriv_policy = 'assume_zero' self.connect('windrose_frequencies', 'floris_AEP.windrose_frequencies') self.connect('floris_AEP.AEP', 'AEP') self.connect('floris_AEP.power_directions_out', 'power_directions') # set up constraints self.add('floris_dist_const', dist_const(nTurbines=nTurbines)) self.connect('turbineX', 'floris_dist_const.turbineX') self.connect('turbineY', 'floris_dist_const.turbineY') if nSamples > 0: samplingNonSampling = ['', 'Sampling_'] else: samplingNonSampling = [''] for i in range(0, nDirections): # add fixed point iterator self.add('FPIdriver_%d' % i, FixedPointIterator()) self.add( 'rotor_CPCT_%d' % i, CPCT_Interpolate(nTurbines=self.nTurbines, datasize=self.datasize)) CP = 'rotor_CPCT_%d.CP' % i CT = 'rotor_CPCT_%d.CT' % i CPCT = 'rotor_CPCT_%d' % i # add components of floris to assembly F2 = self.add('floris_windframe_%d' % i, floris_windframe(nTurbines=nTurbines)) F2.missing_deriv_policy = 'assume_zero' self.add('floris_wcent_wdiam_%d' % i, floris_wcent_wdiam(nTurbines=nTurbines)) F4 = self.add('floris_overlap_%d' % i, floris_overlap(nTurbines=nTurbines)) F4.missing_deriv_policy = 'assume_zero' self.add('floris_power_%d' % i, floris_power(nTurbines=nTurbines)) # add visualization components of floris to assembly if nSamples > 0: self.add( 'Sampling_floris_windframe_%d' % i, floris_windframe(nTurbines=nTurbines, nSamples=nSamples)) self.add( 'Sampling_floris_wcent_wdiam_%d' % i, floris_wcent_wdiam(nTurbines=nTurbines, nSamples=nSamples)) self.add('Sampling_floris_overlap_%d' % i, floris_overlap(nTurbines=nTurbines)) self.add('Sampling_floris_power_%d' % i, floris_power(nTurbines=nTurbines, nSamples=nSamples)) # connect inputs to components self.connect('curve_CP', 'rotor_CPCT_%d.windSpeedToCPCT.CP' % i) self.connect('curve_CT', 'rotor_CPCT_%d.windSpeedToCPCT.CT' % i) self.connect('curve_wind_speed', 'rotor_CPCT_%d.windSpeedToCPCT.wind_speed' % i) self.connect('parameters.pP', 'rotor_CPCT_%d.pP' % i) for ssn in samplingNonSampling: self.connect('parameters', [ '%sfloris_wcent_wdiam_%d.parameters' % (ssn, i), '%sfloris_power_%d.parameters' % (ssn, i) ]) self.connect('verbose', [ '%sfloris_windframe_%d.verbose' % (ssn, i), '%sfloris_wcent_wdiam_%d.verbose' % (ssn, i), '%sfloris_power_%d.verbose' % (ssn, i) ]) self.connect('turbineX', '%sfloris_windframe_%d.turbineX' % (ssn, i)) self.connect('turbineY', '%sfloris_windframe_%d.turbineY' % (ssn, i)) self.connect('rotorDiameter', [ '%sfloris_wcent_wdiam_%d.rotorDiameter' % (ssn, i), '%sfloris_overlap_%d.rotorDiameter' % (ssn, i), '%sfloris_power_%d.rotorDiameter' % (ssn, i) ]) self.connect('axialInduction', '%sfloris_power_%d.axialInduction' % (ssn, i)) self.connect( 'generator_efficiency', '%sfloris_power_%d.generator_efficiency' % (ssn, i)) if nSamples > 0: # connections needed for visualization self.connect('ws_positionX', 'Sampling_floris_windframe_%d.ws_positionX' % i) self.connect('ws_positionY', 'Sampling_floris_windframe_%d.ws_positionY' % i) self.connect('ws_positionZ', 'Sampling_floris_windframe_%d.ws_positionZ' % i) self.connect('hubHeight', 'Sampling_floris_wcent_wdiam_%d.hubHeight' % i) if optimize_yaw: yawToConnect = 'yaw_%d' % i else: yawToConnect = 'yaw' self.connect(yawToConnect, '%s.yaw' % CPCT) for ssn in samplingNonSampling: self.connect(yawToConnect, [ '%sfloris_wcent_wdiam_%d.yaw' % (ssn, i), '%sfloris_power_%d.yaw' % (ssn, i) ]) for ssn in samplingNonSampling: self.connect('air_density', '%sfloris_power_%d.air_density' % (ssn, i)) self.connect('windrose_directions[%d]' % i, '%sfloris_windframe_%d.wind_direction' % (ssn, i)) # for satisfying the verbosity in windframe for ssn in samplingNonSampling: self.connect(CT, '%sfloris_windframe_%d.Ct' % (ssn, i)) self.connect(CP, '%sfloris_windframe_%d.Cp' % (ssn, i)) self.connect(yawToConnect, '%sfloris_windframe_%d.yaw' % (ssn, i)) self.connect('axialInduction', '%sfloris_windframe_%d.axialInduction' % (ssn, i)) # ############### Connections between components ################## # connections from CtCp calculation to other components for ssn in samplingNonSampling: self.connect(CT, [ '%sfloris_wcent_wdiam_%d.Ct' % (ssn, i), '%sfloris_power_%d.Ct' % (ssn, i) ]) self.connect(CP, '%sfloris_power_%d.Cp' % (ssn, i)) # connections from floris_windframe to floris_wcent_wdiam self.connect('%sfloris_windframe_%d.turbineXw' % (ssn, i), '%sfloris_wcent_wdiam_%d.turbineXw' % (ssn, i)) self.connect('%sfloris_windframe_%d.turbineYw' % (ssn, i), '%sfloris_wcent_wdiam_%d.turbineYw' % (ssn, i)) # connections from floris_wcent_wdiam to floris_overlap self.connect( '%sfloris_wcent_wdiam_%d.wakeCentersYT' % (ssn, i), '%sfloris_overlap_%d.wakeCentersYT' % (ssn, i)) self.connect( '%sfloris_wcent_wdiam_%d.wakeDiametersT' % (ssn, i), '%sfloris_overlap_%d.wakeDiametersT' % (ssn, i)) # connections from floris_windframe to floris_overlap self.connect('%sfloris_windframe_%d.turbineXw' % (ssn, i), '%sfloris_overlap_%d.turbineXw' % (ssn, i)) self.connect('%sfloris_windframe_%d.turbineYw' % (ssn, i), '%sfloris_overlap_%d.turbineYw' % (ssn, i)) # connections from floris_windframe to floris_power self.connect('%sfloris_windframe_%d.turbineXw' % (ssn, i), '%sfloris_power_%d.turbineXw' % (ssn, i)) # connections from floris_overlap to floris_power self.connect('%sfloris_overlap_%d.wakeOverlapTRel' % (ssn, i), '%sfloris_power_%d.wakeOverlapTRel' % (ssn, i)) # additional connections needed for visualization if nSamples > 0: self.connect('Sampling_floris_windframe_%d.wsw_position' % i, [ 'Sampling_floris_wcent_wdiam_%d.wsw_position' % i, 'Sampling_floris_power_%d.wsw_position' % i ]) self.connect('Sampling_floris_wcent_wdiam_%d.wakeCentersY' % i, 'Sampling_floris_power_%d.wakeCentersY' % i) self.connect('Sampling_floris_wcent_wdiam_%d.wakeCentersZ' % i, 'Sampling_floris_power_%d.wakeCentersZ' % i) self.connect( 'Sampling_floris_wcent_wdiam_%d.wakeDiameters' % i, 'Sampling_floris_power_%d.wakeDiameters' % i) self.connect('Sampling_floris_power_%d.ws_array' % i, 'ws_array_%d' % i) # connections from floris_power to floris_AEP self.connect('floris_power_%d.power' % i, 'floris_AEP.power_directions[%d]' % i) # ################################################################# # add to workflow exec( "self.FPIdriver_%d.workflow.add(['rotor_CPCT_%d', 'floris_windframe_%d', \ 'floris_wcent_wdiam_%d', 'floris_overlap_%d', 'floris_power_%d'])" % (i, i, i, i, i, i)) exec( "self.FPIdriver_%d.add_parameter('rotor_CPCT_%d.wind_speed_hub', low=0., high=100.)" % (i, i)) exec( "self.FPIdriver_%d.add_constraint('rotor_CPCT_%d.wind_speed_hub = \ floris_power_%d.velocitiesTurbines')" % (i, i, i)) self.driver.workflow.add('FPIdriver_%d' % i) if nSamples > 0: self.driver.workflow.add([ 'Sampling_floris_windframe_%d' % i, 'Sampling_floris_wcent_wdiam_%d' % i, 'Sampling_floris_overlap_%d' % i, 'Sampling_floris_power_%d' % i ]) if nSpeeds > 1: for i in range(0, nSpeeds): for ssn in samplingNonSampling: self.connect('windrose_speeds[%d]' % i, '%sfloris_power_%d.wind_speed' % (ssn, i)) self.connect('windrose_speeds[%d]' % i, '%sfloris_windframe_%d.wind_speed' % (ssn, i)) else: for i in range(0, nDirections): for ssn in samplingNonSampling: self.connect('windrose_speeds', '%sfloris_power_%d.wind_speed' % (ssn, i)) self.connect('windrose_speeds', '%sfloris_windframe_%d.wind_speed' % (ssn, i)) # add AEP calculations to workflow self.driver.workflow.add(['floris_AEP', 'floris_dist_const']) if optimize_position or optimize_yaw: # set up driver self.driver.iprint = 3 self.driver.accuracy = 1.0e-12 self.driver.maxiter = maxiter self.driver.add_objective('-floris_AEP.AEP') if optimize_position: self.driver.add_parameter('turbineX', low=7 * 126.4, high=np.sqrt(self.nTurbines) * 7 * 126.4) self.driver.add_parameter('turbineY', low=7 * 126.4, high=np.sqrt(self.nTurbines) * 7 * 126.4) self.driver.add_constraint( 'floris_dist_const.separation > 2*rotorDiameter[0]') if optimize_yaw: for direction in range(0, self.nDirections): self.driver.add_parameter('yaw_%d' % direction, low=-30., high=30., scaler=1.)
def configure(self): global_dvs = self.parent.get_global_des_vars() local_dvs = self.parent.get_local_des_vars_by_comp() objective = self.parent.get_objectives().items()[0] constraints = self.parent.list_constraints() coupling = self.parent.list_coupling_vars() self.parent.add('driver', FixedPointIterator()) self.parent.driver.max_iteration = 50 self.parent.driver.tolerance = .005 #set initial values for comp, param in global_dvs: param.initialize(self.parent) for comp, local_params in local_dvs.iteritems(): for param in local_params: param.initialize(self.parent) for couple in coupling.values(): couple.indep.set(couple.start) initial_conditions = [param.start for comp, param in global_dvs] self.parent.add_trait('global_des_vars', Array(initial_conditions, iotype="in")) for i, (comps, param) in enumerate(global_dvs): targets = param.targets self.parent.driver.add_parameter(targets, low=param.low, high=param.high, start=param.start) self.parent.driver.add_constraint("global_des_vars[%d]=%s" % (i, targets[0])) for comp, local_params in local_dvs.iteritems(): initial_conditions = [param.start for param in local_params] self.parent.add_trait('%s_local_des_vars' % comp, Array(initial_conditions, iotype="in")) for i, param in enumerate(local_params): self.parent.driver.add_parameter(param.targets, low=param.low, high=param.high, start=param.start) self.parent.driver.add_constraint('%s_local_des_vars[%d]=%s' % (comp, i, param.targets[0])) # Multidisciplinary Analysis mda = self.parent.add('mda', BroydenSolver()) for couple in coupling.values(): mda.add_parameter(couple.indep.target) mda.add_constraint("%s=%s" % (couple.indep.target, couple.dep.target)) #Global Sensitivity Analysis ssa = self.parent.add("ssa", SensitivityDriver()) ssa.workflow.add("mda") ssa.default_stepsize = 1.0e-6 ssa.add_objective(objective[1].text, name=objective[0]) for comps, param in global_dvs: ssa.add_parameter(param.targets, low=param.low, high=param.high) for constraint in constraints: ssa.add_constraint(constraint) #discipline sensitivity analyses sa_s = [] for comp, local_params in local_dvs.iteritems(): sa = self.parent.add('sa_%s' % comp, SensitivityDriver()) sa.default_stepsize = 1.0e-6 sa_s.append('sa_%s' % comp) for param in local_params: sa.add_parameter(param.targets, low=param.low, high=param.high, fd_step=.001) for constraint in constraints: sa.add_constraint(constraint) sa.add_objective(objective[1].text, name=objective[0]) #Linear System Optimizations # Discipline Optimization # (Only discipline1 has an optimization input) bbopts = [] for comp, local_params in local_dvs.iteritems(): bbopt = self.parent.add('bbopt_%s' % comp, SLSQPdriver()) bbopt.iprint = 0 bbopts.append('bbopt_%s' % comp) x_store = "%s_local_des_vars" % comp delta_x = [] df = [] dg = [] for i, param in enumerate(local_params): x_store_i = "%s[%d]" % (x_store, i) bbopt.add_parameter(x_store_i, low=param.low, high=param.high, start=param.start) dx = "(%s-%s)" % (x_store_i, param.targets[0]) delta_x.append(dx) #bbopt.add_constraint("%s < %f*%s" %(dx, .2, param.targets[0])) #bbopt.add_constraint("%s > -%f*%s "%(dx, .2, param.targets[0])) bbopt.add_constraint("%s < .5" % (dx, )) bbopt.add_constraint("%s > -.5" % (dx, )) df.append("sa_%s.dF[0][%d]*%s" % (comp, i, dx)) #build the linear constraint string for each constraint for j, const in enumerate(constraints): dg_j = [ "sa_%s.dG[%d][%d]*%s" % (comp, j, i, x) for i, x in enumerate(delta_x) ] constraint_parts = ["sa_%s.G[%d]" % (comp, j)] constraint_parts.extend(dg_j) lin_constraint = "%s < 0" % "+".join(constraint_parts) bbopt.add_constraint(lin_constraint) #build the linear objective string objective_parts = ["sa_%s.F[0]" % comp] objective_parts.extend(df) lin_objective = "+".join(objective_parts) bbopt.add_objective(lin_objective) # Global Optimization delta_z = [] df = [] dg = [] sysopt = self.parent.add('sysopt', SLSQPdriver()) sysopt.recorders = self.data_recorders sysopt.iprint = 0 for i, (comps, param) in enumerate(global_dvs): z_store = "global_des_vars[%d]" % i target = list(param.targets)[0] sysopt.add_parameter(z_store, low=param.low, high=param.high, start=param.start) dz = "(%s-%s)" % (z_store, target) delta_z.append(dz) #sysopt.add_constraint("%s < %f*%s" % (dz, .1, target)) #sysopt.add_constraint("%s > -%f*%s" % (dz, .1, target)) sysopt.add_constraint("%s < .5" % (dz, )) sysopt.add_constraint("%s > -.5" % (dz, )) df.append("ssa.dF[0][%d]*%s" % (i, dz)) dg_j = [ "ssa.dG[%d][%d]*%s" % (j, i, dz) for j, const in enumerate(constraints) ] dg.append(dg_j) objective_parts = ["ssa.F[0]"] objective_parts.extend(df) lin_objective = "+".join(objective_parts) sysopt.add_objective(lin_objective) #build the linear constraint string for each constraint for j, const in enumerate(constraints): dg_j = [ "ssa.dG[%d][%d]*%s" % (j, i, x) for i, x in enumerate(delta_z) ] constraint_parts = ["ssa.G[%d]" % j] constraint_parts.extend(dg_j) lin_constraint = "%s < 0" % "+".join(constraint_parts) sysopt.add_constraint(lin_constraint) #self.parent.driver.workflow.add("mda") self.parent.driver.workflow.add(sa_s) if global_dvs: self.parent.driver.workflow.add("ssa") self.parent.driver.workflow.add(bbopts) if global_dvs: self.parent.driver.workflow.add("sysopt")
def configure(self): # --------------------------------------------------------------------------- # # --- Instantiate Counter Component # --------------------------------------------------------------------------- # self.add('counter', DOECounterComp()) # --------------------------------------------------------------------------- # # --- Instantiate Subcounter Component # --------------------------------------------------------------------------- # self.add('subcounter', SubCounterComp()) # --------------------------------------------------------------------------- # # --- Instantiate Restart Component # --------------------------------------------------------------------------- # self.add('restart_doe', RestartComp()) # --------------------------------------------------------------------------- # # --- Instantiate NPSS Non-Reacting Component # --------------------------------------------------------------------------- # self.add('npss_nonreacting', NpssNonreacting()) self.npss_nonreacting.Comb_dPqPBase = init_dP() # --------------------------------------------------------------------------- # # --- Instantiate NPSS Reacting Component # --------------------------------------------------------------------------- # self.add('npss_reacting', NpssReacting()) self.npss_reacting.Comb_dPqPBase = init_dP() # --------------------------------------------------------------------------- # # --- Instantiate Geometry Component # --------------------------------------------------------------------------- # self.add('geometry', GeometryComp()) # --------------------------------------------------------------------------- # # --- Instantiate Mesh Component # --------------------------------------------------------------------------- # self.add('mesh', MeshComp()) # --------------------------------------------------------------------------- # # --- Instantiate NCC Non-reacting Component (1-Step Chemistry) # --------------------------------------------------------------------------- # self.add('ncc_nonreacting', NCCcomponent()) self.ncc_nonreacting.max_iterations_per_time_step = 40000 self.ncc_nonreacting.nonreacting = True self.ncc_nonreacting.continuity_goal = 2000 self.ncc_nonreacting.restarts = 40000 self.ncc_nonreacting.CFL = 0.8 self.ncc_nonreacting.mass_imbalance_goal = 1.0E-2 self.ncc_nonreacting.aero2 = -1.0E-3 self.ncc_nonreacting.k_e2 = -1.0E-3 self.ncc_nonreacting.species2 = -1.0E-3 self.ncc_nonreacting.enthalpy2 = -1.0E-3 self.ncc_nonreacting.aero4 = 0.05 self.ncc_nonreacting.k_e4 = 0.05 self.ncc_nonreacting.species4 = 0.05 self.ncc_nonreacting.enthalpy4 = 0.05 self.ncc_nonreacting.twall_run = 4.0 self.ncc_nonreacting._num_procs = 400 # --- Must be divisible by 20 to run on Ivy Bridge # --------------------------------------------------------------------------- # # --- Instantiate NCC Reacting Component (1-Step Chemistry) # --------------------------------------------------------------------------- # self.add('ncc_reacting', NCCcomponent()) self.ncc_reacting.reacting = True self.ncc_reacting.continuity_goal = 750 self.ncc_reacting.max_iterations_per_time_step = 15000 self.ncc_reacting.restarts = 15000 self.ncc_reacting.CFL = 0.8 self.ncc_reacting.pbcfl = 0.375 self.ncc_reacting.etau_beta = 0.15 self.ncc_reacting.mass_imbalance_goal = 1.0E-3 self.ncc_reacting.aux_var_name_list = "'unmixed' 'C12H23'" self.ncc_reacting.spec_name_ignite = 'C12H23' self.ncc_reacting.fuel_symbol = 'C12H23' self.ncc_reacting.combust = True self.ncc_reacting.lspray = True self.ncc_reacting.aero2 = -2.5E-3 self.ncc_reacting.k_e2 = -2.5E-3 self.ncc_reacting.species2 = -2.5E-3 self.ncc_reacting.enthalpy2 = -2.5E-3 self.ncc_reacting.aero4 = 0.05 self.ncc_reacting.k_e4 = 0.05 self.ncc_reacting.species4 = 0.05 self.ncc_reacting.enthalpy4 = 0.05 self.ncc_reacting.ignite_done_model = 0 self.ncc_reacting.ignition_on = True self.ncc_reacting.no_of_streams = 16 self.ncc_reacting.twall_run = 4.0 self.ncc_reacting._num_procs = 400 # --- Must be divisible by 20 to run on Ivy Bridge # --------------------------------------------------------------------------- # # --- Instantiate NCC Reacting Component (Detailed Chemistry) # --------------------------------------------------------------------------- # self.add('ncc_reacting2', NCCcomponent()) self.ncc_reacting2.reacting2 = True self.ncc_reacting2.continuity_goal = 750 self.ncc_reacting2.max_iterations_per_time_step = 10000 self.ncc_reacting2.restarts = 10000 self.ncc_reacting2.CFL = 0.9 self.ncc_reacting.pbcfl = 0.5 self.ncc_reacting2.mass_imbalance_goal = 1.0E-3 self.ncc_reacting2.aux_var_name_list = "'unmixed' 'C11H21'" self.ncc_reacting2.spec_name_ignite = 'C11H21' self.ncc_reacting2.fuel_symbol = 'C11H21' self.ncc_reacting2.combust = True self.ncc_reacting2.lspray = True self.ncc_reacting2.aero2 = -1.0E-3 self.ncc_reacting2.k_e2 = -1.0E-3 self.ncc_reacting2.species2 = -1.0E-3 self.ncc_reacting2.enthalpy2 = -1.0E-3 self.ncc_reacting2.aero4 = 0.05 self.ncc_reacting2.k_e4 = 0.05 self.ncc_reacting2.species4 = 0.05 self.ncc_reacting2.enthalpy4 = 0.05 self.ncc_reacting2.energy = 0.0001 self.ncc_reacting2.when_start_spray = 1 self.ncc_reacting2.ignite_done_model = 0 self.ncc_reacting2.ignition_on = True self.ncc_reacting2.twall_run = 7.5 self.ncc_reacting2._num_procs = 400 # --- Must be divisible by 20 to Run on Ivy Bridge # --------------------------------------------------------------------------- # # --- Instantiate Tecplot Nonreacting Component # --------------------------------------------------------------------------- # self.add('tecplot_nonreacting', TecplotComp()) self.tecplot_nonreacting.nonreacting = True # --------------------------------------------------------------------------- # # --- Instantiate Tecplot Reacting Spray Component # --------------------------------------------------------------------------- # self.add('tecplot_reacting', TecplotComp()) self.tecplot_reacting.reacting = True # --------------------------------------------------------------------------- # # --- Instantiate Tecplot Reacting Spray Component # --------------------------------------------------------------------------- # self.add('tecplot_reacting2', TecplotComp()) self.tecplot_reacting2.reacting2 = True # --------------------------------------------------------------------------- # # --- Create Driver Instances # --------------------------------------------------------------------------- # # --- Top Level Assembly Driver self.add('driver', IterateUntil()) self.driver.max_iterations = 1 self.driver.workflow = SequentialWorkflow() # --- Inner Nonreacting Driver (Fixed Point) self.add('nonreacting_driver', FixedPointIterator()) self.nonreacting_driver.workflow = SequentialWorkflow() self.nonreacting_driver.step_size = 0.125 self.nonreacting_driver.max_iteration = 1 self.nonreacting_driver.tolerance = 0.001 # --- Inner Reacting Driver self.add('reacting_driver', IterateUntil()) self.reacting_driver.max_iterations = 1 self.reacting_driver.workflow = SequentialWorkflow() # --- Inner Reacting Driver #2 self.add('reacting_driver2', IterateUntil()) self.reacting_driver2.max_iterations = 2 self.reacting_driver2.workflow = SequentialWorkflow() self.reacting_driver2.add_stop_condition( 'tecplot_reacting2.dTqTBase < 0.0025') # --- Run Design at All ICAO Power Settings self.add('power_hook', CaseIteratorDriver()) self.power_hook.workflow = SequentialWorkflow() self.power_hook.iterator = CSVCaseIterator(filename='ICAOsettings.csv') self.power_hook.workflow.add(['reacting_driver2']) # --------------------------------------------------------------------------- # # --- Create Main Assembly Workflow # --------------------------------------------------------------------------- # # --- Add component instances to top-level assembly #self.driver.workflow.add(['counter', 'restart_doe', 'geometry', 'mesh', 'nonreacting_driver', 'reacting_driver', 'reacting_driver2']) #self.driver.workflow.add(['counter', 'restart_doe', 'geometry', 'nonreacting_driver', 'reacting_driver', 'reacting_driver2']) #self.driver.workflow.add(['counter', 'restart_doe', 'geometry', 'reacting_driver2']) #self.driver.workflow.add(['counter', 'restart_doe', 'geometry', 'npss_nonreacting', 'npss_reacting']) self.driver.workflow.add( ['counter', 'restart_doe', 'geometry', 'power_hook']) # --------------------------------------------------------------------------- # # --- Create Sub-Assembly Workflows # --------------------------------------------------------------------------- # # --- Inner Nonreacting Loop - Solve via fixed point iteration self.nonreacting_driver.workflow.add([ 'subcounter', 'npss_nonreacting', 'ncc_nonreacting', 'tecplot_nonreacting' ]) # --- Add solver independents and dependents for fixed point iterator self.nonreacting_driver.add_parameter( ['npss_nonreacting.Comb_dPqPBase', 'npss_reacting.Comb_dPqPBase'], low=-9.e99, high=9.e99) self.nonreacting_driver.add_constraint( 'tecplot_nonreacting.dPqPBase = npss_nonreacting.Comb_dPqPBase') # --- Inner Reacting Loop - Run Once self.reacting_driver.workflow.add([ 'subcounter', 'npss_reacting', 'ncc_reacting', 'tecplot_reacting' ]) # --- Inner Reacting Loop #2 - Run Once self.reacting_driver2.workflow.add([ 'subcounter', 'npss_reacting', 'ncc_reacting2', 'tecplot_reacting2' ]) # --------------------------------------------------------------------------- # # --- Add Driver Events --- Comment this section out to override numbering # --------------------------------------------------------------------------- # if (self.subcounter._iteration == 0): self.driver.add_event('subcounter.reset_iteration') self.driver.add_event('ncc_nonreacting.clean_start') self.power_hook.add_event('subcounter.reset_iteration') self.power_hook.add_event('ncc_nonreacting.clean_start') # --------------------------------------------------------------------------- # # --- Specify Case Recorders # --------------------------------------------------------------------------- # self.driver.case_outputs = [ 'geometry.pilot_recession', 'geometry.vane_height', 'geometry.venturi_angle', 'nonreacting_driver.ncc_nonreacting.FAR', 'nonreacting_driver.tecplot_nonreacting.dPqPBase' ] self.power_hook.recorders = [DumpCaseRecorder()] # --------------------------------------------------------------------------- # # --- Create Data Connections # --------------------------------------------------------------------------- # self.connect('counter.config', [ 'subcounter.case', 'restart_doe.config', 'geometry.config', 'mesh.config' ]) self.connect('subcounter.config', [ 'ncc_nonreacting.config', 'ncc_reacting.config', 'ncc_reacting2.config', 'tecplot_nonreacting.config', 'tecplot_reacting.config', 'tecplot_reacting2.config' ]) self.connect('restart_doe.pilot_recession', ['geometry.pilot_recession', 'mesh.pilot_recession']) self.connect('restart_doe.venturi_angle', ['geometry.venturi_angle', 'mesh.venturi_angle']) self.connect('restart_doe.vane_height', ['geometry.vane_height', 'mesh.vane_height']) self.connect('geometry.injector_dia', [ 'ncc_nonreacting.injector_dia', 'ncc_nonreacting.bc1_Lmix', 'ncc_reacting.injector_dia', 'ncc_reacting.bc1_Lmix', 'ncc_reacting2.injector_dia', 'ncc_reacting2.bc1_Lmix' ]) self.connect('geometry.sector_area', [ 'npss_nonreacting.Inlet_Fl_O_Aphy', 'npss_nonreacting.Comb_Fl_O_Aphy', 'npss_nonreacting.Bld1_Fl_O_Aphy', 'npss_nonreacting.Bld2_Fl_O_Aphy' ]) self.connect('geometry.sector_area', [ 'npss_reacting.Inlet_Fl_O_Aphy', 'npss_reacting.Comb_Fl_O_Aphy', 'npss_reacting.Bld1_Fl_O_Aphy', 'npss_reacting.Bld2_Fl_O_Aphy' ]) self.connect('geometry.venturi_throat_area', [ 'npss_nonreacting.Conv_Duct_Fl_O_Aphy', 'npss_reacting.Conv_Duct_Fl_O_Aphy' ]) self.connect('geometry.venturi_exit_area', [ 'npss_nonreacting.Div_Duct_Fl_O_Aphy', 'npss_reacting.Div_Duct_Fl_O_Aphy' ]) self.connect('npss_nonreacting.Conv_Duct_Fl_O_W', 'ncc_nonreacting.bc1_mdot') self.connect('npss_nonreacting.Inlet_Fl_O_V', 'ncc_nonreacting.u_init') self.connect( 'npss_nonreacting.Inlet_Fl_O_Ts', ['ncc_nonreacting.bc1_Tstatic', 'ncc_nonreacting.Tstatic_init']) self.connect( 'npss_nonreacting.Comb_Fl_O_Ps', ['ncc_nonreacting.bc2_Pstatic', 'ncc_nonreacting.Pstatic_init']) self.connect('npss_nonreacting.Comb_Fl_O_Ts', 'ncc_nonreacting.bc2_Tstatic') self.connect('npss_nonreacting.Comb_FAR', 'ncc_nonreacting.FAR') self.connect('npss_nonreacting.Inlet_Fl_O_rhos', 'ncc_nonreacting.rho_air') self.connect('npss_nonreacting.Bld1_BldOut_W', 'ncc_nonreacting.bc7_mdot') self.connect('npss_nonreacting.Bld1_Fl_O_Ts', 'ncc_nonreacting.bc7_Tstatic') self.connect('npss_reacting.Conv_Duct_Fl_O_W', ['ncc_reacting.bc1_mdot', 'ncc_reacting2.bc1_mdot']) self.connect('npss_reacting.Inlet_Fl_O_Ts', ['ncc_reacting.bc1_Tstatic', 'ncc_reacting2.bc1_Tstatic']) self.connect('npss_reacting.Comb_Fl_O_Ps', [ 'ncc_reacting.bc2_Pstatic', 'ncc_reacting2.bc2_Pstatic', 'ncc_reacting.Pstatic_init', 'ncc_reacting2.Pstatic_init' ]) self.connect('npss_reacting.Comb_Fl_O_Ts', [ 'ncc_reacting.bc2_Tstatic', 'ncc_reacting2.bc2_Tstatic', 'ncc_reacting.Tstatic_init', 'ncc_reacting2.Tstatic_init' ]) self.connect('npss_reacting.Comb_FAR', ['ncc_reacting.FAR', 'ncc_reacting2.FAR']) self.connect('npss_reacting.Inlet_Fl_O_rhos', ['ncc_reacting.rho_air', 'ncc_reacting2.rho_air']) self.connect('npss_reacting.Bld1_BldOut_W', ['ncc_reacting.bc7_mdot', 'ncc_reacting2.bc7_mdot']) self.connect('npss_reacting.Bld1_Fl_O_Ts', ['ncc_reacting.bc7_Tstatic', 'ncc_reacting2.bc7_Tstatic'])
def __init__(self): super(Scalable, self).__init__() #three components: d0,d1,d2 obj = "d0.z0**2+d0.z1**2+d0.z2**2+d0.y_out**2+d1.y_out**2+d2.y_out**2" d0_const = "1-d0.y_out/c0 <= 0" d1_const = "1-d1.y_out/c1 <= 0" d2_const = "1-d2.y_out/c2 <= 0" #initial MDA mda = self.add("mda", BroydenSolver()) mda.add_parameter("d0.y_in0", low=-1e99, high=1e99) mda.add_parameter("d0.y_in1", low=-1e99, high=1e99) mda.add_constraint("d0.y_out=d1.y_in0") mda.add_constraint("d0.y_out=d2.y_in0") mda.add_parameter("d1.y_in0", low=-1e99, high=1e99) mda.add_parameter("d1.y_in1", low=-1e99, high=1e99) mda.add_constraint("d1.y_out=d0.y_in0") mda.add_constraint("d1.y_out=d2.y_in1") mda.add_parameter("d2.y_in0", low=-1e99, high=1e99) mda.add_parameter("d2.y_in1", low=-1e99, high=1e99) mda.add_constraint("d2.y_out=d0.y_in1") mda.add_constraint("d2.y_out=d1.y_in1") sa0 = self.add('sa0', SensitivityDriver()) sa0.differentiator = FiniteDifference() sa0.add_parameter('d0.x0', low=-10, high=10) sa0.add_parameter('d0.x1', low=-10, high=10) sa0.add_parameter('d0.x2', low=-10, high=10) sa0.add_objective(obj) sa0.add_constraint(d0_const) sa1 = self.add('sa1', SensitivityDriver()) sa1.differentiator = FiniteDifference() sa1.add_parameter('d1.x0', low=-10, high=10) sa1.add_parameter('d1.x1', low=-10, high=10) sa1.add_parameter('d1.x2', low=-10, high=10) sa1.add_objective(obj) sa1.add_constraint(d1_const) sa2 = self.add('sa2', SensitivityDriver()) sa2.differentiator = FiniteDifference() sa2.add_parameter('d0.x0', low=-10, high=10) sa2.add_parameter('d0.x1', low=-10, high=10) sa2.add_parameter('d0.x2', low=-10, high=10) sa2.add_objective(obj) sa2.add_constraint(d2_const) ssa = self.add('ssa', SensitivityDriver()) ssa.differentiator = FiniteDifference() ssa.add_parameter(("d0.z0", "d1.z0", "d2.z0"), low=-10, high=10) ssa.add_parameter(("d0.z1", "d1.z1", "d2.z1"), low=-10, high=10) ssa.add_parameter(("d0.z2", "d1.z2", "d2.z2"), low=-10, high=10) ssa.add_objective(obj) ssa.add_constraint(d0_const) ssa.add_constraint(d1_const) ssa.add_constraint(d2_const) bbopt0 = self.add('bbopt0', CONMINdriver()) bbopt0.add_parameter('d0_local_des_vars[0]', low=-10, high=10) bbopt0.add_parameter('d0_local_des_vars[1]', low=-10, high=10) bbopt0.add_parameter('d0_local_des_vars[2]', low=-10, high=10) bbopt0.add_objective( 'sa0.F[0] + sa0.dF[0][0]*(d0_local_des_vars[0]-d0.x0)' '+ sa0.dF[0][1]*(d0_local_des_vars[1]-d0.x1)' '+ sa0.dF[0][2]*(d0_local_des_vars[2]-d0.x2)') bbopt0.add_constraint( 'sa0.G[0] + sa0.dG[0][0]*(d0_local_des_vars[0]-d0.x0)' '+ sa0.dG[0][1]*(d0_local_des_vars[1]-d0.x1)' '+ sa0.dG[0][2]*(d0_local_des_vars[2]-d0.x2) <= 0') bbopt0.add_constraint( '(d0_local_des_vars[0]-d0.x0)<=(percent*d0.x0+.0001)*factor**(mda.exec_count-offset)' ) bbopt0.add_constraint( '(d0_local_des_vars[1]-d1.x1)<=(percent*d0.x1+.0001)*factor**(mda.exec_count-offset)' ) bbopt0.add_constraint( '(d0_local_des_vars[2]-d2.x2)<=(percent*d0.x2+.0001)*factor**(mda.exec_count-offset)' ) bbopt0.add_constraint( '(d0_local_des_vars[0]-d0.x0)>=(-percent*d0.x0-.0001)*factor**(mda.exec_count-offset)' ) bbopt0.add_constraint( '(d0_local_des_vars[1]-d1.x1)>=(-percent*d0.x1-.0001)*factor**(mda.exec_count-offset)' ) bbopt0.add_constraint( '(d0_local_des_vars[2]-d2.x2)>=(-percent*d0.x2-.0001)*factor**(mda.exec_count-offset)' ) bbopt1 = self.add('bbopt1', CONMINdriver()) bbopt1.add_parameter('d1_local_des_vars[0]', low=-10, high=10) bbopt1.add_parameter('d1_local_des_vars[1]', low=-10, high=10) bbopt1.add_parameter('d1_local_des_vars[2]', low=-10, high=10) bbopt1.add_objective( 'sa1.F[0] + sa1.dF[0][0]*(d1_local_des_vars[0]-d1.x0)' '+ sa1.dF[0][1]*(d1_local_des_vars[1]-d1.x1)' '+ sa1.dF[0][2]*(d1_local_des_vars[2]-d1.x2)') bbopt1.add_constraint( 'sa1.G[0] + sa1.dG[0][0]*(d1_local_des_vars[0]-d1.x0)' '+ sa1.dG[0][1]*(d1_local_des_vars[1]-d1.x1)' '+ sa1.dG[0][2]*(d1_local_des_vars[2]-d1.x2) <= 0') bbopt1.add_constraint( '(d1_local_des_vars[0]-d1.x0)<=(percent*d1.x0+.0001)*factor**(mda.exec_count-offset)' ) bbopt1.add_constraint( '(d1_local_des_vars[1]-d1.x1)<=(percent*d1.x1+.0001)*factor**(mda.exec_count-offset)' ) bbopt1.add_constraint( '(d1_local_des_vars[2]-d1.x2)<=(percent*d1.x2+.0001)*factor**(mda.exec_count-offset)' ) bbopt1.add_constraint( '(d1_local_des_vars[0]-d1.x0)>=(-percent*d1.x0-.0001)*factor**(mda.exec_count-offset)' ) bbopt1.add_constraint( '(d1_local_des_vars[1]-d1.x1)>=(-percent*d1.x1-.0001)*factor**(mda.exec_count-offset)' ) bbopt1.add_constraint( '(d1_local_des_vars[2]-d1.x2)>=(-percent*d1.x2-.0001)*factor**(mda.exec_count-offset)' ) bbopt2 = self.add('bbopt2', CONMINdriver()) bbopt2.add_parameter('d2_local_des_vars[0]', low=-10, high=10) bbopt2.add_parameter('d2_local_des_vars[1]', low=-10, high=10) bbopt2.add_parameter('d2_local_des_vars[2]', low=-10, high=10) bbopt2.add_objective( 'sa2.F[0] + sa2.dF[0][0]*(d2_local_des_vars[0]-d2.x0)' '+ sa2.dF[0][1]*(d2_local_des_vars[1]-d2.x1)' '+ sa2.dF[0][2]*(d2_local_des_vars[2]-d2.x2)') bbopt2.add_constraint( 'sa2.G[0] + sa2.dG[0][0]*(d2_local_des_vars[0]-d2.x0)' '+ sa2.dG[0][1]*(d2_local_des_vars[1]-d2.x1)' '+ sa2.dG[0][2]*(d2_local_des_vars[2]-d2.x2) <= 0') bbopt2.add_constraint( '(d2_local_des_vars[0]-d2.x0)<=(percent*d2.x0+.0001)*factor**(mda.exec_count-offset)' ) bbopt2.add_constraint( '(d2_local_des_vars[1]-d2.x1)<=(percent*d2.x1+.0001)*factor**(mda.exec_count-offset)' ) bbopt2.add_constraint( '(d2_local_des_vars[2]-d2.x2)<=(percent*d2.x2+.0001)*factor**(mda.exec_count-offset)' ) bbopt2.add_constraint( '(d2_local_des_vars[0]-d2.x0)>=(-percent*d2.x0-.0001)*factor**(mda.exec_count-offset)' ) bbopt2.add_constraint( '(d2_local_des_vars[1]-d2.x1)>=(-percent*d2.x1-.0001)*factor**(mda.exec_count-offset)' ) bbopt2.add_constraint( '(d2_local_des_vars[2]-d2.x2)>=(-percent*d2.x2-.0001)*factor**(mda.exec_count-offset)' ) sysopt = self.add('sysopt', CONMINdriver()) sysopt.add_parameter('global_des_vars[0]', low=-10, high=10) sysopt.add_parameter('global_des_vars[1]', low=-10, high=10) sysopt.add_parameter('global_des_vars[2]', low=-10, high=10) sysopt.add_objective( 'ssa.F[0] + ssa.dF[0][0]*(global_des_vars[0]-d0.z0)' '+ ssa.dF[0][1]*(global_des_vars[1]-d0.z1)' '+ ssa.dF[0][2]*(global_des_vars[2]-d0.z2)') sysopt.add_constraint( 'ssa.G[0] + ssa.dG[0][0]*(global_des_vars[0]-d0.z0)' '+ ssa.dG[0][1]*(global_des_vars[1]-d0.z1)' '+ ssa.dG[0][2]*(global_des_vars[2]-d0.z2) <= 0') sysopt.add_constraint( 'ssa.G[1] + ssa.dG[1][0]*(global_des_vars[0]-d0.z0)' '+ ssa.dG[1][1]*(global_des_vars[1]-d0.z1)' '+ ssa.dG[1][2]*(global_des_vars[2]-d0.z2) <= 0') sysopt.add_constraint( 'ssa.G[2] + ssa.dG[2][0]*(global_des_vars[0]-d0.z0)' '+ ssa.dG[2][1]*(global_des_vars[1]-d0.z1)' '+ ssa.dG[2][2]*(global_des_vars[2]-d0.z2) <= 0') sysopt.add_constraint( '(global_des_vars[0]-d0.z0) >= (percent*d0.z0 +.0001)*factor**(mda.exec_count-offset)' ) sysopt.add_constraint( '(global_des_vars[0]-d0.z0) <= (-percent*d0.z0 -.0001)*factor**(mda.exec_count-offset)' ) sysopt.add_constraint( '(global_des_vars[1]-d0.z1) >= (percent*d0.z1 +.0001)*factor**(mda.exec_count-offset)' ) sysopt.add_constraint( '(global_des_vars[1]-d0.z1) <= (-percent*d0.z1 -.0001)*factor**(mda.exec_count-offset)' ) sysopt.add_constraint( '(global_des_vars[2]-d0.z2) >= (percent*d0.z2 +.0001)*factor**(mda.exec_count-offset)' ) sysopt.add_constraint( '(global_des_vars[2]-d0.z2) <= (-percent*d0.z2 -.0001)*factor**(mda.exec_count-offset)' ) debug = self.add('debug', DebugComp()) debug.force_execute = True driver = self.add('driver', FixedPointIterator()) driver.add_parameter('d0.x0', low=-1e99, high=1e99) driver.add_parameter('d0.x1', low=-1e99, high=1e99) driver.add_parameter('d0.x2', low=-1e99, high=1e99) driver.add_constraint('d0_local_des_vars[0]=d0.x0') driver.add_constraint('d0_local_des_vars[1]=d0.x1') driver.add_constraint('d0_local_des_vars[2]=d0.x2') driver.add_parameter('d1.x0', low=-1e99, high=1e99) driver.add_parameter('d1.x1', low=-1e99, high=1e99) driver.add_parameter('d1.x2', low=-1e99, high=1e99) driver.add_constraint('d1_local_des_vars[0]=d1.x0') driver.add_constraint('d1_local_des_vars[1]=d1.x1') driver.add_constraint('d1_local_des_vars[2]=d1.x2') driver.add_parameter('d2.x0', low=-1e99, high=1e99) driver.add_parameter('d2.x1', low=-1e99, high=1e99) driver.add_parameter('d2.x2', low=-1e99, high=1e99) driver.add_constraint('d2_local_des_vars[0]=d2.x0') driver.add_constraint('d2_local_des_vars[1]=d2.x1') driver.add_constraint('d2_local_des_vars[2]=d2.x2') driver.add_parameter(['d0.z0', 'd1.z0', 'd2.z0'], low=-1e99, high=1e99) driver.add_parameter(['d0.z1', 'd1.z1', 'd2.z1'], low=-1e99, high=1e99) driver.add_parameter(['d0.z2', 'd1.z2', 'd2.z2'], low=-1e99, high=1e99) driver.add_constraint('global_des_vars[0]=d0.z0') driver.add_constraint('global_des_vars[1]=d0.z1') driver.add_constraint('global_des_vars[2]=d0.z2') self.driver.workflow.add([ 'mda', 'sa0', 'sa1', 'sa2', 'ssa', 'bbopt0', 'bbopt1', 'bbopt2', 'sysopt', 'debug' ])
def configure_turbine(assembly, with_new_nacelle=True, flexible_blade=False, with_3pt_drive=False): """a stand-alone configure method to allow for flatter assemblies Parameters ---------- assembly : Assembly an openmdao assembly to be configured with_new_nacelle : bool False uses the default implementation, True uses an experimental implementation designed to smooth out discontinities making in amenable for gradient-based optimization flexible_blade : bool if True, internally solves the coupled aero/structural deflection using fixed point iteration. Note that the coupling is currently only in the flapwise deflection, and is primarily only important for highly flexible blades. If False, the aero loads are passed to the structure but there is no further iteration. """ # --- general turbine configuration inputs--- assembly.add( 'rho', Float(1.225, iotype='in', units='kg/m**3', desc='density of air', deriv_ignore=True)) assembly.add( 'mu', Float(1.81206e-5, iotype='in', units='kg/m/s', desc='dynamic viscosity of air', deriv_ignore=True)) assembly.add( 'shear_exponent', Float(0.2, iotype='in', desc='shear exponent', deriv_ignore=True)) assembly.add('hub_height', Float(90.0, iotype='in', units='m', desc='hub height')) assembly.add( 'turbine_class', Enum('I', ('I', 'II', 'III', 'IV'), iotype='in', desc='IEC turbine class')) assembly.add( 'turbulence_class', Enum('B', ('A', 'B', 'C'), iotype='in', desc='IEC turbulence class class')) assembly.add( 'g', Float(9.81, iotype='in', units='m/s**2', desc='acceleration of gravity', deriv_ignore=True)) assembly.add( 'cdf_reference_height_wind_speed', Float( 90.0, iotype='in', desc= 'reference hub height for IEC wind speed (used in CDF calculation)' )) assembly.add('downwind', Bool(False, iotype='in', desc='flag if rotor is downwind')) assembly.add( 'tower_d', Array([0.0], iotype='in', units='m', desc='diameters along tower')) assembly.add('generator_speed', Float(iotype='in', units='rpm', desc='generator speed')) assembly.add( 'machine_rating', Float(5000.0, units='kW', iotype='in', desc='machine rated power')) assembly.add( 'rna_weightM', Bool(True, iotype='in', desc='flag to consider or not the RNA weight effect on Moment')) assembly.add('rotor', RotorSE()) if with_new_nacelle: assembly.add('hub', HubSE()) assembly.add('hubSystem', Hub_System_Adder_drive()) assembly.add('moments', blade_moment_transform()) assembly.add('forces', blade_force_transform()) if with_3pt_drive: assembly.add('nacelle', Drive3pt()) else: assembly.add('nacelle', Drive4pt()) else: assembly.add('nacelle', DriveWPACT()) assembly.add('hub', HubWPACT()) assembly.add('rna', RNAMass()) assembly.add('rotorloads1', RotorLoads()) assembly.add('rotorloads2', RotorLoads()) assembly.add('tower', TowerSE()) assembly.add('maxdeflection', MaxTipDeflection()) if flexible_blade: assembly.add('fpi', FixedPointIterator()) assembly.fpi.workflow.add(['rotor']) assembly.fpi.add_parameter('rotor.delta_precurve_sub', low=-1.e99, high=1.e99) assembly.fpi.add_parameter('rotor.delta_bladeLength', low=-1.e99, high=1.e99) assembly.fpi.add_constraint( 'rotor.delta_precurve_sub = rotor.delta_precurve_sub_out') assembly.fpi.add_constraint( 'rotor.delta_bladeLength = rotor.delta_bladeLength_out') assembly.fpi.max_iteration = 20 assembly.fpi.tolerance = 1e-8 assembly.driver.workflow.add(['fpi']) else: assembly.driver.workflow.add(['rotor']) assembly.driver.workflow.add([ 'hub', 'nacelle', 'tower', 'maxdeflection', 'rna', 'rotorloads1', 'rotorloads2' ]) if with_new_nacelle: assembly.driver.workflow.add(['hubSystem', 'moments', 'forces']) # TODO: rotor drivetrain design should be connected to nacelle drivetrain design # connections to rotor assembly.connect('machine_rating', 'rotor.control.ratedPower') assembly.connect('rho', 'rotor.rho') assembly.connect('mu', 'rotor.mu') assembly.connect('shear_exponent', 'rotor.shearExp') assembly.connect('hub_height', 'rotor.hubHt') assembly.connect('turbine_class', 'rotor.turbine_class') assembly.connect('turbulence_class', 'rotor.turbulence_class') assembly.connect('g', 'rotor.g') assembly.connect('cdf_reference_height_wind_speed', 'rotor.cdf_reference_height_wind_speed') # connections to hub and hub system assembly.connect('rotor.mass_one_blade', 'hub.blade_mass') assembly.connect('rotor.root_bending_moment', 'hub.rotor_bending_moment') assembly.connect('rotor.diameter', ['hub.rotor_diameter']) assembly.connect('rotor.hub_diameter', 'hub.blade_root_diameter') assembly.connect('rotor.nBlades', 'hub.blade_number') if with_new_nacelle: assembly.connect('machine_rating', 'hub.machine_rating') assembly.connect('rotor.diameter', ['hubSystem.rotor_diameter']) assembly.connect('nacelle.MB1_location', 'hubSystem.MB1_location') # TODO: bearing locations assembly.connect('nacelle.L_rb', 'hubSystem.L_rb') assembly.connect('rotor.tilt', 'hubSystem.shaft_angle') assembly.connect('hub.hub_diameter', 'hubSystem.hub_diameter') assembly.connect('hub.hub_thickness', 'hubSystem.hub_thickness') assembly.connect('hub.hub_mass', 'hubSystem.hub_mass') assembly.connect('hub.spinner_mass', 'hubSystem.spinner_mass') assembly.connect('hub.pitch_system_mass', 'hubSystem.pitch_system_mass') # connections to nacelle #TODO: fatigue option variables assembly.connect('rotor.diameter', 'nacelle.rotor_diameter') assembly.connect('1.5 * rotor.ratedConditions.Q', 'nacelle.rotor_torque') assembly.connect('rotor.ratedConditions.T', 'nacelle.rotor_thrust') assembly.connect('rotor.ratedConditions.Omega', 'nacelle.rotor_speed') assembly.connect('machine_rating', 'nacelle.machine_rating') assembly.connect('rotor.root_bending_moment', 'nacelle.rotor_bending_moment') assembly.connect('generator_speed/rotor.ratedConditions.Omega', 'nacelle.gear_ratio') assembly.connect( 'tower_d[-1]', 'nacelle.tower_top_diameter') # OpenMDAO circular dependency issue assembly.connect( 'rotor.mass_all_blades + hub.hub_system_mass', 'nacelle.rotor_mass') # assuming not already in rotor force / moments # variable connections for new nacelle if with_new_nacelle: assembly.connect('rotor.nBlades', 'nacelle.blade_number') assembly.connect('rotor.tilt', 'nacelle.shaft_angle') assembly.connect('333.3 * machine_rating / 1000.0', 'nacelle.shrink_disc_mass') assembly.connect('rotor.hub_diameter', 'nacelle.blade_root_diameter') #moments # assembly.connect('rotor.Q_extreme','nacelle.rotor_bending_moment_x') assembly.connect('rotor.Mxyz_0', 'moments.b1') assembly.connect('rotor.Mxyz_120', 'moments.b2') assembly.connect('rotor.Mxyz_240', 'moments.b3') assembly.connect('rotor.Pitch', 'moments.pitch_angle') assembly.connect('rotor.TotalCone', 'moments.cone_angle') assembly.connect('moments.Mx', 'nacelle.rotor_bending_moment_x' ) #accounted for in ratedConditions.Q assembly.connect('moments.My', 'nacelle.rotor_bending_moment_y') assembly.connect('moments.Mz', 'nacelle.rotor_bending_moment_z') #forces # assembly.connect('rotor.T_extreme','nacelle.rotor_force_x') assembly.connect('rotor.Fxyz_0', 'forces.b1') assembly.connect('rotor.Fxyz_120', 'forces.b2') assembly.connect('rotor.Fxyz_240', 'forces.b3') assembly.connect('rotor.Pitch', 'forces.pitch_angle') assembly.connect('rotor.TotalCone', 'forces.cone_angle') assembly.connect('forces.Fx', 'nacelle.rotor_force_x') assembly.connect('forces.Fy', 'nacelle.rotor_force_y') assembly.connect('forces.Fz', 'nacelle.rotor_force_z') '''if with_new_nacelle: assembly.connect('rotor.g', 'nacelle.g') # Only drive smooth taking g from rotor; TODO: update when drive_smooth is updated''' # connections to rna assembly.connect('rotor.mass_all_blades', 'rna.blades_mass') assembly.connect('rotor.I_all_blades', 'rna.blades_I') if with_new_nacelle: assembly.connect('hubSystem.hub_system_mass', 'rna.hub_mass') assembly.connect('hubSystem.hub_system_cm', 'rna.hub_cm') assembly.connect('hubSystem.hub_system_I', 'rna.hub_I') else: assembly.connect('hub.hub_system_mass', 'rna.hub_mass') assembly.connect('hub.hub_system_cm', 'rna.hub_cm') assembly.connect('hub.hub_system_I', 'rna.hub_I') assembly.connect('nacelle.nacelle_mass', 'rna.nac_mass') assembly.connect('nacelle.nacelle_cm', 'rna.nac_cm') assembly.connect('nacelle.nacelle_I', 'rna.nac_I') # connections to rotorloads1 assembly.connect('downwind', 'rotorloads1.downwind') assembly.connect('rna_weightM', 'rotorloads1.rna_weightM') assembly.connect('1.8 * rotor.ratedConditions.T', 'rotorloads1.F[0]') assembly.connect('rotor.ratedConditions.Q', 'rotorloads1.M[0]') if with_new_nacelle: assembly.connect('hubSystem.hub_system_cm', 'rotorloads1.r_hub') else: assembly.connect('hub.hub_system_cm', 'rotorloads1.r_hub') assembly.connect('rna.rna_cm', 'rotorloads1.rna_cm') assembly.connect('rotor.tilt', 'rotorloads1.tilt') assembly.connect('g', 'rotorloads1.g') assembly.connect('rna.rna_mass', 'rotorloads1.m_RNA') # connections to rotorloads2 assembly.connect('downwind', 'rotorloads2.downwind') assembly.connect('rna_weightM', 'rotorloads2.rna_weightM') assembly.connect('rotor.T_extreme', 'rotorloads2.F[0]') assembly.connect('rotor.Q_extreme', 'rotorloads2.M[0]') if with_new_nacelle: assembly.connect('hubSystem.hub_system_cm', 'rotorloads2.r_hub') else: assembly.connect('hub.hub_system_cm', 'rotorloads2.r_hub') assembly.connect('rna.rna_cm', 'rotorloads2.rna_cm') assembly.connect('rotor.tilt', 'rotorloads2.tilt') assembly.connect('g', 'rotorloads2.g') assembly.connect('rna.rna_mass', 'rotorloads2.m_RNA') # connections to tower assembly.connect('rho', 'tower.wind_rho') assembly.connect('mu', 'tower.wind_mu') assembly.connect('g', 'tower.g') assembly.connect('hub_height', 'tower.wind_zref') assembly.connect('tower_d', 'tower.d_param') assembly.connect('rotor.ratedConditions.V', 'tower.wind_Uref1') assembly.connect('rotor.V_extreme', 'tower.wind_Uref2') assembly.connect('rotor.yaw', 'tower.yaw') assembly.connect('hub_height - nacelle.nacelle_cm[2]', 'tower.z_param[-1]') #TODO: hub height should be derived assembly.connect('rna.rna_mass', 'tower.m[0]') assembly.connect('rna.rna_cm[0]', 'tower.mrhox[0]') assembly.connect('rna.rna_cm[1]', 'tower.mrhoy[0]') assembly.connect('rna.rna_cm[2]', 'tower.mrhoz[0]') assembly.connect('rna.rna_I_TT[0]', 'tower.mIxx[0]') assembly.connect('rna.rna_I_TT[1]', 'tower.mIyy[0]') assembly.connect('rna.rna_I_TT[2]', 'tower.mIzz[0]') assembly.connect('rna.rna_I_TT[3]', 'tower.mIxy[0]') assembly.connect('rna.rna_I_TT[4]', 'tower.mIxz[0]') assembly.connect('rna.rna_I_TT[5]', 'tower.mIyz[0]') assembly.connect('rotorloads1.top_F[0]', 'tower.Fx1[0]') assembly.connect('rotorloads1.top_F[1]', 'tower.Fy1[0]') assembly.connect('rotorloads1.top_F[2]', 'tower.Fz1[0]') assembly.connect('rotorloads1.top_M[0]', 'tower.Mxx1[0]') assembly.connect('rotorloads1.top_M[1]', 'tower.Myy1[0]') assembly.connect('rotorloads1.top_M[2]', 'tower.Mzz1[0]') assembly.connect('rotorloads2.top_F[0]', 'tower.Fx2[0]') assembly.connect('rotorloads2.top_F[1]', 'tower.Fy2[0]') assembly.connect('rotorloads2.top_F[2]', 'tower.Fz2[0]') assembly.connect('rotorloads2.top_M[0]', 'tower.Mxx2[0]') assembly.connect('rotorloads2.top_M[1]', 'tower.Myy2[0]') assembly.connect('rotorloads2.top_M[2]', 'tower.Mzz2[0]') # connections to maxdeflection assembly.connect('rotor.Rtip', 'maxdeflection.Rtip') assembly.connect('rotor.precurveTip', 'maxdeflection.precurveTip') assembly.connect('rotor.presweepTip', 'maxdeflection.presweepTip') assembly.connect('rotor.precone', 'maxdeflection.precone') assembly.connect('rotor.tilt', 'maxdeflection.tilt') if with_new_nacelle: assembly.connect('hubSystem.hub_system_cm', 'maxdeflection.hub_tt') else: assembly.connect('hub.hub_system_cm', 'maxdeflection.hub_tt') assembly.connect('tower.z_param', 'maxdeflection.tower_z') assembly.connect('tower.d_param', 'maxdeflection.tower_d') assembly.connect('hub_height - nacelle.nacelle_cm[2]', 'maxdeflection.towerHt')