cbhbd 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cbhbd-1.0.0/.github/workflows/ci_tests.yml +52 -0
- cbhbd-1.0.0/.gitignore +8 -0
- cbhbd-1.0.0/PKG-INFO +98 -0
- cbhbd-1.0.0/README.md +77 -0
- cbhbd-1.0.0/cbhbd/__init__.py +8 -0
- cbhbd-1.0.0/cbhbd/cbhbd.py +159 -0
- cbhbd-1.0.0/cbhbd/cluster.py +1825 -0
- cbhbd-1.0.0/cbhbd/cluster_prescriptions.py +520 -0
- cbhbd-1.0.0/cbhbd/funcs.py +177 -0
- cbhbd-1.0.0/cbhbd/mergers.py +444 -0
- cbhbd-1.0.0/cbhbd/remnant.py +205 -0
- cbhbd-1.0.0/examples/cbhbd_example.ipynb +1436 -0
- cbhbd-1.0.0/pyproject.toml +42 -0
- cbhbd-1.0.0/tests/test_cluster.py +12 -0
- cbhbd-1.0.0/tests/test_funcs.py +48 -0
- cbhbd-1.0.0/tests/test_merger.py +31 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: CI Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- "**"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test-cluster:
|
|
10
|
+
name: "Test cluster (no mergers)"
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout repository
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.x"
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade pip
|
|
25
|
+
pip install pytest .
|
|
26
|
+
- name: Test cluster
|
|
27
|
+
run: python -m pytest tests/test_cluster.py -v
|
|
28
|
+
|
|
29
|
+
test-mergers:
|
|
30
|
+
name: "Test mergers"
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- name: Checkout repository
|
|
35
|
+
uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Set up Python
|
|
38
|
+
uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.x"
|
|
41
|
+
|
|
42
|
+
- name: Install dependencies
|
|
43
|
+
run: |
|
|
44
|
+
sudo apt-get update
|
|
45
|
+
sudo apt-get install -y libgsl-dev
|
|
46
|
+
python -m pip install --upgrade pip
|
|
47
|
+
pip install pytest .
|
|
48
|
+
pip install surfinBH bhptnrremnant h5py lalsuite
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
- name: Test mergers
|
|
52
|
+
run: python -m pytest tests/test_merger.py -v
|
cbhbd-1.0.0/.gitignore
ADDED
cbhbd-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cbhbd
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A fast code for simulating star cluster and black hole dynamics
|
|
5
|
+
Project-URL: repository, https://github.com/cBHBd/cBHBd
|
|
6
|
+
Author-email: Daniel Marín Pina <daniel.marin@uni-heidelberg.de>, Fabio Antonini <AntoniniF@cardiff.ac.uk>, Fotis Fronimos <fotisfronimos@icc.ub.edu>, Mark Gieles <mgieles@gmail.com>, Nolan Dickson <nolan.dickson@smu.ca>, Vincent Henault-Brunet <Vincent.Henault@smu.ca>
|
|
7
|
+
License-Expression: BSD-3-Clause
|
|
8
|
+
Keywords: bhbdynamics,clusterbh
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Requires-Dist: astro-ssptools
|
|
16
|
+
Requires-Dist: astropy
|
|
17
|
+
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: pandas
|
|
19
|
+
Requires-Dist: scipy
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# ᴄBHBᴅ
|
|
23
|
+
|
|
24
|
+
A fast code for simulating star clusters and black hole dynamics.
|
|
25
|
+
|
|
26
|
+
ᴄBHBᴅ can be used for
|
|
27
|
+
|
|
28
|
+
1) the evolution of a star cluster with black holes in a tidal field
|
|
29
|
+
2) population synthesis of binary black hole mergers in a time-evolving star cluster
|
|
30
|
+
|
|
31
|
+
If you use ᴄBHBᴅ in any publication, please cite it as follows:
|
|
32
|
+
> ᴄBHBᴅ (Antonini & Gieles [2020](https://ui.adsabs.harvard.edu/abs/2020MNRAS.492.2936A/abstract); Antonini et
|
|
33
|
+
> al. [2023](https://ui.adsabs.harvard.edu/abs/2023MNRAS.522..466A/abstract)), with the updates of Fronimos Pouliasis et
|
|
34
|
+
> al. ([2025](https://ui.adsabs.harvard.edu/abs/2026arXiv260528088F/abstract)),
|
|
35
|
+
> Chattopadhyay et al. ([2026](https://ui.adsabs.harvard.edu/abs/2026arXiv260409773C/abstract)), and Marín Pina et al.
|
|
36
|
+
> (in prep)
|
|
37
|
+
|
|
38
|
+
ᴄBHBᴅ stands for the combination of ᴄʟᴜsᴛᴇʀBH (the code for the cluster evolution) and BHBᴅʏɴᴀᴍɪᴄs (the code for the
|
|
39
|
+
black hole mergers).
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
The cBHBd package can be installed directly from this repository using pip:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
python -m pip install git+https://github.com/cBHBd/cBHBd.git
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
All required dependencies will be installed automatically.
|
|
50
|
+
|
|
51
|
+
You can also simply download the ᴄBHBᴅ package source from this repository and install or place it into your path:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
git clone https://github.com/cBHBd/cBHBd
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Running ᴄBHBᴅ
|
|
58
|
+
|
|
59
|
+
You can run ᴄBHBᴅ as
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
from cbhbd.cbhbd import CBHBD
|
|
63
|
+
|
|
64
|
+
c = CBHBD(...)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
with the following arguments:
|
|
68
|
+
|
|
69
|
+
- `N`: Initial number of stars _or_ `M0`: Initial cluster mass
|
|
70
|
+
- `rhoh0`: Initial half-mass density [Msun/pc^3] _or_ `rh0`: Initial half-mass radius [pc]
|
|
71
|
+
- `Z`: Metallicity _or_ `FeH`: Metallicity as in [Fe/H]
|
|
72
|
+
- `kwargs`: Additional parameters to override defaults (see code comments in the `CBHBD` class and the `Cluster` class)
|
|
73
|
+
|
|
74
|
+
If you only want to run the cluster evolution, you can use `compute_mergers=False` for efficiency
|
|
75
|
+
|
|
76
|
+
## Analysing the ᴄBHBᴅ output
|
|
77
|
+
|
|
78
|
+
The output of the simulations is stored in a `CBHBD` object. The cluster properties can be accessed from `c.cluster`.
|
|
79
|
+
See `cluster.py` for the full documentation.
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
c.cluster.Mst # Total stellar mass in the cluster as function of time
|
|
83
|
+
c.cluster.Mbh # Total BH mass in the cluster as function of time
|
|
84
|
+
c.cluster.rh # Half-mass radius of the cluster as function of time
|
|
85
|
+
...
|
|
86
|
+
c.cluster.Mst_interp(t) # For convenience, you can also interpolate the cluster properties at any time using the interpolating functions
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The merger properties are stored in a `pandas.Dataframe` in `c.mergers`. See `mergers.py` for the full documentation.
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
c.mergers # The merger data, use print(c.mergers) to see a table of the merger properties
|
|
93
|
+
c.mergers.m1 # The mass of the primary
|
|
94
|
+
c.mergers.merger_type # The type of merger (ejected, gw_capture, ...), see the code for the full documentation
|
|
95
|
+
...
|
|
96
|
+
c.mergers.to_numpy() # You can also export the merger data to a numpy array
|
|
97
|
+
```
|
|
98
|
+
|
cbhbd-1.0.0/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# ᴄBHBᴅ
|
|
2
|
+
|
|
3
|
+
A fast code for simulating star clusters and black hole dynamics.
|
|
4
|
+
|
|
5
|
+
ᴄBHBᴅ can be used for
|
|
6
|
+
|
|
7
|
+
1) the evolution of a star cluster with black holes in a tidal field
|
|
8
|
+
2) population synthesis of binary black hole mergers in a time-evolving star cluster
|
|
9
|
+
|
|
10
|
+
If you use ᴄBHBᴅ in any publication, please cite it as follows:
|
|
11
|
+
> ᴄBHBᴅ (Antonini & Gieles [2020](https://ui.adsabs.harvard.edu/abs/2020MNRAS.492.2936A/abstract); Antonini et
|
|
12
|
+
> al. [2023](https://ui.adsabs.harvard.edu/abs/2023MNRAS.522..466A/abstract)), with the updates of Fronimos Pouliasis et
|
|
13
|
+
> al. ([2025](https://ui.adsabs.harvard.edu/abs/2026arXiv260528088F/abstract)),
|
|
14
|
+
> Chattopadhyay et al. ([2026](https://ui.adsabs.harvard.edu/abs/2026arXiv260409773C/abstract)), and Marín Pina et al.
|
|
15
|
+
> (in prep)
|
|
16
|
+
|
|
17
|
+
ᴄBHBᴅ stands for the combination of ᴄʟᴜsᴛᴇʀBH (the code for the cluster evolution) and BHBᴅʏɴᴀᴍɪᴄs (the code for the
|
|
18
|
+
black hole mergers).
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
The cBHBd package can be installed directly from this repository using pip:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
python -m pip install git+https://github.com/cBHBd/cBHBd.git
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
All required dependencies will be installed automatically.
|
|
29
|
+
|
|
30
|
+
You can also simply download the ᴄBHBᴅ package source from this repository and install or place it into your path:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
git clone https://github.com/cBHBd/cBHBd
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Running ᴄBHBᴅ
|
|
37
|
+
|
|
38
|
+
You can run ᴄBHBᴅ as
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
from cbhbd.cbhbd import CBHBD
|
|
42
|
+
|
|
43
|
+
c = CBHBD(...)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
with the following arguments:
|
|
47
|
+
|
|
48
|
+
- `N`: Initial number of stars _or_ `M0`: Initial cluster mass
|
|
49
|
+
- `rhoh0`: Initial half-mass density [Msun/pc^3] _or_ `rh0`: Initial half-mass radius [pc]
|
|
50
|
+
- `Z`: Metallicity _or_ `FeH`: Metallicity as in [Fe/H]
|
|
51
|
+
- `kwargs`: Additional parameters to override defaults (see code comments in the `CBHBD` class and the `Cluster` class)
|
|
52
|
+
|
|
53
|
+
If you only want to run the cluster evolution, you can use `compute_mergers=False` for efficiency
|
|
54
|
+
|
|
55
|
+
## Analysing the ᴄBHBᴅ output
|
|
56
|
+
|
|
57
|
+
The output of the simulations is stored in a `CBHBD` object. The cluster properties can be accessed from `c.cluster`.
|
|
58
|
+
See `cluster.py` for the full documentation.
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
c.cluster.Mst # Total stellar mass in the cluster as function of time
|
|
62
|
+
c.cluster.Mbh # Total BH mass in the cluster as function of time
|
|
63
|
+
c.cluster.rh # Half-mass radius of the cluster as function of time
|
|
64
|
+
...
|
|
65
|
+
c.cluster.Mst_interp(t) # For convenience, you can also interpolate the cluster properties at any time using the interpolating functions
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The merger properties are stored in a `pandas.Dataframe` in `c.mergers`. See `mergers.py` for the full documentation.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
c.mergers # The merger data, use print(c.mergers) to see a table of the merger properties
|
|
72
|
+
c.mergers.m1 # The mass of the primary
|
|
73
|
+
c.mergers.merger_type # The type of merger (ejected, gw_capture, ...), see the code for the full documentation
|
|
74
|
+
...
|
|
75
|
+
c.mergers.to_numpy() # You can also export the merger data to a numpy array
|
|
76
|
+
```
|
|
77
|
+
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from . import cluster
|
|
3
|
+
from . import mergers
|
|
4
|
+
from . import remnant
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MergerOutcome:
|
|
8
|
+
# Define all possible merger types
|
|
9
|
+
|
|
10
|
+
InClusterInspiral = "incluster_inspiral"
|
|
11
|
+
GWCaptureBS = "gw_capture_bs"
|
|
12
|
+
GWCaptureBB = "gw_capture_bb"
|
|
13
|
+
Ejected = "ejected"
|
|
14
|
+
GWCaptureDirect = "gw_capture_direct"
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def get_outcomes():
|
|
18
|
+
return [MergerOutcome.InClusterInspiral,
|
|
19
|
+
MergerOutcome.GWCaptureBS,
|
|
20
|
+
MergerOutcome.GWCaptureBB,
|
|
21
|
+
MergerOutcome.Ejected,
|
|
22
|
+
MergerOutcome.GWCaptureDirect]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class CBHBD:
|
|
26
|
+
remnant_models = {k: None for k in remnant.available_remnant_models.keys()}
|
|
27
|
+
|
|
28
|
+
def __init__(self, **kwargs):
|
|
29
|
+
self._run_mergers = mergers._run_mergers
|
|
30
|
+
self._get_IMBH_data = mergers._get_IMBH_data
|
|
31
|
+
|
|
32
|
+
self.tend = 13.8e3 # [Myr] Requested final time for integration. Actual final time can be smaller if e.g. the cluster dissolves
|
|
33
|
+
self.M0 = None # [Msun] Initial mass of the cluster.
|
|
34
|
+
self.N = None # Initial number of stars in the cluster
|
|
35
|
+
self.rh0 = None # [pc] Initial half-mass radius
|
|
36
|
+
self.rhoh0 = None # [Msun/pc^3] Initial density within the half-mass radius
|
|
37
|
+
self.rg = 8 # [kpc] Galactocentric distance of the cluster. For eccentric orbits, consider it as a(1 - e) where a is the semi-major axis, e is eccentricity.
|
|
38
|
+
self.Z = None # Metallicity of the cluster, where Z=0.02 is solar metallicity
|
|
39
|
+
self.FeH = None # Metallicity of the cluster, where FeH=0 is solar metallicity
|
|
40
|
+
|
|
41
|
+
self.Zsolar = 0.02 # Solar metallicity.
|
|
42
|
+
|
|
43
|
+
self.verbose = True # If True, print extra output.
|
|
44
|
+
self.seed = None # Seed for random number generator. Use None to get a random seed.
|
|
45
|
+
self.remnant_model = "RemnantModelVarma19Islam23" # GW remnant model, see remnant.py for available options.
|
|
46
|
+
self.compute_mergers = True # If true, compute the mergers. If false, only compute the cluster model.
|
|
47
|
+
self.ifmr = "sevn-rapid" # IFMR relation to be used if ssp is selected.
|
|
48
|
+
|
|
49
|
+
self.dtout = None # [Myr] Time step for integration. If None, computations are faster.
|
|
50
|
+
self.dense_output = True # Condition for solve_ivp to give continuous solutions. Facilitates interpolation. Can be used instead of specifying t_eval. Necessary if compute_mergers==True.
|
|
51
|
+
self.BH = True # Condition to work with BHs in clusterBH.
|
|
52
|
+
self.ssp = True # Condition to use the SSP tools to extract the BHMF at any moment. Default option uses such tools.
|
|
53
|
+
self.kick = True # Condition to include natal kicks. Affects the BH population obtained. Default option considers kicks.
|
|
54
|
+
|
|
55
|
+
self.output_mergers = False # A Boolean parameter to save the mergers to a file
|
|
56
|
+
self.outfile_mergers = "mergers.txt" # File to save the mergers, if needed.
|
|
57
|
+
|
|
58
|
+
# The user can either specify the initial average mass beforehand, or it is extracted from the IMF.
|
|
59
|
+
# If m0 is not None, the IMF must be well defined so that it matches.
|
|
60
|
+
self.m0 = None # [Msun] Average mass obtained for this particular IMF.
|
|
61
|
+
|
|
62
|
+
# Pass in lists for a_slopes, m_breaks and nbins. Any number of IMF intervals, based on size of lists. m_breaks must be size N + 1.
|
|
63
|
+
|
|
64
|
+
# Slopes of mass function.
|
|
65
|
+
self.a_slopes = [-1.3, -2.3, -2.3]
|
|
66
|
+
self.a_kroupa = self.a_slopes.copy() # In case the user inserts a different set of slopes (and mass breaks), the stellar mass loss rate ν (and time tsev) is different. If ssp is True, this is acoounted, if not, bottom-light IMFs are studied with sev_tune=True.
|
|
67
|
+
|
|
68
|
+
# Mass function break masses.
|
|
69
|
+
self.m_breaks = [0.08, 0.5, 1, 150]
|
|
70
|
+
self.m_kroupa = self.m_breaks.copy() # The user can insert different masses. The slopes and mass breaks of the Kroupa should not change.
|
|
71
|
+
|
|
72
|
+
# Number of bins per interval of the mass function.
|
|
73
|
+
self.nbins = [5, 5, 20]
|
|
74
|
+
|
|
75
|
+
# Valid input parameters. Do not define more input params after this line.
|
|
76
|
+
self.cbhbd_params = [attr for attr in self.__dict__.keys() if attr[0] != "_"]
|
|
77
|
+
|
|
78
|
+
# Read the user's input parameters
|
|
79
|
+
if kwargs is not None:
|
|
80
|
+
for key, value in kwargs.items():
|
|
81
|
+
setattr(self, key, value)
|
|
82
|
+
|
|
83
|
+
assert self.remnant_model in remnant.available_remnant_models, f"Remnant model {self.remnant_model} not available, please choose from {remnant.available_remnant_models.keys()}"
|
|
84
|
+
self._construct_input_params()
|
|
85
|
+
|
|
86
|
+
# Add the unchanged defaults to kwargs, to then pass it to ClusterBH
|
|
87
|
+
for attr, value in self.__dict__.items():
|
|
88
|
+
if attr[0] != "_":
|
|
89
|
+
kwargs[attr] = value
|
|
90
|
+
|
|
91
|
+
# Derived variables
|
|
92
|
+
self.mmin = self.m_breaks[0]
|
|
93
|
+
self.mmax = self.m_breaks[-1]
|
|
94
|
+
|
|
95
|
+
# Output
|
|
96
|
+
self.cluster, self.mergers = None, None
|
|
97
|
+
self.mIMBH, self.chiIMBH, self.genIMBH = None, None, None # Properties of the most massive BH in the cluster.
|
|
98
|
+
self.mIMBHej, self.chiIMBHej, self.genIMBHej = None, None, None # Properties of the most massive BH ejected from the cluster.
|
|
99
|
+
self.bhv = None
|
|
100
|
+
|
|
101
|
+
self._run(**kwargs)
|
|
102
|
+
|
|
103
|
+
def _construct_input_params(self):
|
|
104
|
+
# Construct the mass and IMF
|
|
105
|
+
if (self.M0 is None) == (self.N is None):
|
|
106
|
+
raise ValueError("Please provide either M0 or N. "
|
|
107
|
+
"To change the mean mass, modify the IMF breaks and limits (m_break) or slopes (a_slope)")
|
|
108
|
+
if self.m0 is None:
|
|
109
|
+
self.m0 = cluster.initial_average_mass(self.a_slopes, self.m_breaks)
|
|
110
|
+
if self.M0 is None:
|
|
111
|
+
self.M0 = self.m0 * self.N
|
|
112
|
+
else:
|
|
113
|
+
self.N = self.M0 / self.m0
|
|
114
|
+
|
|
115
|
+
# Construct the half-mass radius and density
|
|
116
|
+
if (self.rh0 is None) == (self.rhoh0 is None):
|
|
117
|
+
raise ValueError("Please provide either rh0 or rhoh0.")
|
|
118
|
+
if self.rhoh0 is None:
|
|
119
|
+
self.rhoh0 = 3 * self.M0 / (8 * np.pi * self.rh0 ** 3)
|
|
120
|
+
else:
|
|
121
|
+
self.rh0 = (3 * self.M0 / (8 * np.pi * self.rhoh0)) ** (1 / 3)
|
|
122
|
+
|
|
123
|
+
# Construct the metallicity
|
|
124
|
+
if (self.Z is None) == (self.FeH is None):
|
|
125
|
+
raise ValueError("Please provide either Z or FeH.")
|
|
126
|
+
if self.Z is None:
|
|
127
|
+
self.Z = self.Zsolar * 10 ** self.FeH
|
|
128
|
+
else:
|
|
129
|
+
self.FeH = np.log10(self.Z / self.Zsolar)
|
|
130
|
+
|
|
131
|
+
# General sanity checks
|
|
132
|
+
assert self.rh0 > 0
|
|
133
|
+
assert self.rhoh0 > 0
|
|
134
|
+
assert self.M0 > 0
|
|
135
|
+
assert self.N > 0
|
|
136
|
+
if self.compute_mergers:
|
|
137
|
+
assert self.ssp, "Mergers are only available when SSP is enabled"
|
|
138
|
+
assert self.BH, "Mergers are only available when BHs are enabled"
|
|
139
|
+
assert self.dense_output, "Mergers are only available when dense_output is enabled"
|
|
140
|
+
|
|
141
|
+
def _run(self, **kwargs):
|
|
142
|
+
self.cluster = cluster.Cluster(**kwargs)
|
|
143
|
+
|
|
144
|
+
if self.compute_mergers:
|
|
145
|
+
try:
|
|
146
|
+
self.mergers = self._run_mergers(self)
|
|
147
|
+
self._get_IMBH_data(self)
|
|
148
|
+
if self.output_mergers:
|
|
149
|
+
self.mergers.to_csv(self.outfile_mergers, header=True, index=False)
|
|
150
|
+
except Exception as err:
|
|
151
|
+
print("Error in computing the mergers in model with", flush=True)
|
|
152
|
+
print(f"\t Mass = {self.M0} M_sun", flush=True)
|
|
153
|
+
print(f"\t Metallicity = {self.Z}", flush=True)
|
|
154
|
+
print(f"\t Final time = {self.tend} Myr", flush=True)
|
|
155
|
+
print(f"\t Initial density = {self.rhoh0:.3g} M_sun/pc^3", flush=True)
|
|
156
|
+
print(f"\t IFMR model = {self.ifmr}", flush=True)
|
|
157
|
+
print(f"\t Seed = {self.seed}", flush=True)
|
|
158
|
+
print(err, flush=True)
|
|
159
|
+
raise err
|