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
G4Decay.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//
27// $Id$
28//
29//
30// --------------------------------------------------------------
31// GEANT 4 class implementation file
32//
33// History: first implementation, based on object model of
34// 2nd December 1995, G.Cosmo
35// 7 July 1996 H.Kurashige
36// ------------------------------------------------------------
37// remove BuildPhysicsTable() 28 Nov. 1997 H.Kurashige
38// change DBL_EPSIRON to DBL_MIN 14 Dec. 1997 H.Kurashige
39// modified for new ParticleChange 12 Mar. 1998 H.Kurashige
40// modified for "GoodForTrackingFlag" 19 June 1998 H.Kurashige
41// rename thePhysicsTable to aPhyscisTable 2 Aug. 1998 H.Kurashige
42// modified IsApplicable in order to protect the decay from registered
43// to resonances 12 Dec. 1998 H.Kurashige
44// remove G4ParticleMomentum 6 Feb. 99 H.Kurashige
45// modified IsApplicable to activate G4Decay for resonances 1 Mar. 00 H.Kurashige
46// Add External Decayer 23 Feb. 2001 H.Kurashige
47// change LowestBinValue,HighestBinValue and TotBin(200) 9 Feb. 2002
48//
49
50#include "G4Decay.hh"
51
53#include "G4SystemOfUnits.hh"
54#include "G4DynamicParticle.hh"
55#include "G4DecayProducts.hh"
56#include "G4DecayTable.hh"
57#include "G4VDecayChannel.hh"
58#include "G4PhysicsLogVector.hh"
60#include "G4VExtDecayer.hh"
61
62// constructor
63G4Decay::G4Decay(const G4String& processName)
64 :G4VRestDiscreteProcess(processName, fDecay),
65 verboseLevel(1),
66 HighestValue(20.0),
67 fRemainderLifeTime(-1.0),
68 pExtDecayer(0)
69{
70 // set Process Sub Type
71 SetProcessSubType(static_cast<int>(DECAY));
72
73#ifdef G4VERBOSE
74 if (GetVerboseLevel()>1) {
75 G4cout << "G4Decay constructor " << " Name:" << processName << G4endl;
76 }
77#endif
78
80}
81
83{
84 if (pExtDecayer) {
85 delete pExtDecayer;
86 }
87}
88
90{
91 // check if the particle is stable?
92 if (aParticleType.GetPDGLifeTime() <0.0) {
93 return false;
94 } else if (aParticleType.GetPDGMass() <= 0.0*MeV) {
95 return false;
96 } else {
97 return true;
98 }
99}
100
103{
104 // returns the mean free path in GEANT4 internal units
105 G4double meanlife;
106
107 // get particle
108 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
109 const G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
110 G4double aLife = aParticleDef->GetPDGLifeTime();
111
112 // check if the particle is stable?
113 if (aParticleDef->GetPDGStable()) {
114 meanlife = DBL_MAX;
115
116 } else {
117 meanlife = aLife;
118 }
119
120#ifdef G4VERBOSE
121 if (GetVerboseLevel()>1) {
122 G4cout << "mean life time: "<< meanlife/ns << "[ns]" << G4endl;
123 }
124#endif
125
126 return meanlife;
127}
128
130{
131 // get particle
132 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
133 const G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
134 G4double aMass = aParticle->GetMass();
135 G4double aLife = aParticleDef->GetPDGLifeTime();
136
137
138 // returns the mean free path in GEANT4 internal units
139 G4double pathlength;
140 G4double aCtau = c_light * aLife;
141
142 // check if the particle is stable?
143 if (aParticleDef->GetPDGStable()) {
144 pathlength = DBL_MAX;
145
146 //check if the particle has very short life time ?
147 } else if (aCtau < DBL_MIN) {
148 pathlength = DBL_MIN;
149
150 } else {
151 //calculate the mean free path
152 // by using normalized kinetic energy (= Ekin/mass)
153 G4double rKineticEnergy = aParticle->GetKineticEnergy()/aMass;
154 if ( rKineticEnergy > HighestValue) {
155 // gamma >> 1
156 pathlength = ( rKineticEnergy + 1.0)* aCtau;
157 } else if ( rKineticEnergy < DBL_MIN ) {
158 // too slow particle
159#ifdef G4VERBOSE
160 if (GetVerboseLevel()>1) {
161 G4cout << "G4Decay::GetMeanFreePath() !!particle stops!!";
162 G4cout << aParticleDef->GetParticleName() << G4endl;
163 G4cout << "KineticEnergy:" << aParticle->GetKineticEnergy()/GeV <<"[GeV]";
164 }
165#endif
166 pathlength = DBL_MIN;
167 } else {
168 // beta <1
169 pathlength = (aParticle->GetTotalMomentum())/aMass*aCtau ;
170 }
171 }
172 return pathlength;
173}
174
176{
177 return;
178}
179
181{
182 // The DecayIt() method returns by pointer a particle-change object.
183 // Units are expressed in GEANT4 internal units.
184
185 // Initialize ParticleChange
186 // all members of G4VParticleChange are set to equal to
187 // corresponding member in G4Track
189
190 // get particle
191 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
192 const G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
193
194 // check if the particle is stable
195 if (aParticleDef->GetPDGStable()) return &fParticleChangeForDecay ;
196
197
198 //check if thePreAssignedDecayProducts exists
199 const G4DecayProducts* o_products = (aParticle->GetPreAssignedDecayProducts());
200 G4bool isPreAssigned = (o_products != 0);
201 G4DecayProducts* products = 0;
202
203 // decay table
204 G4DecayTable *decaytable = aParticleDef->GetDecayTable();
205
206 // check if external decayer exists
207 G4bool isExtDecayer = (decaytable == 0) && (pExtDecayer !=0);
208
209 // Error due to NO Decay Table
210 if ( (decaytable == 0) && !isExtDecayer &&!isPreAssigned ){
211 if (GetVerboseLevel()>0) {
212 G4cout << "G4Decay::DoIt : decay table not defined for ";
213 G4cout << aParticle->GetDefinition()->GetParticleName()<< G4endl;
214 }
215 G4Exception( "G4Decay::DecayIt ",
216 "DECAY101",JustWarning,
217 "Decay table is not defined");
218
220 // Kill the parent particle
223
226 }
227
228 if (isPreAssigned) {
229 // copy decay products
230 products = new G4DecayProducts(*o_products);
231 } else if ( isExtDecayer ) {
232 // decay according to external decayer
233 products = pExtDecayer->ImportDecayProducts(aTrack);
234 } else {
235 // decay acoording to decay table
236 // choose a decay channel
237 G4VDecayChannel *decaychannel = decaytable->SelectADecayChannel();
238 if (decaychannel == 0 ){
239 // decay channel not found
240 G4Exception("G4Decay::DoIt", "DECAY003", FatalException,
241 " can not determine decay channel ");
242 } else {
243 // execute DecayIt()
244#ifdef G4VERBOSE
245 G4int temp = decaychannel->GetVerboseLevel();
246 if (GetVerboseLevel()>1) {
247 G4cout << "G4Decay::DoIt : selected decay channel addr:" << decaychannel <<G4endl;
248 decaychannel->SetVerboseLevel(GetVerboseLevel());
249 }
250#endif
251 products = decaychannel->DecayIt(aParticle->GetMass());
252#ifdef G4VERBOSE
253 if (GetVerboseLevel()>1) {
254 decaychannel->SetVerboseLevel(temp);
255 }
256#endif
257#ifdef G4VERBOSE
258 if (GetVerboseLevel()>2) {
259 if (! products->IsChecked() ) products->DumpInfo();
260 }
261#endif
262 }
263 }
264
265 // get parent particle information ...................................
266 G4double ParentEnergy = aParticle->GetTotalEnergy();
267 G4double ParentMass = aParticle->GetMass();
268 if (ParentEnergy < ParentMass) {
269 if (GetVerboseLevel()>0) {
270 G4cout << "G4Decay::DoIt : Total Energy is less than its mass" << G4endl;
271 G4cout << " Particle: " << aParticle->GetDefinition()->GetParticleName();
272 G4cout << " Energy:" << ParentEnergy/MeV << "[MeV]";
273 G4cout << " Mass:" << ParentMass/MeV << "[MeV]";
274 G4cout << G4endl;
275 }
276 G4Exception( "G4Decay::DecayIt ",
277 "DECAY102",JustWarning,
278 "Total Energy is less than its mass");
279 ParentEnergy = ParentMass;
280 }
281
282 G4ThreeVector ParentDirection(aParticle->GetMomentumDirection());
283
284 //boost all decay products to laboratory frame
285 G4double energyDeposit = 0.0;
286 G4double finalGlobalTime = aTrack.GetGlobalTime();
287 G4double finalLocalTime = aTrack.GetLocalTime();
288 if (aTrack.GetTrackStatus() == fStopButAlive ){
289 // AtRest case
290 finalGlobalTime += fRemainderLifeTime;
291 finalLocalTime += fRemainderLifeTime;
292 energyDeposit += aParticle->GetKineticEnergy();
293 if (isPreAssigned) products->Boost( ParentEnergy, ParentDirection);
294 } else {
295 // PostStep case
296 if (!isExtDecayer) products->Boost( ParentEnergy, ParentDirection);
297 }
298
299 // set polarization for daughter particles
300 DaughterPolarization(aTrack, products);
301
302
303 //add products in fParticleChangeForDecay
304 G4int numberOfSecondaries = products->entries();
306#ifdef G4VERBOSE
307 if (GetVerboseLevel()>1) {
308 G4cout << "G4Decay::DoIt : Decay vertex :";
309 G4cout << " Time: " << finalGlobalTime/ns << "[ns]";
310 G4cout << " X:" << (aTrack.GetPosition()).x() /cm << "[cm]";
311 G4cout << " Y:" << (aTrack.GetPosition()).y() /cm << "[cm]";
312 G4cout << " Z:" << (aTrack.GetPosition()).z() /cm << "[cm]";
313 G4cout << G4endl;
314 G4cout << "G4Decay::DoIt : decay products in Lab. Frame" << G4endl;
315 products->DumpInfo();
316 }
317#endif
318 G4int index;
319 G4ThreeVector currentPosition;
320 const G4TouchableHandle thand = aTrack.GetTouchableHandle();
321 for (index=0; index < numberOfSecondaries; index++)
322 {
323 // get current position of the track
324 currentPosition = aTrack.GetPosition();
325 // create a new track object
326 G4Track* secondary = new G4Track( products->PopProducts(),
327 finalGlobalTime ,
328 currentPosition );
329 // switch on good for tracking flag
330 secondary->SetGoodForTrackingFlag();
331 secondary->SetTouchableHandle(thand);
332 // add the secondary track in the List
334 }
335 delete products;
336
337 // Kill the parent particle
341
342 // Clear NumberOfInteractionLengthLeft
344
346}
347
349{
350}
351
352
353
355{
358
359 fRemainderLifeTime = -1.0;
360}
361
363{
364 // Clear NumberOfInteractionLengthLeft
366
368}
369
370
372 const G4Track& track,
373 G4double previousStepSize,
375 )
376{
377
378 // condition is set to "Not Forced"
380
381 // pre-assigned Decay time
384
385 if (pTime < 0.) {
386 // normal case
387 if ( previousStepSize > 0.0){
388 // subtract NumberOfInteractionLengthLeft
392 }
394 }
395 // get mean free path
396 currentInteractionLength = GetMeanFreePath(track, previousStepSize, condition);
397
398#ifdef G4VERBOSE
399 if ((currentInteractionLength <=0.0) || (verboseLevel>2)){
400 G4cout << "G4Decay::PostStepGetPhysicalInteractionLength " << G4endl;
401 track.GetDynamicParticle()->DumpInfo();
402 G4cout << " in Material " << track.GetMaterial()->GetName() <<G4endl;
403 G4cout << "MeanFreePath = " << currentInteractionLength/cm << "[cm]" <<G4endl;
404 }
405#endif
406
407 G4double value;
410 } else {
411 value = DBL_MAX;
412 }
413
414 return value;
415
416 } else {
417 //pre-assigned Decay time case
418 // reminder proper time
419 fRemainderLifeTime = pTime - track.GetProperTime();
421
422 G4double rvalue=0.0;
423 // use pre-assigned Decay time to determine PIL
424 if (aLife>0.0) {
425 // ordinary particle
426 rvalue = (fRemainderLifeTime/aLife)*GetMeanFreePath(track, previousStepSize, condition);
427 } else {
428 // shortlived particle
429 rvalue = c_light * fRemainderLifeTime;
430 // by using normalized kinetic energy (= Ekin/mass)
431 G4double aMass = track.GetDynamicParticle()->GetMass();
432 rvalue *= track.GetDynamicParticle()->GetTotalMomentum()/aMass;
433 }
434 return rvalue;
435 }
436}
437
439 const G4Track& track,
441 )
442{
443 // condition is set to "Not Forced"
445
447 if (pTime >= 0.) {
448 fRemainderLifeTime = pTime - track.GetProperTime();
450 } else {
453 }
454 return fRemainderLifeTime;
455}
456
457
459{
460 pExtDecayer = val;
461
462 // set Process Sub Type
463 if ( pExtDecayer !=0 ) {
464 SetProcessSubType(static_cast<int>(DECAY_External));
465 }
466}
@ DECAY_External
G4double condition(const G4ErrorSymMatrix &m)
@ JustWarning
@ FatalException
G4ForceCondition
@ NotForced
@ fDecay
@ fStopAndKill
@ fStopButAlive
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
void DumpInfo() const
G4int entries() const
G4DynamicParticle * PopProducts()
G4bool IsChecked() const
void Boost(G4double totalEnergy, const G4ThreeVector &momentumDirection)
G4VDecayChannel * SelectADecayChannel()
Definition: G4DecayTable.cc:81
virtual G4bool IsApplicable(const G4ParticleDefinition &)
Definition: G4Decay.cc:89
virtual G4double GetMeanFreePath(const G4Track &aTrack, G4double previousStepSize, G4ForceCondition *condition)
Definition: G4Decay.cc:129
virtual ~G4Decay()
Definition: G4Decay.cc:82
G4VExtDecayer * pExtDecayer
Definition: G4Decay.hh:181
virtual void EndTracking()
Definition: G4Decay.cc:362
virtual void DaughterPolarization(const G4Track &aTrack, G4DecayProducts *products)
Definition: G4Decay.cc:348
virtual G4double AtRestGetPhysicalInteractionLength(const G4Track &track, G4ForceCondition *condition)
Definition: G4Decay.cc:438
virtual void BuildPhysicsTable(const G4ParticleDefinition &)
Definition: G4Decay.cc:175
virtual G4VParticleChange * DecayIt(const G4Track &aTrack, const G4Step &aStep)
Definition: G4Decay.cc:180
G4double fRemainderLifeTime
Definition: G4Decay.hh:175
G4ParticleChangeForDecay fParticleChangeForDecay
Definition: G4Decay.hh:178
virtual G4double GetMeanLifeTime(const G4Track &aTrack, G4ForceCondition *condition)
Definition: G4Decay.cc:101
void SetExtDecayer(G4VExtDecayer *)
Definition: G4Decay.cc:458
G4int GetVerboseLevel() const
Definition: G4Decay.hh:188
const G4double HighestValue
Definition: G4Decay.hh:172
G4Decay(const G4String &processName="Decay")
Definition: G4Decay.cc:63
virtual void StartTracking(G4Track *)
Definition: G4Decay.cc:354
G4int verboseLevel
Definition: G4Decay.hh:164
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
Definition: G4Decay.cc:371
G4double GetMass() const
void DumpInfo(G4int mode=0) const
const G4ThreeVector & GetMomentumDirection() const
const G4DecayProducts * GetPreAssignedDecayProducts() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
G4double GetPreAssignedDecayProperTime() const
G4double GetTotalMomentum() const
const G4String & GetName() const
Definition: G4Material.hh:177
virtual void Initialize(const G4Track &)
G4DecayTable * GetDecayTable() const
G4double GetPDGLifeTime() const
const G4String & GetParticleName() const
Definition: G4Step.hh:78
G4TrackStatus GetTrackStatus() const
const G4ThreeVector & GetPosition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4double GetGlobalTime() const
G4double GetProperTime() const
G4double GetLocalTime() const
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
void SetGoodForTrackingFlag(G4bool value=true)
void SetVerboseLevel(G4int value)
G4int GetVerboseLevel() const
virtual G4DecayProducts * DecayIt(G4double parentMass=-1.0)=0
virtual G4DecayProducts * ImportDecayProducts(const G4Track &aTrack)=0
void ProposeTrackStatus(G4TrackStatus status)
void AddSecondary(G4Track *aSecondary)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetNumberOfSecondaries(G4int totSecondaries)
G4double currentInteractionLength
Definition: G4VProcess.hh:297
virtual void ResetNumberOfInteractionLengthLeft()
Definition: G4VProcess.cc:92
void ClearNumberOfInteractionLengthLeft()
Definition: G4VProcess.hh:418
void SubtractNumberOfInteractionLengthLeft(G4double previousStepSize)
Definition: G4VProcess.cc:98
G4double theNumberOfInteractionLengthLeft
Definition: G4VProcess.hh:293
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:403
G4VParticleChange * pParticleChange
Definition: G4VProcess.hh:283
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
#define DBL_MIN
Definition: templates.hh:75
#define DBL_MAX
Definition: templates.hh:83
#define ns
Definition: xmlparse.cc:597