Пример #1
0
class ModalElement_AsRigidBody_Tests:
    def setup(self):
        self.density = 230.4
        self.length = 20.0
        self.modes = _mock_rigid_uniform_modes(self.density, self.length)
        self.element = ModalElement('element', self.modes)

    def test_element_mass_when_aligned_with_global_coordinates(self):
        self.element.calc_mass()

        # Expected values: rod along x axis
        m = self.density * self.length
        Iy = m * self.length**2 / 3
        expected_mass = m * eye(3)
        expected_inertia = diag([0, Iy, Iy])
        expected_offdiag = zeros((3, 3))

        # Y accel -> positive moment about Z
        # Z accel -> negative moment about Y
        expected_offdiag[2, 1] = m * self.length / 2
        expected_offdiag[1, 2] = -m * self.length / 2

        elmass = self.element.mass_vv
        assert_aae(elmass[:3, :3], expected_mass)
        assert_aae(elmass[3:, 3:], expected_inertia)
        assert_aae(elmass[3:, :3], expected_offdiag)
        assert_aae(elmass[:3, 3:], expected_offdiag.T)

    def test_element_mass_when_rotated_and_offset(self):
        Rp = dot(rotmat_y(pi / 5), dot(rotmat_z(-pi / 7),
                                       rotmat_x(3 * pi / 4)))
        self.element.rp[:] = [304.3, 12.3, -402.0]
        self.element.Rp[:, :] = Rp
        self.element.calc_mass()

        # Expected values: rod along x axis
        m = self.density * self.length
        Iy = m * self.length**2 / 3
        expected_mass = m * eye(3)
        expected_inertia = diag([0, Iy, Iy])
        expected_offdiag = zeros((3, 3))

        # Y accel -> positive moment about Z
        # Z accel -> negative moment about Y
        expected_offdiag[2, 1] = m * self.length / 2
        expected_offdiag[1, 2] = -m * self.length / 2

        transform = lambda A: dot(Rp, dot(A, Rp.T))
        assert_aae(expected_mass, transform(expected_mass))

        elmass = self.element.mass_vv
        assert_aae(elmass[:3, :3], transform(expected_mass))
        assert_aae(elmass[3:, 3:], transform(expected_inertia))
        assert_aae(elmass[3:, :3], transform(expected_offdiag))
        assert_aae(elmass[:3, 3:], transform(expected_offdiag).T)
Пример #2
0
class ModalElement_AsRigidBody_Tests:

    def setup(self):
        self.density = 230.4
        self.length = 20.0
        self.modes = _mock_rigid_uniform_modes(self.density, self.length)
        self.element = ModalElement('element', self.modes)

    def test_element_mass_when_aligned_with_global_coordinates(self):
        self.element.calc_mass()

        # Expected values: rod along x axis
        m = self.density * self.length
        Iy = m * self.length**2 / 3
        expected_mass = m * eye(3)
        expected_inertia = diag([0, Iy, Iy])
        expected_offdiag = zeros((3, 3))

        # Y accel -> positive moment about Z
        # Z accel -> negative moment about Y
        expected_offdiag[2, 1] =  m * self.length / 2
        expected_offdiag[1, 2] = -m * self.length / 2

        elmass = self.element.mass_vv
        assert_aae(elmass[:3, :3], expected_mass)
        assert_aae(elmass[3:, 3:], expected_inertia)
        assert_aae(elmass[3:, :3], expected_offdiag)
        assert_aae(elmass[:3, 3:], expected_offdiag.T)

    def test_element_mass_when_rotated_and_offset(self):
        Rp = dot(rotmat_y(pi/5), dot(rotmat_z(-pi/7), rotmat_x(3*pi/4)))
        self.element.rp[:] = [304.3, 12.3, -402.0]
        self.element.Rp[:, :] = Rp
        self.element.calc_mass()

        # Expected values: rod along x axis
        m = self.density * self.length
        Iy = m * self.length**2 / 3
        expected_mass = m * eye(3)
        expected_inertia = diag([0, Iy, Iy])
        expected_offdiag = zeros((3, 3))

        # Y accel -> positive moment about Z
        # Z accel -> negative moment about Y
        expected_offdiag[2, 1] =  m * self.length / 2
        expected_offdiag[1, 2] = -m * self.length / 2

        transform = lambda A: dot(Rp, dot(A, Rp.T))
        assert_aae(expected_mass, transform(expected_mass))

        elmass = self.element.mass_vv
        assert_aae(elmass[:3, :3], transform(expected_mass))
        assert_aae(elmass[3:, 3:], transform(expected_inertia))
        assert_aae(elmass[3:, :3], transform(expected_offdiag))
        assert_aae(elmass[:3, 3:], transform(expected_offdiag).T)
Пример #3
0
    def setup(self):
        x = linspace(0, self.length, 50)
        density = self.mass / self.length
        # One mode shape: linear in z direction.
        shape = linspace(0, 1, 50)
        rotation = -np.ones(50) / self.length
        shapes = c_[0 * x, 0 * x, shape].reshape((len(x), 3, 1))
        rotations = c_[0 * x, rotation, 0 * x].reshape((len(x), 3, 1))

        # Natural frequency: w^2 = k/I
        I0 = self.mass * (self.length**2 / 3)  # inertia about end
        freq = (self.stiffness / I0)**0.5
        modes = ModalRepresentation(x, density, shapes, rotations, [freq])
        self.beam = ModalElement('beam', modes)
Пример #4
0
 def setup(self):
     self.density = 230.4
     self.length = 20.0
     self.modes = _mock_rigid_uniform_modes(self.density, self.length)
     self.element = ModalElement('element', self.modes)
Пример #5
0
def make_a_modal_beam(length, density=None, section_inertia=None):
    x = linspace(0, length, 10)
    modes = ModalRepresentation(x, density, section_inertia=section_inertia)
    beam = ModalElement('beam', modes)
    return beam
Пример #6
0
 def setup(self):
     self.density = 230.4
     self.length = 20.0
     self.modes = _mock_rigid_uniform_modes(self.density, self.length)
     self.element = ModalElement('element', self.modes)
Пример #7
0
    def __init__(self, structure_config):
        s = structure_config

        #### Load details of flexible elements ####
        if 'definition' in s['tower']:
            if 'mass' in s['tower']:
                raise ValueError("Both tower definition and explicit mass!")
            self.tower_definition = Tower(s['tower']['definition'])
            assert np.all(self.tower_definition.stn_pos[:, :2] == 0)  # vert.
            z_tower = self.tower_definition.stn_pos[:, 2]
            self.tower_modes = ModesFromScratch(
                z_tower - z_tower[0],
                self.tower_definition.density, 1,
                self.tower_definition.EIy, self.tower_definition.EIz)
        else:
            self.tower_definition = None
            self.tower_modes = None

        if 'blade' in s:
            self.blade_modes = load_modes_from_Bladed(s['blade']['definition'])
        else:
            self.blade_modes = None

        #### Create the elements ####

        # Free joint represents the rigid-body motion of the platform
        free_joint = FreeJoint('base')

        # This is the rigid-body mass of the platform structure
        conn_platform = RigidConnection('conn-platform',
                                        offset=s['platform']['CoM'])
        platform = RigidBody('platform',
                             mass=s['platform']['mass'],
                             inertia=np.diag(s['platform']['inertia']))
        free_joint.add_leaf(conn_platform)
        conn_platform.add_leaf(platform)

        # Make a rigid body to represent the added mass
        # (approximate to zero frequency)
        #  XXX this is skipping the coupling matrix
        #A = whales_model.A(0)
        # added_mass = RigidBody('added-mass', mass=np.diag(A[:3, :3]),
        #                           inertia=A[3:, 3:])

        # Flexible tower or equivalent rigid body
        if self.tower_modes:
            # move base of tower 10m up, and rotate so tower x-axis is vertical
            conn_tower = RigidConnection(
                'conn-tower', offset=[0, 0, z_tower[0]],
                rotation=rotmat_y(-pi/2))
            tower = DistalModalElementFromScratch(
                'tower', self.tower_modes,
                s['tower']['number of normal modes'])
        else:
            # move tower to COG
            conn_tower = RigidConnection(
                'conn-tower', offset=s['tower']['CoM'])
            tower = RigidBody('tower', s['tower']['mass'],
                              np.diag(s['tower']['inertia']))
        free_joint.add_leaf(conn_tower)
        conn_tower.add_leaf(tower)

        # The nacelle -- rigid body
        # rotate back so nacelle inertia is aligned with global coordinates
        if self.tower_modes:
            nacoff = s['nacelle']['offset from tower top']
            conn_nacelle = RigidConnection('conn-nacelle',
                                           offset=dot(rotmat_y(pi/2), nacoff),
                                           rotation=rotmat_y(pi/2))
            tower.add_leaf(conn_nacelle)
        else:
            conn_nacelle = RigidConnection(
                'conn-nacelle',
                offset=np.array([0, 0, s['nacelle']['height']]))
            free_joint.add_leaf(conn_nacelle)
        nacelle = RigidBody(
            'nacelle',
            mass=s['nacelle']['mass'],
            inertia=np.diag(s['nacelle'].get('inertia', np.zeros(3))))
        conn_nacelle.add_leaf(nacelle)

        # The rotor hub -- currently just connections (no mass)
        # rotate so rotor centre is aligned with global coordinates
        if self.tower_modes:
            rotoff = s['rotor']['offset from tower top']
            conn_rotor = RigidConnection('conn-rotor',
                                         offset=dot(rotmat_y(pi/2), rotoff),
                                         rotation=rotmat_y(pi/2))
            tower.add_leaf(conn_rotor)
        else:
            conn_rotor = RigidConnection(
                'conn-rotor',
                offset=np.array([0, 0, s['nacelle']['height']]))
            free_joint.add_leaf(conn_rotor)

        # The drive shaft rotation (rotation about x)
        shaft = Hinge('shaft', [1, 0, 0])
        conn_rotor.add_leaf(shaft)

        # The blades
        if self.blade_modes:
            rtlen = s['rotor']['root length']
            Ryx = dot(rotmat_y(-pi/2), rotmat_x(-pi/2))  # align blade modes
            for i in range(3):
                R = rotmat_x(i*2*pi/3)
                root = RigidConnection('root%d' % (i+1),
                                       offset=dot(R, [0, 0, rtlen]),
                                       rotation=dot(R, Ryx))
                blade = ModalElement('blade%d' % (i+1), self.blade_modes)
                shaft.add_leaf(root)
                root.add_leaf(blade)
        else:
            rotor = RigidBody('rotor', s['rotor']['mass'],
                              np.diag(s['rotor']['inertia']))
            shaft.add_leaf(rotor)

        # Build system
        self.system = System(free_joint)

        # Constrain missing DOFs -- tower torsion & extension not complete
        if self.tower_modes:
            self.system.prescribe(tower, vel=0, part=[0, 3])