Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/track/src/G4ParticleChange.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 // G4ParticleChange class implementation
 27 //
 28 // Author: Hisaya Kurashige, 23 March 1998  
 29 // --------------------------------------------------------------------
 30 
 31 #include "G4ParticleChange.hh"
 32 #include "G4PhysicalConstants.hh"
 33 #include "G4SystemOfUnits.hh"
 34 #include "G4Track.hh"
 35 #include "G4Step.hh"
 36 #include "G4DynamicParticle.hh"
 37 #include "G4ExceptionSeverity.hh"
 38 
 39 // --------------------------------------------------------------------
 40 G4ParticleChange::G4ParticleChange()
 41 {}
 42 
 43 // --------------------------------------------------------------------
 44 void G4ParticleChange::AddSecondary(G4DynamicParticle* aParticle,
 45                                     G4bool IsGoodForTracking)
 46 {
 47   // create track
 48   G4Track* aTrack = new G4Track(aParticle, GetGlobalTime(), thePositionChange);
 49 
 50   // set IsGoodGorTrackingFlag
 51   if(IsGoodForTracking)
 52     aTrack->SetGoodForTrackingFlag();
 53 
 54   // touchable handle is copied to keep the pointer
 55   aTrack->SetTouchableHandle(theCurrentTrack->GetTouchableHandle());
 56 
 57   // add a secondary
 58   G4VParticleChange::AddSecondary(aTrack);
 59 }
 60 
 61 // --------------------------------------------------------------------
 62 void G4ParticleChange::AddSecondary(G4DynamicParticle* aParticle,
 63                                     G4ThreeVector newPosition,
 64                                     G4bool IsGoodForTracking)
 65 {
 66   // create track
 67   G4Track* aTrack = new G4Track(aParticle, GetGlobalTime(), newPosition);
 68 
 69   // set IsGoodGorTrackingFlag
 70   if(IsGoodForTracking)
 71     aTrack->SetGoodForTrackingFlag();
 72 
 73   // touchable is a temporary object, so you cannot keep the pointer
 74   aTrack->SetTouchableHandle(nullptr);
 75 
 76   // add a secondary
 77   G4VParticleChange::AddSecondary(aTrack);
 78 }
 79 
 80 // --------------------------------------------------------------------
 81 void G4ParticleChange::AddSecondary(G4DynamicParticle* aParticle,
 82                                     G4double newTime, G4bool IsGoodForTracking)
 83 {
 84   // create track
 85   G4Track* aTrack = new G4Track(aParticle, newTime, thePositionChange);
 86 
 87   // set IsGoodGorTrackingFlag
 88   if(IsGoodForTracking)
 89     aTrack->SetGoodForTrackingFlag();
 90 
 91   // touchable handle is copied to keep the pointer
 92   aTrack->SetTouchableHandle(theCurrentTrack->GetTouchableHandle());
 93 
 94   // add a secondary
 95   G4VParticleChange::AddSecondary(aTrack);
 96 }
 97 
 98 // --------------------------------------------------------------------
 99 
100 void G4ParticleChange::AddSecondary(G4Track* aTrack)
101 {
102   // add a secondary
103   G4VParticleChange::AddSecondary(aTrack);
104 }
105 
106 // --------------------------------------------------------------------
107 void G4ParticleChange::Initialize(const G4Track& track)
108 {
109   // use base class's method at first
110   G4VParticleChange::Initialize(track);
111 
112   // set Energy/Momentum etc. equal to those of the parent particle
113   const G4DynamicParticle* pParticle = track.GetDynamicParticle();
114   theEnergyChange                    = pParticle->GetKineticEnergy();
115   theVelocityChange                  = track.GetVelocity();
116   isVelocityChanged                  = false;
117   theMomentumDirectionChange         = pParticle->GetMomentumDirection();
118   thePolarizationChange              = pParticle->GetPolarization();
119   theProperTimeChange                = pParticle->GetProperTime();
120 
121   // set mass/charge/MagneticMoment of DynamicParticle
122   theMassChange           = pParticle->GetMass();
123   theChargeChange         = pParticle->GetCharge();
124   theMagneticMomentChange = pParticle->GetMagneticMoment();
125 
126   // set Position equal to those of the parent track
127   thePositionChange = track.GetPosition();
128 
129   // set TimeChange equal to local time of the parent track
130   theTimeChange = theLocalTime0 = track.GetLocalTime();
131 
132   // set initial global time of the parent track
133   theGlobalTime0 = track.GetGlobalTime();
134 }
135 
136 // --------------------------------------------------------------------
137 G4Step* G4ParticleChange::UpdateStepForAlongStep(G4Step* pStep)
138 {
139   // A physics process always calculates the final state of the
140   // particle relative to the initial state at the beginning
141   // of the Step, i.e., based on information of G4Track (or
142   // equivalently the PreStepPoint).
143   // So, the differences (delta) between these two states have to be
144   // calculated and be accumulated in PostStepPoint
145 
146   // Take note that the return type of GetMomentumDirectionChange() is a
147   // pointer to G4ParticleMometum. Also it is a normalized
148   // momentum vector
149 
150   const G4StepPoint* pPreStepPoint = pStep->GetPreStepPoint();
151   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
152 
153   // set Mass/Charge/MagneticMoment
154   pPostStepPoint->SetMass(theMassChange);
155   pPostStepPoint->SetCharge(theChargeChange);
156   pPostStepPoint->SetMagneticMoment(theMagneticMomentChange);
157 
158   // calculate new kinetic energy
159   G4double preEnergy = pPreStepPoint->GetKineticEnergy();
160   G4double energy =
161     pPostStepPoint->GetKineticEnergy() + (theEnergyChange - preEnergy);
162 
163   // update kinetic energy and momentum direction
164   if(energy > 0.0)
165   {
166     // calculate new momentum
167     G4ThreeVector pMomentum = pPostStepPoint->GetMomentum()
168       + (CalcMomentum(theEnergyChange, theMomentumDirectionChange,
169           theMassChange) - pPreStepPoint->GetMomentum());
170     G4double tMomentum2 = pMomentum.mag2();
171     G4ThreeVector direction(1.0, 0.0, 0.0);
172     if(tMomentum2 > 0.)
173     {
174       direction = pMomentum / std::sqrt(tMomentum2);
175     }
176     pPostStepPoint->SetMomentumDirection(direction);
177     pPostStepPoint->SetKineticEnergy(energy);
178 
179     // if velocity is not set it should be recomputed
180     //  
181     if(!isVelocityChanged)
182     {
183       if (theMassChange > 0.0)
184       {
185   theVelocityChange = CLHEP::c_light *
186     std::sqrt(energy*(energy + 2*theMassChange))/(energy + theMassChange);
187       }
188       else 
189       {
190   // zero mass particle
191   theVelocityChange = CLHEP::c_light;
192   // optical photon case
193   if(theCurrentTrack->GetParticleDefinition()->GetPDGEncoding() == -22)
194   {
195           G4Track* pTrack = pStep->GetTrack();
196           G4double e = pTrack->GetKineticEnergy();
197     pTrack->SetKineticEnergy(energy);
198           theVelocityChange = pTrack->CalculateVelocityForOpticalPhoton();
199     pTrack->SetKineticEnergy(e);
200   }
201       }
202     }
203     pPostStepPoint->SetVelocity(theVelocityChange);
204   }
205   else
206   {
207     // stop case
208     pPostStepPoint->SetKineticEnergy(0.0);
209     pPostStepPoint->SetVelocity(0.0);
210   }
211 
212   // update polarization
213   pPostStepPoint->AddPolarization(thePolarizationChange -
214                                   pPreStepPoint->GetPolarization());
215 
216   // update position and time
217   pPostStepPoint->AddPosition(thePositionChange - pPreStepPoint->GetPosition());
218   pPostStepPoint->AddGlobalTime(theTimeChange - theLocalTime0);
219   pPostStepPoint->AddLocalTime(theTimeChange - theLocalTime0);
220   pPostStepPoint->AddProperTime(theProperTimeChange -
221                                 pPreStepPoint->GetProperTime());
222 
223   if(isParentWeightProposed)
224   {
225     pPostStepPoint->SetWeight(theParentWeight);
226   }
227 
228 #ifdef G4VERBOSE
229   if(debugFlag) { CheckIt( *theCurrentTrack ); }
230 #endif
231 
232   // update the G4Step specific attributes
233   return UpdateStepInfo(pStep);
234 }
235 
236 // --------------------------------------------------------------------
237 G4Step* G4ParticleChange::UpdateStepForPostStep(G4Step* pStep)
238 {
239   // A physics process always calculates the final state of the particle
240 
241   // Take note that the return type of GetMomentumChange() is a
242   // pointer to G4ParticleMometum. Also it is a normalized
243   // momentum vector
244 
245   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
246   G4Track* pTrack             = pStep->GetTrack();
247 
248   // set Mass/Charge
249   pPostStepPoint->SetMass(theMassChange);
250   pPostStepPoint->SetCharge(theChargeChange);
251   pPostStepPoint->SetMagneticMoment(theMagneticMomentChange);
252 
253   // update kinetic energy and momentum direction
254   pPostStepPoint->SetMomentumDirection(theMomentumDirectionChange);
255 
256   // calculate velocity
257   if(theEnergyChange > 0.0)
258   {
259     pPostStepPoint->SetKineticEnergy(theEnergyChange);
260     pTrack->SetKineticEnergy(theEnergyChange);
261     if(!isVelocityChanged)
262     {
263       theVelocityChange = pTrack->CalculateVelocity();
264     }
265     pPostStepPoint->SetVelocity(theVelocityChange);
266   }
267   else 
268   {
269     pPostStepPoint->SetKineticEnergy(0.0);
270     pPostStepPoint->SetVelocity(0.0);
271   }
272 
273   // update polarization
274   pPostStepPoint->SetPolarization(thePolarizationChange);
275 
276   // update position and time
277   pPostStepPoint->SetPosition(thePositionChange);
278   pPostStepPoint->AddGlobalTime(theTimeChange - theLocalTime0);
279   pPostStepPoint->SetLocalTime(theTimeChange);
280   pPostStepPoint->SetProperTime(theProperTimeChange);
281 
282   if(isParentWeightProposed)
283   {
284     pPostStepPoint->SetWeight(theParentWeight);
285   }
286 
287 #ifdef G4VERBOSE
288   if(debugFlag) { CheckIt( *theCurrentTrack ); }
289 #endif
290 
291   // update the G4Step specific attributes
292   return UpdateStepInfo(pStep);
293 }
294 
295 // --------------------------------------------------------------------
296 G4Step* G4ParticleChange::UpdateStepForAtRest(G4Step* pStep)
297 {
298   // A physics process always calculates the final state of the particle
299 
300   G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
301 
302   // set Mass/Charge
303   pPostStepPoint->SetMass(theMassChange);
304   pPostStepPoint->SetCharge(theChargeChange);
305   pPostStepPoint->SetMagneticMoment(theMagneticMomentChange);
306 
307   // update kinetic energy and momentum direction
308   pPostStepPoint->SetMomentumDirection(theMomentumDirectionChange);
309   pPostStepPoint->SetKineticEnergy(theEnergyChange);
310   if(!isVelocityChanged)
311     theVelocityChange = theCurrentTrack->CalculateVelocity();
312   pPostStepPoint->SetVelocity(theVelocityChange);
313 
314   // update polarization
315   pPostStepPoint->SetPolarization(thePolarizationChange);
316 
317   // update position and time
318   pPostStepPoint->SetPosition(thePositionChange);
319   pPostStepPoint->AddGlobalTime(theTimeChange - theLocalTime0);
320   pPostStepPoint->SetLocalTime(theTimeChange);
321   pPostStepPoint->SetProperTime(theProperTimeChange);
322 
323   if(isParentWeightProposed)
324   {
325     pPostStepPoint->SetWeight(theParentWeight);
326   }
327 
328 #ifdef G4VERBOSE
329   if(debugFlag) { CheckIt( *theCurrentTrack ); }
330 #endif
331 
332   // update the G4Step specific attributes
333   return UpdateStepInfo(pStep);
334 }
335 
336 // --------------------------------------------------------------------
337 void G4ParticleChange::DumpInfo() const
338 {
339   // use base-class DumpInfo
340   G4VParticleChange::DumpInfo();
341 
342   G4long oldprc = G4cout.precision(8);
343 
344   G4cout << "        Mass (GeV)          : " << std::setw(20) << theMassChange / GeV
345          << G4endl;
346   G4cout << "        Charge (eplus)      : " << std::setw(20)
347          << theChargeChange / eplus << G4endl;
348   G4cout << "        MagneticMoment      : " << std::setw(20)
349          << theMagneticMomentChange << G4endl;
350   G4cout << "                         =  : " << std::setw(20)
351          << theMagneticMomentChange
352             * 2. * theMassChange / c_squared / eplus / hbar_Planck
353          << "*[e hbar]/[2 m]" << G4endl;
354   G4cout << "        Position - x (mm)   : " << std::setw(20)
355          << thePositionChange.x() / mm << G4endl;
356   G4cout << "        Position - y (mm)   : " << std::setw(20)
357          << thePositionChange.y() / mm << G4endl;
358   G4cout << "        Position - z (mm)   : " << std::setw(20)
359          << thePositionChange.z() / mm << G4endl;
360   G4cout << "        Time (ns)           : " << std::setw(20)
361          << theTimeChange / ns << G4endl;
362   G4cout << "        Proper Time (ns)    : " << std::setw(20)
363          << theProperTimeChange / ns << G4endl;
364   G4cout << "        Momentum Direct - x : " << std::setw(20)
365          << theMomentumDirectionChange.x() << G4endl;
366   G4cout << "        Momentum Direct - y : " << std::setw(20)
367          << theMomentumDirectionChange.y() << G4endl;
368   G4cout << "        Momentum Direct - z : " << std::setw(20)
369          << theMomentumDirectionChange.z() << G4endl;
370   G4cout << "        Kinetic Energy (MeV): " << std::setw(20)
371          << theEnergyChange / MeV << G4endl;
372   G4cout << "        Velocity  (/c)      : " << std::setw(20)
373          << theVelocityChange / c_light << G4endl;
374   G4cout << "        Polarization - x    : " << std::setw(20)
375          << thePolarizationChange.x() << G4endl;
376   G4cout << "        Polarization - y    : " << std::setw(20)
377          << thePolarizationChange.y() << G4endl;
378   G4cout << "        Polarization - z    : " << std::setw(20)
379          << thePolarizationChange.z() << G4endl;
380   G4cout.precision(oldprc);
381 }
382