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::ThermalizationAction, smash::ScatterActionPhoton, smash::ScatterActionMulti, smash::ScatterAction, smash::HypersurfacecrossingAction, smash::FreeforallAction, smash::DecayActionDilepton, smash::DecayAction, and smash::BremsstrahlungAction.
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) {
343 <<
"An interaction requiring " << sqrts
344 <<
"GeV was attempted below the minimum energy threshold" << msum_all
345 <<
" GeV, but was ignored.\nThis is a known internal error which does "
346 "not significantly affect physical results, and will be fixed in a "
347 "near-future release.";
348 throw StochasticBelowEnergyThreshold(
"Ignoring this action.");
352 std::vector<double> Minv(
n);
354 double weight_sqr_max = 1;
355 const double Ekin_share = (sqrts - msum_all) / (
n - 1);
356 for (
size_t i = 1; i <
n; i++) {
359 weight_sqr_max *=
pCM_sqr(i * Ekin_share + msum[i],
360 (i - 1) * Ekin_share + msum[i - 1], m[i]);
364 const double safety_factor = 1.1 + (
n - 2) * 0.2;
365 weight_sqr_max *= (safety_factor * safety_factor);
366 bool first_warning =
true;
372 Minv[
n - 1] = sqrts - msum_all;
373 for (
size_t i = 1; i <
n - 1; i++) {
376 std::sort(Minv.begin(), Minv.end());
377 for (
size_t i = 0; i <
n; i++) {
381 double weight_sqr = 1;
382 for (
size_t i = 1; i <
n; i++) {
383 weight_sqr *=
pCM_sqr(Minv[i], Minv[i - 1], m[i]);
388 w = weight_sqr / weight_sqr_max;
391 <<
"sample_manybody_phasespace_impl: alarm, weight > 1, w^2 = " << w
392 <<
". Increase safety factor." << std::endl;
394 if (rejection_counter > 20 && first_warning) {
395 logg[
LAction].warn() <<
"sample_manybody_phasespace_impl: "
396 <<
"likely hanging, way too many rejections,"
397 <<
" n = " <<
n <<
", sqrts = " << sqrts
398 <<
", msum = " << msum_all;
399 first_warning =
false;
401 }
while (w < r01 * r01);
404 std::vector<ThreeVector>
beta(
n);
405 for (
size_t i =
n - 1; i > 0; i--) {
406 const double pcm =
pCM(Minv[i], Minv[i - 1], m[i]);
408 phitheta.distribute_isotropically();
409 const ThreeVector isotropic_unitvector = phitheta.threevec();
410 sampled_momenta[i] = FourVector(std::sqrt(m[i] * m[i] + pcm * pcm),
411 pcm * isotropic_unitvector);
413 beta[i - 2] = pcm * isotropic_unitvector /
414 std::sqrt(pcm * pcm + Minv[i - 1] * Minv[i - 1]);
417 sampled_momenta[0] = FourVector(std::sqrt(m[0] * m[0] + pcm * pcm),
418 -pcm * isotropic_unitvector);
422 for (
size_t i = 0; i <
n - 2; i++) {
424 FourVector ptot = FourVector(0.0, 0.0, 0.0, 0.0);
425 for (
size_t j = 0; j <= i + 1; j++) {
426 ptot += sampled_momenta[j];
428 logg[
LAction].debug() <<
"Total momentum of 0.." << i + 1 <<
" = "
429 << ptot.threevec() <<
" and should be (0, 0, 0). "
433 for (
size_t j = 0; j <= i + 1; j++) {
434 sampled_momenta[j] = sampled_momenta[j].lorentz_boost(
beta[i]);
438 FourVector ptot_all = FourVector(0.0, 0.0, 0.0, 0.0);
439 for (
size_t j = 0; j <
n; j++) {
440 ptot_all += sampled_momenta[j];
442 logg[
LAction].debug() <<
"Total 4-momentum = " << ptot_all <<
", should be ("
443 << 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