TransitionListener 2.0.0__py3-none-any.whl

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.
Files changed (95) hide show
  1. transitionlistener/__init__.py +21 -0
  2. transitionlistener/bubbledynamics.py +2250 -0
  3. transitionlistener/bubbledynamics_fixedstep.py +2929 -0
  4. transitionlistener/check_installation.py +309 -0
  5. transitionlistener/ckm.py +91 -0
  6. transitionlistener/colors.py +288 -0
  7. transitionlistener/config.py +185 -0
  8. transitionlistener/constants.py +64 -0
  9. transitionlistener/counterterms/__init__.py +230 -0
  10. transitionlistener/counterterms/cw.py +298 -0
  11. transitionlistener/counterterms/tensors.py +343 -0
  12. transitionlistener/counterterms/twohdm.py +520 -0
  13. transitionlistener/counterterms/twohdm_solver.py +374 -0
  14. transitionlistener/errors.py +315 -0
  15. transitionlistener/examples/bp_et.yaml +64 -0
  16. transitionlistener/examples/bp_lisa.yaml +70 -0
  17. transitionlistener/examples/bp_muares.yaml +69 -0
  18. transitionlistener/examples/bp_pta.yaml +64 -0
  19. transitionlistener/examples/example_dark_photon.yaml +73 -0
  20. transitionlistener/examples/example_grid.yaml +55 -0
  21. transitionlistener/examples/example_line.yaml +51 -0
  22. transitionlistener/examples/example_point.yaml +73 -0
  23. transitionlistener/examples/example_random_conformal.yaml +42 -0
  24. transitionlistener/examples/example_ultranest.yaml +39 -0
  25. transitionlistener/finiteT.py +468 -0
  26. transitionlistener/generic_potential.py +1521 -0
  27. transitionlistener/gridplots.py +592 -0
  28. transitionlistener/gwfopt.py +604 -0
  29. transitionlistener/helper_functions.py +843 -0
  30. transitionlistener/hydrodynamics.py +647 -0
  31. transitionlistener/interface/__init__.py +95 -0
  32. transitionlistener/interface/check.py +51 -0
  33. transitionlistener/interface/cli.py +211 -0
  34. transitionlistener/interface/config_loader.py +264 -0
  35. transitionlistener/interface/logging_utils.py +30 -0
  36. transitionlistener/interface/output_schema.py +296 -0
  37. transitionlistener/interface/pipeline.py +300 -0
  38. transitionlistener/interface/samplers.py +565 -0
  39. transitionlistener/interface/scans.py +468 -0
  40. transitionlistener/interface/single_point.py +581 -0
  41. transitionlistener/interface/state.py +61 -0
  42. transitionlistener/lineplots.py +597 -0
  43. transitionlistener/logo/TL-logo_large.png +0 -0
  44. transitionlistener/logo/TL-logo_small.png +0 -0
  45. transitionlistener/models/TL_2HDM.py +512 -0
  46. transitionlistener/models/TL_conformal_dark_u1.py +202 -0
  47. transitionlistener/models/TL_dark_U1.py +198 -0
  48. transitionlistener/models/TL_dark_U1_g_parameterization.py +198 -0
  49. transitionlistener/models/TL_dark_flipflop.py +274 -0
  50. transitionlistener/models/templatePotential.py +260 -0
  51. transitionlistener/nucleation.py +412 -0
  52. transitionlistener/observability.py +790 -0
  53. transitionlistener/particles.py +436 -0
  54. transitionlistener/pathDeformation.py +1462 -0
  55. transitionlistener/percolation_adaptive_gridbuilders.py +1385 -0
  56. transitionlistener/percolation_adaptive_rate.py +1049 -0
  57. transitionlistener/percolation_adaptivestepsize.py +1632 -0
  58. transitionlistener/percolation_fixedstepsize.py +618 -0
  59. transitionlistener/phases.py +1499 -0
  60. transitionlistener/plot_settings.py +121 -0
  61. transitionlistener/plots.py +1781 -0
  62. transitionlistener/runtime_options.py +278 -0
  63. transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/bandwidths.npy +0 -0
  64. transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/density.npy +0 -0
  65. transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/freqs.npy +0 -0
  66. transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/log.txt +16 -0
  67. transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/log10rhogrid.npy +0 -0
  68. transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/log10rholabels.txt +30 -0
  69. transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/pulsar_list.txt +1 -0
  70. transitionlistener/tab_data/HLV-O2-PLI.csv +82 -0
  71. transitionlistener/tab_data/HLV-O2-noise.csv +83 -0
  72. transitionlistener/tab_data/HLVK-design-PLI.csv +61 -0
  73. transitionlistener/tab_data/HLVK-design-noise.csv +83 -0
  74. transitionlistener/tab_data/NG15_PLI_hc.csv +31 -0
  75. transitionlistener/tab_data/NG15_noise_hc.csv +56 -0
  76. transitionlistener/tab_data/PLI-dataset.csv +327 -0
  77. transitionlistener/tab_data/energydensities.dat +1001 -0
  78. transitionlistener/tab_data/finiteT_b.dat.txt +1999 -0
  79. transitionlistener/tab_data/finiteT_f.dat.txt +1000 -0
  80. transitionlistener/tab_data/geff_SM.dat +10009 -0
  81. transitionlistener/tab_data/muAres_f_Hz_PLI_h2OmegaGW.csv +131 -0
  82. transitionlistener/tab_data/muAres_f_Hz_h2Omega_noise.csv +99 -0
  83. transitionlistener/tab_data/noise-dataset.csv +327 -0
  84. transitionlistener/tab_data/numberdensities.dat +1001 -0
  85. transitionlistener/tab_data/pressures.dat +1001 -0
  86. transitionlistener/thermodynamics.py +686 -0
  87. transitionlistener/transitionObservables.py +1199 -0
  88. transitionlistener/transitionObservables_fixedstep.py +976 -0
  89. transitionlistener/transitions.py +1000 -0
  90. transitionlistener/tunneling1D.py +910 -0
  91. transitionlistener-2.0.0.dist-info/METADATA +817 -0
  92. transitionlistener-2.0.0.dist-info/RECORD +95 -0
  93. transitionlistener-2.0.0.dist-info/WHEEL +4 -0
  94. transitionlistener-2.0.0.dist-info/entry_points.txt +2 -0
  95. transitionlistener-2.0.0.dist-info/licenses/LICENSE.txt +674 -0
@@ -0,0 +1,436 @@
1
+ """
2
+ Particle and mass spectrum utilities with concrete particle species.
3
+
4
+ Part of TransitionListener v2.0
5
+ Documentation: https://tasillo.de/TransitionListener/
6
+
7
+ Authors:
8
+ Jonas Matuszak <jonas.matuszak@kit.edu>
9
+ Carlo Tasillo <carlo.tasillo@ific.uv.es>
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from dataclasses import dataclass, field
15
+ from typing import Callable, Iterable, List, Optional, Sequence, Tuple, Union
16
+
17
+ import numpy as np
18
+
19
+ ThermalPrefactor = float | Callable[[np.ndarray], np.ndarray]
20
+
21
+
22
+ def _ensure_callable(name: str, fn):
23
+ """Return ``fn`` unchanged when callable and raise a targeted error otherwise."""
24
+ if fn is None or callable(fn):
25
+ return fn
26
+ raise TypeError(f"{name} must be callable or None.")
27
+
28
+ @dataclass
29
+ class Scalar:
30
+ """Structure to represent scalars"""
31
+ name: str
32
+ latex_name: str
33
+ dof: float
34
+ is_SM: bool
35
+ gauge_coupling: float = 0.0
36
+ is_physical: bool = True
37
+ c: float = 1.5
38
+
39
+ @dataclass
40
+ class Goldstone:
41
+ """Structure to represent Golstone bosons"""
42
+ name: str
43
+ latex_name: str
44
+ dof: float
45
+ is_SM: bool
46
+ gauge_coupling: float = 0.0
47
+ is_physical: bool = False
48
+ c: float = 1.5
49
+
50
+
51
+ @dataclass
52
+ class GaugeBoson:
53
+ """Structure to represent gauge bosons"""
54
+ name: str
55
+ latex_name: str
56
+ dof: float
57
+ is_SM: bool
58
+ gauge_coupling: float = 0.0
59
+ is_physical = True
60
+ c: float = 5.0/6.0
61
+
62
+
63
+ @dataclass
64
+ class Fermion:
65
+ """Structure to represent fermions."""
66
+ name: str
67
+ latex_name: str
68
+ dof: float
69
+ is_SM: bool
70
+ c: float = 1.5
71
+
72
+
73
+ class MassSpectrum:
74
+ """Container describing the particle content and mass functions of a model.
75
+
76
+ The class keeps the legacy ``CosmoTransitions``-style tuple interface used
77
+ throughout TransitionListener. It stores particle metadata such as degrees
78
+ of freedom and renormalisation constants alongside callables returning the
79
+ field- and temperature-dependent mass eigenvalues.
80
+ """
81
+
82
+ def __init__(self, scalars, gaugeBosons=[], fermions=[],
83
+ boson_massSq_fn=None, fermion_massSq_fn=None):
84
+ r"""Register the bosonic and fermionic sectors of the model.
85
+
86
+ Parameters
87
+ ----------
88
+ scalars, gaugeBosons, fermions:
89
+ Particle descriptors providing names, degrees of freedom, and the
90
+ renormalization constant ``c`` used in the one-loop effective
91
+ potential for both bosons and fermions.
92
+ boson_massSq_fn:
93
+ Callable returning the bosonic mass-squared spectrum
94
+ :math:`m_i^2(\phi, T)`.
95
+ fermion_massSq_fn:
96
+ Callable returning the fermionic mass-squared spectrum
97
+ :math:`m_f^2(\phi)`.
98
+ """
99
+ self.Nscalars = len(scalars)
100
+ self.NgaugeBosons = len(gaugeBosons)
101
+ self.Nbosons = self.Nscalars + self.NgaugeBosons
102
+ self.Nfermions = len(fermions)
103
+ self.bosons = scalars + gaugeBosons
104
+ self.fermions = fermions
105
+
106
+ # Necessary for correct DOFs
107
+ self.number_gauge_bosons = self.calc_N_gauge_bosons(gaugeBosons)
108
+
109
+ self.boson_massSq_fn = self.set_bmass_fn(boson_massSq_fn)
110
+ self.fermion_massSq_fn = self.set_fmass_fn(fermion_massSq_fn)
111
+
112
+ if fermions == []:
113
+ self.dof_fermions = np.array([0.0])
114
+ self.c_fermions = np.array([3./2.])
115
+ self.is_SM_fermions = np.array([False])
116
+ else:
117
+ self.dof_fermions = np.array([particle.dof for particle in self.fermions])
118
+ self.c_fermions = np.array([particle.c for particle in self.fermions])
119
+ self.is_SM_fermions = np.array([particle.is_SM for particle in self.fermions])
120
+
121
+ self.dof_bosons = np.array([particle.dof for particle in self.bosons])
122
+ self.c_bosons = np.array([particle.c for particle in self.bosons])
123
+ self.is_physical_bosons = np.array([particle.is_physical for particle in self.bosons])
124
+ self.is_SM_bosons = np.array([particle.is_SM for particle in self.bosons])
125
+
126
+ self.boson_gauge_couplings = np.zeros(self.Nbosons)
127
+ for i in range(self.Nbosons):
128
+ self.boson_gauge_couplings[i] = self.bosons[i].gauge_coupling
129
+
130
+ def calc_N_gauge_bosons(self, gaugeBosons):
131
+ """Infer the number of vector bosons from the total bosonic degrees of freedom."""
132
+ dof = 0
133
+ for gb in gaugeBosons:
134
+ dof += gb.dof
135
+
136
+ nGBosons = int(dof/3)
137
+ resid = dof % 3
138
+ if resid != 0:
139
+ raise Exception("DOF of bosons does not add up!")
140
+ return nGBosons
141
+
142
+ def boson_labels(self, type: str):
143
+ """Return boson names either in plain text or in LaTeX form."""
144
+ if type == "latex":
145
+ return [p.latex_name for p in self.bosons]
146
+ elif type == "text":
147
+ return [p.name for p in self.bosons]
148
+ else:
149
+ raise Exception("Wrong label type supplied.")
150
+
151
+ def fermion_labels(self, type: str):
152
+ """Return fermion names either in plain text or in LaTeX form."""
153
+ if type == "latex":
154
+ return [p.latex_name for p in self.fermions]
155
+ elif type == "text":
156
+ return [p.name for p in self.fermions]
157
+ else:
158
+ raise Exception("Wrong label type supplied.")
159
+
160
+ def set_bmass_fn(self, bmass_fn):
161
+ """Normalise the bosonic mass callback and supply a massless default when absent."""
162
+ if bmass_fn is None:
163
+ def fn(X, T):
164
+ X = np.asarray(X)
165
+ M2 = np.zeros(X[...,0].shape + (1, ))
166
+ return M2
167
+ return fn
168
+ return bmass_fn
169
+
170
+ def set_fmass_fn(self, fmass_fn):
171
+ """Normalise the fermionic mass callback and supply a massless default when absent."""
172
+ if fmass_fn is None:
173
+ def fn(X):
174
+ X = np.asarray(X)
175
+ M2 = np.zeros(X[...,0].shape + (1, ))
176
+ return M2
177
+ return fn
178
+ return fmass_fn
179
+
180
+ def bosons_massSq(self, X: np.ndarray, T: float):
181
+ r"""Return the bosonic masses entering the one-loop effective potential.
182
+
183
+ The returned tuple is interpreted as ``(m_i^2, n_i, c_i, physical_i)``,
184
+ where :math:`m_i^2(\phi, T)` are the bosonic mass eigenvalues,
185
+ :math:`n_i` their degrees of freedom, and :math:`c_i` the
186
+ renormalisation constants used in
187
+
188
+ .. math::
189
+ V_1^{B}(\phi, T=0)
190
+ = \sum_i \frac{n_i\, m_i^4(\phi, 0)}{64\pi^2}
191
+ \left[\log\!\left(\frac{m_i^2(\phi, 0)}{\mu^2}\right) - c_i\right].
192
+
193
+ Parameters
194
+ ----------
195
+ X:
196
+ Field configuration :math:`\phi`.
197
+ T:
198
+ Temperature in the internal TransitionListener units.
199
+
200
+ Returns
201
+ -------
202
+ tuple
203
+ ``(masses_sq, dof, c_constants, is_physical)``.
204
+ """
205
+ M2 = self.boson_massSq_fn(X, T)
206
+ return M2, self.dof_bosons, self.c_bosons, self.is_physical_bosons
207
+
208
+ def fermion_massSq(self, X: np.ndarray):
209
+ r"""Return the fermionic masses entering the one-loop effective potential.
210
+
211
+ The returned tuple is interpreted as ``(m_f^2, n_f)`` and is used in
212
+
213
+ .. math::
214
+ V_1^{F}(\phi)
215
+ = -\sum_f \frac{n_f\, m_f^4(\phi)}{64\pi^2}
216
+ \left[\log\!\left(\frac{m_f^2(\phi)}{\mu^2}\right) - \tfrac{3}{2}\right].
217
+
218
+ Parameters
219
+ ----------
220
+ X:
221
+ Field configuration :math:`\phi`.
222
+
223
+ Returns
224
+ -------
225
+ tuple
226
+ ``(masses_sq, dof)``.
227
+ """
228
+ M2 = self.fermion_massSq_fn(X)
229
+ return M2, self.dof_fermions
230
+
231
+ def get_gauge_coupling(self):
232
+ """Return the per-boson gauge couplings associated with the stored spectrum."""
233
+ return self.boson_gauge_couplings
234
+
235
+
236
+ @dataclass
237
+ class BaseParticle:
238
+ """Shared particle descriptor used by the newer block-based spectrum API."""
239
+
240
+ name: str
241
+ latex_name: str
242
+ dof: float
243
+ is_SM: bool
244
+ c: float
245
+ gauge_coupling: float = 0.0
246
+ thermal_prefactor: ThermalPrefactor = None
247
+ hard_thermal_mass_fn: Optional[Callable[[np.ndarray, float], np.ndarray]] = None
248
+ metadata: dict = field(default_factory=dict)
249
+
250
+ def __post_init__(self) -> None:
251
+ """Validate the basic particle metadata and normalise optional callables."""
252
+ if self.dof < 0:
253
+ raise ValueError("Particle degrees of freedom must be non-negative.")
254
+ self.hard_thermal_mass_fn = _ensure_callable(
255
+ f"hard_thermal_mass_fn for {self.name}", self.hard_thermal_mass_fn
256
+ )
257
+ if self.thermal_prefactor is not None and not callable(self.thermal_prefactor):
258
+ value = float(self.thermal_prefactor)
259
+ self.thermal_prefactor = lambda X, value=value: np.array(value, dtype=float)
260
+
261
+ def evaluate_prefactor(self, X: np.ndarray) -> Optional[np.ndarray]:
262
+ """Evaluate the optional thermal prefactor at field point ``X``."""
263
+ if self.thermal_prefactor is None:
264
+ return None
265
+ return np.asarray(self.thermal_prefactor(np.asarray(X)), dtype=float)
266
+
267
+ @property
268
+ def is_BSM(self) -> bool:
269
+ """Whether the particle belongs to the beyond-the-Standard-Model sector."""
270
+ return not self.is_SM
271
+
272
+ @property
273
+ def statistic(self) -> str:
274
+ """Bosonic/fermionic label implemented by concrete subclasses."""
275
+ raise NotImplementedError
276
+
277
+ @property
278
+ def is_physical(self) -> bool:
279
+ """Whether the particle should contribute as a physical excitation."""
280
+ return True
281
+
282
+
283
+ @dataclass
284
+ class BosonSector:
285
+ """Evaluated bosonic spectrum together with particle metadata."""
286
+
287
+ masses_sq: np.ndarray
288
+ dof: np.ndarray
289
+ c: np.ndarray
290
+ is_physical: np.ndarray
291
+ gauge_coupling: np.ndarray
292
+ is_bsm: np.ndarray
293
+ particles: Sequence[BaseParticle]
294
+ thermal_masses_sq: Optional[np.ndarray] = None
295
+
296
+ def as_tuple(self) -> Tuple[np.ndarray, ...]:
297
+ """Return the legacy tuple representation used by older callers."""
298
+ return (
299
+ self.masses_sq,
300
+ self.dof,
301
+ self.c,
302
+ self.is_physical,
303
+ self.gauge_coupling,
304
+ self.is_bsm,
305
+ )
306
+
307
+ @property
308
+ def latex_labels(self) -> List[str]:
309
+ """LaTeX labels for each bosonic degree of freedom."""
310
+ return [p.latex_name for p in self.particles]
311
+
312
+ @property
313
+ def text_labels(self) -> List[str]:
314
+ """Plain-text labels for each bosonic degree of freedom."""
315
+ return [p.name for p in self.particles]
316
+
317
+
318
+ @dataclass
319
+ class FermionSector:
320
+ """Evaluated fermionic spectrum together with particle metadata."""
321
+
322
+ masses_sq: np.ndarray
323
+ dof: np.ndarray
324
+ is_bsm: np.ndarray
325
+ particles: Sequence[BaseParticle]
326
+
327
+ def as_tuple(self) -> Tuple[np.ndarray, ...]:
328
+ """Return the legacy tuple representation used by older callers."""
329
+ return (self.masses_sq, self.dof, self.is_bsm)
330
+
331
+ @property
332
+ def latex_labels(self) -> List[str]:
333
+ """LaTeX labels for each fermionic degree of freedom."""
334
+ return [p.latex_name for p in self.particles]
335
+
336
+ @property
337
+ def text_labels(self) -> List[str]:
338
+ """Plain-text labels for each fermionic degree of freedom."""
339
+ return [p.name for p in self.particles]
340
+
341
+
342
+ @dataclass
343
+ class SpectrumSnapshot:
344
+ """Simultaneous bosonic and fermionic spectrum evaluation at a given state."""
345
+
346
+ bosons: BosonSector
347
+ fermions: FermionSector
348
+
349
+
350
+ @dataclass
351
+ class MassBlock:
352
+ """Group of particles sharing one mass function and, optionally, one thermal correction."""
353
+
354
+ particles: Sequence[BaseParticle]
355
+ mass_function: Callable[[np.ndarray, float], np.ndarray]
356
+ hard_thermal_mass_function: Optional[Callable[[np.ndarray, float], np.ndarray]] = None
357
+ label: Optional[str] = None
358
+
359
+ def __post_init__(self) -> None:
360
+ """Validate particle statistics and normalise the supplied callables."""
361
+ if not self.particles:
362
+ raise ValueError("MassBlock requires at least one particle.")
363
+ stats = {p.statistic for p in self.particles}
364
+ if len(stats) != 1:
365
+ raise ValueError("All particles in a MassBlock must share the same statistic.")
366
+ self.particles = list(self.particles)
367
+ self.mass_function = _ensure_callable("mass_function", self.mass_function)
368
+ self.hard_thermal_mass_function = _ensure_callable(
369
+ "hard_thermal_mass_function", self.hard_thermal_mass_function
370
+ )
371
+
372
+ @property
373
+ def statistic(self) -> str:
374
+ """Bosonic/fermionic statistic shared by every particle in the block."""
375
+ return self.particles[0].statistic
376
+
377
+ def evaluate(self, X: np.ndarray, T: float) -> np.ndarray:
378
+ """Evaluate the block mass function and align its trailing axis with ``particles``."""
379
+ masses = np.asarray(self.mass_function(X, T))
380
+ if masses.shape[-1] != len(self.particles):
381
+ if masses.shape[0] == len(self.particles):
382
+ masses = np.moveaxis(masses, 0, -1)
383
+ if masses.shape[-1] != len(self.particles):
384
+ raise ValueError(
385
+ f"Mass function for block {self.label!r} returned shape {masses.shape}, "
386
+ f"expected trailing dimension {len(self.particles)}."
387
+ )
388
+ return masses
389
+
390
+ def evaluate_thermal(self, X: np.ndarray, T: float) -> Optional[np.ndarray]:
391
+ r"""Evaluate hard thermal masses or ``c_i T^2``-style prefactors for the block.
392
+
393
+ When no explicit thermal-mass callback is provided, the function falls
394
+ back to per-particle prefactors and returns
395
+
396
+ .. math::
397
+ \Pi_i(\phi, T) = c_i(\phi)\, T^2.
398
+ """
399
+ if self.hard_thermal_mass_function is not None:
400
+ thermal = np.asarray(self.hard_thermal_mass_function(X, T))
401
+ if thermal.shape[-1] != len(self.particles):
402
+ if thermal.shape[0] == len(self.particles):
403
+ thermal = np.moveaxis(thermal, 0, -1)
404
+ if thermal.shape[-1] != len(self.particles):
405
+ raise ValueError(
406
+ f"Thermal mass function for block {self.label!r} returned shape {thermal.shape}, "
407
+ f"expected trailing dimension {len(self.particles)}."
408
+ )
409
+ return thermal
410
+
411
+ prefactors = []
412
+ has_prefactor = False
413
+ for particle in self.particles:
414
+ pref = particle.evaluate_prefactor(X)
415
+ if pref is None:
416
+ pref = 0.0
417
+ else:
418
+ has_prefactor = True
419
+ prefactors.append(np.asarray(pref, dtype=float))
420
+ if not has_prefactor:
421
+ return None
422
+ pref_array = np.stack(prefactors, axis=-1)
423
+ T_arr = np.asarray(T, dtype=float)
424
+ return pref_array * (np.square(T_arr)[..., np.newaxis])
425
+
426
+ __all__ = [
427
+ "Scalar",
428
+ "Goldstone",
429
+ "GaugeBoson",
430
+ "Fermion",
431
+ "MassSpectrum",
432
+ "MassBlock",
433
+ "BosonSector",
434
+ "FermionSector",
435
+ "SpectrumSnapshot",
436
+ ]