Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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