def test_nodes_to_elements(self, n_elem):
     random_vector = np.random.rand(3).reshape(3, 1)
     input = np.repeat(random_vector, n_elem + 1, axis=1)
     input[..., 0] *= 0.5
     input[..., -1] *= 0.5
     correct_output = np.repeat(random_vector, n_elem, axis=1)
     output = nodes_to_elements(input)
     assert_allclose(correct_output, output, atol=Tolerance.atol())
     assert_allclose(np.sum(input), np.sum(output), atol=Tolerance.atol())
    def test_static_rolling_friction_total_torque_larger_than_static_friction_force(
            self, n_elem, torque_mag):
        """
        In this test case, static rolling friction force tested with zero internal and external force and
        with non-zero external torque. Here torque magnitude chosen such that total rolling force is
        always larger than the static friction force. Thus, lateral friction force will be equal to static
        friction force.
        Parameters
        ----------
        n_elem
        torque_mag

        Returns
        -------

        """

        [rod, frictionplane, external_forces_collection
         ] = self.initializer(n_elem,
                              static_mu_array=np.array([0.0, 0.0, 1.0]))

        external_torques = np.zeros((3, n_elem))
        external_torques[2] = torque_mag
        rod.external_torques = external_torques.copy()

        frictionplane.apply_forces(rod)

        correct_forces = np.zeros((3, n_elem + 1))
        correct_forces[0] = (-1.0 * np.sign(torque_mag) *
                             np.fabs(external_forces_collection[1]))
        assert_allclose(correct_forces,
                        rod.external_forces,
                        atol=Tolerance.atol())

        forces_on_elements = nodes_to_elements(external_forces_collection)
        correct_torques = external_torques
        correct_torques[2] += -(np.sign(torque_mag) *
                                np.fabs(forces_on_elements[1]) * rod.radius)

        assert_allclose(correct_torques,
                        rod.external_torques,
                        atol=Tolerance.atol())
    def test_kinetic_rolling_friction(self, n_elem, velocity, omega):
        """
        This test is for testing kinetic rolling friction,
        for different translational and angular velocities,
        we compute the final external forces and torques on the rod
        using apply friction function and compare results with
        analytical solutions.
        Parameters
        ----------
        n_elem
        velocity
        omega

        Returns
        -------

        """
        [rod, frictionplane, external_forces_collection
         ] = self.initializer(n_elem,
                              kinetic_mu_array=np.array([0.0, 0.0, 1.0]))

        rod.velocity_collection += np.array([velocity, 0.0, 0.0]).reshape(3, 1)
        rod.omega_collection += np.array([0.0, 0.0, omega]).reshape(3, 1)

        frictionplane.apply_forces(rod)

        correct_forces = np.zeros((3, n_elem + 1))
        correct_forces[0] = (-1.0 * np.sign(velocity + omega * rod.radius[0]) *
                             np.fabs(external_forces_collection[1]))

        assert_allclose(correct_forces,
                        rod.external_forces,
                        atol=Tolerance.atol())
        forces_on_elements = nodes_to_elements(external_forces_collection)
        correct_torques = np.zeros((3, n_elem))
        correct_torques[2] += (-1.0 *
                               np.sign(velocity + omega * rod.radius[0]) *
                               np.fabs(forces_on_elements[1]) * rod.radius)

        assert_allclose(correct_torques,
                        rod.external_torques,
                        atol=Tolerance.atol())
    def test_static_rolling_friction_total_force_larger_than_static_friction_force(
            self, n_elem, force_mag):
        """
        In this test case static rolling friction force is tested. We set external and internal torques to
        zero and only changed the force in rolling direction. In this test case, total force in rolling direction
        is larger than static friction force in rolling direction.
        Parameters
        ----------
        n_elem
        force_mag

        Returns
        -------

        """

        [rod, frictionplane, external_forces_collection
         ] = self.initializer(n_elem,
                              static_mu_array=np.array([0.0, 0.0, 1.0]),
                              force_mag_side=force_mag)

        frictionplane.apply_forces(rod)

        correct_forces = np.zeros((3, n_elem + 1))
        correct_forces[0] = external_forces_collection[0] - np.sign(
            external_forces_collection[0]) * np.fabs(
                external_forces_collection[1])
        assert_allclose(correct_forces,
                        rod.external_forces,
                        atol=Tolerance.atol())

        forces_on_elements = nodes_to_elements(external_forces_collection)
        correct_torques = np.zeros((3, n_elem))
        correct_torques[2] += (-1.0 * np.sign(forces_on_elements[0]) *
                               np.fabs(forces_on_elements[1]) * rod.radius)

        assert_allclose(correct_torques,
                        rod.external_torques,
                        atol=Tolerance.atol())