Exemple #1
0
    def test_symplectics_against_ellipse_motion_with_numpy_PEFRL(
            self, monkeypatch):
        monkeypatch.setenv("IMPORT_TEST_NUMPY", "True", prepend=False)
        # After changing the import flag reload the modules.
        importlib.reload(elastica)
        importlib.reload(elastica.timestepper.symplectic_steppers)
        # importlib.reload(elastica.timestepper.integrate)
        importlib.reload(elastica.timestepper)
        from elastica.timestepper.symplectic_steppers import PEFRL
        from elastica.timestepper import integrate

        random_start_position = np.random.randn(3, 1)
        random_directors, _ = np.linalg.qr(np.random.randn(3, 3))
        random_directors = random_directors.reshape(3, 3, 1)

        rod_like_system = make_simple_system_with_positions_directors(
            random_start_position, random_directors)
        final_time = 1.0
        n_steps = 1000
        stepper = PEFRL()

        integrate(stepper,
                  rod_like_system,
                  final_time=final_time,
                  n_steps=n_steps)

        assert_allclose(
            rod_like_system.position_collection.reshape(3),
            rod_like_system.analytical_solution("Positions", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        assert_allclose(
            rod_like_system.velocity_collection.reshape(3),
            rod_like_system.analytical_solution("Velocity", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        # Reshaping done in the director collection to prevent numba from
        # complaining about returning multiple types
        assert_allclose(
            rod_like_system.director_collection.reshape(-1, 1),
            rod_like_system.analytical_solution("Directors", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        # Remove the import flag
        monkeypatch.delenv("IMPORT_TEST_NUMPY")
        # Reload the elastica after changing flag
        importlib.reload(elastica)
        importlib.reload(elastica.timestepper.symplectic_steppers)
        importlib.reload(elastica.timestepper)
        from elastica.timestepper.symplectic_steppers import PEFRL
        from elastica.timestepper import integrate
Exemple #2
0
    def test_symplectic_against_undamped_harmonic_oscillator(self, stepper):
        system = SymplecticUndampedSimpleHarmonicOscillatorSystem()
        final_time = 4.0 * np.pi
        n_steps = 2000
        integrate(stepper(), system, final_time=final_time, n_steps=n_steps)

        # Symplectic systems conserve energy to a certain extent
        assert_allclose(
            *system.compute_energy(final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )
Exemple #3
0
    def test_against_damped_harmonic_oscillator(self, stepper):
        system = DampedSimpleHarmonicOscillatorSystem()
        final_time = 4.0 * np.pi
        n_steps = 2000
        integrate(stepper(), system, final_time=final_time, n_steps=n_steps)

        assert_allclose(
            system.state,
            system.analytical_solution(final_time),
            rtol=Tolerance.rtol(),
            atol=Tolerance.atol(),
        )
Exemple #4
0
    def test_against_scalar_exponential(self, stepper):
        system = ScalarExponentialDecaySystem(-1, 1)
        final_time = 1
        n_steps = 1000
        integrate(stepper(), system, final_time=final_time, n_steps=n_steps)

        assert_allclose(
            system.state,
            system.analytical_solution(final_time),
            rtol=Tolerance.rtol() * 1e3,
            atol=Tolerance.atol(),
        )
Exemple #5
0
    def test_explicit_against_analytical_system(self, explicit_stepper):
        system = SecondOrderHybridSystem()
        final_time = 1.0
        n_steps = 2000
        integrate(explicit_stepper(),
                  system,
                  final_time=final_time,
                  n_steps=n_steps)

        assert_allclose(
            system.final_solution(final_time),
            system.analytical_solution(final_time),
            rtol=Tolerance.rtol() * 1e2,
            atol=Tolerance.atol(),
        )
Exemple #6
0
    def test_hybrid_symplectic_against_analytical_system(
            self, symplectic_stepper):
        system = SecondOrderHybridSystem()
        final_time = 1.0
        n_steps = 2000
        stepper = SymplecticCosseratRodStepper(
            symplectic_stepper=symplectic_stepper())
        integrate(stepper, system, final_time=final_time, n_steps=n_steps)

        assert_allclose(
            system.final_solution(final_time),
            system.analytical_solution(final_time),
            rtol=Tolerance.rtol() * 1e2,
            atol=Tolerance.atol(),
        )
Exemple #7
0
    def test_linear_exponential_integrator(self):
        system = MultipleFrameRotationSystem(n_frames=128)
        final_time = np.pi
        n_steps = 1000
        integrate(
            StatefulLinearExponentialIntegrator(),
            system,
            final_time=final_time,
            n_steps=n_steps,
        )

        assert_allclose(
            system.linearly_evolving_state,
            system.analytical_solution(final_time),
            atol=1e-4,
        )
    def test_symplectic_steppers(self, symplectic_stepper):
        collective_system = SymplecticUndampedHarmonicOscillatorCollectiveSystem(
        )
        final_time = 1.0
        n_steps = 2000
        stepper = symplectic_stepper()
        integrate(stepper,
                  collective_system,
                  final_time=final_time,
                  n_steps=n_steps)

        for system in collective_system:
            assert_allclose(
                *system.compute_energy(final_time),
                rtol=Tolerance.rtol() * 1e1,
                atol=Tolerance.atol(),
            )
    def test_symplectics_against_ellipse_motion(self, symplectic_stepper):
        from elastica.systems.analytical import (
            make_simple_system_with_positions_directors,
            SimpleSystemWithPositionsDirectors,
        )

        random_start_position = np.random.randn(3, 1)
        random_end_position = np.random.randn(3, 1)
        random_directors, _ = np.linalg.qr(np.random.randn(3, 3))
        random_directors = random_directors.reshape(3, 3, 1)

        rod_like_system = make_simple_system_with_positions_directors(
            random_start_position, random_end_position, random_directors)
        final_time = 1.0
        n_steps = 1000
        stepper = symplectic_stepper()

        integrate(stepper,
                  rod_like_system,
                  final_time=final_time,
                  n_steps=n_steps)

        assert_allclose(
            rod_like_system.position_collection,
            rod_like_system.analytical_solution("Positions", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        assert_allclose(
            rod_like_system.velocity_collection,
            rod_like_system.analytical_solution("Velocity", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        # Reshaping done in the director collection to prevent numba from
        # complaining about returning multiple types
        assert_allclose(
            rod_like_system.director_collection.reshape(-1, 1),
            rod_like_system.analytical_solution("Directors", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )
Exemple #10
0
    def test_explicit_against_ellipse_motion(self, explicit_stepper):
        from elastica.systems.analytical import SimpleSystemWithPositionsDirectors

        rod_like_system = SimpleSystemWithPositionsDirectors(
            np.array([0.0, 0.0, 0.0]), np.random.randn(3, 3, 1))
        final_time = 1.0
        n_steps = 500
        stepper = explicit_stepper()

        integrate(stepper,
                  rod_like_system,
                  final_time=final_time,
                  n_steps=n_steps)

        assert_allclose(
            rod_like_system.position_collection,
            rod_like_system.analytical_solution("Positions", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )
Exemple #11
0
    def test_symplectics_against_ellipse_motion(self, symplectic_stepper):
        from elastica.systems.analytical import SimpleSystemWithPositionsDirectors

        random_start_position = np.random.randn(3, 1)
        random_end_position = np.random.randn(3, 1)
        random_directors, _ = np.linalg.qr(np.random.randn(3, 3))
        random_directors = random_directors.reshape(3, 3, 1)

        rod_like_system = SimpleSystemWithPositionsDirectors(
            random_start_position, random_end_position, random_directors)
        final_time = 1.0
        n_steps = 1000
        stepper = symplectic_stepper()

        integrate(stepper,
                  rod_like_system,
                  final_time=final_time,
                  n_steps=n_steps)

        assert_allclose(
            rod_like_system.position_collection,
            rod_like_system.analytical_solution("Positions", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        assert_allclose(
            rod_like_system.velocity_collection,
            rod_like_system.analytical_solution("Velocity", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        assert_allclose(
            rod_like_system.director_collection,
            rod_like_system.analytical_solution("Directors", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )
def test_integrate_throws_an_assert_for_negative_total_steps():
    with pytest.raises(AssertionError) as excinfo:
        integrate([], [], np.random.rand(1), -np.random.randint(100, 10000))
    assert "steps is negative" in str(excinfo.value)
def test_integrate_throws_an_assert_for_negative_final_time():
    with pytest.raises(AssertionError) as excinfo:
        integrate([], [], -np.random.rand(1))
    assert "time is negative" in str(excinfo.value)
                                                step_skip=1000,
                                                callback_params=pp_list_rod1)
hinge_joint_sim.collect_diagnostics(rod2).using(TestJoints,
                                                step_skip=1000,
                                                callback_params=pp_list_rod2)

hinge_joint_sim.finalize()
timestepper = PositionVerlet()
# timestepper = PEFRL()

final_time = 10
dl = base_length / n_elem
dt = 1e-5
total_steps = int(final_time / dt)
print("Total steps", total_steps)
integrate(timestepper, hinge_joint_sim, final_time, total_steps)

PLOT_FIGURE = True
SAVE_FIGURE = False
PLOT_VIDEO = False

# plotting results
if PLOT_FIGURE:
    filename = "hinge_joint_test.png"
    plot_position(pp_list_rod1, pp_list_rod2, filename, SAVE_FIGURE)

if PLOT_VIDEO:
    filename = "hinge_joint_test.mp4"
    plot_video(pp_list_rod1,
               pp_list_rod2,
               video_name=filename,
)
fixed_joint_sim.collect_diagnostics(rod2).using(
    TestJoints, step_skip=1000, callback_params=pp_list_rod2
)


fixed_joint_sim.finalize()
timestepper = PositionVerlet()
# timestepper = PEFRL()

final_time = 10
dl = base_length / n_elem
dt = 1e-5
total_steps = int(final_time / dt)
print("Total steps", total_steps)
integrate(timestepper, fixed_joint_sim, final_time, total_steps)

PLOT_FIGURE = True
SAVE_FIGURE = False
PLOT_VIDEO = False

# plotting results
if PLOT_FIGURE:
    filename = "fixed_joint_test.png"
    plot_position(pp_list_rod1, pp_list_rod2, filename, SAVE_FIGURE)

if PLOT_VIDEO:
    filename = "fixed_joint_test.mp4"
    plot_video(pp_list_rod1, pp_list_rod2, video_name=filename, margin=0.2, fps=100)
    plot_video_xy(
        pp_list_rod1, pp_list_rod2, video_name=filename + "_xy.mp4", margin=0.2, fps=100
Exemple #16
0
    )

    timoshenko_sim.append(unshearable_rod)
    timoshenko_sim.constrain(unshearable_rod).using(
        OneEndFixedRod, constrained_position_idx=(0,), constrained_director_idx=(0,)
    )
    timoshenko_sim.add_forcing_to(unshearable_rod).using(
        EndpointForces, 0.0 * end_force, end_force, ramp_up_time=final_time / 2.0
    )

timoshenko_sim.finalize()
timestepper = PositionVerlet()
# timestepper = PEFRL()

dl = base_length / n_elem
dt = 0.01 * dl
total_steps = int(final_time / dt)
print("Total steps", total_steps)
integrate(timestepper, timoshenko_sim, final_time, total_steps)

if PLOT_FIGURE:
    plot_timoshenko(shearable_rod, end_force, SAVE_FIGURE, ADD_UNSHEARABLE_ROD)

if SAVE_RESULTS:
    import pickle

    filename = "Timoshenko_beam_data.dat"
    file = open(filename, "wb")
    pickle.dump(shearable_rod, file)
    file.close()
    constrained_position_idx=(0, -1),
    constrained_director_idx=(0, -1),
    twisting_time=500,
    slack=slack,
    number_of_rotations=number_of_rotations,
)

helicalbuckling_sim.finalize()
timestepper = PositionVerlet()
shearable_rod.velocity_collection[..., int(
    (n_elem) / 2)] += np.array([0, 1e-6, 0.0])
# timestepper = PEFRL()

final_time = 10500.0
dl = base_length / n_elem
dt = 1e-3 * dl
total_steps = int(final_time / dt)
print("Total steps", total_steps)
integrate(timestepper, helicalbuckling_sim, final_time, total_steps)

if PLOT_FIGURE:
    plot_helicalbuckling(shearable_rod, SAVE_FIGURE)

if SAVE_RESULTS:
    import pickle

    filename = "HelicalBuckling_data.dat"
    file = open(filename, "wb")
    pickle.dump(shearable_rod, file)
    file.close()
Exemple #18
0
def simulate_rolling_friction_initial_velocity_with(IFactor=0.0):

    rolling_friction_initial_velocity_sim = RollingFrictionInitialVelocitySimulator(
    )

    # setting up test params
    n_elem = 50
    start = np.zeros((3, ))
    direction = np.array([0.0, 0.0, 1.0])
    normal = np.array([0.0, 1.0, 0.0])
    base_length = 1.0
    base_radius = 0.025
    base_area = np.pi * base_radius**2
    mass = 1.0
    density = mass / (base_length * base_area)
    nu = 1e-6
    E = 1e9
    # For shear modulus of 2E/3
    poisson_ratio = 0.5

    # Set shear matrix
    shear_matrix = np.repeat(1e4 * np.identity((3))[:, :, np.newaxis],
                             n_elem,
                             axis=2)

    shearable_rod = CosseratRod.straight_rod(
        n_elem,
        start,
        direction,
        normal,
        base_length,
        base_radius,
        density,
        nu,
        E,
        poisson_ratio,
    )

    # TODO: CosseratRod has to be able to take shear matrix as input, we should change it as done below
    shearable_rod.shear_matrix = shear_matrix
    # change the mass moment of inertia matrix and its inverse
    shearable_rod.mass_second_moment_of_inertia *= IFactor
    shearable_rod.inv_mass_second_moment_of_inertia /= IFactor

    # set initial velocity of 1m/s to rod elements in the slip direction
    Vs = 1.0
    shearable_rod.velocity_collection[0, :] += Vs

    rolling_friction_initial_velocity_sim.append(shearable_rod)
    rolling_friction_initial_velocity_sim.constrain(shearable_rod).using(
        FreeRod)

    # Add gravitational forces
    gravitational_acc = -9.80665
    rolling_friction_initial_velocity_sim.add_forcing_to(shearable_rod).using(
        GravityForces, acc_gravity=np.array([0.0, gravitational_acc, 0.0]))

    # Add friction forces
    origin_plane = np.array([0.0, -base_radius, 0.0])
    normal_plane = np.array([0.0, 1.0, 0.0])
    slip_velocity_tol = 1e-6
    static_mu_array = np.array([0.4, 0.4,
                                0.4])  # [forward, backward, sideways]
    kinetic_mu_array = np.array([0.2, 0.2,
                                 0.2])  # [forward, backward, sideways]

    rolling_friction_initial_velocity_sim.add_forcing_to(shearable_rod).using(
        AnisotropicFrictionalPlane,
        k=10.0,
        nu=1e-4,
        plane_origin=origin_plane,
        plane_normal=normal_plane,
        slip_velocity_tol=slip_velocity_tol,
        static_mu_array=static_mu_array,
        kinetic_mu_array=kinetic_mu_array,
    )

    rolling_friction_initial_velocity_sim.finalize()
    timestepper = PositionVerlet()

    final_time = 2.0
    dt = 1e-6
    total_steps = int(final_time / dt)
    print("Total steps", total_steps)
    integrate(timestepper, rolling_friction_initial_velocity_sim, final_time,
              total_steps)

    # compute translational and rotational energy
    translational_energy = shearable_rod.compute_translational_energy()
    rotational_energy = shearable_rod.compute_rotational_energy()

    # compute translational and rotational energy using analytical equations
    analytical_translational_energy = 0.5 * mass * Vs**2 / (1.0 +
                                                            IFactor / 2)**2
    analytical_rotational_energy = (0.5 * mass * Vs**2 * (IFactor / 2.0) /
                                    (1.0 + IFactor / 2)**2)

    return {
        "rod": shearable_rod,
        "sweep": IFactor / 2.0,
        "translational_energy": translational_energy,
        "rotational_energy": rotational_energy,
        "analytical_translational_energy": analytical_translational_energy,
        "analytical_rotational_energy": analytical_rotational_energy,
    }
Exemple #19
0
def simulate_axial_friction_with(force=0.0):

    axial_friction_sim = AxialFrictionSimulator()

    # setting up test params
    n_elem = 50
    start = np.zeros((3, ))
    direction = np.array([0.0, 0.0, 1.0])
    normal = np.array([0.0, 1.0, 0.0])
    base_length = 1.0
    base_radius = 0.025
    base_area = np.pi * base_radius**2
    mass = 1.0
    density = mass / (base_length * base_area)
    nu = 1e-6
    E = 1e5
    # For shear modulus of 2E/3
    poisson_ratio = 0.5

    # Set shear matrix
    shear_matrix = np.repeat(1e4 * np.identity((3))[:, :, np.newaxis],
                             n_elem,
                             axis=2)

    shearable_rod = CosseratRod.straight_rod(
        n_elem,
        start,
        direction,
        normal,
        base_length,
        base_radius,
        density,
        nu,
        E,
        poisson_ratio,
    )

    # TODO: CosseratRod has to be able to take shear matrix as input, we should change it as done below
    shearable_rod.shear_matrix = shear_matrix

    axial_friction_sim.append(shearable_rod)
    axial_friction_sim.constrain(shearable_rod).using(FreeRod)

    # Add gravitational forces
    gravitational_acc = -9.80665
    axial_friction_sim.add_forcing_to(shearable_rod).using(
        GravityForces, acc_gravity=np.array([0.0, gravitational_acc, 0.0]))

    # Add Uniform force on the rod
    axial_friction_sim.add_forcing_to(shearable_rod).using(UniformForces,
                                                           force=1.0 * force,
                                                           direction=direction)

    # Add friction forces
    origin_plane = np.array([0.0, -base_radius, 0.0])
    normal_plane = np.array([0.0, 1.0, 0.0])
    slip_velocity_tol = 1e-4
    static_mu_array = np.array([0.8, 0.4,
                                0.4])  # [forward, backward, sideways]
    kinetic_mu_array = np.array([0.4, 0.2,
                                 0.2])  # [forward, backward, sideways]

    axial_friction_sim.add_forcing_to(shearable_rod).using(
        AnisotropicFrictionalPlane,
        k=10.0,
        nu=1e-4,
        plane_origin=origin_plane,
        plane_normal=normal_plane,
        slip_velocity_tol=slip_velocity_tol,
        static_mu_array=static_mu_array,
        kinetic_mu_array=kinetic_mu_array,
    )

    axial_friction_sim.finalize()
    timestepper = PositionVerlet()

    final_time = 0.25
    dt = 1e-5
    total_steps = int(final_time / dt)
    print("Total steps", total_steps)
    integrate(timestepper, axial_friction_sim, final_time, total_steps)

    # compute translational and rotational energy
    translational_energy = shearable_rod.compute_translational_energy()
    rotational_energy = shearable_rod.compute_rotational_energy()

    # compute translational and rotational energy using analytical equations

    if force >= 0.0:  # forward friction force
        if np.abs(force) <= np.abs(
                static_mu_array[0] * mass * gravitational_acc):
            analytical_translational_energy = 0.0
        else:
            analytical_translational_energy = (
                final_time**2 / (2.0 * mass) *
                (np.abs(force) -
                 kinetic_mu_array[0] * mass * np.abs(gravitational_acc))**2)

    else:  # backward friction force
        if np.abs(force) <= np.abs(
                static_mu_array[1] * mass * gravitational_acc):
            analytical_translational_energy = 0.0
        else:
            analytical_translational_energy = (
                final_time**2 / (2.0 * mass) *
                (np.abs(force) -
                 kinetic_mu_array[1] * mass * np.abs(gravitational_acc))**2)

    analytical_rotational_energy = 0.0

    return {
        "rod": shearable_rod,
        "sweep": force,
        "translational_energy": translational_energy,
        "rotational_energy": rotational_energy,
        "analytical_translational_energy": analytical_translational_energy,
        "analytical_rotational_energy": analytical_rotational_energy,
    }
Exemple #20
0
def run_snake(b_coeff, SAVE_RESULTS=False):

    snake_sim = SnakeSimulator()

    # setting up test params
    n_elem = 20
    start = np.zeros((3, ))
    direction = np.array([0.0, 0.0, 1.0])
    normal = np.array([0.0, 1.0, 0.0])
    base_length = 1.0
    base_radius = 0.025
    base_area = np.pi * base_radius**2
    density = 1000
    nu = 5.0
    E = 1e7
    poisson_ratio = 0.5

    shearable_rod = CosseratRod.straight_rod(
        n_elem,
        start,
        direction,
        normal,
        base_length,
        base_radius,
        density,
        nu,
        E,
        poisson_ratio,
    )

    snake_sim.append(shearable_rod)

    # Add gravitational forces
    gravitational_acc = -9.80665
    snake_sim.add_forcing_to(shearable_rod).using(
        GravityForces, acc_gravity=np.array([0.0, gravitational_acc, 0.0]))

    period = 1.0
    wave_length = b_coeff[-1]
    snake_sim.add_forcing_to(shearable_rod).using(
        MuscleTorques,
        base_length=base_length,
        b_coeff=b_coeff[:-1],
        period=period,
        wave_number=2.0 * np.pi / (wave_length),
        phase_shift=0.0,
        direction=normal,
        rest_lengths=shearable_rod.rest_lengths,
        ramp_up_time=period,
        with_spline=True,
    )

    # Add friction forces
    origin_plane = np.array([0.0, -base_radius, 0.0])
    normal_plane = normal
    slip_velocity_tol = 1e-8
    froude = 0.1
    mu = base_length / (period * period * np.abs(gravitational_acc) * froude)
    kinetic_mu_array = np.array([mu, 1.5 * mu,
                                 2.0 * mu])  # [forward, backward, sideways]
    static_mu_array = 2 * kinetic_mu_array
    snake_sim.add_forcing_to(shearable_rod).using(
        AnisotropicFrictionalPlane,
        k=1.0,
        nu=1e-6,
        plane_origin=origin_plane,
        plane_normal=normal_plane,
        slip_velocity_tol=slip_velocity_tol,
        static_mu_array=static_mu_array,
        kinetic_mu_array=kinetic_mu_array,
    )

    # Add call backs
    class ContinuumSnakeCallBack(CallBackBaseClass):
        """
        Call back function for continuum snake
        """
        def __init__(self, step_skip: int, callback_params: dict):
            CallBackBaseClass.__init__(self)
            self.every = step_skip
            self.callback_params = callback_params

        def make_callback(self, system, time, current_step: int):

            if current_step % self.every == 0:

                self.callback_params["time"].append(time)
                self.callback_params["position"].append(
                    system.position_collection.copy())

                return

    pp_list = defaultdict(list)
    snake_sim.collect_diagnostics(shearable_rod).using(ContinuumSnakeCallBack,
                                                       step_skip=200,
                                                       callback_params=pp_list)

    snake_sim.finalize()
    timestepper = PositionVerlet()
    # timestepper = PEFRL()

    final_time = (11.0 + 0.01) * period
    dt = 5.0e-5 * period
    total_steps = int(final_time / dt)
    print("Total steps", total_steps)
    integrate(timestepper, snake_sim, final_time, total_steps)

    if SAVE_RESULTS:
        import pickle

        filename = "continuum_snake.dat"
        file = open(filename, "wb")
        pickle.dump(pp_list, file)
        file.close()

    return pp_list
def simulate_timoshenko_beam_with(elements=10,
                                  PLOT_FIGURE=False,
                                  ADD_UNSHEARABLE_ROD=False):
    timoshenko_sim = TimoshenkoBeamSimulator()
    final_time = 5000
    # setting up test params
    n_elem = elements
    start = np.zeros((3, ))
    direction = np.array([0.0, 0.0, 1.0])
    normal = np.array([0.0, 1.0, 0.0])
    base_length = 3.0
    base_radius = 0.25
    base_area = np.pi * base_radius**2
    density = 5000
    nu = 0.1
    E = 1e6
    # For shear modulus of 1e4, nu is 99!
    poisson_ratio = 99

    shearable_rod = CosseratRod.straight_rod(
        n_elem,
        start,
        direction,
        normal,
        base_length,
        base_radius,
        density,
        nu,
        E,
        poisson_ratio,
    )

    timoshenko_sim.append(shearable_rod)
    timoshenko_sim.constrain(shearable_rod).using(
        OneEndFixedRod,
        constrained_position_idx=(0, ),
        constrained_director_idx=(0, ))
    end_force = np.array([-15.0, 0.0, 0.0])
    timoshenko_sim.add_forcing_to(shearable_rod).using(
        EndpointForces,
        0.0 * end_force,
        end_force,
        ramp_up_time=final_time / 2)

    if ADD_UNSHEARABLE_ROD:
        # Start into the plane
        unshearable_start = np.array([0.0, -1.0, 0.0])
        unshearable_rod = CosseratRod.straight_rod(
            n_elem,
            unshearable_start,
            direction,
            normal,
            base_length,
            base_radius,
            density,
            nu,
            E,
            # Unshearable rod needs G -> inf, which is achievable with -ve poisson ratio
            poisson_ratio=-0.7,
        )

        timoshenko_sim.append(unshearable_rod)
        timoshenko_sim.constrain(unshearable_rod).using(
            OneEndFixedRod,
            constrained_position_idx=(0, ),
            constrained_director_idx=(0, ))
        timoshenko_sim.add_forcing_to(unshearable_rod).using(
            EndpointForces,
            0.0 * end_force,
            end_force,
            ramp_up_time=final_time / 2)

    timoshenko_sim.finalize()
    timestepper = PositionVerlet()
    # timestepper = PEFRL()

    dl = base_length / n_elem
    dt = 0.01 * dl
    total_steps = int(final_time / dt)
    print("Total steps", total_steps)
    integrate(timestepper, timoshenko_sim, final_time, total_steps)

    if PLOT_FIGURE:
        plot_timoshenko(shearable_rod, end_force, SAVE_FIGURE,
                        ADD_UNSHEARABLE_ROD)

    # calculate errors and norms
    # Since we need to evaluate analytical solution only on nodes, n_nodes = n_elems+1
    error, l1, l2, linf = calculate_error_norm(
        analytical_shearable(shearable_rod, end_force, n_elem + 1)[1],
        shearable_rod.position_collection[0, ...],
        n_elem,
    )
    return {
        "rod": shearable_rod,
        "error": error,
        "l1": l1,
        "l2": l2,
        "linf": linf
    }
Exemple #22
0
def simulate_rolling_friction_torque_with(C_s=0.0):

    rolling_friction_torque_sim = RollingFrictionTorqueSimulator()

    # setting up test params
    n_elem = 50
    start = np.zeros((3, ))
    direction = np.array([0.0, 0.0, 1.0])
    normal = np.array([0.0, 1.0, 0.0])
    base_length = 1.0
    base_radius = 0.025
    base_area = np.pi * base_radius**2
    mass = 1.0
    density = mass / (base_length * base_area)
    nu = 1e-6
    E = 1e9
    # For shear modulus of 2E/3
    poisson_ratio = 0.5

    # Set shear matrix
    shear_matrix = np.repeat(1e4 * np.identity((3))[:, :, np.newaxis],
                             n_elem,
                             axis=2)

    shearable_rod = CosseratRod.straight_rod(
        n_elem,
        start,
        direction,
        normal,
        base_length,
        base_radius,
        density,
        nu,
        E,
        poisson_ratio,
    )

    # TODO: CosseratRod has to be able to take shear matrix as input, we should change it as done below
    shearable_rod.shear_matrix = shear_matrix

    rolling_friction_torque_sim.append(shearable_rod)
    rolling_friction_torque_sim.constrain(shearable_rod).using(FreeRod)

    # Add gravitational forces
    gravitational_acc = -9.80665
    rolling_friction_torque_sim.add_forcing_to(shearable_rod).using(
        GravityForces, acc_gravity=np.array([0.0, gravitational_acc, 0.0]))

    # Add Uniform torque on the rod
    rolling_friction_torque_sim.add_forcing_to(shearable_rod).using(
        UniformTorques, torque=1.0 * C_s, direction=direction)

    # Add friction forces
    origin_plane = np.array([0.0, -base_radius, 0.0])
    normal_plane = np.array([0.0, 1.0, 0.0])
    slip_velocity_tol = 1e-4
    static_mu_array = np.array([0.4, 0.4,
                                0.4])  # [forward, backward, sideways]
    kinetic_mu_array = np.array([0.2, 0.2,
                                 0.2])  # [forward, backward, sideways]

    rolling_friction_torque_sim.add_forcing_to(shearable_rod).using(
        AnisotropicFrictionalPlane,
        k=10.0,
        nu=1e-4,
        plane_origin=origin_plane,
        plane_normal=normal_plane,
        slip_velocity_tol=slip_velocity_tol,
        static_mu_array=static_mu_array,
        kinetic_mu_array=kinetic_mu_array,
    )

    rolling_friction_torque_sim.finalize()
    timestepper = PositionVerlet()

    final_time = 1.0
    dt = 1e-6
    total_steps = int(final_time / dt)
    print("Total steps", total_steps)
    integrate(timestepper, rolling_friction_torque_sim, final_time,
              total_steps)

    # compute translational and rotational energy
    translational_energy = shearable_rod.compute_translational_energy()
    rotational_energy = shearable_rod.compute_rotational_energy()

    # compute translational and rotational energy using analytical equations
    force_slip = static_mu_array[2] * mass * gravitational_acc
    force_noslip = 2.0 * C_s / (3.0 * base_radius)

    mass_moment_of_inertia = 0.5 * mass * base_radius**2

    if np.abs(force_noslip) <= np.abs(force_slip):
        analytical_translational_energy = (2.0 / mass *
                                           (final_time * C_s /
                                            (3.0 * base_radius))**2)
        analytical_rotational_energy = (2.0 * mass_moment_of_inertia *
                                        (final_time * C_s /
                                         (3.0 * base_radius**2 * mass))**2)
    else:
        analytical_translational_energy = (
            mass * (kinetic_mu_array[2] * gravitational_acc * final_time)**2 /
            2.0)
        analytical_rotational_energy = (
            (C_s - kinetic_mu_array[2] * mass * np.abs(gravitational_acc) *
             base_radius)**2 * final_time**2 / (2.0 * mass_moment_of_inertia))

    return {
        "rod": shearable_rod,
        "sweep": C_s,
        "translational_energy": translational_energy,
        "rotational_energy": rotational_energy,
        "analytical_translational_energy": analytical_translational_energy,
        "analytical_rotational_energy": analytical_rotational_energy,
    }
Exemple #23
0
# FIXME change callback_of to collect_diagnostics
spherical_joint_sim.collect_diagnostics(rod1).using(
    TestJoints, step_skip=1000, callback_params=pp_list_rod1)
spherical_joint_sim.collect_diagnostics(rod2).using(
    TestJoints, step_skip=1000, callback_params=pp_list_rod2)

spherical_joint_sim.finalize()
timestepper = PositionVerlet()
# timestepper = PEFRL()

final_time = 10
dl = base_length / n_elem
dt = 1e-5
total_steps = int(final_time / dt)
print("Total steps", total_steps)
integrate(timestepper, spherical_joint_sim, final_time, total_steps)

PLOT_FIGURE = True
SAVE_FIGURE = False
PLOT_VIDEO = True

# plotting results
if PLOT_FIGURE:
    filename = "spherical_joint_test_last_node_pos_xy.png"
    plot_position(pp_list_rod1, pp_list_rod2, filename, SAVE_FIGURE)

if PLOT_VIDEO:
    filename = "spherical_joint_test.mp4"
    plot_video(pp_list_rod1,
               pp_list_rod2,
               video_name=filename,