| 1 | //
|
|---|
| 2 | // ********************************************************************
|
|---|
| 3 | // * License and Disclaimer *
|
|---|
| 4 | // * *
|
|---|
| 5 | // * The Geant4 software is copyright of the Copyright Holders of *
|
|---|
| 6 | // * the Geant4 Collaboration. It is provided under the terms and *
|
|---|
| 7 | // * conditions of the Geant4 Software License, included in the file *
|
|---|
| 8 | // * LICENSE and available at http://cern.ch/geant4/license . These *
|
|---|
| 9 | // * include a list of copyright holders. *
|
|---|
| 10 | // * *
|
|---|
| 11 | // * Neither the authors of this software system, nor their employing *
|
|---|
| 12 | // * institutes,nor the agencies providing financial support for this *
|
|---|
| 13 | // * work make any representation or warranty, express or implied, *
|
|---|
| 14 | // * regarding this software system or assume any liability for its *
|
|---|
| 15 | // * use. Please see the license in the file LICENSE and URL above *
|
|---|
| 16 | // * for the full disclaimer and the limitation of liability. *
|
|---|
| 17 | // * *
|
|---|
| 18 | // * This code implementation is the result of the scientific and *
|
|---|
| 19 | // * technical work of the GEANT4 collaboration. *
|
|---|
| 20 | // * By using, copying, modifying or distributing the software (or *
|
|---|
| 21 | // * any work based on the software) you agree to acknowledge its *
|
|---|
| 22 | // * use in resulting scientific publications, and indicate your *
|
|---|
| 23 | // * acceptance of all terms of the Geant4 Software license. *
|
|---|
| 24 | // ********************************************************************
|
|---|
| 25 | //
|
|---|
| 26 | //
|
|---|
| 27 | // $Id: G4RKG3_Stepper.cc,v 1.17 2010/07/23 14:13:49 tnikitin Exp $
|
|---|
| 28 | // GEANT4 tag $Name: field-V09-03-03 $
|
|---|
| 29 | //
|
|---|
| 30 | // -------------------------------------------------------------------
|
|---|
| 31 |
|
|---|
| 32 | #include "G4RKG3_Stepper.hh"
|
|---|
| 33 | #include "G4LineSection.hh"
|
|---|
| 34 | #include "G4Mag_EqRhs.hh"
|
|---|
| 35 |
|
|---|
| 36 | G4RKG3_Stepper::G4RKG3_Stepper(G4Mag_EqRhs *EqRhs)
|
|---|
| 37 | : G4MagIntegratorStepper(EqRhs,6), hStep(0.), fPtrMagEqOfMot(EqRhs)
|
|---|
| 38 | {
|
|---|
| 39 | }
|
|---|
| 40 |
|
|---|
| 41 | G4RKG3_Stepper::~G4RKG3_Stepper()
|
|---|
| 42 | {
|
|---|
| 43 | }
|
|---|
| 44 |
|
|---|
| 45 | void G4RKG3_Stepper::Stepper( const G4double yInput[8],
|
|---|
| 46 | const G4double dydx[6],
|
|---|
| 47 | G4double Step,
|
|---|
| 48 | G4double yOut[8],
|
|---|
| 49 | G4double yErr[])
|
|---|
| 50 | {
|
|---|
| 51 | G4double B[3];
|
|---|
| 52 | G4int nvar = 6 ;
|
|---|
| 53 | G4int i;
|
|---|
| 54 | G4double by15 = 1. / 15. ; // was 0.066666666 ;
|
|---|
| 55 |
|
|---|
| 56 | G4double yTemp[8], dydxTemp[6], yIn[8] ;
|
|---|
| 57 | // Saving yInput because yInput and yOut can be aliases for same array
|
|---|
| 58 | for(i=0;i<nvar;i++) yIn[i]=yInput[i];
|
|---|
| 59 | yIn[6] = yInput[6];
|
|---|
| 60 | yIn[7] = yInput[7];
|
|---|
| 61 | G4double h = Step * 0.5;
|
|---|
| 62 | hStep=Step;
|
|---|
| 63 | // Do two half steps
|
|---|
| 64 |
|
|---|
| 65 | StepNoErr(yIn, dydx,h, yTemp,B) ;
|
|---|
| 66 |
|
|---|
| 67 | //Store Bfld for DistChord Calculation
|
|---|
| 68 | for(i=0;i<3;i++)BfldIn[i]=B[i];
|
|---|
| 69 |
|
|---|
| 70 | // RightHandSide(yTemp,dydxTemp) ;
|
|---|
| 71 |
|
|---|
| 72 | GetEquationOfMotion()->EvaluateRhsGivenB(yTemp,B,dydxTemp) ;
|
|---|
| 73 | StepNoErr(yTemp,dydxTemp,h,yOut,B);
|
|---|
| 74 |
|
|---|
| 75 | // Store midpoint, chord calculation
|
|---|
| 76 |
|
|---|
| 77 | fyMidPoint = G4ThreeVector( yTemp[0], yTemp[1], yTemp[2]);
|
|---|
| 78 |
|
|---|
| 79 | // Do a full Step
|
|---|
| 80 |
|
|---|
| 81 | h *= 2 ;
|
|---|
| 82 | StepNoErr(yIn,dydx,h,yTemp,B);
|
|---|
| 83 | for(i=0;i<nvar;i++)
|
|---|
| 84 | {
|
|---|
| 85 | yErr[i] = yOut[i] - yTemp[i] ;
|
|---|
| 86 | yOut[i] += yErr[i]*by15 ; // Provides 5th order of accuracy
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | //Store values for DistChord method
|
|---|
| 90 |
|
|---|
| 91 | fyInitial = G4ThreeVector( yIn[0], yIn[1], yIn[2]);
|
|---|
| 92 | fpInitial = G4ThreeVector( yIn[3], yIn[4], yIn[5]);
|
|---|
| 93 | fyFinal = G4ThreeVector( yOut[0], yOut[1], yOut[2]);
|
|---|
| 94 |
|
|---|
| 95 | // NormaliseTangentVector( yOut ); // Deleted
|
|---|
| 96 | }
|
|---|
| 97 |
|
|---|
| 98 | // ---------------------------------------------------------------------------
|
|---|
| 99 |
|
|---|
| 100 | // Integrator for RK from G3 with evaluation of error in solution and delta
|
|---|
| 101 | // geometry based on naive similarity with the case of uniform magnetic field.
|
|---|
| 102 | // B1[3] is input and is the first magnetic field values
|
|---|
| 103 | // B2[3] is output and is the final magnetic field values.
|
|---|
| 104 |
|
|---|
| 105 | void G4RKG3_Stepper::StepWithEst( const G4double*,
|
|---|
| 106 | const G4double*,
|
|---|
| 107 | G4double,
|
|---|
| 108 | G4double*,
|
|---|
| 109 | G4double&,
|
|---|
| 110 | G4double&,
|
|---|
| 111 | const G4double*,
|
|---|
| 112 | G4double* )
|
|---|
| 113 |
|
|---|
| 114 | {
|
|---|
| 115 | G4Exception("G4RKG3_Stepper::StepWithEst()", "ObsoleteMethod",
|
|---|
| 116 | FatalException, "Method no longer used.");
|
|---|
| 117 | }
|
|---|
| 118 |
|
|---|
| 119 | // -----------------------------------------------------------------
|
|---|
| 120 |
|
|---|
| 121 |
|
|---|
| 122 | // Integrator RK Stepper from G3 with only two field evaluation per Step.
|
|---|
| 123 | // It is used in propagation initial Step by small substeps after solution
|
|---|
| 124 | // error and delta geometry considerations. B[3] is magnetic field which
|
|---|
| 125 | // is passed from substep to substep.
|
|---|
| 126 |
|
|---|
| 127 | void G4RKG3_Stepper::StepNoErr(const G4double tIn[8],
|
|---|
| 128 | const G4double dydx[6],
|
|---|
| 129 | G4double Step,
|
|---|
| 130 | G4double tOut[8],
|
|---|
| 131 | G4double B[3] ) // const
|
|---|
| 132 |
|
|---|
| 133 | {
|
|---|
| 134 |
|
|---|
| 135 | // Copy and edit the routine above, to delete alpha2, beta2, ...
|
|---|
| 136 | G4double K1[7],K2[7],K3[7],K4[7] ;
|
|---|
| 137 | G4double tTemp[8], yderiv[6] ;
|
|---|
| 138 |
|
|---|
| 139 | // Need Momentum value to give correct values to the coefficients in equation
|
|---|
| 140 | // Integration on unit velocity, but tIn[3,4,5] is momentum
|
|---|
| 141 | G4double mom,inverse_mom;
|
|---|
| 142 | G4int i ;
|
|---|
| 143 | const G4double c1=0.5,c2=0.125,c3=1./6.;
|
|---|
| 144 |
|
|---|
| 145 | // GetEquationOfMotion()->EvaluateRhsReturnB(tIn,dydx,B1) ;
|
|---|
| 146 | // Correction for momentum not a velocity
|
|---|
| 147 | // Need the protection !!! must be not zero
|
|---|
| 148 | mom=std::sqrt(tIn[3]*tIn[3]+tIn[4]*tIn[4]+tIn[5]*tIn[5]);
|
|---|
| 149 | inverse_mom=1./mom;
|
|---|
| 150 | for(i=0;i<3;i++)
|
|---|
| 151 | {
|
|---|
| 152 | K1[i] = Step * dydx[i+3]*inverse_mom;
|
|---|
| 153 | tTemp[i] = tIn[i] + Step*(c1*tIn[i+3]*inverse_mom + c2*K1[i]) ;
|
|---|
| 154 | tTemp[i+3] = tIn[i+3] + c1*K1[i]*mom ;
|
|---|
| 155 |
|
|---|
| 156 | }
|
|---|
| 157 |
|
|---|
| 158 | GetEquationOfMotion()->EvaluateRhsReturnB(tTemp,yderiv,B) ;
|
|---|
| 159 |
|
|---|
| 160 |
|
|---|
| 161 | for(i=0;i<3;i++)
|
|---|
| 162 | {
|
|---|
| 163 | K2[i] = Step * yderiv[i+3]*inverse_mom;
|
|---|
| 164 | tTemp[i+3] = tIn[i+3] + c1*K2[i]*mom ;
|
|---|
| 165 | }
|
|---|
| 166 |
|
|---|
| 167 | // Given B, calculate yderiv !
|
|---|
| 168 | GetEquationOfMotion()->EvaluateRhsGivenB(tTemp,B,yderiv) ;
|
|---|
| 169 |
|
|---|
| 170 | for(i=0;i<3;i++)
|
|---|
| 171 | {
|
|---|
| 172 | K3[i] = Step * yderiv[i+3]*inverse_mom;
|
|---|
| 173 | tTemp[i] = tIn[i] + Step*(tIn[i+3]*inverse_mom + c1*K3[i]) ;
|
|---|
| 174 | tTemp[i+3] = tIn[i+3] + K3[i]*mom ;
|
|---|
| 175 | }
|
|---|
| 176 |
|
|---|
| 177 |
|
|---|
| 178 | // Calculates y-deriv(atives) & returns B too!
|
|---|
| 179 | GetEquationOfMotion()->EvaluateRhsReturnB(tTemp,yderiv,B) ;
|
|---|
| 180 |
|
|---|
| 181 |
|
|---|
| 182 | for(i=0;i<3;i++) // Output trajectory vector
|
|---|
| 183 | {
|
|---|
| 184 | K4[i] = Step * yderiv[i+3]*inverse_mom;
|
|---|
| 185 | tOut[i] = tIn[i] + Step*(tIn[i+3]*inverse_mom+ (K1[i] + K2[i] + K3[i])*c3) ;
|
|---|
| 186 | tOut[i+3] = tIn[i+3] + mom*(K1[i] + 2*K2[i] + 2*K3[i] +K4[i])*c3 ;
|
|---|
| 187 | }
|
|---|
| 188 | tOut[6] = tIn[6];
|
|---|
| 189 | tOut[7] = tIn[7];
|
|---|
| 190 | // NormaliseTangentVector( tOut );
|
|---|
| 191 |
|
|---|
| 192 |
|
|---|
| 193 | }
|
|---|
| 194 |
|
|---|
| 195 |
|
|---|
| 196 | // ---------------------------------------------------------------------------
|
|---|
| 197 |
|
|---|
| 198 | G4double G4RKG3_Stepper::DistChord() const
|
|---|
| 199 | {
|
|---|
| 200 | // Soon: must check whether h/R > 2 pi !!
|
|---|
| 201 | // Method below is good only for < 2 pi
|
|---|
| 202 | G4double distChord,distLine;
|
|---|
| 203 |
|
|---|
| 204 | if (fyInitial != fyFinal) {
|
|---|
| 205 | distLine= G4LineSection::Distline(fyMidPoint,fyInitial,fyFinal );
|
|---|
| 206 |
|
|---|
| 207 | distChord = distLine;
|
|---|
| 208 | }else{
|
|---|
| 209 | distChord = (fyMidPoint-fyInitial).mag();
|
|---|
| 210 | }
|
|---|
| 211 |
|
|---|
| 212 |
|
|---|
| 213 | return distChord;
|
|---|
| 214 |
|
|---|
| 215 | }
|
|---|
| 216 |
|
|---|