"""Merging and isolated evolution step."""
__authors__ = [
"Emmanouil Zapartas <ezapartas@gmail.com>",
"Simone Bavera <Simone.Bavera@unige.ch>",
"Konstantinos Kovlakas <Konstantinos.Kovlakas@unige.ch>"
]
import numpy as np
from posydon.utils.data_download import PATH_TO_POSYDON_DATA
from posydon.binary_evol.singlestar import STARPROPERTIES, convert_star_to_massless_remnant
from posydon.utils.common_functions import check_state_of_star
from posydon.binary_evol.DT.step_isolated import IsolatedStep
from posydon.utils.posydonerror import FlowError
from posydon.utils.posydonwarning import Pwarn
from posydon.binary_evol.flow_chart import (
STAR_STATES_H_RICH,
STAR_STATES_HE_RICH,
STAR_STATES_NOT_CO
)
LIST_ACCEPTABLE_STATES_FOR_HMS = ["H-rich_Core_H_burning"]
LIST_ACCEPTABLE_STATES_FOR_HeMS = ["stripped_He_Core_He_burning"]
LIST_ACCEPTABLE_STATES_FOR_POSTMS = STAR_STATES_H_RICH.copy()
[LIST_ACCEPTABLE_STATES_FOR_POSTMS.remove(x) for x in LIST_ACCEPTABLE_STATES_FOR_HMS]
LIST_ACCEPTABLE_STATES_FOR_POSTHeMS = STAR_STATES_HE_RICH.copy()
[LIST_ACCEPTABLE_STATES_FOR_POSTHeMS.remove(x) for x in LIST_ACCEPTABLE_STATES_FOR_HeMS]
[docs]
class MergedStep(IsolatedStep):
"""
Prepare a merging star to do an an IsolatedStep
"""
def __init__(
self,
grid_name_Hrich=None,
grid_name_strippedHe=None,
path=PATH_TO_POSYDON_DATA,
merger_critical_rot = 0.4,
rel_mass_lost_HMS_HMS = 0.1,
list_for_matching_HMS = [
["mass", "center_h1", "he_core_mass"],
[20.0, 1.0, 10.0],
["log_min_max", "min_max", "min_max"],
#[m_min_H, m_max_H], [0, None]
[None, None], [0, None]
],
list_for_matching_postMS = [
["mass", "center_he4", "he_core_mass"],
[20.0, 1.0, 10.0],
["log_min_max", "min_max", "min_max"],
#[m_min_H, m_max_H], [0, None]
[None, None], [0, None]
],
list_for_matching_HeStar = [
["he_core_mass", "center_he4"],
[10.0, 1.0],
["min_max" , "min_max"],
#[[m_min_He, m_max_He], [0, None]],
[None, None], [0, None]
],
*args,
**kwargs
):
self.merger_critical_rot = merger_critical_rot
self.rel_mass_lost_HMS_HMS = rel_mass_lost_HMS_HMS
super().__init__(
grid_name_Hrich=grid_name_Hrich,
grid_name_strippedHe=grid_name_strippedHe,
list_for_matching_HMS = list_for_matching_HMS,
list_for_matching_postMS = list_for_matching_postMS,
list_for_matching_HeStar = list_for_matching_HeStar,
*args,
**kwargs)
def __call__(self,binary):
merged_star_properties = self.merged_star_properties
if self.verbose:
print("Before Merger", binary.star_1.state,binary.star_2.state,binary.state, binary.event)
print("M1 , M2, he_core_mass1, he_core_mass2: ", binary.star_1.mass,binary.star_2.mass, binary.star_1.he_core_mass, binary.star_2.he_core_mass)
print("star_1.center_he4, star_2.center_he4, star_1.surface_he4, star_2.surface_he4: ", binary.star_1.center_he4,binary.star_2.center_he4, binary.star_1.surface_he4,binary.star_2.surface_he4)
if binary.state == "merged":
if binary.event == 'oMerging1':
binary.star_1, binary.star_2 = merged_star_properties(binary.star_1, binary.star_2)
elif binary.event == 'oMerging2':
binary.star_2, binary.star_1 = merged_star_properties(binary.star_2, binary.star_1)
else:
raise ValueError("binary.state='merged' but binary.event != 'oMerging1/2'")
## assume that binaries in RLO with two He-rich stars always merge
elif binary.star_1.state in STAR_STATES_HE_RICH and binary.star_2.state in STAR_STATES_HE_RICH:
binary.state = "merged"
if binary.event == 'oRLO1':
binary.star_1, binary.star_2 = merged_star_properties(binary.star_1, binary.star_2)
elif binary.event == 'oRLO2':
binary.star_2, binary.star_1 = merged_star_properties(binary.star_2, binary.star_1)
else:
raise ValueError("step_merged initiated for He stars but RLO not initiated")
else:
raise ValueError("step_merged initiated but binary is not in valid merging state!")
binary.event = None
if self.verbose:
print("After Merger", binary.star_1.state,binary.star_2.state,binary.state, binary.event)
print("M_merged , he_core_mass merged: ", binary.star_1.mass, binary.star_1.he_core_mass)
print("star_1.center_he4, star_1.surface_he4: ", binary.star_1.center_he4, binary.star_1.surface_he4)
super().__call__(binary)
[docs]
def merged_star_properties(self,star_base,comp):
"""
Make assumptions about the core/total mass, and abundances of the star of a merged product.
Similar to the table of merging in BSE
star_base: Single Star
is our base star that engulfs its companion. The merged star will have this star as a base
comp: Single Star
is the star that is engulfed
"""
#by default the stellar attributes that keep the same value from the
#merged_star = copy.copy(star_base)
merged_star = star_base
s1 = star_base.state
s2 = comp.state
def mass_weighted_avg(star1=star_base,star2=comp, abundance_name="center_h1", mass_weight1="mass", mass_weight2=None):
A1 = getattr(star1, abundance_name)
A2 = getattr(star2, abundance_name)
if mass_weight1 == "H-rich_envelope_mass":
M1 = getattr(star1, "mass") - getattr(star1, "he_core_mass")
elif mass_weight1 == "He-rich_envelope_mass":
M1 = getattr(star1, "he_core_mass") - getattr(star1, "co_core_mass")
else:
M1 = getattr(star1, mass_weight1)
if mass_weight2 is None:
mass_weight2 = mass_weight1
if mass_weight2 == "H-rich_envelope_mass":
M2 = getattr(star2, "mass") - getattr(star2, "he_core_mass")
elif mass_weight2 == "He-rich_envelope_mass":
M2 = getattr(star2, "he_core_mass") - getattr(star2, "co_core_mass")
else:
M2 = getattr(star2, mass_weight2)
return (A1*M1 + A2*M2 ) / (M1+M2)
# MS + MS
if ( s1 in LIST_ACCEPTABLE_STATES_FOR_HMS
and s2 in LIST_ACCEPTABLE_STATES_FOR_HMS):
#these stellar attributes change value
merged_star.mass = (star_base.mass + comp.mass) * (1.-self.rel_mass_lost_HMS_HMS)
#TODO for key in ["center_h1", "center_he4", "center_c12", "center_n14","center_o16"]:
merged_star.center_h1 = mass_weighted_avg()
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16")
#TODO: should I check if the abundaces above end up in ~1 (?)
# weigheted mixing on the surface abundances
merged_star.surface_h1 = mass_weighted_avg(abundance_name = "surface_h1")
merged_star.surface_he4 = mass_weighted_avg(abundance_name = "surface_he4")
merged_star.surface_c12 = mass_weighted_avg(abundance_name = "surface_c12")
merged_star.surface_n14 = mass_weighted_avg(abundance_name = "surface_n14")
merged_star.surface_o16 = mass_weighted_avg(abundance_name = "surface_o16")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin", "envelope_binding_energy"]:
setattr(merged_star, key, np.nan)
massless_remnant = convert_star_to_massless_remnant(comp)
#postMS + MS
elif (s1 in LIST_ACCEPTABLE_STATES_FOR_POSTMS
and s2 in LIST_ACCEPTABLE_STATES_FOR_HMS):
merged_star.mass = star_base.mass + comp.mass #TODO: in step_CEE we need to eject part of the (common) envelope
# weigheted mixing on the surface abundances of the whole comp with the envelope of star_base
merged_star.surface_h1 = mass_weighted_avg(abundance_name = "surface_h1", mass_weight1="H-rich_envelope_mass", mass_weight2="mass")
merged_star.surface_he4 = mass_weighted_avg(abundance_name = "surface_he4", mass_weight1="H-rich_envelope_mass", mass_weight2="mass")
merged_star.surface_c12 = mass_weighted_avg(abundance_name = "surface_c12", mass_weight1="H-rich_envelope_mass", mass_weight2="mass")
merged_star.surface_n14 = mass_weighted_avg(abundance_name = "surface_n14", mass_weight1="H-rich_envelope_mass", mass_weight2="mass")
merged_star.surface_o16 = mass_weighted_avg(abundance_name = "surface_o16", mass_weight1="H-rich_envelope_mass", mass_weight2="mass")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.log_LHe = star_base.log_LHe
merged_star.log_LZ = star_base.log_LZ
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(comp)
# as above but opposite stars
elif (s1 in LIST_ACCEPTABLE_STATES_FOR_HMS
and s2 in LIST_ACCEPTABLE_STATES_FOR_POSTMS):
merged_star = comp
merged_star.mass = star_base.mass + comp.mass
merged_star.surface_h1 = mass_weighted_avg(abundance_name = "surface_h1", mass_weight2="H-rich_envelope_mass", mass_weight1="mass")
merged_star.surface_he4 = mass_weighted_avg(abundance_name = "surface_he4", mass_weight2="H-rich_envelope_mass", mass_weight1="mass")
merged_star.surface_c12 = mass_weighted_avg(abundance_name = "surface_c12", mass_weight2="H-rich_envelope_mass", mass_weight1="mass")
merged_star.surface_n14 = mass_weighted_avg(abundance_name = "surface_n14", mass_weight2="H-rich_envelope_mass", mass_weight1="mass")
merged_star.surface_o16 = mass_weighted_avg(abundance_name = "surface_o16", mass_weight2="H-rich_envelope_mass", mass_weight1="mass")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.log_LHe = comp.log_LHe
merged_star.log_LZ = comp.log_LZ
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(star_base)
#postMS + postMS
elif (s1 in LIST_ACCEPTABLE_STATES_FOR_POSTMS
and s2 in LIST_ACCEPTABLE_STATES_FOR_POSTMS):
# add total and core masses
for key in ["mass", "he_core_mass", "c_core_mass", "o_core_mass", "co_core_mass"]:
current = getattr(merged_star, key) + getattr(comp, key)
setattr(merged_star, key,current)
# weighted central abundances if merging cores. Else only from star_base
if star_base.co_core_mass == 0 and comp.co_core_mass == 0: # two stars with Helium cores
merged_star.center_h1 = mass_weighted_avg(mass_weight1="he_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="he_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="he_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="he_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="he_core_mass")
elif (star_base.co_core_mass > 0 and comp.co_core_mass == 0): # star_base with CO core and the comp has a He core
pass # the central abundances are kept as the ones of star_base
elif (comp.co_core_mass > 0 and star_base.co_core_mass == 0): # comp with CO core and the star_base has a He core
merged_star.center_h1 = comp.center_h1
merged_star.center_he4 = comp.center_he4
merged_star.center_c12 = comp.center_c12
merged_star.center_n14 = comp.center_n14
merged_star.center_o16 = comp.center_o16
elif (star_base.co_core_mass > 0 and comp.co_core_mass > 0):
merged_star.center_h1 = mass_weighted_avg(mass_weight1="co_core_mass") #TODO : maybe he_core_mass makes more sense?
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="co_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="co_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="co_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="co_core_mass")
else:
Pwarn("weird compbination of CO core masses during merging", "EvolutionWarning")
# weigheted mixing on the surface abundances based on the envelopes of the two stars
merged_star.surface_h1 = mass_weighted_avg(abundance_name = "surface_h1", mass_weight1="H-rich_envelope_mass", mass_weight2="H-rich_envelope_mass")
merged_star.surface_he4 = mass_weighted_avg(abundance_name = "surface_he4", mass_weight1="H-rich_envelope_mass", mass_weight2="H-rich_envelope_mass")
merged_star.surface_c12 = mass_weighted_avg(abundance_name = "surface_c12", mass_weight1="H-rich_envelope_mass", mass_weight2="H-rich_envelope_mass")
merged_star.surface_n14 = mass_weighted_avg(abundance_name = "surface_n14", mass_weight1="H-rich_envelope_mass", mass_weight2="H-rich_envelope_mass")
merged_star.surface_o16 = mass_weighted_avg(abundance_name = "surface_o16", mass_weight1="H-rich_envelope_mass", mass_weight2="H-rich_envelope_mass")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(comp)
#postMS + HeMSStar
elif (s1 in LIST_ACCEPTABLE_STATES_FOR_POSTMS
and s2 in LIST_ACCEPTABLE_STATES_FOR_HeMS):
# add total and core masses
for key in ["mass", "he_core_mass", "c_core_mass", "o_core_mass", "co_core_mass"]:
current = getattr(merged_star, key) + getattr(comp, key)
setattr(merged_star, key,current)
# weighted central abundances if merging cores. Else only from star_base
if star_base.co_core_mass == 0 and comp.co_core_mass == 0: # two stars with only Helium cores, not CO cores
merged_star.center_h1 = mass_weighted_avg(mass_weight1="he_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="he_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="he_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="he_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="he_core_mass")
elif (star_base.co_core_mass > 0 and comp.co_core_mass == 0): # star_base with CO core and the comp has just a He core (is a HeMS star)
pass # the central abundances are kept as the ones of star_base
else:
Pwarn("weird compbination of CO core masses during merging", "EvolutionWarning")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(comp)
# as above but opposite stars
elif (s1 in LIST_ACCEPTABLE_STATES_FOR_HeMS
and s2 in LIST_ACCEPTABLE_STATES_FOR_POSTMS):
merged_star = comp
# add total and core masses
for key in ["mass", "he_core_mass", "c_core_mass", "o_core_mass", "co_core_mass"]:
current = getattr(merged_star, key) + getattr(star_base, key)
setattr(merged_star, key,current)
# weighted central abundances if merging cores. Else only from star_base
if star_base.co_core_mass == 0 and comp.co_core_mass == 0: # two stars with only Helium cores, not CO cores
merged_star.center_h1 = mass_weighted_avg(mass_weight1="he_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="he_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="he_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="he_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="he_core_mass")
elif (star_base.co_core_mass == 0 and comp.co_core_mass > 0): # star_base is the HeMS Star and comp has a CO core
pass # the central abundances are kept as the ones of star_base
else:
Pwarn("weird compbination of CO core masses during merging", "EvolutionWarning")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(star_base)
#postMS + HeStar that is not in HeMS
elif (s1 in LIST_ACCEPTABLE_STATES_FOR_POSTMS
and s2 in LIST_ACCEPTABLE_STATES_FOR_POSTHeMS):
# add total and core masses
for key in ["mass", "he_core_mass", "c_core_mass", "o_core_mass", "co_core_mass"]:
current = getattr(merged_star, key) + getattr(comp, key)
setattr(merged_star, key,current)
# weighted central abundances if merging cores. Else only from star_base
if star_base.co_core_mass == 0 and comp.co_core_mass == 0: # two stars with Helium cores
merged_star.center_h1 = mass_weighted_avg(mass_weight1="he_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="he_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="he_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="he_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="he_core_mass")
elif (star_base.co_core_mass > 0 and comp.co_core_mass == 0): # star_base with CO core and the comp has a He core
pass # the central abundances are kept as the ones of star_base
elif (comp.co_core_mass > 0 and star_base.co_core_mass == 0): # comp with CO core and the star_base has a He core
merged_star.center_h1 = comp.center_h1
merged_star.center_he4 = comp.center_he4
merged_star.center_c12 = comp.center_c12
merged_star.center_n14 = comp.center_n14
merged_star.center_o16 = comp.center_o16
elif (star_base.co_core_mass > 0 and comp.co_core_mass > 0):
merged_star.center_h1 = mass_weighted_avg(mass_weight1="co_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="co_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="co_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="co_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="co_core_mass")
else:
Pwarn("weird compbination of CO core masses during merging", "EvolutionWarning")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(comp)
# as above but the opposite stars
elif (s1 in LIST_ACCEPTABLE_STATES_FOR_POSTHeMS
and s2 in LIST_ACCEPTABLE_STATES_FOR_POSTMS):
merged_star = comp
# add total and core masses
for key in ["mass", "he_core_mass", "c_core_mass", "o_core_mass", "co_core_mass"]:
current = getattr(merged_star, key) + getattr(star_base, key)
setattr(merged_star, key,current)
# weighted central abundances if merging cores. Else only from star_base
if star_base.co_core_mass == 0 and comp.co_core_mass == 0: # two stars with Helium cores
merged_star.center_h1 = mass_weighted_avg(mass_weight1="he_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="he_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="he_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="he_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="he_core_mass")
elif (star_base.co_core_mass > 0 and comp.co_core_mass == 0): # star_base with CO core and the comp has a He core
pass # the central abundances are kept as the ones of star_base
elif (comp.co_core_mass > 0 and star_base.co_core_mass == 0): # comp with CO core and the star_base has a He core
merged_star.center_h1 = comp.center_h1
merged_star.center_he4 = comp.center_he4
merged_star.center_c12 = comp.center_c12
merged_star.center_n14 = comp.center_n14
merged_star.center_o16 = comp.center_o16
elif (star_base.co_core_mass > 0 and comp.co_core_mass > 0):
merged_star.center_h1 = mass_weighted_avg(mass_weight1="co_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="co_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="co_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="co_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="co_core_mass")
else:
Pwarn("weird compbination of CO core masses during merging", "EvolutionWarning")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(star_base)
# HeStar + HeStar
elif (s1 in STAR_STATES_HE_RICH
and s2 in STAR_STATES_HE_RICH):
# add total and core masses
for key in ["mass", "he_core_mass", "c_core_mass", "o_core_mass", "co_core_mass"]:
current = getattr(merged_star, key) + getattr(comp, key)
setattr(merged_star, key,current)
# weighted central abundances if merging cores. Else only from star_base
if star_base.co_core_mass == 0 and comp.co_core_mass == 0: # two stars with Helium cores
merged_star.center_h1 = mass_weighted_avg(mass_weight1="he_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="he_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="he_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="he_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="he_core_mass")
elif (star_base.co_core_mass > 0 and comp.co_core_mass == 0): # star_base with CO core and the comp has a He core
pass # the central abundances are kept as the ones of star_base
elif (comp.co_core_mass > 0 and star_base.co_core_mass == 0): # comp with CO core and the star_base has a He core
merged_star.center_h1 = comp.center_h1
merged_star.center_he4 = comp.center_he4
merged_star.center_c12 = comp.center_c12
merged_star.center_n14 = comp.center_n14
merged_star.center_o16 = comp.center_o16
elif (star_base.co_core_mass > 0 and comp.co_core_mass > 0):
merged_star.center_h1 = mass_weighted_avg(mass_weight1="co_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="co_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="co_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="co_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="co_core_mass")
else:
Pwarn("weird compbination of CO core masses during merging", "EvolutionWarning")
# weigheted mixing on the surface abundances based on the He-rich envelopes of the two stars
merged_star.surface_h1 = mass_weighted_avg(abundance_name = "surface_h1", mass_weight1="He-rich_envelope_mass", mass_weight2="He-rich_envelope_mass")
merged_star.surface_he4 = mass_weighted_avg(abundance_name = "surface_he4", mass_weight1="He-rich_envelope_mass", mass_weight2="He-rich_envelope_mass")
merged_star.surface_c12 = mass_weighted_avg(abundance_name = "surface_c12", mass_weight1="He-rich_envelope_mass", mass_weight2="He-rich_envelope_mass")
merged_star.surface_n14 = mass_weighted_avg(abundance_name = "surface_n14", mass_weight1="He-rich_envelope_mass", mass_weight2="He-rich_envelope_mass")
merged_star.surface_o16 = mass_weighted_avg(abundance_name = "surface_o16", mass_weight1="He-rich_envelope_mass", mass_weight2="He-rich_envelope_mass")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(comp)
# Star + WD
elif (s1 in STAR_STATES_NOT_CO
and s2 in ["WD"]):
#WD is considered a stripped CO core
# add total and core masses
for key in ["mass", "he_core_mass", "c_core_mass", "o_core_mass", "co_core_mass"]:
current = getattr(merged_star, key) + getattr(comp, "mass")
setattr(merged_star, key,current)
# weighted central abundances if merging cores. Else only from star_base
if (comp.co_core_mass > 0 and star_base.co_core_mass == 0): # comp with CO core and the star_base has not
merged_star.center_h1 = comp.center_h1
merged_star.center_he4 = comp.center_he4
merged_star.center_c12 = comp.center_c12
merged_star.center_n14 = comp.center_n14
merged_star.center_o16 = comp.center_o16
elif (star_base.co_core_mass > 0 and comp.co_core_mass > 0):
merged_star.center_h1 = mass_weighted_avg(mass_weight1="co_core_mass")
merged_star.center_he4 = mass_weighted_avg(abundance_name = "center_he4", mass_weight1="co_core_mass")
merged_star.center_c12 = mass_weighted_avg(abundance_name = "center_c12", mass_weight1="co_core_mass")
merged_star.center_n14 = mass_weighted_avg(abundance_name = "center_n14", mass_weight1="co_core_mass")
merged_star.center_o16 = mass_weighted_avg(abundance_name = "center_o16", mass_weight1="co_core_mass")
else:
Pwarn("weird compbination of CO core masses during merging", "EvolutionWarning")
for key in STARPROPERTIES:
# these stellar attributes become np.nan
for substring in ["log_", "lg_", "surf_", "conv_", "lambda", "profile"]:
if (substring in key) :
setattr(merged_star, key, np.nan)
if key in [ "c12_c12", "center_gamma",
"avg_c_in_c_core", "total_moment_of_inertia", "spin"]:
setattr(merged_star, key, np.nan)
merged_star.state = check_state_of_star(merged_star, star_CO=False) # TODO for sure this needs testing!
massless_remnant = convert_star_to_massless_remnant(comp)
# Star + NS/BH
elif (s1 in STAR_STATES_NOT_CO
and s2 in ["NS", "BH"]):
merged_star = comp
# TODO: potentially flag a Thorne-Zytkov object
massless_remnant = convert_star_to_massless_remnant(star_base)
## in this case, want CO companion object to stay the same, and base star to be assigned massless remnant
return massless_remnant, merged_star
else:
print("Combination of merging star states not expected: ", s1, s2)
# ad hoc spin of merged star to be used in the detached step
merged_star.surf_avg_omega_div_omega_crit = self.merger_critical_rot
return merged_star, massless_remnant