Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4MuonMinusCaptureAtRest.cc
Go to the documentation of this file.
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// $Id$
27//
28// G4MuonMinusCaptureAtRest physics process
29// Larry Felawka (TRIUMF) and Art Olin (TRIUMF)
30// April 1998
31//---------------------------------------------------------------------
32//
33// Modifications:
34// 18/08/2000 V.Ivanchenko Update description
35// 12/12/2003 H.P.Wellisch Completly rewrite mu-nuclear part
36// 17/05/2006 V.Ivanchenko Cleanup
37// 15/11/2006 V.Ivanchenko Review and rewrite all kinematics
38// 24/01/2007 V.Ivanchenko Force to work with integer Z and A
39// 23/01/2009 V.Ivanchenko Add deregistration
40//
41//-----------------------------------------------------------------------------
42
44#include "G4DynamicParticle.hh"
45#include "Randomize.hh"
47#include "G4SystemOfUnits.hh"
48#include "G4He3.hh"
49#include "G4NeutrinoMu.hh"
50#include "G4Fragment.hh"
52#include "G4Proton.hh"
53#include "G4PionPlus.hh"
55#include "G4Fancy3DNucleus.hh"
58
59//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
60
62 G4ProcessType aType ) :
63 G4VRestProcess (processName, aType), nCascade(0), targetZ(0), targetA(0),
64 isInitialised(false)
65{
67 Cascade = new G4GHEKinematicsVector [17];
68 pSelector = new G4StopElementSelector();
69 pEMCascade = new G4MuMinusCaptureCascade();
70 theN = new G4Fancy3DNucleus();
71 theHandler = new G4ExcitationHandler();
73}
74
75//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
76
78{
80 delete [] Cascade;
81 delete pSelector;
82 delete pEMCascade;
83 delete theN;
84 delete theHandler;
85}
86
87//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
88
90{
91 return ( &p == G4MuonMinus::MuonMinus() );
92}
93
94//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
95
97{
99}
100
101//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
102
104{
106}
107
108//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
109
111 const G4Step&)
112{
113 //
114 // Handles MuonMinuss at rest; a MuonMinus can either create secondaries or
115 // do nothing (in which case it should be sent back to decay-handling
116 // section
117 //
119
120 // select element and get Z,A.
121 G4Element* aEle = pSelector->GetElement(track.GetMaterial());
122 targetZ = aEle->GetZ();
123 targetA = G4double(G4int(aEle->GetN()+0.5));
124 G4int ni = 0;
125
126 G4IsotopeVector* isv = aEle->GetIsotopeVector();
127 if(isv) ni = isv->size();
128
129 if(ni == 1) {
130 targetA = G4double(aEle->GetIsotope(0)->GetN());
131 } else if(ni > 1) {
134 G4int j = -1;
135 ni--;
136 do {
137 j++;
138 y -= ab[j];
139 } while (y > 0.0 && j < ni);
140 targetA = G4double(aEle->GetIsotope(j)->GetN());
141 }
142
143 // Do the electromagnetic cascade of the muon in the nuclear field.
144 nCascade = 0;
145 targetMass = G4NucleiProperties::GetNuclearMass(targetA, targetZ);
146 nCascade = pEMCascade->DoCascade(targetZ, targetMass, Cascade);
147
148 // Decide on Decay or Capture, and doit.
149 G4double lambdac = pSelector->GetMuonCaptureRate(targetZ, targetA);
150 G4double lambdad = pSelector->GetMuonDecayRate(targetZ, targetA);
151 G4double lambda = lambdac + lambdad;
152
153 // === Throw for capture time.
154
155 G4double tDelay = -std::log(G4UniformRand()) / lambda;
156
157 G4ReactionProductVector * captureResult = 0;
158 G4int nEmSecondaries = nCascade;
159 G4int nSecondaries = nCascade;
160 /*
161 G4cout << "lambda= " << lambda << " lambdac= " << lambdac
162 << " nem= " << nEmSecondaries << G4endl;
163 */
164 if( G4UniformRand()*lambda > lambdac)
165 pEMCascade->DoBoundMuonMinusDecay(targetZ, &nEmSecondaries, Cascade);
166 else
167 captureResult = DoMuCapture();
168
169 // fill the final state
170 if(captureResult) nSecondaries += captureResult->size();
171 else nSecondaries = nEmSecondaries;
172 //G4cout << " nsec= " << nSecondaries << " nem= " << nEmSecondaries << G4endl;
173
175
176 G4double globalTime = track.GetGlobalTime();
178 // Store nuclear cascade
179 if(captureResult) {
180 G4int n = captureResult->size();
181 for ( G4int isec = 0; isec < n; isec++ ) {
182 G4ReactionProduct* aParticle = captureResult->operator[](isec);
183 G4DynamicParticle * aNewParticle = new G4DynamicParticle();
184 aNewParticle->SetDefinition( aParticle->GetDefinition() );
185 G4LorentzVector itV(aParticle->GetTotalEnergy(), aParticle->GetMomentum());
186 aNewParticle->SetMomentum(itV.vect());
187 G4double localtime = globalTime + tDelay + aParticle->GetTOF();
188 G4Track* aNewTrack = new G4Track( aNewParticle, localtime, position);
189 aNewTrack->SetTouchableHandle(track.GetTouchableHandle());
190 aParticleChange.AddSecondary( aNewTrack );
191 delete aParticle;
192 }
193 delete captureResult;
194 }
195
196 // Store electromagnetic cascade
197
198 if(nEmSecondaries > 0) {
199
200 for ( G4int isec = 0; isec < nEmSecondaries; isec++ ) {
201 G4ParticleDefinition* pd = Cascade[isec].GetParticleDef();
202 G4double localtime = globalTime;
203 if(isec >= nCascade) localtime += tDelay;
204 if(pd) {
205 G4DynamicParticle* aNewParticle = new G4DynamicParticle;
206 aNewParticle->SetDefinition( pd );
207 aNewParticle->SetMomentum( Cascade[isec].GetMomentum() );
208
209 G4Track* aNewTrack = new G4Track( aNewParticle, localtime, position );
210 aNewTrack->SetTouchableHandle(track.GetTouchableHandle());
211 aParticleChange.AddSecondary( aNewTrack );
212 }
213 }
214 }
215
218
219 return &aParticleChange;
220}
221
222//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
223
224G4ReactionProductVector* G4MuonMinusCaptureAtRest::DoMuCapture()
225{
227 G4double muBindingEnergy = pEMCascade->GetKShellEnergy(targetZ);
228 /*
229 G4cout << "G4MuonMinusCaptureAtRest::DoMuCapture called Emu= "
230 << muBindingEnergy << G4endl;
231 */
232 // Energy on K-shell
233 G4double muEnergy = mumass + muBindingEnergy;
234 G4double muMom = std::sqrt(muBindingEnergy*(muBindingEnergy + 2.0*mumass));
235 G4double availableEnergy = targetMass + mumass - muBindingEnergy;
236 G4LorentzVector momInitial(0.0,0.0,0.0,availableEnergy);
237 G4LorentzVector momResidual;
238
239 G4ThreeVector vmu = muMom*pEMCascade->GetRandomVec();
240 G4LorentzVector aMuMom(vmu, muEnergy);
241
242 G4double residualMass =
243 G4NucleiProperties::GetNuclearMass(targetA, targetZ - 1.0);
244
245 G4ReactionProductVector* aPreResult = 0;
248
249 G4int iz = G4int(targetZ);
250 G4int ia = G4int(targetA);
251
252 // p, d, t, 3He or alpha as target
253 if(iz <= 2) {
254
255 if(ia > 1) {
256 if(iz == 1 && ia == 2) {
257 availableEnergy -= neutron_mass_c2;
258 } else if(iz == 1 && ia == 3) {
259 availableEnergy -= 2.0*neutron_mass_c2;
260 } else if(iz == 2) {
261 G4ParticleDefinition* pd = 0;
262 if (ia == 3) {
264 } else if(ia == 4) {
265 pd = G4Triton::Triton();
266 } else {
267 pd = G4ParticleTable::GetParticleTable()->FindIon(1,ia-1,0,1);
268 }
269
270 // G4cout << "Extra " << pd->GetParticleName() << G4endl;
271 availableEnergy -= pd->GetPDGMass();
272 }
273 }
274 //
275 // Computation in assumption of CM collision of mu and nucleaon
276 //
277 G4double Enu = 0.5*(availableEnergy -
278 neutron_mass_c2*neutron_mass_c2/availableEnergy);
279
280 // make the nu, and transform to lab;
281 G4ThreeVector nu3Mom = Enu*pEMCascade->GetRandomVec();
282
285 aN->SetTotalEnergy( availableEnergy - Enu );
286 aN->SetMomentum( -nu3Mom );
287
288 aNu->SetTotalEnergy( Enu );
289 aNu->SetMomentum( nu3Mom );
290 aPreResult = new G4ReactionProductVector();
291
292 aPreResult->push_back(aN );
293 aPreResult->push_back(aNu);
294
295 if(verboseLevel > 1)
296 G4cout << "DoMuCapture on H or He"
297 <<" EkinN(MeV)= " << (availableEnergy - Enu - neutron_mass_c2)/MeV
298 <<" Enu(MeV)= "<<aNu->GetTotalEnergy()/MeV
299 <<" n= " << aPreResult->size()
300 <<G4endl;
301
302 return aPreResult;
303 }
304
305 // pick random proton inside nucleus
306 G4double eEx;
307 do {
308 theN->Init(ia, iz);
309 G4LorentzVector thePMom;
310 G4Nucleon * aNucleon = 0;
311 G4int theProtonCounter = G4int( targetZ * G4UniformRand() );
312 G4int counter = 0;
313 theN->StartLoop();
314
315 while( (aNucleon=theN->GetNextNucleon()) ) {
316
317 if( aNucleon->GetDefinition() == G4Proton::Proton() ) {
318 counter++;
319 if(counter == theProtonCounter) {
320 thePMom = aNucleon->GetMomentum();
321 break;
322 }
323 }
324 }
325
326 // Get the nu momentum in the CMS
327 G4LorentzVector theCMS = thePMom + aMuMom;
328 G4ThreeVector bst = theCMS.boostVector();
329
330 G4double Ecms = theCMS.mag();
331 G4double Enu = 0.5*(Ecms - neutron_mass_c2*neutron_mass_c2/Ecms);
332 eEx = 0.0;
333
334 if(Enu > 0.0) {
335 // make the nu, and transform to lab;
336 G4ThreeVector nu3Mom = Enu*pEMCascade->GetRandomVec();
337 G4LorentzVector nuMom(nu3Mom, Enu);
338
339 // nu in lab.
340 nuMom.boost(bst);
341 aNu->SetTotalEnergy( nuMom.e() );
342 aNu->SetMomentum( nuMom.vect() );
343
344 // make residual
345 momResidual = momInitial - nuMom;
346
347 // Call pre-compound on the rest.
348 eEx = momResidual.mag();
349 if(verboseLevel > 1)
350 G4cout << "G4MuonMinusCaptureAtRest::DoMuCapture: "
351 << " Eex(MeV)= " << (eEx-residualMass)/MeV
352 << " Enu(MeV)= "<<aNu->GetTotalEnergy()/MeV
353 <<G4endl;
354 }
355 } while(eEx <= residualMass);
356
357// G4cout << "muonCapture : " << eEx << " " << residualMass
358// << " A,Z= " << targetA << ", "<< targetZ
359// << " " << G4int(targetA) << ", " << G4int(targetZ) << G4endl;
360
361 //
362 // Start Deexcitation
363 //
364 G4ThreeVector fromBreit = momResidual.boostVector();
365 G4LorentzVector fscm(0.0,0.0,0.0, eEx);
366 G4Fragment anInitialState;
367 anInitialState.SetA(targetA);
368 anInitialState.SetZ(G4double(iz - 1));
369 anInitialState.SetNumberOfParticles(2);
370 anInitialState.SetNumberOfCharged(0);
371 anInitialState.SetNumberOfHoles(1);
372 anInitialState.SetMomentum(fscm);
373 aPreResult = theHandler->BreakItUp(anInitialState);
374
375 G4ReactionProductVector::iterator ires;
376 G4double eBal = availableEnergy - aNu->GetTotalEnergy();
377 for(ires=aPreResult->begin(); ires!=aPreResult->end(); ires++) {
378 G4LorentzVector itV((*ires)->GetTotalEnergy(), (*ires)->GetMomentum());
379 itV.boost(fromBreit);
380 (*ires)->SetTotalEnergy(itV.t());
381 (*ires)->SetMomentum(itV.vect());
382 eBal -= itV.t();
383 }
384 //
385 // fill neutrino into result
386 //
387 aPreResult->push_back(aNu);
388
389 if(verboseLevel > 1)
390 G4cout << "DoMuCapture: Nsec= "
391 << aPreResult->size() << " Ebalance(MeV)= " << eBal/MeV
392 <<" E0(MeV)= " <<availableEnergy/MeV
393 <<" Mres(GeV)= " <<residualMass/GeV
394 <<G4endl;
395
396 return aPreResult;
397}
398
@ fHadronAtRest
std::vector< G4Isotope * > G4IsotopeVector
G4ProcessType
std::vector< G4ReactionProduct * > G4ReactionProductVector
@ fStopAndKill
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector boostVector() const
Hep3Vector vect() const
static G4Deuteron * Deuteron()
Definition: G4Deuteron.cc:94
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
void SetMomentum(const G4ThreeVector &momentum)
G4double * GetRelativeAbundanceVector() const
Definition: G4Element.hh:166
G4double GetZ() const
Definition: G4Element.hh:131
const G4Isotope * GetIsotope(G4int iso) const
Definition: G4Element.hh:169
G4double GetN() const
Definition: G4Element.hh:134
G4IsotopeVector * GetIsotopeVector() const
Definition: G4Element.hh:162
G4ReactionProductVector * BreakItUp(const G4Fragment &theInitialState) const
G4Nucleon * GetNextNucleon()
void Init(G4int theA, G4int theZ)
void SetZ(G4double value)
Definition: G4Fragment.hh:288
void SetNumberOfCharged(G4int value)
Definition: G4Fragment.hh:349
void SetNumberOfHoles(G4int valueTot, G4int valueP=0)
Definition: G4Fragment.hh:335
void SetA(G4double value)
Definition: G4Fragment.hh:294
void SetMomentum(const G4LorentzVector &value)
Definition: G4Fragment.hh:256
void SetNumberOfParticles(G4int value)
Definition: G4Fragment.hh:344
G4ParticleDefinition * GetParticleDef()
void DeRegisterExtraProcess(G4VProcess *)
void RegisterExtraProcess(G4VProcess *)
void RegisterParticleForExtraProcess(G4VProcess *, const G4ParticleDefinition *)
static G4HadronicProcessStore * Instance()
void PrintInfo(const G4ParticleDefinition *)
G4int GetN() const
Definition: G4Isotope.hh:94
void DoBoundMuonMinusDecay(G4double Z, G4int *nCascade, G4GHEKinematicsVector *Cascade)
G4int DoCascade(const G4double Z, const G4double A, G4GHEKinematicsVector *Cascade)
G4double GetKShellEnergy(G4double Z)
virtual G4bool IsApplicable(const G4ParticleDefinition &)
virtual void PreparePhysicsTable(const G4ParticleDefinition &)
virtual G4VParticleChange * AtRestDoIt(const G4Track &, const G4Step &)
virtual void BuildPhysicsTable(const G4ParticleDefinition &)
G4MuonMinusCaptureAtRest(const G4String &processName="muMinusCaptureAtRest", G4ProcessType aType=fHadronic)
static G4MuonMinus * MuonMinus()
Definition: G4MuonMinus.cc:100
static G4NeutrinoMu * NeutrinoMu()
Definition: G4NeutrinoMu.cc:85
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
static G4double GetNuclearMass(const G4double A, const G4double Z)
virtual G4ParticleDefinition * GetDefinition() const
Definition: G4Nucleon.hh:85
const G4LorentzVector & GetMomentum() const
Definition: G4Nucleon.hh:71
void AddSecondary(G4Track *aSecondary)
virtual void Initialize(const G4Track &)
G4ParticleDefinition * FindIon(G4int atomicNumber, G4int atomicMass, G4double excitationEnergy)
static G4ParticleTable * GetParticleTable()
static G4Proton * Proton()
Definition: G4Proton.cc:93
void SetMomentum(const G4double x, const G4double y, const G4double z)
void SetTotalEnergy(const G4double en)
G4double GetTotalEnergy() const
G4ThreeVector GetMomentum() const
G4double GetTOF() const
G4ParticleDefinition * GetDefinition() const
void SetDefinition(G4ParticleDefinition *aParticleDefinition)
Definition: G4Step.hh:78
G4Element * GetElement(const G4Material *aMaterial)
G4double GetMuonDecayRate(G4double Z, G4double A)
G4double GetMuonCaptureRate(G4double Z, G4double A)
const G4ThreeVector & GetPosition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4double GetGlobalTime() const
G4Material * GetMaterial() const
const G4TouchableHandle & GetTouchableHandle() const
static G4Triton * Triton()
Definition: G4Triton.cc:95
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetNumberOfSecondaries(G4int totSecondaries)
G4ParticleChange aParticleChange
Definition: G4VProcess.hh:289
G4int verboseLevel
Definition: G4VProcess.hh:368
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:403