Previous ToC Up Next

## 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