69 *gmsg <<
"* Initialize OutputPlane at " <<
centre_m <<
" with normal " <<
normal_m <<
"\n*";
82 *gmsg <<
" Using empty field map";
91 *gmsg <<
"* OutputPlane goes offline " <<
getName() <<
endl;
96 const double& chargeToMass,
100 double thalfStep = tStep / 2.;
101 double tPlusHalf = t + thalfStep;
102 double tPlusStep = t + tStep;
110 Vector_t R2(R1[0] + thalfStep * deriv1[0], R1[1] + thalfStep * deriv1[1], R1[2] + thalfStep * deriv1[2]);
111 Vector_t P2(P1[0] + thalfStep * deriv1[3], P1[1] + thalfStep * deriv1[4], P1[2] + thalfStep * deriv1[5]);
116 Vector_t R3(R1[0] + thalfStep * deriv2[0], R1[1] + thalfStep * deriv2[1], R1[2] + thalfStep * deriv2[2]);
117 Vector_t P3(P1[0] + thalfStep * deriv2[3], P1[1] + thalfStep * deriv2[4], P1[2] + thalfStep * deriv2[5]);
122 Vector_t R4(R1[0] + tStep * deriv3[0], R1[1] + tStep * deriv3[1], R1[2] + tStep * deriv3[2]);
123 Vector_t P4(P1[0] + tStep * deriv3[3], P1[1] + tStep * deriv3[4], P1[2] + tStep * deriv3[5]);
127 R1[0] += (deriv1[0] + deriv4[0] + 2. * (deriv2[0] + deriv3[0])) * tStep / 6.;
128 R1[1] += (deriv1[1] + deriv4[1] + 2. * (deriv2[1] + deriv3[1])) * tStep / 6.;
129 R1[2] += (deriv1[2] + deriv4[2] + 2. * (deriv2[2] + deriv3[2])) * tStep / 6.;
130 P1[0] += (deriv1[3] + deriv4[3] + 2. * (deriv2[3] + deriv3[3])) * tStep / 6.;
131 P1[1] += (deriv1[4] + deriv4[4] + 2. * (deriv2[4] + deriv3[4])) * tStep / 6.;
132 P1[2] += (deriv1[5] + deriv4[5] + 2. * (deriv2[5] + deriv3[5])) * tStep / 6.;
138 const double& chargeToMass,
141 double gamma =
std::sqrt(1 + (P[0] * P[0] + P[1] * P[1] + P[2] * P[2]));
144 double betax = beta[0];
145 double betay = beta[1];
146 double betaz = beta[2];
162 yp[3] = chargeToMass * (externalB(2) * betay - externalB(1) * betaz+externalE(0));
163 yp[4] = chargeToMass * (externalB(0) * betaz - externalB(2) * betax + externalE(1));
164 yp[5] = chargeToMass * (externalB(1) * betax - externalB(0) * betay + externalE(2));
177 if (betaEstimate > 1) {
182 *gmsg <<
"* First check crossing of plane " <<
getName() <<
" at " << centre_m <<
" with normal " <<
normal_m <<
endl;
183 *gmsg <<
" Particle " << index <<
" with R " << R <<
" P " << P <<
" t0 " << t <<
" tstep " << tstep <<
endl;
184 *gmsg <<
" Distance prestep " << distance <<
" compared to s step length " << sStep <<
endl;
193 RK4Step(tstep, chargeToMass, t, rTest, pTest);
194 double distanceTest =
dot(
normal_m, (rTest-centre_m));
196 *gmsg <<
"* Second check crossing of plane " <<
getName() <<
" at " << centre_m <<
" with normal " <<
normal_m <<
endl;
197 *gmsg <<
" Particle " << index <<
" with R " << R <<
" P " << P <<
" tstep " << tstep <<
endl;
198 *gmsg <<
" After RK4 " << rTest <<
" " << pTest <<
endl;
199 *gmsg <<
" Step distance " << distanceTest <<
" compared to " << distance <<
endl;
202 if (distance != 0 && distanceTest/distance > 0) {
210 rk4Test(tstep, chargeToMass, t, R, P);
219 <<
" R " << R <<
" P " << P <<
" t " << t <<
endl
220 <<
" delta " << delta <<
endl;
238 *gmsg <<
"* Recentred output plane to " << centre_m
239 <<
" with normal " <<
normal_m <<
" by event " << index <<
endl;
242 *gmsg <<
"* Found track" <<
endl;
249 double preStepDistance = 0.0;
251 size_t iteration = 0;
253 preStepDistance = postStepDistance;
254 RK4Step(tstep, chargeToMass, t, R, P);
256 *gmsg <<
" RK4 iteration " << iteration <<
" step distance " << preStepDistance <<
" R " << R <<
" P " << P
260 *gmsg <<
" B " << externalB <<
" [kG] E " << externalE <<
" [MV/m] " <<
endl;
264 if (postStepDistance/preStepDistance < 0) {
267 tstep *= -
abs(postStepDistance)/
abs(postStepDistance - preStepDistance);
270 tstep *=
abs(postStepDistance)/
abs(postStepDistance - preStepDistance);
282 double gamma =
std::sqrt(1 + P[0] * P[0] + P[1] * P[1] + P[2] * P[2]);
291 const double t,
const double tstep) {
293 for(
unsigned int i = 0; i < tempnum; ++i) {
295 *gmsg <<
"OutputPlane checking at time " << t
296 <<
" turn number " << turnnumber <<
" track id " << i <<
endl;
303 bool crossing =
checkOne(i, tstep, chargeToMass, t0, R, P);
307 t0, bunch->
Q[i], bunch->
M[i]),
308 std::make_pair(turnnumber, bunch->
bunchNum[i]));
Tps< T > sqrt(const Tps< T > &x)
Square root.
constexpr double c
The velocity of light in m/s.
void rk4Test(double tstep, double chargeToMass, double &t, Vector_t &R, Vector_t &P)
virtual void visitOutputPlane(const OutputPlane &)=0
Apply the algorithm to an outputplane.
void setCentre(Vector_t centre)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
ParticleAttrib< Vector_t > P
ElementBase * clone() const override
ParticleAttrib< short > bunchNum
bool checkOne(const int index, const double tstep, double chargeToMass, double &t, Vector_t &R, Vector_t &P)
virtual void doGoOffline() override
Hook for goOffline.
ParticleAttrib< double > M
virtual void accept(BeamlineVisitor &) const override
double horizontalExtent_m
virtual const std::string & getName() const
Get element name.
Inform & endl(Inform &inf)
std::unique_ptr< LossDataSink > lossDs_m
Pointer to Loss instance.
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B)
T euclidean_norm(const Vector< T > &)
Euclidean norm.
size_t getLocalNum() const
void recentre(Vector_t R, Vector_t P)
ParticleAttrib< double > Q
constexpr double q_e
The elementary charge in As.
virtual bool doCheck(PartBunchBase< double, 3 > *bunch, const int turnnumber, const double t, const double tstep) override
Record probe hits when bunch particles pass.
void getDerivatives(const Vector_t &R, const Vector_t &P, const double &t, const double &chargeToMass, double *yp) const
ElementType getType() const override
Get element type std::string.
void RK4Step(const double &tstep, const double &chargeToMass, const double &t, Vector_t &R, Vector_t &P) const
virtual void doInitialise(PartBunchBase< double, 3 > *) override
Initialise peakfinder file.
void interpolation(double &t, Vector_t &R, Vector_t &P)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
void setNormal(Vector_t normal)