40 #include <gsl/gsl_randist.h>
50 struct DegraderInsideTester:
public InsideTester {
55 bool checkHit(
const Vector_t&
R)
override {
62 struct CollimatorInsideTester:
public InsideTester {
67 bool checkHit(
const Vector_t&
R)
override {
74 struct FlexCollimatorInsideTester:
public InsideTester {
75 explicit FlexCollimatorInsideTester(
ElementBase* el) {
79 bool checkHit(
const Vector_t&
R)
override {
89 std::string& material,
90 bool enableRutherford,
115 stoppedPartStat_m(0),
117 totalPartsInMat_m(0),
121 enableRutherford_m(enableRutherford),
122 lowEnergyThr_m(lowEnergyThr)
126 rGen_m = gsl_rng_alloc(gsl_rng_default);
133 mySeed = tv.tv_sec + tv.tv_usec;
153 "Unsupported element type");
176 Z_m = material->getAtomicNumber();
177 A_m = material->getAtomicMass();
178 rho_m = material->getMassDensity();
179 X0_m = material->getRadiationLength();
180 I_m = material->getMeanExcitationEnergy();
194 const std::pair<Vector_t, double>& boundingSphere) {
215 "ScatteringPhysics::apply",
217 " is not supported for scattering interactions!");
242 if (onlyOneLoopOverParticles) {
261 onlyOneLoopOverParticles =
true;
263 }
while (onlyOneLoopOverParticles ==
false);
276 for (
size_t i = 0; i <
locParts_m.size(); ++i) {
318 bool includeFluctuations)
const {
321 constexpr
double m2cm = 1e2;
322 constexpr
double eV2keV = 1
e-3;
323 constexpr
double GeV2keV = 1e6;
324 const double mass_keV =
mass_m * eV2keV;
325 constexpr
double massElectron_keV =
Physics::m_e * GeV2keV;
330 const double gammaSqr =
std::pow(gamma, 2);
331 const double betaSqr = 1.0 - 1.0 / gammaSqr;
333 double Ekin = (gamma - 1) * mass_keV;
335 double epsilon = 0.0;
337 const double deltas = deltat * beta *
Physics::c;
338 const double deltasrho = deltas * m2cm *
rho_m;
340 const double massRatio = massElectron_keV / mass_keV;
341 double Tmax = (2.0 * massElectron_keV * betaSqr * gammaSqr /
342 (
std::pow(gamma + massRatio, 2) - (gammaSqr - 1.0)));
346 if (Ekin >= 600 && Ekin < 1e7) {
348 (0.5 *
std::log(2 * massElectron_keV * betaSqr * gammaSqr * Tmax /
std::pow(
I_m * eV2keV, 2)) - betaSqr));
351 const double Ts = Ekin / massProton_amu;
355 epsilon = (epsilon_low * epsilon_high) / (epsilon_low + epsilon_high);
356 }
else if (Ekin > 1) {
362 "for energy loss calculation." <<
endl);
365 if (Ekin > 10000 && Ekin < 1e6) {
367 (0.5 *
std::log(2 * massElectron_keV * betaSqr * gammaSqr * Tmax /
std::pow(
I_m * eV2keV, 2)) - betaSqr));
368 }
else if (Ekin > 1 && Ekin <= 10000) {
369 const double T = Ekin * 1
e-3;
372 epsilon = (epsilon_low * epsilon_high) / (epsilon_low + epsilon_high);
376 "for energy loss calculation." <<
endl);
380 Ekin += deltasrho * dEdx;
382 if (includeFluctuations) {
384 Ekin += gsl_ran_gaussian(
rGen_m, sigma_E);
387 gamma = Ekin / mass_keV + 1.0;
391 bool stopped = (Ekin < lowEnergyThr_m * 1e3 || dEdx > 0);
418 double thetaru = 2.5 /
std::sqrt(gsl_rng_uniform(
rGen_m)) * 2.0 * theta0;
421 double normPtrans =
std::sqrt(P(0) * P(0) + P(1) * P(1));
445 constexpr
double sqrtThreeInv = 0.57735026918962576451;
447 const double gammaSqr =
std::pow(normP, 2) + 1.0;
448 const double beta =
std::sqrt(1.0 - 1.0 / gammaSqr);
450 const double theta0 = (13.6e6 / (beta * normP *
mass_m) *
455 for (
unsigned int i = 0; i < 2; ++ i) {
460 double z1 = gsl_ran_gaussian(
rGen_m, 1.0);
461 double z2 = gsl_ran_gaussian(
rGen_m, 1.0);
464 z1 = gsl_ran_gaussian(
rGen_m, 1.0);
465 z2 = gsl_ran_gaussian(
rGen_m, 1.0);
468 double thetacou = z2 * theta0;
469 double shift = (z1 * sqrtThreeInv + z2) * deltas * theta0 * 0.5;
479 gsl_rng_uniform(
rGen_m) < 0.0047) {
490 unsigned int numLocalParticles = bunch->
getLocalNum();
493 for (
size_t i = 0; i < nL; ++ i) {
496 if (
R[2] >= elementLength) {
504 bunch->
Bin[numLocalParticles] = 1;
505 bunch->
R[numLocalParticles] =
R;
506 bunch->
P[numLocalParticles] =
locParts_m[i].Pincol;
507 bunch->
Q[numLocalParticles] =
locParts_m[i].Qincol;
508 bunch->
M[numLocalParticles] =
locParts_m[i].Mincol;
509 bunch->
Bf[numLocalParticles] = 0.0;
510 bunch->
Ef[numLocalParticles] = 0.0;
511 bunch->
dt[numLocalParticles] =
dT_m;
521 ++ numLocalParticles;
530 const std::pair<Vector_t, double>& boundingSphere)
536 double zmax = boundingSphere.first(2) + boundingSphere.second;
537 double zmin = boundingSphere.first(2) - boundingSphere.second;
544 std::set<size_t> partsToDel;
545 for (
size_t i = 0; i < nL; ++ i) {
546 if ((bunch->
Bin[i] == -1 || bunch->
Bin[i] == 1) &&
558 double tau = bunch->
R[i](2) / stepWidth;
580 partsToDel.insert(i);
584 for (
auto it = partsToDel.begin(); it != partsToDel.end(); ++ it) {
605 <<
"--- ScatteringPhysics\n"
606 <<
"Name: " <<
name_m <<
" - "
609 <<
"Particle Statistics @ " << time.
time() <<
"\n"
641 if ((*inv).label == -1)
656 for (
size_t i = 0; i <
locParts_m.size(); ++i) {
674 for (
size_t i = 0; i <
locParts_m.size(); ++i) {
681 if (
R(2) < elementLength &&
682 R(2) + stepLength(2) > elementLength) {
684 double distance = elementLength -
R(2);
685 double tau = distance / stepLength(2);
696 for (
size_t i = 0; i <
locParts_m.size(); ++i) {
705 unsigned int locPartsInMat;
708 constexpr
unsigned short numItems = 4;
709 unsigned int partStatistics[numItems] = {locPartsInMat,
714 allreduce(&(partStatistics[0]), numItems, std::plus<unsigned int>());
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Tps< T > cos(const Tps< T > &x)
Cosine.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sin(const Tps< T > &x)
Sine.
Tps< T > sqrt(const Tps< T > &x)
Square root.
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
PETE_TBTree< OpNE, Index::PETE_Expr_t, PETE_Scalar< double > > ne(const Index &idx, double x)
void allreduce(const T *input, T *output, int count, Op op)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Inform & endl(Inform &inf)
Inform & level2(Inform &inf)
Inform & level4(Inform &inf)
constexpr double amu
The atomic mass unit energy equivalent in GeV.
constexpr double two_pi
The value of.
constexpr double Avo
The Avogadro's number.
constexpr double m_p
The proton rest mass in GeV.
constexpr double m_e
The electron rest mass in GeV.
constexpr double e
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.
constexpr double r_e
The classical electron radius in m.
std::string::iterator iterator
int seed
The current random seed.
double getGamma(Vector_t p)
std::string toStringWithThousandSep(T value, char sep='\'')
ParticleAttrib< Vector_t > Ef
ParticleAttrib< int > Bin
std::string getPTypeString()
double getQ() const
Access to reference data.
size_t getLocalNum() const
ParticleAttrib< double > M
ParticleAttrib< Vector_t > P
ParticleAttrib< double > Q
ParticleType getPType() const
void createWithID(unsigned id)
ParticleAttrib< double > dt
void performDestroy(bool updateLocalNum=false)
void destroy(size_t M, size_t I, bool doNow=false)
ParticleAttrib< Vector_t > Bf
virtual bool isInMaterial(double z)
virtual const std::string & getName() const
Get element name.
virtual double getElementLength() const
Get design length.
virtual ElementType getType() const =0
Get element type std::string.
bool isStopped(const Vector_t &R)
int checkPoint(const double &x, const double &y) const
Checks if coordinate is within element.
Vector_t rotateFrom(const Vector_t &r) const
Vector_t transformFrom(const Vector_t &r) const
Vector_t rotateTo(const Vector_t &r) const
static std::shared_ptr< Material > getMaterial(const std::string &name)
ElementBase * element_ref_m
bool allParticleInMat_m
if all particles are in matter stay inside the particle matter interaction
void addBackToBunch(PartBunchBase< double, 3 > *bunch)
virtual bool computeEnergyLoss(PartBunchBase< double, 3 > *bunch, Vector_t &P, const double deltat, bool includeFluctuations=true) const
void configureMaterialParameters()
The material of the collimator.
virtual bool stillActive()
void setTimeStepForLeavingParticles()
ElementBase::ElementType collshape_m
void copyFromBunch(PartBunchBase< double, 3 > *bunch, const std::pair< Vector_t, double > &boundingSphere)
virtual void apply(PartBunchBase< double, 3 > *bunch, const std::pair< Vector_t, double > &boundingSphere)
unsigned int bunchToMatStat_m
void deleteParticleFromLocalVector()
IpplTimings::TimerRef DegraderLoopTimer_m
void applyRotation(Vector_t &P, Vector_t &R, double xplane, double thetacou)
ScatteringPhysics(const std::string &name, ElementBase *element, std::string &mat, bool enableRutherford, double lowEnergyThr)
void computeInteraction(PartBunchBase< double, 3 > *bunch)
unsigned int totalPartsInMat_m
void applyRandomRotation(Vector_t &P, double theta0)
void computeCoulombScattering(Vector_t &R, Vector_t &P, double dt)
std::unique_ptr< InsideTester > hitTester_m
virtual std::string getName()
std::vector< PART > locParts_m
unsigned int rediffusedStat_m
IpplTimings::TimerRef DegraderApplyTimer_m
unsigned int stoppedPartStat_m
IpplTimings::TimerRef DegraderDestroyTimer_m
virtual void print(Inform &os)
std::unique_ptr< LossDataSink > lossDs_m
std::string time() const
Return time.
std::ios_base::fmtflags FmtFlags_t
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
Vektor< double, 3 > Vector_t