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 // 26 // 27 // ------------------------------------------- 27 // ------------------------------------------------------------------- 28 // 28 // 29 // GEANT4 Class header file 29 // GEANT4 Class header file 30 // 30 // 31 // 31 // 32 // File name: G4eDPWACoulombScatteringMode 32 // File name: G4eDPWACoulombScatteringModel 33 // 33 // 34 // Author: Mihaly Novak 34 // Author: Mihaly Novak 35 // 35 // 36 // Creation date: 02.07.2020 36 // Creation date: 02.07.2020 37 // 37 // 38 // Modifications: 38 // Modifications: 39 // 39 // 40 // ------------------------------------------- 40 // ------------------------------------------------------------------- 41 41 42 #include "G4eDPWACoulombScatteringModel.hh" 42 #include "G4eDPWACoulombScatteringModel.hh" 43 43 44 #include "G4eDPWAElasticDCS.hh" 44 #include "G4eDPWAElasticDCS.hh" 45 #include "G4ParticleChangeForGamma.hh" 45 #include "G4ParticleChangeForGamma.hh" 46 #include "G4ParticleDefinition.hh" 46 #include "G4ParticleDefinition.hh" 47 #include "G4DataVector.hh" 47 #include "G4DataVector.hh" 48 48 49 #include "G4ProductionCutsTable.hh" 49 #include "G4ProductionCutsTable.hh" 50 #include "G4Material.hh" 50 #include "G4Material.hh" 51 #include "G4Element.hh" 51 #include "G4Element.hh" 52 #include "G4ElementVector.hh" 52 #include "G4ElementVector.hh" 53 53 54 #include "G4Electron.hh" 54 #include "G4Electron.hh" 55 55 56 #include "G4PhysicalConstants.hh" 56 #include "G4PhysicalConstants.hh" 57 #include "G4SystemOfUnits.hh" 57 #include "G4SystemOfUnits.hh" 58 #include "Randomize.hh" 58 #include "Randomize.hh" 59 #include "G4ThreeVector.hh" 59 #include "G4ThreeVector.hh" 60 60 61 61 62 G4eDPWACoulombScatteringModel::G4eDPWACoulombS 62 G4eDPWACoulombScatteringModel::G4eDPWACoulombScatteringModel(G4bool ismixed, G4bool isscpcor, G4double mumin) 63 : G4VEmModel("eDPWACoulombScattering"), 63 : G4VEmModel("eDPWACoulombScattering"), 64 fIsMixedModel(ismixed), 64 fIsMixedModel(ismixed), 65 fIsScpCorrection(isscpcor), 65 fIsScpCorrection(isscpcor), 66 fMuMin(mumin), 66 fMuMin(mumin), 67 fTheDCS(nullptr), 67 fTheDCS(nullptr), 68 fParticleChange(nullptr) 68 fParticleChange(nullptr) 69 { 69 { 70 SetLowEnergyLimit ( 0.0*CLHEP::eV); // eki 70 SetLowEnergyLimit ( 0.0*CLHEP::eV); // ekin = 10 eV is used if (E< 10 eV) 71 SetHighEnergyLimit(100.0*CLHEP::MeV); // eki 71 SetHighEnergyLimit(100.0*CLHEP::MeV); // ekin = 100 MeV is used if (E>100 MeV) 72 } 72 } 73 73 74 74 75 G4eDPWACoulombScatteringModel::~G4eDPWACoulomb 75 G4eDPWACoulombScatteringModel::~G4eDPWACoulombScatteringModel() 76 { 76 { 77 if (IsMaster()) { 77 if (IsMaster()) { 78 delete fTheDCS; 78 delete fTheDCS; 79 } 79 } 80 } 80 } 81 81 82 82 83 void G4eDPWACoulombScatteringModel::Initialise 83 void G4eDPWACoulombScatteringModel::Initialise(const G4ParticleDefinition* pdef, 84 84 const G4DataVector& prodcuts) 85 { 85 { 86 if(!fParticleChange) { 86 if(!fParticleChange) { 87 fParticleChange = GetParticleChangeForGamm 87 fParticleChange = GetParticleChangeForGamma(); 88 } 88 } 89 fMuMin = 0.5*(1.0-std::cos(PolarAngle 89 fMuMin = 0.5*(1.0-std::cos(PolarAngleLimit())); 90 fIsMixedModel = (fMuMin > 0.0); 90 fIsMixedModel = (fMuMin > 0.0); 91 if(IsMaster()) { 91 if(IsMaster()) { 92 // clean the G4eDPWAElasticDCS object if a 92 // clean the G4eDPWAElasticDCS object if any 93 delete fTheDCS; << 93 if (fTheDCS) { >> 94 delete fTheDCS; >> 95 } 94 fTheDCS = new G4eDPWAElasticDCS(pdef==G4El 96 fTheDCS = new G4eDPWAElasticDCS(pdef==G4Electron::Electron(), fIsMixedModel); 95 // init only for the elements that are use 97 // init only for the elements that are used in the geometry 96 G4ProductionCutsTable* theCpTable = G4Prod 98 G4ProductionCutsTable* theCpTable = G4ProductionCutsTable::GetProductionCutsTable(); 97 G4int numOfCouples = (G4int)theCpTable->Ge << 99 std::size_t numOfCouples = theCpTable->GetTableSize(); 98 for(G4int j=0; j<numOfCouples; ++j) { << 100 for(std::size_t j=0; j<numOfCouples; ++j) { 99 const G4Material* mat = theCpTable->GetM << 101 const G4Material* mat = theCpTable->GetMaterialCutsCouple(j)->GetMaterial(); 100 const G4ElementVector* elV = mat->GetEle 102 const G4ElementVector* elV = mat->GetElementVector(); 101 std::size_t numOfElem = mat->GetNumberOf << 103 std::size_t numOfElem = mat->GetNumberOfElements(); 102 for (std::size_t ie = 0; ie < numOfElem; << 104 for (size_t ie = 0; ie < numOfElem; ++ie) { 103 fTheDCS->InitialiseForZ((*elV)[ie]->Ge 105 fTheDCS->InitialiseForZ((*elV)[ie]->GetZasInt()); 104 } 106 } 105 } 107 } 106 // init scattering power correction 108 // init scattering power correction 107 if (fIsScpCorrection) { 109 if (fIsScpCorrection) { 108 fTheDCS->InitSCPCorrection(LowEnergyLimi 110 fTheDCS->InitSCPCorrection(LowEnergyLimit(), HighEnergyLimit()); 109 } 111 } 110 // will make use of the cross sections so 112 // will make use of the cross sections so the above needs to be done before 111 InitialiseElementSelectors(pdef, prodcuts) 113 InitialiseElementSelectors(pdef, prodcuts); 112 } 114 } 113 } 115 } 114 116 115 117 116 void G4eDPWACoulombScatteringModel::Initialise 118 void G4eDPWACoulombScatteringModel::InitialiseLocal(const G4ParticleDefinition*, 117 119 G4VEmModel* masterModel) 118 { 120 { 119 SetElementSelectors(masterModel->GetElementS 121 SetElementSelectors(masterModel->GetElementSelectors()); 120 SetTheDCS(static_cast<G4eDPWACoulombScatteri 122 SetTheDCS(static_cast<G4eDPWACoulombScatteringModel*>(masterModel)->GetTheDCS()); 121 } 123 } 122 124 123 125 124 G4double 126 G4double 125 G4eDPWACoulombScatteringModel::ComputeCrossSec 127 G4eDPWACoulombScatteringModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*, 126 128 G4double ekin, 127 129 G4double Z, 128 130 G4double /*A*/, 129 131 G4double /*prodcut*/, 130 132 G4double /*emax*/) 131 { 133 { 132 // Cross sections are computed by numerical 134 // Cross sections are computed by numerical integration of the pre-computed 133 // DCS data between the muMin, muMax limits 135 // DCS data between the muMin, muMax limits where mu(theta)=0.5[1-cos(theta)]. 134 // In case of single scattering model (i.e. 136 // In case of single scattering model (i.e. when fMuMin=0): [muMin=0, muMax=1] 135 // In case of mixed simulation model (i.e. 137 // In case of mixed simulation model (i.e. when fMuMin>0): [fMuMin , muMax=1] 136 // NOTE: cross sections will be zero if the 138 // NOTE: cross sections will be zero if the kinetic enrgy is out of the 137 // [10 eV-100 MeV] range for which DCS 139 // [10 eV-100 MeV] range for which DCS data has been computed. 138 // 140 // 139 G4double elCS = 0.0; // elastic cr 141 G4double elCS = 0.0; // elastic cross section 140 G4double tr1CS = 0.0; // first tran 142 G4double tr1CS = 0.0; // first transport cross section 141 G4double tr2CS = 0.0; // second tra 143 G4double tr2CS = 0.0; // second transport cross section 142 const G4double muMin = fMuMin; 144 const G4double muMin = fMuMin; 143 const G4double muMax = 1.0; 145 const G4double muMax = 1.0; 144 fTheDCS->ComputeCSPerAtom((G4int)Z, ekin, el 146 fTheDCS->ComputeCSPerAtom((G4int)Z, ekin, elCS, tr1CS, tr2CS, muMin, muMax); 145 // scattering power correction: should be on 147 // scattering power correction: should be only in condensed history ioni! 146 if (fIsScpCorrection && CurrentCouple()) { 148 if (fIsScpCorrection && CurrentCouple()) { 147 const G4double theScpCor = fTheDCS->Comput 149 const G4double theScpCor = fTheDCS->ComputeScatteringPowerCorrection(CurrentCouple(), ekin); 148 elCS *= (theScpCor*(1.0+1.0/Z)); 150 elCS *= (theScpCor*(1.0+1.0/Z)); 149 } 151 } 150 return std::max(0.0, elCS); 152 return std::max(0.0, elCS); 151 } 153 } 152 154 153 155 154 void 156 void 155 G4eDPWACoulombScatteringModel::SampleSecondari 157 G4eDPWACoulombScatteringModel::SampleSecondaries(std::vector<G4DynamicParticle*>*, 156 158 const G4MaterialCutsCouple* cp, 157 159 const G4DynamicParticle* dp, 158 160 G4double, G4double) 159 { 161 { 160 const G4double ekin = dp->GetKineticEne 162 const G4double ekin = dp->GetKineticEnergy(); 161 const G4double lekin = dp->GetLogKinetic 163 const G4double lekin = dp->GetLogKineticEnergy(); 162 const G4Element* target = SelectTargetAtom( 164 const G4Element* target = SelectTargetAtom(cp, dp->GetParticleDefinition(), ekin, lekin); 163 const G4int izet = target->GetZasInt 165 const G4int izet = target->GetZasInt(); 164 // sample cosine of the polar scattering ang 166 // sample cosine of the polar scattering angle in (hard) elastic insteraction 165 CLHEP::HepRandomEngine* rndmEngine = G4Rando 167 CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine(); 166 G4double cost = 1.0; 168 G4double cost = 1.0; 167 if (!fIsMixedModel) { 169 if (!fIsMixedModel) { 168 G4double rndm[3]; 170 G4double rndm[3]; 169 rndmEngine->flatArray(3, rndm); 171 rndmEngine->flatArray(3, rndm); 170 cost = fTheDCS->SampleCosineTheta(izet, le 172 cost = fTheDCS->SampleCosineTheta(izet, lekin, rndm[0], rndm[1], rndm[2]); 171 } else { 173 } else { 172 //sample cost between costMax,costMin wher 174 //sample cost between costMax,costMin where costMax = 1-2xfMuMin; 173 const G4double costMax = 1.0-2.0*fMuMin; 175 const G4double costMax = 1.0-2.0*fMuMin; 174 const G4double costMin = -1.0; 176 const G4double costMin = -1.0; 175 G4double rndm[2]; 177 G4double rndm[2]; 176 rndmEngine->flatArray(2, rndm); 178 rndmEngine->flatArray(2, rndm); 177 cost = fTheDCS->SampleCosineThetaRestricte 179 cost = fTheDCS->SampleCosineThetaRestricted(izet, lekin, rndm[0], rndm[1], costMin, costMax); 178 } 180 } 179 // compute the new direction in the scatteri 181 // compute the new direction in the scattering frame 180 const G4double sint = std::sqrt((1.0-cost)*( 182 const G4double sint = std::sqrt((1.0-cost)*(1.0+cost)); 181 const G4double phi = CLHEP::twopi*rndmEngin 183 const G4double phi = CLHEP::twopi*rndmEngine->flat(); 182 G4ThreeVector theNewDirection(sint*std::cos( 184 G4ThreeVector theNewDirection(sint*std::cos(phi), sint*std::sin(phi), cost); 183 // get original direction in lab frame and r 185 // get original direction in lab frame and rotate new direction to lab frame 184 G4ThreeVector theOrgDirectionLab = dp->GetMo 186 G4ThreeVector theOrgDirectionLab = dp->GetMomentumDirection(); 185 theNewDirection.rotateUz(theOrgDirectionLab) 187 theNewDirection.rotateUz(theOrgDirectionLab); 186 // set new direction 188 // set new direction 187 fParticleChange->ProposeMomentumDirection(th 189 fParticleChange->ProposeMomentumDirection(theNewDirection); 188 } 190 } 189 191 190 192 191 193 192 194 193 195 194 196