LDDS

Tutorial 1: Continuous 1DoF systems

In this very first tutorial, we will introduce the basic setups for computation and visualization of the Lagrangian descriptor for the dynamics of 1DoF continuous dynamical systems: autonomous and nonautonomous (time-dependent).

First, we will look at the Hamilton centre system, a well-known autonomous system, enumerating every step.

Then, additional examples of other Hamiltonian systems are added to reinforce the logic and for you to play around with them!

A first example: Hamilton centre system

In this first example, we look at the centre system: a Hamiltonian autnomous system described by the following Hamiltonian function, identified as the energy of the system, and its vector field given by Hamilton's equations of motion.

Energy

\begin{equation*} H(x, p_x) = \frac{\omega}{2} (p_x^2 + x^2) \;, \;\; \omega > 0 \end{equation*}

Vector field

\begin{align*} \dot{x} &= \frac{\partial H}{\partial p_x} = f_1(x, p_x) = \omega p_x \\ \dot{p}_x &= -\frac{\partial H}{\partial x} = f_2(x, p_x) = -\omega x \end{align*}

The origin of this system is a stable equilibrium point, which unlike other example systems provided in ldds does not have stable and unstable invariant manifolds.

FIRST

We begin by importing the basic functions from the ldds module to calculate and plot the Lagrangian descriptors (LDs) of the dynamics of the system, and also the function that define its vector field.

NOTE When running this notebook, if you haven't installed ldds then, you might get an import error from Python. Try out the following lines to fix that, restart the notebook, and then try importing the above functions again.

SECOND

Define the paramaters for a 2D rectangular grid for visualization of the Lagrangian descriptor in the plane $x-p_x$, from which initial conditions to solve the dynamics are taken too.

NOTE We recomend starting calculations with a coarse grid first to prevent overloading your computer, for example: Nx, Ny = [100,100] or less, and subsequently increasing the resolution or recentering the grid.

THIRD

Define the paramaters for integration of the dynamics: the integration time, $\tau$, and the $p$-value, determining the deifnition of the Lagrangian descriptor function to use.

NOTE For further info on different versions of the Lagrangian descriptor function. Look at this online reference. Here.

FOURTH

Define the vector field function describing the dynamics.

LDDS provides a thorough description of every vector field function, which can be displayed using help.

This is particularly helpful if you want to change PARAMETERS of the system, which can be done constructing vector_field from HamCenter1D as below

NOTE Here, we imported the function HamCenter1D that lives in the module ldds.vector_fields. LDDS can also accept user-defined functions, as it will be seen later in Tutorial 4

FIFTH

Compute the forward and backward Lagrangian descriptors passing all the above parameters to compute_lagrangian_descriptor.

Note that for the backwards LD the integration time is passed with a negative sign, since the dynamics has to be solved "backwards in time" for this LD.

SIXTH

Visualise the Lagrangian descriptor and its gradient using the draw_all_lds function.

This will return two contour plots, one of LD values and another of its gradient magnitude over each point in the 2D grid that we defined initially.

SEVENTH (OPTIONAL)

The graphical output provided by draw_all_lds can be further modified, since it returns the plot handles of the figure. So, typical modifications to Python matplotlib objects apply.

Below we show how the first row of plots can be customised from the outputted subplot handles.

More autonomous systems

Next, we introduce extra examples of computation of LDs for other autonomous and nonautonomous dynamical systems.

For simplification we just present the executable cells with all the necessary input parameters and variables.

Feel free to change all the different parameters as an exercise to see their influence on the graphical output of the LDs.

Hamilton Saddle

Energy

\begin{equation*} H(x, p_x) = \frac{\lambda}{2}( p_x^2 - x^2 ) \; , \;\; \lambda > 0 \end{equation*}

Vector field

\begin{align*} \dot{x} &= \frac{\partial H}{\partial p_x} = f_1(x, p_x) = \lambda p_x \\ \dot{p}_x &= -\frac{\partial H}{\partial x} = f_2(x, p_x) = \lambda x \end{align*}

Duffing oscillator

Energy

\begin{equation*} H(x, p_x) = \dfrac{1}{2}p_x^2 - \dfrac{1}{2}x^2 + \dfrac{1}{4}x^4 \end{equation*}

Vector field

\begin{align*} \dot{x} &= \frac{\partial H}{\partial p_x} = f_1(x, p_x) = p_x \\ \dot{p}_x &= -\frac{\partial H}{\partial x} = f_2(x, p_x) = x - x^3 \end{align*}

Working with nonautonomous systems

For nonautnomous dynamical systems their vector field is time-dependent.

Since the Lagrangian descriptor is a function of the initial conditions of trajectories at time t0, then if t0 changes, then computed LD values will change too.

By default, LDDS assumes t0 = 0, however, this can be easily changed as we will see later.

NEXT, we introduce a basic example of a 2D nonautonomous system: The Double Gyre.

For this example, the steps to set up the computation of the LDs follow as before. The only fundamental difference is the definition of the vector field, which must be a time-dependent Python function.

Double-gyre ($t_0 = 0$)

Vector field

\begin{align*} \dot{x} &= -\pi A sin(\pi f(t, x)/s) cos(\pi y / s) - \mu x \\ \dot{y} &= \pi A cos(\pi f(t, x)/s) sin(\pi y / s) \frac{df(t,x)}{dx} - \mu y \end{align*}

where

\begin{align*} f(t, x) &= \epsilon \cdot sin(\phi t + \psi) x^2 + (1 - 2 \epsilon \cdot sin(\phi t + \psi)) x \\ \frac{df(t,x)}{dx} &= 2 \epsilon \cdot sin(\phi t + \psi) x + (1 - 2 \epsilon \cdot sin(\phi t + \psi)) \end{align*}

with $A, \phi, \psi, \mu, s, \epsilon$ constant parameters.

Double-gyre ($t_0 \neq 0$)

As mentioned above, LDDS takes t0 = 0 by default.

However, this can be changes via the parameter called phase_shift, which is set as equal to zero by default, as seen using Python help.

In general, phase_shift appear for any time-dependent vector field in the vector_fields module.

To change phase_shift we need the redefine the PARAMETERS of the DoubleGyre vector field, as below

Then, all the remaining steps of the set up are done as before

See the difference between the above output and the one generated using default parameters (when phase_shift = 0).