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 void | 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 void | 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...
|
|
|
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...
|
|
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...
|
|
virtual double smash::Action::get_total_weight |
( |
| ) |
const |
|
pure virtual |
Return the total weight value, which is mainly used for the weight output entry.
It has different meanings depending of the type of action. It is the total cross section in case of a ScatterAction, the total decay width in case of a DecayAction and the shining weight in case of a DecayActionDilepton.
Prefer to use a more specific function. If there is no weight for the action type, 0 should be returned.
- Returns
- total cross section, decay width or shining weight
Implemented in smash::ThermalizationAction, smash::BremsstrahlungAction, smash::DecayAction, smash::DecayActionDilepton, smash::HypersurfacecrossingAction, smash::ScatterAction, smash::ScatterActionMulti, smash::ScatterActionPhoton, and smash::WallcrossingAction.
virtual double smash::Action::get_partial_weight |
( |
| ) |
const |
|
pure virtual |
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 311 of file action.cc.
330 const size_t n = m.size();
332 sampled_momenta.resize(
n);
335 std::vector<double> msum(
n);
337 for (
size_t i = 1; i <
n; i++) {
338 msum[i] = msum[i - 1] + m[i];
340 const double msum_all = msum[
n - 1];
341 int rejection_counter = -1;
342 if (sqrts <= msum_all) {
343 logg[
LAction].error() <<
"sample_manybody_phasespace_impl: "
344 <<
"Can't sample when sqrts = " << sqrts
345 <<
" < msum = " << msum_all;
349 std::vector<double> Minv(
n);
351 double weight_sqr_max = 1;
352 const double Ekin_share = (sqrts - msum_all) / (
n - 1);
353 for (
size_t i = 1; i <
n; i++) {
356 weight_sqr_max *=
pCM_sqr(i * Ekin_share + msum[i],
357 (i - 1) * Ekin_share + msum[i - 1], m[i]);
361 const double safety_factor = 1.1 + (
n - 2) * 0.2;
362 weight_sqr_max *= (safety_factor * safety_factor);
363 bool first_warning =
true;
369 Minv[
n - 1] = sqrts - msum_all;
370 for (
size_t i = 1; i <
n - 1; i++) {
373 std::sort(Minv.begin(), Minv.end());
374 for (
size_t i = 0; i <
n; i++) {
378 double weight_sqr = 1;
379 for (
size_t i = 1; i <
n; i++) {
380 weight_sqr *=
pCM_sqr(Minv[i], Minv[i - 1], m[i]);
385 w = weight_sqr / weight_sqr_max;
388 <<
"sample_manybody_phasespace_impl: alarm, weight > 1, w^2 = " << w
389 <<
". Increase safety factor." << std::endl;
391 if (rejection_counter > 20 && first_warning) {
392 logg[
LAction].warn() <<
"sample_manybody_phasespace_impl: "
393 <<
"likely hanging, way too many rejections,"
394 <<
" n = " <<
n <<
", sqrts = " << sqrts
395 <<
", msum = " << msum_all;
396 first_warning =
false;
398 }
while (w < r01 * r01);
401 std::vector<ThreeVector>
beta(
n);
402 for (
size_t i =
n - 1; i > 0; i--) {
403 const double pcm =
pCM(Minv[i], Minv[i - 1], m[i]);
405 phitheta.distribute_isotropically();
406 const ThreeVector isotropic_unitvector = phitheta.threevec();
407 sampled_momenta[i] = FourVector(std::sqrt(m[i] * m[i] + pcm * pcm),
408 pcm * isotropic_unitvector);
410 beta[i - 2] = pcm * isotropic_unitvector /
411 std::sqrt(pcm * pcm + Minv[i - 1] * Minv[i - 1]);
414 sampled_momenta[0] = FourVector(std::sqrt(m[0] * m[0] + pcm * pcm),
415 -pcm * isotropic_unitvector);
419 for (
size_t i = 0; i <
n - 2; i++) {
421 FourVector ptot = FourVector(0.0, 0.0, 0.0, 0.0);
422 for (
size_t j = 0; j <= i + 1; j++) {
423 ptot += sampled_momenta[j];
425 logg[
LAction].debug() <<
"Total momentum of 0.." << i + 1 <<
" = "
426 << ptot.threevec() <<
" and should be (0, 0, 0). "
430 for (
size_t j = 0; j <= i + 1; j++) {
431 sampled_momenta[j] = sampled_momenta[j].lorentz_boost(
beta[i]);
435 FourVector ptot_all = FourVector(0.0, 0.0, 0.0, 0.0);
436 for (
size_t j = 0; j <
n; j++) {
437 ptot_all += sampled_momenta[j];
439 logg[
LAction].debug() <<
"Total 4-momentum = " << ptot_all <<
", should be ("
440 << 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