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.
- transitionlistener/__init__.py +21 -0
- transitionlistener/bubbledynamics.py +2250 -0
- transitionlistener/bubbledynamics_fixedstep.py +2929 -0
- transitionlistener/check_installation.py +309 -0
- transitionlistener/ckm.py +91 -0
- transitionlistener/colors.py +288 -0
- transitionlistener/config.py +185 -0
- transitionlistener/constants.py +64 -0
- transitionlistener/counterterms/__init__.py +230 -0
- transitionlistener/counterterms/cw.py +298 -0
- transitionlistener/counterterms/tensors.py +343 -0
- transitionlistener/counterterms/twohdm.py +520 -0
- transitionlistener/counterterms/twohdm_solver.py +374 -0
- transitionlistener/errors.py +315 -0
- transitionlistener/examples/bp_et.yaml +64 -0
- transitionlistener/examples/bp_lisa.yaml +70 -0
- transitionlistener/examples/bp_muares.yaml +69 -0
- transitionlistener/examples/bp_pta.yaml +64 -0
- transitionlistener/examples/example_dark_photon.yaml +73 -0
- transitionlistener/examples/example_grid.yaml +55 -0
- transitionlistener/examples/example_line.yaml +51 -0
- transitionlistener/examples/example_point.yaml +73 -0
- transitionlistener/examples/example_random_conformal.yaml +42 -0
- transitionlistener/examples/example_ultranest.yaml +39 -0
- transitionlistener/finiteT.py +468 -0
- transitionlistener/generic_potential.py +1521 -0
- transitionlistener/gridplots.py +592 -0
- transitionlistener/gwfopt.py +604 -0
- transitionlistener/helper_functions.py +843 -0
- transitionlistener/hydrodynamics.py +647 -0
- transitionlistener/interface/__init__.py +95 -0
- transitionlistener/interface/check.py +51 -0
- transitionlistener/interface/cli.py +211 -0
- transitionlistener/interface/config_loader.py +264 -0
- transitionlistener/interface/logging_utils.py +30 -0
- transitionlistener/interface/output_schema.py +296 -0
- transitionlistener/interface/pipeline.py +300 -0
- transitionlistener/interface/samplers.py +565 -0
- transitionlistener/interface/scans.py +468 -0
- transitionlistener/interface/single_point.py +581 -0
- transitionlistener/interface/state.py +61 -0
- transitionlistener/lineplots.py +597 -0
- transitionlistener/logo/TL-logo_large.png +0 -0
- transitionlistener/logo/TL-logo_small.png +0 -0
- transitionlistener/models/TL_2HDM.py +512 -0
- transitionlistener/models/TL_conformal_dark_u1.py +202 -0
- transitionlistener/models/TL_dark_U1.py +198 -0
- transitionlistener/models/TL_dark_U1_g_parameterization.py +198 -0
- transitionlistener/models/TL_dark_flipflop.py +274 -0
- transitionlistener/models/templatePotential.py +260 -0
- transitionlistener/nucleation.py +412 -0
- transitionlistener/observability.py +790 -0
- transitionlistener/particles.py +436 -0
- transitionlistener/pathDeformation.py +1462 -0
- transitionlistener/percolation_adaptive_gridbuilders.py +1385 -0
- transitionlistener/percolation_adaptive_rate.py +1049 -0
- transitionlistener/percolation_adaptivestepsize.py +1632 -0
- transitionlistener/percolation_fixedstepsize.py +618 -0
- transitionlistener/phases.py +1499 -0
- transitionlistener/plot_settings.py +121 -0
- transitionlistener/plots.py +1781 -0
- transitionlistener/runtime_options.py +278 -0
- transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/bandwidths.npy +0 -0
- transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/density.npy +0 -0
- transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/freqs.npy +0 -0
- transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/log.txt +16 -0
- transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/log10rhogrid.npy +0 -0
- transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/log10rholabels.txt +30 -0
- transitionlistener/tab_data/30f_fs{hd}_100fDMGP_ceffyl/pulsar_list.txt +1 -0
- transitionlistener/tab_data/HLV-O2-PLI.csv +82 -0
- transitionlistener/tab_data/HLV-O2-noise.csv +83 -0
- transitionlistener/tab_data/HLVK-design-PLI.csv +61 -0
- transitionlistener/tab_data/HLVK-design-noise.csv +83 -0
- transitionlistener/tab_data/NG15_PLI_hc.csv +31 -0
- transitionlistener/tab_data/NG15_noise_hc.csv +56 -0
- transitionlistener/tab_data/PLI-dataset.csv +327 -0
- transitionlistener/tab_data/energydensities.dat +1001 -0
- transitionlistener/tab_data/finiteT_b.dat.txt +1999 -0
- transitionlistener/tab_data/finiteT_f.dat.txt +1000 -0
- transitionlistener/tab_data/geff_SM.dat +10009 -0
- transitionlistener/tab_data/muAres_f_Hz_PLI_h2OmegaGW.csv +131 -0
- transitionlistener/tab_data/muAres_f_Hz_h2Omega_noise.csv +99 -0
- transitionlistener/tab_data/noise-dataset.csv +327 -0
- transitionlistener/tab_data/numberdensities.dat +1001 -0
- transitionlistener/tab_data/pressures.dat +1001 -0
- transitionlistener/thermodynamics.py +686 -0
- transitionlistener/transitionObservables.py +1199 -0
- transitionlistener/transitionObservables_fixedstep.py +976 -0
- transitionlistener/transitions.py +1000 -0
- transitionlistener/tunneling1D.py +910 -0
- transitionlistener-2.0.0.dist-info/METADATA +817 -0
- transitionlistener-2.0.0.dist-info/RECORD +95 -0
- transitionlistener-2.0.0.dist-info/WHEEL +4 -0
- transitionlistener-2.0.0.dist-info/entry_points.txt +2 -0
- transitionlistener-2.0.0.dist-info/licenses/LICENSE.txt +674 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"""Nucleation-temperature search and tunneling-action bookkeeping.
|
|
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 scipy import optimize
|
|
13
|
+
|
|
14
|
+
from transitionlistener import errors
|
|
15
|
+
from transitionlistener.pathDeformation import bounceAction
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def findTunnelingTmax(DV: callable, Tmin: float, Tmax: float, tol=1e-15, maxiter=100):
|
|
19
|
+
"""Largest temperature where tunneling is energetically allowed."""
|
|
20
|
+
|
|
21
|
+
if DV(Tmax) > 0:
|
|
22
|
+
return Tmax
|
|
23
|
+
try:
|
|
24
|
+
return optimize.brentq(DV, Tmin, Tmax, xtol=tol, maxiter=maxiter)
|
|
25
|
+
except ValueError:
|
|
26
|
+
try:
|
|
27
|
+
return optimize.brentq(DV, 0.5 * (Tmin + Tmax), Tmax, xtol=tol, maxiter=maxiter)
|
|
28
|
+
except ValueError:
|
|
29
|
+
return Tmin
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def findTminFromUShapedNucl(
|
|
33
|
+
Tmin,
|
|
34
|
+
Tmax,
|
|
35
|
+
args,
|
|
36
|
+
start_phase,
|
|
37
|
+
end_phase,
|
|
38
|
+
outdict,
|
|
39
|
+
Ttol,
|
|
40
|
+
maxiter,
|
|
41
|
+
CF,
|
|
42
|
+
verbose,
|
|
43
|
+
nuclCriterion,
|
|
44
|
+
):
|
|
45
|
+
"""Find the action minimum when the nucleation criterion is U-shaped."""
|
|
46
|
+
|
|
47
|
+
def maximizer(x, *criterion_args):
|
|
48
|
+
return -evalNucleationCriterion(x, *criterion_args)
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
Ttest = np.nan
|
|
52
|
+
for temperature in np.linspace(Tmin, Tmax, 100, endpoint=False)[1:]:
|
|
53
|
+
criterion = evalNucleationCriterion(temperature, *args)
|
|
54
|
+
if not np.isinf(criterion):
|
|
55
|
+
Ttest = temperature
|
|
56
|
+
break
|
|
57
|
+
|
|
58
|
+
if np.isnan(Ttest):
|
|
59
|
+
if any(outdict[T]["trantype"] == 2 for T in outdict):
|
|
60
|
+
max_key = max(T for T in outdict if outdict[T]["trantype"] == 2)
|
|
61
|
+
if verbose:
|
|
62
|
+
print(
|
|
63
|
+
"Found a second-order transition at T = ",
|
|
64
|
+
max_key * CF,
|
|
65
|
+
"GeV while scanning a weak first-order candidate.",
|
|
66
|
+
)
|
|
67
|
+
outdict[max_key]["Tcrit"] = outdict[max_key]["Tnuc"] = max_key
|
|
68
|
+
return None
|
|
69
|
+
if all(
|
|
70
|
+
evalNucleationCriterion(T, *args) < 0
|
|
71
|
+
if Tmin <= T <= Tmax
|
|
72
|
+
else True
|
|
73
|
+
for T in outdict
|
|
74
|
+
):
|
|
75
|
+
raise errors.NucleationError("Nucleation criterion failed: too low at all temperatures.")
|
|
76
|
+
raise errors.NucleationError(
|
|
77
|
+
"Nucleation criterion failed: no finite criterion found between Tmin and Tmax."
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
result = optimize.minimize_scalar(
|
|
81
|
+
maximizer,
|
|
82
|
+
bracket=(Tmin, Ttest, Tmax),
|
|
83
|
+
args=args,
|
|
84
|
+
method="brent",
|
|
85
|
+
options={"xtol": (Tmax - Tmin) * 1e-5, "maxiter": maxiter, "disp": 0},
|
|
86
|
+
)
|
|
87
|
+
if not result.success:
|
|
88
|
+
raise errors.NucleationError("Nucleation criterion minimization failed: " + str(result.message))
|
|
89
|
+
|
|
90
|
+
Tmin_u = float(np.squeeze(result.x))
|
|
91
|
+
action_u = outdict[Tmin_u]["action"]
|
|
92
|
+
ncMin_u = nuclCriterion(action_u, Tmin_u, start_phase, end_phase)
|
|
93
|
+
if verbose:
|
|
94
|
+
print("Finding Tmin_u done! Tmin_u = ", Tmin_u * CF, "GeV")
|
|
95
|
+
print("action_u = ", action_u * CF, "GeV")
|
|
96
|
+
print("ncMin_u = ", ncMin_u)
|
|
97
|
+
if ncMin_u < 0:
|
|
98
|
+
raise errors.NucleationError(
|
|
99
|
+
"Nucleation criterion failed because the nucleation rate is too low at all temperatures."
|
|
100
|
+
)
|
|
101
|
+
return Tmin_u
|
|
102
|
+
except Exception as err:
|
|
103
|
+
raise errors.NucleationError("Nucleation calculation failed: " + str(err)) from err
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def computeNucleationTemperature(
|
|
107
|
+
V,
|
|
108
|
+
dV,
|
|
109
|
+
d2V,
|
|
110
|
+
start_phase,
|
|
111
|
+
end_phase,
|
|
112
|
+
CF,
|
|
113
|
+
Ttol=1e-8,
|
|
114
|
+
maxiter=100,
|
|
115
|
+
phitol=1e-8,
|
|
116
|
+
overlapAngle=45.0,
|
|
117
|
+
nuclCriterion=lambda S, T, *_: 140 - S / (T + 1e-100),
|
|
118
|
+
approximate_strength_threshold=1e-4,
|
|
119
|
+
verbose=False,
|
|
120
|
+
fullTunneling_params=None,
|
|
121
|
+
allow_second_order_fallback=True,
|
|
122
|
+
):
|
|
123
|
+
"""Find the instanton and nucleation temperature for one transition."""
|
|
124
|
+
|
|
125
|
+
outdict = {}
|
|
126
|
+
fullTunneling_params = {} if fullTunneling_params is None else fullTunneling_params
|
|
127
|
+
args = (
|
|
128
|
+
start_phase,
|
|
129
|
+
end_phase,
|
|
130
|
+
V,
|
|
131
|
+
dV,
|
|
132
|
+
d2V,
|
|
133
|
+
phitol,
|
|
134
|
+
overlapAngle,
|
|
135
|
+
nuclCriterion,
|
|
136
|
+
fullTunneling_params,
|
|
137
|
+
verbose,
|
|
138
|
+
outdict,
|
|
139
|
+
CF,
|
|
140
|
+
)
|
|
141
|
+
Tmin = max(start_phase.Tmin, end_phase.Tmin)
|
|
142
|
+
|
|
143
|
+
def DV(T):
|
|
144
|
+
from transitionlistener.phases import findLocalMinimum
|
|
145
|
+
|
|
146
|
+
x0 = findLocalMinimum(start_phase.valAt(T), T, dV, d2V)
|
|
147
|
+
x1 = findLocalMinimum(end_phase.valAt(T), T, dV, d2V)
|
|
148
|
+
if np.sqrt(np.sum((x0 - start_phase.valAt(T)) ** 2)) > 1:
|
|
149
|
+
x0 = start_phase.valAt(T)
|
|
150
|
+
if np.sqrt(np.sum((x1 - end_phase.valAt(T)) ** 2)) > 1:
|
|
151
|
+
x1 = end_phase.valAt(T)
|
|
152
|
+
dist = np.sqrt(np.dot(x0 - x1, x0 - x1))
|
|
153
|
+
return V(x0, T) - (V(x1, T) + dist * 1e-3)
|
|
154
|
+
|
|
155
|
+
Tmax = findTunnelingTmax(DV, Tmin, end_phase.Tmax)
|
|
156
|
+
if not checkNucleationPossibility(
|
|
157
|
+
Tmin,
|
|
158
|
+
Tmax,
|
|
159
|
+
args,
|
|
160
|
+
outdict,
|
|
161
|
+
V,
|
|
162
|
+
dV,
|
|
163
|
+
start_phase,
|
|
164
|
+
end_phase,
|
|
165
|
+
CF,
|
|
166
|
+
approximate_strength_threshold,
|
|
167
|
+
verbose,
|
|
168
|
+
):
|
|
169
|
+
return dict(
|
|
170
|
+
Tcrit=Tmax,
|
|
171
|
+
Tnuc=Tmax,
|
|
172
|
+
Tperc=Tmax,
|
|
173
|
+
low_vev=end_phase.valAt(Tmax),
|
|
174
|
+
high_vev=start_phase.valAt(Tmax),
|
|
175
|
+
low_phase=end_phase.key,
|
|
176
|
+
high_phase=start_phase.key,
|
|
177
|
+
action=np.nan,
|
|
178
|
+
full_tunneling_info=np.nan,
|
|
179
|
+
instanton=np.nan,
|
|
180
|
+
trantype=2,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
ncrit_Tmin = evalNucleationCriterion(Tmin, *args)
|
|
184
|
+
ncrit_Tmax = evalNucleationCriterion(Tmax, *args)
|
|
185
|
+
if ncrit_Tmax >= 0:
|
|
186
|
+
if verbose:
|
|
187
|
+
print(f"Nucl. crit fulfilled at Tmax = {Tmax * CF}!")
|
|
188
|
+
rdict = outdict[Tmax]
|
|
189
|
+
rdict["Tcrit"] = Tmax
|
|
190
|
+
if rdict["trantype"] != 2:
|
|
191
|
+
rdict["full_tunneling_info"] = _filtered_tunneling_history(outdict)
|
|
192
|
+
return rdict
|
|
193
|
+
|
|
194
|
+
if ncrit_Tmin < 0:
|
|
195
|
+
if verbose:
|
|
196
|
+
print("Nucleation criterion not fulfilled at Tmin")
|
|
197
|
+
print("The bounce action might be U-shaped. Try to find the minimum of it")
|
|
198
|
+
print("between Tmin = ", Tmin * CF, "GeV and Tmax = ", Tmax * CF, "GeV.")
|
|
199
|
+
Tmin = findTminFromUShapedNucl(
|
|
200
|
+
Tmin,
|
|
201
|
+
Tmax,
|
|
202
|
+
args,
|
|
203
|
+
start_phase,
|
|
204
|
+
end_phase,
|
|
205
|
+
outdict,
|
|
206
|
+
Ttol,
|
|
207
|
+
maxiter,
|
|
208
|
+
CF,
|
|
209
|
+
verbose,
|
|
210
|
+
nuclCriterion,
|
|
211
|
+
)
|
|
212
|
+
if Tmin is None:
|
|
213
|
+
return dict(
|
|
214
|
+
Tcrit=Tmax,
|
|
215
|
+
Tnuc=Tmax,
|
|
216
|
+
Tperc=Tmax,
|
|
217
|
+
low_vev=end_phase.valAt(Tmax),
|
|
218
|
+
high_vev=start_phase.valAt(Tmax),
|
|
219
|
+
low_phase=end_phase.key,
|
|
220
|
+
high_phase=start_phase.key,
|
|
221
|
+
action=np.nan,
|
|
222
|
+
full_tunneling_info=np.nan,
|
|
223
|
+
instanton=np.nan,
|
|
224
|
+
trantype=2,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
Tnuc = optimize.brentq(evalNucleationCriterion, Tmin, Tmax, args=args, xtol=Ttol, maxiter=maxiter, disp=False)
|
|
229
|
+
if verbose:
|
|
230
|
+
print("Brentq done after first try. Tnuc = ", Tnuc * CF, "GeV")
|
|
231
|
+
except ValueError:
|
|
232
|
+
print("Brentq failed for first try, retrying with larger Ttol.")
|
|
233
|
+
try:
|
|
234
|
+
Tnuc = optimize.brentq(
|
|
235
|
+
evalNucleationCriterion,
|
|
236
|
+
Tmin,
|
|
237
|
+
Tmax,
|
|
238
|
+
args=args,
|
|
239
|
+
xtol=Ttol * 10,
|
|
240
|
+
maxiter=maxiter,
|
|
241
|
+
disp=False,
|
|
242
|
+
)
|
|
243
|
+
if verbose:
|
|
244
|
+
print("Brentq done after second try! Tnuc = ", Tnuc * CF, "GeV")
|
|
245
|
+
except Exception as err:
|
|
246
|
+
if verbose:
|
|
247
|
+
print("Brentq failed again after increasing the numerical tolerance by a factor 10.")
|
|
248
|
+
raise errors.NucleationError("Nucleation criterion failed due to unknown reason.") from err
|
|
249
|
+
|
|
250
|
+
if Tnuc not in outdict:
|
|
251
|
+
raise errors.NucleationError(
|
|
252
|
+
"Tnuc not in outdict. This can only happen if the nucleation criterion "
|
|
253
|
+
"could not be fulfilled at any temperature."
|
|
254
|
+
)
|
|
255
|
+
rdict = outdict[Tnuc]
|
|
256
|
+
rdict["full_tunneling_info"] = _filtered_tunneling_history(outdict)
|
|
257
|
+
|
|
258
|
+
if "trantype" in rdict and rdict["trantype"] > 0:
|
|
259
|
+
if rdict["trantype"] == 2:
|
|
260
|
+
if verbose:
|
|
261
|
+
print("The transition is actually second-order because the action is zero at the transition.")
|
|
262
|
+
rdict["Tcrit"] = rdict["Tnuc"] = Tnuc
|
|
263
|
+
return rdict
|
|
264
|
+
rdict["Tcrit"] = Tmax
|
|
265
|
+
return rdict
|
|
266
|
+
|
|
267
|
+
if "trantype" in rdict and rdict["trantype"] == 0:
|
|
268
|
+
keys = sorted(key for key in outdict if key != "full_tunneling_info" and key < Tnuc)
|
|
269
|
+
max_key = keys[-1] if keys else None
|
|
270
|
+
if max_key is not None and outdict[max_key]["trantype"] == 2:
|
|
271
|
+
if not allow_second_order_fallback:
|
|
272
|
+
raise errors.NucleationError(
|
|
273
|
+
"Nucleation criterion converged to a pathological trantype = 0 candidate, "
|
|
274
|
+
"and the only nearby fallback is a cached second-order entry just below Tnuc."
|
|
275
|
+
)
|
|
276
|
+
if verbose:
|
|
277
|
+
print(
|
|
278
|
+
"The found transition had an infinite action. But found a second-order "
|
|
279
|
+
"transition just below Tnuc. Returning it. Tcrit = ",
|
|
280
|
+
max_key * CF,
|
|
281
|
+
"GeV",
|
|
282
|
+
)
|
|
283
|
+
rdict = outdict[max_key]
|
|
284
|
+
rdict["Tcrit"] = rdict["Tnuc"] = max_key
|
|
285
|
+
return rdict
|
|
286
|
+
if verbose:
|
|
287
|
+
print(
|
|
288
|
+
"The transition has action = 0 and trantype = 0, but no second-order "
|
|
289
|
+
"transition was found just below Tnuc. This is likely numerical."
|
|
290
|
+
)
|
|
291
|
+
return rdict
|
|
292
|
+
|
|
293
|
+
raise errors.NucleationError(
|
|
294
|
+
"The nucleation computation failed: either the barrier is too high or the transition is second order."
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def checkNucleationPossibility(
|
|
299
|
+
Tmin,
|
|
300
|
+
Tmax,
|
|
301
|
+
args,
|
|
302
|
+
outdict,
|
|
303
|
+
V,
|
|
304
|
+
dV,
|
|
305
|
+
start_phase,
|
|
306
|
+
end_phase,
|
|
307
|
+
conversionFactor,
|
|
308
|
+
apprx_strength_thr,
|
|
309
|
+
verbose,
|
|
310
|
+
) -> bool:
|
|
311
|
+
"""Quickly reject hidden second-order or negligibly weak transitions."""
|
|
312
|
+
|
|
313
|
+
nuclCritTmax = evalNucleationCriterion(Tmax, *args)
|
|
314
|
+
if np.isinf(nuclCritTmax) and Tmax in outdict:
|
|
315
|
+
rdict = outdict[Tmax]
|
|
316
|
+
if "trantype" in rdict and rdict["trantype"] == 2:
|
|
317
|
+
if verbose:
|
|
318
|
+
print("The transition is actually second-order because the action is zero at the transition.")
|
|
319
|
+
return False
|
|
320
|
+
|
|
321
|
+
def approx_strength(T):
|
|
322
|
+
DV = V(start_phase.valAt(T), T) - V(end_phase.valAt(T), T)
|
|
323
|
+
return np.abs(DV) / T**4
|
|
324
|
+
|
|
325
|
+
approx_strength_range = np.array([approx_strength(T) for T in np.linspace(Tmin, Tmax, 100)])
|
|
326
|
+
if np.all(approx_strength_range < apprx_strength_thr):
|
|
327
|
+
if verbose:
|
|
328
|
+
print(f"PT strength {np.max(approx_strength_range)} below threshold: {apprx_strength_thr}.")
|
|
329
|
+
print(f"This is treated as a second-order transition at Tmax = {Tmax * conversionFactor} GeV.")
|
|
330
|
+
return False
|
|
331
|
+
return True
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def evalNucleationCriterion(
|
|
335
|
+
T,
|
|
336
|
+
start_phase,
|
|
337
|
+
end_phase,
|
|
338
|
+
V,
|
|
339
|
+
dV,
|
|
340
|
+
d2V,
|
|
341
|
+
phitol,
|
|
342
|
+
overlapAngle,
|
|
343
|
+
nuclCriterion,
|
|
344
|
+
fullTunneling_params,
|
|
345
|
+
verbose,
|
|
346
|
+
outdict,
|
|
347
|
+
conversionFactor,
|
|
348
|
+
):
|
|
349
|
+
"""Evaluate the nucleation criterion and cache the action in ``outdict``."""
|
|
350
|
+
|
|
351
|
+
try:
|
|
352
|
+
T = T[0]
|
|
353
|
+
except Exception:
|
|
354
|
+
pass
|
|
355
|
+
|
|
356
|
+
if T in outdict:
|
|
357
|
+
return nuclCriterion(outdict[T]["action"], T, start_phase, end_phase)
|
|
358
|
+
|
|
359
|
+
from transitionlistener.phases import findLocalMinimum
|
|
360
|
+
|
|
361
|
+
x0 = findLocalMinimum(start_phase.valAt(T), T, dV, d2V)
|
|
362
|
+
if np.sqrt(np.sum((x0 - start_phase.valAt(T)) ** 2)) > 1:
|
|
363
|
+
x0 = start_phase.valAt(T)
|
|
364
|
+
V0 = V(x0, T)
|
|
365
|
+
|
|
366
|
+
if end_phase.Tmin > T:
|
|
367
|
+
if verbose:
|
|
368
|
+
print(
|
|
369
|
+
"Phase %s not valid at T = %g" % (end_phase.key, T * conversionFactor),
|
|
370
|
+
"GeV < Tmin = ",
|
|
371
|
+
end_phase.Tmin * conversionFactor,
|
|
372
|
+
"GeV",
|
|
373
|
+
)
|
|
374
|
+
return np.inf
|
|
375
|
+
if end_phase.Tmax < T:
|
|
376
|
+
if verbose:
|
|
377
|
+
print(
|
|
378
|
+
"Phase %s not valid at T = %g" % (end_phase.key, T * conversionFactor),
|
|
379
|
+
"GeV > Tmax = ",
|
|
380
|
+
end_phase.Tmax * conversionFactor,
|
|
381
|
+
"GeV",
|
|
382
|
+
)
|
|
383
|
+
return -np.inf
|
|
384
|
+
|
|
385
|
+
x1 = findLocalMinimum(end_phase.valAt(T), T, dV, d2V)
|
|
386
|
+
if np.sqrt(np.sum((x1 - end_phase.valAt(T)) ** 2)) > 1:
|
|
387
|
+
x1 = end_phase.valAt(T)
|
|
388
|
+
if V(x1, T) >= V0 and verbose:
|
|
389
|
+
print(
|
|
390
|
+
"Tunneling energetically not possible. Tmax might be too high or the "
|
|
391
|
+
"numerical accuracy is not sufficient. This is not a problem, just a warning."
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
tdict = dict(low_vev=x1, high_vev=x0, Tnuc=T, low_phase=end_phase.key, high_phase=start_phase.key)
|
|
395
|
+
bounceAction(
|
|
396
|
+
T,
|
|
397
|
+
V,
|
|
398
|
+
dV,
|
|
399
|
+
outdict,
|
|
400
|
+
tdict,
|
|
401
|
+
verbose=verbose,
|
|
402
|
+
conversionFactor=conversionFactor,
|
|
403
|
+
**fullTunneling_params,
|
|
404
|
+
)
|
|
405
|
+
return nuclCriterion(outdict[T]["action"], T, start_phase, end_phase)
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def _filtered_tunneling_history(outdict: dict) -> dict:
|
|
409
|
+
"""Return cached tunneling data without large instanton payloads."""
|
|
410
|
+
|
|
411
|
+
filtered = {T: {key: value for key, value in payload.items() if key != "instanton"} for T, payload in outdict.items()}
|
|
412
|
+
return dict(sorted(filtered.items()))
|