Custom population synthesis
The modularity of the POSYDON code allows the user to easily change
the default evolutionary tree dictated by the flow chart tree. The flow
chart tree is a list of 4D points composed of binary.star_1.state,
binary.star_2.state, binary.state, binary.event
which map to a corresponding
evolutionary step. Here we show how the user can replace part or the entire
POSYDON flow chart tree and customize the evolution with user specified
steps.
Custom step
The user can develop a POSYDON
step which is a python class with a
__call__
method which updates the current properties of the binary objects
(see reference binary object). As an example, let’s create our own treatment
for a common envelope. For simplicity sake we will halve the orbital separation
and set the post-CE donor star mass to the star’s helium core mass.
from posydon.utils import common_functions as cf
class my_CE_step(object):
"""Compute a fake CE event."""
def __init__(self, verbose):
self.verbose = verbose
def __call__(self, binary):
if self.verbose:
print('The orbital separation post CE is half the pre CE orbital separation!')
# Determine which star is the donor and which is the companion
if binary.event in ["oCE1", "oDoubleCE1"]:
donor_star = binary.star_1
comp_star = binary.star_2
elif binary.event in ["oCE2", "oDoubleCE2"]:
donor_star = binary.star_2
comp_star = binary.star_1
else:
raise ValueError("CEE does not apply if `event` is not "
"`oCE1`, 'oDoubleCE1' or `oCE2`, 'oDoubleCE1'")
binary.separation /= 2.
m1 = donor_star.he_core_mass
m2 = comp_star.mass
binary.separation = cf.orbital_period_from_separation(binary.separation, m1, m2)
The new custom step can be used by importing the new function into the simulation properties as follows (see ref. the POSYDON API)
from custom_CE_step import my_CE_step
CE_STEP = dict(verbose=False)
# pass the simulation properties to each step
sim_kwargs = dict(
flow = (flow_chart, {}),
step_HMS_HMS = (MS_MS_step, MESA_STEP),
step_CO_HeMS = (CO_HeMS_step, MESA_STEP),
step_CO_HMS_RLO = (CO_HMS_RLO_step, MESA_STEP),
step_detached = (detached_step, DETACHED_STEP),
step_CE = (my_CE_step, CE_STEP), # <--- WE ONLY EDITED THIS LINE HERE
step_SN = (StepSN, SN_STEP),
step_dco = (DoubleCO, DCO_STEP),
step_end = (step_end, END_STEP),
extra_hooks = [(StepNamesHooks, {})]
)
Custom flow charts
Let us now see how one can alter the default flow chart links. Let us assume
that you have a custom step that maps the evolution of Roche lobe overflowing
HMS-HeMS binaries called HMS_HeMS_RLO_step
. With the CHANGE_FLOW_CHART
option of the flow_chart
method we can replace the the tree links which
are currently mapped to the step_end
as follows.
from posydon.binary_evol.flow_chart import flow_chart, POSYDON_FLOW_CHART, STAR_STATES_H_RICH, STAR_STATES_HE_RICH
NEW_FLOW_CHART_LINKS = {}
for s1 in STAR_STATES_H_RICH:
for s2 in STAR_STATES_HE_RICH:
NEW_FLOW_CHART_LINKS[(s1, s2, 'RLO1', 'oRLO1')] = 'step_HMS_HeMS_RLO'
NEW_FLOW_CHART_LINKS[(s2, s1, 'RLO2', 'oRLO2')] = 'step_HMS_HeMS_RLO'
new_flow_chart = flow_chart(FLOW_CHART=POSYDON_FLOW_CHART, CHANGE_FLOW_CHART=NEW_FLOW_CHART_LINKS)
We can load the new flow chart into the simulation properties as.
from custom_HMS_HeMS_step import HMS_HeMS_RLO_step
HMS_HeMS_RLO_STEP = dict(verbose=False)
sim_kwargs = dict(
flow = (new_flow_chart, {}), # <--- WE ONLY EDITED THIS LINE HERE
step_HMS_HMS = (MS_MS_step, MESA_STEP),
step_CO_HeMS = (CO_HeMS_step, MESA_STEP),
step_CO_HMS_RLO = (CO_HMS_RLO_step, MESA_STEP),
step_HMS_HeMS_RLO = (HMS_HeMS_RLO_step, HMS_HeMS_RLO_STEP), # ADD NEW STEP HERE
step_detached = (detached_step, DETACHED_STEP),
step_CE = (StepCEE, CE_STEP),
step_SN = (StepSN, SN_STEP),
step_dco = (DoubleCO, DCO_STEP),
step_end = (step_end, END_STEP),
extra_hooks = [(StepNamesHooks, {})]
)