Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4BFieldIntegrationDriver implementation 27 // 28 // Specialized integration driver for pure mag 29 // 30 // Author: D.Sorokin 31 // ------------------------------------------- 32 33 #include "G4BFieldIntegrationDriver.hh" 34 35 #include "G4FieldTrack.hh" 36 #include "G4FieldUtils.hh" 37 #include "G4Exception.hh" 38 #include "G4PhysicalConstants.hh" 39 #include "G4SystemOfUnits.hh" 40 #include "templates.hh" 41 42 43 namespace { 44 45 G4Mag_EqRhs* toMagneticEquation(G4EquationOfMo 46 { 47 auto e = dynamic_cast<G4Mag_EqRhs*>(equati 48 49 if (e == nullptr) 50 { 51 G4Exception("G4BFieldIntegrationDriver 52 "GeomField0003", FatalErro 53 "Works only with G4Mag_EqR 54 } 55 56 return e; 57 } 58 59 } // namespace 60 61 62 G4BFieldIntegrationDriver::G4BFieldIntegration 63 std::unique_ptr<G4VIntegrationDriver> smal 64 std::unique_ptr<G4VIntegrationDriver> larg 65 : fSmallStepDriver(std::move(smallStepDriv 66 fLargeStepDriver(std::move(largeStepDriv 67 fCurrDriver(fSmallStepDriver.get()), 68 fEquation(toMagneticEquation(fCurrDriver 69 { 70 if (fSmallStepDriver->GetEquationOfMotion( 71 != fLargeStepDriver->GetEquationOfMotion( 72 { 73 G4Exception("G4BFieldIntegrationDriver 74 "GeomField1001", FatalExce 75 } 76 } 77 78 G4double G4BFieldIntegrationDriver::AdvanceCho 79 80 81 82 { 83 const G4double radius = CurvatureRadius(yC 84 85 G4VIntegrationDriver* driver = nullptr; 86 if (chordDistance < 2 * radius) 87 { 88 stepMax = std::min(stepMax, twopi * ra 89 driver = fSmallStepDriver.get(); 90 ++fSmallDriverSteps; 91 } else 92 { 93 driver = fLargeStepDriver.get(); 94 ++fLargeDriverSteps; 95 } 96 97 if (driver != fCurrDriver) 98 { 99 driver->OnComputeStep(); 100 } 101 102 fCurrDriver = driver; 103 104 return fCurrDriver->AdvanceChordLimited(yC 105 ep 106 } 107 108 void 109 G4BFieldIntegrationDriver::SetEquationOfMotion 110 { 111 fEquation = toMagneticEquation(equation); 112 fSmallStepDriver->SetEquationOfMotion(equa 113 fLargeStepDriver->SetEquationOfMotion(equa 114 } 115 116 G4double 117 G4BFieldIntegrationDriver::CurvatureRadius(con 118 { 119 G4double field[G4Field::MAX_NUMBER_OF_COMP 120 121 GetFieldValue(track, field); 122 123 const G4double Bmag2 = field[0] * field[ 124 + field[1] * field[ 125 + field[2] * field[ 126 if (Bmag2 == 0.0 ) 127 { 128 return DBL_MAX; 129 } 130 131 const G4double momentum2 = track.GetMoment 132 const G4double fCof_inv = eplus / std::abs 133 134 return std::sqrt(momentum2 / Bmag2) * fCof 135 } 136 137 void 138 G4BFieldIntegrationDriver::GetFieldValue(const 139 G4dou 140 { 141 G4ThreeVector pos= track.GetPosition(); 142 G4double positionTime[4]= { pos.x(), pos.y 143 track.GetLabTi 144 145 fEquation->GetFieldValue(positionTime, Fie 146 } 147 148 void G4BFieldIntegrationDriver::PrintStatistic 149 { 150 const auto totSteps = fSmallDriverSteps + 151 const auto toFraction = [&](double value) 152 153 G4cout << "============= G4BFieldIntegrati 154 << "total steps " << totSteps << " 155 << "smallDriverSteps " << toFractio 156 << "largeDriverSteps " << toFractio 157 << "=============================== 158 } 159