19 : sig_(param.gaussian_sigma),
20 rc_(conf.take({
"Gaussian_Cutoff"}, 2.2)),
21 rr_(conf.take({
"Spatial_Averaging_Radius"}, 1.86)),
22 rp_(conf.take({
"Momentum_Averaging_Radius"}, 0.08)),
23 ntest_(param.testparticles),
24 n_ensembles_(param.n_ensembles) {
49 if (ntest_ * n_ensembles_ < 20) {
51 "Phase-space density calculation in Pauli blocking"
52 " will not work reasonably. Either use testparticles or ensembles, or "
54 " The recommended testparticles * ensembles is at least 20");
57 if (rc_ < rr_ || rr_ < 0.0 || rp_ < 0) {
59 "Please choose reasonable parameters for Pauli blocking:"
60 "All radii have to be positive and Gaussian_Cutoff should"
61 "be larger than Spatial_Averaging_Radius");
64 init_weights_analytical();
67 PauliBlocker::~PauliBlocker() {}
70 const std::vector<Particles> &ensembles,
72 const ParticleList &disregard)
const {
78 for (
const Particles &particles : ensembles) {
81 if (part.pdgcode() != pdg) {
85 const double pdist_sqr = (part.momentum().threevec() -
p).sqr();
86 if (pdist_sqr > rp_ * rp_) {
89 const double rdist_sqr = (part.position().threevec() - r).sqr();
91 if (rdist_sqr >= (rr_ + rc_) * (rr_ + rc_)) {
95 bool to_disregard =
false;
96 for (
const auto &disregard_part : disregard) {
97 if (part.id() == disregard_part.id()) {
105 const double i_real =
106 std::sqrt(rdist_sqr) / (rr_ + rc_) * weights_.size();
107 const size_t i = std::floor(i_real);
108 const double rest = i_real - i;
109 if (
likely(i + 1 < weights_.size())) {
110 f += weights_[i] * rest + weights_[i + 1] * (1. - rest);
114 return f / ntest_ / n_ensembles_;
117 void PauliBlocker::init_weights_analytical() {
118 const double pi = M_PI;
119 const double sqrt2 = std::sqrt(2.);
120 const double sqrt_2pi = std::sqrt(2. * pi);
122 const double phase_volume =
123 2 * (4. / 3. * pi * rr_ * rr_ * rr_) * (4. / 3. * pi * rp_ * rp_ * rp_) /
127 std::erf(rc_ / sqrt2 / sig_) -
128 rc_ * 2 / sqrt_2pi / sig_ * std::exp(-0.5 * rc_ * rc_ / sig_ / sig_);
132 const double d_pos = (rr_ + rc_) /
static_cast<double>(weights_.size());
134 for (
size_t k = 0; k < weights_.size(); k++) {
136 const double rj = d_pos * k;
139 const double A = rr_ / sqrt2 / sig_;
140 integral = sqrt_2pi * sig_ * std::erf(A) - 2 * rr_ * std::exp(-A * A);
141 integral *= sig_ * sig_;
142 }
else if (rc_ > rj + rr_) {
143 const double A = (rj + rr_) / sqrt2 / sig_;
144 const double B = (rj - rr_) / sqrt2 / sig_;
145 integral = sig_ / rj * (std::exp(-A * A) - std::exp(-B * B)) +
146 0.5 * sqrt_2pi * (std::erf(A) - std::erf(B));
147 integral *= sig_ * sig_ * sig_;
149 const double A = rc_ / sqrt2 / sig_;
150 const double B = (rj - rr_) / sqrt2 / sig_;
151 const double C = (rc_ - rj) * (rc_ - rj) - rr_ * rr_ + 2 * sig_ * sig_;
153 (0.5 * std::exp(-A * A) * C - sig_ * sig_ * std::exp(-B * B)) / rj +
154 0.5 * sqrt_2pi * sig_ * (std::erf(A) - std::erf(B));
155 integral *= sig_ * sig_;
157 integral *= 2 * pi / std::pow(2 * pi * sig_ * sig_, 1.5);
158 weights_[k] = integral / norm / phase_volume;
Interface to the SMASH configuration files.
ParticleData contains the dynamic information of a certain particle.
The Particles class abstracts the storage and manipulation of particles.
PauliBlocker(Configuration conf, const ExperimentParameters ¶meters)
PauliBlocker constructor.
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
The ThreeVector class represents a physical three-vector with the components .
Collection of useful constants that are known at compile time.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
#define likely(x)
Tell the branch predictor that this expression is likely true.
static constexpr int LPauliBlocking
constexpr double hbarc
GeV <-> fm conversion factor.
constexpr double really_small
Numerical error tolerance.
Helper structure for Experiment.