source: trunk/source/particles/management/src/G4DecayProducts.cc @ 1276

Last change on this file since 1276 was 1196, checked in by garnier, 15 years ago

update CVS release candidate geant4.9.3.01

File size: 10.6 KB
Line 
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: G4DecayProducts.cc,v 1.17 2009/04/02 02:24:53 kurasige Exp $
28// GEANT4 tag $Name: geant4-09-03-cand-01 $
29//
30//
31// ------------------------------------------------------------
32//      GEANT 4 class implementation file
33//
34//      History: first implementation, based on object model of
35//      10 July 1996 H.Kurashige
36//      21 Oct  1996 H.Kurashige
37//      12 Dec 1997 H.Kurashige
38// ------------------------------------------------------------
39
40#include "G4ios.hh"
41#include "globals.hh"
42#include "G4DecayProducts.hh"
43
44#include "G4LorentzVector.hh"
45#include "G4LorentzRotation.hh"
46
47G4Allocator<G4DecayProducts> aDecayProductsAllocator;
48
49
50G4DecayProducts::G4DecayProducts()
51                :numberOfProducts(0),theParentParticle(0)
52{ 
53
54}
55
56G4DecayProducts::G4DecayProducts(const G4DynamicParticle &aParticle)
57                :numberOfProducts(0),theParentParticle(0)
58{
59  theParentParticle = new G4DynamicParticle(aParticle);
60}
61
62G4DecayProducts::G4DecayProducts(const G4DecayProducts &right) 
63                :numberOfProducts(0)
64{
65  // copy parent (Deep Copy)
66  theParentParticle = new G4DynamicParticle(*right.theParentParticle);
67
68  //copy daughters (Deep Copy)
69  for (G4int index=0; index < right.numberOfProducts; index++)
70  {
71    G4DynamicParticle* daughter = right.theProductVector[index];
72    const G4DecayProducts* pPreAssigned = daughter->GetPreAssignedDecayProducts();
73    G4double properTime = daughter->GetPreAssignedDecayProperTime();
74    G4DynamicParticle* pDaughter =  new G4DynamicParticle(*daughter);
75
76    if (pPreAssigned) {
77      G4DecayProducts* pPA = new G4DecayProducts(*pPreAssigned);
78      pDaughter->SetPreAssignedDecayProducts(pPA);
79      if(properTime>0.0)
80      { pDaughter->SetPreAssignedDecayProperTime(properTime); }
81    }
82
83    PushProducts( pDaughter );
84  }
85}
86
87G4DecayProducts & G4DecayProducts::operator=(const G4DecayProducts &right)
88{
89  G4int index;
90
91  if (this != &right)
92  { 
93    // recreate parent
94    if (theParentParticle != 0) delete theParentParticle;
95    theParentParticle = new G4DynamicParticle(*right.theParentParticle);
96
97    // delete G4DynamicParticle objects
98    for (index=0; index < numberOfProducts; index++)
99    {
100      delete theProductVector[index];
101    }
102
103    //copy daughters (Deep Copy)
104    for (index=0; index < right.numberOfProducts; index++) {
105      PushProducts( new G4DynamicParticle(*right.theProductVector[index]) );
106    } 
107    numberOfProducts = right.numberOfProducts;
108   
109  }
110  return *this;
111}
112
113G4DecayProducts::~G4DecayProducts()
114{
115  //delete parent
116  if (theParentParticle != 0) delete theParentParticle;
117 
118  // delete G4DynamicParticle object
119  for (G4int index=0; index < numberOfProducts; index++)
120  {
121      delete theProductVector[index];
122  }
123  numberOfProducts = 0;   
124}
125
126G4DynamicParticle* G4DecayProducts::PopProducts()
127{
128   if ( numberOfProducts >0 ) {
129     numberOfProducts -= 1;   
130     return  theProductVector[numberOfProducts];
131   } else {
132     return 0;
133   }
134}
135
136G4int G4DecayProducts::PushProducts(G4DynamicParticle *aParticle)
137{
138   if ( numberOfProducts < MaxNumberOfProducts) {
139     theProductVector[numberOfProducts]= aParticle;
140     numberOfProducts += 1; 
141   } else {
142#ifdef G4VERBOSE
143     G4cout << "G4DecayProducts::PushProducts ";
144     G4cout << " exceeds MaxNumberOfProducts(="
145            << G4int(MaxNumberOfProducts) << ")";
146     G4cout << G4endl;
147#endif
148   }
149   return numberOfProducts;
150}
151
152G4DynamicParticle* G4DecayProducts::operator[](G4int anIndex) const
153{
154   if ((numberOfProducts > anIndex) && (anIndex >=0) ) {
155     return  theProductVector[anIndex];
156   } else {
157     return 0;
158   }
159}
160
161void  G4DecayProducts::SetParentParticle(const G4DynamicParticle &aParticle)
162{
163  if (theParentParticle != 0) delete theParentParticle;
164  theParentParticle = new G4DynamicParticle(aParticle);
165}
166
167
168void G4DecayProducts::Boost(G4double totalEnergy, const G4ThreeVector &momentumDirection)
169{
170  // calcurate new beta
171  G4double   mass = theParentParticle->GetMass();
172  G4double   totalMomentum(0);
173  if (totalEnergy > mass ) totalMomentum  = std::sqrt( (totalEnergy - mass)*(totalEnergy + mass) );
174  G4double   betax = momentumDirection.x()*totalMomentum/totalEnergy; 
175  G4double   betay = momentumDirection.y()*totalMomentum/totalEnergy; 
176  G4double   betaz = momentumDirection.z()*totalMomentum/totalEnergy; 
177  this->Boost(betax, betay, betaz);
178}
179
180void G4DecayProducts::Boost(G4double newbetax, G4double newbetay, G4double newbetaz)
181{ 
182  G4double   mass = theParentParticle->GetMass();
183  G4double   energy  = theParentParticle->GetTotalEnergy();
184  G4double   momentum  = 0.0;
185
186  G4ThreeVector direction(0.0,0.0,1.0);   
187  G4LorentzVector p4;
188
189  if (energy - mass > DBL_MIN) {
190    // calcurate  beta of initial state
191    momentum  = theParentParticle->GetTotalMomentum();
192    direction = theParentParticle->GetMomentumDirection();
193    G4double betax = -1.0*direction.x()*momentum/energy; 
194    G4double betay = -1.0*direction.y()*momentum/energy; 
195    G4double betaz = -1.0*direction.z()*momentum/energy; 
196   
197    for (G4int index=0; index < numberOfProducts; index++) {
198       // make G4LorentzVector for secondaries
199       p4 = theProductVector[index]->Get4Momentum();
200
201       // boost secondaries to theParentParticle's rest frame
202       p4.boost(betax, betay, betaz);
203
204       // boost secondaries to  new frame
205       p4.boost(newbetax, newbetay, newbetaz);
206
207       // change energy/momentum
208       theProductVector[index]->Set4Momentum(p4);
209     }
210   } else {
211     for (G4int index=0; index < numberOfProducts; index++) {
212       // make G4LorentzVector for secondaries
213       p4 = theProductVector[index]->Get4Momentum();
214
215       // boost secondaries to  new frame
216       p4.boost(newbetax, newbetay, newbetaz);
217
218       // change energy/momentum
219       theProductVector[index]->Set4Momentum(p4);
220      }
221   }
222   // make G4LorentzVector for parent in its rest frame
223   mass = theParentParticle->GetMass();
224   G4LorentzVector parent4( 0.0, 0.0, 0.0, mass);
225
226   // boost parent to new frame
227   parent4.boost(newbetax, newbetay, newbetaz);
228
229   // change energy/momentum
230   theParentParticle->Set4Momentum(parent4);
231}
232
233G4bool G4DecayProducts::IsChecked() const
234{
235  G4bool returnValue = true;
236  // check parent
237  //   energy/momentum
238  G4double   parent_energy  = theParentParticle->GetTotalEnergy();
239  G4ThreeVector direction = theParentParticle->GetMomentumDirection();
240  G4ThreeVector parent_momentum = direction*(theParentParticle->GetTotalMomentum());
241  // check momentum dirction is a unit vector
242  if ( (parent_momentum.mag() >0.0) && (std::fabs(direction.mag()-1.0) >1.0e-6 ) ) {
243#ifdef G4VERBOSE
244    G4cout << " Momentum Direction Vector of Parent is not normalized ";
245    G4cout << "  (=" << direction.mag() << ")" << G4endl;
246#endif
247    returnValue = false;
248    parent_momentum = parent_momentum * (1./direction.mag());
249  }
250
251  //daughters
252  G4double   mass, energy;
253  G4ThreeVector momentum;
254  G4double   total_energy = parent_energy;
255  G4ThreeVector total_momentum =  parent_momentum;
256  for (G4int index=0; index < numberOfProducts; index++) 
257  {
258    mass = theProductVector[index]->GetMass();
259    energy  = theProductVector[index]->GetTotalEnergy();
260    direction = theProductVector[index]->GetMomentumDirection();
261    momentum = direction*(theProductVector[index]->GetTotalMomentum());
262    // check momentum dirction is a unit vector
263    if ( (momentum.mag()>0.0) && (std::fabs(direction.mag()-1.0) > 1.0e-6)) {
264#ifdef G4VERBOSE
265      G4cout << " Momentum Direction Vector of Daughter [" << index;
266      G4cout << "]  is not normalized (=" << direction.mag() << ")" << G4endl;
267#endif
268      returnValue = false;
269      momentum = momentum * (1./direction.mag());
270    }
271    // whether daughter stops or not
272    if (energy - mass < DBL_MIN ) {
273#ifdef G4VERBOSE
274      G4cout << "Daughter [" << index << "] has no kinetic energy "<< G4endl;
275#endif
276      returnValue = false;
277    }
278    total_energy -= energy; 
279    total_momentum -= momentum;
280  }
281  // check energy/momentum conservation
282  if ( (std::fabs(total_energy) >1.0e-9*MeV) || (total_momentum.mag() >1.0e-9*MeV ) ){ 
283#ifdef G4VERBOSE
284    G4cout << " Energy/Momentum is not conserved   "<< G4endl;
285    G4cout << " difference between parent energy and sum of dughters' energy : " 
286           << total_energy /MeV << "[MeV]  " << G4endl; 
287    G4cout << " difference between parent momentum and sum of dughters' momentum : " 
288           << " x:" << total_momentum.getX()/MeV
289           << " y:" << total_momentum.getY()/MeV 
290           << " z:" << total_momentum.getZ()/MeV 
291           << G4endl;
292#endif
293    returnValue = false;
294  }
295  return returnValue;
296}
297
298void G4DecayProducts::DumpInfo() const
299{
300   G4cout << " ----- List of DecayProducts  -----" << G4endl;
301   G4cout << " ------ Parent Particle ----------" << G4endl;
302   if (theParentParticle != 0) theParentParticle->DumpInfo();
303   G4cout << " ------ Daughter Particles  ------" << G4endl; 
304   for (G4int index=0; index < numberOfProducts; index++) 
305   {
306      G4cout << " ----------" << index+1 << " -------------" << G4endl; 
307      theProductVector[index]-> DumpInfo();
308   }
309   G4cout << " ----- End List of DecayProducts  -----" << G4endl;
310   G4cout << G4endl;
311} 
Note: See TracBrowser for help on using the repository browser.