This book originated as a set of notes written to accompany a semester-long (12 week) course on “Galactic Structure and Dynamics” at the University of Toronto that I started teaching in the Fall of 2017 and have since thought twice more, in Fall 2018 and Fall 2020. I had various objectives in writing these notes. The first is that while excellent, graduate-level books on this topic exist (foremost “Galactic Dynamics” by Binney & Tremaine 2008; BT08), in preparing for my class I found that the detailed, deep, and exhaustive treatment of all important topics in galactic dynamics that can be found in BT08 is likely to be overwhelming to students just starting out in the field. The BT08 treatment is also largely divorced from observational background and applications (except for their excellent introductory chapter) and does not cover galaxy formation and evolution or its cosmological context. The standard solution to this problem is to supplement BT08 by Binney & Merrifield (1998) (BM98 hereafter), another \(\approx800\) page tome with detailed, in-depth discussions of many of the important topics in galactic structure, but somewhat out of date at this point. These are and remain excellent books and hardly a day goes by that I do not consult BT08 at length in my own research, but especially BT08 is in my opinion a reference book rather than a textbook. The objective of this book is to present a selection of topics largely covered in BT08 and BM98 in a sequence closer aligned with how these topics would actually be taught, rather than covering all aspects of a topic before going on to the next, while bringing the discussion up to date with the latest research and paying more attention to the cosmological context of galaxies and their evolution. This book obviously owe a tremendous debt to mostly BT08 but also BM98.
The second objective of this book is reduce the distance between a standard textbook and the practice of research. Code examples are given throughout the notes to illustrate the concepts discussed, more so in later chapters, because some of the introductory material does not lend itself as easily to interesting code examples. All of these examples can be run in
python on your own machine or directly in the browser using cloud computing (look for the “Make interactive” button); you should
play around with these, changing parameters in the code to see what happens and deepen your understanding. Some current highlights are the two-dimensional velocity fields in Chapter 9.1, the surfaces of section and chaos in Chapter 14, the Schwarzschild modeling example in Chapter 15.3.2, and the example tree-based \(N\)-body solver in Chapter 19.1.2.
Many of the examples use
galpy, a Python-based galactic-dynamics code (Bovy 2015). The code also contains interactive visualizations of data sets (such as globular cluster in the Milky Way in Chapter 2.2.4 and the \((l,v)\) diagram of molecular clouds in Chapter 9.3.1) and of orbits computed in galpy (e.g., orbits in an axisymmetric potential in Chapter 10.1
and box and loop orbits in non-axisymmetric potentials in Chapter 14). The latter hopefully give a much better sense of the dynamic nature of the subject than the static images of orbits that one typically finds in books and journal articles! Some further instructions on how to use the code in this book are given below.
This book discusses many of the standard results in galactic structure and dynamics. It also discusses some aspects of the field in a different manner from the standard treatment, some that are not typically discussed, and some new developments. Some examples of these are:
The virial theorem is used to introduce the topic of dynamical equilibrium, rather than derived as a consequence of the collisionless Boltzmann equation.
Chapter 7 discusses a number of recent results in dynamical modeling of spherical systems. In particular, it contains a somewhat simplified derivation of the “Wolf mass estimator”, a robust and now popular estimator for the mass of a spherical system at the half-mass radius.
The gravitational potential of a disky mass distribution in Chapter 8.3 is derived using Bessel functions and Hankel transforms, which allow a unified treatment and a clear trajectory from razor-thin, axisymmetric disks to thick, non-axisymmetric disks. This differs from the treatment in BT08, who start by deriving the potential of a razor-thin disk as the limit of a flattened, oblate spheroid.
Chapter 8.3 also contains an explicit proof that a finite-mass razor-thin disk approaches the point-mass potential at large distances and derives an approximate expression for the rotation curve of a thick, double-exponential disk. The latter is a standard model for a disk galaxy, but it is difficult to come by this approximate expression in the literature (it is derived here from scratch).
The discussion on orbits in disk potentials in Chapter 10 focuses much attention on the importance of the approximate separability of the planar and out-of-plane motions, which is heavily relied upon in Chapter 11 when discussing equilibrium models for disks.
Chapter 9 contains a detailed and critical discussion of the evidence for dark-matter from rotation curves in the 1970s and 1980s that eventually led to the widespread acceptance of the dark-matter paradigm.
Chapter 18 contains a brief, self-contained discussion of cosmological perturbation theory and the astrophysics of dark-matter-halo virialization.
Chapter 19.2 discusses orbit integrators as falling in two distinct classes: regular differential-equation solvers, which approximately solve the equations of motion, and “Hamiltonian” solvers, which exactly solve the equations of motion of an approximate Hamiltonian.
The present version of this book is only an incomplete, under construction version of the final book. The first three parts are essentially complete, with only minor changes envisioned for the final version. The fourth part is largely incomplete, with only two chapters drafted so far; these are included already in the hope that they may be useful, but they may change substantially in the final version. Chapters whose titles include the ⚠️🚧 🚧🚨 symbols are under heavy construction. A set of appendices is also still under construction, with appendices on coordinate transformation and the general theory of relativity largely complete, but an appendix containing mathematical background largely incomplete.
1.1. How to use these notes¶
The code snippets in this book are largely self-contained, including all of the necessary imports to run the code. Different code snippets within the same subsection may depend on each other (especially on imports earlier in the section), although an effort is made to make sure that qualitatively different parts of a chapter can stand alone. However, some basic commands are assumed, in particular, the following code is always assumed to be run (and is not included in the book):
import warnings warnings.filterwarnings('ignore') import numpy import astropy.units as u from galpy.util import plot as galpy_plot galpy_plot.start_print(axes_labelsize=17.,text_fontsize=12., xtick_labelsize=15.,ytick_labelsize=15.) %pylab inline
This code gives access to all of the
pylab plotting functions (allowing commands like
xlim, etc.), it sets up the style of any figures (this is not essential for code snippets to works, although
galpy_plot may be assumed in snippets), and ignores any warnings (to suppress ugly warnings in the notes; when running the code, it may be prudent to not ignore the warnings).
You can run the code examples given in these notes directly within the browser by clicking on the “Make interactive!” button in the lower right of each page. Clicking this button will request a free, cloud-based Python kernel that includes all of the necessary packages to run the code examples. Clicking the “Make interactive!” button changes the button to “Launching kernel …” and converts all of the code examples into editable cells (also removing the output that is shown when the page is not connected to a Python kernel). Once the button changes to “Kernel loaded!”, you can start executing the cells, either by clicking the “run” button within each cell or by clicking “shift-return” like in a jupyter notebook/lab session (note that you do not have to run the code block given above; this is automatically executed as part of the initialization). The normally-blue side of a cell will turn green while the cell is executing, reverting back to blue when the cell has completed executing. You can run arbitrary Python code in the editable cells when the page is interactive (it’s essentially the same as a jupyter session). Edit the given code and run again to see what happens when you change parameters! Note that there is currently no way to restart the kernel; if you run into problems with the kernel or seem to lose connection (e.g., through a period of inactivity), please reload the page and click “Make interactive!” again.
If you want to run the code on your own machine, installing the packages required to execute the code in the notes is easiest if you are using the Anaconda Python distribution, a package manager for Python. Most of the necessary packages can be installed by doing
conda env create -f environment.yml
which creates the conda environment
environment.yml file should have the following contents:
name: galaxiesbook channels: - conda-forge dependencies: - python=3.8 - ipython - jupyter - numpy - scipy - matplotlib - pyqt - pandas - pip - conda-forge::astropy>=2 - conda-forge::specutils - conda-forge::galpy - pip: - astroquery
Activate this environment with
source activate galaxiesbook
Note that for some of the code, you also need to have the
wget UNIX utility installed. The code also assumes that you are using the
galpy configuration file that can be found here; see this galpy documentation page for more info on the configuration file (TLDR: either put it in your home directory to use it globally, or in the directory where
you are running code to use it locally).
This book uses MathJax to typeset math and equations, with some customizations from the basic setup. The different chapters contain links to equations on different webpages, but be aware that clicking on them will load the entire new webpage (which may take a while) and only go to the correct equation at the end of the loading (which is when MathJax can resolve the reference). This means that if you have made the page interactive, clicking on an equation link in another chapter without choosing to open the link in a new page will sever your interactive session (the same holds for links to other chapters and sections in them). To make seeing referenced equations easier, hovering over the equation link will bring up a tooltip window that displays the equation, as shown in the example below
Links to an equation number on the same page can be followed with no harmful effects, but hovering over them will similarly show the linked equation.
References can also be viewed by hovering over the reference, which further allows you to click on the links to follow the reference to its source, as shown in the next example.
In the references, the journal title is linked to the DOI (which typically leads to the journal version, except for very old papers), the volume to the ADS entry, and the page numbers to the arXiv version, when they exist. Clicking on a reference brings you to its entry in the References chapter.
This set of notes is written as a set of jupyter notebooks, rendered as HTML pages using Sphinx and the nbsphinx extension (note that I use a slightly customized version of sphinx available here). Python interactivity is added using thebelab, which connects the page to a free
binder kernel. The setup for this binder kernel is in the jobovy/galastro-binder repository. The
thebelab support was inspired by and partially-based on the code in jupyter-book’s sphinx-book-theme.