00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "BDSOctStepper.hh"
00017 #include "G4ThreeVector.hh"
00018 #include "G4LineSection.hh"
00019 #include "G4TransportationManager.hh"
00020
00021 extern G4double BDSLocalRadiusOfCurvature;
00022
00023 BDSOctStepper::BDSOctStepper(G4Mag_EqRhs *EqRhs)
00024 : G4MagIntegratorStepper(EqRhs,6),
00025
00026 itsBTrpPrime(0.0), itsDist(0.0)
00027 {
00028 fPtrMagEqOfMot = EqRhs;
00029 }
00030
00031
00032 void BDSOctStepper::AdvanceHelix( const G4double yIn[],
00033 G4ThreeVector,
00034 G4double h,
00035 G4double yOct[])
00036 {
00037 const G4double *pIn = yIn+3;
00038 G4ThreeVector v0= G4ThreeVector( pIn[0], pIn[1], pIn[2]);
00039 G4ThreeVector InitMomDir=v0.unit();
00040
00041 G4ThreeVector GlobalPosition= G4ThreeVector( yIn[0], yIn[1], yIn[2]);
00042 G4double InitMag=v0.mag();
00043 G4double kappa= -fPtrMagEqOfMot->FCof()*itsBTrpPrime/InitMag;
00044
00045
00046
00047 if(fabs(kappa)<1.e-20)
00048 {
00049 G4ThreeVector positionMove = (h/InitMag) * v0;
00050
00051 yOct[0] = yIn[0] + positionMove.x();
00052 yOct[1] = yIn[1] + positionMove.y();
00053 yOct[2] = yIn[2] + positionMove.z();
00054
00055 yOct[3] = v0.x();
00056 yOct[4] = v0.y();
00057 yOct[5] = v0.z();
00058
00059 itsDist=0;
00060 }
00061 else
00062 {
00063 G4Navigator* OctNavigator=
00064 G4TransportationManager::GetTransportationManager()->
00065 GetNavigatorForTracking();
00066
00067 G4AffineTransform LocalAffine=OctNavigator->GetLocalToGlobalTransform();
00068
00069
00070
00071
00072
00073
00074
00075
00076 G4AffineTransform GlobalAffine=OctNavigator->GetGlobalToLocalTransform();
00077 G4ThreeVector LocalR=GlobalAffine.TransformPoint(GlobalPosition);
00078 G4ThreeVector LocalRp=GlobalAffine.TransformAxis(InitMomDir);
00079
00080
00081
00082
00083 G4double x0=LocalR.x();
00084 G4double y0=LocalR.y();
00085 G4double z0=LocalR.z();
00086
00087
00088
00089 G4double xp=LocalRp.x();
00090 G4double yp=LocalRp.y();
00091 G4double zp=LocalRp.z();
00092
00093 G4double y3fac=y0*(y0*y0-3*x0*x0);
00094 G4double x3fac=x0*(x0*x0-3*y0*y0);
00095
00096
00097 G4ThreeVector LocalRpp;
00098
00099
00100
00101
00102
00103
00104
00105 LocalRpp.setX(-zp*x3fac);
00106 LocalRpp.setY(-zp*y3fac);
00107 LocalRpp.setZ( xp*x3fac + yp*y3fac);
00108
00109 LocalRpp*=kappa/6;
00110
00111
00112 G4double R_1 = LocalRpp.mag();
00113 if(R_1>0.)
00114 {
00115
00116 BDSLocalRadiusOfCurvature=1/R_1;
00117
00118
00119 G4double h2=h*h;
00120 itsDist= h2*R_1/8;
00121
00122 G4double dx=LocalRp.x()*h + LocalRpp.x()*h2/2;
00123 G4double dy=LocalRp.y()*h + LocalRpp.y()*h2/2;
00124
00125 G4double dz=sqrt(h2*(1.-h2*R_1*R_1/12)-dx*dx-dy*dy);
00126
00127 G4double ScaleFac=(dx*dx+dy*dy+dz*dz)/h2;
00128 if(ScaleFac>1.0000001)
00129 {
00130 ScaleFac=sqrt(ScaleFac);
00131 dx/=ScaleFac;
00132 dy/=ScaleFac;
00133 dz/=ScaleFac;
00134 }
00135
00136 LocalR.setX(x0+dx);
00137 LocalR.setY(y0+dy);
00138 LocalR.setZ(z0+dz);
00139
00140 LocalRp = LocalRp+ h*LocalRpp;
00141 }
00142 else
00143 {LocalR += h*LocalRp;}
00144
00145 GlobalPosition=LocalAffine.TransformPoint(LocalR);
00146 G4ThreeVector GlobalTangent=LocalAffine.TransformAxis(LocalRp)*InitMag;
00147
00148 yOct[0] = GlobalPosition.x();
00149 yOct[1] = GlobalPosition.y();
00150 yOct[2] = GlobalPosition.z();
00151
00152 yOct[3] = GlobalTangent.x();
00153 yOct[4] = GlobalTangent.y();
00154 yOct[5] = GlobalTangent.z();
00155 }
00156 }
00157
00158 void BDSOctStepper::Stepper( const G4double yInput[],
00159 const G4double[],
00160 const G4double hstep,
00161 G4double yOut[],
00162 G4double yErr[] )
00163 {
00164 G4int i;
00165 const G4int nvar = 6 ;
00166
00167
00168
00169
00170
00171
00172 G4double yTemp[7], yIn[7];
00173
00174
00175
00176 for(i=0;i<nvar;i++) yIn[i]=yInput[i];
00177
00178 G4double h = hstep * 0.5;
00179
00180
00181 AdvanceHelix(yIn, (G4ThreeVector)0, h, yTemp);
00182 AdvanceHelix(yTemp, (G4ThreeVector)0, h, yOut);
00183
00184
00185 h = hstep ;
00186 AdvanceHelix(yIn, (G4ThreeVector)0, h, yTemp);
00187
00188 for(i=0;i<nvar;i++) yErr[i] = yOut[i] - yTemp[i] ;
00189
00190 }
00191
00192 G4double BDSOctStepper::DistChord() const
00193 {
00194 return itsDist;
00195 }
00196
00197 BDSOctStepper::~BDSOctStepper()
00198 {}