Geant4-11
G4VParticleChange.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// G4VParticleChange class implementation
27//
28// Author: Hisaya Kurashige, 23 March 1998
29// --------------------------------------------------------------------
30
31#include "G4VParticleChange.hh"
32#include "G4SystemOfUnits.hh"
33#include "G4Track.hh"
34#include "G4Step.hh"
35#include "G4TrackFastVector.hh"
37
40
41// --------------------------------------------------------------------
43 : theSizeOftheListOfSecondaries(G4TrackFastVectorSize)
44{
45#ifdef G4VERBOSE
46 // activate CheckIt if in VERBOSE mode
47 debugFlag = true;
48#endif
50}
51
52// --------------------------------------------------------------------
54{
55 // check if tracks still exist in theListOfSecondaries
57 {
58 for(G4int index = 0; index < theNumberOfSecondaries; ++index)
59 {
60 delete(*theListOfSecondaries)[index];
61 }
62 }
64}
65
66// --------------------------------------------------------------------
68 : theStatusChange(right.theStatusChange)
69 , theSteppingControlFlag(right.theSteppingControlFlag)
70 , theLocalEnergyDeposit(right.theLocalEnergyDeposit)
71 , theNonIonizingEnergyDeposit(right.theNonIonizingEnergyDeposit)
72 , theTrueStepLength(right.theTrueStepLength)
73 , theParentWeight(right.theParentWeight)
74 , theSizeOftheListOfSecondaries(G4TrackFastVectorSize)
75 , verboseLevel(right.verboseLevel)
76 , theFirstStepInVolume(right.theFirstStepInVolume)
77 , theLastStepInVolume(right.theLastStepInVolume)
78 , fSetSecondaryWeightByProcess(right.fSetSecondaryWeightByProcess)
79 , debugFlag(right.debugFlag)
80{
83 for(G4int index = 0; index < theNumberOfSecondaries; ++index)
84 {
85 G4Track* newTrack = new G4Track(*((*right.theListOfSecondaries)[index]));
86 theListOfSecondaries->SetElement(index, newTrack);
87 }
88}
89
90// --------------------------------------------------------------------
92{
93 if(this != &right)
94 {
96 {
97 for(G4int index = 0; index < theNumberOfSecondaries; ++index)
98 {
99 if((*theListOfSecondaries)[index])
100 delete((*theListOfSecondaries)[index]);
101 }
102 }
104
107 for(G4int index = 0; index < theNumberOfSecondaries; ++index)
108 {
109 G4Track* newTrack = new G4Track(*((*right.theListOfSecondaries)[index]));
110 theListOfSecondaries->SetElement(index, newTrack);
111 }
117
120
124
126
128 debugFlag = right.debugFlag;
129 }
130 return *this;
131}
132
133// --------------------------------------------------------------------
135{
136 return (this == (G4VParticleChange*) &right);
137}
138
139// --------------------------------------------------------------------
141{
142 return (this != (G4VParticleChange*) &right);
143}
144
145// --------------------------------------------------------------------
147{
148 if(debugFlag)
149 CheckSecondary(*aTrack);
150
151 // add a secondary after size check
153 {
154 // set weight of secondary tracks
156 aTrack->SetWeight(theParentWeight);
159 }
160 else
161 {
162 delete aTrack;
163
164 G4Exception("G4VParticleChange::AddSecondary()", "TRACK101", JustWarning,
165 "Secondary buffer is full. The track is deleted!");
166 }
167}
168
169// --------------------------------------------------------------------
171{
172 // Update the G4Step specific attributes
177
179 {
180 pStep->SetFirstStepFlag();
181 }
182 else
183 {
184 pStep->ClearFirstStepFlag();
185 }
187 {
188 pStep->SetLastStepFlag();
189 }
190 else
191 {
192 pStep->ClearLastStepFlag();
193 }
194
195 return pStep;
196}
197
198// --------------------------------------------------------------------
200{
202 {
204 }
205 return UpdateStepInfo(Step);
206}
207
208// --------------------------------------------------------------------
210{
212 {
213 G4double initialWeight = Step->GetPreStepPoint()->GetWeight();
214 G4double currentWeight = Step->GetPostStepPoint()->GetWeight();
215 G4double finalWeight = (theParentWeight / initialWeight) * currentWeight;
216 Step->GetPostStepPoint()->SetWeight(finalWeight);
217 }
218 return UpdateStepInfo(Step);
219}
220
221// --------------------------------------------------------------------
223{
225 {
227 }
228 return UpdateStepInfo(Step);
229}
230
231// --------------------------------------------------------------------
233{
234 // Show header
235 G4int olprc = G4cout.precision(3);
236 G4cout << " -----------------------------------------------" << G4endl;
237 G4cout << " G4ParticleChange Information " << std::setw(20) << G4endl;
238 G4cout << " -----------------------------------------------" << G4endl;
239
240 G4cout << " # of secondaries : " << std::setw(20)
242
244 {
245 G4cout << " Pointer to 2ndaries : " << std::setw(20)
246 << GetSecondary(0) << G4endl;
247 G4cout << " (Showed only 1st one)" << G4endl;
248 }
249 G4cout << " -----------------------------------------------" << G4endl;
250
251 G4cout << " Energy Deposit (MeV): " << std::setw(20)
253
254 G4cout << " Non-ionizing Energy Deposit (MeV): " << std::setw(11)
256
257 G4cout << " Track Status : " << std::setw(20);
259 {
260 G4cout << " Alive";
261 }
263 {
264 G4cout << " StopButAlive";
265 }
266 else if(theStatusChange == fStopAndKill)
267 {
268 G4cout << " StopAndKill";
269 }
271 {
272 G4cout << " KillTrackAndSecondaries";
273 }
274 else if(theStatusChange == fSuspend)
275 {
276 G4cout << " Suspend";
277 }
279 {
280 G4cout << " PostponeToNextEvent";
281 }
282 G4cout << G4endl;
283 G4cout << " True Path Length (mm) : " << std::setw(18)
285 G4cout << " Stepping Control : " << std::setw(20)
288 {
289 G4cout << " First step in volume" << G4endl;
290 }
292 {
293 G4cout << " Last step in volume" << G4endl;
294 }
295 G4cout.precision(olprc);
296}
297
298// --------------------------------------------------------------------
300#ifdef G4VERBOSE
301 aTrack
302#endif
303)
304{
305 G4bool exitWithError = false;
306 G4double accuracy;
307 static G4ThreadLocal G4int nError = 0;
308#ifdef G4VERBOSE
309 const G4int maxError = 30;
310#endif
311
312 // Energy deposit should not be negative
313 G4bool itsOKforEnergy = true;
314 accuracy = -1.0 * theLocalEnergyDeposit / MeV;
315 if(accuracy > accuracyForWarning)
316 {
317 itsOKforEnergy = false;
318 nError += 1;
319 exitWithError = (accuracy > accuracyForException);
320#ifdef G4VERBOSE
321 if(nError < maxError)
322 {
323 G4cout << " G4VParticleChange::CheckIt : ";
324 G4cout << "the energy deposit is negative !!"
325 << " Difference: " << accuracy << "[MeV] " << G4endl;
326 G4cout << aTrack.GetDefinition()->GetParticleName()
327 << " E=" << aTrack.GetKineticEnergy() / MeV
328 << " pos=" << aTrack.GetPosition().x() / m << ", "
329 << aTrack.GetPosition().y() / m << ", "
330 << aTrack.GetPosition().z() / m << G4endl;
331 }
332#endif
333 }
334
335 // true path length should not be negative
336 G4bool itsOKforStepLength = true;
337 accuracy = -1.0 * theTrueStepLength / mm;
338 if(accuracy > accuracyForWarning)
339 {
340 itsOKforStepLength = false;
341 nError += 1;
342 exitWithError = (accuracy > accuracyForException);
343#ifdef G4VERBOSE
344 if(nError < maxError)
345 {
346 G4cout << " G4VParticleChange::CheckIt : ";
347 G4cout << "the true step length is negative !!"
348 << " Difference: " << accuracy << "[MeV] " << G4endl;
349 G4cout << aTrack.GetDefinition()->GetParticleName()
350 << " E=" << aTrack.GetKineticEnergy() / MeV
351 << " pos=" << aTrack.GetPosition().x() / m << ", "
352 << aTrack.GetPosition().y() / m << ", "
353 << aTrack.GetPosition().z() / m << G4endl;
354 }
355#endif
356 }
357#ifdef G4VERBOSE
358 if(!itsOKforStepLength || !itsOKforEnergy)
359 {
360 // dump out information of this particle change
361 DumpInfo();
362 }
363#endif
364
365 // Exit with error
366 if(exitWithError)
367 {
368 G4Exception("G4VParticleChange::CheckIt()", "TRACK001", EventMustBeAborted,
369 "Step length and/or energy deposit was illegal");
370 }
371
372 // correction
373 if(!itsOKforStepLength)
374 {
375 theTrueStepLength = (1.e-12) * mm;
376 }
377 if(!itsOKforEnergy)
378 {
380 }
381 return (itsOKforStepLength && itsOKforEnergy);
382}
383
384// --------------------------------------------------------------------
386{
387 G4bool exitWithError = false;
388 G4double accuracy;
389 static G4ThreadLocal G4int nError = 0;
390#ifdef G4VERBOSE
391 const G4int maxError = 30;
392#endif
393
394 // MomentumDirection should be unit vector
395 G4bool itsOKforMomentum = true;
396 if(aTrack.GetKineticEnergy() > 0.)
397 {
398 accuracy = std::fabs((aTrack.GetMomentumDirection()).mag2() - 1.0);
399 if(accuracy > accuracyForWarning)
400 {
401 itsOKforMomentum = false;
402 nError += 1;
403 exitWithError = exitWithError || (accuracy > accuracyForException);
404#ifdef G4VERBOSE
405 if(nError < maxError)
406 {
407 G4cout << " G4VParticleChange::CheckSecondary : ";
408 G4cout << "the Momentum direction is not unit vector !! "
409 << " Difference: " << accuracy << G4endl;
411 << " E=" << aTrack.GetKineticEnergy() / MeV
412 << " pos=" << aTrack.GetPosition().x() / m << ", "
413 << aTrack.GetPosition().y() / m << ", "
414 << aTrack.GetPosition().z() / m << G4endl;
415 }
416#endif
417 }
418 }
419
420 // Kinetic Energy should not be negative
421 G4bool itsOKforEnergy = true;
422 accuracy = -1.0 * (aTrack.GetKineticEnergy()) / MeV;
423 if(accuracy > accuracyForWarning)
424 {
425 itsOKforEnergy = false;
426 nError += 1;
427 exitWithError = exitWithError || (accuracy > accuracyForException);
428#ifdef G4VERBOSE
429 if(nError < maxError)
430 {
431 G4cout << " G4VParticleChange::CheckSecondary : ";
432 G4cout << "the kinetic energy is negative !!"
433 << " Difference: " << accuracy << "[MeV] " << G4endl;
434 G4cout << " G4VParticleChange::CheckSecondary : ";
435 G4cout << "the global time of secondary is earlier than the parent !!"
436 << " Difference: " << accuracy << "[ns] " << G4endl;
438 << " E=" << aTrack.GetKineticEnergy() / MeV
439 << " pos=" << aTrack.GetPosition().x() / m << ", "
440 << aTrack.GetPosition().y() / m << ", "
441 << aTrack.GetPosition().z() / m << G4endl;
442 }
443#endif
444 }
445 // Check timing of secondaries
446 G4bool itsOKforTiming = true;
447
448 accuracy = (theParentGlobalTime - aTrack.GetGlobalTime()) / ns;
449 if(accuracy > accuracyForWarning)
450 {
451 itsOKforTiming = false;
452 nError += 1;
453 exitWithError = (accuracy > accuracyForException);
454#ifdef G4VERBOSE
455 if(nError < maxError)
456 {
457 G4cout << " G4VParticleChange::CheckSecondary : ";
458 G4cout
459 << "the global time of secondary goes back comapared to the parent !!"
460 << " Difference: " << accuracy << "[ns] " << G4endl;
462 << " E=" << aTrack.GetKineticEnergy() / MeV
463 << " pos=" << aTrack.GetPosition().x() / m << ", "
464 << aTrack.GetPosition().y() / m << ", "
465 << aTrack.GetPosition().z() / m
466 << " time=" << aTrack.GetGlobalTime() / ns
467 << " parent time=" << theParentGlobalTime / ns << G4endl;
468 }
469#endif
470 }
471
472 // Exit with error
473 if(exitWithError)
474 {
475 G4Exception("G4VParticleChange::CheckSecondary()", "TRACK001",
476 EventMustBeAborted, "Secondary with illegal energy/momentum ");
477 }
478
479 G4bool itsOK = itsOKforMomentum && itsOKforEnergy && itsOKforTiming;
480
481 // correction
482 if(!itsOKforMomentum)
483 {
484 G4double vmag = (aTrack.GetMomentumDirection()).mag();
485 aTrack.SetMomentumDirection((1. / vmag) * aTrack.GetMomentumDirection());
486 }
487 if(!itsOKforEnergy)
488 {
489 aTrack.SetKineticEnergy(0.0);
490 }
491
492 if(!itsOK)
493 {
494 this->DumpInfo();
495 }
496
497 return itsOK;
498}
499
500// --------------------------------------------------------------------
502{
503 return accuracyForWarning;
504}
505
506// --------------------------------------------------------------------
508{
510}
511
512// --------------------------------------------------------------------
513// Obsolete methods for parent weight
514//
@ JustWarning
@ EventMustBeAborted
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
static constexpr double m
Definition: G4SIunits.hh:109
static constexpr double mm
Definition: G4SIunits.hh:95
static constexpr double MeV
Definition: G4SIunits.hh:200
G4FastVector< G4Track, G4TrackFastVectorSize > G4TrackFastVector
const G4int G4TrackFastVectorSize
@ fKillTrackAndSecondaries
@ fSuspend
@ fAlive
@ fStopAndKill
@ fStopButAlive
@ fPostponeToNextEvent
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
double x() const
double y() const
void SetElement(G4int anIndex, Type *anElement)
Definition: G4FastVector.hh:72
const G4String & GetParticleName() const
void SetWeight(G4double aValue)
G4double GetWeight() const
Definition: G4Step.hh:62
void SetLastStepFlag()
void SetStepLength(G4double value)
void AddNonIonizingEnergyDeposit(G4double value)
void AddTotalEnergyDeposit(G4double value)
G4StepPoint * GetPreStepPoint() const
void SetControlFlag(G4SteppingControl StepControlFlag)
void ClearLastStepFlag()
void SetFirstStepFlag()
void ClearFirstStepFlag()
G4StepPoint * GetPostStepPoint() const
void SetWeight(G4double aValue)
const G4ThreeVector & GetPosition() const
G4double GetGlobalTime() const
G4ParticleDefinition * GetDefinition() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
void SetKineticEnergy(const G4double aValue)
void SetMomentumDirection(const G4ThreeVector &aValue)
virtual G4bool CheckIt(const G4Track &)
static const G4double accuracyForException
G4TrackStatus theStatusChange
G4TrackFastVector * theListOfSecondaries
G4SteppingControl theSteppingControlFlag
static const G4double accuracyForWarning
G4bool IsParentWeightSetByProcess() const
virtual G4Step * UpdateStepForAlongStep(G4Step *Step)
virtual G4Step * UpdateStepForAtRest(G4Step *Step)
G4double theNonIonizingEnergyDeposit
virtual G4Step * UpdateStepForPostStep(G4Step *Step)
G4double GetAccuracyForException() const
void AddSecondary(G4Track *aSecondary)
void SetParentWeightByProcess(G4bool)
G4double GetAccuracyForWarning() const
virtual void DumpInfo() const
G4VParticleChange & operator=(const G4VParticleChange &right)
G4bool CheckSecondary(G4Track &)
G4Step * UpdateStepInfo(G4Step *Step)
G4Track * GetSecondary(G4int anIndex) const
G4bool operator==(const G4VParticleChange &right) const
G4bool operator!=(const G4VParticleChange &right) const
virtual ~G4VParticleChange()
#define G4ThreadLocal
Definition: tls.hh:77
#define ns
Definition: xmlparse.cc:614