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,274 @@
1
+ """
2
+ This module contains the Higgs potential for a dark sector model with two singlet scalars
3
+ which can mix with each other, but not with the SM Higgs. The purpose of this model is to
4
+ study possible phase transition in a two-dimensional field space.
5
+
6
+ Part of TransitionListener v2.0
7
+ Documentation: https://tasillo.de/TransitionListener/
8
+
9
+ Authors:
10
+ Jonas Matuszak <jonas.matuszak@kit.edu>
11
+ Carlo Tasillo <carlo.tasillo@ific.uv.es>
12
+ """
13
+
14
+ import numpy as np
15
+ from scipy import optimize
16
+ from transitionlistener import generic_potential
17
+ from transitionlistener import config
18
+ from transitionlistener import helper_functions
19
+ from transitionlistener import constants as cn
20
+ from transitionlistener.particles import MassSpectrum, Scalar, Fermion
21
+ from transitionlistener.errors import InitPotentialError
22
+
23
+
24
+
25
+ class DarkFlipFlop(generic_potential.generic_potential):
26
+ """Dark flip-flop model with two interacting singlets."""
27
+
28
+ model_parameters = {
29
+ "lambda0": {
30
+ "default": 0.1,
31
+ "plotname": r"$\lambda_0$",
32
+ "min": 0,
33
+ "max": np.inf},
34
+ "gamma": {
35
+ "default": 1,
36
+ "plotname": r"$\gamma$",
37
+ "min": 0,
38
+ "max": np.inf},
39
+ "lambda1": {
40
+ "default": 0.1,
41
+ "plotname": r"$\lambda_1$",
42
+ "min": 0,
43
+ "max": np.inf},
44
+ "lambda12": {
45
+ "default": 0.1,
46
+ "plotname": r"$\lambda_{12}$",
47
+ "min": 0,
48
+ "max": np.inf},
49
+ "v_GeV": {
50
+ "default": 0.1,
51
+ "plotname": r"$v$ [GeV]",
52
+ "min": 0,
53
+ "max": np.inf},
54
+ "y": {
55
+ "default": 1,
56
+ "plotname": r"$y$",
57
+ "min": 0,
58
+ "max": np.inf},
59
+ }
60
+
61
+ def init(self, inputparam_dict, verbose=True):
62
+ """Initialise the flip-flop scalar potential with user-supplied parameters."""
63
+ self.mp = self.set_modelparams(inputparam_dict)
64
+ lambda0, gamma, lambda1, lambda12, v_GeV, y = [self.mp[name]["value"] for name in self.mp.keys()]
65
+ self.retrieved_input = np.array([lambda0, gamma, lambda1, lambda12, v_GeV, y])
66
+ self.Ndim = 2
67
+
68
+ self.lambda0 = lambda0
69
+ self.gamma = gamma
70
+ self.lambda1 = lambda1
71
+ self.lambda12 = lambda12
72
+ self.v_GeV = v_GeV
73
+ self.y = y
74
+ self.verbose = verbose
75
+
76
+ self.v_stable = 1000
77
+ self.v = self.v_stable
78
+ self.daisy = "ArnoldEspinosa"
79
+ self.Z2_cutoff = -5
80
+ self.conversionFactor = self.computeConversionFactor(self.v_stable, v_GeV)
81
+ self.xi_nuc = 1
82
+
83
+ self.v2_GeV2 = v_GeV**2
84
+
85
+ self.v2 = self.v2_GeV2 / self.conversionFactor**2
86
+ self.renormScaleSq = self.v2
87
+
88
+ self.mass_spectrum = self._build_mass_spectrum()
89
+
90
+ self.dmu1 = 0.0
91
+ self.dmu2 = 0.0
92
+ self.dlambda1 = 0.0
93
+ self.dlambda2 = 0.0
94
+ self.dlambda12 = 0.0
95
+ self.calcCounterTerms()
96
+
97
+ # The next line sets the field values of the absolute minimum.
98
+ def fmin(x, t):
99
+ return optimize.fmin(self.Vtot, x, args=(t,), xtol=self.x_eps, disp=False)
100
+
101
+ # X0_1 = fmin([0, self.v], self.Tmin)
102
+ # X0_2 = fmin([self.v, 0], self.Tmin)
103
+ # Its better to use the analytical minima as a starting point here
104
+ self.Tmin = cn.T0_SM_GeV / self.conversionFactor
105
+ X0_1 = fmin([0, self.v/gamma], self.Tmin)
106
+ X0_2 = fmin([self.v*np.sqrt(1 + lambda1/lambda0), 0], self.Tmin)
107
+ V0_1 = self.Vtot(X0_1, self.Tmin)
108
+ V0_2 = self.Vtot(X0_2, self.Tmin)
109
+ self.X0 = X0_1 if V0_1 < V0_2 else X0_2
110
+
111
+ bosons_Tmin = self.boson_massSq(self.X0, self.Tmin)
112
+ self.m1sq_Tmin = float(bosons_Tmin[0][..., 0])
113
+ self.m2sq_Tmin = float(bosons_Tmin[0][..., 1])
114
+ self.m1_Tmin_GeV = np.sqrt(self.m1sq_Tmin) * self.conversionFactor
115
+ self.m2_Tmin_GeV = np.sqrt(self.m2sq_Tmin) * self.conversionFactor
116
+ self.derived_param_names = [name for name in config.all_observables.keys()]
117
+ self.derived_param_plot_names = [config.all_observables[name] for name in self.derived_param_names]
118
+
119
+ # if self.m1_Tmin_GeV < 0.2 or self.m2_Tmin_GeV < 0.2:
120
+ # # This is an ad-hoc cut to avoid very light scalars that are ruled out by
121
+ # # BBN DNeff constraints. Above 200 MeV they can decay to muons and are
122
+ # # hence safe.
123
+ # msg = ("The scalar masses are below 200 MeV "
124
+ # "at T=0: m1 = {:.3f} GeV, m2 = {:.3f} GeV.".format(
125
+ # self.m1_Tmin_GeV, self.m2_Tmin_GeV))
126
+ # raise InitPotentialError(msg)
127
+
128
+ if self.verbose:
129
+ input_dict = {
130
+ "lambda0": self.lambda0,
131
+ "gamma": self.gamma,
132
+ "lambda1": self.lambda1,
133
+ "lambda12": self.lambda12,
134
+ "v / GeV": self.v_GeV
135
+ }
136
+ derived_dict = {
137
+ "v / i.u.": self.v,
138
+ "m1 / GeV": self.m1_Tmin_GeV,
139
+ "m2 / GeV": self.m2_Tmin_GeV,
140
+ }
141
+ self.makePrettyDictionaryPrint(derived_dict)
142
+
143
+ def setConfigParameters(self) -> None:
144
+ """Change the default config parameters for tracing, hydrodynamics, and GW
145
+ computation.
146
+ """
147
+ self.config.tracingConf.gen_mirror_phases = False
148
+ self.config.tracingConf.tracing_field_accuracy = 1e-3
149
+ # self.config.gwConf.weak_threshold = 5e-2 # This could be a bit low if alpha_nuc << alpha_perc
150
+ self.config.gwConf.weak_threshold = 1e-4
151
+ # self.config.tracingConf.internal_scale = 1000
152
+ # self.config.tracingConf.Tmax_factor = 2.5
153
+ # ...
154
+
155
+ def calcCounterTerms(self, eps=0.1) -> None:
156
+ """Compute the counter terms of the MS bar scheme."""
157
+ v1 = self.v * np.sqrt(1 + self.lambda1/self.lambda0)
158
+
159
+ def V_coleman_weinberg(X):
160
+ bosons = self.boson_massSq(X, 0.0)
161
+ fermions = self.fermion_massSq(X)
162
+ return self.V1(bosons, fermions)
163
+
164
+ # Take the derivative with larger \Delta\phi, this improves stability!
165
+ dV1 = helper_functions.gradientFunction(
166
+ # V_coleman_weinberg, eps=self.x_eps, Ndim=self.Ndim, order=self.deriv_order)
167
+ V_coleman_weinberg, eps=eps, Ndim=self.Ndim, order=self.deriv_order)
168
+
169
+ d2V1 = helper_functions.hessianFunction(
170
+ # V_coleman_weinberg, eps=self.x_eps, Ndim=self.Ndim, order=self.deriv_order)
171
+ V_coleman_weinberg, eps=eps, Ndim=self.Ndim, order=self.deriv_order)
172
+
173
+ dVdx1 = dV1([v1, 0])[0]
174
+ d2Vdx1 = d2V1([v1, 0])[0, 0]
175
+ d2Vdx2 = d2V1([v1, 0])[1, 1]
176
+ # d2Vdx2 = d2V1([0, v2])[1,1]
177
+
178
+ self.dmu1 = 3/(2*v1) * dVdx1 - 0.5 * d2Vdx1
179
+ self.dmu2 = d2Vdx2
180
+ self.dlambda1 = 0.5/v1**3 * dVdx1 - 0.5/v1**2 * d2Vdx1
181
+ self.dlambda2 = 0.0
182
+ self.dlambda12 = 0.0
183
+
184
+ def forbidPhaseCrit(self, X):
185
+ """Return True when a candidate minimum should be excluded by symmetry."""
186
+ Z2_1 = (np.array([X])[..., 0] < self.Z2_cutoff).any()
187
+ Z2_2 = (np.array([X])[..., 1] < self.Z2_cutoff).any()
188
+ return Z2_1 or Z2_2
189
+
190
+ def V0(self, X):
191
+ """Evaluate the tree-level potential for the scalar doublet."""
192
+ X = np.asanyarray(X)
193
+ phi1 = X[..., 0]
194
+ phi2 = X[..., 1]
195
+ r = .25*self.lambda0*(phi1**2 + self.gamma**2 * phi2**2 - self.v2)**2
196
+ r += -.5 * self.lambda1 * self.v2 * phi1**2
197
+ r += .5 * self.lambda12 * phi1**2 * phi2**2
198
+ return r
199
+
200
+ def Vct(self, X):
201
+ r"""The counter terms in the MS bar scheme.
202
+
203
+ .. math::
204
+ `V_{ct} = - \frac{\delta\mu_1^2}{2} \phi_1^{2} - \frac{\delta\mu_2^2}{2} \phi_{2}^{2} +
205
+ \frac{\delta\lambda_{1}}{4}\phi_{1}^{4} +
206
+ \frac{\delta\lambda_{2}}{4}\phi_{2}^4 + \frac{\delta\lambda_{12}}{2}\phi_{1}^2\phi_2^2`
207
+ """
208
+ X = np.asarray(X)
209
+ phi1 = X[..., 0]
210
+ phi2 = X[..., 1]
211
+
212
+ Vct = - 0.5*self.dmu1*phi1**2 - 0.5*self.dmu2*phi2**2
213
+ Vct += 0.25*self.dlambda1*phi1**4 + 0.25*self.dlambda2*phi2**2
214
+ Vct += 0.5*self.dlambda12 * phi1**2 * phi2**2
215
+ return Vct
216
+
217
+ def _build_mass_spectrum(self) -> MassSpectrum:
218
+
219
+ scalar1 = Scalar(name="m_h1", latex_name=r"$m_{h_1}$", dof=1, is_SM=False)
220
+ scalar2 = Scalar(name="m_h2", latex_name=r"$m_{h_2}$", dof=1, is_SM=False)
221
+
222
+ def boson_mass_function(X, T):
223
+ X = np.asarray(X)
224
+ phi1 = X[..., 0]
225
+ phi2 = X[..., 1]
226
+ T_arr = np.asarray(T, dtype=float)
227
+ T2 = T_arr * T_arr
228
+ if T2.ndim == 0:
229
+ T2 = T2 + np.zeros_like(phi1)
230
+
231
+ a = 2 * self.lambda0 * phi1**2
232
+ a += self.lambda0 * (phi1**2 + self.gamma**2 * phi2**2 - self.v2)
233
+ a += -self.lambda1 * self.v2 + self.lambda12 * phi2**2
234
+
235
+ b = 2 * self.gamma**4 * self.lambda0 * phi2**2
236
+ b += self.lambda0 * self.gamma**2 * (phi1**2 + self.gamma**2 * phi2**2 - self.v2)
237
+ b += self.lambda12 * phi1**2
238
+
239
+ coeff1 = (self.y**2 + 2 * ((3 + self.gamma**2) * self.lambda0 + self.lambda12)) / 24.0
240
+ coeff2 = (self.gamma**2 * self.lambda0 + 3 * self.gamma**4 * self.lambda0 + self.lambda12) / 12.0
241
+ a += coeff1 * T2
242
+ b += coeff2 * T2
243
+
244
+ c = 2 * self.gamma**2 * self.lambda0 * phi1 * phi2 + 2 * self.lambda12 * phi1 * phi2
245
+
246
+ A = 0.5 * (a + b)
247
+ B = np.sqrt(0.25 * (a - b) ** 2 + c ** 2)
248
+ m1sq = A + B
249
+ m2sq = A - B
250
+
251
+ return np.stack((m1sq, m2sq), axis=-1)
252
+
253
+ fermion = Fermion(name="m_psi", latex_name=r"$m_{\psi}$", dof=2, is_SM=False)
254
+
255
+ def fermion_mass_function(X):
256
+ X = np.asarray(X)
257
+ phi1 = X[..., 0]
258
+ m2psi = 0.5 * self.y**2 * phi1**2
259
+ return np.stack((m2psi,), axis=-1)
260
+
261
+ spectrum = MassSpectrum([scalar1, scalar2], fermions=[fermion],
262
+ boson_massSq_fn=boson_mass_function,
263
+ fermion_massSq_fn=fermion_mass_function)
264
+
265
+ return spectrum
266
+
267
+ def approxZeroTMin(self):
268
+ """Return approximate zero-temperature minima for the flip-flop model."""
269
+ # There are generically two minima at zero temperature in this model,
270
+ # and we want to include both of them.
271
+ v = self.v2**.5
272
+ v1 = v/self.gamma
273
+ v2 = v*np.sqrt(1 + self.lambda1/self.lambda0)
274
+ return [np.array([0, v1]), np.array([v2, 0])]
@@ -0,0 +1,260 @@
1
+ """Template to implement the effective potential of a new model.
2
+
3
+ Part of TransitionListener v2.0
4
+ Documentation: https://tasillo.de/TransitionListener/
5
+
6
+ Authors:
7
+ Jonas Matuszak <jonas.matuszak@kit.edu>
8
+ Carlo Tasillo <carlo.tasillo@ific.uv.es>
9
+ """
10
+
11
+ import numpy as np
12
+ from transitionlistener.generic_potential import generic_potential
13
+ import transitionlistener.constants as c
14
+ from transitionlistener import config
15
+ from transitionlistener.particles import MassSpectrum, Scalar, Goldstone, GaugeBoson, Fermion
16
+
17
+
18
+
19
+ # Rename the class to match your implemented model
20
+ class TemplatePotenital(generic_potential):
21
+ """Template potential"""
22
+
23
+ # Specify the
24
+ model_parameters = {
25
+ "m1_GeV": {
26
+ "default": 125.20,
27
+ "plotname": r"$m_1$ [GeV]",
28
+ "min": 0,
29
+ "max": np.inf},
30
+ "g": {
31
+ "default": 0.5,
32
+ "plotname": r"$g$",
33
+ "min": 0,
34
+ "max": 4*np.pi
35
+ },
36
+ "l": {
37
+ "default": 1e-3,
38
+ "plotname": r"$\lambda$",
39
+ "min": 0,
40
+ "max": 4*np.pi
41
+ },
42
+ "y": {
43
+ "default": 0.1,
44
+ "plotname": r"$y$",
45
+ "min": 0,
46
+ "max": np.sqrt(2)*4*np.pi,
47
+ },
48
+ "v_GeV": {
49
+ "default": 246.22,
50
+ "plotname": r"$v$ [GeV]",
51
+ "min": 0,
52
+ "max": np.inf},
53
+ }
54
+
55
+ def init(self, input_dict, verbose=True):
56
+ """Perform the initialisation of the potential"""
57
+ self.verbose = verbose
58
+
59
+ # Specify the number of scalar field dimension:
60
+ self.Ndim = 1
61
+
62
+ # read input and set (default) values
63
+ self.mp = self.set_modelparams(input_dict)
64
+ self.m1_GeV = self.mp["m1_GeV"]["value"]
65
+ self.v_GeV = self.mp["v_GeV"]["value"]
66
+ self.y = self.mp["y"]["value"]
67
+ self.l = self.mp["l"]["value"]
68
+ self.g = self.mp["g"]["value"]
69
+
70
+ # Use the vev in internal units, normalised to 1000 by default
71
+ self.v = self.v_stable
72
+ self.conversionFactor = self.computeConversionFactor(self.v_stable, self.v_GeV)
73
+ self.daisy = "ArnoldEspinosa" # or: "Parwani" or "off"
74
+
75
+ # Set any parameters derived from the input
76
+ self.mu2 = -2 * self.v**2
77
+ self.mu2_GeV = - 2 * self.v_GeV**2
78
+
79
+ # Set the T = 0 minima, this has to have the shape (1, Ndim)
80
+ self.X0 = np.array([self.v])
81
+
82
+ # Build particle spectrum definition used throughout the potential
83
+ self.mass_spectrum = self.build_mass_spectrum()
84
+
85
+ # Set the renormalization scale
86
+ self.renormScaleSq = self.v**2 # In internal units
87
+ self.renormScaleSq_GeV2 = self.renormScaleSq * self.conversionFactor**2. # In GeV
88
+ self.renormScale_GeV = np.sqrt(self.renormScaleSq) * self.conversionFactor
89
+
90
+ # Impose the renormalization conditions on the potential.
91
+ dV1 = self.dV1atvev()
92
+ d2V1 = self.d2V1atvev()
93
+ self.dmu2 = 3./2. * dV1 / self.v - 1./2. * d2V1
94
+ self.dmu2_GeV2 = self.dmu2 * self.conversionFactor**2.
95
+ self.dl = 1./2. * dV1 / self.v**3. - 1./2. * d2V1 / self.v**2.
96
+
97
+ # Get the zero temperature masses in the global vev
98
+ bosonMassSq_vev, _, _, _ = self.boson_massSq(self.X0, 0.0)
99
+
100
+ # Set the background degrees of freedom:
101
+ # The defaults includes the SM degrees of freedom, i.e. the sector undergoing the
102
+ # phase transition is coupled to the SM during the phase transition.
103
+ # self.kin_coupled_e_geff = e_geffSM # This can be overwritten
104
+ # self.kin_coupled_p_geff = p_geffSM # This can be overwritten
105
+
106
+ # This specifies additional radiation that is not coupled to the sector undergoing
107
+ # a phase transition. If e.g. a dark sector is completely decoupled from the SM,
108
+ # put the SM geff here.
109
+ # self.kin_decoupled_e_geff = lambda T, cf: 0.0 * T # If the SM is decoupled, put e_geffSM here
110
+ # self.kin_decoupled_p_geff = lambda T, cf: 0.0 * T # If the SM is decoupled, put p_geffSM here
111
+
112
+ # Include the input and derived parameters in the class.
113
+ self.derived_param_names = [name for name in config.all_observables.keys()]
114
+ self.derived_param_plot_names = [config.all_observables[name] for name in self.derived_param_names]
115
+
116
+ if self.verbose:
117
+ input_dict = dict(
118
+ vev_GeV=self.v_GeV,
119
+ vev_iu=self.v,
120
+ quartic_coupling=self.l,
121
+ gauge_coupling=self.g,
122
+ y=self.y,
123
+ conversion_factor_GeV_per_iu=self.conversionFactor
124
+ )
125
+ derived_dict = dict(
126
+ mu2_GeV2=self.mu2_GeV2,
127
+ dmu2_GeV2=self.dmu2_GeV2,
128
+ dl=self.dl,
129
+ renormScale_GeV=self.renormScale_GeV,
130
+ renormScaleSq=self.renormScaleSq)
131
+ self.makePrettyDictionaryPrint(input_dict, derived_dict)
132
+
133
+ def setConfigParameters(self) -> None:
134
+ """Change the default config parameters for tracing, hydrodynamics, and GW
135
+ computation.
136
+ """
137
+ self.config.tracingConf.gen_mirror_phases = False
138
+ self.config.tracingConf.tracing_field_accuracy = 1e-3 # for Hessian
139
+ # self.config.tracingConf.internal_scale = 1000
140
+ # self.config.tracingConf.Tmax_factor = 2.5
141
+ # ...
142
+
143
+
144
+ def forbidPhaseCrit(self, X):
145
+ """
146
+ forbidPhaseCrit is used since there is a Z2 symmetry in the theory and
147
+ we don't want to double-count all of the phases.
148
+ """
149
+ return (np.array([X])[..., 0] < self.Z2_cutoff).any()
150
+
151
+ def V0(self, X: np.ndarray) -> np.ndarray:
152
+ """ This method defines the tree-level potential."""
153
+ X = np.asanyarray(X)
154
+
155
+ phi1 = X[..., 0]
156
+ # For Ndims > 1, the other field directions are exctracted as
157
+ # phi2 = X[..., 1]
158
+ # phi3 = X[..., 2]
159
+
160
+ # Compute the contributions to the tree level potential with the
161
+ # model parameters
162
+ V = - self.mu2*(phi1**2.)/2. + self.l*(phi1**4.)/4.
163
+
164
+ # Potentially other field directions contribute, e.g.:
165
+ # V += - self.mu2_2 * phi2**2/2 + self.l_2 * phi2**4/4.
166
+
167
+ return V
168
+
169
+ def Vct(self, X: np.ndarray) -> np.ndarray:
170
+ """ The counterterm lagrangian is the same as the tree level lagrangian but
171
+ with masses and couplings replaced by counter term values (i.e. here
172
+ mu2 -> dmu2 and l -> dl).
173
+ """
174
+ X = np.array(X)
175
+ phi1 = X[..., 0]
176
+ # For Ndims > 1, the other field directions are exctracted as
177
+ # phi2 = X[..., 1]
178
+ # phi3 = X[..., 2]
179
+
180
+ # Compute the contribution from the counter terms
181
+ V = - self.dmu2*(phi1**2.)/2. + self.dl*(phi1**4.)/4.
182
+ # Potentially other field directions contribute, e.g.:
183
+ # V += - self.dmu2_2 * phi2**2/2 + self.dl_2 * phi2**4/4.
184
+
185
+ return V
186
+
187
+ def build_mass_spectrum(self) -> MassSpectrum:
188
+ """This function constructs the mass spectrum by specifying
189
+ the particle content and the mass functions."""
190
+
191
+ # First the scalar particles have to be specified.
192
+ scalar_particles = [
193
+ Scalar(name="m_phi", latex_name=r"$m_\phi$", dof=1, is_SM=False),
194
+ Goldstone(name="m_varphi", latex_name=r"$m_\varphi$", dof=1, is_SM=False),
195
+ ]
196
+
197
+ # For the gauge bosons, split the longitudinal and transversal
198
+ # components due to the different thermal masses
199
+ gauge_particles = [
200
+ GaugeBoson(name="m_ZT", latex_name=r"$m_{Z^\prime, T}$", dof=2, gauge_coupling=self.g, is_SM=False),
201
+ GaugeBoson(name="m_ZL", latex_name=r"$m_{Z^\prime, L}$", dof=1, gauge_coupling=self.g, is_SM=False),
202
+ ]
203
+
204
+ def boson_mass_function(X, T):
205
+ """This returns the squared masses of the bosonic particles."""
206
+ X = np.asarray(X)
207
+ T = np.asarray(T)
208
+
209
+ phi = X[..., 0]
210
+ phi_sq = phi*phi
211
+
212
+ Pi_phi = (self.l/3.0 + self.g**2 / 4.0 + self.y**2/12) * T*T # Hard thermal masses scalar
213
+ Pi_Z = (self.g**2/3.0) * T*T # Hard thermal masses gauge boson
214
+
215
+ mPhi_sq = - self.mu2 + 3.0 * self.l * phi_sq
216
+ mVarphi_sq = -self.mu2 + self.l * phi_sq
217
+ mZT_sq = self.g**2 * phi_sq
218
+ mZL_sq = self.g**2 * phi_sq
219
+
220
+ # Four entries
221
+ Nbosons = 4
222
+ M2 = np.empty(phi.shape + (Nbosons,))
223
+ # This has to have the same order as the
224
+ # scalar_particles
225
+ M2[..., 0] = mPhi_sq + Pi_phi
226
+ M2[..., 1] = mVarphi_sq + Pi_phi
227
+ # and the same order as the gauge_particles
228
+ M2[..., 2] = mZT_sq
229
+ M2[..., 3] = mZL_sq + Pi_Z
230
+
231
+ # Add additional bosonic particles:
232
+ # M2[..., 4] = ...
233
+ # M2[..., 5] = ...
234
+
235
+ return M2
236
+
237
+ # specify the fermionic particles:
238
+ fermion_particles = [
239
+ Fermion(name="m_chi", latex_name=r"$m_chi$", dof=4, is_SM=False),
240
+ ]
241
+
242
+ def fermion_mass_function(X):
243
+ """Compute the squared masses of the fermionic particles."""
244
+ X = np.asarray(X)
245
+ phi = X[..., 0]
246
+ mChi = self.y**2/2.0 * phi**2
247
+ return np.stack((mChi,), axis=-1)
248
+
249
+ # Construct the complete mass spectrum contributing to the potential
250
+ spectrum = MassSpectrum(scalars=scalar_particles,
251
+ gaugeBosons=gauge_particles,
252
+ fermions=fermion_particles,
253
+ boson_massSq_fn=boson_mass_function,
254
+ fermion_massSq_fn=fermion_mass_function)
255
+
256
+ return spectrum
257
+
258
+ def approxZeroTMin(self):
259
+ """Return approximate zero-temperature minima."""
260
+ return self.X0