Previous ToC Up Next

11. Centering

11.1. Center of Mass Adjustment

Bob: I could see that you were not too impressed with my quiet start. However, I expect that you may be more interested in a more important improvement I would like to make, the center of mass adjustment.

Alice: Indeed. I think it would be better to shift to a coordinate system in which the newly created star cluster has its center of mass in the origin of the coordinate system. In addition, it would be nice to give the coordinate system a boost in such a way that the velocity of the center of mass is zero in that coordinate system. Is this what you had in mind?

Bob: Exactly. It would of course be possible to sprinkle particles in space, and in velocity space, in pairs, so that you would cancel the contributions: you could place them at opposite sides of the center, and give them opposite velocities. But that would create artificial correlations, and I don't like to do that. Better to create a realization first, and then to shift the coordinate system in the way you suggested.

After creating our model, we measure the center of mass position , which I will name pos_com in the code, as follows:

and similarly for the velocity of the center of mass, which I will call vel_com in the code:

If we then subtract from each particle's position, and also subtract from each particle's velocity, we will be guaranteed that . This is then the shift that we ordered.

11.2. Implementation

Here is a straightforward implementation, in file mkplummer5.rb. At the end of the mkplummer, after all the work is done, I am adding a line:

   nb.adjust_center_of_mass                                                   

which invokes the following method:

   def adjust_center_of_mass
     vel_com = pos_com = @body[0].pos*0     # null vectors of the correct length
     @body.each do |b|
       pos_com += b.pos*b.mass
       vel_com += b.vel*b.mass
     end
     @body.each do |b|
       b.pos -= pos_com
       b.vel -= vel_com
     end
   end

Alice: Straightforward indeed. Normally you would have to divide the positions and the velocities by the total mass, but here the total mass is unity, so you can skip that. Okay, that looks good, but as always, let's first do a couple checks.

Bob: Never hurts. Here they are. First the energy:

 |gravity> kali mkplummer5.rb -n 1000 | kali energy.rb
 ==> Plummer's Model Builder <==
 Number of particles            : N = 1000
 pseudorandom number seed given : 0
 Screen Output Verbosity Level  : verbosity = 1
 ACS Output Verbosity Level     : acs_verbosity = 1
 Floating point precision       : precision = 16
 Incremental indentation                : add_indent = 2
              actual seed used  : 102454465076170166590054456817370041259
   E_kin = 0.249 , E_pot =  -0.499 , E_tot = -0.251
That certainly looks fine. Now the quartiles:

 |gravity> kali mkplummer5.rb -n 100 | kali quartiles.rb
 ==> Plummer's Model Builder <==
 Number of particles            : N = 100
 pseudorandom number seed given : 0
 Screen Output Verbosity Level  : verbosity = 1
 ACS Output Verbosity Level     : acs_verbosity = 1
 Floating point precision       : precision = 16
 Incremental indentation                : add_indent = 2
              actual seed used  : 200676475510777406202831945260956218951
 The values of the three quartiles for r(M) are:
   r(1/4) = 0.4624
   r(1/2) = 0.7879
   r(3/4) = 1.283

11.3. A Bit Disquieting

Hmm, a bit less quiet than before, it seems. Let me try a few more:

 |gravity> kali mkplummer5.rb -n 100 | kali quartiles.rb
 ==> Plummer's Model Builder <==
 Number of particles            : N = 100
 pseudorandom number seed given : 0
 Screen Output Verbosity Level  : verbosity = 1
 ACS Output Verbosity Level     : acs_verbosity = 1
 Floating point precision       : precision = 16
 Incremental indentation                : add_indent = 2
              actual seed used  : 99631758195921206451479458186316084502
 The values of the three quartiles for r(M) are:
   r(1/4) = 0.5536
   r(1/2) = 0.8253
   r(3/4) = 1.299
 |gravity> kali mkplummer5.rb -n 100 | kali quartiles.rb
 ==> Plummer's Model Builder <==
 Number of particles            : N = 100
 pseudorandom number seed given : 0
 Screen Output Verbosity Level  : verbosity = 1
 ACS Output Verbosity Level     : acs_verbosity = 1
 Floating point precision       : precision = 16
 Incremental indentation                : add_indent = 2
              actual seed used  : 41391745497524075502477861292072449084
 The values of the three quartiles for r(M) are:
   r(1/4) = 0.5362
   r(1/2) = 0.7709
   r(3/4) = 1.263
Definitely less quiet than before. How can shifting . . . ah, shifting the center of mass also shifts the positions of my idealized mass shells which provided the scaffolding for sprinkling particles in such a nicely layered way. Of course!

Alice: Yes, that must be the reason. Well, that's the price you have to pay for preventing your model for being off-center!

Bob: Perhaps layering was not such a hot idea after all. Oh, well. I may as well leave it in, for now.

11.4. Checking the One-Body Problem

Alice: So far, so good, but we should check that the center of mass is indeed in the center, and will stay there.

Bob: That may not be so easy to check, unless we write a new analysis tool to report the center of mass position and motion.

Alice: And that tool would reflect the same equations you just entered in the code, making it less of an independent check.

Bob: Ah, wait a minute: we can look at a few-body system. Starting with one body, it should sit happily in the center, and two bodies should now be placed opposite each other, in position as well as in velocity.

Alice: Yes, of course. That's a good way to check. Better first run those cases with the version you created when you went to standard units, and then to repeat them for your shifted version.

Bob: Okay, here is a one-body system without shifting:

 |gravity> kali mkplummer3.rb -n 1
 ==> Plummer's Model Builder <==
 Number of particles            : N = 1
 pseudorandom number seed given : 0
 Screen Output Verbosity Level  : verbosity = 1
 ACS Output Verbosity Level     : acs_verbosity = 1
 Floating point precision       : precision = 16
 Incremental indentation                : add_indent = 2
              actual seed used  : 117540113266824901678461589969679016117
 ACS
   NBody 
     Array body
       Body body[0]
         Float mass
              1.0000000000000000e+00
         Vector pos
              8.2111243294477043e-01  -4.8661601396052317e-01  -1.4706629848817832e-01
         Vector vel
              4.6522686113441319e-02   3.2363093321616582e-01  -7.8983556646314623e-01
 SCA
and here with the proper center of mass shifts:

 |gravity> kali mkplummer5.rb -n 1
 ==> Plummer's Model Builder <==
 Number of particles            : N = 1
 pseudorandom number seed given : 0
 Screen Output Verbosity Level  : verbosity = 1
 ACS Output Verbosity Level     : acs_verbosity = 1
 Floating point precision       : precision = 16
 Incremental indentation                : add_indent = 2
              actual seed used  : 314170348508520766155720812462576619851
 ACS
   NBody 
     Array body
       Body body[0]
         Float mass
              1.0000000000000000e+00
         Vector pos
              0.0000000000000000e+00   0.0000000000000000e+00   0.0000000000000000e+00
         Vector vel
              0.0000000000000000e+00   0.0000000000000000e+00   0.0000000000000000e+00
 SCA
Alice: Proper indeed.

11.5. Checking the Two-Body Problem

Bob: And here for the two-body system, unshifted:

 |gravity> kali mkplummer3.rb -n 2
 ==> Plummer's Model Builder <==
 Number of particles            : N = 2
 pseudorandom number seed given : 0
 Screen Output Verbosity Level  : verbosity = 1
 ACS Output Verbosity Level     : acs_verbosity = 1
 Floating point precision       : precision = 16
 Incremental indentation                : add_indent = 2
              actual seed used  : 237728020487946610170767126745428789849
 ACS
   NBody 
     Array body
       Body body[0]
         Float mass
              5.0000000000000000e-01
         Vector pos
             -2.9299850908732511e-01  -4.0256004615972074e-01  -1.5130991761430146e+00
         Vector vel
             -5.6160498361946032e-02  -5.1316168186746514e-01  -5.6570871896224492e-02
       Body body[1]
         Float mass
              5.0000000000000000e-01
         Vector pos
             -4.9899225413335158e-01  -4.7029124592957827e-01   9.3316540518483304e-01
         Vector vel
              2.3915358744844937e-02   5.4932465510773354e-01   7.2246385493690901e-01
 SCA
and shifted:

 |gravity> kali mkplummer5.rb -n 2
 ==> Plummer's Model Builder <==
 Number of particles            : N = 2
 pseudorandom number seed given : 0
 Screen Output Verbosity Level  : verbosity = 1
 ACS Output Verbosity Level     : acs_verbosity = 1
 Floating point precision       : precision = 16
 Incremental indentation                : add_indent = 2
              actual seed used  : 181979391731729668432519383999579206235
 ACS
   NBody 
     Array body
       Body body[0]
         Float mass
              5.0000000000000000e-01
         Vector pos
              7.4044576262045037e-01   2.1533080480730585e-01   6.5519200939322386e-01
         Vector vel
              1.7084546907264581e-01  -2.5237649159672826e-01   3.3883781805669311e-01
       Body body[1]
         Float mass
              5.0000000000000000e-01
         Vector pos
             -7.4044576262045037e-01  -2.1533080480730582e-01  -6.5519200939322386e-01
         Vector vel
             -1.7084546907264575e-01   2.5237649159672826e-01  -3.3883781805669305e-01
 SCA
Alice: Good! I believe the code now. We have acquired a well-adjusted codes that speaks in standard units.
Previous ToC Up Next