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 // $Id$ 26 // 27 // 27 //-------------------------------------------- 28 //----------------------------------------------------------------------------- 28 // 29 // 29 // GEANT4 Class file 30 // GEANT4 Class file 30 // 31 // 31 // File name: G4MuMinusCapturePrecompound 32 // File name: G4MuMinusCapturePrecompound 32 // 33 // 33 // Author: V.Ivanchenko (Vladimir.Ivant 34 // Author: V.Ivanchenko (Vladimir.Ivantchenko@cern.ch) 34 // 35 // 35 // Creation date: 22 April 2012 on base of G4M 36 // Creation date: 22 April 2012 on base of G4MuMinusCaptureCascade 36 // 37 // 37 // 38 // 38 //-------------------------------------------- 39 //----------------------------------------------------------------------------- 39 // 40 // 40 // Modifications: 41 // Modifications: 41 // 42 // 42 //-------------------------------------------- 43 //----------------------------------------------------------------------------- 43 44 44 #include "G4MuMinusCapturePrecompound.hh" 45 #include "G4MuMinusCapturePrecompound.hh" 45 #include "Randomize.hh" 46 #include "Randomize.hh" 46 #include "G4RandomDirection.hh" 47 #include "G4RandomDirection.hh" 47 #include "G4PhysicalConstants.hh" 48 #include "G4PhysicalConstants.hh" 48 #include "G4SystemOfUnits.hh" 49 #include "G4SystemOfUnits.hh" 49 #include "G4MuonMinus.hh" 50 #include "G4MuonMinus.hh" 50 #include "G4NeutrinoMu.hh" 51 #include "G4NeutrinoMu.hh" 51 #include "G4Neutron.hh" 52 #include "G4Neutron.hh" 52 #include "G4Proton.hh" 53 #include "G4Proton.hh" 53 #include "G4Triton.hh" 54 #include "G4Triton.hh" 54 #include "G4LorentzVector.hh" 55 #include "G4LorentzVector.hh" 55 #include "G4ParticleDefinition.hh" 56 #include "G4ParticleDefinition.hh" 56 #include "G4NucleiProperties.hh" 57 #include "G4NucleiProperties.hh" 57 #include "G4VPreCompoundModel.hh" 58 #include "G4VPreCompoundModel.hh" 58 #include "G4PreCompoundModel.hh" 59 #include "G4PreCompoundModel.hh" 59 #include "G4HadronicInteractionRegistry.hh" 60 #include "G4HadronicInteractionRegistry.hh" 60 61 61 //....oooOO0OOooo........oooOO0OOooo........oo 62 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 62 63 63 G4MuMinusCapturePrecompound::G4MuMinusCaptureP 64 G4MuMinusCapturePrecompound::G4MuMinusCapturePrecompound( 64 G4VPreCompoundModel* ptr) 65 G4VPreCompoundModel* ptr) 65 : G4HadronicInteraction("muMinusNuclearCaptu 66 : G4HadronicInteraction("muMinusNuclearCapture") 66 { 67 { 67 fMuMass = G4MuonMinus::MuonMinus()->GetPDGMa 68 fMuMass = G4MuonMinus::MuonMinus()->GetPDGMass(); 68 fProton = G4Proton::Proton(); 69 fProton = G4Proton::Proton(); 69 fNeutron = G4Neutron::Neutron(); 70 fNeutron = G4Neutron::Neutron(); 70 fThreshold = 10*MeV; 71 fThreshold = 10*MeV; 71 fTime = 0.0; << 72 fPreCompound = ptr; 72 fPreCompound = ptr; 73 if(!ptr) { 73 if(!ptr) { 74 G4HadronicInteraction* p = 74 G4HadronicInteraction* p = 75 G4HadronicInteractionRegistry::Instance( 75 G4HadronicInteractionRegistry::Instance()->FindModel("PRECO"); 76 ptr = static_cast<G4VPreCompoundModel*>(p) 76 ptr = static_cast<G4VPreCompoundModel*>(p); 77 fPreCompound = ptr; 77 fPreCompound = ptr; 78 if(!ptr) { fPreCompound = new G4PreCompoun 78 if(!ptr) { fPreCompound = new G4PreCompoundModel(); } 79 } 79 } 80 } 80 } 81 81 82 //....oooOO0OOooo........oooOO0OOooo........oo 82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 83 83 84 G4MuMinusCapturePrecompound::~G4MuMinusCapture 84 G4MuMinusCapturePrecompound::~G4MuMinusCapturePrecompound() 85 { 85 { 86 result.Clear(); 86 result.Clear(); 87 } 87 } 88 88 89 //....oooOO0OOooo........oooOO0OOooo........oo 89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 90 90 91 G4HadFinalState* 91 G4HadFinalState* 92 G4MuMinusCapturePrecompound::ApplyYourself(con 92 G4MuMinusCapturePrecompound::ApplyYourself(const G4HadProjectile& projectile, 93 G4Nucleus& targetNucleus) 93 G4Nucleus& targetNucleus) 94 { 94 { 95 result.Clear(); 95 result.Clear(); 96 result.SetStatusChange(stopAndKill); 96 result.SetStatusChange(stopAndKill); 97 fTime = projectile.GetGlobalTime(); 97 fTime = projectile.GetGlobalTime(); 98 G4double time0 = fTime; 98 G4double time0 = fTime; 99 99 100 G4double muBindingEnergy = projectile.GetBou 100 G4double muBindingEnergy = projectile.GetBoundEnergy(); 101 101 102 G4int Z = targetNucleus.GetZ_asInt(); 102 G4int Z = targetNucleus.GetZ_asInt(); 103 G4int A = targetNucleus.GetA_asInt(); 103 G4int A = targetNucleus.GetA_asInt(); 104 G4double massA = G4NucleiProperties::GetNucl 104 G4double massA = G4NucleiProperties::GetNuclearMass(A, Z); 105 105 106 /* 106 /* 107 G4cout << "G4MuMinusCapturePrecompound::Appl 107 G4cout << "G4MuMinusCapturePrecompound::ApplyYourself: Emu= " 108 << muBindingEnergy << G4endl; 108 << muBindingEnergy << G4endl; 109 */ 109 */ 110 // Energy on K-shell 110 // Energy on K-shell 111 G4double muEnergy = fMuMass + muBindingEnerg 111 G4double muEnergy = fMuMass + muBindingEnergy; 112 G4double muMom =std::sqrt(muBindingEnergy*(m << 112 G4double muMom = std::sqrt(muBindingEnergy*(muBindingEnergy + 2.0*fMuMass)); 113 G4double availableEnergy = massA + fMuMass - 113 G4double availableEnergy = massA + fMuMass - muBindingEnergy; 114 G4double residualMass = G4NucleiProperties:: 114 G4double residualMass = G4NucleiProperties::GetNuclearMass(A, Z - 1); 115 115 116 G4ThreeVector vmu = muMom*G4RandomDirection( 116 G4ThreeVector vmu = muMom*G4RandomDirection(); 117 G4LorentzVector aMuMom(vmu, muEnergy); 117 G4LorentzVector aMuMom(vmu, muEnergy); 118 118 119 const G4double nenergy = keV; << 120 << 121 // p or 3He as a target 119 // p or 3He as a target 122 // two body reaction mu- + A(Z,A) -> nuMu + 120 // two body reaction mu- + A(Z,A) -> nuMu + A(Z-1,A) 123 if((1 == Z && 1 == A) || (2 == Z && 3 == A)) 121 if((1 == Z && 1 == A) || (2 == Z && 3 == A)) { 124 122 125 const G4ParticleDefinition* pd = 0; << 123 G4ParticleDefinition* pd = 0; 126 if(1 == Z) { pd = fNeutron; } 124 if(1 == Z) { pd = fNeutron; } 127 else { pd = G4Triton::Triton(); } 125 else { pd = G4Triton::Triton(); } 128 126 129 // 127 // 130 // Computation in assumption of CM reacti 128 // Computation in assumption of CM reaction 131 // 129 // 132 G4double e = 0.5*(availableEnergy - 130 G4double e = 0.5*(availableEnergy - 133 residualMass*residualMass/availableE 131 residualMass*residualMass/availableEnergy); 134 132 135 G4ThreeVector nudir = G4RandomDirection(); 133 G4ThreeVector nudir = G4RandomDirection(); 136 AddNewParticle(G4NeutrinoMu::NeutrinoMu(), 134 AddNewParticle(G4NeutrinoMu::NeutrinoMu(), nudir, e); 137 nudir *= -1.0; 135 nudir *= -1.0; 138 AddNewParticle(pd, nudir, availableEnergy 136 AddNewParticle(pd, nudir, availableEnergy - e - residualMass); 139 137 140 // d or 4He as a target << 141 // three body reaction mu- + A(Z,A) -> nuMu << 142 // extra neutron produced at rest << 143 } else if((1 == Z && 2 == A) || (2 == Z && 4 << 144 << 145 const G4ParticleDefinition* pd = 0; << 146 if(1 == Z) { pd = fNeutron; } << 147 else { pd = G4Triton::Triton(); } << 148 << 149 availableEnergy -= neutron_mass_c2 - nener << 150 residualMass = pd->GetPDGMass(); << 151 << 152 // << 153 // Computation in assumption of CM reacti << 154 // << 155 G4double e = 0.5*(availableEnergy - << 156 residualMass*residualMass/availableE << 157 << 158 G4ThreeVector nudir = G4RandomDirection(); << 159 AddNewParticle(G4NeutrinoMu::NeutrinoMu(), << 160 nudir *= -1.0; << 161 AddNewParticle(pd, nudir, availableEnergy << 162 << 163 // extra low-energy neutron << 164 nudir = G4RandomDirection(); << 165 AddNewParticle(fNeutron, nudir, nenergy); << 166 138 167 } else { 139 } else { 168 // sample mu- + p -> nuMu + n reaction in 140 // sample mu- + p -> nuMu + n reaction in CM of muonic atom 169 141 >> 142 // muon >> 143 // >> 144 // NOTE by K.Genser and J.Yarba: >> 145 // The code below isn't working because emu always turns smaller than fMuMass >> 146 // For this reason the sqrt is producing a NaN >> 147 // >> 148 // G4double emu = (availableEnergy*availableEnergy - massA*massA >> 149 // + fMuMass*fMuMass)/(2*availableEnergy); >> 150 // G4ThreeVector mudir = G4RandomDirection(); >> 151 // G4LorentzVector momMuon(std::sqrt(emu*emu - fMuMass*fMuMass)*mudir, emu); >> 152 170 // nucleus 153 // nucleus 171 G4LorentzVector momInitial(0.0,0.0,0.0,ava 154 G4LorentzVector momInitial(0.0,0.0,0.0,availableEnergy); 172 G4LorentzVector momResidual, momNu; 155 G4LorentzVector momResidual, momNu; 173 156 174 // pick random proton inside nucleus 157 // pick random proton inside nucleus 175 G4double eEx; 158 G4double eEx; 176 fNucleus.Init(A, Z); 159 fNucleus.Init(A, Z); 177 const std::vector<G4Nucleon>& nucleons= fN 160 const std::vector<G4Nucleon>& nucleons= fNucleus.GetNucleons(); 178 const G4ParticleDefinition* pDef; << 161 G4ParticleDefinition* pDef; 179 162 >> 163 G4int nneutrons = 1; 180 G4int reentryCount = 0; 164 G4int reentryCount = 0; 181 165 182 do { 166 do { 183 ++reentryCount; 167 ++reentryCount; 184 G4int index = 0; 168 G4int index = 0; 185 do { 169 do { 186 index=G4int(A*G4UniformRand()); 170 index=G4int(A*G4UniformRand()); 187 pDef = nucleons[index].GetDefinition(); 171 pDef = nucleons[index].GetDefinition(); 188 } while(pDef != fProton); 172 } while(pDef != fProton); 189 G4LorentzVector momP = nucleons[index].G 173 G4LorentzVector momP = nucleons[index].Get4Momentum(); 190 174 191 // Get CMS kinematics 175 // Get CMS kinematics 192 G4LorentzVector theCMS = momP + aMuMom; 176 G4LorentzVector theCMS = momP + aMuMom; 193 G4ThreeVector bst = theCMS.boostVector() 177 G4ThreeVector bst = theCMS.boostVector(); 194 178 195 G4double Ecms = theCMS.mag(); 179 G4double Ecms = theCMS.mag(); 196 G4double Enu = 0.5*(Ecms - neutron_mass 180 G4double Enu = 0.5*(Ecms - neutron_mass_c2*neutron_mass_c2/Ecms); 197 eEx = 0.0; 181 eEx = 0.0; 198 182 199 if(Enu > 0.0) { 183 if(Enu > 0.0) { 200 // make the nu, and transform to lab; 184 // make the nu, and transform to lab; 201 momNu.set(Enu*G4RandomDirection(), Enu); 185 momNu.set(Enu*G4RandomDirection(), Enu); 202 186 203 // nu in lab. 187 // nu in lab. 204 momNu.boost(bst); 188 momNu.boost(bst); 205 momResidual = momInitial - momNu; 189 momResidual = momInitial - momNu; 206 eEx = momResidual.mag() - residualMass; 190 eEx = momResidual.mag() - residualMass; 207 if(eEx < 0.0 && eEx + nenergy >= 0.0) << 191 208 momResidual.set(0.0, 0.0, 0.0, resid << 192 // release neutron 209 eEx = 0.0; << 193 >> 194 if(eEx > 0.0) { >> 195 G4double eth = residualMass - massA + fThreshold + 2*neutron_mass_c2; >> 196 if(Ecms - Enu > eth) { >> 197 theCMS -= momNu; >> 198 G4double ekin = theCMS.e() - eth; >> 199 G4ThreeVector dir = theCMS.vect().unit(); >> 200 AddNewParticle(fNeutron, dir, ekin); >> 201 momResidual -= >> 202 result.GetSecondary(0)->GetParticle()->Get4Momentum(); >> 203 --Z; >> 204 --A; >> 205 residualMass = G4NucleiProperties::GetNuclearMass(A, Z); >> 206 nneutrons = 0; >> 207 } 210 } 208 } 211 } 209 } 212 // in the case of many iterations stop t << 210 if(Enu <= 0.0 && eEx <= 0.0 && reentryCount > 100) { 213 // with zero excitation energy << 214 if(reentryCount > 100 && eEx < 0.0) { << 215 G4ExceptionDescription ed; 211 G4ExceptionDescription ed; 216 ed << "Call for " << GetModelName() << G4end 212 ed << "Call for " << GetModelName() << G4endl; 217 ed << "Target Z= " << Z 213 ed << "Target Z= " << Z 218 << " A= " << A << " Eex(MeV)= " << eEx/ << 214 << " A= " << A << G4endl; 219 ed << " ApplyYourself does not completed aft << 215 ed << " ApplyYourself does not completed after 100 attempts" << G4endl; 220 << " excitation energy is set to zero"; << 216 G4Exception("G4MuMinusCapturePrecompound::AtRestDoIt", "had006", 221 G4Exception("G4MuMinusCapturePrecompound::Ap << 217 FatalException, ed); 222 JustWarning, ed); << 223 momResidual.set(0.0, 0.0, 0.0, residualMass) << 224 eEx = 0.0; << 225 } 218 } 226 // Loop checking, 06-Aug-2015, Vladimir << 227 } while(eEx <= 0.0); 219 } while(eEx <= 0.0); 228 220 229 G4ThreeVector dir = momNu.vect().unit(); 221 G4ThreeVector dir = momNu.vect().unit(); 230 AddNewParticle(G4NeutrinoMu::NeutrinoMu(), 222 AddNewParticle(G4NeutrinoMu::NeutrinoMu(), dir, momNu.e()); 231 223 232 G4Fragment initialState(A, Z-1, momResidua << 224 G4Fragment initialState(A, Z, momResidual); 233 initialState.SetNumberOfExcitedParticle(2, << 225 initialState.SetNumberOfExcitedParticle(nneutrons,0); 234 initialState.SetNumberOfHoles(1,1); 226 initialState.SetNumberOfHoles(1,1); 235 227 236 // decay time for pre-compound/de-excitati 228 // decay time for pre-compound/de-excitation starts from zero 237 G4ReactionProductVector* rpv = fPreCompoun 229 G4ReactionProductVector* rpv = fPreCompound->DeExcite(initialState); 238 size_t n = rpv->size(); 230 size_t n = rpv->size(); 239 for(size_t i=0; i<n; ++i) { 231 for(size_t i=0; i<n; ++i) { 240 G4ReactionProduct* rp = (*rpv)[i]; 232 G4ReactionProduct* rp = (*rpv)[i]; 241 233 242 // reaction time 234 // reaction time 243 fTime = time0 + rp->GetTOF(); 235 fTime = time0 + rp->GetTOF(); 244 G4ThreeVector direction = rp->GetMomentu 236 G4ThreeVector direction = rp->GetMomentum().unit(); 245 AddNewParticle(rp->GetDefinition(), dire 237 AddNewParticle(rp->GetDefinition(), direction, rp->GetKineticEnergy()); 246 delete rp; 238 delete rp; 247 } 239 } 248 delete rpv; 240 delete rpv; 249 } 241 } 250 if(verboseLevel > 1) 242 if(verboseLevel > 1) 251 G4cout << "G4MuMinusCapturePrecompound::Ap 243 G4cout << "G4MuMinusCapturePrecompound::ApplyYourself: Nsec= " 252 << result.GetNumberOfSecondaries() 244 << result.GetNumberOfSecondaries() 253 <<" E0(MeV)= " <<availableEnergy/MeV 245 <<" E0(MeV)= " <<availableEnergy/MeV 254 <<" Mres(GeV)= " <<residualMass/GeV 246 <<" Mres(GeV)= " <<residualMass/GeV 255 <<G4endl; 247 <<G4endl; 256 248 257 return &result; 249 return &result; 258 } 250 } 259 251 260 //....oooOO0OOooo........oooOO0OOooo........oo 252 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 261 253 262 void G4MuMinusCapturePrecompound::ModelDescrip 254 void G4MuMinusCapturePrecompound::ModelDescription(std::ostream& outFile) const 263 { 255 { 264 outFile << "Sampling of mu- capture by atomi 256 outFile << "Sampling of mu- capture by atomic nucleus from K-shell" 265 << " mesoatom orbit.\n" 257 << " mesoatom orbit.\n" 266 << "Primary reaction mu- + p -> n + neutri 258 << "Primary reaction mu- + p -> n + neutrino, neutron providing\n" 267 << " initial excitation of the target nuc 259 << " initial excitation of the target nucleus and PreCompound" 268 << " model samples final state\n"; 260 << " model samples final state\n"; 269 } 261 } 270 262 271 //....oooOO0OOooo........oooOO0OOooo........oo 263 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 272 264