82 *
gmsg <<
" Using empty field map";
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];
157 field_m->apply(R, P, t, externalE, externalB);
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) {
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;
186 if (std::abs(distance) > sStep) {
193 RK4Step(tstep, chargeToMass, t, rTest, pTest);
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;
239 <<
" with normal " <<
normal_m <<
" by event " << index <<
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
259 field_m->apply(R, P, t, externalE, externalB);
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]));
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
T euclidean_norm(const Vector< T > &)
Euclidean norm.
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & endl(Inform &inf)
constexpr double q_e
The elementary charge in As.
constexpr double c
The velocity of light in m/s.
size_t getLocalNum() const
ParticleAttrib< double > M
ParticleAttrib< Vector_t > P
ParticleAttrib< double > Q
ParticleAttrib< short > bunchNum
virtual void visitOutputPlane(const OutputPlane &)=0
Apply the algorithm to an outputplane.
virtual const std::string & getName() const
Get element name.
ElementBase(const std::string &name)
Constructor with given name.
void setCentre(Vector_t centre)
void RK4Step(const double &tstep, const double &chargeToMass, const double &t, Vector_t &R, Vector_t &P) const
void rk4Test(double tstep, double chargeToMass, double &t, Vector_t &R, Vector_t &P)
OutputPlane(const std::string &name)
void setNormal(Vector_t normal)
void getDerivatives(const Vector_t &R, const Vector_t &P, const double &t, const double &chargeToMass, double *yp) const
bool checkOne(const int index, const double tstep, double chargeToMass, double &t, Vector_t &R, Vector_t &P)
virtual void doInitialise(PartBunchBase< double, 3 > *) override
Initialise peakfinder file.
ElementType getType() const override
Get element type std::string.
ElementBase * clone() const override
virtual void doGoOffline() override
Hook for goOffline.
void recentre(Vector_t R, Vector_t P)
double horizontalExtent_m
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 interpolation(double &t, Vector_t &R, Vector_t &P)
virtual void accept(BeamlineVisitor &) const override
std::unique_ptr< LossDataSink > lossDs_m
Pointer to Loss instance.
PluginElement(const std::string &name)
Constructor with given name.
Vektor< double, 3 > Vector_t