G4KineticTrack.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // -----------------------------------------------------------------------------
00028 //      GEANT 4 class implementation file
00029 //
00030 //      History: first implementation, A. Feliciello, 20th May 1998
00031 // -----------------------------------------------------------------------------
00032 
00033 #include "globals.hh"
00034 #include "G4ios.hh"
00035 #include <cmath>
00036 
00037 #include "Randomize.hh"
00038 #include "G4SimpleIntegration.hh"
00039 #include "G4ThreeVector.hh"
00040 #include "G4LorentzVector.hh"
00041 #include "G4KineticTrack.hh"
00042 #include "G4KineticTrackVector.hh"
00043 #include "G4ParticleDefinition.hh"
00044 #include "G4DecayTable.hh"
00045 #include "G4GeneralPhaseSpaceDecay.hh"
00046 #include "G4DecayProducts.hh"
00047 #include "G4LorentzRotation.hh"
00048 #include "G4SampleResonance.hh"
00049 #include "G4Integrator.hh"
00050 #include "G4KaonZero.hh"
00051 #include "G4KaonZeroShort.hh"
00052 #include "G4KaonZeroLong.hh"
00053 #include "G4AntiKaonZero.hh"
00054 
00055 #include "G4HadTmpUtil.hh"
00056 
00057 //
00058 // Some static clobal for integration
00059 //
00060 
00061 static G4double  G4KineticTrack_Gmass, G4KineticTrack_xmass1;
00062 
00063 //
00064 //   Default constructor
00065 //
00066 
00067 G4KineticTrack::G4KineticTrack() :
00068                 theDefinition(0),
00069                 theFormationTime(0),
00070                 thePosition(0),
00071                 the4Momentum(0),
00072                 theFermi3Momentum(0),
00073                 theTotal4Momentum(0),
00074                 theNucleon(0),
00075                 nChannels(0),
00076                 theActualMass(0),            
00077                 theActualWidth(0),            
00078                 theDaughterMass(0),
00079                 theDaughterWidth(0),
00080                 theStateToNucleus(undefined),
00081                 theProjectilePotential(0)
00082 {
00084 //    DEBUG   //
00086 
00087 /*
00088  G4cerr << G4endl << G4endl << G4endl;
00089  G4cerr << "   G4KineticTrack default constructor invoked! \n";
00090  G4cerr << "   =========================================== \n" << G4endl;
00091 */
00092 }
00093 
00094 
00095 
00096 //
00097 //   Copy constructor
00098 //
00099 
00100 G4KineticTrack::G4KineticTrack(const G4KineticTrack &right) : G4VKineticNucleon()
00101 {
00102  G4int i;
00103  theDefinition = right.GetDefinition();
00104  theFormationTime = right.GetFormationTime();
00105  thePosition = right.GetPosition();
00106  the4Momentum = right.GetTrackingMomentum();
00107  theFermi3Momentum = right.theFermi3Momentum;
00108  theTotal4Momentum = right.theTotal4Momentum;
00109  theNucleon=right.theNucleon;
00110  nChannels = right.GetnChannels();
00111  theActualMass = right.GetActualMass();
00112  theActualWidth = new G4double[nChannels];
00113  for (i = 0; i < nChannels; i++)
00114   {
00115     theActualWidth[i] = right.theActualWidth[i];
00116   }
00117   theDaughterMass = 0;
00118   theDaughterWidth = 0;
00119   theStateToNucleus=right.theStateToNucleus;
00120   theProjectilePotential=right.theProjectilePotential;
00121  
00123 //    DEBUG   //
00125 
00126 /*
00127  G4cerr << G4endl << G4endl << G4endl;
00128  G4cerr << "   G4KineticTrack copy constructor invoked! \n";
00129  G4cerr << "   ======================================== \n" <<G4endl;
00130 */
00131 }
00132 
00133 
00134 //
00135 //   By argument constructor
00136 //
00137 
00138 G4KineticTrack::G4KineticTrack(G4ParticleDefinition* aDefinition,
00139                                G4double aFormationTime,
00140                                G4ThreeVector aPosition,
00141                                G4LorentzVector& a4Momentum) :
00142                 theDefinition(aDefinition),
00143                 theFormationTime(aFormationTime),
00144                 thePosition(aPosition),
00145                 the4Momentum(a4Momentum),
00146                 theFermi3Momentum(0),
00147                 theTotal4Momentum(a4Momentum),
00148                 theNucleon(0),
00149                 theStateToNucleus(undefined),
00150                 theProjectilePotential(0)
00151 {
00152   if(G4KaonZero::KaonZero() == theDefinition ||
00153     G4AntiKaonZero::AntiKaonZero() == theDefinition)
00154   {
00155     if(G4UniformRand()<0.5)
00156     {
00157       theDefinition = G4KaonZeroShort::KaonZeroShort();
00158     }
00159     else
00160     {
00161       theDefinition = G4KaonZeroLong::KaonZeroLong();
00162     }
00163   }
00164 
00165 //
00166 //      Get the number of decay channels
00167 //
00168 
00169  G4DecayTable* theDecayTable = theDefinition->GetDecayTable();
00170  if (theDecayTable != 0)
00171     {
00172      nChannels = theDecayTable->entries();
00173 
00174     }
00175  else
00176     {
00177      nChannels = 0;
00178     }  
00179 
00180 //
00181 //   Get the actual mass value
00182 //
00183 
00184  theActualMass = GetActualMass();
00185 
00186 //
00187 //   Create an array to Store the actual partial widths 
00188 //   of the decay channels
00189 //
00190 
00191   theDaughterMass = 0;
00192   theDaughterWidth = 0;
00193   theActualWidth = 0;
00194   G4bool * theDaughterIsShortLived = 0;
00195   
00196   if(nChannels!=0) theActualWidth = new G4double[nChannels];
00197 
00198   //  cout << " ****CONSTR*** ActualMass ******* " << theActualMass << G4endl;
00199   G4int index;
00200   for (index = nChannels - 1; index >= 0; index--)
00201     {
00202       G4VDecayChannel* theChannel = theDecayTable->GetDecayChannel(index);
00203       G4int nDaughters = theChannel->GetNumberOfDaughters();
00204       G4double theMotherWidth;
00205       if (nDaughters == 2 || nDaughters == 3) 
00206         {
00207           G4double thePoleMass  = theDefinition->GetPDGMass();
00208           theMotherWidth = theDefinition->GetPDGWidth();
00209           G4double thePoleWidth = theChannel->GetBR()*theMotherWidth;
00210           G4ParticleDefinition* aDaughter;
00211           theDaughterMass = new G4double[nDaughters];
00212           theDaughterWidth = new G4double[nDaughters];
00213           theDaughterIsShortLived = new G4bool[nDaughters];
00214           G4int n;
00215           for (n = 0; n < nDaughters; n++)
00216             {
00217               aDaughter = theChannel->GetDaughter(n);
00218               theDaughterMass[n] = aDaughter->GetPDGMass();
00219               theDaughterWidth[n] = aDaughter->GetPDGWidth();
00220               theDaughterIsShortLived[n] = aDaughter->IsShortLived();
00221             }     
00222           
00223 //
00224 //           Check whether both the decay products are stable
00225 //
00226 
00227           G4double theActualMom = 0.0;
00228           G4double thePoleMom = 0.0;
00229           G4SampleResonance aSampler;
00230           if (nDaughters==2) 
00231             {
00232               if ( !theDaughterIsShortLived[0] && !theDaughterIsShortLived[1] )
00233                 {
00234                   
00235                   //              G4cout << G4endl << "Both the " << nDaughters <<
00236                   //                              " decay products are stable!";
00237                   //                   cout << " LB: Both decay products STABLE !" << G4endl;
00238                   //                   cout << " parent:     " << theChannel->GetParentName() << G4endl;
00239                   //                   cout << " particle1:  " << theChannel->GetDaughterName(0) << G4endl;
00240                   //                   cout << " particle2:  " << theChannel->GetDaughterName(1) << G4endl;
00241                   
00242                   theActualMom = EvaluateCMMomentum(theActualMass, 
00243                                                     theDaughterMass);   
00244                   thePoleMom = EvaluateCMMomentum(thePoleMass, 
00245                                                   theDaughterMass);
00246                   //          cout << G4endl;
00247                   //          cout << " LB: ActualMass/DaughterMass  " << theActualMass << "   " << theDaughterMass << G4endl; 
00248                   //          cout << " LB: ActualMom " << theActualMom << G4endl;
00249                   //          cout << " LB: PoleMom   " << thePoleMom << G4endl;
00250                   //          cout << G4endl;
00251                 }
00252               else if ( !theDaughterIsShortLived[0] && theDaughterIsShortLived[1] )   
00253                 {
00254                   
00255                   //              G4cout << G4endl << "Only the first of the " << nDaughters <<" decay products is stable!";
00256                   //           cout << " LB: only the first decay product is STABLE !" << G4endl;
00257                   //           cout << " parent:     " << theChannel->GetParentName() << G4endl;
00258                   //           cout << " particle1:  " << theChannel->GetDaughterName(0) << G4endl;
00259                   //           cout << " particle2:  " << theChannel->GetDaughterName(1) << G4endl;
00260                   
00261 // global variable definition
00262                   G4double lowerLimit = aSampler.GetMinimumMass(theChannel->GetDaughter(1));
00263                   theActualMom = IntegrateCMMomentum(lowerLimit);
00264                   thePoleMom = IntegrateCMMomentum(lowerLimit, thePoleMass);
00265                   //          cout << " LB Parent Mass = " <<  G4KineticTrack_Gmass << G4endl;
00266                   //          cout << " LB Actual Mass = " << theActualMass << G4endl;
00267                   //          cout << " LB Daughter1 Mass = " <<  G4KineticTrack_Gmass1 << G4endl;
00268                   //          cout << " LB Daughter2 Mass = " <<  G4KineticTrack_Gmass2 << G4endl;
00269                   //          cout << " The Actual Momentum = " << theActualMom << G4endl;
00270                   //          cout << " The Pole Momentum   = " << thePoleMom << G4endl;
00271                   //          cout << G4endl;
00272                   
00273                 }        
00274               else if ( theDaughterIsShortLived[0] && !theDaughterIsShortLived[1] )   
00275                 {
00276                   
00277                   //              G4cout << G4endl << "Only the second of the " << nDaughters <<
00278                   //                              " decay products is stable!";
00279                   //                   cout << " LB: only the second decay product is STABLE !" << G4endl;
00280                   //           cout << " parent:     " << theChannel->GetParentName() << G4endl;
00281                   //           cout << " particle1:  " << theChannel->GetDaughterName(0) << G4endl;
00282                   //           cout << " particle2:  " << theChannel->GetDaughterName(1) << G4endl;
00283                   
00284 //
00285 //               Swap the content of the theDaughterMass and theDaughterWidth arrays!!!
00286 //
00287                   
00288                   G4SwapObj(theDaughterMass, theDaughterMass + 1);
00289                   G4SwapObj(theDaughterWidth, theDaughterWidth + 1);
00290                   
00291 // global variable definition
00292                   G4double lowerLimit = aSampler.GetMinimumMass(theChannel->GetDaughter(0));
00293                   theActualMom = IntegrateCMMomentum(lowerLimit);
00294                   thePoleMom = IntegrateCMMomentum(lowerLimit, thePoleMass);
00295                   //          cout << " LB Parent Mass = " <<  G4KineticTrack_Gmass << G4endl;
00296                   //          cout << " LB Actual Mass = " << theActualMass << G4endl;
00297                   //          cout << " LB Daughter1 Mass = " <<  G4KineticTrack_Gmass1 << G4endl;
00298                   //          cout << " LB Daughter2 Mass = " <<  G4KineticTrack_Gmass2 << G4endl;
00299                   //          cout << " The Actual Momentum = " << theActualMom << G4endl;
00300                   //          cout << " The Pole Momentum   = " << thePoleMom << G4endl;
00301                   //              cout << G4endl;
00302                   
00303                 }        
00304               else if ( theDaughterIsShortLived[0] && theDaughterIsShortLived[1] )   
00305                 {
00306                
00307 //              G4cout << G4endl << "Both the " << nDaughters <<
00308 //                              " decay products are resonances!";
00309                   //           cout << " LB: both decay products are RESONANCES !" << G4endl;
00310                   //           cout << " parent:     " << theChannel->GetParentName() << G4endl;
00311                   //           cout << " particle1:  " << theChannel->GetDaughterName(0) << G4endl;
00312                   //           cout << " particle2:  " << theChannel->GetDaughterName(1) << G4endl;
00313                   
00314 // global variable definition
00315                   G4KineticTrack_Gmass = theActualMass;
00316                   theActualMom = IntegrateCMMomentum2();
00317                   G4KineticTrack_Gmass = thePoleMass;
00318                   thePoleMom = IntegrateCMMomentum2();
00319                   //          cout << " LB Parent Mass = " <<  G4KineticTrack_Gmass << G4endl;
00320                   //          cout << " LB Daughter1 Mass = " <<  G4KineticTrack_Gmass1 << G4endl;
00321                   //          cout << " LB Daughter2 Mass = " <<  G4KineticTrack_Gmass2 << G4endl;
00322                   //              cout << " The Actual Momentum = " << theActualMom << G4endl;
00323                   //              cout << " The Pole Momentum   = " << thePoleMom << G4endl;
00324                   //              cout << G4endl;
00325                   
00326                 }        
00327             } 
00328           else  // (nDaughter==3)
00329             {
00330               
00331               int nShortLived = 0;
00332               if ( theDaughterIsShortLived[0] ) 
00333                 { 
00334                   nShortLived++; 
00335                 }
00336               if ( theDaughterIsShortLived[1] )
00337                 { 
00338                   nShortLived++; 
00339                   G4SwapObj(theDaughterMass, theDaughterMass + 1);
00340                   G4SwapObj(theDaughterWidth, theDaughterWidth + 1);        
00341                 }
00342               if ( theDaughterIsShortLived[2] )
00343                 { 
00344                   nShortLived++; 
00345                   G4SwapObj(theDaughterMass, theDaughterMass + 2);
00346                   G4SwapObj(theDaughterWidth, theDaughterWidth + 2);        
00347                 }
00348               if ( nShortLived == 0 ) 
00349                 {
00350                   theDaughterMass[1]+=theDaughterMass[2];
00351                   theActualMom = EvaluateCMMomentum(theActualMass, 
00352                                                     theDaughterMass);   
00353                   thePoleMom = EvaluateCMMomentum(thePoleMass, 
00354                                                   theDaughterMass);
00355                 }
00356 //            else if ( nShortLived == 1 )
00357               else if ( nShortLived >= 1 )
00358                 { 
00359                   // need the shortlived particle in slot 1! (very bad style...)
00360                   G4SwapObj(theDaughterMass, theDaughterMass + 1);
00361                   G4SwapObj(theDaughterWidth, theDaughterWidth + 1);        
00362                   theDaughterMass[0] += theDaughterMass[2];
00363                   theActualMom = IntegrateCMMomentum(0.0);
00364                   thePoleMom = IntegrateCMMomentum(0.0, thePoleMass);
00365                 }
00366 //            else
00367 //              {
00368 //                throw G4HadronicException(__FILE__, __LINE__,  ("can't handle more than one shortlived in 3 particle output channel");
00369 //              }     
00370               
00371             }
00372           
00373           G4double l=0;
00374           //if(nDaughters<3) theChannel->GetAngularMomentum(); 
00375           G4double theMassRatio = thePoleMass / theActualMass;
00376           G4double theMomRatio = theActualMom / thePoleMom;
00377           theActualWidth[index] = thePoleWidth * theMassRatio *
00378                                   std::pow(theMomRatio, (2 * l + 1)) *
00379                                   (1.2 / (1+ 0.2*std::pow(theMomRatio, (2 * l))));
00380           delete [] theDaughterMass;
00381           theDaughterMass = 0;
00382           delete [] theDaughterWidth;
00383           theDaughterWidth = 0;
00384           delete [] theDaughterIsShortLived;
00385           theDaughterIsShortLived = 0;
00386         }
00387       
00388       else //  nDaughter = 1 ( e.g. K0  decays 50% to Kshort, 50% Klong 
00389         {
00390           theMotherWidth = theDefinition->GetPDGWidth();
00391           theActualWidth[index] = theChannel->GetBR()*theMotherWidth;
00392         }
00393     }
00394 
00396 //    DEBUG   //
00398 
00399 // for (G4int y = nChannels - 1; y >= 0; y--)
00400 //     {
00401 //      G4cout << G4endl << theActualWidth[y];
00402 //     }
00403 // G4cout << G4endl << G4endl << G4endl;
00404 
00405  /*
00406  G4cerr << G4endl << G4endl << G4endl;
00407  G4cerr << "   G4KineticTrack by argument constructor invoked! \n";
00408  G4cerr << "   =============================================== \n" << G4endl;
00409  */
00410 
00411 }
00412 
00413 G4KineticTrack::G4KineticTrack(G4Nucleon * nucleon,
00414                                 G4ThreeVector aPosition,
00415                                 G4LorentzVector& a4Momentum)
00416   :     theDefinition(nucleon->GetDefinition()),
00417         theFormationTime(0),
00418         thePosition(aPosition),
00419         the4Momentum(a4Momentum),
00420         theFermi3Momentum(nucleon->GetMomentum()),
00421         theNucleon(nucleon),
00422         nChannels(0),
00423         theActualMass(nucleon->GetDefinition()->GetPDGMass()),
00424         theActualWidth(0),
00425         theDaughterMass(0),
00426         theDaughterWidth(0),
00427         theStateToNucleus(undefined),
00428         theProjectilePotential(0)
00429 {
00430         theFermi3Momentum.setE(0);
00431         Set4Momentum(a4Momentum);
00432 }
00433 
00434 
00435 G4KineticTrack::~G4KineticTrack()
00436 {
00437  if (theActualWidth != 0) delete [] theActualWidth;
00438  if (theDaughterMass != 0) delete [] theDaughterMass;
00439  if (theDaughterWidth != 0) delete [] theDaughterWidth;
00440 }
00441 
00442 
00443 
00444 G4KineticTrack& G4KineticTrack::operator=(const G4KineticTrack& right)
00445 {
00446  if (this != &right)
00447     {
00448      theDefinition = right.GetDefinition();
00449      theFormationTime = right.GetFormationTime();
00450      the4Momentum = right.the4Momentum;  
00451      the4Momentum = right.GetTrackingMomentum();
00452      theFermi3Momentum = right.theFermi3Momentum;
00453      theTotal4Momentum = right.theTotal4Momentum;
00454      theNucleon=right.theNucleon;
00455      theStateToNucleus=right.theStateToNucleus;
00456      if (theActualWidth != 0) delete [] theActualWidth;
00457      nChannels = right.GetnChannels();      
00458      theActualWidth = new G4double[nChannels];
00459      for ( G4int i = 0; i < nChannels; i++)
00460         {
00461          theActualWidth[i] = right.theActualWidth[i];
00462         }
00463     }
00464  return *this;
00465 }
00466 
00467 
00468 
00469 G4int G4KineticTrack::operator==(const G4KineticTrack& right) const
00470 {
00471  return (this == & right);
00472 }
00473 
00474 
00475 
00476 G4int G4KineticTrack::operator!=(const G4KineticTrack& right) const
00477 {
00478  return (this != & right);
00479 }
00480 
00481 
00482 
00483 G4KineticTrackVector* G4KineticTrack::Decay()
00484 {
00485 //
00486 //   Select a possible decay channel
00487 //
00488 /*
00489     G4int index1;
00490     for (index1 = nChannels - 1; index1 >= 0; index1--)
00491       G4cout << "DECAY Actual Width IND/ActualW " << index1 << "  " << theActualWidth[index1] << G4endl;
00492       G4cout << "DECAY Actual Mass " << theActualMass << G4endl;
00493 */
00494   G4ParticleDefinition* thisDefinition = this->GetDefinition();
00495   if(!thisDefinition)
00496   {
00497     G4cerr << "Error condition encountered in G4KineticTrack::Decay()"<<G4endl;
00498     G4cerr << "  track has no particle definition associated."<<G4endl;
00499     return 0;
00500   }
00501   G4DecayTable* theDecayTable = thisDefinition->GetDecayTable();
00502   if(!theDecayTable)
00503   {
00504     G4cerr << "Error condition encountered in G4KineticTrack::Decay()"<<G4endl;
00505     G4cerr << "  particle definiton has no decay table associated."<<G4endl;
00506     G4cerr << "  particle was "<<thisDefinition->GetParticleName()<<G4endl;
00507     return 0;
00508   }
00509  
00510  G4int chargeBalance = G4lrint(theDefinition->GetPDGCharge() );     
00511  G4int baryonBalance = G4lrint(theDefinition->GetBaryonNumber() );
00512  G4LorentzVector energyMomentumBalance(Get4Momentum());
00513  G4double theTotalActualWidth = this->EvaluateTotalActualWidth();
00514  if (theTotalActualWidth !=0)
00515     {
00516      G4int index;
00517      G4double theSumActualWidth = 0.0;
00518      G4double* theCumActualWidth = new G4double[nChannels];
00519      for (index = nChannels - 1; index >= 0; index--)
00520         {
00521          theSumActualWidth += theActualWidth[index];
00522          theCumActualWidth[index] = theSumActualWidth;
00523          //      cout << "DECAY Cum. Width " << index << "  " << theCumActualWidth[index] << G4endl;
00524         }
00525      //  cout << "DECAY Total Width " << theSumActualWidth << G4endl;
00526      //  cout << "DECAY Total Width " << theTotalActualWidth << G4endl;
00527      G4double r = theTotalActualWidth * G4UniformRand();
00528      G4VDecayChannel* theDecayChannel(0);
00529      G4int chosench=-1;
00530      for (index = nChannels - 1; index >= 0; index--)
00531         {
00532          if (r < theCumActualWidth[index])
00533             {
00534              theDecayChannel = theDecayTable->GetDecayChannel(index);
00535              //      cout << "DECAY SELECTED CHANNEL" << index << G4endl;
00536              chosench=index;
00537              break; 
00538             }
00539         }
00540 
00541      delete [] theCumActualWidth;
00542    
00543      if(!theDecayChannel)
00544      {
00545        G4cerr << "Error condition encountered in G4KineticTrack::Decay()"<<G4endl;
00546        G4cerr << "  decay channel has 0x0 channel associated."<<G4endl;
00547        G4cerr << "  particle was "<<thisDefinition->GetParticleName()<<G4endl;
00548        G4cerr << "  channel index "<< chosench << "of "<<nChannels<<"channels"<<G4endl;
00549        return 0;
00550      }
00551      G4String theParentName = theDecayChannel->GetParentName();
00552      G4double theParentMass = this->GetActualMass();
00553      G4double theBR = theActualWidth[index];
00554      //     cout << "**BR*** DECAYNEW  " << theBR << G4endl;
00555      G4int theNumberOfDaughters = theDecayChannel->GetNumberOfDaughters();
00556      G4String theDaughtersName1 = "";
00557      G4String theDaughtersName2 = "";
00558      G4String theDaughtersName3 = "";
00559      
00560      G4double masses[3]={0.,0.,0.};
00561      G4int shortlivedDaughters[3];
00562      G4int numberOfShortliveds(0);
00563      G4double SumLongLivedMass(0);
00564      for (G4int aD=0; aD < theNumberOfDaughters ; aD++)
00565      {
00566         G4ParticleDefinition* aDaughter = theDecayChannel->GetDaughter(aD);
00567         masses[aD] = aDaughter->GetPDGMass();
00568         if ( aDaughter->IsShortLived() ) 
00569         {
00570             shortlivedDaughters[numberOfShortliveds]=aD;
00571             numberOfShortliveds++;
00572         } else {
00573             SumLongLivedMass += aDaughter->GetPDGMass();
00574         }
00575                 
00576      }    
00577      switch (theNumberOfDaughters)
00578         {
00579          case 0:
00580             break;
00581          case 1:
00582             theDaughtersName1 = theDecayChannel->GetDaughterName(0);
00583             theDaughtersName2 = "";
00584             theDaughtersName3 = "";
00585             break;
00586          case 2:    
00587             theDaughtersName1 = theDecayChannel->GetDaughterName(0);        
00588             theDaughtersName2 = theDecayChannel->GetDaughterName(1);
00589             theDaughtersName3 = "";
00590             if (  numberOfShortliveds == 1) 
00591             {   G4SampleResonance aSampler;
00592                 G4double massmax=theParentMass - SumLongLivedMass;
00593                 G4ParticleDefinition * aDaughter=theDecayChannel->GetDaughter(shortlivedDaughters[0]);      
00594                 masses[shortlivedDaughters[0]]= aSampler.SampleMass(aDaughter,massmax);
00595             } else if (  numberOfShortliveds == 2) {
00596                 // choose masses one after the other, start with randomly choosen
00597                 G4int zero= (G4UniformRand() > 0.5) ? 0 : 1;
00598                 G4int one = 1-zero;
00599                 G4SampleResonance aSampler;
00600                 G4double massmax=theParentMass - aSampler.GetMinimumMass(theDecayChannel->GetDaughter(shortlivedDaughters[one]));
00601                 G4ParticleDefinition * aDaughter=theDecayChannel->GetDaughter(shortlivedDaughters[zero]);           
00602                 masses[shortlivedDaughters[zero]]=aSampler.SampleMass(aDaughter,massmax);
00603                 massmax=theParentMass - masses[shortlivedDaughters[zero]];
00604                 aDaughter=theDecayChannel->GetDaughter(shortlivedDaughters[one]);
00605                 masses[shortlivedDaughters[one]]=aSampler.SampleMass(aDaughter,massmax);
00606             }
00607             break;              
00608          default:    
00609             theDaughtersName1 = theDecayChannel->GetDaughterName(0);
00610             theDaughtersName2 = theDecayChannel->GetDaughterName(1);
00611             theDaughtersName3 = theDecayChannel->GetDaughterName(2);
00612             if (  numberOfShortliveds == 1) 
00613             {   G4SampleResonance aSampler;
00614                 G4double massmax=theParentMass - SumLongLivedMass;
00615                 G4ParticleDefinition * aDaughter=theDecayChannel->GetDaughter(shortlivedDaughters[0]);      
00616                 masses[shortlivedDaughters[0]]= aSampler.SampleMass(aDaughter,massmax);
00617             }
00618             break;
00619         }
00620 
00621 //      
00622 //      Get the decay products List
00623 //
00624      
00625      G4GeneralPhaseSpaceDecay thePhaseSpaceDecayChannel(theParentName,
00626                                                         theParentMass,
00627                                                         theBR,
00628                                                         theNumberOfDaughters,
00629                                                         theDaughtersName1,                  
00630                                                         theDaughtersName2,
00631                                                         theDaughtersName3,
00632                                                         masses);
00633      G4DecayProducts* theDecayProducts = thePhaseSpaceDecayChannel.DecayIt();
00634      if(!theDecayProducts)
00635      {
00636        G4cerr << "Error condition encountered in G4KineticTrack::Decay()"<<G4endl;
00637        G4cerr << "  phase-space decay failed."<<G4endl;
00638        G4cerr << "  particle was "<<thisDefinition->GetParticleName()<<G4endl;
00639        G4cerr << "  channel index "<< chosench << "of "<<nChannels<<"channels"<<G4endl;
00640        G4cerr << "  "<<theNumberOfDaughters<< " Daughter particles: "
00641               << theDaughtersName1<<" "<<theDaughtersName2<<" "<<theDaughtersName3<<G4endl;
00642        return 0;
00643      }
00644                                                         
00645 //
00646 //      Create the kinetic track List associated to the decay products
00647 //
00648      G4LorentzRotation toMoving(Get4Momentum().boostVector());
00649      G4DynamicParticle* theDynamicParticle;
00650      G4double formationTime = 0.0;
00651      G4ThreeVector position = this->GetPosition();
00652      G4LorentzVector momentum;
00653      G4LorentzVector momentumBalanceCMS(0);
00654      G4KineticTrackVector* theDecayProductList = new G4KineticTrackVector;
00655      G4int dEntries = theDecayProducts->entries();
00656      G4ParticleDefinition * aProduct = 0;
00657      for (G4int i=dEntries; i > 0; i--)
00658         {
00659          theDynamicParticle = theDecayProducts->PopProducts();
00660          aProduct = theDynamicParticle->GetDefinition();
00661          chargeBalance -= G4lrint(aProduct->GetPDGCharge() );
00662          baryonBalance -= G4lrint(aProduct->GetBaryonNumber() );
00663          momentumBalanceCMS += theDynamicParticle->Get4Momentum();
00664          momentum = toMoving*theDynamicParticle->Get4Momentum();
00665          energyMomentumBalance -= momentum;
00666          theDecayProductList->push_back(new G4KineticTrack (aProduct,
00667                                                          formationTime,
00668                                                          position,
00669                                                          momentum));
00670          delete theDynamicParticle;
00671         }
00672      delete theDecayProducts;
00673      if(getenv("DecayEnergyBalanceCheck"))
00674        std::cout << "DEBUGGING energy balance in cms and lab, charge baryon balance : "
00675                  << momentumBalanceCMS << " " 
00676                  <<energyMomentumBalance << " " 
00677                  <<chargeBalance<<" "
00678                  <<baryonBalance<<" "
00679                  <<G4endl;
00680      return theDecayProductList;
00681     }
00682  else
00683     {
00684      return 0;
00685     }
00686 }
00687 
00688 G4double G4KineticTrack::IntegrandFunction1(G4double xmass) const 
00689 {
00690   G4double mass = theActualMass;   /* the actual mass value */
00691   G4double mass1 = theDaughterMass[0];
00692   G4double mass2 = theDaughterMass[1];
00693   G4double gamma2 = theDaughterWidth[1];
00694   
00695   G4double result = (1. / (2 * mass)) *
00696     std::sqrt(std::max((((mass * mass) - (mass1 + xmass) * (mass1 + xmass)) *
00697              ((mass * mass) - (mass1 - xmass) * (mass1 - xmass))),0.0)) *
00698     BrWig(gamma2, mass2, xmass);
00699   return result;
00700 }
00701 
00702 G4double G4KineticTrack::IntegrandFunction2(G4double xmass) const
00703 {
00704   G4double mass = theDefinition->GetPDGMass();   /* the pole mass value */
00705   G4double mass1 = theDaughterMass[0];
00706   G4double mass2 = theDaughterMass[1];
00707   G4double gamma2 = theDaughterWidth[1];
00708   G4double result = (1. / (2 * mass)) *
00709     std::sqrt(std::max((((mass * mass) - (mass1 + xmass) * (mass1 + xmass)) *
00710              ((mass * mass) - (mass1 - xmass) * (mass1 - xmass))),0.0)) *
00711     BrWig(gamma2, mass2, xmass);
00712  return result;
00713 }
00714 
00715 G4double G4KineticTrack::IntegrandFunction3(G4double xmass) const
00716 {
00717   const G4double mass =  G4KineticTrack_Gmass;   /* the actual mass value */
00718 //  const G4double mass1 = theDaughterMass[0];
00719   const G4double mass2 = theDaughterMass[1];
00720   const G4double gamma2 = theDaughterWidth[1];
00721 
00722   const G4double result = (1. / (2 * mass)) *
00723     std::sqrt(((mass * mass) - (G4KineticTrack_xmass1 + xmass) * (G4KineticTrack_xmass1 + xmass)) *
00724          ((mass * mass) - (G4KineticTrack_xmass1 - xmass) * (G4KineticTrack_xmass1 - xmass))) *
00725     BrWig(gamma2, mass2, xmass);
00726   return result;
00727 }
00728 
00729 G4double G4KineticTrack::IntegrandFunction4(G4double xmass) const
00730 {
00731   const G4double mass =  G4KineticTrack_Gmass;
00732   const G4double mass1 = theDaughterMass[0];
00733   const G4double gamma1 = theDaughterWidth[0];
00734 //  const G4double mass2 = theDaughterMass[1];
00735   
00736   G4KineticTrack_xmass1 = xmass;
00737   
00738   const G4double theLowerLimit = 0.0;
00739   const G4double theUpperLimit = mass - xmass;
00740   const G4int nIterations = 100;
00741   
00742   G4Integrator<const G4KineticTrack, G4double(G4KineticTrack::*)(G4double) const> integral;
00743   G4double result = BrWig(gamma1, mass1, xmass)*
00744     integral.Simpson(this, &G4KineticTrack::IntegrandFunction3, theLowerLimit, theUpperLimit, nIterations);
00745 
00746   return result;
00747 }
00748 
00749 G4double G4KineticTrack::IntegrateCMMomentum(const G4double theLowerLimit) const
00750 {
00751   const G4double theUpperLimit = theActualMass - theDaughterMass[0];
00752   const G4int nIterations = 100;
00753  
00754   if (theLowerLimit>=theUpperLimit) return 0.0;
00755 
00756   G4Integrator<const G4KineticTrack, G4double(G4KineticTrack::*)(G4double) const> integral;
00757   G4double theIntegralOverMass2 = integral.Simpson(this, &G4KineticTrack::IntegrandFunction1, 
00758                                                    theLowerLimit, theUpperLimit, nIterations);
00759   return theIntegralOverMass2;
00760 }
00761 
00762 G4double G4KineticTrack::IntegrateCMMomentum(const G4double theLowerLimit, const G4double poleMass) const
00763 {
00764   const G4double theUpperLimit = poleMass - theDaughterMass[0];
00765   const G4int nIterations = 100;
00766   
00767   if (theLowerLimit>=theUpperLimit) return 0.0;
00768 
00769   G4Integrator<const G4KineticTrack, G4double(G4KineticTrack::*)(G4double) const> integral;
00770   const G4double theIntegralOverMass2 = integral.Simpson(this, &G4KineticTrack::IntegrandFunction2,
00771                                                     theLowerLimit, theUpperLimit, nIterations);
00772   return theIntegralOverMass2;
00773 }
00774 
00775 
00776 G4double G4KineticTrack::IntegrateCMMomentum2() const
00777 {
00778   const G4double theLowerLimit = 0.0;
00779   const G4double theUpperLimit = theActualMass;
00780   const G4int nIterations = 100;
00781   
00782   if (theLowerLimit>=theUpperLimit) return 0.0;
00783   
00784   G4Integrator<const G4KineticTrack, G4double(G4KineticTrack::*)(G4double) const> integral;
00785   G4double theIntegralOverMass2 = integral.Simpson(this, &G4KineticTrack::IntegrandFunction4,
00786                                                    theLowerLimit, theUpperLimit, nIterations);
00787   return theIntegralOverMass2;
00788 }
00789 
00790 
00791 
00792 
00793 
00794 
00795 
00796 

Generated on Mon May 27 17:48:43 2013 for Geant4 by  doxygen 1.4.7