BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSIntegratorRMatrixThin.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "BDSDebug.hh"
21#include "BDSIntegratorRMatrixThin.hh"
22#include "BDSStep.hh"
23#include "BDSUtilities.hh"
24
25#include "globals.hh"
26#include "G4Mag_EqRhs.hh"
27
28BDSIntegratorRMatrixThin::BDSIntegratorRMatrixThin(BDSMagnetStrength const* strength,
29 G4Mag_EqRhs* eqOfMIn,
30 G4double maximumRadiusIn):
31 BDSIntegratorMag(eqOfMIn, 6),
32 maximumRadius(maximumRadiusIn)
33{
34 kick1 = (*strength)["kick1"];
35 kick2 = (*strength)["kick2"];
36 kick3 = (*strength)["kick3"];
37 kick4 = (*strength)["kick4"];
38 rmat11 = (*strength)["rmat11"];
39 rmat12 = (*strength)["rmat12"];
40 rmat13 = (*strength)["rmat13"];
41 rmat14 = (*strength)["rmat14"];
42 rmat21 = (*strength)["rmat21"];
43 rmat22 = (*strength)["rmat22"];
44 rmat23 = (*strength)["rmat23"];
45 rmat24 = (*strength)["rmat24"];
46 rmat31 = (*strength)["rmat31"];
47 rmat32 = (*strength)["rmat32"];
48 rmat33 = (*strength)["rmat33"];
49 rmat34 = (*strength)["rmat34"];
50 rmat41 = (*strength)["rmat41"];
51 rmat42 = (*strength)["rmat42"];
52 rmat43 = (*strength)["rmat43"];
53 rmat44 = (*strength)["rmat44"];
54
55#ifdef BDSDEBUG
56 G4cout << "RMatrix " << rmat11 << " " << rmat12 << " " << rmat13 << " " << rmat14 << " " << kick1 << G4endl;
57 G4cout << "RMatrix " << rmat21 << " " << rmat22 << " " << rmat23 << " " << rmat24 << " " << kick2 << G4endl;
58 G4cout << "RMatrix " << rmat31 << " " << rmat32 << " " << rmat33 << " " << rmat34 << " " << kick3 << G4endl;
59 G4cout << "RMatrix " << rmat41 << " " << rmat42 << " " << rmat43 << " " << rmat44 << " " << kick4 << G4endl;
60#endif
61}
62
63void BDSIntegratorRMatrixThin::Stepper(const G4double yIn[],
64 const G4double /*dydx*/[],
65 const G4double h,
66 G4double yOut[],
67 G4double yErr[])
68{
69 for (G4int i = 0; i < 3; i++)
70 {
71 yErr[i] = 0;
72 yErr[i+3] = 0;
73 }
74
75 // check if beam particle, if so step as drift
76 const G4double fcof = eqOfM->FCof();
77 G4double lengthFraction = h / thinElementLength;
78
79 // only apply the kick if we're taking a step longer than half the length of the item,
80 // in which case, apply the full kick. This appears more robust than scaling the kick
81 // by h / thinElementLength as the precise geometrical length depends on the geometry
82 // ie if there's a beam pipe etc -> more length safetys. The geometry layout should
83 // prevent more than one step begin taken, but occasionally, a very small initial step
84 // can be taken resulting in a double kick.
85 if (lengthFraction < 0.51 || !BDS::IsFiniteStrength(fcof))
86 {
87 AdvanceDriftMag(yIn, h, yOut, yErr);
88 SetDistChord(0);
89 return;
90 }
91
92 G4ThreeVector pos = G4ThreeVector( yIn[0], yIn[1], yIn[2]);
93 G4ThreeVector mom = G4ThreeVector(yIn[3], yIn[4], yIn[5]);
94 G4double momMag = mom.mag();
95
96 BDSStep localPosMom = ConvertToLocal(pos, mom, h, false);
97 G4ThreeVector localPos = localPosMom.PreStepPoint();
98 G4ThreeVector localMom = localPosMom.PostStepPoint();
99 G4ThreeVector localMomUnit = localMom.unit();
100
101 G4double x0 = localPos.x();
102 G4double y0 = localPos.y();
103 G4double z0 = localPos.z();
104
105 G4double xp = localMomUnit.x();
106 G4double yp = localMomUnit.y();
107 G4double zp = localMomUnit.z();
108
109 // only proceed with thin matrix if particle is paraxial
110 // judged by forward momentum > 1-limit and |transverse| < limit (default limit=0.1)
111 if (zp < (1.0-backupStepperMomLimit) || std::abs(xp) > backupStepperMomLimit || std::abs(yp) > backupStepperMomLimit)
112 {
113 AdvanceDriftMag(yIn, h, yOut, yErr);
114 SetDistChord(0);
115 return;
116 }
117
118 G4double x1 = rmat11 * x0 + rmat12 * xp * CLHEP::m + rmat13 * y0 + rmat14 * yp * CLHEP::m + kick1;
119 G4double xp1 = rmat21 * x0 / CLHEP::m + rmat22 * xp + rmat23 * y0 / CLHEP::m + rmat24 * yp + kick2;
120 G4double y1 = rmat31 * x0 + rmat32 * xp * CLHEP::meter + rmat33 * y0 + rmat34 * yp * CLHEP::m + kick3;
121 G4double yp1 = rmat41 * x0 / CLHEP::m + rmat42 * xp + rmat43 * y0 / CLHEP::m + rmat44 * yp + kick4;
122 G4double z1 = z0 + h;
123 G4double zp1 = std::sqrt(1 - std::pow(xp1,2) - std::pow(yp1,2));
124
125 // need to check against aperture before returning
126 if(x1 > maximumRadius)
127 {x1 = maximumRadius;}
128 else if( x1 < -maximumRadius)
129 {x1 = -maximumRadius;}
130 if(y1 > maximumRadius)
131 {y1 = maximumRadius;}
132 else if( y1 < -maximumRadius)
133 {y1 = -maximumRadius;}
134
135 G4ThreeVector localPosOut = G4ThreeVector(x1, y1, z1);
136 G4ThreeVector localMomUnitOut = G4ThreeVector(xp1, yp1, zp1);
137 ConvertToGlobal(localPosOut, localMomUnitOut, yOut, yErr, momMag);
138}
BDSStep ConvertToLocal(G4Step const *const step, G4bool useCurvilinear=true) const
void AdvanceDriftMag(const G4double yIn[], const G4double h, G4double yOut[], G4double yErr[]) const
Error array [6] all 0.
Common functionality to BDSIM integrators.
G4double backupStepperMomLimit
G4Mag_EqRhs * eqOfM
void SetDistChord(G4double distChordIn)
Setter for distChord to private member.
static G4double thinElementLength
void ConvertToGlobal(const G4ThreeVector &localPos, const G4ThreeVector &localMom, G4double yOut[], G4double yErr[], const G4double momScaling=1.0)
scaling of momentum in case localMom is a unit vector
Efficient storage of magnet strengths.
A simple class to represent the positions of a step.
Definition: BDSStep.hh:33
G4ThreeVector PostStepPoint() const
Accessor.
Definition: BDSStep.hh:43
G4ThreeVector PreStepPoint() const
Accessor.
Definition: BDSStep.hh:42
G4bool IsFiniteStrength(G4double variable)