42 #include <gsl/gsl_randist.h>
57 bool checkHit(
const Vector_t&
R)
override {
68 bool checkHit(
const Vector_t&
R)
override {
76 explicit FlexCollimatorInsideTester(
ElementBase* el) {
79 bool checkHit(
const Vector_t& R)
override {
86 constexpr
long double operator"" _keV(
long double value) {
return value; }
87 constexpr
long double operator"" _MeV(
long double value) {
return value * 1e3; }
88 constexpr
long double operator"" _GeV(
long double value) {
return value * 1e6; }
93 std::string& material,
94 bool enableRutherford,
101 material_m(material),
118 stoppedPartStat_m(0),
120 totalPartsInMat_m(0),
124 enableRutherford_m(enableRutherford),
125 lowEnergyThr_m(lowEnergyThr)
129 rGen_m = gsl_rng_alloc(gsl_rng_default);
136 mySeed = tv.tv_sec + tv.tv_usec;
156 "Unsupported element type");
178 Z_m = material->getAtomicNumber();
179 A_m = material->getAtomicMass();
180 rho_m = material->getMassDensity();
181 X0_m = material->getRadiationLength();
182 I_m = material->getMeanExcitationEnergy();
196 const std::pair<Vector_t, double>& boundingSphere) {
217 "ScatteringPhysics::apply",
219 " is not supported for scattering interactions!");
244 if (onlyOneLoopOverParticles) {
263 onlyOneLoopOverParticles =
true;
265 }
while (onlyOneLoopOverParticles ==
false);
278 for (
size_t i = 0; i <
locParts_m.size(); ++i) {
330 bool includeFluctuations)
const {
341 const double gammaSqr =
std::pow(gamma, 2);
342 const double betaSqr = 1.0 - 1.0 / gammaSqr;
344 double Ekin_keV = (gamma - 1) * mass_keV;
346 double epsilon = 0.0;
348 const double deltas = deltat * beta *
Physics::c;
351 const double massRatio = massElectron_keV / mass_keV;
352 double Tmax = (2.0 * massElectron_keV * betaSqr * gammaSqr /
353 (
std::pow(gamma + massRatio, 2) - (gammaSqr - 1.0)));
357 if (Ekin_keV >= 0.6_MeV && Ekin_keV < 10.0_GeV) {
359 (0.5 *
std::log(2 * massElectron_keV * betaSqr * gammaSqr * Tmax /
std::pow(
I_m * Units::eV2keV, 2)) - betaSqr));
362 const double Ts = Ekin_keV / massProton_amu;
363 if (Ekin_keV > 10.0_keV) {
366 epsilon = (epsilon_low * epsilon_high) / (epsilon_low + epsilon_high);
367 }
else if (Ekin_keV > 1.0_keV) {
373 "for energy loss calculation." <<
endl);
376 if (Ekin_keV > 10.0_MeV && Ekin_keV < 1.0_GeV) {
378 (0.5 *
std::log(2 * massElectron_keV * betaSqr * gammaSqr * Tmax /
std::pow(
I_m * Units::eV2keV, 2)) - betaSqr));
379 }
else if (Ekin_keV > 1.0_keV && Ekin_keV <= 10.0_MeV) {
383 epsilon = (epsilon_low * epsilon_high) / (epsilon_low + epsilon_high);
387 "for energy loss calculation." <<
endl);
391 Ekin_keV += deltasrho * dEdx;
393 if (includeFluctuations) {
395 Ekin_keV += gsl_ran_gaussian(
rGen_m, sigma_E);
398 gamma = Ekin_keV / mass_keV + 1.0;
402 bool stopped = (Ekin_keV < lowEnergyThr_m * Units::MeV2keV || dEdx > 0);
429 double thetaru = 2.5 /
std::sqrt(gsl_rng_uniform(
rGen_m)) * 2.0 * theta0;
432 double normPtrans =
std::sqrt(P(0) * P(0) + P(1) * P(1));
446 P = X * CosT +
cross(W, X) * SinT + W *
dot(W, X) * (1.0 - CosT);
456 constexpr
double sqrtThreeInv = 0.57735026918962576451;
460 const double theta0 = (13.6e6 / (beta * normP *
mass_m) *
465 for (
unsigned int i = 0; i < 2; ++ i) {
470 double z1 = gsl_ran_gaussian(
rGen_m, 1.0);
471 double z2 = gsl_ran_gaussian(
rGen_m, 1.0);
474 z1 = gsl_ran_gaussian(
rGen_m, 1.0);
475 z2 = gsl_ran_gaussian(
rGen_m, 1.0);
478 double thetacou = z2 * theta0;
479 double shift = (z1 * sqrtThreeInv + z2) * deltas * theta0 * 0.5;
500 for (
size_t i = 0; i < nL; ++ i) {
523 const PART& particle,
bool pdead) {
525 unsigned int numLocalParticles = bunch->
getLocalNum();
530 bunch->
Bin[numLocalParticles] = 1;
532 bunch->
Bin[numLocalParticles] = -1;
535 bunch->
R[numLocalParticles] = particle.
Rincol;
536 bunch->
P[numLocalParticles] = particle.
Pincol;
537 bunch->
Q[numLocalParticles] = particle.
Qincol;
538 bunch->
M[numLocalParticles] = particle.
Mincol;
539 bunch->
Bf[numLocalParticles] = 0.0;
540 bunch->
Ef[numLocalParticles] = 0.0;
541 bunch->
dt[numLocalParticles] =
dT_m;
546 const std::pair<Vector_t, double>& boundingSphere)
552 double zmax = boundingSphere.first(2) + boundingSphere.second;
553 double zmin = boundingSphere.first(2) - boundingSphere.second;
560 std::set<size_t> partsToDel;
561 for (
size_t i = 0; i < nL; ++ i) {
562 if ((bunch->
Bin[i] == -1 || bunch->
Bin[i] == 1) &&
581 tau = bunch->
R[i](2) / stepWidth;
604 partsToDel.insert(i);
608 for (
auto it = partsToDel.begin();
it != partsToDel.end(); ++
it) {
628 <<
"--- ScatteringPhysics ---\n"
629 <<
"Name: " <<
name_m <<
" - "
632 <<
"Particle Statistics @ " << time.
time() <<
"\n"
663 if ((*inv).label == -1)
678 for (
size_t i = 0; i <
locParts_m.size(); ++i) {
696 for (
size_t i = 0; i <
locParts_m.size(); ++i) {
703 if (
R(2) < elementLength &&
704 R(2) + stepLength(2) > elementLength &&
708 double distance = elementLength -
R(2);
709 double tau = distance / stepLength(2);
720 for (
size_t i = 0; i <
locParts_m.size(); ++i) {
728 unsigned int locPartsInMat;
731 constexpr
unsigned short numItems = 4;
732 unsigned int partStatistics[numItems] = {locPartsInMat,
737 allreduce(&(partStatistics[0]), numItems, std::plus<unsigned int>());
static OpalData * getInstance()
Tps< T > sqrt(const Tps< T > &x)
Square root.
IpplTimings::TimerRef DegraderDestroyTimer_m
constexpr double c
The velocity of light in m/s.
int seed
The current random seed.
void copyFromBunch(PartBunchBase< double, 3 > *bunch, const std::pair< Vector_t, double > &boundingSphere)
ScatteringPhysics(const std::string &name, ElementBase *element, std::string &mat, bool enableRutherford, double lowEnergyThr)
constexpr double Avo
The Avogadro's number.
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
std::unique_ptr< LossDataSink > lossDs_m
constexpr double two_pi
The value of .
void addBackToBunch(PartBunchBase< double, 3 > *bunch)
void setTimeStepForLeavingParticles()
void deleteParticleFromLocalVector()
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual bool isInside(const Vector_t &R) const override
void createWithID(unsigned id)
ParticleAttrib< Vector_t > P
void computeCoulombScattering(Vector_t &R, Vector_t &P, double dt)
Vektor< double, 3 > Vector_t
void destroy(size_t M, size_t I, bool doNow=false)
ParticleAttrib< Vector_t > Ef
virtual void apply(PartBunchBase< double, 3 > *bunch, const std::pair< Vector_t, double > &boundingSphere) override
ParticleAttrib< double > M
bool allParticleInMat_m
if all particles are in matter stay inside the particle matter interaction
void applyRotation(Vector_t &P, Vector_t &R, double xplane, double thetacou)
ElementBase * element_ref_m
void addParticleBackToBunch(PartBunchBase< double, 3 > *bunch, const PART &particle, bool pdead=false)
virtual const std::string & getName() const
Get element name.
double getQ() const
Access to reference data.
constexpr double pi
The value of .
Inform & endl(Inform &inf)
Vector_t transformFrom(const Vector_t &r) const
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)
Vector_t rotateFrom(const Vector_t &r) const
ParticleAttrib< Vector_t > Bf
static void startTimer(TimerRef t)
std::string::iterator iterator
std::ios_base::fmtflags FmtFlags_t
T euclidean_norm(const Vector< T > &)
Euclidean norm.
unsigned int bunchToMatStat_m
Vector_t rotateTo(const Vector_t &r) const
int checkPoint(const double &x, const double &y) const
Checks if coordinate is within element.
ParticleType getPType() const
unsigned int totalPartsInMat_m
Inform & level4(Inform &inf)
size_t getLocalNum() const
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
virtual bool computeEnergyLoss(PartBunchBase< double, 3 > *bunch, Vector_t &P, const double deltat, bool includeFluctuations=true) const override
static std::shared_ptr< Material > getMaterial(const std::string &name)
std::string toStringWithThousandSep(T value, char sep= '\'')
Vector_t getBeta(Vector_t p)
constexpr double amu
The atomic mass unit energy equivalent in GeV.
virtual ElementType getType() const =0
Get element type std::string.
void allreduce(const T *input, T *output, int count, Op op)
ParticleAttrib< double > Q
virtual double getElementLength() const
Get design length.
std::unique_ptr< InsideTester > hitTester_m
unsigned int stoppedPartStat_m
ParticleAttrib< double > dt
double getGamma(Vector_t p)
Tps< T > cos(const Tps< T > &x)
Cosine.
std::vector< PART > locParts_m
constexpr double m_e
The electron rest mass in GeV.
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
Tps< T > log(const Tps< T > &x)
Natural logarithm.
unsigned int rediffusedStat_m
virtual bool stillActive() override
void configureMaterialParameters()
The material of the collimator.
std::string time() const
Return time.
constexpr double m_p
The proton rest mass in GeV.
static TimerRef getTimer(const char *nm)
PETE_TBTree< OpNE, Index::PETE_Expr_t, PETE_Scalar< double > > ne(const Index &idx, double x)
Inform & level2(Inform &inf)
void performDestroy(bool updateLocalNum=false)
ParticleAttrib< int > Bin
void applyRandomRotation(Vector_t &P, double theta0)
IpplTimings::TimerRef DegraderLoopTimer_m
bool isStopped(const Vector_t &R)
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
void computeInteraction(PartBunchBase< double, 3 > *bunch)
Tps< T > sin(const Tps< T > &x)
Sine.
static void stopTimer(TimerRef t)
IpplTimings::TimerRef DegraderApplyTimer_m
virtual std::string getName() override
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
virtual void print(Inform &os) override
static std::string getParticleTypeString(const ParticleType &type)
constexpr double r_e
The classical electron radius in m.