Skip to content

A semi-analytical satellite galaxy and dark matter halo generator

Notifications You must be signed in to change notification settings

Jonathanfreundlich/SatGen

 
 

Repository files navigation

SatGen

A semi-analytical satellite galaxy and dark matter halo generator, introduced in Jiang et al. (2020), extended in Green et al. (2020).

  • Model overview

SatGen generates satellite-galaxy populations for host halos of desired mass and redshift. It combines halo merger trees, empirical relations for galaxy-halo connection, and analytic prescriptions for tidal effects, dynamical friction, and ram-pressure stripping. It emulates zoom-in cosmological hydrosimulations in certain ways and outperforms simulations regarding statistical power and numerical resolution.

  • Modules

profiles.py: halo-density-profile classes, currently supporting NFW profile, Einasto profile, Dekel+ profile, and Miyamoto-Nagai disk

orbit.py: orbit class and equation of motion

cosmo.py: cosmology-related functions, including an implementation of the Parkinson+08 merger tree algorithm

config.py: global variables and user controls

galhalo.py: galaxy-halo connections

init.py: for initializing satellite properties at infall

evolve.py: for mass stripping and structural evolution of satellites

TreeGen.py: an example program for generating halo merger trees

SatEvo.py: an example program for evolving satellite galaxies after generating merger trees with TreeGen.py

  • Dependent libraries and packages

numpy, scipy, cosmolopy

We recommend using python installations from Enthought or Conda.

  • Basic usage

SatGen builds upon density-profile classes and an orbit class, as implemented in profiles.py and orbit.py. Apart from SatGen's main purpose of generating satellite galaxies in a cosmological setup, these two modules are useful for simpler studies that involve halo profiles (e.g, Jeans modeling) and orbit integration within spherical or axisymmetric potential wells. Here we walk through the basic usage of profiles.py and orbit.py.

To initialize a halo, for example, we can do

[]: from profiles import NFW,Dekel,Einasto

[]: h = NFW(1e12, 10, Delta=200., z=0.)

This defines a halo object "h" following an NFW profile of a virial mass of and a concentration of 10, where a halo is defined as spherical enclosure of 200 times the critical density of the Universe at redshift 0. (Note that since the profiles module internally imports the cosmo module, if it is the first time of importing profiles, it takes a few seconds to initialize cosmology-related stuff.)

With the halo object defined, one can easily evaluate, at radius [kpc], the density [ ], the enclosed mass [ ], the gravitational potential [], the circular velocity [kpc/Gyr], the 1D velocity dispersion [kpc/Gyr] (under the assumption of isotropic velocity distributino), etc, by accessing the corresponding attribute or method. For example:

[]: h.M(10.)

returns the halo mass within a radius of 10 kpc; and

[]: h.rmax

gives the radius [kpc] at which the circular velocity reaches the maximum.

To initialize a disk potential:

[]: from profiles import MN

[]: d = MN(10**10.7, 6.5, 0.25)

This defines a disc object "d" following a Miyamoto-Nagai profile of mass with a scale radius of kpc and a scale height of kpc.

Similarly, one can evaluates various quantities by accessing the attributes and mothods of the disk object "d". For example,

[]: d.Phi(8.,z=0.)

returns the gravitational potential at the cylindrical coordinate .

One can make a composite potential simply by creating a list, e.g.,

[]: p = [h,d]

This creates a composite potential consisting of the NFW halo and the MN disk defined above. The properties of the composite potential can also be evaluated easily. For example, if we want to get the circular velocity profile, we can do:

[]: import numpy as np

[]: R = np.logspace(-3,0,100)

[]: Vcirc(p,R,z=0.)

Let's say, we now want to integrate the orbit of a point mass in this composite potential "p". To do this, first, we initialize the orbit, by specifying the initial 6D phase-space coordinate "xv" in the cylindrical frame (a list or an numpy array), xv = [kpc, radian, kpc, kpc/Gyr, kpc/Gyr, kpc/Gyr] --

[]: import orbit as orb

[]: o = orb.orbit(xv)

This gives us an orbit object "o". Then, orbit integration can be done by calling the o.integrate method:

[]: o.integrate(t,p)

This integrates the orbit for time "t" [Gyr] (float or array) in the potential well "p", without considering dynamical friction. If instead we want to consider dynamical friction, we simply add the test-object's mass "m" as a third parameter when calling the o.integrate function, i.e.,

[]: o.integrate(t,p,m)

After the orbit integration, we can access the instantaneous 6D coordinate simply by

[]: o.xv

and access the time elapsed since the initial position by

[]: o.t

If the "t" used in "o.integrate(t,p,m)" is an array, the full orbit can be accessed by

[]:o.xvArray

Moving on to a more realistic exercise, we recommend interested readers to follow the program test_evolve.py. This is an example of evolving a satellite galaxy in a static host potential. In addition to halo profiles and orbit integration described above, this example also considers tidal stripping, tidal heating, and ram-pressure stripping, and thus serves as a good walk-through different modules (profiles.py, orbit.py, galhalo.py, init.py, and evolve.py).

  • Advanced usage

For full cosmological applications, TreeGen.py and SatEvo.py constitute a complete set of exercises. TreeGen.py generates EPS merger trees and initializes satellites at the first virial-crossing. SatEvo.py evolves the satellites.

These programs are process-based parallelized using python's multiprocessing library.

SatGen has detailed docstrings, and all the example programs are designed to be self-explanatory. Please feel free to contact the authors Fangzhou Jiang ([email protected]) and Sheridan Beckwith Green ([email protected]), if you have any question.

About

A semi-analytical satellite galaxy and dark matter halo generator

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 99.7%
  • Shell 0.3%