Esempio n. 1
0
def test_skew():
    assert np.allclose(utils.skew(np.zeros(3)), np.zeros((3,3)))
    assert np.allclose(utils.skew([1,2,3]), np.array([
        [ 0, -3,  2],
        [ 3,  0, -1],
        [-2,  1,  0],
    ]))
Esempio n. 2
0
def test_skew():
    assert np.allclose(utils.skew(np.zeros(3)), np.zeros((3, 3)))
    assert np.allclose(utils.skew([1, 2, 3]),
                       np.array([
                           [0, -3, 2],
                           [3, 0, -1],
                           [-2, 1, 0],
                       ]))
Esempio n. 3
0
    def Morison_inertial_force(self, w):
        r"""Calculate the Morison inertial force
        """

        # XXX
        rho = 1025

        # Define the matrix which transforms the 6 rigid-body DOFs
        # into the acceleration at each element
        L = np.array([np.c_[np.eye(3), -skew(x)] for x in self.element_centres])

        # For inertial force: calculate normal fluid acceleration for unit wave
        a_fluid = 1j * w[:,newaxis,newaxis] * self.wave_velocity_transfer_function(w)

        # Only normal accelerations count -- subtract the longitudinal
        # component at each element:  at = (a . t) t
        t = self.element_axes[:,:,2]
        at = np.einsum('wei,ei,ej->wej', a_fluid, t, t)
        an = a_fluid - at

        # Added mass force for each element (Nel x 3 x 6)
        F_inertial = (self.Cm * rho *
                      (pi*self.element_diameters[newaxis,:,newaxis]**2/4) *
                      self.element_lengths[newaxis,:,newaxis] * an)

        # Sum up to get total resultant force and moment
        #  A = sum [ L.T * F_added ]
        F = np.einsum('eix,wei->wx', L, F_inertial)
        return F
Esempio n. 4
0
    def structural_velocity_transfer_function(self, w, H):
        """Return the transfer functions from wave elevation to structure
        velocity.
         - H: array of transfer functions (RAOs)

        Returns: array (frequency, element, xyz)
        """
        H_us = np.zeros((len(w), len(self.element_diameters), 3),
                        dtype=np.complex)
        for iel in range(H_us.shape[1]):
            xs = skew(self.element_centres[iel])
            for j in range(H_us.shape[0]):
                # H may have more than 6 DOFs if model is flexible
                H_us[j, iel, :] = (1j*w[j] * (H[j, 0:3] - dot(xs, H[j, 3:6])))
        return H_us
Esempio n. 5
0
    def Morison_added_mass(self):
        """Calculate added mass matrix from Morison elements"""

        # Define the matrix which transforms the 6 rigid-body DOFs
        # into the acceleration at each element
        L = np.array([np.c_[np.eye(3), -skew(x)] for x in self.element_centres])

        # Only normal accelerations count -- subtract the longitudinal
        # component at each element:  at = (a . t) t
        t = self.element_axes[:,:,2]
        a = L
        at = np.einsum('eix,ei,ej->ejx', a, t, t)
        an = a - at

        # Added mass force for each element (Nel x 3 x 6)
        F_added = ((self.Cm - 1) * 1025 *
                   (pi*self.element_diameters[:,newaxis,newaxis]**2/4) *
                   self.element_lengths[:,newaxis,newaxis] * an)

        # Sum up to get total resultant force and moment
        #  A = sum [ L.T * F_added ]
        A = np.einsum('eix,eiy->xy', L, F_added)
        return A
Esempio n. 6
0
    def total_drag(self, w, H_wave, S_wave, vc=None):
        r"""Calculate the linearised forces on each element then sum

        The total force and moment together are
        $$ \boldsymbol{F} = \sum \boldsymbol{L}_i \boldsymbol{F}^_i$$
        with
        $$\boldsymbol{L}_i = \begin{bmatrix}
        \boldsymbol{I} \\ \boldsymbol{\tilde{X}_i} \end{bmatrix}$$

        The drag force on each element is
        $$ \boldsymbol{F}_i = C \boldsymbol{A} (
        \boldsymbol{u}_f - \boldsymbol{u}_s ) + C \boldsymbol{b} $$
        where $C = \rho C_d D \mathrm{d}s / 2$ is a constant, and
        $\boldsymbol{A}$ is the transformed linearisation matrix.

        Using the fluid velocity transfer functions $\boldsymbol{H}_{uf \zeta}$,
        $\boldsymbol{u}_f(t) = \boldsymbol{H}_{uf \zeta}(\omega)
        \zeta_a e^{i\omega t}$, so this part goes on the RHS as a force
        $C \boldsymbol{A} \boldsymbol{H}_{u_f \zeta} \zeta_a
        e^{i\omega t} + C \boldsymbol{b}$.

        The structural response is given by
        $$ \boldsymbol{u}_s = i\omega
        \begin{bmatrix} \boldsymbol{I} & -\boldsymbol{\tilde{X}} \end{bmatrix}
        \boldsymbol{\Xi}(\omega) e^{i\omega t} $$
        so the rest of the drag force goes on the LHS as a damping matrix
        $$\boldsymbol{B}_v = C \boldsymbol{A} \boldsymbol{L}^{\mathrm{T}}$$

        This function returns Fvc = sum (C Li bi), the steady part of the force,
        and Fvv[freq] = sum (C Li Ai H_uf), which is the harmonic drag force for
        unit wave amplitude.

        NB this is very slow if w goes right to zero -- why?
        """

        # XXX
        rho = 1025

        H_uf = self.wave_velocity_transfer_function(w)
        A, b = self.linearised_drag_force(w, H_wave, S_wave, vc)

        Bv = np.zeros((6,6))                       # viscous drag damping
        Fvc = np.zeros(6)                          # constant drag force
        Fvv = np.zeros((len(w), 6), dtype=complex) # time-varying drag force
        for iel in range(len(self.element_diameters)):
            # Drag constant for each element
            C = (0.5 * rho * self.Cd *
                 self.element_diameters[iel] * self.element_lengths[iel])

            # Force acts at centre of each element
            x = self.element_centres[iel]
            L = np.r_[ np.eye(3), skew(x) ] # forces and moments about origin

            # Damping effect of viscous drag force
            Bv += C * dot(L, dot(A[iel], L.T))

            # Applied viscous drag force
            Fvc += C * dot(L, b[iel])
            for iw in range(len(w)):
                Fvv[iw] += C * dot(L, dot(A[iel], H_uf[iw, iel, :]))

        return Bv, Fvc, Fvv