Example #1
0
    def analytical_solution(self, type, time):
        if type == "Positions":
            analytical_solution = (np.hstack((self.init_pos, self.final_pos)) +
                                   np.sin(np.pi * time) / np.pi**2)
        elif type == "Velocity":
            analytical_solution = (0.0 * np.hstack(
                (self.init_pos, self.final_pos)) +
                                   np.cos(np.pi * time) / np.pi)
        elif type == "Directors":
            from elastica._rotations import _rotate

            final_angle = self.omega_value * time + 0.5 * 0.1 * np.pi * time**2
            axis = np.array([0.0, 0.0,
                             1.0]).reshape(3, 1)  # There is only one director
            analytical_solution = _rotate(self.init_dir, final_angle, axis)
        return analytical_solution
def rotate(matrix, scale, axis):
    """
        This function takes single or multiple frames as matrix. Then rotates these frames
        around a single axis for all frames, or can rotate each frame around its own
        rotation axis as defined by user. Scale determines how much frames rotates
        around this axis.

        matrix: minimum shape = dim**2x1, supports shape = 3x3xn
        axis: minimum dim = 3x1, 1x3, supports dim = 3xn, nx3
        scale: minimum float, supports 1D vectors also dim = n

    """

    matrix = format_matrix_shape(matrix)
    axis = format_vector_shape(axis)

    return _rotate(matrix, scale, axis)
 def analytical_solution(self, type, time):
     if type == "Positions":
         analytical_solution = (np.hstack(
             (self.init_pos)) + np.sin(np.pi * time) / np.pi**2)
     elif type == "Velocity":
         analytical_solution = (0.0 * np.hstack(
             (self.init_pos)) + np.cos(np.pi * time) / np.pi)
     elif type == "Directors":
         final_angle = self.omega_value * time + 0.5 * 0.1 * np.pi * time**2
         axis = np.array([0.0, 0.0,
                          1.0]).reshape(3, 1)  # There is only one director
         # Reshaping done to prevent numba equivalent to complain
         # While we can prevent it here, its' done to make the front end testing scripts "look"
         # nicer and cleaner
         analytical_solution = _rotate(self.init_dir, final_angle,
                                       axis).reshape(-1, 1)
     return analytical_solution
Example #4
0
    def __add__(self, scaled_derivative_state):
        """overloaded + operator, useful in state.k1 = state + dt * deriv_state

        The add for directors is customized to reflect Rodrigues' rotation
        formula.

        Parameters
        ----------
        scaled_derivative_state : np.ndarray with dt * (v, ω, dv/dt, dω/dt)
        ,as returned from _DerivativeState's __mul__ method

        Returns
        -------
        state : new _State object with modified data (copied)

        Caveats
        -------
        Note that the argument is not a `other` _State object but is rather
        assumed to be a `np.ndarray` from calling _DerivativeState's __mul__
        method. This reflects the most common use-case in time-steppers

        """
        # x += v*dt
        position_collection = (
            self.position_collection + scaled_derivative_state[..., : self.n_nodes]
        )
        # Devs : see `_State.__iadd__` for reasons why we do matmul here
        director_collection = _rotate(
            self.director_collection,
            1.0,
            scaled_derivative_state[..., self.n_nodes : self.n_kinematic_rates],
        )
        # (v,ω) += (dv/dt, dω/dt)*dt
        kinematic_rate_collection = (
            self.kinematic_rate_collection
            + scaled_derivative_state[..., self.n_kinematic_rates :]
        )
        return _State(
            self.n_nodes - 1,
            position_collection,
            director_collection,
            kinematic_rate_collection,
        )
Example #5
0
def test_rotate_correctness():
    blocksize = 16

    def get_aligned_director_collection(theta_collection):
        sins = np.sin(theta_collection)
        coss = np.cos(theta_collection)
        # Get basic director out, then modify it as you like
        dir = np.tile(np.eye(3).reshape(3, 3, 1), blocksize)
        dir[0, 0, ...] = coss
        # Flip signs on [0,1] and [1,0] to go from our row-wise
        # representation to the more commonly used
        # columnwise representation, for similar reasons metioned
        # before
        dir[0, 1, ...] = sins
        dir[1, 0, ...] = -sins
        dir[1, 1, ...] = coss

        return dir

    base_angle = np.deg2rad(np.linspace(0.0, 90.0, blocksize))
    rotated_by = np.deg2rad(15.0) + 0.0 * base_angle
    rotated_about = np.array([0.0, 0.0, 1.0]).reshape(-1, 1)

    director_collection = get_aligned_director_collection(base_angle)
    axis_collection = np.tile(rotated_about, blocksize)
    axis_collection *= rotated_by
    dt = 1.0

    test_rotated_director_collection = _rotate(director_collection, dt,
                                               axis_collection)
    correct_rotation = rotated_by + 1.0 * base_angle
    correct_rotated_director_collection = get_aligned_director_collection(
        correct_rotation)

    assert test_rotated_director_collection.shape == (3, 3, blocksize)
    assert_allclose(
        test_rotated_director_collection,
        correct_rotated_director_collection,
        atol=Tolerance.atol(),
    )