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) {
50 "Phase-space density calculation in Pauli blocking"
51 " will not work reasonably for a small number of testparticles."
52 " The recommended number of testparticles is 20.");
55 if (rc_ < rr_ || rr_ < 0.0 || rp_ < 0) {
57 "Please choose reasonable parameters for Pauli blocking:"
58 "All radii have to be positive and Gaussian_Cutoff should"
59 "be larger than Spatial_Averaging_Radius");
62 init_weights_analytical();
65 PauliBlocker::~PauliBlocker() {}
70 const ParticleList &disregard)
const {
76 for (
const auto &part : particles) {
78 if (part.pdgcode() != pdg) {
82 const double pdist_sqr = (part.momentum().threevec() -
p).sqr();
83 if (pdist_sqr > rp_ * rp_) {
86 const double rdist_sqr = (part.position().threevec() - r).sqr();
88 if (rdist_sqr >= (rr_ + rc_) * (rr_ + rc_)) {
92 bool to_disregard =
false;
93 for (
const auto &disregard_part : disregard) {
94 if (part.id() == disregard_part.id()) {
102 const double i_real = std::sqrt(rdist_sqr) / (rr_ + rc_) * weights_.size();
103 const size_t i = std::floor(i_real);
104 const double rest = i_real - i;
105 if (
likely(i + 1 < weights_.size())) {
106 f += weights_[i] * rest + weights_[i + 1] * (1. - rest);
112 void PauliBlocker::init_weights_analytical() {
113 const double pi = M_PI;
114 const double sqrt2 = std::sqrt(2.);
115 const double sqrt_2pi = std::sqrt(2. * pi);
117 const double phase_volume =
118 2 * (4. / 3. * pi * rr_ * rr_ * rr_) * (4. / 3. * pi * rp_ * rp_ * rp_) /
122 std::erf(rc_ / sqrt2 / sig_) -
123 rc_ * 2 / sqrt_2pi / sig_ * std::exp(-0.5 * rc_ * rc_ / sig_ / sig_);
127 const double d_pos = (rr_ + rc_) /
static_cast<double>(weights_.size());
129 for (
size_t k = 0; k < weights_.size(); k++) {
131 const double rj = d_pos * k;
134 const double A = rr_ / sqrt2 / sig_;
135 integral = sqrt_2pi * sig_ * std::erf(A) - 2 * rr_ * std::exp(-A * A);
136 integral *= sig_ * sig_;
137 }
else if (rc_ > rj + rr_) {
138 const double A = (rj + rr_) / sqrt2 / sig_;
139 const double B = (rj - rr_) / sqrt2 / sig_;
140 integral = sig_ / rj * (std::exp(-A * A) - std::exp(-B * B)) +
141 0.5 * sqrt_2pi * (std::erf(A) - std::erf(B));
142 integral *= sig_ * sig_ * sig_;
144 const double A = rc_ / sqrt2 / sig_;
145 const double B = (rj - rr_) / sqrt2 / sig_;
146 const double C = (rc_ - rj) * (rc_ - rj) - rr_ * rr_ + 2 * sig_ * sig_;
148 (0.5 * std::exp(-A * A) * C - sig_ * sig_ * std::exp(-B * B)) / rj +
149 0.5 * sqrt_2pi * sig_ * (std::erf(A) - std::erf(B));
150 integral *= sig_ * sig_;
152 integral *= 2 * pi / std::pow(2 * pi * sig_ * sig_, 1.5);
153 weights_[k] = integral / norm / phase_volume;