Skip to content

Pendulum 3D

Let's use the system class pydykit.systems_multi_body.ParticleSystem to simulate a single particle with concentrated mass within a three-dimensional space.

The particle's initial position is (1.0, 0.0, 0.0) and its initial velocity points into the y-direction. The particle's distance to a fixed support at (0.0, 0.0, 0.0) is constraint to be of length 1.0 and there is a gravitational field into negative z-direction.

In consequence, the particle is called a 3D pendulum and its motion is visualized in belows Result tab. The source code of leading to this viosualization is given within the Source tab.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import plotly.graph_objects as go

from pydykit.configuration import Configuration
from pydykit.examples import ExampleManager
from pydykit.managers import Manager
from pydykit.plotters import Plotter

####### Simulation
file_content = ExampleManager().get_example(name="pendulum_3d")
configuration = Configuration(**file_content)  # Validate config file content

manager = Manager()
manager.configure(configuration=configuration)

result = manager.manage()  # Run the simulation

####### Plotting
df = result.to_df()
fig = go.Figure()
plotter = Plotter(results_df=df)
for index in range(manager.system.nbr_particles):
    plotter.plot_3d_trajectory(
        figure=fig,
        x_components=df[f"position0_particle{index}"],
        y_components=df[f"position1_particle{index}"],
        z_components=df[f"position2_particle{index}"],
        time=df["time"],
    )
    index_time = 0
    plotter.add_3d_annotation(
        figure=fig,
        x=df[f"position0_particle{index}"][index_time],
        y=df[f"position1_particle{index}"][index_time],
        z=df[f"position2_particle{index}"][index_time],
        text=f"start of particle {index}",
    )
plotter.fix_scene_bounds_to_extrema(figure=fig, df=df)

####### Show visualization
script_is_executed_on_local_machine = False  # You might want to change this

if script_is_executed_on_local_machine:
    fig.show()
else:
    print(
        fig.to_html(
            full_html=False,
            include_plotlyjs="cdn",
        )
    )

Config File

Let's have a closer look at the configuration file of this simulation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
name: pendulum_3d
system:
  class_name: ParticleSystem
  nbr_spatial_dimensions: 3
  particles:
    - index: 0
      initial_position: [1.0, 0.0, 0.0]
      initial_momentum: [0.0, 1.0, 0.0]
      mass: 1.0
  supports:
    - index: 0
      type: fixed
      position: [0.0, 0.0, 0.0]
  springs: []
  dampers: []
  constraints:
    - start:
        type: support
        index: 0
      end:
        type: particle
        index: 0
      length: 1.0
  gravity: [0.0, 0.0, -9.81]
integrator:
  class_name: MidpointMultibody
simulator:
  class_name: OneStep
  solver_name: NewtonPlainPython
  newton_epsilon: 1.e-07
  max_iterations: 40
time_stepper:
  class_name: FixedIncrementHittingEnd
  step_size: 0.08
  start: 0.0
  end: 1.3

System

The system-section in the above configuration file defines the scene, aka. system, to be simulated. This includes definition of the particle, the fixed support, the constraint and the gravitation.

The system-sections variable class_name tells pydykit that the scene shall be based on the system class ParticleSystem, which belongs to the family of MBS. This class is known to pydykit as it has been registered within the SystemFactory.

Integrator

The integrator-section in the above configuration file defines the integration scheme to be used. Here, the implicit midpoint rule will be applied to the system which is formulated as a MBS.

Similar to the registration pattern of the system, the variable class_name within section integrator tells pydykit to use the class MidpointMultibody. This class is known to pydykit as it has been registered within the IntegratorFactory. The pattern of referencing a registered Python class in terms of class_name also applies to the sections simulator and time_stepper.

Simulator

The simulator-section defines the solution procedure, aka. simulator, to be used. The simulator uses a Newton method with a specific accuracy for the norm of the residual newton_epsilon and a maximum number of iterations per time step before the simulation procedure is stopped.

Time Stepper

The time_stepper-section defines the time stepping algorithm based on settings for start time, end time and step size.