def interactions_decay_products(cls, interactions_primary=None, interactions_SM=None, muon_dec=False, neutrinos=None, leptons=None, mesons=None, photon=None, kind=None): if kind in [CollisionIntegralKind.F_1_vacuum_decay, CollisionIntegralKind.F_f_vacuum_decay]: kind_creation = CollisionIntegralKind.F_1_vacuum_decay kind_decay = CollisionIntegralKind.F_f_vacuum_decay else: kind_creation = CollisionIntegralKind.F_creation kind_decay = CollisionIntegralKind.F_decay interactions = [] primary_mesons = [] species = Counter() for main in interactions_primary: for inter in main: for integral in inter.integrals: species.update(Counter(item.specie.name for item in integral.reaction if item.side == 1)) if species['Muon'] and not muon_dec or species['Tau']: interactions += SMI.lepton_interactions( leptons=leptons, neutrinos=neutrinos, # SM_inters=already_there(interactions_SM, ['Muon', 'Tau']), kind=kind ) if mesons: for meson in mesons: if species[meson.name]: primary_mesons.append(meson) if muon_dec: species['Muon'] += 1 if primary_mesons: interactions += SMI.meson_interactions( primary_mesons=primary_mesons, mesons=mesons, leptons=leptons, neutrinos=neutrinos, photon=photon, muon_tau=[species['Muon'], species['Tau']], kind=kind ) for inter in interactions: inter.integrals = [integral for integral in inter.integrals \ if utils.reaction_type(integral).CREATION or utils.reaction_type(integral).DECAY] for integral in inter.integrals: if utils.reaction_type(integral).CREATION: integral.kind = kind_creation else: integral.kind = kind_decay return interactions
def Icoll_fast_decay(particle, ps): F1s = [] Ffs = [] Ffs_temp = [] dofs = [] for integral in particle.collision_integrals: F1, Ff = integral.integrate(ps, stepsize=particle.params.h) F1s.append(F1) Ffs_temp.append(Ff) dofs.append(particle.dof if particle.majorana else particle.dof / 2) distr_backg = particle.equilibrium_distribution(conf_mass=particle.mass * particle.aT / particle.decoupling_temperature)\ * np.exp(-(particle.params.t - particle.t_decoupling) / particle.lifetime) if particle.thermal_dyn else np.zeros(len(ps)) if hasattr(particle, 'thermalization'): distr_ini = distr_backg + sum(F1s) * particle.params.h distr_bef = distr_backg + simps(sum(F1s) * particle.grid.TEMPLATE**2, particle.grid.TEMPLATE) * particle.params.h \ / (2 * np.pi * particle.conformal_mass * particle.aT)**(3/2) \ * np.exp(-particle.grid.TEMPLATE**2 / (2 * particle.conformal_mass * particle.aT)) else: distr_bef = distr_backg + sum(F1s) * particle.params.h particle.num_creation = simps( sum(F1s * np.array(dofs)[:, None]) * particle.grid.TEMPLATE**2, particle.grid.TEMPLATE) for index, Ff in enumerate(Ffs_temp): integral = particle.collision_integrals[index] if utils.reaction_type(integral.reaction).DECAY: # line not necessary sym = ''.join( [item.specie.symbol for item in integral.reaction[1:]]) for key in integral.reaction[0].specie.BR: if Counter(sym) == Counter(key): BR = integral.reaction[0].specie.BR[key] dof = particle.dof if particle.majorana else particle.dof / 2 decayed = simps( -1 * distr_bef * Ff * dof * particle.grid.TEMPLATE**2, particle.grid.TEMPLATE) if decayed == 0.: Ffs.append(np.zeros(len(Ff))) else: scaling = BR * particle.num_creation / decayed Ffs.append(scaling * Ff * distr_bef) else: Ffs.append(Ff * distr_bef) if hasattr(particle, 'thermalization'): coll_creation_th = sum(F1s) coll_thermalization_th = (distr_bef - distr_ini) / particle.params.h coll_decay_th = sum(Ffs) coll_integral_th = coll_creation_th + coll_thermalization_th + coll_decay_th particle._distribution = distr_bef return coll_integral_th coll_creation = sum(F1s) coll_decay = sum(Ffs) coll_integral = coll_creation + coll_decay particle._distribution = distr_bef return coll_integral
def grid_cutoff_3p(interaction, ps): slice_1 = [] slice_3 = [] if utils.reaction_type(interaction).CREATION: slice_1, slice_2, slice_3 = three_particle_grid_bounds_creation( interaction.reaction) if not slice_2.any(): return False ps = slice_2 / interaction.particle.params.aT return ps, slice_1, slice_3
def grid_cutoff_4p(interaction): # Cut off grid for creation reactions if utils.reaction_type(interaction).CREATION: slice_1, slice_2 = four_particle_grid_cutoff_creation( interaction.reaction) ps = slice_1 / interaction.particle.params.aT # Cut off grid for scattering reactions if utils.reaction_type(interaction).SCATTERING: slice_1, slice_2 = four_particle_grid_cutoff_scattering( interaction.particle) ps = slice_1 / interaction.particle.params.aT # Cut off grid for decay reactions if utils.reaction_type(interaction).DECAY: slice_1, slice_2 = four_particle_grid_cutoff_decay( interaction.particle) ps = slice_1 / interaction.particle.params.aT return ps, slice_1, slice_2
def CollisionMultiplier3p(interaction): if 'Sterile neutrino (Dirac)' in [item.specie.name for item in interaction.reaction] or \ utils.reaction_type(interaction).CREATION and not \ (interaction.reaction[2].specie.majorana and interaction.particle.Q): left = Counter(item.specie for item in interaction.reaction if item.side == -1) right = Counter(item.specie for item in interaction.reaction if item.side == 1) if left[interaction.reaction[0].specie] == 2 and right[ interaction.reaction[0].specie] == 0: return 2. return 1.
def Neglect4pInteraction(interaction, ps): # If particle has decayed, don't calculate creation integrals for decay products if utils.reaction_type( interaction).CREATION and interaction.reaction[-1].specie.decayed: return True # If particles have diluted to such extent that they can be neglected scat_thr = 1e-10 * (interaction.particle.params.a_ini / 10)**3 if utils.reaction_type(interaction).SCATTERING and (interaction.reaction[0].specie.density / interaction.reaction[0].specie.data['params']['density'][0] < scat_thr\ or interaction.reaction[1].specie.density / interaction.reaction[1].specie.data['params']['density'][0] < scat_thr)\ and (interaction.reaction[2].specie.density / interaction.reaction[2].specie.data['params']['density'][0] < scat_thr or\ interaction.reaction[3].specie.density / interaction.reaction[3].specie.data['params']['density'][0] < scat_thr): return True #TODO: Improve this (zero initial density etc) # If there are no muons/mesons created yet, skip creation and decay reactions if utils.reaction_type(interaction).CREATION and hasattr(interaction.reaction[-1].specie, 'fast_decay') and interaction.reaction[-1].specie.num_creation == 0\ or utils.reaction_type(interaction).DECAY and hasattr(interaction.reaction[0].specie, 'fast_decay') and interaction.reaction[0].specie.num_creation == 0: return True # Decoupling of scattering reactions involving HNL if utils.reaction_type(interaction).SCATTERING and any(item.specie.name == 'Sterile neutrino (Dirac)' for item in interaction.reaction)\ and (environment.get('Relativistic_decoupling') and interaction.particle.params.T < interaction.particle.params.m / interaction.particle.params.a_ini / 15. or interaction.particle.params.T < 1. * UNITS.MeV): return True # If temperature is higher than HNL mass, skip decay reaction to prevent incorrect computation of collision integral if utils.reaction_type( interaction ).DECAY and interaction.particle.name == 'Sterile neutrino (Dirac)' and interaction.particle.params.T > interaction.particle.mass: return True return False
def Neglect3pInteraction(interaction, ps): if interaction.reaction[0].specie.mass == 0 and interaction.reaction[ 1].side == 1: return True if utils.reaction_type( interaction).CREATION and interaction.reaction[-1].specie.decayed: if interaction.kind in [ CollisionIntegralKind.Full, CollisionIntegralKind.Full_vacuum_decay ] or hasattr(interaction.particle, 'fast_decay'): return True if utils.reaction_type(interaction).CREATION and hasattr(interaction.reaction[-1].specie, 'fast_decay') and interaction.reaction[-1].specie.num_creation == 0\ or utils.reaction_type(interaction).DECAY and hasattr(interaction.reaction[0].specie, 'fast_decay') and interaction.reaction[0].specie.num_creation == 0: if interaction.kind in [ CollisionIntegralKind.Full, CollisionIntegralKind.Full_vacuum_decay ] or hasattr(interaction.particle, 'fast_decay'): return True return False
def sterile_hadrons_interactions(cls, thetas=None, sterile=None, neutrinos=None, leptons=None, mesons=None, kind=None): inters = [] for neutrino in neutrinos: if thetas[neutrino.flavour]: for particle in mesons: if particle.Q == 0: if particle.type == "scalar": inters += cls.neutral_scalar_meson(theta=thetas[neutrino.flavour], sterile=sterile, active=neutrino, meson=particle, kind=kind) if particle.type == "vector": inters += cls.neutral_vector_meson(theta=thetas[neutrino.flavour], sterile=sterile, active=neutrino, meson=particle, kind=kind) for lepton in leptons: if thetas[lepton.flavour]: for particle in mesons: if particle.Q == -1: if particle.type == "scalar": inters += cls.charged_scalar_meson(theta=thetas[lepton.flavour], sterile=sterile, lepton=lepton, meson=particle, kind=kind) if particle.type == "vector": inters += cls.charged_vector_meson(theta=thetas[neutrino.flavour], sterile=sterile, lepton=lepton, meson=particle, kind=kind) for inter in inters: for integral in inter.integrals: if hasattr(integral.reaction[0].specie, 'fast_decay'): if utils.reaction_type(integral).CREATION: integral.kind = CollisionIntegralKind.F_creation else: integral.kind = CollisionIntegralKind.F_decay return inters
def scaling(interaction, fullstack, constant): grid = interaction.particle.grid if utils.reaction_type(interaction).CREATION and hasattr( interaction.reaction[-1].specie, 'fast_decay'): sym = ''.join( [item.specie.symbol for item in interaction.reaction[:-1]]) for key in interaction.reaction[-1].specie.BR: if Counter(sym) == Counter(key): BR = interaction.reaction[-1].specie.BR[key] dof = interaction.particle.dof if interaction.particle.majorana else interaction.particle.dof / 2. created = simps(fullstack * constant * dof * grid.TEMPLATE**2, grid.TEMPLATE) if created == 0.: return False scaling = BR * interaction.reaction[-1].specie.num_creation / created fullstack *= scaling return fullstack