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...
|
|
|
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::WallcrossingAction, smash::ScatterActionPhoton, smash::ScatterActionMulti, smash::ScatterAction, smash::HypersurfacecrossingAction, smash::DecayActionDilepton, smash::DecayAction, smash::BremsstrahlungAction, smash::ThermalizationAction, and smash::FreeforallAction.
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 313 of file action.cc.
332 const size_t n = m.size();
334 sampled_momenta.resize(
n);
337 std::vector<double> msum(
n);
338 std::partial_sum(m.begin(), m.end(), msum.begin());
339 const double msum_all = msum[
n - 1];
340 int rejection_counter = -1;
341 if (sqrts <= msum_all) {
342 logg[
LAction].error() <<
"sample_manybody_phasespace_impl: "
343 <<
"Can't sample when sqrts = " << sqrts
344 <<
" < msum = " << msum_all;
348 std::vector<double> Minv(
n);
350 double weight_sqr_max = 1;
351 const double Ekin_share = (sqrts - msum_all) / (
n - 1);
352 for (
size_t i = 1; i <
n; i++) {
355 weight_sqr_max *=
pCM_sqr(i * Ekin_share + msum[i],
356 (i - 1) * Ekin_share + msum[i - 1], m[i]);
360 const double safety_factor = 1.1 + (
n - 2) * 0.2;
361 weight_sqr_max *= (safety_factor * safety_factor);
362 bool first_warning =
true;
368 Minv[
n - 1] = sqrts - msum_all;
369 for (
size_t i = 1; i <
n - 1; i++) {
372 std::sort(Minv.begin(), Minv.end());
373 for (
size_t i = 0; i <
n; i++) {
377 double weight_sqr = 1;
378 for (
size_t i = 1; i <
n; i++) {
379 weight_sqr *=
pCM_sqr(Minv[i], Minv[i - 1], m[i]);
384 w = weight_sqr / weight_sqr_max;
387 <<
"sample_manybody_phasespace_impl: alarm, weight > 1, w^2 = " << w
388 <<
". Increase safety factor." << std::endl;
390 if (rejection_counter > 20 && first_warning) {
391 logg[
LAction].warn() <<
"sample_manybody_phasespace_impl: "
392 <<
"likely hanging, way too many rejections,"
393 <<
" n = " <<
n <<
", sqrts = " << sqrts
394 <<
", msum = " << msum_all;
395 first_warning =
false;
397 }
while (w < r01 * r01);
400 std::vector<ThreeVector>
beta(
n);
401 for (
size_t i =
n - 1; i > 0; i--) {
402 const double pcm =
pCM(Minv[i], Minv[i - 1], m[i]);
404 phitheta.distribute_isotropically();
405 const ThreeVector isotropic_unitvector = phitheta.threevec();
406 sampled_momenta[i] = FourVector(std::sqrt(m[i] * m[i] + pcm * pcm),
407 pcm * isotropic_unitvector);
409 beta[i - 2] = pcm * isotropic_unitvector /
410 std::sqrt(pcm * pcm + Minv[i - 1] * Minv[i - 1]);
413 sampled_momenta[0] = FourVector(std::sqrt(m[0] * m[0] + pcm * pcm),
414 -pcm * isotropic_unitvector);
418 for (
size_t i = 0; i <
n - 2; i++) {
420 FourVector ptot = FourVector(0.0, 0.0, 0.0, 0.0);
421 for (
size_t j = 0; j <= i + 1; j++) {
422 ptot += sampled_momenta[j];
424 logg[
LAction].debug() <<
"Total momentum of 0.." << i + 1 <<
" = "
425 << ptot.threevec() <<
" and should be (0, 0, 0). "
429 for (
size_t j = 0; j <= i + 1; j++) {
430 sampled_momenta[j] = sampled_momenta[j].lorentz_boost(
beta[i]);
434 FourVector ptot_all = FourVector(0.0, 0.0, 0.0, 0.0);
435 for (
size_t j = 0; j <
n; j++) {
436 ptot_all += sampled_momenta[j];
438 logg[
LAction].debug() <<
"Total 4-momentum = " << ptot_all <<
", should be ("
439 << 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