Example #1
0
    def getStiffnessA(self, lines_only=False):
        '''Gets the analytical stiffness matrix of the Body with other objects fixed.

        Returns
        -------
        K : matrix
            6x6 analytic stiffness matrix.

        '''

        #print("Getting Body "+str(self.number)+" stiffness matrix...")

        K = np.zeros([6, 6])

        for PointID, rPointRel in zip(self.attachedP, self.rPointRel):

            r = rotatePosition(
                rPointRel, self.r6[3:]
            )  # relative position of Point about body ref point in unrotated reference frame
            f3 = self.sys.pointList[PointID - 1].getForces(
            )  # total force on point (for additional rotational stiffness term due to change in moment arm)
            K3 = self.sys.pointList[
                PointID -
                1].getStiffnessA()  # local 3D stiffness matrix of the point

            # following are from functions translateMatrix3to6
            H = getH(r)
            K[:3, :3] += K3
            K[:3, 3:] += np.matmul(
                K3, H
            )  # only add up one off-diagonal sub-matrix for now, then we'll mirror at the end
            K[3:, 3:] += np.matmul(np.matmul(H, K3), H.T) + np.matmul(
                getH(f3), H.T)
            #K[3:,3:] += np.matmul(np.matmul(H, K3), H.T) - np.matmul( getH(f3), H)  # <<< should be the same

        K[3:, :3] = K[:3, 3:].T  # copy over other off-diagonal sub-matrix

        if lines_only == False:

            # rotational stiffness effect of weight
            rCG_rotated = rotatePosition(
                self.rCG, self.r6[3:]
            )  # relative position of CG about body ref point in unrotated reference frame
            Kw = -np.matmul(getH([0, 0, -self.m * self.sys.g]),
                            getH(rCG_rotated))

            # rotational stiffness effect of buoyancy at metacenter
            rM_rotated = rotatePosition(
                self.rM, self.r6[3:]
            )  # relative position of metacenter about body ref point in unrotated reference frame
            Kb = -np.matmul(getH([0, 0, self.sys.rho * self.sys.g * self.v]),
                            getH(rM_rotated))

            # hydrostatic heave stiffness (if AWP is nonzero)
            Kwp = self.sys.rho * self.sys.g * self.AWP

            K[3:, 3:] += Kw + Kb
            K[2, 2] += Kwp

        return K
Example #2
0
    def getForces(self, lines_only=False):
        '''Sums the forces and moments on the Body, including its own plus those from any attached objects.

        Parameters
        ----------
        lines_only : boolean, optional
            An option for calculating forces from just the mooring lines or not. The default is False.

        Returns
        -------
        f6 : array
            The 6DOF forces and moments applied to the body in its current position [N, Nm]

        '''

        f6 = np.zeros(6)

        # TODO: could save time in below by storing the body's rotation matrix when it's position is set rather than
        #       recalculating it in each of the following function calls.

        if lines_only == False:

            # add weight, which may result in moments as well as a force
            rCG_rotated = rotatePosition(
                self.rCG, self.r6[3:]
            )  # relative position of CG about body ref point in unrotated reference frame
            f6 += translateForce3to6DOF(rCG_rotated,
                                        np.array([
                                            0, 0, -self.m * self.sys.g
                                        ]))  # add to net forces/moments

            # add buoyancy force and moments if applicable (this can include hydrostatic restoring moments
            # if rM is considered the metacenter location rather than the center of buoyancy)
            rM_rotated = rotatePosition(
                self.rM, self.r6[3:]
            )  # relative position of metacenter about body ref point in unrotated reference frame
            f6 += translateForce3to6DOF(rM_rotated,
                                        np.array([
                                            0, 0,
                                            self.sys.rho * self.sys.g * self.v
                                        ]))  # add to net forces/moments

            # add hydrostatic heave stiffness (if AWP is nonzero)
            f6[2] -= self.sys.rho * self.sys.g * self.AWP * self.r6[2]

            # add any externally applied forces/moments (in global orientation)
            f6 += self.f6Ext

        # add forces from any attached Points (and their attached lines)
        for PointID, rPointRel in zip(self.attachedP, self.rPointRel):

            fPoint = self.sys.pointList[PointID - 1].getForces(
                lines_only=lines_only)  # get net force on attached Point
            rPoint_rotated = rotatePosition(
                rPointRel, self.r6[3:]
            )  # relative position of Point about body ref point in unrotated reference frame
            f6 += translateForce3to6DOF(
                rPoint_rotated, fPoint
            )  # add net force and moment resulting from its position to the Body

        # All forces and moments on the body should now be summed, and are in global/unrotated orientations.

        # For application to the body DOFs, convert the moments to be about the body's local/rotated x/y/z axes <<< do we want this in all cases?
        rotMat = rotationMatrix(*self.r6[3:])  # get rotation matrix for body
        moment_about_body_ref = np.matmul(
            rotMat.T, f6[3:]
        )  # transform moments so that they are about the body's local/rotated axes
        f6[3:] = moment_about_body_ref  # use these moments

        return f6