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) {
39 "Phase-space density calculation in Pauli blocking"
40 " will not work reasonably for a small number of testparticles."
41 " The recommended number of testparticles is 20.");
44 if (rc_ < rr_ || rr_ < 0.0 || rp_ < 0) {
46 "Please choose reasonable parameters for Pauli blocking:"
47 "All radii have to be positive and Gaussian_Cutoff should"
48 "be larger than Spatial_Averaging_Radius");
51 init_weights_analytical();
54 PauliBlocker::~PauliBlocker() {}
59 const ParticleList &disregard)
const {
65 for (
const auto &part : particles) {
67 if (part.pdgcode() != pdg) {
71 const double pdist_sqr = (part.momentum().threevec() -
p).sqr();
72 if (pdist_sqr > rp_ * rp_) {
75 const double rdist_sqr = (part.position().threevec() - r).sqr();
77 if (rdist_sqr >= (rr_ + rc_) * (rr_ + rc_)) {
81 bool to_disregard =
false;
82 for (
const auto &disregard_part : disregard) {
83 if (part.id() == disregard_part.id()) {
91 const double i_real = std::sqrt(rdist_sqr) / (rr_ + rc_) * weights_.size();
92 const size_t i = std::floor(i_real);
93 const double rest = i_real - i;
94 if (
likely(i + 1 < weights_.size())) {
95 f += weights_[i] * rest + weights_[i + 1] * (1. - rest);
101 void PauliBlocker::init_weights_analytical() {
102 const double pi = M_PI;
103 const double sqrt2 = std::sqrt(2.);
104 const double sqrt_2pi = std::sqrt(2. * pi);
106 const double phase_volume =
107 2 * (4. / 3. * pi * rr_ * rr_ * rr_) * (4. / 3. * pi * rp_ * rp_ * rp_) /
111 std::erf(rc_ / sqrt2 / sig_) -
112 rc_ * 2 / sqrt_2pi / sig_ * std::exp(-0.5 * rc_ * rc_ / sig_ / sig_);
116 const double d_pos = (rr_ + rc_) / static_cast<double>(weights_.size());
118 for (
size_t k = 0; k < weights_.size(); k++) {
120 const double rj = d_pos * k;
123 const double A = rr_ / sqrt2 / sig_;
124 integral = sqrt_2pi * sig_ * std::erf(A) - 2 * rr_ * std::exp(-A * A);
125 integral *= sig_ * sig_;
126 }
else if (rc_ > rj + rr_) {
127 const double A = (rj + rr_) / sqrt2 / sig_;
128 const double B = (rj - rr_) / sqrt2 / sig_;
129 integral = sig_ / rj * (std::exp(-A * A) - std::exp(-B * B)) +
130 0.5 * sqrt_2pi * (std::erf(A) - std::erf(B));
131 integral *= sig_ * sig_ * sig_;
133 const double A = rc_ / sqrt2 / sig_;
134 const double B = (rj - rr_) / sqrt2 / sig_;
135 const double C = (rc_ - rj) * (rc_ - rj) - rr_ * rr_ + 2 * sig_ * sig_;
137 (0.5 * std::exp(-A * A) * C - sig_ * sig_ * std::exp(-B * B)) / rj +
138 0.5 * sqrt_2pi * sig_ * (std::erf(A) - std::erf(B));
139 integral *= sig_ * sig_;
141 integral *= 2 * pi / std::pow(2 * pi * sig_ * sig_, 1.5);
142 weights_[k] = integral / norm / phase_volume;