Action is the base class for a generic process that takes a number of incoming particles and transforms them into any number of outgoing particles.
Currently such an action can be either a decay, a two-body collision, a wallcrossing or a thermalization. (see derived classes).
Definition at line 35 of file action.h.
|
| | Action (const ParticleList &in_part, double time) |
| | Construct an action object with incoming particles and relative time. More...
|
| |
| | Action (const ParticleData &in_part, const ParticleData &out_part, double time, ProcessType type) |
| | Construct an action object with the incoming particles, relative time, and the already known outgoing particles and type of the process. More...
|
| |
| | Action (const ParticleList &in_part, const ParticleList &out_part, double absolute_execution_time, ProcessType type) |
| | Construct an action object with the incoming particles, absolute time, and the already known outgoing particles and type of the process. More...
|
| |
| | Action (const Action &)=delete |
| | Copying is disabled. Use pointers or create a new Action. More...
|
| |
| virtual | ~Action () |
| | Virtual Destructor. More...
|
| |
| bool | operator< (const Action &rhs) const |
| | Determine whether one action takes place before another in time. More...
|
| |
| virtual double | get_total_weight () const =0 |
| | Return the total weight value, which is mainly used for the weight output entry. More...
|
| |
| virtual double | get_partial_weight () const =0 |
| | Return the specific weight for the chosen outgoing channel, which is mainly used for the partial weight output entry. More...
|
| |
| virtual ProcessType | get_type () const |
| | Get the process type. More...
|
| |
| template<typename Branch > |
| void | add_process (ProcessBranchPtr< Branch > &p, ProcessBranchList< Branch > &subprocesses, double &total_weight) |
| | Add a new subprocess. More...
|
| |
| template<typename Branch > |
| void | add_processes (ProcessBranchList< Branch > pv, ProcessBranchList< Branch > &subprocesses, double &total_weight) |
| | Add several new subprocesses at once. More...
|
| |
| virtual void | generate_final_state ()=0 |
| | Generate the final state for this action. More...
|
| |
| virtual double | perform (Particles *particles, uint32_t id_process) |
| | Actually perform the action, e.g. More...
|
| |
| bool | is_valid (const Particles &particles) const |
| | Check whether the action still applies. More...
|
| |
| bool | is_pauli_blocked (const std::vector< Particles > &ensembles, const PauliBlocker &p_bl) const |
| | Check if the action is Pauli-blocked. More...
|
| |
| const ParticleList & | incoming_particles () const |
| | Get the list of particles that go into the action. More...
|
| |
| void | update_incoming (const Particles &particles) |
| | Update the incoming particles that are stored in this action to the state they have in the global particle list. More...
|
| |
| const ParticleList & | outgoing_particles () const |
| | Get the list of particles that resulted from the action. More...
|
| |
| double | time_of_execution () const |
| | Get the time at which the action is supposed to be performed. More...
|
| |
| virtual double | check_conservation (const uint32_t id_process) const |
| | Check various conservation laws. More...
|
| |
| double | sqrt_s () const |
| | Determine the total energy in the center-of-mass frame [GeV]. More...
|
| |
| FourVector | total_momentum_of_outgoing_particles () const |
| | Calculate the total kinetic momentum of the outgoing particles. More...
|
| |
| FourVector | get_interaction_point () const |
| | Get the interaction point. More...
|
| |
| std::pair< FourVector, FourVector > | get_potential_at_interaction_point () const |
| | Get the skyrme and asymmetry potential at the interaction point. More...
|
| |
| void | set_stochastic_pos_idx () |
| | Setter function that stores a random incoming particle index latter used to determine the interaction point. More...
|
| |
| void | assign_unpolarized_spin_vector_to_outgoing_particles () |
| | Assign an unpolarized spin vector to all outgoing particles. More...
|
| |
|
| FourVector | total_momentum () const |
| | Sum of 4-momenta of incoming particles. More...
|
| |
| template<typename Branch > |
| const Branch * | choose_channel (const ProcessBranchList< Branch > &subprocesses, double total_weight) |
| | Decide for a particular final-state channel via Monte-Carlo and return it as a ProcessBranch. More...
|
| |
| virtual std::pair< double, double > | sample_masses (double kinetic_energy_cm) const |
| | Sample final-state masses in general X->2 processes (thus also fixing the absolute c.o.m. More...
|
| |
| virtual void | sample_angles (std::pair< double, double > masses, double kinetic_energy_cm) |
| | Sample final-state momenta in general X->2 processes (here: using an isotropical angular distribution). More...
|
| |
| virtual void | sample_2body_phasespace () |
| | Sample the full 2-body phase-space (masses, momenta, angles) in the center-of-mass frame for the final state particles. More...
|
| |
| virtual void | sample_manybody_phasespace () |
| | Sample the full n-body phase-space (masses, momenta, angles) in the center-of-mass frame for the final state particles. More...
|
| |
| void | assign_formation_time_to_outgoing_particles () |
| | Assign the formation time to the outgoing particles. More...
|
| |
| virtual void | format_debug_output (std::ostream &out) const =0 |
| | Writes information about this action to the out stream. More...
|
| |
| void smash::Action::sample_manybody_phasespace_impl |
( |
double |
sqrts, |
|
|
const std::vector< double > & |
m, |
|
|
std::vector< FourVector > & |
sampled_momenta |
|
) |
| |
|
static |
Implementation of the full n-body phase-space sampling (masses, momenta, angles) in the center-of-mass frame for the final state particles.
Function is static for convenient testing.
Using the M-method from CERN-68-15 report, paragraph 9.6 1) Generate invariant masses M12, M123, M1234, etc from distribution dM12 x dM123 x dM1234 x ... This is not trivial because of the integration limits. Here the idea is to change variables to T12 = M12 - (m1 + m2), T123 = M123 - (m1 + m2 + m3), etc. Then we need to generate uniform T such that 0 <= T12 <= T123 <= T1234 <= ... <= sqrts - sum (m_i). For the latter there is a trick: generate values uniformly in [0, sqrts - sum (m_i)] and then sort the values. 2) accept or reject this combination of invariant masses with weight proportional to R2(sqrt, M_{n-1}, m_n) x R2(M_{n-1}, M_{n-2}, m_{n-1}) x ... x R2(M2, m1, m2) x (prod M_i). Maximum weight is estmated heuristically, here I'm using an idea by Scott Pratt that maximum is close to T12 = T123 = T1234 = ... = (sqrts - sum (m_i)) / (n - 1)
Definition at line 316 of file action.cc.
335 const size_t n = m.size();
337 sampled_momenta.resize(
n);
340 std::vector<double> msum(
n);
341 std::partial_sum(m.begin(), m.end(), msum.begin());
342 const double msum_all = msum[
n - 1];
343 int rejection_counter = -1;
344 if (sqrts <= msum_all) {
346 <<
"An interaction requiring " << sqrts
347 <<
"GeV was attempted below the minimum energy threshold" << msum_all
348 <<
" GeV, but was ignored.\nThis is a known internal error which does "
349 "not significantly affect physical results, and will be fixed in a "
350 "near-future release.";
351 throw StochasticBelowEnergyThreshold(
"Ignoring this action.");
355 std::vector<double> Minv(
n);
357 double weight_sqr_max = 1;
358 const double Ekin_share = (sqrts - msum_all) / (
n - 1);
359 for (
size_t i = 1; i <
n; i++) {
362 weight_sqr_max *=
pCM_sqr(i * Ekin_share + msum[i],
363 (i - 1) * Ekin_share + msum[i - 1], m[i]);
367 const double safety_factor = 1.1 + (
n - 2) * 0.2;
368 weight_sqr_max *= (safety_factor * safety_factor);
369 bool first_warning =
true;
375 Minv[
n - 1] = sqrts - msum_all;
376 for (
size_t i = 1; i <
n - 1; i++) {
379 std::sort(Minv.begin(), Minv.end());
380 for (
size_t i = 0; i <
n; i++) {
384 double weight_sqr = 1;
385 for (
size_t i = 1; i <
n; i++) {
386 weight_sqr *=
pCM_sqr(Minv[i], Minv[i - 1], m[i]);
391 w = weight_sqr / weight_sqr_max;
394 <<
"sample_manybody_phasespace_impl: alarm, weight > 1, w^2 = " << w
395 <<
". Increase safety factor." << std::endl;
397 if (rejection_counter > 20 && first_warning) {
398 logg[
LAction].warn() <<
"sample_manybody_phasespace_impl: "
399 <<
"likely hanging, way too many rejections,"
400 <<
" n = " <<
n <<
", sqrts = " << sqrts
401 <<
", msum = " << msum_all;
402 first_warning =
false;
404 }
while (w < r01 * r01);
407 std::vector<ThreeVector>
beta(
n);
408 for (
size_t i =
n - 1; i > 0; i--) {
409 const double pcm =
pCM(Minv[i], Minv[i - 1], m[i]);
411 phitheta.distribute_isotropically();
412 const ThreeVector isotropic_unitvector = phitheta.threevec();
413 sampled_momenta[i] = FourVector(std::sqrt(m[i] * m[i] + pcm * pcm),
414 pcm * isotropic_unitvector);
416 beta[i - 2] = pcm * isotropic_unitvector /
417 std::sqrt(pcm * pcm + Minv[i - 1] * Minv[i - 1]);
420 sampled_momenta[0] = FourVector(std::sqrt(m[0] * m[0] + pcm * pcm),
421 -pcm * isotropic_unitvector);
425 for (
size_t i = 0; i <
n - 2; i++) {
427 FourVector ptot = FourVector(0.0, 0.0, 0.0, 0.0);
428 for (
size_t j = 0; j <= i + 1; j++) {
429 ptot += sampled_momenta[j];
431 logg[
LAction].debug() <<
"Total momentum of 0.." << i + 1 <<
" = "
432 << ptot.threevec() <<
" and should be (0, 0, 0). "
436 for (
size_t j = 0; j <= i + 1; j++) {
437 sampled_momenta[j] = sampled_momenta[j].lorentz_boost(
beta[i]);
441 FourVector ptot_all = FourVector(0.0, 0.0, 0.0, 0.0);
442 for (
size_t j = 0; j <
n; j++) {
443 ptot_all += sampled_momenta[j];
445 logg[
LAction].debug() <<
"Total 4-momentum = " << ptot_all <<
", should be ("
446 << sqrts <<
", 0, 0, 0)" << std::endl;
T beta(T a, T b)
Draws a random number from a beta-distribution, where probability density of is .
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
T pCM_sqr(const T sqrts, const T mass_a, const T mass_b) noexcept