Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4BogackiShampine23 implementation << 26 // Bogacki-Shampine - 4 - 3(2) non-FSAL implementation by Somnath Banerjee >> 27 // Supervision / code review: John Apostolakis 27 // 28 // 28 // Bogacki-Shampine - 4 - 3(2) non-FSAL imple << 29 // Sponsored by Google in Google Summer of Code 2015. 29 // << 30 // Implementation of the method proposed in t << 31 // "A 3(2) pair of Runge - Kutta formulas" << 32 // by P. Bogacki and L. F. Shampine, << 33 // Appl. Math. Lett., vol. 2, no. 4, pp. 32 << 34 // 30 // 35 // The Bogacki shampine method has the followi << 31 // First version: 20 May 2015 36 // << 37 // 0 | << 38 // 1/2|1/2 << 39 // 3/4|0 3/4 << 40 // 1 |2/9 1/3 4/9 << 41 // ------------------- << 42 // |2/9 1/3 4/9 0 << 43 // |7/24 1/4 1/3 1/8 << 44 // 32 // 45 // Created: Somnath Banerjee, Google Summer of << 33 // History 46 // Supervision: John Apostolakis, CERN << 34 // ----------------------------- 47 // ------------------------------------------- << 35 // Created by Somnath Banerjee on 20 May 2015 >> 36 /////////////////////////////////////////////////////////////////////////////// >> 37 >> 38 >> 39 /* >> 40 >> 41 This contains the stepper function of the G4BogackiShampine23 class >> 42 >> 43 The Bogacki shampine method has the following Butcher's tableau >> 44 >> 45 0 | >> 46 1/2|1/2 >> 47 3/4|0 3/4 >> 48 1 |2/9 1/3 4/9 >> 49 ------------------- >> 50 |2/9 1/3 4/9 0 >> 51 |7/24 1/4 1/3 1/8 >> 52 >> 53 */ 48 54 49 #include "G4BogackiShampine23.hh" 55 #include "G4BogackiShampine23.hh" 50 #include "G4LineSection.hh" 56 #include "G4LineSection.hh" 51 #include "G4FieldUtils.hh" << 52 57 53 using namespace field_utils; << 58 // using namespace std; 54 59 55 G4BogackiShampine23::G4BogackiShampine23(G4Equ << 60 //Constructor 56 G4int << 61 G4BogackiShampine23::G4BogackiShampine23(G4EquationOfMotion *EqRhs, 57 : G4MagIntegratorStepper(EqRhs, integrationV << 62 G4int noIntegrationVariables, >> 63 G4bool primary) >> 64 : G4MagIntegratorStepper(EqRhs, noIntegrationVariables), >> 65 fLastStepLength(0.), fAuxStepper(nullptr) 58 { 66 { 59 SetIntegrationOrder(3); << 67 const G4int numberOfVariables = noIntegrationVariables; >> 68 >> 69 SetIntegrationOrder(2); // Apparently 3-rd order extension not used 60 SetFSAL(true); 70 SetFSAL(true); >> 71 >> 72 ak2 = new G4double[numberOfVariables] ; >> 73 ak3 = new G4double[numberOfVariables] ; >> 74 ak4 = new G4double[numberOfVariables] ; >> 75 >> 76 pseudoDydx_for_DistChord = new G4double[numberOfVariables]; >> 77 >> 78 const G4int numStateVars = std::max(noIntegrationVariables, >> 79 GetNumberOfStateVariables() ); >> 80 >> 81 yTemp = new G4double[numberOfVariables] ; >> 82 yIn = new G4double[numberOfVariables] ; >> 83 >> 84 fLastInitialVector = new G4double[numStateVars] ; >> 85 fLastFinalVector = new G4double[numStateVars] ; >> 86 fLastDyDx = new G4double[numStateVars]; >> 87 >> 88 fMidVector = new G4double[numStateVars]; >> 89 fMidError = new G4double[numStateVars]; >> 90 if( primary ) >> 91 { >> 92 fAuxStepper = new G4BogackiShampine23(EqRhs, numberOfVariables, !primary); >> 93 } 61 } 94 } 62 95 63 void G4BogackiShampine23::makeStep(const G4dou << 96 64 const G4dou << 97 //Destructor 65 const G4dou << 98 G4BogackiShampine23::~G4BogackiShampine23() 66 G4double yO << 67 G4double* d << 68 G4double* y << 69 { 99 { >> 100 delete[] ak2; >> 101 delete[] ak3; >> 102 delete[] ak4; >> 103 delete[] pseudoDydx_for_DistChord; >> 104 >> 105 delete[] yTemp; >> 106 delete[] yIn; >> 107 >> 108 delete[] fLastInitialVector; >> 109 delete[] fLastFinalVector; >> 110 delete[] fLastDyDx; >> 111 delete[] fMidVector; >> 112 delete[] fMidError; 70 113 71 G4double yTemp[G4FieldTrack::ncompSVEC]; << 114 delete fAuxStepper; 72 for(G4int i = GetNumberOfVariables(); i < Ge << 115 } 73 { << 74 yOutput[i] = yTemp[i] = yInput[i]; << 75 } << 76 116 77 G4double ak2[G4FieldTrack::ncompSVEC], << 117 //****************************************************************************** 78 ak3[G4FieldTrack::ncompSVEC]; << 118 // >> 119 // Given values for n = 4 variables yIn[0,...,n-1] >> 120 // known at x, use the 3rd order Bogacki Shampine method >> 121 // to advance the solution over an interval Step >> 122 // and return the incremented variables as yOut[0,...,n-1]. Also >> 123 // return an estimate of the local truncation error yErr[] using the >> 124 // embedded 2nd order method. The user supplies routine >> 125 // RightHandSide(y,dydx), which returns derivatives dydx for y . >> 126 >> 127 >> 128 //****************************************************************************** >> 129 >> 130 >> 131 void >> 132 G4BogackiShampine23::Stepper( const G4double yInput[], >> 133 const G4double DyDx[], >> 134 G4double Step, >> 135 G4double yOut[], >> 136 G4double yErr[]) >> 137 { >> 138 G4int i; 79 139 80 const G4double b21 = 0.5 , << 140 const G4double b21 = 0.5 , 81 b31 = 0., b32 = 3.0 / 4.0, << 141 b31 = 0. , b32 = 3.0/4.0 , 82 b41 = 2.0 / 9.0, b42 = 1.0 / << 142 b41 = 2.0/9.0, b42 = 1.0/3.0 , b43 = 4.0/9.0; 83 << 143 84 const G4double dc1 = b41 - 7.0 / 24.0, dc2 << 144 const G4double dc1 = b41 - 7.0/24.0 , dc2 = b42 - 1.0/4.0 , 85 dc3 = b43 - 1.0 / 3.0, dc4 << 145 dc3 = b43 - 1.0/3.0 , dc4 = - 0.125 ; 86 << 87 // RightHandSide(yInput, dydx); << 88 for(G4int i = 0; i < GetNumberOfVariables(); << 89 { << 90 yTemp[i] = yInput[i] + b21 * hstep * dydx[ << 91 } << 92 146 93 RightHandSide(yTemp, ak2); << 147 // Initialise time to t0, needed when it is not updated by the integration. 94 for(G4int i = 0; i < GetNumberOfVariables(); << 148 // [ Note: Only for time dependent fields (usually electric) 95 { << 149 // is it neccessary to integrate the time.] 96 yTemp[i] = yInput[i] + hstep * (b31 * dydx << 150 yOut[7] = yTemp[7] = yIn[7]; 97 } << 151 >> 152 const G4int numberOfVariables= this->GetNumberOfVariables(); // The number of variables to be integrated over >> 153 >> 154 // Saving yInput because yInput and yOut can be aliases for same array >> 155 >> 156 for(i=0;i<numberOfVariables;i++) >> 157 { >> 158 yIn[i]=yInput[i]; >> 159 } >> 160 // RightHandSide(yIn, dydx) ; // 1st Step --Not doing, getting passed >> 161 >> 162 for(i=0;i<numberOfVariables;i++) >> 163 { >> 164 yTemp[i] = yIn[i] + b21*Step*DyDx[i] ; >> 165 } >> 166 RightHandSide(yTemp, ak2) ; // 2nd Step >> 167 >> 168 for(i=0;i<numberOfVariables;i++) >> 169 { >> 170 yTemp[i] = yIn[i] + Step*(b31*DyDx[i] + b32*ak2[i]) ; >> 171 } >> 172 RightHandSide(yTemp, ak3) ; // 3rd Step 98 173 99 RightHandSide(yTemp, ak3); << 174 for(i=0;i<numberOfVariables;i++) 100 for(G4int i = 0; i < GetNumberOfVariables(); << 175 { 101 { << 176 yOut[i] = yIn[i] + Step*(b41*DyDx[i] + b42*ak2[i] + b43*ak3[i]) ; 102 yOutput[i] = yInput[i] + hstep * (b41*dydx << 177 // yOut[i] = yIn[i] + Step*(c1*DyDx[i]+ c2*ak2[i] + c3*ak3[i] + c4*ak4[i]); 103 } << 178 } >> 179 // Extra step used only in calculation of error >> 180 RightHandSide(yOut, ak4) ; // 4th Step >> 181 // Derivative and end-point already calculated in 'ak4' ! => Can be used in FSAL version 104 182 105 if ((dydxOutput != nullptr) && (yError != nu << 183 for(i=0;i<numberOfVariables;i++) 106 { << 107 RightHandSide(yOutput, dydxOutput); << 108 for(G4int i = 0; i < GetNumberOfVariables( << 109 { 184 { 110 yError[i] = hstep * (dc1 * dydx[i] + dc2 << 185 yErr[i] = Step*(dc1*DyDx[i] + dc2*ak2[i] + dc3*ak3[i] + 111 dc3 * ak3[i] + dc4 << 186 dc4*ak4[i] ) ; >> 187 >> 188 // Store Input and Final values, for possible use in calculating chord >> 189 fLastInitialVector[i] = yIn[i] ; >> 190 fLastFinalVector[i] = yOut[i]; >> 191 fLastDyDx[i] = DyDx[i]; 112 } 192 } 113 } << 193 // NormaliseTangentVector( yOut ); // Not wanted >> 194 >> 195 fLastStepLength =Step; >> 196 >> 197 return ; 114 } 198 } 115 199 116 void G4BogackiShampine23::Stepper(const G4doub << 200 G4double G4BogackiShampine23::DistChord() const 117 const G4doub << 118 G4double hst << 119 G4double yOu << 120 G4double yEr << 121 { 201 { 122 copy(fyIn, yInput); << 202 G4double distLine, distChord; 123 copy(fdydx, dydx); << 203 G4ThreeVector initialPoint, finalPoint, midPoint; 124 fhstep = hstep; << 125 << 126 makeStep(fyIn, fdydx, fhstep, fyOut, fdydxOu << 127 204 128 copy(yOutput, fyOut); << 205 // Store last initial and final points (they will be overwritten in self-Stepper call!) 129 } << 206 initialPoint = G4ThreeVector( fLastInitialVector[0], >> 207 fLastInitialVector[1], fLastInitialVector[2]); >> 208 finalPoint = G4ThreeVector( fLastFinalVector[0], >> 209 fLastFinalVector[1], fLastFinalVector[2]); 130 210 131 void G4BogackiShampine23::Stepper(const G4doub << 211 // Do half a step using StepNoErr 132 const G4doub << 133 G4double hst << 134 G4double yOu << 135 G4double yEr << 136 G4double dyd << 137 { << 138 copy(fyIn, yInput); << 139 copy(fdydx, dydx); << 140 fhstep = hstep; << 141 212 142 makeStep(fyIn, fdydx, fhstep, fyOut, fdydxOu << 213 fAuxStepper->Stepper( fLastInitialVector, fLastDyDx, 0.5 * fLastStepLength, >> 214 fMidVector, fMidError ); 143 215 144 copy(yOutput, fyOut); << 216 midPoint = G4ThreeVector( fMidVector[0], fMidVector[1], fMidVector[2]); 145 copy(dydxOutput, fdydxOut); << 146 } << 147 217 148 G4double G4BogackiShampine23::DistChord() cons << 218 // Use stored values of Initial and Endpoint + new Midpoint to evaluate 149 { << 219 // distance of Chord 150 G4double yMid[G4FieldTrack::ncompSVEC]; << 151 makeStep(fyIn, fdydx, fhstep / 2., yMid); << 152 220 153 const G4ThreeVector begin = makeVector(fyIn, << 154 const G4ThreeVector mid = makeVector(yMid, V << 155 const G4ThreeVector end = makeVector(fyOut, << 156 221 157 return G4LineSection::Distline(mid, begin, e << 222 if (initialPoint != finalPoint) >> 223 { >> 224 distLine = G4LineSection::Distline( midPoint, initialPoint, finalPoint ); >> 225 distChord = distLine; >> 226 } >> 227 else >> 228 { >> 229 distChord = (midPoint-initialPoint).mag(); >> 230 } >> 231 return distChord; 158 } 232 } >> 233 >> 234 //------Verified------- 159 235