Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4DynamicParticle.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// G4DynamicParticle class implementation
27//
28// History:
29// - 2 December 1995, G.Cosmo - first design, based on object model.
30// - 29 January 1996, M.Asai - first implementation.
31// - 1996 - 2007, H.Kurashige - revisions.
32// - 15 March 2019, M.Novak - log-kinetic energy value is computed only
33// on demand if its stored value is not up-to-date.
34//---------------------------------------------------------------------
35
36#include "G4DynamicParticle.hh"
37#include "G4DecayProducts.hh"
38#include "G4LorentzVector.hh"
40#include "G4IonTable.hh"
41#include "G4PrimaryParticle.hh"
42
44{
46 return _instance;
47}
48
49static const G4double EnergyMomentumRelationAllowance = 1.0e-2*CLHEP::keV;
50static const G4double EnergyMRA2 =
51 EnergyMomentumRelationAllowance*EnergyMomentumRelationAllowance;
52
53////////////////////
54// -- constructors ----
55////////////////////
57 : theMomentumDirection(0.0,0.0,1.0),
58 thePolarization(0.0,0.0,0.0)
59{
60}
61
62////////////////////
64G4DynamicParticle(const G4ParticleDefinition* aParticleDefinition,
65 const G4ThreeVector& aMomentumDirection,
66 G4double aKineticEnergy)
67 : theMomentumDirection(aMomentumDirection),
68 thePolarization(0.0,0.0,0.0),
69 theParticleDefinition(aParticleDefinition),
70 theKineticEnergy(aKineticEnergy),
71 theDynamicalMass(aParticleDefinition->GetPDGMass()),
72 theDynamicalCharge(aParticleDefinition->GetPDGCharge()),
73 theDynamicalSpin(aParticleDefinition->GetPDGSpin()),
74 theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment())
75{
76}
77
78////////////////////
80G4DynamicParticle(const G4ParticleDefinition* aParticleDefinition,
81 const G4ThreeVector& aMomentumDirection,
82 G4double aKineticEnergy,
83 const G4double dynamicalMass)
84 : theMomentumDirection(aMomentumDirection),
85 thePolarization(0.0,0.0,0.0),
86 theParticleDefinition(aParticleDefinition),
87 theKineticEnergy(aKineticEnergy),
88 theDynamicalMass(aParticleDefinition->GetPDGMass()),
89 theDynamicalCharge(aParticleDefinition->GetPDGCharge()),
90 theDynamicalSpin(aParticleDefinition->GetPDGSpin()),
91 theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment())
92{
93 if (std::abs(theDynamicalMass-dynamicalMass)
94 > EnergyMomentumRelationAllowance)
95 {
96 if (dynamicalMass>EnergyMomentumRelationAllowance)
97 theDynamicalMass= dynamicalMass;
98 else
99 theDynamicalMass= 0.0;
100 }
101}
102
103////////////////////
105G4DynamicParticle(const G4ParticleDefinition* aParticleDefinition,
106 const G4ThreeVector& aParticleMomentum)
107 : thePolarization(0.0,0.0,0.0),
108 theParticleDefinition(aParticleDefinition),
109 theDynamicalMass(aParticleDefinition->GetPDGMass()),
110 theDynamicalCharge(aParticleDefinition->GetPDGCharge()),
111 theDynamicalSpin(aParticleDefinition->GetPDGSpin()),
112 theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment())
113{
114 SetMomentum(aParticleMomentum); // 3-dim momentum is given
115}
116
117////////////////////
119G4DynamicParticle(const G4ParticleDefinition* aParticleDefinition,
120 const G4LorentzVector& aParticleMomentum)
121 : thePolarization(0.0,0.0,0.0),
122 theParticleDefinition(aParticleDefinition),
123 theDynamicalMass(aParticleDefinition->GetPDGMass()),
124 theDynamicalCharge(aParticleDefinition->GetPDGCharge()),
125 theDynamicalSpin(aParticleDefinition->GetPDGSpin()),
126 theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment())
127{
128 Set4Momentum(aParticleMomentum); // 4-momentum vector (Lorentz vector)
129}
130
131////////////////////
133G4DynamicParticle(const G4ParticleDefinition * aParticleDefinition,
134 G4double totalEnergy,
135 const G4ThreeVector &aParticleMomentum)
136 : thePolarization(0.0,0.0,0.0),
137 theParticleDefinition(aParticleDefinition),
138 theDynamicalMass(aParticleDefinition->GetPDGMass()),
139 theDynamicalCharge(aParticleDefinition->GetPDGCharge()),
140 theDynamicalSpin(aParticleDefinition->GetPDGSpin()),
141 theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment())
142{
143 // total energy and 3-dim momentum are given
144 G4double pModule2 = aParticleMomentum.mag2();
145 if (pModule2 > 0.0)
146 {
147 G4double mass2 = totalEnergy*totalEnergy - pModule2;
148 G4double PDGmass2 = (aParticleDefinition->GetPDGMass())
149 * (aParticleDefinition->GetPDGMass());
150 SetMomentumDirection(aParticleMomentum.unit());
151 if (mass2 < EnergyMRA2)
152 {
153 theDynamicalMass = 0.;
154 SetKineticEnergy(totalEnergy);
155 }
156 else
157 {
158 if (std::abs(PDGmass2-mass2)>EnergyMRA2)
159 {
160 theDynamicalMass = std::sqrt(mass2);
161 SetKineticEnergy(totalEnergy-theDynamicalMass);
162 }
163 else
164 {
165 SetKineticEnergy(totalEnergy-theDynamicalMass);
166 }
167 }
168 }
169 else
170 {
171 SetMomentumDirection(1.0,0.0,0.0);
172 SetKineticEnergy(0.0);
173 }
174}
175
176////////////////////
178 : theMomentumDirection(right.theMomentumDirection),
179 thePolarization(right.thePolarization),
180 theParticleDefinition(right.theParticleDefinition),
181 theElectronOccupancy(nullptr),
182 thePreAssignedDecayProducts(nullptr), // Don't copy preassignedDecayProducts
183 primaryParticle(right.primaryParticle),
184 theKineticEnergy(right.theKineticEnergy),
185 theLogKineticEnergy(right.theLogKineticEnergy),
186 theBeta(right.theBeta),
187 theProperTime(right.theProperTime),
188 theDynamicalMass(right.theDynamicalMass),
189 theDynamicalCharge(right.theDynamicalCharge),
190 theDynamicalSpin(right.theDynamicalSpin),
191 theDynamicalMagneticMoment(right.theDynamicalMagneticMoment),
192 thePreAssignedDecayTime(-1.0),
193 verboseLevel(right.verboseLevel),
194 thePDGcode(right.thePDGcode)
195{
196 if (right.theElectronOccupancy != nullptr)
197 {
198 theElectronOccupancy = new G4ElectronOccupancy(*right.theElectronOccupancy);
199 }
200}
201
202////////////////////
204 : theMomentumDirection(from.theMomentumDirection),
205 thePolarization(from.thePolarization),
206 theParticleDefinition(from.theParticleDefinition),
207 theElectronOccupancy(from.theElectronOccupancy),
208 thePreAssignedDecayProducts(nullptr), // Don't move preassignedDecayProducts
209 primaryParticle(from.primaryParticle),
210 theKineticEnergy(from.theKineticEnergy),
211 theLogKineticEnergy(from.theLogKineticEnergy),
212 theBeta(from.theBeta),
213 theProperTime(from.theProperTime),
214 theDynamicalMass(from.theDynamicalMass),
215 theDynamicalCharge(from.theDynamicalCharge),
216 theDynamicalSpin(from.theDynamicalSpin),
217 theDynamicalMagneticMoment(from.theDynamicalMagneticMoment),
218 thePreAssignedDecayTime(-1.0),
219 verboseLevel(from.verboseLevel),
220 thePDGcode(from.thePDGcode)
221{
222 // Release the data from the source object
223 from.theParticleDefinition = nullptr;
224 from.theElectronOccupancy = nullptr;
225 from.thePreAssignedDecayProducts = nullptr;
226 from.primaryParticle = nullptr;
227}
228
229////////////////////
230// -- destructor ----
231////////////////////
233{
234 if (thePreAssignedDecayProducts != nullptr)
235 delete thePreAssignedDecayProducts;
236 thePreAssignedDecayProducts = nullptr;
237
238 if (theElectronOccupancy != nullptr)
239 delete theElectronOccupancy;
240 theElectronOccupancy = nullptr;
241}
242
243////////////////////
244// -- operators ----
245////////////////////
247{
248 if (this != &right)
249 {
250 theMomentumDirection = right.theMomentumDirection;
251 theParticleDefinition = right.theParticleDefinition;
252 thePolarization = right.thePolarization;
253 theKineticEnergy = right.theKineticEnergy;
254 theProperTime = right.theProperTime;
255
256 theDynamicalMass = right.theDynamicalMass;
257 theDynamicalCharge = right.theDynamicalCharge;
258 theDynamicalSpin = right.theDynamicalSpin;
259 theDynamicalMagneticMoment = right.theDynamicalMagneticMoment;
260
261 if (theElectronOccupancy != nullptr) { delete theElectronOccupancy; }
262 if (right.theElectronOccupancy != nullptr)
263 {
264 theElectronOccupancy =
265 new G4ElectronOccupancy(*right.theElectronOccupancy);
266 }
267 else
268 {
269 theElectronOccupancy = nullptr;
270 }
271
272 // thePreAssignedDecayProducts must not be copied.
273 thePreAssignedDecayProducts = nullptr;
274 thePreAssignedDecayTime = -1.0;
275
276 verboseLevel = right.verboseLevel;
277
278 // Primary particle information must be preserved
279 //*** primaryParticle = right.primaryParticle;
280
281 thePDGcode = right.thePDGcode;
282 }
283 return *this;
284}
285
286////////////////////
288{
289 if (this != &from)
290 {
291 theMomentumDirection = from.theMomentumDirection;
292 thePolarization = from.thePolarization;
293 theKineticEnergy = from.theKineticEnergy;
294 theProperTime = from.theProperTime;
295
296 theDynamicalMass = from.theDynamicalMass;
297 theDynamicalCharge = from.theDynamicalCharge;
298 theDynamicalSpin = from.theDynamicalSpin;
299 theDynamicalMagneticMoment = from.theDynamicalMagneticMoment;
300
301 if (theElectronOccupancy != nullptr) { delete theElectronOccupancy; }
302 theElectronOccupancy = from.theElectronOccupancy;
303 from.theElectronOccupancy = nullptr;
304
305 // thePreAssignedDecayProducts must not be moved.
306 thePreAssignedDecayProducts = nullptr;
307 from.thePreAssignedDecayProducts = nullptr;
308 thePreAssignedDecayTime = -1.0;
309
310 theParticleDefinition = from.theParticleDefinition;
311 from.theParticleDefinition = nullptr;
312
313 verboseLevel = from.verboseLevel;
314
315 primaryParticle = from.primaryParticle;
316 from.primaryParticle = nullptr;
317
318 thePDGcode = from.thePDGcode;
319 }
320 return *this;
321}
322
323////////////////////
325SetDefinition(const G4ParticleDefinition* aParticleDefinition)
326{
327 // remove preassigned decay
328 if (thePreAssignedDecayProducts != nullptr)
329 {
330#ifdef G4VERBOSE
331 if (verboseLevel>0)
332 {
333 G4cout << " G4DynamicParticle::SetDefinition()::"
334 << "!!! Pre-assigned decay products is attached !!!! " << G4endl;
335 G4cout << "!!! New Definition is "
336 << aParticleDefinition->GetParticleName() << " !!! " << G4endl;
337 G4cout << "!!! Pre-assigned decay products will be deleted !!!! "
338 << G4endl;
339 }
340#endif
341 delete thePreAssignedDecayProducts;
342 }
343 thePreAssignedDecayProducts = nullptr;
344
345 theParticleDefinition = aParticleDefinition;
346
347 // set Dynamic mass/charge
348 SetMass(theParticleDefinition->GetPDGMass());
349 theDynamicalCharge = theParticleDefinition->GetPDGCharge();
350 theDynamicalSpin = theParticleDefinition->GetPDGSpin();
351 theDynamicalMagneticMoment = theParticleDefinition->GetPDGMagneticMoment();
352
353 // Set electron orbits
354 if (theElectronOccupancy != nullptr)
355 {
356 delete theElectronOccupancy;
357 theElectronOccupancy = nullptr;
358 }
359}
360
361////////////////////
363{
364 return (this == (G4DynamicParticle *) &right);
365}
366
367////////////////////
369{
370 return (this != (G4DynamicParticle *) &right);
371}
372
373////////////////////
374// -- AllocateElectronOccupancy --
375////////////////////
377{
378 if (G4IonTable::IsIon(theParticleDefinition))
379 {
380 // Only ions can have ElectronOccupancy
381 theElectronOccupancy = new G4ElectronOccupancy();
382
383 }
384 else
385 {
386 theElectronOccupancy = nullptr;
387 }
388}
389
390////////////////////
391// -- methods for setting Energy/Momentum --
392////////////////////
394{
395 G4double pModule2 = momentum.mag2();
396 if (pModule2>0.0)
397 {
398 const G4double mass = theDynamicalMass;
399 SetMomentumDirection(momentum.unit());
400 SetKineticEnergy(pModule2/(std::sqrt(pModule2 + mass*mass)+mass));
401 }
402 else
403 {
404 SetMomentumDirection(1.0,0.0,0.0);
405 SetKineticEnergy(0.0);
406 }
407}
408
409////////////////////
411{
412 G4double pModule2 = momentum.vect().mag2();
413 if (pModule2>0.0)
414 {
415 SetMomentumDirection(momentum.vect().unit());
416 const G4double totalenergy = momentum.t();
417 const G4double mass2 = totalenergy*totalenergy - pModule2;
418 const G4double PDGmass2 = (theParticleDefinition->GetPDGMass())
419 * (theParticleDefinition->GetPDGMass());
420 if (mass2 < EnergyMRA2)
421 {
422 theDynamicalMass = 0.;
423 }
424 else if (std::abs(PDGmass2-mass2)>EnergyMRA2)
425 {
426 theDynamicalMass = std::sqrt(mass2);
427 }
428 SetKineticEnergy(totalenergy-theDynamicalMass);
429 }
430 else
431 {
432 SetMomentumDirection(1.0,0.0,0.0);
433 SetKineticEnergy(0.0);
434 }
435}
436
437////////////////////
438// --- Dump Information --
439////////////////////
440#ifdef G4VERBOSE
441void G4DynamicParticle::DumpInfo(G4int mode) const
442{
443 if (theParticleDefinition == nullptr)
444 {
445 G4cout << " G4DynamicParticle::DumpInfo() - Particle type not defined !!! "
446 << G4endl;
447 }
448 else
449 {
450 G4cout << " Particle type - " << theParticleDefinition->GetParticleName()
451 << G4endl
452 << " mass: " << GetMass()/CLHEP::GeV << "[GeV]" << G4endl
453 << " charge: " << GetCharge()/CLHEP::eplus << "[e]" << G4endl
454 << " Direction x: " << GetMomentumDirection().x() << ", y: "
455 << GetMomentumDirection().y() << ", z: "
457 << " Total Momentum = "
458 << GetTotalMomentum()/CLHEP::GeV << "[GeV]" << G4endl
459 << " Momentum: " << GetMomentum().x() /CLHEP::GeV << "[GeV]"
460 << ", y: " << GetMomentum().y() /CLHEP::GeV << "[GeV]"
461 << ", z: " << GetMomentum().z() /CLHEP::GeV << "[GeV]" << G4endl
462 << " Total Energy = "
463 << GetTotalEnergy()/CLHEP::GeV << "[GeV]" << G4endl
464 << " Kinetic Energy = "
465 << GetKineticEnergy()/CLHEP::GeV << "[GeV]" << G4endl
466 << " MagneticMoment [MeV/T]: "
467 << GetMagneticMoment()/CLHEP::MeV*CLHEP::tesla << G4endl
468 << " ProperTime = "
469 << GetProperTime() /CLHEP::ns << "[ns]" << G4endl;
470
471 if (mode>0)
472 {
473 if( theElectronOccupancy != nullptr)
474 {
475 theElectronOccupancy->DumpInfo();
476 }
477 }
478 }
479}
480#else
482{
483 return;
484}
485#endif
486
487////////////////////////
489{
490 return CLHEP::electron_mass_c2;
491}
G4Allocator< G4DynamicParticle > *& pDynamicParticleAllocator()
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
double z() const
Hep3Vector unit() const
double x() const
double mag2() const
double y() const
Hep3Vector vect() const
G4double GetMass() const
void SetMomentumDirection(const G4ThreeVector &aDirection)
void DumpInfo(G4int mode=0) const
const G4ThreeVector & GetMomentumDirection() const
G4bool operator==(const G4DynamicParticle &right) const
G4double GetCharge() const
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
void SetMass(G4double mass)
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
G4bool operator!=(const G4DynamicParticle &right) const
void Set4Momentum(const G4LorentzVector &momentum)
void SetMomentum(const G4ThreeVector &momentum)
G4double GetProperTime() const
G4ThreeVector GetMomentum() const
G4DynamicParticle & operator=(const G4DynamicParticle &right)
G4double GetMagneticMoment() const
G4double GetTotalMomentum() const
G4double GetElectronMass() const
void SetKineticEnergy(G4double aEnergy)
static G4bool IsIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1302
G4double GetPDGMagneticMoment() const
G4double GetPDGCharge() const
const G4String & GetParticleName() const
#define G4ThreadLocalStatic
Definition: tls.hh:76