Example #1
0
    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)
Example #2
0
    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)
Example #3
0
        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)
Example #5
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()
Example #6
0
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])
Example #8
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)
Example #9
0
    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
Example #10
0
    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
Example #11
0
    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
Example #12
0
    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
Example #13
0
 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)
Example #16
0
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)
Example #18
0
    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()
Example #19
0
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)
Example #20
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)
Example #22
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()
Example #23
0
    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()
Example #24
0
    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()
Example #25
0
    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)
Example #27
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()
Example #28
0
    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)
Example #29
0
        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)
Example #30
0
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)