Message Boards Message Boards

Chaos bifurcation of double pendulums calculation with OOP

Posted 8 years ago

This sample program is developed to show the power of Mathematica OOP as shown in other my OOP projects.

It is well known that the double pendulum motion becomes a chaos with time development. Also, in the time development of a pendulum, we can observe another kind of chaos caused by the initial condition. A very small fluctuation of the initial condition affect the time development deeply. In this program case, angle perturbation less than 10^-12 can have an effect on the time development.

To observe this phenomenon this program traces simultaneously a several tens of double pendulums each has random initial angle difference. The pendulums are represented by the instance constructed from the OOP Lagrange equation of motion class. The Mathematica OOP can represent these number of double pendulums motion in time development with a simple and an effective way.

50 pendulums in time development

Setup for global parameters and OOP class

{g = 9.8, m = 1, r1 = 1, r2 = 0.5, time = 50};

case[nam_] := 
  Module[{\[Theta]1, \[Theta]2, ans, T1, T2, V1, V2, t, L, lkeq, 
    initcond},

   initialize[nam[th1_, th2_]] ^:= (
     (* Lagrangian setup *)
     T1 = 1/2 m*r1^2*\[Theta]1'[t]^2;
     V1 = -m*g*r1*Cos[\[Theta]1[t]];
     T2 = 
      1/2 m*(r1^2*\[Theta]1'[t]^2 + r2^2*\[Theta]2'[t]^2 + 
         2 r1*r2*\[Theta]1'[t]*\[Theta]2'[t]*r1*r2*
          Cos[\[Theta]1[t] - \[Theta]2[t]]);
     V2 = -m*g*(r1*Cos[\[Theta]1[t]] + r2*Cos[\[Theta]2[t]]);
     L = T1 + T2 - (V1 + V2);

     (* Lagrange equation of motion *)

     lkeq = {D[D[L, \[Theta]1'[t]], t] - D[L, \[Theta]1[t]] == 0,
       D[D[L, \[Theta]2'[t]], t] - D[L, \[Theta]2[t]] == 0};
     initcond = {
       \[Theta]1[0] == th1,
       \[Theta]2[0] == th2,
       \[Theta]1'[0] == 0,
       \[Theta]2'[0] == 0};

     (* Numerical solve of equation *)

     ans = NDSolve[{lkeq, initcond}, {\[Theta]1, \[Theta]2}, {t, 0, 
         time}, MaxSteps -> Infinity, PrecisionGoal -> \[Infinity]][[
       1]];
     );

   pendulum[nam[tr_]] ^:= (
     (* Pendulum graphics return *)

     Graphics[{Line[{{0, 
          0}, {r1*Sin[\[Theta]1[tr]], -r1*Cos[\[Theta]1[tr]]} /. 
          ans}], Line[{{r1*Sin[\[Theta]1[tr]], -r1*
            Cos[\[Theta]1[tr]]}, {(r1*Sin[\[Theta]1[tr]] + 
             r2*Sin[\[Theta]2[tr]]), (-r1*Cos[\[Theta]1[tr]] - 
             r2*Cos[\[Theta]2[tr]])}} /. ans]}, 
      PlotRange -> {{-1.8, 1.8}, {-1.8, 1.8}}]
     )
   ];

Setup initial conditions and construct instances, and display of results

{pendulums = 50, angle1 = 4 Pi/3, angle2 = 4 Pi/3, butterfly = 10^-12};

objectList = Table[Unique[], {pendulums}];
Map[case[#] &, objectList];
Map[initialize[#[angle1, angle2 + butterfly*RandomReal[{-1, 1}]]] &, 
  objectList];

Animate[Show[
  Map[pendulum[#[tr]] &, objectList]
  ], {tr, 0, time}, AnimationRepetitions -> 1, AnimationRate -> 1]

Enjoy a sudden divergence.

8 Replies

enter image description here -- you have earned Featured Contributor Badge enter image description here

Your exceptional post has been selected for our editorial column Staff Picks http://wolfr.am/StaffPicks and Your Profile is now distinguished by a Featured Contributor Badge and is displayed on the Featured Contributor Board. Thank you, keep it coming, and consider contributing to the The Notebook Archive!

POSTED BY: EDITORIAL BOARD
Posted 8 years ago

Very good. WSM can undoubtedly be used for this type of problems. The original discussion however was about the benefits of OOP as compared to classic functional programming. OOP is indeed many times faster and he can introduce hundreds of pendulums and still have a fast animation. The number is absurd but Kobayashi was making a key point: OOP is very, very much faster, at least in this case. Some experts on OOP will understand why? My functional program example is limited to some 10 pendulums beyond that, speed becomes an issue. I do not know if WSM would give similar speed benefits?

POSTED BY: Erik Mahieu

Nice work Patrik!

One other important note about using WSM (Wolfram SystemModeler) for this type of problem is that you do not need to formulate the Lagrangian or derive the equations of motion. You just drag and drop the elements and configure them. SystemModeler derives the equations of motion. It integrates the equations very quickly (because it optimizes them) and gives you interactive plots and an animation if you use the multibody elements.

It is a great tool for this type of problem.

POSTED BY: Neil Singer

Fantastic application! Thanks for sharing this.

Another way to observe this phenomenon could be using Wolfram SystemModeler. Here I have constructed a double pendulum model in SystemModeler (model is attached): enter image description here

Like your application, the underlying language of SystemModeler is object oriented. This allows all the components you see above be extended into arrays of components. By setting a parameter "n", the number of pendulums can be selected. enter image description here

Using Mathematica, we can set the initial angles of the different pendulums to have very small deviations:

Needs["WSMLink`"]

n = 10;

WSMSetValues["DoublePendulum", {"n" -> n}];
WSMSetValues[
  "DoublePendulum", {"revolute2.phi" -> 
    RandomReal[{-10^-12 Degree, 10^-12 Degree}, n]}, "InitialValues"];

The result will look something like this: enter image description here

Video courtesy of @Neil Singer

Attachments:
POSTED BY: Patrik Ekenberg
Posted 8 years ago

Excuse my "goof", I am a hobbyist programmer and trying to learn from similar goofs in the past! As you made your point, OOP is indeed significantly faster in tis case of 100 or more pendulums. This may not be very realistic but it could be interesting in a lot of other cases I already encountered and had speed problems.

In the past I have been trying to model the dynamics of a falling or swinging chain with an n-linked pendulum(see my demonstration "Dynamics of a Falling Chain" at:http://demonstrations.wolfram.com/DynamicsOfAFallingChain/). As you can see, due to speed limitations, I had to limit my demonstration to 11 links, which is not fully realistic. A good model should include 50 or even 100 links. Could OOP be used to equally speed up the case of a 100-linked chain? I am sure you could adapt your OOP code to 1 pendulum with 100 links? An equally dramatic speed increase would be very important here! ...and maybe convert more people to OOP?

POSTED BY: Erik Mahieu

Hi, Mahieu,

Your project is intending centuple pendulum motion equation! Great! I hope the OOP can help your project, however, i have no idea on your Falling Chain code now. But, if there was a bottleneck on the drawing graphics, OOP may support the speedup for the graphics with representing each pendulum as a instance of graphics class.

I'm very grad you did understand my OOP idea well. Thank you.

Hello Mahieu, Your work is a goof comparison without OOP. Please try a case of pendulum number to 100 or greater.

Posted 8 years ago

I am very interested in your subject of chaos and the double pendulum. Your implementation with OOP was a surprise but I figured it out and I was able to learn a lot about UpValues, Upset, DelayedUpset etc... However, I do not understand what is the exact advantage of using your OOP paradigm. I did the same using ParametricNDSolve and implemented your formulas without any problem.

Manipulate[
 Quiet@Module[{T1, T2, V1, V2, L, lkeq, 
    ans, \[Theta]1Eff, \[Theta]2Eff, pendulum, butterfly, g = 9.8, 
    m = 1, r1 = 1, r2 = 0.5},
   SeedRandom[13];
   (*Lagrangian setup*)
   T1 = 1/2 m*r1^2*\[Theta]1'[t]^2;
   V1 = -m*g*r1*Cos[\[Theta]1[t]];
   T2 = 1/
      2 m*(r1^2*\[Theta]1'[t]^2 + r2^2*\[Theta]2'[t]^2 + 
       2 r1*r2*\[Theta]1'[t]*\[Theta]2'[t]*r1*r2*
        Cos[\[Theta]1[t] - \[Theta]2[t]]);
   V2 = -m*g*(r1*Cos[\[Theta]1[t]] + r2*Cos[\[Theta]2[t]]);
   L = T1 + T2 - (V1 + V2);
   (*Lagrange equation of motion*)
   lkeq = {D[D[L, \[Theta]1'[t]], t] - D[L, \[Theta]1[t]] == 0, 
     D[D[L, \[Theta]2'[t]], t] - D[L, \[Theta]2[t]] == 0};
   (*Numerical solve parametric differential equation: 
   parameter is the initial angular displacement increment*)
   ans = ParametricNDSolve[{lkeq, {\[Theta]1[0] == 
        th1 + \[Epsilon], \[Theta]2[0] == 
        th2 + \[Epsilon], \[Theta]1'[0] == 0, \[Theta]2'[0] == 
        0}}, {\[Theta]1, \[Theta]2}, {t, 0, time}, {\[Epsilon]}, 
     MaxSteps -> \[Infinity], PrecisionGoal -> \[Infinity]];
   \[Theta]1Eff[\[Epsilon]_, tr_] := \[Theta]1[\[Epsilon]][tr] /. 
     ans;
   \[Theta]2Eff[\[Epsilon]_, tr_] := \[Theta]2[\[Epsilon]][tr] /. ans;
    butterfly = 10^-pwr;
   pendulum[\[Epsilon]_, col_: Black] := {col, 
     Line[{{0, 
        0}, {r1*Sin[\[Theta]1Eff[\[Epsilon], tr]], -r1*
         Cos[\[Theta]1Eff[\[Epsilon], tr]]}}], 
     Line[{{r1*Sin[\[Theta]1Eff[\[Epsilon], tr]], -r1*
         Cos[\[Theta]1Eff[\[Epsilon], tr]]}, {(r1*
           Sin[\[Theta]1Eff[\[Epsilon], tr]] + 
          r2*Sin[\[Theta]2Eff[\[Epsilon], tr]]), (-r1*
           Cos[\[Theta]1Eff[\[Epsilon], tr]] - 
          r2*Cos[\[Theta]2Eff[\[Epsilon], tr]])}}]};
   (*-----graphics display--------*)

   Graphics[
    Map[pendulum[butterfly*#1, Hue[#1]] &, RandomReal[{-1, 1}, n]], 
    PlotRange -> {{-1.8, 1.8}, {-1.8, 1.8}}]],
 (*-----controls--------*)
 {{tr, 0, Style["time", 12]}, 0, time, 
  Animator, AnimationRunning -> False, AnimationRepetitions -> 1, 
  AnimationRate -> .025},
 Row[{Style["\nnumber of pendulums", 12], 
   Control[{{n, 6, ""}, Range[12]}]}],
 Style["\ninitial angular base displacemenents", 
  12], {{th1, 2., "\[Theta]1"}, -3.14, 
  3.14}, {{th2, 2.5, "\[Theta]2"}, -3.14, 3.14},
 Row[{Style[
    "\ninitial angular displacement difference\n\[Theta]2-\[Theta]1: \
10^-", 12], Control[{{pwr, 12, ""}, Range[3, 16]}]}], {{time, 50}, 
  None},
 (*-----options--------*)
 TrackedSymbols :> Manipulate, 
 AutorunSequencing -> {}, ControlPlacement -> Left]

I further more could introduce a variable number of pendulums and a variable "butterfly" value. All this using plain functional programming. Your method is very elegant and smart but what exactly can one do more,faster or better with OOP?

enter image description here

POSTED BY: Erik Mahieu
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract