def test_bounds_backtracking(self): class SimpleImplicitComp(Component): """ A Simple Implicit Component with an additional output equation. f(x,z) = xz + z - 4 y = x + 2z Sol: when x = 0.5, z = 2.666 Sol: when x = 2.0, z = 1.333 Coupled derivs: y = x + 8/(x+1) dy_dx = 1 - 8/(x+1)**2 = -2.5555555555555554 z = 4/(x+1) dz_dx = -4/(x+1)**2 = -1.7777777777777777 """ def __init__(self): super(SimpleImplicitComp, self).__init__() # Params self.add_param('x', 0.5) # Unknowns self.add_output('y', 0.0) # States self.add_state('z', 2.0, lower=1.5, upper=2.5) self.maxiter = 10 self.atol = 1.0e-12 def solve_nonlinear(self, params, unknowns, resids): pass def apply_nonlinear(self, params, unknowns, resids): """ Don't solve; just calculate the residual.""" x = params['x'] z = unknowns['z'] resids['z'] = x * z + z - 4.0 # Output equations need to evaluate a residual just like an explicit comp. resids['y'] = x + 2.0 * z - unknowns['y'] def linearize(self, params, unknowns, resids): """Analytical derivatives.""" J = {} # Output equation J[('y', 'x')] = np.array([1.0]) J[('y', 'z')] = np.array([2.0]) # State equation J[('z', 'z')] = np.array([params['x'] + 1.0]) J[('z', 'x')] = np.array([unknowns['z']]) return J #------------------------------------------------------ # Test that Newton doesn't drive it past lower bounds #------------------------------------------------------ top = Problem() top.root = Group() top.root.add('comp', SimpleImplicitComp()) top.root.ln_solver = ScipyGMRES() top.root.nl_solver = Newton() top.root.nl_solver.options['maxiter'] = 5 top.root.add('px', IndepVarComp('x', 1.0)) top.root.connect('px.x', 'comp.x') top.setup(check=False) top['px.x'] = 2.0 top.run() self.assertEqual(top['comp.z'], 1.5) #------------------------------------------------------ # Test that Newton doesn't drive it past upper bounds #------------------------------------------------------ top = Problem() top.root = Group() top.root.add('comp', SimpleImplicitComp()) top.root.ln_solver = ScipyGMRES() top.root.nl_solver = Newton() top.root.nl_solver.options['maxiter'] = 5 top.root.add('px', IndepVarComp('x', 1.0)) top.root.connect('px.x', 'comp.x') top.setup(check=False) top['px.x'] = 0.5 top.run() self.assertEqual(top['comp.z'], 2.5)
def test_param_as_obj_1darray_implicit(self): prob = Problem() root = prob.root = Group() root.add('comp', ExecComp('y = 3.0*x', x=np.zeros((10, )), y=np.zeros((10, ))), promotes=['x', 'y']) root.add('p', IndepVarComp('x', np.zeros((10, ))), promotes=['x']) prob.driver.add_desvar('x', np.ones((8, )), indices=[1, 2, 3, 4, 5, 6, 7, 8]) prob.driver.add_objective('x', indices=[5, 6, 7]) prob.driver.add_constraint('y', lower=-100.0) prob.setup(check=False) # Cheat to make Driver give derivs prob.driver._problem = prob prob.run() Jbase = np.zeros((3, 8)) Jbase[0, 4] = 1.0 Jbase[1, 5] = 1.0 Jbase[2, 6] = 1.0 J = prob.driver.calc_gradient(['x'], ['x'], mode='fwd', return_format='dict') diff = np.linalg.norm(J['x']['x'] - Jbase) assert_rel_error(self, diff, 0.0, 1.0e-9) J = prob.driver.calc_gradient(['x'], ['x'], mode='fwd', return_format='array') diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1.0e-9) J = prob.driver.calc_gradient(['x'], ['x'], mode='rev', return_format='dict') diff = np.linalg.norm(J['x']['x'] - Jbase) assert_rel_error(self, diff, 0.0, 1.0e-9) J = prob.driver.calc_gradient(['x'], ['x'], mode='rev', return_format='array') diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1.0e-9) J = prob.driver.calc_gradient(['x'], ['x'], mode='fd', return_format='dict') diff = np.linalg.norm(J['x']['x'] - Jbase) assert_rel_error(self, diff, 0.0, 1.0e-9) J = prob.driver.calc_gradient(['x'], ['x'], mode='fd', return_format='array') diff = np.linalg.norm(J - Jbase) assert_rel_error(self, diff, 0.0, 1.0e-9)
current = params['torque'] / k_t resistor_voltage = current * params['resistance'] inductor_impedance = frequency * params['inductance'] inductor_voltage = current * inductor_impedance speed_voltage = k_v * speed real_voltage = speed_voltage + resistor_voltage phase = numpy.arctan2(inductor_voltage, real_voltage) return phase if __name__ == '__main__': root = Group() prob = Problem(root) prob.root.add('comp', ElectricMotor()) prob.setup() prob.run() # Printing various input parameters print('kappa: %f' % prob['comp.KAPPA']) print('imax [A]: %f' % prob['comp.imax']) print('Max RPM: %f' % prob['comp.max_rpm']) print('Design Power [hp]: %f' % prob['comp.design_power']) print('LD Ratio:%f' % prob['comp.L_D_RATIO']) print('I0 [A]: %f' % prob['comp.i0']) print('Torque [N*m]: %f' % prob['comp.torque']) print('-----------------------------') # Outputs print('Max Torque [N*m]: %f' % prob['comp.tmax']) print('Kv [rad/s/V]: %f' % prob['comp.k_v'])
def test_load_balanced_doe_soft_fail(self): problem = Problem() root = problem.root = Group() root.add('indep_var', IndepVarComp('x', val=1.0)) root.add('const', IndepVarComp('c', val=2.0)) fail_rank = 1 root.add('mult', ExecComp4Test("y=c*x", fail_rank=fail_rank, fails=[3, 4, 5])) root.connect('indep_var.x', 'mult.x') root.connect('const.c', 'mult.c') num_levels = 25 num_par_doe = 5 problem.driver = FullFactorialDriver(num_levels=num_levels, num_par_doe=num_par_doe, load_balance=True) problem.driver.options['auto_add_response'] = True problem.driver.add_desvar('indep_var.x', lower=1.0, upper=float(num_levels)) problem.driver.add_objective('mult.y') problem.driver.add_response('mult.case_rank') problem.setup(check=False) problem.run() num_cases = len(problem.driver.recorders[0].iters) self.assertEqual(num_cases, num_levels) nfails = [0] * num_par_doe nsuccs = [0] * num_par_doe num_cases = 0 for responses, success, msg in problem.driver.get_responses(): responses = dict(responses) num_cases += 1 rank = responses['mult.case_rank'] if success: self.assertEqual(responses['indep_var.x'] * 2.0, responses['mult.y']) nsuccs[rank] += 1 else: nfails[rank] += 1 # there's a chance that the fail rank didn't get enough # cases to actually fail 3 times, so we need to check # how many cases it actually got. cases_in_fail_rank = nsuccs[fail_rank] + nfails[fail_rank] if cases_in_fail_rank > 5: self.assertEqual(nfails[fail_rank], 3) elif cases_in_fail_rank > 4: self.assertEqual(nfails[fail_rank], 2) elif cases_in_fail_rank > 3: self.assertEqual(nfails[fail_rank], 1) else: self.assertEqual(nfails[fail_rank], 0)
# --- Constructor for Surface Meshing Component --- # ------------------------------------------------- super(AFLR3, self).__init__() self.options['external_input_files'] = [ os.path.join('..', 'Meshing', 'AFLR3', 'Hyperloop_PW.b8.ugrid'), os.path.join('..', 'Meshing', 'AFLR3', 'Hyperloop.tags') ] self.options['external_output_files'] = [ os.path.join('..', 'Aero', 'Fun3D', 'Hyperloop.b8.ugrid') ] self.options['command'] = ['sh', self.aflr3_exec] def execute(self): # ------------------------------- # --- Execute AFLR3 Component --- # ------------------------------- super(AFLR3, self).solve_nonlinear(params, unknowns, resids) if __name__ == "__main__": # ------------------------- # --- Default Test Case --- # ------------------------- p = Problem(root=Group()) p.root.add('aflr3', AFLR3()) p.setup() p.run()
def PMSG_arms_Opt_example(): opt_problem = Problem(root=PMSG_arms_Opt()) #Example optimization of a PMSG_arms generator for costs on a 5 MW reference turbine # add optimizer and set-up problem (using user defined input on objective function) opt_problem.driver = pyOptSparseDriver() opt_problem.driver.options['optimizer'] = 'CONMIN' opt_problem.driver.add_objective('Costs') # Define Objective opt_problem.driver.opt_settings['IPRINT'] = 4 opt_problem.driver.opt_settings['ITRM'] = 3 opt_problem.driver.opt_settings['ITMAX'] = 10 opt_problem.driver.opt_settings['DELFUN'] = 1e-3 opt_problem.driver.opt_settings['DABFUN'] = 1e-3 opt_problem.driver.opt_settings['IFILE'] = 'CONMIN_PMSG_arms.out' opt_problem.root.deriv_options['type'] = 'fd' # Specificiency target efficiency(%) Eta_Target = 93.0 # Set bounds for design variables for a PMSG designed for a 5MW turbine opt_problem.driver.add_desvar('r_s', lower=0.5, upper=9.0) opt_problem.driver.add_desvar('l_s', lower=0.5, upper=2.5) opt_problem.driver.add_desvar('h_s', lower=0.04, upper=0.1) opt_problem.driver.add_desvar('tau_p', lower=0.04, upper=0.1) opt_problem.driver.add_desvar('h_m', lower=0.005, upper=0.1) opt_problem.driver.add_desvar('n_r', lower=5.0, upper=15.0) opt_problem.driver.add_desvar('h_yr', lower=0.045, upper=0.25) opt_problem.driver.add_desvar('h_ys', lower=0.045, upper=0.25) opt_problem.driver.add_desvar('b_r', lower=0.1, upper=1.5) opt_problem.driver.add_desvar('d_r', lower=0.1, upper=1.5) opt_problem.driver.add_desvar('t_wr', lower=0.001, upper=0.2) opt_problem.driver.add_desvar('n_s', lower=5.0, upper=15.0) opt_problem.driver.add_desvar('b_st', lower=0.1, upper=1.5) opt_problem.driver.add_desvar('d_s', lower=0.1, upper=1.5) opt_problem.driver.add_desvar('t_ws', lower=0.001, upper=0.2) # set up constraints for the PMSG_arms generator opt_problem.driver.add_constraint('B_symax', upper=2.0 - 1.0e-6) #1 opt_problem.driver.add_constraint('B_rymax', upper=2.0 - 1.0e-6) #2 opt_problem.driver.add_constraint('B_tmax', upper=2.0 - 1.0e-6) #3 opt_problem.driver.add_constraint('B_g', lower=0.7, upper=1.20) #4 opt_problem.driver.add_constraint('con_Bsmax', lower=0.0 + 1.0e-6) #5 opt_problem.driver.add_constraint('E_p', lower=500.0, upper=5000.0) #6 opt_problem.driver.add_constraint('con_uAs', lower=0.0 + 1.0e-6) #7 opt_problem.driver.add_constraint('con_zAs', lower=0.0 + 1.0e-6) #8 opt_problem.driver.add_constraint('con_yAs', lower=0.0 + 1.0e-6) #9 opt_problem.driver.add_constraint('con_uAr', lower=0.0 + 1.0e-6) #10 opt_problem.driver.add_constraint('con_zAr', lower=0.0 + 1.0e-6) #11 opt_problem.driver.add_constraint('con_yAr', lower=0.0 + 1.0e-6) #12 opt_problem.driver.add_constraint('con_TC2', lower=0.0 + 1.0e-6) #13 opt_problem.driver.add_constraint('con_TC3', lower=0.0 + 1e-6) #14 opt_problem.driver.add_constraint('con_br', lower=0.0 + 1e-6) #15 opt_problem.driver.add_constraint('con_bst', lower=0.0 + 1e-6) #16 opt_problem.driver.add_constraint('A_1', upper=60000.0 + 1e-6) #17 opt_problem.driver.add_constraint('J_s', upper=6.0) #18 opt_problem.driver.add_constraint('A_Cuscalc', lower=5.0) #19 opt_problem.driver.add_constraint('K_rad', lower=0.2 + 1e-6, upper=0.27) #20 opt_problem.driver.add_constraint('Slot_aspect_ratio', lower=4.0, upper=10.0) #21 opt_problem.driver.add_constraint('gen_eff', lower=Eta_Target) #22 opt_problem.setup() # Specify Target machine parameters opt_problem['machine_rating'] = 5000000.0 opt_problem['Torque'] = 4.143289e6 opt_problem['n_nom'] = 12.1 # Initialize design variables opt_problem['r_s'] = 3.26 opt_problem['l_s'] = 1.60 opt_problem['h_s'] = 0.070 opt_problem['tau_p'] = 0.080 opt_problem['h_m'] = 0.009 opt_problem['h_ys'] = 0.075 opt_problem['h_yr'] = 0.075 opt_problem['n_s'] = 5.0 opt_problem['b_st'] = 0.480 opt_problem['n_r'] = 5.0 opt_problem['b_r'] = 0.530 opt_problem['d_r'] = 0.700 opt_problem['d_s'] = 0.350 opt_problem['t_wr'] = 0.06 opt_problem['t_ws'] = 0.06 opt_problem[ 'R_o'] = 0.43 #0.523950817 #0.43 #0.523950817 #0.17625 #0.2775 #0.363882632 ##0.35 #0.523950817 #0.43 #523950817 #0.43 #0.523950817 #0.523950817 #0.17625 #0.2775 #0.363882632 #0.43 #0.523950817 #0.43 # Provide specific costs for materials opt_problem['C_Cu'] = 4.786 opt_problem['C_Fe'] = 0.556 opt_problem['C_Fes'] = 0.50139 opt_problem['C_PM'] = 95.0 opt_problem['main_shaft_cm'] = np.array([0.0, 0.0, 0.0]) opt_problem['main_shaft_length'] = 2.0 # Provide Material properties opt_problem['rho_Fe'] = 7700.0 #Steel density opt_problem['rho_Fes'] = 7850.0 #Steel density opt_problem['rho_Copper'] = 8900.0 # Kg/m3 copper density opt_problem['rho_PM'] = 7450.0 #Run optimization opt_problem.run() """Uncomment to print solution to screen/an excel file
def test_deriv_options_step_calc(self): class ScaledParaboloid(Component): """ Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """ def __init__(self): super(ScaledParaboloid, self).__init__() # Params self.add_param('x', 1.0) self.add_param('y', 1.0) # Unknowns self.add_output('f_xy', 0.0) self.scale = 1.0e-6 def solve_nonlinear(self, params, unknowns, resids): """f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 Optimal solution (minimum): x = 6.6667; y = -7.3333 """ x = params['x'] y = params['y'] f_xy = ((x-3.0)**2 + x*y + (y+4.0)**2 - 3.0) unknowns['f_xy'] = self.scale*f_xy def linearize(self, params, unknowns, resids): """Analytical derivatives""" x = params['x'] y = params['y'] J = {} J['f_xy', 'x'] = (2.0*x - 6.0 + y) * self.scale J['f_xy', 'y'] = (2.0*y + 8.0 + x) * self.scale return J prob = Problem() prob.root = Group() comp = prob.root.add('comp', ScaledParaboloid()) prob.root.add('p1', IndepVarComp('x', 8.0*comp.scale)) prob.root.add('p2', IndepVarComp('y', 8.0*comp.scale)) prob.root.connect('p1.x', 'comp.x') prob.root.connect('p2.y', 'comp.y') comp.deriv_options['type'] = 'fd' comp.deriv_options['step_calc'] = 'absolute' prob.setup(check=False) prob.run() J1 = prob.calc_gradient(['p1.x'], ['comp.f_xy'], return_format='dict') comp.deriv_options['step_calc'] = 'relative' J2 = prob.calc_gradient(['p1.x'], ['comp.f_xy'], return_format='dict') # Couldnt put together a case where one is much worse, so just make sure they # are not equal. self.assertNotEqual(self, J1['comp.f_xy']['p1.x'][0][0], J2['comp.f_xy']['p1.x'][0][0])
def test_inner_connection(self): class Squarer(Component): def __init__(self, size): super(Squarer, self).__init__() self.add_param(name='input:x', val=np.zeros(size), desc='x') self.add_output(name='output:x2', val=np.zeros(size), desc='x squared') def solve_nonlinear(self, params, unknowns, resids): unknowns['output:x2'] = params['input:x']**2 class Cuber(Component): def __init__(self, size): super(Cuber, self).__init__() self.add_param(name='x', val=np.zeros(size), desc='x') self.add_output(name='output:x3', val=np.zeros(size), desc='x squared') def solve_nonlinear(self, params, unknowns, resids): unknowns['output:x3'] = params['x']**3 class InnerGroup(Group): def __init__(self): super(InnerGroup, self).__init__() self.add('square1', Squarer(5)) self.add('square2', Squarer(3), promotes=['input:x']) # the following connection should result in 'cube1.x' using the # same src_indices as 'input:x', which is [2,3,4] from the outer # connection self.add('cube1', Cuber(3)) self.connect('input:x', 'cube1.x') # the following connection should result in 'cube2.x' using # src_indices [0,1] of 'input:x', which corresponds to the # src_indices [2,3] from the outer connection self.add('cube2', Cuber(2)) self.connect('input:x', 'cube2.x', src_indices=[0, 1]) # the following connection should result in 'cube3.x' using # src_indices [1,2] of 'square1.input:x', which corresponds to the # src_indices [1,2] from the outer connection self.add('cube3', Cuber(2)) self.connect('square1.input:x', 'cube3.x', src_indices=[1, 2]) class OuterGroup(Group): def __init__(self): super(OuterGroup, self).__init__() iv = IndepVarComp('input:x', np.zeros(5)) self.add('indep_vars', iv, promotes=['*']) self.add('inner', InnerGroup()) self.connect('input:x', 'inner.square1.input:x') self.connect('input:x', 'inner.input:x', src_indices=[2, 3, 4]) prob = Problem(root=OuterGroup()) prob.setup(check=False) prob['input:x'] = np.array([4., 5., 6., 7., 8.]) prob.run() assert_rel_error(self, prob.root.inner.square1.params['input:x'], np.array([4., 5., 6., 7., 8.]), 0.00000001) assert_rel_error(self, prob.root.inner.cube1.params['x'], np.array([6., 7., 8.]), 0.00000001) assert_rel_error(self, prob.root.inner.cube2.params['x'], np.array([6., 7.]), 0.00000001) assert_rel_error(self, prob.root.inner.cube3.params['x'], np.array([5., 6.]), 0.00000001)
def test_cannonball_src_indices(self): # this test replicates the structure of a problem in pointer. The bug was that # the state variables in the segments were not getting connected to the proper # src_indices of the parameters from the independent variables component state_var_names = ['x', 'y', 'vx', 'vy'] param_arg_names = ['g'] num_seg = 3 seg_ncn = 3 num_nodes = 3 class Trajectory(Group): def __init__(self): super(Trajectory, self).__init__() class Phase(Group): def __init__(self, num_seg, seg_ncn): super(Phase, self).__init__() ncn_u = 7 state_vars = [('X_c:{0}'.format(state_name), np.zeros(ncn_u)) for state_name in state_var_names] self.add('state_var_comp', IndepVarComp(state_vars), promotes=['*']) param_args = [('P_s:{0}'.format(param_name), 0.) for param_name in param_arg_names] self.add('static_params', IndepVarComp(param_args), promotes=['*']) for i in range(num_seg): self.add('seg{0}'.format(i), Segment(seg_ncn)) offset_states = 0 for i in range(num_seg): idxs_states = range(offset_states, num_nodes + offset_states) offset_states += num_nodes - 1 for state_name in state_var_names: self.connect('X_c:{0}'.format(state_name), 'seg{0:d}.X_c:{1}'.format(i, state_name), src_indices=idxs_states) for param_name in param_arg_names: self.connect('P_s:{0}'.format(param_name), 'seg{0:d}.P_s:{1}'.format(i, param_name)) class Segment(Group): def __init__(self, num_nodes): super(Segment, self).__init__() self.add('eom_c', EOM(num_nodes)) self.add('static_bcast', StaticBCast(num_nodes), promotes=['*']) self.add('state_interp', StateInterp(num_nodes), promotes=['*']) for name in state_var_names: self.connect('X_c:{0}'.format(name), 'eom_c.X:{0}'.format(name)) class EOM(Component): def __init__(self, num_nodes): super(EOM, self).__init__() for name in state_var_names: self.add_param('X:{0}'.format(name), np.zeros(num_nodes)) self.add_output('dXdt:{0}'.format(name), np.zeros(num_nodes)) for name in param_arg_names: self.add_param('P:{0}'.format(name), 0.) def solve_nonlinear(self, params, unknowns, resids): unknowns['dXdt:x'][:] = params['X:vx'] unknowns['dXdt:y'][:] = params['X:vy'] unknowns['dXdt:vx'][:] = 0.0 unknowns['dXdt:vy'][:] = -params['P:g'] class StaticBCast(Component): def __init__(self, num_nodes): super(StaticBCast, self).__init__() for name in param_arg_names: self.add_param('P_s:{0}'.format(name), 0.) def solve_nonlinear(self, params, unknowns, resids): pass class StateInterp(Component): def __init__(self, num_nodes): super(StateInterp, self).__init__() for name in state_var_names: self.add_param('X_c:{0}'.format(name), np.zeros(num_nodes)) def solve_nonlinear(self, params, unknowns, resids): pass prob = Problem(root=Trajectory()) phase0 = prob.root.add('phase0', Phase(num_seg, seg_ncn)) # Call setup so we can access variables through the prob dict interface prob.setup(check=False) # Populate the unique cardinal values of the states with some values we expect to be distributed to the phases prob['phase0.X_c:x'][:] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] prob['phase0.X_c:y'][:] = [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0] prob['phase0.X_c:vx'][:] = [ 0.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0 ] prob['phase0.X_c:vy'][:] = [ 0.0, 1000.0, 2000.0, 3000.0, 4000.0, 5000.0, 6000.0 ] prob['phase0.P_s:g'] = 9.80665 # Run to update the values throughout the model prob.run() for state in ['x', 'y', 'vx', 'vy']: phase_cardinal_values = prob['phase0.X_c:{0}'.format(state)] idx = 0 #print('phase0.X_c:{0}'.format(state), phase_cardinal_values) for i in range(num_seg): seg_ncn = num_nodes seg_cardinal_values = prob['phase0.seg{0}.X_c:{1}'.format( i, state)] eomc_cardinal_values = prob['phase0.seg{0}.eom_c.X:{1}'.format( i, state)] #print('phase0.seg{0}.X_c:{1}'.format(i, state), seg_cardinal_values) #print('phase0.seg{0}.eom_c.X:{1}'.format(i, state), eomc_cardinal_values) assert_almost_equal(seg_cardinal_values, phase_cardinal_values[idx:idx + seg_ncn], decimal=12) assert_almost_equal(seg_cardinal_values, eomc_cardinal_values, decimal=12) idx = idx + seg_ncn - 1
def setUpClass(self): super(test_floris, self).setUpClass() try: from plantenergy.floris import floris_wrapper, add_floris_params_IndepVarComps self.working_import = True except: self.working_import = False # define turbine locations in global reference frame turbineX = np.array([1164.7, 947.2, 1682.4, 1464.9, 1982.6, 2200.1]) turbineY = np.array([1024.7, 1335.3, 1387.2, 1697.8, 2060.3, 1749.7]) hub_height = 90. hubHeight = np.ones_like(turbineX) * hub_height # initialize input variable arrays nTurbines = turbineX.size rotorDiameter = np.zeros(nTurbines) axialInduction = np.zeros(nTurbines) Ct = np.zeros(nTurbines) Cp = np.zeros(nTurbines) generatorEfficiency = np.zeros(nTurbines) yaw = np.zeros(nTurbines) # define initial values for turbI in range(0, nTurbines): rotorDiameter[turbI] = 126.4 # m axialInduction[turbI] = 1.0 / 3.0 Ct[turbI] = 4.0 * axialInduction[turbI] * (1.0 - axialInduction[turbI]) Cp[turbI] = 0.7737 / 0.944 * 4.0 * 1.0 / 3.0 * np.power( (1 - 1.0 / 3.0), 2) generatorEfficiency[turbI] = 0.944 yaw[turbI] = 0. # deg. # Define flow properties nDirections = 1 wind_speed = 8.0 # m/s air_density = 1.1716 # kg/m^3 wind_direction = 270. - 0.523599 * 180. / np.pi # deg (N = 0 deg., using direction FROM, as in met-mast data) wind_frequency = 1. # probability of wind in this direction at this speed # set up problem model_options = { 'differentiable': True, 'use_rotor_components': False, 'nSamples': 0, 'verbose': False, 'use_ct_curve': False, 'ct_curve': None, 'interp_type': 1, 'nRotorPoints': 1 } # prob = Problem(root=AEPGroup(nTurbines, nDirections, wake_model=floris_wrapper, wake_model_options=model_options, # params_IdepVar_func=add_floris_params_IndepVarComps, # params_IndepVar_args={'use_rotor_components': False})) from plantenergy.OptimizationGroups import OptAEP prob = Problem( root=OptAEP(nTurbines, differentiable=True, use_rotor_components=False, wake_model=floris_wrapper, params_IdepVar_func=add_floris_params_IndepVarComps, wake_model_options=model_options)) # initialize problem prob.setup(check=False) # assign values to turbine states prob['turbineX'] = turbineX prob['turbineY'] = turbineY prob['hubHeight'] = hubHeight prob['yaw0'] = yaw # assign values to constant inputs (not design variables) prob['rotorDiameter'] = rotorDiameter prob['axialInduction'] = axialInduction prob['generatorEfficiency'] = generatorEfficiency prob['windSpeeds'] = np.array([wind_speed]) prob['air_density'] = air_density prob['windDirections'] = np.array([wind_direction]) prob['windFrequencies'] = np.array([wind_frequency]) prob['Ct_in'] = Ct prob['Cp_in'] = Cp prob[ 'model_params:cos_spread'] = 1E12 # turns off cosine spread (just needs to be very large) prob['model_params:useWakeAngle'] = False # run the problem prob.run() print(prob['wtVelocity0']) self.prob = prob
def setUpClass(self): super(test_guass, self).setUpClass() try: from plantenergy.gauss import gauss_wrapper, add_gauss_params_IndepVarComps self.working_import = True except: self.working_import = False # define turbine locations in global reference frame turbineX = np.array([1164.7, 947.2, 1682.4, 1464.9, 1982.6, 2200.1]) turbineY = np.array([1024.7, 1335.3, 1387.2, 1697.8, 2060.3, 1749.7]) hubHeight = np.zeros_like(turbineX) + 90. # import matplotlib.pyplot as plt # plt.plot(turbineX, turbineY, 'o') # plt.plot(np.array([0.0, ])) # plt.show() # initialize input variable arrays nTurbines = turbineX.size rotorDiameter = np.zeros(nTurbines) axialInduction = np.zeros(nTurbines) Ct = np.zeros(nTurbines) Cp = np.zeros(nTurbines) generatorEfficiency = np.zeros(nTurbines) yaw = np.zeros(nTurbines) # define initial values for turbI in range(0, nTurbines): rotorDiameter[turbI] = 126.4 # m axialInduction[turbI] = 1.0 / 3.0 Ct[turbI] = 4.0 * axialInduction[turbI] * (1.0 - axialInduction[turbI]) Cp[turbI] = 0.7737 / 0.944 * 4.0 * 1.0 / 3.0 * np.power( (1 - 1.0 / 3.0), 2) generatorEfficiency[turbI] = 0.944 yaw[turbI] = 0. # deg. # Define flow properties nDirections = 1 wind_speed = 8.0 # m/s air_density = 1.1716 # kg/m^3 wind_direction = 270. - 0.523599 * 180. / np.pi # deg (N = 0 deg., using direction FROM, as in met-mast data) wind_frequency = 1. # probability of wind in this direction at this speed # set up problem wake_model_options = {'nSamples': 0} prob = Problem( root=AEPGroup(nTurbines=nTurbines, nDirections=nDirections, wake_model=gauss_wrapper, wake_model_options=wake_model_options, datasize=0, use_rotor_components=False, params_IdepVar_func=add_gauss_params_IndepVarComps, differentiable=True, params_IndepVar_args={})) # initialize problem prob.setup(check=True) # assign values to turbine states prob['turbineX'] = turbineX prob['turbineY'] = turbineY prob['hubHeight'] = hubHeight prob['yaw0'] = yaw # assign values to constant inputs (not design variables) prob['rotorDiameter'] = rotorDiameter prob['axialInduction'] = axialInduction prob['generatorEfficiency'] = generatorEfficiency prob['windSpeeds'] = np.array([wind_speed]) prob['model_params:z_ref'] = 90. prob['air_density'] = air_density prob['windDirections'] = np.array([wind_direction]) prob['windFrequencies'] = np.array([wind_frequency]) prob['Ct_in'] = Ct prob['Cp_in'] = Cp # run the problem prob.run() self.prob = prob
def setUpClass(self): super(test_jensen, self).setUpClass() try: from plantenergy.jensen import jensen_wrapper, add_jensen_params_IndepVarComps self.working_import = True except: self.working_import = False # define turbine locations in global reference frame turbineX = np.array([1164.7, 947.2, 1682.4, 1464.9, 1982.6, 2200.1]) turbineY = np.array([1024.7, 1335.3, 1387.2, 1697.8, 2060.3, 1749.7]) # initialize input variable arrays nTurbines = turbineX.size rotorDiameter = np.zeros(nTurbines) axialInduction = np.zeros(nTurbines) Ct = np.zeros(nTurbines) Cp = np.zeros(nTurbines) generatorEfficiency = np.zeros(nTurbines) yaw = np.zeros(nTurbines) # define initial values for turbI in range(0, nTurbines): rotorDiameter[turbI] = 126.4 # m axialInduction[turbI] = 1.0 / 3.0 Ct[turbI] = 4.0 * axialInduction[turbI] * (1.0 - axialInduction[turbI]) Cp[turbI] = 0.7737 / 0.944 * 4.0 * 1.0 / 3.0 * np.power( (1 - 1.0 / 3.0), 2) generatorEfficiency[turbI] = 0.944 yaw[turbI] = 0. # deg. # Define flow properties nDirections = 1 wind_speed = 8.1 # m/s air_density = 1.1716 # kg/m^3 wind_direction = 270. - 0.523599 * 180. / np.pi # deg (N = 0 deg., using direction FROM, as in met-mast data) wind_frequency = 1. # probability of wind in this direction at this speed # set up problem wake_model_options = None # prob = Problem(root=AEPGroup(nTurbines, nDirections, wake_model=jensen_wrapper, wake_model_options=wake_model_options, # params_IdepVar_func=add_jensen_params_IndepVarComps, # params_IndepVar_args={'use_angle': False})) prob = Problem( root=AEPGroup(nTurbines, nDirections, wake_model=jensen_wrapper, wake_model_options=wake_model_options, params_IdepVar_func=add_jensen_params_IndepVarComps, params_IndepVar_args={'use_angle': False})) # initialize problem prob.setup(check=True) # assign values to turbine states prob['turbineX'] = turbineX prob['turbineY'] = turbineY prob['yaw0'] = yaw # assign values to constant inputs (not design variables) prob['rotorDiameter'] = rotorDiameter prob['axialInduction'] = axialInduction prob['generatorEfficiency'] = generatorEfficiency prob['windSpeeds'] = np.array([wind_speed]) prob['air_density'] = air_density prob['windDirections'] = np.array([wind_direction]) prob['windFrequencies'] = np.array([wind_frequency]) prob['Ct_in'] = Ct prob['Cp_in'] = Cp # prob['model_params:spread_angle'] = 20.0 # prob['model_params:alpha'] = 0.1 # run the problem prob.run() self.prob = prob
sub.driver.options['optimizer'] = 'COBYLA' # Type of Optimizer. 'COBYLA' does not require derivatives sub.driver.options['tol'] = 1.0e-4 # Tolerance for termination. Not sure exactly what it represents. Default: 1.0e-6 sub.driver.options['maxiter'] = 200 # Maximum iterations. Default: 200 #sub.driver.opt_settings['rhobeg'] = 1.0 # COBYLA-specific setting. Initial step size. Default: 1.0 #sub.driver.opt_settings['catol'] = 0.1 # COBYLA-specific setting. Absolute tolerance for constraint violations. Default: 0.1 # Add design variables, objective, and constraints to the optimization driver sub.driver.add_desvar('p1.x_init', lower=-50, upper=50) sub.driver.add_objective('Paraboloid.f_xy') # Data collection recorder = SqliteRecorder('record_results') recorder.options['record_params'] = True recorder.options['record_metadata'] = True sub.driver.add_recorder(recorder) # Setup, run, & cleanup sub.setup(check=False) sub.run() sub.cleanup() # Data retrieval & display # Old way - good for debugging IndepVars db = sqlitedict.SqliteDict( 'record_results', 'iterations' ) db_keys = list( db.keys() ) # list() needed for compatibility with Python 3. Not needed for Python 2 for i in db_keys: data = db[i] print('\n') print(data['Unknowns']) print(data['Parameters'])
def test_case1_vs_inductrack(self): root = Group() root.add('lev', levitation_group.LevGroup()) prob = Problem(root) params = (('m_pod', 3000.0, { 'units': 'kg' }), ('l_pod', 22.0, { 'units': 'm' }), ('d_pod', 1.0, { 'units': 'm' }), ('vel_b', 23.0, { 'units': 'm/s' }), ('h_lev', 0.01, { 'unit': 'm' }), ('vel', 350.0, { 'units': 'm/s' })) prob.root.add('input_vars', IndepVarComp(params)) prob.root.connect('input_vars.m_pod', 'lev.m_pod') prob.root.connect('input_vars.l_pod', 'lev.l_pod') prob.root.connect('input_vars.d_pod', 'lev.d_pod') prob.root.connect('input_vars.vel_b', 'lev.vel_b') prob.root.connect('input_vars.h_lev', 'lev.h_lev') prob.root.connect('input_vars.vel', 'lev.vel') prob.setup() prob['lev.Drag.b_res'] = 1.48 prob['lev.Drag.num_mag_hal'] = 4.0 prob['lev.Drag.gamma'] = 1.0 prob['lev.Drag.w_mag'] = 3.0 prob['lev.Drag.spacing'] = 0.0 prob['lev.Drag.w_strip'] = .005 prob['lev.Drag.num_sheets'] = 1.0 prob['lev.Drag.delta_c'] = .0005334 prob['lev.Drag.strip_c'] = .0105 prob['lev.Drag.rc'] = 1.713e-8 prob['lev.Drag.MU0'] = 4.0 * np.pi * (1.0e-7) prob['lev.Drag.track_factor'] = .75 prob['lev.Drag.g'] = 9.81 prob['lev.Drag.mag_thk'] = .15 prob['lev.Mass.mag_thk'] = .15 prob['lev.Mass.rho_mag'] = 7500.0 prob['lev.Mass.gamma'] = 1.0 prob['lev.Mass.cost_per_kg'] = 44.0 prob['lev.Mass.w_mag'] = 3.0 prob['lev.Mass.track_factor'] = .75 prob.run() # Print Statements for debugging # print('Mag Mass %f' % prob['lev.m_mag']) # print('Mag Drag is %f' % prob['lev.mag_drag']) # Test Values assert np.isclose(prob['lev.mag_drag'], 9025.39, rtol=.01) assert np.isclose(prob['lev.total_pod_mass'], 21562.50, rtol=.01)
def test_simple_implicit(self): prob = Problem() prob.root = Group() prob.root.ln_solver = ScipyGMRES() prob.root.add('comp', SimpleImplicitComp()) prob.root.add('p1', IndepVarComp('x', 0.5)) prob.root.connect('p1.x', 'comp.x') prob.root.comp.deriv_options['check_type'] = 'cs' prob.setup(check=False) prob.run() # Correct total derivatives (we can do this one manually) J = prob.calc_gradient(['p1.x'], ['comp.y'], mode='fwd') assert_rel_error(self, J[0][0], -2.5555511, 1e-5) J = prob.calc_gradient(['p1.x'], ['comp.y'], mode='rev') assert_rel_error(self, J[0][0], -2.5555511, 1e-5) J = prob.calc_gradient(['p1.x'], ['comp.y'], mode='fd') assert_rel_error(self, J[0][0], -2.5555511, 1e-5) # Clean up old FD prob.run() # Partials data = prob.check_partial_derivatives(out_stream=None) #data = prob.check_partial_derivatives() for key1, val1 in iteritems(data): for key2, val2 in iteritems(val1): assert_rel_error(self, val2['abs error'][0], 0.0, 1e-5) assert_rel_error(self, val2['abs error'][1], 0.0, 1e-5) assert_rel_error(self, val2['abs error'][2], 0.0, 1e-5) assert_rel_error(self, val2['rel error'][0], 0.0, 1e-5) assert_rel_error(self, val2['rel error'][1], 0.0, 1e-5) assert_rel_error(self, val2['rel error'][2], 0.0, 1e-5) assert_rel_error(self, data['comp'][('y', 'x')]['J_fwd'][0][0], 1.0, 1e-6) assert_rel_error(self, data['comp'][('y', 'z')]['J_fwd'][0][0], 2.0, 1e-6) assert_rel_error(self, data['comp'][('z', 'x')]['J_fwd'][0][0], 2.66666667, 1e-6) assert_rel_error(self, data['comp'][('z', 'z')]['J_fwd'][0][0], 1.5, 1e-6) # Clean up old FD prob.run() # Make sure check_totals works too data = prob.check_total_derivatives(out_stream=None) for key1, val1 in iteritems(data): assert_rel_error(self, val1['abs error'][0], 0.0, 1e-5) assert_rel_error(self, val1['abs error'][1], 0.0, 1e-5) assert_rel_error(self, val1['abs error'][2], 0.0, 1e-5) assert_rel_error(self, val1['rel error'][0], 0.0, 1e-5) assert_rel_error(self, val1['rel error'][1], 0.0, 1e-5) assert_rel_error(self, val1['rel error'][2], 0.0, 1e-5)
def semiExample(): # Number of sections to be used in the design nsection = 5 # Initialize OpenMDAO problem and FloatingSE Group prob = Problem(root=FloatingSE(nsection)) prob.setup() # Add in auxiliary columns and truss elements prob['number_of_auxiliary_columns'] = 3 prob[ 'cross_attachment_pontoons_int'] = 1 # Lower-Upper base-to-auxiliary connecting cross braces prob[ 'lower_attachment_pontoons_int'] = 1 # Lower base-to-auxiliary connecting pontoons prob[ 'upper_attachment_pontoons_int'] = 1 # Upper base-to-auxiliary connecting pontoons prob[ 'lower_ring_pontoons_int'] = 1 # Lower ring of pontoons connecting auxiliary columns prob[ 'upper_ring_pontoons_int'] = 1 # Upper ring of pontoons connecting auxiliary columns prob[ 'outer_cross_pontoons_int'] = 1 # Auxiliary ring connecting V-cross braces # Set environment to that used in OC4 testing campaign prob['water_depth'] = 200.0 # Distance to sea floor [m] prob['hmax'] = 10.8 # Significant wave height [m] prob['T'] = 9.8 # Wave period [s] prob['Uref'] = 11.0 # Wind reference speed [m/s] prob['zref'] = 119.0 # Wind reference height [m] prob['shearExp'] = 0.11 # Shear exponent in wind power law prob['cm'] = 2.0 # Added mass coefficient prob['Uc'] = 0.0 # Mean current speed prob['z0'] = 0.0 # Water line prob['yaw'] = 0.0 # Turbine yaw angle prob['beta'] = 0.0 # Wind beta angle prob['cd_usr'] = np.inf # Compute drag coefficient # Wind and water properties prob['base.windLoads.rho'] = 1.226 # Density of air [kg/m^3] prob['base.windLoads.mu'] = 1.78e-5 # Viscosity of air [kg/m/s] prob['water_density'] = 1025.0 # Density of water [kg/m^3] prob['base.waveLoads.mu'] = 1.08e-3 # Viscosity of water [kg/m/s] # Material properties prob['material_density'] = 7850.0 # Steel [kg/m^3] prob['E'] = 200e9 # Young's modulus [N/m^2] prob['G'] = 79.3e9 # Shear modulus [N/m^2] prob['yield_stress'] = 3.45e8 # Elastic yield stress [N/m^2] prob['nu'] = 0.26 # Poisson's ratio prob['permanent_ballast_density'] = 4492.0 # [kg/m^3] # Mass and cost scaling factors prob['bulkhead_mass_factor'] = 1.0 # Scaling for unaccounted bulkhead mass prob['ring_mass_factor'] = 1.0 # Scaling for unaccounted stiffener mass prob['shell_mass_factor'] = 1.0 # Scaling for unaccounted shell mass prob['column_mass_factor'] = 1.05 # Scaling for unaccounted column mass prob[ 'outfitting_mass_fraction'] = 0.06 # Fraction of additional outfitting mass for each column prob['ballast_cost_rate'] = 100.0 # Cost factor for ballast mass [$/kg] prob[ 'tapered_col_cost_rate'] = 4720.0 # Cost factor for column mass [$/kg] prob[ 'outfitting_cost_rate'] = 6980.0 # Cost factor for outfitting mass [$/kg] prob['mooring_cost_rate'] = 1.1 # Cost factor for mooring mass [$/kg] prob['pontoon_cost_rate'] = 6.250 # Cost factor for pontoons [$/kg] # Safety factors prob['gamma_f'] = 1.35 # Safety factor on loads prob['gamma_b'] = 1.1 # Safety factor on buckling prob['gamma_m'] = 1.1 # Safety factor on materials prob['gamma_n'] = 1.0 # Safety factor on consequence of failure prob['gamma_fatigue'] = 1.755 # Not used # Column geometry prob[ 'base_permanent_ballast_height'] = 10.0 # Height above keel for permanent ballast [m] prob['base_freeboard'] = 10.0 # Height extension above waterline [m] prob['base_section_height'] = np.array([36.0, 36.0, 36.0, 8.0, 14.0 ]) # Length of each section [m] prob['base_outer_diameter'] = np.array( [9.4, 9.4, 9.4, 9.4, 6.5, 6.5]) # Diameter at each section node (linear lofting between) [m] prob['base_wall_thickness'] = 0.05 * np.ones( nsection + 1) # Shell thickness at each section node (linear lofting between) [m] prob['base_bulkhead_thickness'] = 0.05 * np.array([ 1, 1, 0, 0, 0, 0 ]) # Locations/thickness of internal bulkheads at section interfaces [m] # Auxiliary column geometry prob['radius_to_auxiliary_column'] = 33.333 * np.cos( np.pi / 6) # Centerline of base column to centerline of auxiliary column [m] prob[ 'auxiliary_permanent_ballast_height'] = 0.1 # Height above keel for permanent ballast [m] prob['auxiliary_freeboard'] = 12.0 # Height extension above waterline [m] prob['auxiliary_section_height'] = np.array( [6.0, 0.1, 7.9, 8.0, 10]) # Length of each section [m] prob['auxiliary_outer_diameter'] = np.array( [24, 24, 12, 12, 12, 12]) # Diameter at each section node (linear lofting between) [m] prob['auxiliary_wall_thickness'] = 0.06 * np.ones( nsection + 1) # Shell thickness at each section node (linear lofting between) [m] # Column ring stiffener parameters prob['base_stiffener_web_height'] = 0.10 * np.ones( nsection) # (by section) [m] prob['base_stiffener_web_thickness'] = 0.04 * np.ones( nsection) # (by section) [m] prob['base_stiffener_flange_width'] = 0.10 * np.ones( nsection) # (by section) [m] prob['base_stiffener_flange_thickness'] = 0.02 * np.ones( nsection) # (by section) [m] prob['base_stiffener_spacing'] = 0.40 * np.ones( nsection) # (by section) [m] # Auxiliary column ring stiffener parameters prob['auxiliary_stiffener_web_height'] = 0.10 * np.ones( nsection) # (by section) [m] prob['auxiliary_stiffener_web_thickness'] = 0.04 * np.ones( nsection) # (by section) [m] prob['auxiliary_stiffener_flange_width'] = 0.01 * np.ones( nsection) # (by section) [m] prob['auxiliary_stiffener_flange_thickness'] = 0.02 * np.ones( nsection) # (by section) [m] prob['auxiliary_stiffener_spacing'] = 0.40 * np.ones( nsection) # (by section) [m] # Pontoon parameters prob[ 'pontoon_outer_diameter'] = 3.2 # Diameter of all pontoon/truss elements [m] prob[ 'pontoon_wall_thickness'] = 0.0175 # Thickness of all pontoon/truss elements [m] prob[ 'base_pontoon_attach_lower'] = -20.0 # Lower z-coordinate on base where truss attaches [m] prob[ 'base_pontoon_attach_upper'] = 10.0 # Upper z-coordinate on base where truss attaches [m] # Mooring parameters prob['number_of_mooring_lines'] = 3 # Evenly spaced around structure prob[ 'mooring_type'] = 'chain' # Options are chain, nylon, polyester, fiber, or iwrc prob[ 'anchor_type'] = 'suctionpile' # Options are SUCTIONPILE or DRAGEMBEDMENT prob['mooring_diameter'] = 0.0766 # Diameter of mooring line/chain [m] prob['fairlead'] = 14.0 # Distance below waterline for attachment [m] prob[ 'fairlead_offset_from_shell'] = 0.5 # Offset from shell surface for mooring attachment [m] prob[ 'scope_ratio'] = 4.4919 # Ratio of line length to distance to sea floor (from fairlead) prob[ 'anchor_radius'] = 837.6 # Distance from centerline to sea floor landing [m] prob[ 'drag_embedment_extra_length'] = 300.0 # Extra length beyond sea flor landing to ensure anchors only see horizontal forces [m] # Porperties of turbine tower prob[ 'hub_height'] = 77.6 # Length from tower base to top (not including freeboard) [m] prob['tower_section_height'] = 77.6 / nsection * np.ones( nsection) # Length of each tower section [m] prob['tower_outer_diameter'] = np.linspace( 6.5, 3.87, nsection + 1) # Diameter at each tower section node (linear lofting between) [m] prob['tower_wall_thickness'] = np.linspace( 0.027, 0.019, nsection + 1) # Diameter at each tower section node (linear lofting between) [m] prob[ 'tower_buckling_length'] = 30.0 # Tower buckling reinforcement spacing [m] prob[ 'tower_outfitting_factor'] = 1.07 # Scaling for unaccounted tower mass in outfitting # Properties of rotor-nacelle-assembly (RNA) prob['rna_mass'] = 350e3 # Mass [kg] prob['rna_I'] = 1e5 * np.array([ 1149.307, 220.354, 187.597, 0, 5.037, 0 ]) # Moment of intertia (xx,yy,zz,xy,xz,yz) [kg/m^2] prob['rna_cg'] = np.array( [-1.132, 0, 0.509]) # Offset of RNA center of mass from tower top (x,y,z) [m] # Max thrust prob['rna_force'] = np.array([1284744.196, 0, -112400.5527 ]) # Net force acting on RNA (x,y,z) [N] prob['rna_moment'] = np.array([3963732.762, 896380.8464, -346781.682 ]) # Net moment acting on RNA (x,y,z) [N*m] # Max wind speed #prob['rna_force'] = np.array([188038.8045, 0, -16451.2637]) # Net force acting on RNA (x,y,z) [N] #prob['rna_moment'] = np.array([0.0, 131196.8431, 0.0]) # Net moment acting on RNA (x,y,z) [N*m] # Mooring constraints prob['mooring_max_offset'] = 0.1 * prob[ 'water_depth'] # Max surge/sway offset [m] prob['mooring_max_heel'] = 10.0 # Max heel (pitching) angle [deg] # Design constraints prob['min_taper_ratio'] = 0.4 # For manufacturability of rolling steel prob['min_diameter_thickness_ratio'] = 120.0 # For weld-ability prob['connection_ratio_max'] = 0.25 # For welding pontoons to columns # API 2U flag prob['loading'] = 'hydrostatic' prob.run() '''
def test_apply_linear_units(self): # Make sure we can index into dparams class Attitude_Angular(Component): """ Calculates angular velocity vector from the satellite's orientation matrix and its derivative. """ def __init__(self, n=2): super(Attitude_Angular, self).__init__() self.n = n # Inputs self.add_param( 'O_BI', np.zeros((3, 3, n)), units="ft", desc= "Rotation matrix from body-fixed frame to Earth-centered " "inertial frame over time") self.add_param('Odot_BI', np.zeros((3, 3, n)), units="km", desc="First derivative of O_BI over time") # Outputs self.add_output( 'w_B', np.zeros((3, n)), units="1/s", scaler=12.0, desc="Angular velocity vector in body-fixed frame over time" ) self.dw_dOdot = np.zeros((n, 3, 3, 3)) self.dw_dO = np.zeros((n, 3, 3, 3)) def solve_nonlinear(self, params, unknowns, resids): """ Calculate output. """ O_BI = params['O_BI'] Odot_BI = params['Odot_BI'] w_B = unknowns['w_B'] for i in range(0, self.n): w_B[0, i] = np.dot(Odot_BI[2, :, i], O_BI[1, :, i]) w_B[1, i] = np.dot(Odot_BI[0, :, i], O_BI[2, :, i]) w_B[2, i] = np.dot(Odot_BI[1, :, i], O_BI[0, :, i]) #print(unknowns['w_B']) def linearize(self, params, unknowns, resids): """ Calculate and save derivatives. (i.e., Jacobian) """ O_BI = params['O_BI'] Odot_BI = params['Odot_BI'] for i in range(0, self.n): self.dw_dOdot[i, 0, 2, :] = O_BI[1, :, i] self.dw_dO[i, 0, 1, :] = Odot_BI[2, :, i] self.dw_dOdot[i, 1, 0, :] = O_BI[2, :, i] self.dw_dO[i, 1, 2, :] = Odot_BI[0, :, i] self.dw_dOdot[i, 2, 1, :] = O_BI[0, :, i] self.dw_dO[i, 2, 0, :] = Odot_BI[1, :, i] def apply_linear(self, params, unknowns, dparams, dunknowns, dresids, mode): """ Matrix-vector product with the Jacobian. """ dw_B = dresids['w_B'] if mode == 'fwd': for k in range(3): for i in range(3): for j in range(3): if 'O_BI' in dparams: dw_B[k, :] += self.dw_dO[:, k, i, j] * \ dparams['O_BI'][i, j, :] if 'Odot_BI' in dparams: dw_B[k, :] += self.dw_dOdot[:, k, i, j] * \ dparams['Odot_BI'][i, j, :] else: for k in range(3): for i in range(3): for j in range(3): if 'O_BI' in dparams: dparams['O_BI'][i, j, :] += self.dw_dO[:, k, i, j] * \ dw_B[k, :] if 'Odot_BI' in dparams: dparams['Odot_BI'][i, j, :] -= -self.dw_dOdot[:, k, i, j] * \ dw_B[k, :] prob = Problem() root = prob.root = Group() prob.root.add('comp', Attitude_Angular(n=5), promotes=['*']) prob.root.add('p1', IndepVarComp('O_BI', np.ones((3, 3, 5))), promotes=['*']) prob.root.add('p2', IndepVarComp('Odot_BI', np.ones((3, 3, 5))), promotes=['*']) prob.setup(check=False) prob.run() indep_list = ['O_BI', 'Odot_BI'] unknown_list = ['w_B'] Jf = prob.calc_gradient(indep_list, unknown_list, mode='fwd', return_format='dict') indep_list = ['O_BI', 'Odot_BI'] unknown_list = ['w_B'] Jr = prob.calc_gradient(indep_list, unknown_list, mode='rev', return_format='dict') for key, val in iteritems(Jr): for key2 in val: diff = abs(Jf[key][key2] - Jr[key][key2]) assert_rel_error(self, diff, 0.0, 1e-10) # Clean up old FD prob.run() # Partials data = prob.check_partial_derivatives(out_stream=None) #data = prob.check_partial_derivatives() for key1, val1 in iteritems(data): for key2, val2 in iteritems(val1): assert_rel_error(self, val2['abs error'][0], 0.0, 1e-5) assert_rel_error(self, val2['abs error'][1], 0.0, 1e-5) assert_rel_error(self, val2['abs error'][2], 0.0, 1e-5) assert_rel_error(self, val2['rel error'][0], 0.0, 1e-5) assert_rel_error(self, val2['rel error'][1], 0.0, 1e-5) assert_rel_error(self, val2['rel error'][2], 0.0, 1e-5)
def test_discs(self): OPT, OPTIMIZER = set_pyoptsparse_opt('SNOPT') if OPTIMIZER is not 'SNOPT': raise unittest.SkipTest( "pyoptsparse is not providing SNOPT or SLSQP") # So we compare the same starting locations. np.random.seed(123) radius = 1.0 pin = 15.0 n_disc = 7 prob = Problem() prob.root = root = Group() from openmdao.api import pyOptSparseDriver driver = prob.driver = pyOptSparseDriver() driver.options['optimizer'] = 'SNOPT' driver.options['print_results'] = False # Note, active tolerance requires relevance reduction to work. root.ln_solver.options['single_voi_relevance_reduction'] = True # Also, need to be in adjoint root.ln_solver.options['mode'] = 'rev' obj_expr = 'obj = ' sep = '' for i in range(n_disc): dist = "dist_%d" % i x1var = 'x_%d' % i # First disc is pinned if i == 0: root.add('p_%d' % i, IndepVarComp(x1var, pin), promotes=(x1var, )) # The rest are design variables for the optimizer. else: init_val = 5.0 * np.random.random() - 5.0 + pin root.add('p_%d' % i, IndepVarComp(x1var, init_val), promotes=(x1var, )) driver.add_desvar(x1var) for j in range(i): x2var = 'x_%d' % j yvar = 'y_%d_%d' % (i, j) name = dist + "_%d" % j expr = '%s= (%s - %s)**2' % (yvar, x1var, x2var) root.add(name, ExecComp(expr), promotes=(x1var, x2var, yvar)) # Constraint (you can experiment with turning on/off the active_tol) #driver.add_constraint(yvar, lower=radius) driver.add_constraint(yvar, lower=radius, active_tol=radius * 3.0) # This pair's contribution to objective obj_expr += sep + yvar sep = ' + ' root.add('sum_dist', ExecComp(obj_expr), promotes=('*', )) driver.add_objective('obj') prob.setup(check=False) prob.run()
class TestConnections(unittest.TestCase): def setUp(self): self.p = Problem(root=Group()) root = self.p.root self.G1 = root.add("G1", Group()) self.G2 = self.G1.add("G2", Group()) self.C1 = self.G2.add("C1", ExecComp('y=x*2.0')) self.C2 = self.G2.add("C2", IndepVarComp('x', 1.0)) self.G3 = root.add("G3", Group()) self.G4 = self.G3.add("G4", Group()) self.C3 = self.G4.add("C3", ExecComp('y=x*2.0')) self.C4 = self.G4.add("C4", ExecComp('y=x*2.0')) def test_diff_conn_input_vals(self): # set different initial values self.C1._init_params_dict['x']['val'] = 7. self.C3._init_params_dict['x']['val'] = 5. # connect two inputs self.p.root.connect('G1.G2.C1.x', 'G3.G4.C3.x') try: self.p.setup(check=False) except Exception as err: self.assertEqual( str(err), "The following sourceless connected inputs have different initial values: " "[('G1.G2.C1.x', 7.0), ('G3.G4.C3.x', 5.0)]. Connect one of them to the output of " "an IndepVarComp to ensure that they have the same initial value." ) else: self.fail("Exception expected") def test_diff_conn_input_units(self): # set different but compatible units self.C1._init_params_dict['x']['units'] = 'ft' self.C3._init_params_dict['x']['units'] = 'in' # connect two inputs self.p.root.connect('G1.G2.C1.x', 'G3.G4.C3.x') try: self.p.setup(check=False) except Exception as err: self.assertEqual( str(err), "The following sourceless connected inputs have different units: " "[('G1.G2.C1.x', 'ft'), ('G3.G4.C3.x', 'in')]") else: self.fail("Exception expected") def test_no_conns(self): self.p.setup(check=False) self.assertEqual(self.p._dangling['G1.G2.C1.x'], set(['G1.G2.C1.x'])) self.assertEqual(self.p._dangling['G3.G4.C3.x'], set(['G3.G4.C3.x'])) self.assertEqual(self.p._dangling['G3.G4.C4.x'], set(['G3.G4.C4.x'])) self.assertEqual(len(self.p._dangling), 3) self.p['G1.G2.C1.x'] = 111. self.p['G3.G4.C3.x'] = 222. self.p['G3.G4.C4.x'] = 333. self.assertEqual(self.p.root.G1.G2.C1.params['x'], 111.) self.assertEqual(self.p.root.G3.G4.C3.params['x'], 222.) self.assertEqual(self.p.root.G3.G4.C4.params['x'], 333.) def test_inp_inp_conn_no_src(self): self.p.root.connect('G3.G4.C3.x', 'G3.G4.C4.x') stream = cStringIO() self.p.setup(out_stream=stream) self.assertEqual(self.p._dangling['G1.G2.C1.x'], set(['G1.G2.C1.x'])) self.assertEqual(self.p._dangling['G3.G4.C3.x'], set(['G3.G4.C3.x', 'G3.G4.C4.x'])) self.assertEqual(self.p._dangling['G3.G4.C4.x'], set(['G3.G4.C4.x', 'G3.G4.C3.x'])) self.assertEqual(len(self.p._dangling), 3) self.p['G3.G4.C3.x'] = 999. self.assertEqual(self.p.root.G3.G4.C3.params['x'], 999.) self.assertEqual(self.p.root.G3.G4.C4.params['x'], 999.) content = stream.getvalue() self.assertTrue( "The following parameters have no associated unknowns:\nG1.G2.C1.x\nG3.G4.C3.x\nG3.G4.C4.x" in content) self.assertTrue( "The following components have no connections:\nG1.G2.C1\nG1.G2.C2\nG3.G4.C3\nG3.G4.C4\n" in content) self.assertTrue( "No recorders have been specified, so no data will be saved." in content) def test_inp_inp_conn_w_src(self): self.p.root.connect('G3.G4.C3.x', 'G3.G4.C4.x') self.p.root.connect('G1.G2.C2.x', 'G3.G4.C3.x') self.p.setup(check=False) self.assertEqual(self.p._dangling['G1.G2.C1.x'], set(['G1.G2.C1.x'])) self.assertEqual(len(self.p._dangling), 1) self.p['G1.G2.C2.x'] = 999. self.assertEqual(self.p.root.G3.G4.C3.params['x'], 0.) self.assertEqual(self.p.root.G3.G4.C4.params['x'], 0.) self.p.run() self.assertEqual(self.p.root.G3.G4.C3.params['x'], 999.) self.assertEqual(self.p.root.G3.G4.C4.params['x'], 999.) def test_inp_inp_conn_w_src2(self): self.p.root.connect('G3.G4.C3.x', 'G3.G4.C4.x') self.p.root.connect('G1.G2.C2.x', 'G3.G4.C4.x') self.p.setup(check=False) self.assertEqual(self.p._dangling['G1.G2.C1.x'], set(['G1.G2.C1.x'])) self.assertEqual(len(self.p._dangling), 1) self.p['G1.G2.C2.x'] = 999. self.assertEqual(self.p.root.G3.G4.C3.params['x'], 0.) self.assertEqual(self.p.root.G3.G4.C4.params['x'], 0.) self.p.run() self.assertEqual(self.p.root.G3.G4.C3.params['x'], 999.) self.assertEqual(self.p.root.G3.G4.C4.params['x'], 999.) def test_pull_size_from_source(self): class Src(Component): def __init__(self): super(Src, self).__init__() self.add_param('x', 2.0) self.add_output('y1', np.zeros((3, ))) self.add_output('y2', shape=((3, ))) def solve_nonlinear(self, params, unknowns, resids): """ counts up. """ x = params['x'] unknowns['y1'] = x * np.array([1.0, 2.0, 3.0]) unknowns['y2'] = x * np.array([1.0, 2.0, 3.0]) class Tgt(Component): def __init__(self): super(Tgt, self).__init__() self.add_param('x1') self.add_param('x2') self.add_output('y1', 0.0) self.add_output('y2', 0.0) def solve_nonlinear(self, params, unknowns, resids): """ counts up. """ x1 = params['x1'] x2 = params['x2'] unknowns['y1'] = np.sum(x1) unknowns['y2'] = np.sum(x2) top = Problem() top.root = Group() top.root.add('src', Src()) top.root.add('tgt', Tgt()) top.root.connect('src.y1', 'tgt.x1') top.root.connect('src.y2', 'tgt.x2') top.setup(check=False) top.run() self.assertEqual(top['tgt.y1'], 12.0) self.assertEqual(top['tgt.y2'], 12.0) def test_pull_size_from_source_with_indices(self): class Src(Component): def __init__(self): super(Src, self).__init__() self.add_param('x', 2.0) self.add_output('y1', np.zeros((3, ))) self.add_output('y2', shape=((3, ))) self.add_output('y3', 3.0) def solve_nonlinear(self, params, unknowns, resids): """ counts up. """ x = params['x'] unknowns['y1'] = x * np.array([1.0, 2.0, 3.0]) unknowns['y2'] = x * np.array([1.0, 2.0, 3.0]) unknowns['y3'] = x * 4.0 class Tgt(Component): def __init__(self): super(Tgt, self).__init__() self.add_param('x1') self.add_param('x2') self.add_param('x3') self.add_output('y1', 0.0) self.add_output('y2', 0.0) self.add_output('y3', 0.0) def solve_nonlinear(self, params, unknowns, resids): """ counts up. """ x1 = params['x1'] x2 = params['x2'] x3 = params['x3'] unknowns['y1'] = np.sum(x1) unknowns['y2'] = np.sum(x2) unknowns['y3'] = np.sum(x3) top = Problem() top.root = Group() top.root.add('src', Src()) top.root.add('tgt', Tgt()) top.root.connect('src.y1', 'tgt.x1', src_indices=(0, 1)) top.root.connect('src.y2', 'tgt.x2', src_indices=(0, 1)) top.root.connect('src.y3', 'tgt.x3') top.setup(check=False) top.run() self.assertEqual(top['tgt.y1'], 6.0) self.assertEqual(top['tgt.y2'], 6.0) self.assertEqual(top['tgt.y3'], 8.0)
def test_hohmann_result(self): prob = Problem(root=Group()) root = prob.root root.add('mu_comp', IndepVarComp('mu', val=0.0, units='km**3/s**2'), promotes=['mu']) root.add('r1_comp', IndepVarComp('r1', val=0.0, units='km'), promotes=['r1']) root.add('r2_comp', IndepVarComp('r2', val=0.0, units='km'), promotes=['r2']) root.add('dinc1_comp', IndepVarComp('dinc1', val=0.0, units='deg'), promotes=['dinc1']) root.add('dinc2_comp', IndepVarComp('dinc2', val=0.0, units='deg'), promotes=['dinc2']) root.add('leo', system=VCircComp()) root.add('geo', system=VCircComp()) root.add('transfer', system=TransferOrbitComp()) root.connect('r1', ['leo.r', 'transfer.rp']) root.connect('r2', ['geo.r', 'transfer.ra']) root.connect('mu', ['leo.mu', 'geo.mu', 'transfer.mu']) root.add('dv1', system=DeltaVComp()) root.connect('leo.vcirc', 'dv1.v1') root.connect('transfer.vp', 'dv1.v2') root.connect('dinc1', 'dv1.dinc') root.add('dv2', system=DeltaVComp()) root.connect('transfer.va', 'dv2.v1') root.connect('geo.vcirc', 'dv2.v2') root.connect('dinc2', 'dv2.dinc') root.add('dv_total', system=ExecComp('delta_v=dv1+dv2', units={ 'delta_v': 'km/s', 'dv1': 'km/s', 'dv2': 'km/s' }), promotes=['delta_v']) root.connect('dv1.delta_v', 'dv_total.dv1') root.connect('dv2.delta_v', 'dv_total.dv2') root.add('dinc_total', system=ExecComp('dinc=dinc1+dinc2', units={ 'dinc': 'deg', 'dinc1': 'deg', 'dinc2': 'deg' }), promotes=['dinc']) root.connect('dinc1', 'dinc_total.dinc1') root.connect('dinc2', 'dinc_total.dinc2') prob.driver = ScipyOptimizer() prob.driver.add_desvar('dinc1', lower=0, upper=28.5) prob.driver.add_desvar('dinc2', lower=0, upper=28.5) prob.driver.add_constraint('dinc', lower=28.5, upper=28.5, scaler=1.0) prob.driver.add_objective('delta_v', scaler=1.0) # Setup the problem prob.setup() # Set initial values prob['mu'] = 398600.4418 prob['r1'] = 6778.137 prob['r2'] = 42164.0 prob['dinc1'] = 0.0 prob['dinc2'] = 0.0 # Go! prob.run() self.assertAlmostEqual(prob['delta_v'], 4.19629634132, places=4) self.assertAlmostEqual(prob['dinc1'], 2.2348615725962211, places=4) self.assertAlmostEqual(prob['dinc2'], 26.26513842740378, places=4)
def test_deriv_options_meta_form(self): class MetaParaboloid(Component): """ Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """ def __init__(self): super(MetaParaboloid, self).__init__() # Params self.add_param('x1', 1.0, form = 'forward') self.add_param('x2', 1.0, form = 'backward') self.add_param('y', 1.0) # Unknowns self.add_output('f_xy', 0.0) def solve_nonlinear(self, params, unknowns, resids): """f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 Optimal solution (minimum): x = 6.6667; y = -7.3333 """ x1 = params['x1'] x2 = params['x2'] y = params['y'] f_xy = ((x1-3.0)**2 + (x2-3.0)**2 + (x2+x2)*y + (y+4.0)**2 - 3.0) unknowns['f_xy'] = f_xy def linearize(self, params, unknowns, resids): """Analytical derivatives""" x1 = params['x1'] x2 = params['x2'] y = params['y'] J = {} J['f_xy', 'x1'] = (2.0*x1 - 6.0 + x2*y) J['f_xy', 'x2'] = (2.0*x2 - 6.0 + x1*y) J['f_xy', 'y'] = (2.0*y + 8.0 + x1 + x2) return J prob = Problem() prob.root = Group() comp = prob.root.add('comp', MetaParaboloid()) prob.root.add('p11', IndepVarComp('x1', 15.0)) prob.root.add('p12', IndepVarComp('x2', 15.0)) prob.root.add('p2', IndepVarComp('y', 15.0)) prob.root.connect('p11.x1', 'comp.x1') prob.root.connect('p12.x2', 'comp.x2') prob.root.connect('p2.y', 'comp.y') comp.deriv_options['type'] = 'fd' comp.deriv_options['step_size'] = 1e3 params_list = ['p11.x1'] unknowns_list = ['comp.f_xy'] prob.setup(check=False) prob.run() J = prob.calc_gradient(params_list, unknowns_list, return_format='dict') self.assertGreater(J['comp.f_xy']['p11.x1'][0][0], 0.0) J = prob.calc_gradient(['p12.x2'], unknowns_list, return_format='dict') self.assertLess(J['comp.f_xy']['p12.x2'][0][0], 0.0)
class TestExternalCode(unittest.TestCase): def setUp(self): self.startdir = os.getcwd() self.tempdir = tempfile.mkdtemp(prefix='test_extcode-') os.chdir(self.tempdir) shutil.copy(os.path.join(DIRECTORY, 'external_code_for_testing.py'), os.path.join(self.tempdir, 'external_code_for_testing.py')) self.extcode = ExternalCodeForTesting() self.top = Problem() self.top.root = Group() self.top.root.add('extcode', self.extcode) def tearDown(self): os.chdir(self.startdir) if not os.environ.get('OPENMDAO_KEEPDIRS', False): try: shutil.rmtree(self.tempdir) except OSError: pass def test_normal(self): self.extcode.options['command'] = ['python', 'external_code_for_testing.py', 'external_code_output.txt'] self.extcode.options['external_input_files'] = ['external_code_for_testing.py',] self.extcode.options['external_output_files'] = ['external_code_output.txt',] dev_null = open(os.devnull, 'w') self.top.setup(check=True, out_stream=dev_null) self.top.run() self.assertEqual(self.extcode.timed_out, False) self.assertEqual(self.extcode.errored_out, False) # def test_ls_command(self): # output_filename = 'ls_output.txt' # if sys.platform == 'win32': # self.extcode.options['command'] = ['dir', ] # else: # self.extcode.options['command'] = ['ls', ] # self.extcode.stdout = output_filename # self.extcode.options['external_output_files'] = [output_filename,] # self.top.setup() # self.top.run() # # check the contents of the output file for 'external_code_for_testing.py' # with open(os.path.join(self.tempdir, output_filename), 'r') as out: # file_contents = out.read() # self.assertTrue('external_code_for_testing.py' in file_contents) def test_timeout_raise(self): self.extcode.options['command'] = ['python', 'external_code_for_testing.py', 'external_code_output.txt', '--delay', '3'] self.extcode.options['timeout'] = 1.0 self.extcode.options['external_input_files'] = ['external_code_for_testing.py', ] dev_null = open(os.devnull, 'w') self.top.setup(check=True, out_stream=dev_null) try: self.top.run() except RuntimeError as exc: self.assertEqual(str(exc), 'Timed out') self.assertEqual(self.extcode.timed_out, True) else: self.fail('Expected RunInterrupted') def test_timeout_continue(self): self.extcode.options['command'] = ['python', 'external_code_for_testing.py', 'external_code_output.txt', '--delay', '3'] self.extcode.options['timeout'] = 1.0 self.extcode.options['external_input_files'] = ['external_code_for_testing.py', ] self.extcode.options['on_timeout'] = 'continue' dev_null = open(os.devnull, 'w') self.top.setup(check=True, out_stream=dev_null) self.top.run() self.assertEqual(self.extcode.timed_out, True) def test_error_code_raise(self): self.extcode.options['command'] = ['python', 'external_code_for_testing.py', 'external_code_output.txt', '--delay', '-3'] self.extcode.options['timeout'] = 1.0 self.extcode.options['external_input_files'] = ['external_code_for_testing.py', ] dev_null = open(os.devnull, 'w') self.top.setup(check=True, out_stream=dev_null) try: self.top.run() except RuntimeError as exc: self.assertTrue('Traceback' in str(exc)) self.assertEqual(self.extcode.return_code, 1) self.assertEqual(self.extcode.errored_out, True) else: self.fail('Expected ValueError') def test_error_code_continue(self): self.extcode.options['command'] = ['python', 'external_code_for_testing.py', 'external_code_output.txt', '--delay', '-3'] self.extcode.options['timeout'] = 1.0 self.extcode.options['on_error'] = 'continue' self.extcode.options['external_input_files'] = ['external_code_for_testing.py', ] dev_null = open(os.devnull, 'w') self.top.setup(check=True, out_stream=dev_null) self.top.run() self.assertEqual(self.extcode.errored_out, True) def test_badcmd(self): # Set command to nonexistant path. self.extcode.options['command'] = ['no-such-command', ] self.top.setup(check=False) try: self.top.run() except ValueError as exc: msg = "The command to be executed, 'no-such-command', cannot be found" self.assertEqual(str(exc), msg) self.assertEqual(self.extcode.return_code, -999999) else: self.fail('Expected ValueError') def test_nullcmd(self): self.extcode.stdout = 'nullcmd.out' self.extcode.stderr = STDOUT self.top.setup(check=False) try: self.top.run() except ValueError as exc: self.assertEqual(str(exc), 'Empty command list') else: self.fail('Expected ValueError') finally: if os.path.exists(self.extcode.stdout): os.remove(self.extcode.stdout) def test_env_vars(self): self.extcode.options['env_vars'] = {'TEST_ENV_VAR': 'SOME_ENV_VAR_VALUE'} self.extcode.options['command'] = ['python', 'external_code_for_testing.py', 'external_code_output.txt', '--write_test_env_var'] dev_null = open(os.devnull, 'w') self.top.setup(check=True, out_stream=dev_null) self.top.run() # Check to see if output file contains the env var value with open(os.path.join(self.tempdir, 'external_code_output.txt'), 'r') as out: file_contents = out.read() self.assertTrue('SOME_ENV_VAR_VALUE' in file_contents) def test_check_external_outputs(self): # In the external_files list give it a file that will not be created # If check_external_outputs is True, there will be an exception, but since we set it # to False, no exception should be thrown self.extcode.options['check_external_outputs'] = False self.extcode.options['external_input_files'] = ['external_code_for_testing.py',] self.extcode.options['external_output_files'] = ['does_not_exist.txt',] self.extcode.options['command'] = ['python', 'external_code_for_testing.py', 'external_code_output.txt'] self.top.setup(check=False) self.top.run()
def execute(self): # --- Import Modules import numpy as np import os from openmdao.api import IndepVarComp, Component, Group, Problem, Brent, ScipyGMRES, ScipyOptimizer, DumpRecorder from rotorse.rotor_aeropower import RotorAeroPower from rotorse.rotor_geometry import RotorGeometry, NREL5MW, DTU10MW, NINPUT from rotorse import RPM2RS, RS2RPM, TURBULENCE_CLASS, DRIVETRAIN_TYPE from rotorse.rotor import RotorSE myref = DTU10MW() rotor = Problem() npts_coarse_power_curve = 20 # (Int): number of points to evaluate aero analysis at npts_spline_power_curve = 200 # (Int): number of points to use in fitting spline to power curve rotor.root = RotorSE(myref, npts_coarse_power_curve, npts_spline_power_curve) rotor.setup() # --- # === blade grid === rotor[ 'hubFraction'] = myref.hubFraction #0.023785 # (Float): hub location as fraction of radius rotor[ 'bladeLength'] = myref.bladeLength #96.7 # (Float, m): blade length (if not precurved or swept) otherwise length of blade before curvature rotor['precone'] = myref.precone #4. # (Float, deg): precone angle rotor['tilt'] = myref.tilt #6.0 # (Float, deg): shaft tilt rotor['yaw'] = 0.0 # (Float, deg): yaw error rotor['nBlades'] = myref.nBlades #3 # (Int): number of blades # --- # === blade geometry === rotor[ 'r_max_chord'] = myref.r_max_chord # 0.2366 #(Float): location of max chord on unit radius rotor[ 'chord_in'] = myref.chord # np.array([4.6, 4.869795, 5.990629, 3.00785428, 0.0962]) # (Array, m): chord at control points. defined at hub, then at linearly spaced locations from r_max_chord to tip rotor[ 'theta_in'] = myref.theta # np.array([14.5, 12.874, 6.724, -0.03388039, -0.037]) # (Array, deg): twist at control points. defined at linearly spaced locations from r[idx_cylinder] to tip rotor[ 'precurve_in'] = myref.precurve #np.array([-0., -0.054497, -0.175303, -0.84976143, -6.206217]) # (Array, m): precurve at control points. defined at same locations at chord, starting at 2nd control point (root must be zero precurve) rotor[ 'presweep_in'] = myref.presweep #np.array([0., 0., 0., 0., 0.]) # (Array, m): precurve at control points. defined at same locations at chord, starting at 2nd control point (root must be zero precurve) rotor[ 'sparT_in'] = myref.spar_thickness # np.array([0.03200042 0.07038508 0.08515644 0.07777004 0.01181032]) # (Array, m): spar cap thickness parameters rotor[ 'teT_in'] = myref.te_thickness # np.array([0.04200055 0.08807739 0.05437378 0.01610219 0.00345225]) # (Array, m): trailing-edge thickness parameters # --- # === atmosphere === rotor['analysis.rho'] = 1.225 # (Float, kg/m**3): density of air rotor[ 'analysis.mu'] = 1.81206e-5 # (Float, kg/m/s): dynamic viscosity of air rotor['wind.shearExp'] = 0.25 # (Float): shear exponent rotor[ 'hub_height'] = myref.hub_height #119.0 # (Float, m): hub height rotor[ 'turbine_class'] = myref.turbine_class #TURBINE_CLASS['I'] # (Enum): IEC turbine class rotor['turbulence_class'] = TURBULENCE_CLASS[ 'B'] # (Enum): IEC turbulence class class rotor[ 'wind.zref'] = myref.hub_height #119.0 # (Float): reference hub height for IEC wind speed (used in CDF calculation) rotor['gust_stddev'] = 3 # --- # === control === rotor[ 'control_Vin'] = myref.control_Vin #4.0 # (Float, m/s): cut-in wind speed rotor[ 'control_Vout'] = myref.control_Vout #25.0 # (Float, m/s): cut-out wind speed rotor[ 'control_minOmega'] = myref.control_minOmega #6.0 # (Float, rpm): minimum allowed rotor rotation speed rotor[ 'control_maxOmega'] = myref.control_maxOmega #8.88766 # (Float, rpm): maximum allowed rotor rotation speed rotor[ 'control_tsr'] = myref.control_tsr #10.58 # (Float): tip-speed ratio in Region 2 (should be optimized externally) rotor[ 'control_pitch'] = myref.control_pitch #0.0 # (Float, deg): pitch angle in region 2 (and region 3 for fixed pitch machines) rotor[ 'machine_rating'] = myref.rating #10e6 # (Float, W): rated power rotor[ 'pitch_extreme'] = 0.0 # (Float, deg): worst-case pitch at survival wind condition rotor[ 'azimuth_extreme'] = 0.0 # (Float, deg): worst-case azimuth at survival wind condition rotor[ 'VfactorPC'] = 0.7 # (Float): fraction of rated speed at which the deflection is assumed to representative throughout the power curve calculation # --- # === aero and structural analysis options === rotor[ 'nSector'] = 4 # (Int): number of sectors to divide rotor face into in computing thrust and power rotor[ 'AEP_loss_factor'] = 1.0 # (Float): availability and other losses (soiling, array, etc.) rotor[ 'drivetrainType'] = myref.drivetrain #DRIVETRAIN_TYPE['GEARED'] # (Enum) rotor[ 'dynamic_amplication_tip_deflection'] = 1.35 # (Float): a dynamic amplification factor to adjust the static deflection calculation # --- # === fatigue === r_aero = np.array([ 0.02222276, 0.06666667, 0.11111057, 0.2, 0.23333333, 0.3, 0.36666667, 0.43333333, 0.5, 0.56666667, 0.63333333, 0.64, 0.7, 0.83333333, 0.88888943, 0.93333333, 0.97777724 ]) # (Array): new aerodynamic grid on unit radius rstar_damage = np.array( [ 0.000, 0.022, 0.067, 0.111, 0.167, 0.233, 0.300, 0.367, 0.433, 0.500, 0.567, 0.633, 0.700, 0.767, 0.833, 0.889, 0.933, 0.978 ] ) # (Array): nondimensional radial locations of damage equivalent moments Mxb_damage = 1e3 * np.array([ 2.3743E+003, 2.0834E+003, 1.8108E+003, 1.5705E+003, 1.3104E+003, 1.0488E+003, 8.2367E+002, 6.3407E+002, 4.7727E+002, 3.4804E+002, 2.4458E+002, 1.6339E+002, 1.0252E+002, 5.7842E+001, 2.7349E+001, 1.1262E+001, 3.8549E+000, 4.4738E-001 ]) # (Array, N*m): damage equivalent moments about blade c.s. x-direction Myb_damage = 1e3 * np.array([ 2.7732E+003, 2.8155E+003, 2.6004E+003, 2.3933E+003, 2.1371E+003, 1.8459E+003, 1.5582E+003, 1.2896E+003, 1.0427E+003, 8.2015E+002, 6.2449E+002, 4.5229E+002, 3.0658E+002, 1.8746E+002, 9.6475E+001, 4.2677E+001, 1.5409E+001, 1.8426E+000 ]) # (Array, N*m): damage equivalent moments about blade c.s. y-direction xp = np.r_[0.0, r_aero] xx = np.r_[0.0, myref.r] rotor['rstar_damage'] = np.interp(xx, xp, rstar_damage) rotor['Mxb_damage'] = np.interp(xx, xp, Mxb_damage) rotor['Myb_damage'] = np.interp(xx, xp, Myb_damage) rotor[ 'strain_ult_spar'] = 1.0e-2 # (Float): ultimate strain in spar cap rotor[ 'strain_ult_te'] = 2500 * 1e-6 * 2 # (Float): uptimate strain in trailing-edge panels, note that I am putting a factor of two for the damage part only. rotor['gamma_fatigue'] = 1.755 # (Float): safety factor for fatigue rotor['gamma_f'] = 1.35 # (Float): safety factor for loads/stresses rotor['gamma_m'] = 1.1 # (Float): safety factor for materials rotor[ 'gamma_freq'] = 1.1 # (Float): safety factor for resonant frequencies rotor[ 'm_damage'] = 10.0 # (Float): slope of S-N curve for fatigue analysis rotor[ 'struc.lifetime'] = 20.0 # (Float): number of cycles used in fatigue analysis TODO: make function of rotation speed # ---------------- # === run and outputs === rotor.run() print 'AEP =', rotor['AEP'] print 'diameter =', rotor['diameter'] print 'rated_V =', rotor['rated_V'] print 'rated_Omega =', rotor['rated_Omega'] print 'rated_pitch =', rotor['rated_pitch'] print 'rated_T =', rotor['rated_T'] print 'rated_Q =', rotor['rated_Q'] print 'mass_one_blade =', rotor['mass_one_blade'] print 'mass_all_blades =', rotor['mass_all_blades'] print 'I_all_blades =', rotor['I_all_blades'] print 'freq =', rotor['freq'] print 'tip_deflection =', rotor['tip_deflection'] print 'root_bending_moment =', rotor['root_bending_moment'] outpath = '..\..\..\docs\images' import matplotlib.pyplot as plt plt.figure() plt.plot(rotor['V'], rotor['P'] / 1e6) plt.xlabel('wind speed (m/s)') plt.xlabel('power (W)') plt.figure() plt.plot(rotor['r_pts'], rotor['strainU_spar'], label='suction') plt.plot(rotor['r_pts'], rotor['strainL_spar'], label='pressure') plt.plot(rotor['r_pts'], rotor['eps_crit_spar'], label='critical') # plt.ylim([-6e-3, 6e-3]) plt.xlabel('r') plt.ylabel('strain') plt.legend() plt.savefig( os.path.abspath(os.path.join(outpath, 'strain_spar_dtu10mw.png'))) plt.savefig( os.path.abspath(os.path.join(outpath, 'strain_spar_dtu10mw.pdf'))) plt.figure() plt.plot(rotor['r_pts'], rotor['strainU_te'], label='suction') plt.plot(rotor['r_pts'], rotor['strainL_te'], label='pressure') plt.plot(rotor['r_pts'], rotor['eps_crit_te'], label='critical') # plt.ylim([-5e-3, 5e-3]) plt.xlabel('r') plt.ylabel('strain') plt.legend() plt.savefig( os.path.abspath(os.path.join(outpath, 'strain_te_dtu10mw.png'))) plt.savefig( os.path.abspath(os.path.join(outpath, 'strain_te_dtu10mw.pdf'))) plt.show()
if MPI: # pragma: no cover # if you called this script with 'mpirun', then use the petsc data passing from openmdao.core.petsc_impl import PetscImpl as impl else: # if you didn't use `mpirun`, then use the numpy data passing from openmdao.api import BasicImpl as impl problem = Problem(impl=impl) root = problem.root = Group() root.add('indep_var', IndepVarComp('x', val=7.0)) root.add('const', IndepVarComp('c', val=3.0, pass_by_obj=False)) root.add('dut', DUT()) root.connect('indep_var.x', 'dut.x') root.connect('const.c', 'dut.c') problem.driver = UniformDriver(num_samples=10, num_par_doe=5) problem.driver.add_desvar('indep_var.x', low=4410.0, high=4450.0) problem.driver.add_objective('dut.y') recorder = DumpRecorder() problem.driver.add_recorder(recorder) problem.setup() problem.run() problem['dut.y'] problem.cleanup()
def test_poi_index_w_irrelevant_var(self): prob = Problem() prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = OPTIMIZER prob.driver.options['print_results'] = False prob.root = root = Group() prob.root.ln_solver = LinearGaussSeidel() prob.root.ln_solver.options['single_voi_relevance_reduction'] = True root.add('p1', IndepVarComp('x', np.array([1.0, 3.0, 4.0]))) root.add('p2', IndepVarComp('x', np.array([5.0, 2.0, -1.0]))) root.add('C1', ExecComp('y = 2.0*x', x=np.zeros(3), y=np.zeros(3))) root.add('C2', ExecComp('y = 3.0*x', x=np.zeros(3), y=np.zeros(3))) root.add('con1', ExecComp('c = 7.0 - y', y=np.zeros(3), c=np.zeros(3))) root.add('con2', ExecComp('c = 2.0 - y', y=np.zeros(3), c=np.zeros(3))) root.add('obj', ExecComp('o = y1+y2')) prob.driver.add_desvar('p1.x', indices=[1]) prob.driver.add_desvar('p2.x', indices=[2]) prob.driver.add_constraint('con1.c', upper=0.0, indices=[1]) prob.driver.add_constraint('con2.c', upper=0.0, indices=[2]) prob.driver.add_objective('obj.o') root.connect('p1.x', 'C1.x') root.connect('p2.x', 'C2.x') root.connect('C1.y', 'con1.y') root.connect('C2.y', 'con2.y') root.connect('C1.y', 'obj.y1', src_indices=[1]) root.connect('C2.y', 'obj.y2', src_indices=[2]) prob.root.ln_solver.options['mode'] = 'rev' prob.setup(check=False) prob.run() # I was trying in this test to duplicate an error in pointer, but wasn't able to. # I was able to find a different error that occurred when using return_format='array' # that was also fixed by the same PR that fixed pointer. J = prob.calc_gradient(['p1.x', 'p2.x'], ['con1.c', 'con2.c'], mode='rev', return_format='array') assert_rel_error(self, J[0][0], -2.0, 1e-3) assert_rel_error(self, J[0][1], .0, 1e-3) assert_rel_error(self, J[1][0], .0, 1e-3) assert_rel_error(self, J[1][1], -3.0, 1e-3) J = prob.calc_gradient(['p1.x', 'p2.x'], ['con1.c', 'con2.c'], mode='rev', return_format='dict') assert_rel_error(self, J['con1.c']['p1.x'], -2.0, 1e-3) assert_rel_error(self, J['con1.c']['p2.x'], .0, 1e-3) assert_rel_error(self, J['con2.c']['p1.x'], .0, 1e-3) assert_rel_error(self, J['con2.c']['p2.x'], -3.0, 1e-3) # Cheat a bit so I can twiddle mode OptionsDictionary.locked = False prob.root.ln_solver.options['mode'] = 'fwd' prob.setup(check=False) prob.run() J = prob.calc_gradient(['p1.x', 'p2.x'], ['con1.c', 'con2.c'], mode='fwd', return_format='array') assert_rel_error(self, J[0][0], -2.0, 1e-3) assert_rel_error(self, J[0][1], .0, 1e-3) assert_rel_error(self, J[1][0], .0, 1e-3) assert_rel_error(self, J[1][1], -3.0, 1e-3) J = prob.calc_gradient(['p1.x', 'p2.x'], ['con1.c', 'con2.c'], mode='fwd', return_format='dict') assert_rel_error(self, J['con1.c']['p1.x'], -2.0, 1e-3) assert_rel_error(self, J['con1.c']['p2.x'], .0, 1e-3) assert_rel_error(self, J['con2.c']['p1.x'], .0, 1e-3) assert_rel_error(self, J['con2.c']['p2.x'], -3.0, 1e-3)
def test_scaler_adder_array(self): class ScaleAddDriver(Driver): def run(self, problem): """ Save away scaled info.""" params = self.get_desvars() param_meta = self.get_desvar_metadata() self.set_desvar('x', np.array([22.0, 404.0, 9009.0, 121000.0])) problem.root.solve_nonlinear() objective = self.get_objectives() constraint = self.get_constraints() # Stuff we saved should be in the scaled coordinates. self.param = params['x'] self.obj_scaled = objective['y'] self.con_scaled = constraint['con'] self.param_low = param_meta['x']['lower'] prob = Problem() root = prob.root = Group() driver = prob.driver = ScaleAddDriver() root.add('p1', IndepVarComp('x', val=np.array([[1.0, 1.0], [1.0, 1.0]])), promotes=['*']) root.add('comp', ArrayComp2D(), promotes=['*']) root.add('constraint', ExecComp('con = x + y', x=np.array([[1.0, 1.0], [1.0, 1.0]]), y=np.array([[1.0, 1.0], [1.0, 1.0]]), con=np.array([[1.0, 1.0], [1.0, 1.0]])), promotes=['*']) driver.add_desvar('x', lower=np.array([[-1e5, -1e5], [-1e5, -1e5]]), adder=np.array([[10.0, 100.0], [1000.0, 10000.0]]), scaler=np.array([[1.0, 2.0], [3.0, 4.0]])) driver.add_objective('y', adder=np.array([[10.0, 100.0], [1000.0, 10000.0]]), scaler=np.array([[1.0, 2.0], [3.0, 4.0]])) driver.add_constraint('con', upper=np.zeros((2, 2)), adder=np.array([[10.0, 100.0], [1000.0, 10000.0]]), scaler=np.array([[1.0, 2.0], [3.0, 4.0]])) prob.setup(check=False) prob.run() self.assertEqual(driver.param[0], 11.0) self.assertEqual(driver.param[1], 202.0) self.assertEqual(driver.param[2], 3003.0) self.assertEqual(driver.param[3], 40004.0) self.assertEqual(prob['x'][0, 0], 12.0) self.assertEqual(prob['x'][0, 1], 102.0) self.assertEqual(prob['x'][1, 0], 2003.0) self.assertEqual(prob['x'][1, 1], 20250.0) self.assertEqual(driver.obj_scaled[0], (prob['y'][0, 0] + 10.0) * 1.0) self.assertEqual(driver.obj_scaled[1], (prob['y'][0, 1] + 100.0) * 2.0) self.assertEqual(driver.obj_scaled[2], (prob['y'][1, 0] + 1000.0) * 3.0) self.assertEqual(driver.obj_scaled[3], (prob['y'][1, 1] + 10000.0) * 4.0) self.assertEqual(driver.param_low[0], (-1e5 + 10.0) * 1.0) self.assertEqual(driver.param_low[1], (-1e5 + 100.0) * 2.0) self.assertEqual(driver.param_low[2], (-1e5 + 1000.0) * 3.0) self.assertEqual(driver.param_low[3], (-1e5 + 10000.0) * 4.0) conval = prob['x'] + prob['y'] self.assertEqual(driver.con_scaled[0], (conval[0, 0] + 10.0) * 1.0) self.assertEqual(driver.con_scaled[1], (conval[0, 1] + 100.0) * 2.0) self.assertEqual(driver.con_scaled[2], (conval[1, 0] + 1000.0) * 3.0) self.assertEqual(driver.con_scaled[3], (conval[1, 1] + 10000.0) * 4.0)
def execute(self): # --- Import Modules import numpy as np import os from openmdao.api import IndepVarComp, Component, Group, Problem, Brent, ScipyGMRES from rotorse.rotor_aeropower import RotorAeroPower from rotorse.rotor_geometry import RotorGeometry, NREL5MW, DTU10MW, NINPUT from rotorse import RPM2RS, RS2RPM, TURBULENCE_CLASS, DRIVETRAIN_TYPE # --- # --- Init Problem rotor = Problem() myref = DTU10MW() npts_coarse_power_curve = 20 # (Int): number of points to evaluate aero analysis at npts_spline_power_curve = 200 # (Int): number of points to use in fitting spline to power curve rotor.root = RotorAeroPower(myref, npts_coarse_power_curve, npts_spline_power_curve) rotor.setup() # --- # --- default inputs # === blade grid === rotor['hubFraction'] = myref.hubFraction #0.023785 # (Float): hub location as fraction of radius rotor['bladeLength'] = myref.bladeLength #96.7 # (Float, m): blade length (if not precurved or swept) otherwise length of blade before curvature rotor['precone'] = myref.precone #4. # (Float, deg): precone angle rotor['tilt'] = myref.tilt #6.0 # (Float, deg): shaft tilt rotor['yaw'] = 0.0 # (Float, deg): yaw error rotor['nBlades'] = myref.nBlades #3 # (Int): number of blades # === blade geometry === rotor['r_max_chord'] = myref.r_max_chord #0.2366 # (Float): location of max chord on unit radius rotor['chord_in'] = myref.chord #np.array([4.6, 4.869795, 5.990629, 3.00785428, 0.0962]) # (Array, m): chord at control points. defined at hub, then at linearly spaced locations from r_max_chord to tip rotor['theta_in'] = myref.theta #np.array([14.5, 12.874, 6.724, -0.03388039, -0.037]) # (Array, deg): twist at control points. defined at linearly spaced locations from r[idx_cylinder] to tip rotor['precurve_in'] = myref.precurve #np.array([-0., -0.054497, -0.175303, -0.84976143, -6.206217]) # (Array, m): precurve at control points. defined at same locations at chord, starting at 2nd control point (root must be zero precurve) rotor['presweep_in'] = myref.presweep #np.array([0., 0., 0., 0., 0.]) # (Array, m): precurve at control points. defined at same locations at chord, starting at 2nd control point (root must be zero precurve) rotor['sparT_in'] = myref.spar_thickness #np.array([0.03200042 0.07038508 0.08515644 0.07777004 0.01181032]) # (Array, m): spar cap thickness parameters rotor['teT_in'] = myref.te_thickness #np.array([0.04200055 0.08807739 0.05437378 0.01610219 0.00345225]) # (Array, m): trailing-edge thickness parameters # === atmosphere === rotor['analysis.rho'] = 1.225 # (Float, kg/m**3): density of air rotor['analysis.mu'] = 1.81206e-5 # (Float, kg/m/s): dynamic viscosity of air rotor['hub_height'] = myref.hub_height #119.0 rotor['analysis.shearExp'] = 0.25 # (Float): shear exponent rotor['turbine_class'] = myref.turbine_class #TURBINE_CLASS['I'] # (Enum): IEC turbine class rotor['cdf_reference_height_wind_speed'] = myref.hub_height #119.0 # (Float): reference hub height for IEC wind speed (used in CDF calculation) # === control === rotor['control_Vin'] = myref.control_Vin #4.0 # (Float, m/s): cut-in wind speed rotor['control_Vout'] = myref.control_Vout #25.0 # (Float, m/s): cut-out wind speed rotor['control_ratedPower'] = myref.rating #10e6 # (Float, W): rated power rotor['control_minOmega'] = myref.control_minOmega #6.0 # (Float, rpm): minimum allowed rotor rotation speed rotor['control_maxOmega'] = myref.control_maxOmega #8.88766 # (Float, rpm): maximum allowed rotor rotation speed rotor['control_tsr'] = myref.control_tsr #10.58 # (Float): tip-speed ratio in Region 2 (should be optimized externally) rotor['control_pitch'] = myref.control_pitch #0.0 # (Float, deg): pitch angle in region 2 (and region 3 for fixed pitch machines) # === aero and structural analysis options === rotor['nSector'] = 4 # (Int): number of sectors to divide rotor face into in computing thrust and power rotor['AEP_loss_factor'] = 1.0 # (Float): availability and other losses (soiling, array, etc.) rotor['drivetrainType'] = myref.drivetrain #DRIVETRAIN_TYPE['GEARED'] # (Enum) # --- # === run and outputs === rotor.run() print 'AEP =', rotor['AEP'] print 'diameter =', rotor['diameter'] print 'ratedConditions.V =', rotor['rated_V'] print 'ratedConditions.Omega =', rotor['rated_Omega'] print 'ratedConditions.pitch =', rotor['rated_pitch'] print 'ratedConditions.T =', rotor['rated_T'] print 'ratedConditions.Q =', rotor['rated_Q'] import matplotlib.pyplot as plt plt.plot(rotor['V'], rotor['P']/1e6) plt.xlabel('Wind Speed (m/s)') plt.ylabel('Power (MW)') # plt.show() # --- outpath = '..\..\..\docs\images' # Power Curve f, ax = plt.subplots(1,1,figsize=(5.3, 4)) ax.plot(rotor['V'], rotor['P']/1e6) ax.set(xlabel='Wind Speed (m/s)' , ylabel='Power (MW)') ax.set_ylim([0, 10.3]) ax.set_xlim([0, 25]) f.tight_layout() ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # f.savefig(os.path.abspath(os.path.join(outpath,'power_curve_dtu10mw.png'))) # f.savefig(os.path.abspath(os.path.join(outpath,'power_curve_dtu10mw.pdf'))) # Chord fc, axc = plt.subplots(1,1,figsize=(5.3, 4)) rc_c = np.r_[0.0, myref.r_cylinder, np.linspace(rotor['r_max_chord'], 1.0, NINPUT-2)] r = (rotor['r_pts'] - rotor['Rhub'])/rotor['bladeLength'] axc.plot(r, rotor['chord'], c='k') axc.plot(rc_c, rotor['chord_in'], '.', c='k') for i, (x, y) in enumerate(zip(rc_c, rotor['chord_in'])): txt = '$c_%d$' % i if i<=1: axc.annotate(txt, (x,y), xytext=(x+0.01,y-0.4), textcoords='data') else: axc.annotate(txt, (x,y), xytext=(x+0.01,y+0.2), textcoords='data') axc.set(xlabel='Blade Fraction, $r/R$' , ylabel='Chord (m)') axc.set_ylim([0, 7.5]) axc.set_xlim([0, 1.1]) fc.tight_layout() axc.spines['right'].set_visible(False) axc.spines['top'].set_visible(False) # fc.savefig(os.path.abspath(os.path.join(outpath,'chord_dtu10mw.png'))) # fc.savefig(os.path.abspath(os.path.join(outpath,'chord_dtu10mw.pdf'))) # Twist ft, axt = plt.subplots(1,1,figsize=(5.3, 4)) rc_t = rc_c#np.linspace(myref.r_cylinder, 1.0, NINPUT) r = (rotor['r_pts'] - rotor['Rhub'])/rotor['bladeLength'] axt.plot(r, rotor['theta'], c='k') axt.plot(rc_t, rotor['theta_in'], '.', c='k') for i, (x, y) in enumerate(zip(rc_t, rotor['theta_in'])): txt = '$\Theta_%d$' % i axt.annotate(txt, (x,y), xytext=(x+0.01,y+0.1), textcoords='data') axt.set(xlabel='Blade Fraction, $r/R$' , ylabel='Twist ($\deg$)') axt.set_ylim([-1, 15]) axt.set_xlim([0, 1.1]) ft.tight_layout() axt.spines['right'].set_visible(False) axt.spines['top'].set_visible(False) # ft.savefig(os.path.abspath(os.path.join(outpath,'theta_dtu10mw.png'))) # ft.savefig(os.path.abspath(os.path.join(outpath,'theta_dtu10mw.pdf'))) plt.show()
def test_basics(self): # create a metamodel component mm = MetaModel() mm.add_param('x1', 0.) mm.add_param('x2', 0.) mm.add_output('y1', 0.) mm.add_output('y2', 0., surrogate=FloatKrigingSurrogate()) mm.default_surrogate = ResponseSurface() # add metamodel to a problem prob = Problem(root=Group()) prob.root.add('mm', mm) prob.setup(check=False) # check that surrogates were properly assigned surrogate = prob.root.unknowns.metadata('mm.y1').get('surrogate') self.assertTrue(isinstance(surrogate, ResponseSurface)) surrogate = prob.root.unknowns.metadata('mm.y2').get('surrogate') self.assertTrue(isinstance(surrogate, FloatKrigingSurrogate)) # populate training data prob['mm.train:x1'] = [1.0, 2.0, 3.0] prob['mm.train:x2'] = [1.0, 3.0, 4.0] prob['mm.train:y1'] = [3.0, 2.0, 1.0] prob['mm.train:y2'] = [1.0, 4.0, 7.0] # run problem for provided data point and check prediction prob['mm.x1'] = 2.0 prob['mm.x2'] = 3.0 self.assertTrue(mm.train) # training will occur before 1st run prob.run() assert_rel_error(self, prob['mm.y1'], 2.0, .00001) assert_rel_error(self, prob['mm.y2'], 4.0, .00001) # run problem for interpolated data point and check prediction prob['mm.x1'] = 2.5 prob['mm.x2'] = 3.5 self.assertFalse(mm.train) # training will not occur before 2nd run prob.run() assert_rel_error(self, prob['mm.y1'], 1.5934, .001) # change default surrogate, re-setup and check that metamodel re-trains mm.default_surrogate = FloatKrigingSurrogate() prob.setup(check=False) surrogate = prob.root.unknowns.metadata('mm.y1').get('surrogate') self.assertTrue(isinstance(surrogate, FloatKrigingSurrogate)) self.assertTrue(mm.train) # training will occur after re-setup mm.warm_restart = True # use existing training data prob['mm.x1'] = 2.5 prob['mm.x2'] = 3.5 prob.run() assert_rel_error(self, prob['mm.y1'], 1.5, 1e-2)
self.add('px', IndepVarComp('x', 2.0)) self.add('comp1', SimpleComp()) self.add('comp2', SimpleComp()) self.add('comp3', SimpleComp()) self.add('comp4', SimpleComp()) self.connect('px.x', 'comp1.x') self.connect('comp1.y', 'comp2.x') self.connect('comp2.y', 'comp3.x') self.connect('comp3.y', 'comp4.x') # Tell these whole model to finite difference self.fd_options['force_fd'] = True if __name__ == '__main__': # Setup and run the model. top = Problem() top.root = Model() top.setup() top.run() print('\n\nStart Calc Gradient') print ('-'*25) J = top.calc_gradient(['px.x'], ['comp4.y']) print(J)
def setup(num_inboard=2, num_outboard=3, check=False, out_stream=sys.stdout): ''' Setup the aerostruct mesh using OpenMDAO''' # Define the aircraft properties from CRM import span, v, alpha, rho # Define spatialbeam properties from aluminum import E, G, stress, mrho # Create the mesh with 2 inboard points and 3 outboard points. # This will be mirrored to produce a mesh with 7 spanwise points, # or 6 spanwise panels # print(type(num_inboard)) mesh = gen_crm_mesh(int(num_inboard), int(num_outboard), num_x=2) num_x, num_y = mesh.shape[:2] num_twist = np.max([int((num_y - 1) / 5), 5]) r = radii(mesh) # Set the number of thickness control points and the initial thicknesses num_thickness = num_twist t = r / 10 mesh = mesh.reshape(-1, mesh.shape[-1]) aero_ind = np.atleast_2d(np.array([num_x, num_y])) fem_ind = [num_y] aero_ind, fem_ind = get_inds(aero_ind, fem_ind) # Set additional mesh parameters dihedral = 0. # dihedral angle in degrees sweep = 0. # shearing sweep angle in degrees taper = 1. # taper ratio # Initial displacements of zero tot_n_fem = np.sum(fem_ind[:, 0]) disp = np.zeros((tot_n_fem, 6)) # Define Jacobians for b-spline controls tot_n_fem = np.sum(fem_ind[:, 0]) num_surf = fem_ind.shape[0] jac_twist = get_bspline_mtx(num_twist, num_y) jac_thickness = get_bspline_mtx(num_thickness, tot_n_fem - num_surf) # Define ... twist_cp = np.zeros(num_twist) thickness_cp = np.ones(num_thickness) * np.max(t) # Define the design variables des_vars = [('twist_cp', twist_cp), ('dihedral', dihedral), ('sweep', sweep), ('span', span), ('taper', taper), ('v', v), ('alpha', alpha), ('rho', rho), ('disp', disp), ('aero_ind', aero_ind), ('fem_ind', fem_ind)] root = Group() root.add( 'des_vars', IndepVarComp(des_vars), promotes=['twist_cp', 'span', 'v', 'alpha', 'rho', 'disp', 'dihedral']) root.add( 'mesh', # This component is needed, otherwise resulting loads matrix is NaN GeometryMesh( mesh, aero_ind), # changes mesh given span, sweep, twist, and des_vars promotes=['span', 'sweep', 'dihedral', 'twist', 'taper', 'mesh']) root.add('def_mesh', TransferDisplacements(aero_ind, fem_ind), promotes=['mesh', 'disp', 'def_mesh']) prob = Problem() prob.root = root prob.setup(check=check, out_stream=out_stream) prob.run() # Output the def_mesh for the aero modules def_mesh = prob['def_mesh'] # Other variables needed for aero and struct modules params = { 'mesh': mesh, 'num_x': num_x, 'num_y': num_y, 'span': span, 'twist_cp': twist_cp, 'thickness_cp': thickness_cp, 'v': v, 'alpha': alpha, 'rho': rho, 'r': r, 't': t, 'aero_ind': aero_ind, 'fem_ind': fem_ind, 'num_thickness': num_thickness, 'num_twist': num_twist, 'sweep': sweep, 'taper': taper, 'dihedral': dihedral, 'E': E, 'G': G, 'stress': stress, 'mrho': mrho, 'tot_n_fem': tot_n_fem, 'num_surf': num_surf, 'jac_twist': jac_twist, 'jac_thickness': jac_thickness, 'out_stream': out_stream, 'check': check } return (def_mesh, params)