Geant4  10.02.p03
G4PhaseSpaceDecayChannel Class Reference

#include <G4PhaseSpaceDecayChannel.hh>

Inheritance diagram for G4PhaseSpaceDecayChannel:
Collaboration diagram for G4PhaseSpaceDecayChannel:

Public Types

enum  { MAX_N_DAUGHTERS =4 }
 

Public Member Functions

 G4PhaseSpaceDecayChannel (G4int Verbose=1)
 
 G4PhaseSpaceDecayChannel (const G4String &theParentName, G4double theBR, G4int theNumberOfDaughters, const G4String &theDaughterName1, const G4String &theDaughterName2="", const G4String &theDaughterName3="", const G4String &theDaughterName4="")
 
G4bool SetDaughterMasses (G4double masses[])
 
G4bool SampleDaughterMasses ()
 
virtual ~G4PhaseSpaceDecayChannel ()
 
virtual G4DecayProductsDecayIt (G4double)
 
G4bool IsOKWithParentMass (G4double parentMass)
 
- Public Member Functions inherited from G4VDecayChannel
 G4VDecayChannel (const G4String &aName, G4int Verbose=1)
 
 G4VDecayChannel (const G4String &aName, const G4String &theParentName, G4double theBR, G4int theNumberOfDaughters, const G4String &theDaughterName1, const G4String &theDaughterName2="", const G4String &theDaughterName3="", const G4String &theDaughterName4="")
 
virtual ~G4VDecayChannel ()
 
G4int operator== (const G4VDecayChannel &right) const
 
G4int operator!= (const G4VDecayChannel &right) const
 
G4int operator< (const G4VDecayChannel &right) const
 
const G4StringGetKinematicsName () const
 
G4double GetBR () const
 
G4int GetNumberOfDaughters () const
 
G4ParticleDefinitionGetParent ()
 
G4ParticleDefinitionGetDaughter (G4int anIndex)
 
G4int GetAngularMomentum ()
 
const G4StringGetParentName () const
 
const G4StringGetDaughterName (G4int anIndex) const
 
G4double GetParentMass () const
 
G4double GetDaughterMass (G4int anIndex) const
 
void SetParent (const G4ParticleDefinition *particle_type)
 
void SetParent (const G4String &particle_name)
 
void SetBR (G4double value)
 
void SetNumberOfDaughters (G4int value)
 
void SetDaughter (G4int anIndex, const G4ParticleDefinition *particle_type)
 
void SetDaughter (G4int anIndex, const G4String &particle_name)
 
void SetVerboseLevel (G4int value)
 
G4int GetVerboseLevel () const
 
void DumpInfo ()
 
G4double GetRangeMass () const
 
void SetRangeMass (G4double val)
 
void SetPolarization (const G4ThreeVector &)
 
const G4ThreeVectorGetPolarization () const
 

Static Public Member Functions

static G4double Pmx (G4double e, G4double p1, G4double p2)
 

Private Member Functions

G4DecayProductsOneBodyDecayIt ()
 
G4DecayProductsTwoBodyDecayIt ()
 
G4DecayProductsThreeBodyDecayIt ()
 
G4DecayProductsManyBodyDecayIt ()
 

Private Attributes

G4Cache< G4doublecurrent_parent_mass
 
G4bool useGivenDaughterMass
 
G4double givenDaughterMasses [MAX_N_DAUGHTERS]
 

Additional Inherited Members

- Protected Member Functions inherited from G4VDecayChannel
void ClearDaughtersName ()
 
void CheckAndFillDaughters ()
 
void CheckAndFillParent ()
 
 G4VDecayChannel ()
 
 G4VDecayChannel (const G4VDecayChannel &)
 
G4VDecayChanneloperator= (const G4VDecayChannel &)
 
G4double DynamicalMass (G4double massPDG, G4double width, G4double maxDev=+1.) const
 
- Protected Attributes inherited from G4VDecayChannel
G4String kinematics_name
 
G4double rbranch
 
G4int numberOfDaughters
 
G4Stringparent_name
 
G4String ** daughters_name
 
G4double rangeMass
 
G4ThreeVector parent_polarization
 
G4ParticleTableparticletable
 
G4int verboseLevel
 
G4ParticleDefinitionG4MT_parent
 
G4ParticleDefinition ** G4MT_daughters
 
G4double G4MT_parent_mass
 
G4doubleG4MT_daughters_mass
 
G4doubleG4MT_daughters_width
 
G4Mutex daughtersMutex
 
G4Mutex parentMutex
 
- Static Protected Attributes inherited from G4VDecayChannel
static const G4String noName = " "
 

Detailed Description

Definition at line 46 of file G4PhaseSpaceDecayChannel.hh.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
MAX_N_DAUGHTERS 

Definition at line 49 of file G4PhaseSpaceDecayChannel.hh.

Constructor & Destructor Documentation

◆ G4PhaseSpaceDecayChannel() [1/2]

G4PhaseSpaceDecayChannel::G4PhaseSpaceDecayChannel ( G4int  Verbose = 1)

Definition at line 51 of file G4PhaseSpaceDecayChannel.cc.

52  :G4VDecayChannel("Phase Space", Verbose)
53 {
54 
55 }

◆ G4PhaseSpaceDecayChannel() [2/2]

G4PhaseSpaceDecayChannel::G4PhaseSpaceDecayChannel ( const G4String theParentName,
G4double  theBR,
G4int  theNumberOfDaughters,
const G4String theDaughterName1,
const G4String theDaughterName2 = "",
const G4String theDaughterName3 = "",
const G4String theDaughterName4 = "" 
)

Definition at line 57 of file G4PhaseSpaceDecayChannel.cc.

65  :G4VDecayChannel("Phase Space",
66  theParentName,theBR,
67  theNumberOfDaughters,
68  theDaughterName1,
69  theDaughterName2,
70  theDaughterName3,
71  theDaughterName4),
73 {
74 
75 }

◆ ~G4PhaseSpaceDecayChannel()

G4PhaseSpaceDecayChannel::~G4PhaseSpaceDecayChannel ( )
virtual

Definition at line 77 of file G4PhaseSpaceDecayChannel.cc.

78 {
79 }

Member Function Documentation

◆ DecayIt()

G4DecayProducts * G4PhaseSpaceDecayChannel::DecayIt ( G4double  parentMass)
virtual

Implements G4VDecayChannel.

Definition at line 81 of file G4PhaseSpaceDecayChannel.cc.

82 {
83 #ifdef G4VERBOSE
84  if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::DecayIt ";
85 #endif
86 
87  G4DecayProducts * products = 0;
88 
91 
92  if (parentMass >0.0) current_parent_mass.Put( parentMass );
94 
95  switch (numberOfDaughters){
96  case 0:
97 #ifdef G4VERBOSE
98  if (GetVerboseLevel()>0) {
99  G4cout << "G4PhaseSpaceDecayChannel::DecayIt ";
100  G4cout << " daughters not defined " <<G4endl;
101  }
102 #endif
103  break;
104  case 1:
105  products = OneBodyDecayIt();
106  break;
107  case 2:
108  products = TwoBodyDecayIt();
109  break;
110  case 3:
111  products = ThreeBodyDecayIt();
112  break;
113  default:
114  products = ManyBodyDecayIt();
115  break;
116  }
117 #ifdef G4VERBOSE
118  if ((products == 0) && (GetVerboseLevel()>0)) {
119  G4cout << "G4PhaseSpaceDecayChannel::DecayIt ";
120  G4cout << *parent_name << " can not decay " << G4endl;
121  DumpInfo();
122  }
123 #endif
124  return products;
125 }
void Put(const value_type &val) const
Definition: G4Cache.hh:286
void CheckAndFillDaughters()
G4Cache< G4double > current_parent_mass
G4double G4MT_parent_mass
G4GLOB_DLL std::ostream G4cout
G4String * parent_name
#define G4endl
Definition: G4ios.hh:61
G4int GetVerboseLevel() const
Here is the call graph for this function:

◆ IsOKWithParentMass()

G4bool G4PhaseSpaceDecayChannel::IsOKWithParentMass ( G4double  parentMass)
virtual

Reimplemented from G4VDecayChannel.

Definition at line 719 of file G4PhaseSpaceDecayChannel.cc.

719  {
721 
724 
725  G4double sumOfDaughterMassMin=0.0;
726  for (G4int index=0; index < numberOfDaughters; index++) {
727  sumOfDaughterMassMin += givenDaughterMasses[index];
728  }
729  return (parentMass >= sumOfDaughterMassMin);
730 }
void CheckAndFillDaughters()
Int_t index
G4double givenDaughterMasses[MAX_N_DAUGHTERS]
virtual G4bool IsOKWithParentMass(G4double parentMass)
int G4int
Definition: G4Types.hh:78
double G4double
Definition: G4Types.hh:76
Here is the call graph for this function:

◆ ManyBodyDecayIt()

G4DecayProducts * G4PhaseSpaceDecayChannel::ManyBodyDecayIt ( )
private

Definition at line 448 of file G4PhaseSpaceDecayChannel.cc.

458 {
459  G4int index, index2;
460 
461 #ifdef G4VERBOSE
462  if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt()"<<G4endl;
463 #endif
464 
465 
466  // parent mass
467  G4double parentmass = current_parent_mass.Get();
468 
469  //parent particle
470  G4ThreeVector dummy;
471  G4DynamicParticle * parentparticle = new G4DynamicParticle( G4MT_parent, dummy, 0.0, parentmass);
472 
473  //create G4Decayproducts
474  G4DecayProducts *products = new G4DecayProducts(*parentparticle);
475  delete parentparticle;
476 
477  //daughters'mass
478  G4double *daughtermass = new G4double[numberOfDaughters];
479 
480  G4double sumofdaughtermass = 0.0;
481  for (index=0; index<numberOfDaughters; index++){
482  if (!useGivenDaughterMass) {
483  daughtermass[index] = G4MT_daughters_mass[index];
484  } else {
485  daughtermass[index] = givenDaughterMasses[index];
486  }
487  sumofdaughtermass += daughtermass[index];
488  }
489  if (sumofdaughtermass >parentmass) {
490 #ifdef G4VERBOSE
491  if (GetVerboseLevel()>0) {
492  G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt "
493  << "sum of daughter mass is larger than parent mass" << G4endl;
494  G4cout << "parent :" << G4MT_parent->GetParticleName() << " " << current_parent_mass.Get()/GeV << G4endl;
495  G4cout << "daughter 1 :" << G4MT_daughters[0]->GetParticleName() << " " << daughtermass[0]/GeV << G4endl;
496  G4cout << "daughter 2:" << G4MT_daughters[1]->GetParticleName() << " " << daughtermass[1]/GeV << G4endl;
497  G4cout << "daughter 3:" << G4MT_daughters[2]->GetParticleName() << " " << daughtermass[2]/GeV << G4endl;
498  G4cout << "daughter 4:" << G4MT_daughters[3]->GetParticleName() << " " << daughtermass[3]/GeV << G4endl;
499  }
500 #endif
501  G4Exception("G4PhaseSpaceDecayChannel::ManyBodyDecayIt",
502  "PART112", JustWarning,
503  "Can not create decay products: sum of daughter mass is larger than parent mass");
504  return products;
505  }
506 
507  //Calculate daughter momentum
508  G4double *daughtermomentum = new G4double[numberOfDaughters];
509  G4ThreeVector direction;
510  G4DynamicParticle **daughterparticle;
512  G4double tmas;
513  G4double weight = 1.0;
514  G4int numberOfTry = 0;
515  const size_t MAX_LOOP=10000;
516 
517  for (size_t loop_counter=0; loop_counter <MAX_LOOP; ++loop_counter){
518  //Generate rundom number in descending order
519  G4double temp;
521  rd[0] = 1.0;
522  for(index =1; index < numberOfDaughters -1; index++) rd[index] = G4UniformRand();
523  rd[ numberOfDaughters -1] = 0.0;
524  for(index =1; index < numberOfDaughters -1; index++) {
525  for(index2 = index+1; index2 < numberOfDaughters; index2++) {
526  if (rd[index] < rd[index2]){
527  temp = rd[index];
528  rd[index] = rd[index2];
529  rd[index2] = temp;
530  }
531  }
532  }
533 
534  //calcurate virtual mass
535  tmas = parentmass - sumofdaughtermass;
536  temp = sumofdaughtermass;
537  for(index =0; index < numberOfDaughters; index++) {
538  sm[index] = rd[index]*tmas + temp;
539  temp -= daughtermass[index];
540  if (GetVerboseLevel()>1) {
541  G4cout << index << " rundom number:" << rd[index];
542  G4cout << " virtual mass:" << sm[index]/GeV << "[GeV/c/c]" <<G4endl;
543  }
544  }
545  delete [] rd;
546 
547  //Calculate daughter momentum
548  weight = 1.0;
549  G4bool smOK=true;
550  for(index =0; index< numberOfDaughters-1 && smOK; index--) {
551  smOK = (sm[index]-daughtermass[index]- sm[index+1] >=0.);
552  }
553  if (!smOK) continue;
554 
555  index =numberOfDaughters-1;
556  daughtermomentum[index]= Pmx( sm[index-1],daughtermass[index-1], sm[index]);
557 #ifdef G4VERBOSE
558  if (GetVerboseLevel()>1) {
559  G4cout << " daughter " << index << ":" << *daughters_name[index];
560  G4cout << " momentum:" << daughtermomentum[index]/GeV << "[GeV/c]" <<G4endl;
561  }
562 #endif
563  for(index =numberOfDaughters-2; index>=0; index--) {
564  // calculate
565  daughtermomentum[index]= Pmx( sm[index],daughtermass[index], sm[index +1]);
566  if(daughtermomentum[index] < 0.0) {
567  // !!! illegal momentum !!!
568 #ifdef G4VERBOSE
569  if (GetVerboseLevel()>0) {
570  G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt ";
571  G4cout << " can not calculate daughter momentum " <<G4endl;
572  G4cout << " parent:" << *parent_name;
573  G4cout << " mass:" << parentmass/GeV << "[GeV/c/c]" <<G4endl;
574  G4cout << " daughter " << index << ":" << *daughters_name[index];
575  G4cout << " mass:" << daughtermass[index]/GeV << "[GeV/c/c]" ;
576  G4cout << " mass:" << daughtermomentum[index]/GeV << "[GeV/c]" <<G4endl;
577  if (useGivenDaughterMass) {
578  G4cout << "Daughter Mass is given " << G4endl;
579  }
580  }
581 #endif
582  delete [] sm;
583  delete [] daughtermass;
584  delete [] daughtermomentum;
585 
586  G4Exception("G4PhaseSpaceDecayChannel::ManyBodyDecayIt",
587  "PART112", JustWarning,
588  "Can not create decay products: sum of daughter mass is larger than parent mass");
589 
590  return 0; // Error detection
591 
592  } else {
593  // calculate weight of this events
594  weight *= daughtermomentum[index]/sm[index];
595 #ifdef G4VERBOSE
596  if (GetVerboseLevel()>1) {
597  G4cout << " daughter " << index << ":" << *daughters_name[index];
598  G4cout << " momentum:" << daughtermomentum[index]/GeV << "[GeV/c]" <<G4endl;
599  }
600 #endif
601  }
602  }
603 
604 #ifdef G4VERBOSE
605  if (GetVerboseLevel()>1) {
606  G4cout << " weight: " << weight <<G4endl;
607  }
608 #endif
609 
610  // exit if number of Try exceeds 100
611  if (numberOfTry++ >100) {
612 #ifdef G4VERBOSE
613  if (GetVerboseLevel()>0) {
614  G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt: ";
615  G4cout << " can not determine Decay Kinematics " << G4endl;
616  G4cout << "parent : " << *parent_name << G4endl;
617  G4cout << "daughters : ";
618  for(index=0; index<numberOfDaughters; index++) {
619  G4cout << *daughters_name[index] << " , ";
620  }
621  G4cout << G4endl;
622  }
623 #endif
624  G4Exception("G4PhaseSpaceDecayChannel::ManyBodyDecayIt: ",
625  "PART113", JustWarning,
626  " Cannot decay : Decay Kinematics cannot be calculated ");
627 
628  delete [] sm;
629  delete [] daughtermass;
630  delete [] daughtermomentum;
631  return 0; // Error detection
632  }
633  if ( weight < G4UniformRand()) break;
634  }
635 
636 #ifdef G4VERBOSE
637  if (GetVerboseLevel()>1) {
638  G4cout << "Start calulation of daughters momentum vector "<<G4endl;
639  }
640 #endif
641 
642  G4double costheta, sintheta, phi;
643  G4double beta;
644  daughterparticle = new G4DynamicParticle*[numberOfDaughters];
645 
646  index = numberOfDaughters -2;
647  costheta = 2.*G4UniformRand()-1.0;
648  sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
649  phi = twopi*G4UniformRand()*rad;
650  direction.setZ(costheta);
651  direction.setY(sintheta*std::sin(phi));
652  direction.setX(sintheta*std::cos(phi));
653  daughterparticle[index] = new G4DynamicParticle( G4MT_daughters[index], direction*daughtermomentum[index] );
654  daughterparticle[index+1] = new G4DynamicParticle( G4MT_daughters[index+1], direction*(-1.0*daughtermomentum[index]) );
655 
656  for (index = numberOfDaughters -3; index >= 0; index--) {
657  //calculate momentum direction
658  costheta = 2.*G4UniformRand()-1.0;
659  sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
660  phi = twopi*G4UniformRand()*rad;
661  direction.setZ(costheta);
662  direction.setY(sintheta*std::sin(phi));
663  direction.setX(sintheta*std::cos(phi));
664 
665  // boost already created particles
666  beta = daughtermomentum[index];
667  beta /= std::sqrt( daughtermomentum[index]*daughtermomentum[index] + sm[index+1]*sm[index+1] );
668  for (index2 = index+1; index2<numberOfDaughters; index2++) {
669  G4LorentzVector p4;
670  // make G4LorentzVector for secondaries
671  p4 = daughterparticle[index2]->Get4Momentum();
672 
673  // boost secondaries to new frame
674  p4.boost( direction.x()*beta, direction.y()*beta, direction.z()*beta);
675 
676  // change energy/momentum
677  daughterparticle[index2]->Set4Momentum(p4);
678  }
679  //create daughter G4DynamicParticle
680  daughterparticle[index]= new G4DynamicParticle( G4MT_daughters[index], direction*(-1.0*daughtermomentum[index]));
681  }
682 
683  //add daughters to G4Decayproducts
684  for (index = 0; index<numberOfDaughters; index++) {
685  products->PushProducts(daughterparticle[index]);
686  }
687 
688 #ifdef G4VERBOSE
689  if (GetVerboseLevel()>1) {
690  G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt ";
691  G4cout << " create decay products in rest frame " << G4endl;
692  products->DumpInfo();
693  }
694 #endif
695 
696  delete [] daughterparticle;
697  delete [] daughtermomentum;
698  delete [] daughtermass;
699  delete [] sm;
700 
701  return products;
702 }
G4double * G4MT_daughters_mass
Int_t index
G4int PushProducts(G4DynamicParticle *aParticle)
G4double givenDaughterMasses[MAX_N_DAUGHTERS]
G4ParticleDefinition * G4MT_parent
G4Cache< G4double > current_parent_mass
G4ParticleDefinition ** G4MT_daughters
value_type & Get() const
Definition: G4Cache.hh:282
double weight
Definition: plottest35.C:25
int G4int
Definition: G4Types.hh:78
void setY(double)
void setZ(double)
void setX(double)
const G4String & GetParticleName() const
#define G4UniformRand()
Definition: Randomize.hh:97
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
HepLorentzVector & boost(double, double, double)
static const double twopi
Definition: G4SIunits.hh:75
G4String * parent_name
static const double GeV
Definition: G4SIunits.hh:214
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
double x() const
static const double rad
Definition: G4SIunits.hh:148
void Set4Momentum(const G4LorentzVector &momentum)
double y() const
double z() const
void DumpInfo() const
G4LorentzVector Get4Momentum() const
#define G4endl
Definition: G4ios.hh:61
G4int GetVerboseLevel() const
double G4double
Definition: G4Types.hh:76
G4String ** daughters_name
static G4double Pmx(G4double e, G4double p1, G4double p2)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ OneBodyDecayIt()

G4DecayProducts * G4PhaseSpaceDecayChannel::OneBodyDecayIt ( )
private

Definition at line 127 of file G4PhaseSpaceDecayChannel.cc.

128 {
129 #ifdef G4VERBOSE
130  if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::OneBodyDecayIt()"<<G4endl;
131 #endif
132  // parent mass
133  G4double parentmass = current_parent_mass.Get();
134 
135  //create parent G4DynamicParticle at rest
136  G4ThreeVector dummy;
137  G4DynamicParticle * parentparticle = new G4DynamicParticle( G4MT_parent, dummy, 0.0, parentmass);
138  //create G4Decayproducts
139  G4DecayProducts *products = new G4DecayProducts(*parentparticle);
140  delete parentparticle;
141 
142  //create daughter G4DynamicParticle at rest
143  G4DynamicParticle * daughterparticle = new G4DynamicParticle( G4MT_daughters[0], dummy, 0.0);
144  if (useGivenDaughterMass) daughterparticle->SetMass(givenDaughterMasses[0]);
145  products->PushProducts(daughterparticle);
146 
147 #ifdef G4VERBOSE
148  if (GetVerboseLevel()>1) {
149  G4cout << "G4PhaseSpaceDecayChannel::OneBodyDecayIt ";
150  G4cout << " create decay products in rest frame " <<G4endl;
151  products->DumpInfo();
152  }
153 #endif
154  return products;
155 }
G4int PushProducts(G4DynamicParticle *aParticle)
G4double givenDaughterMasses[MAX_N_DAUGHTERS]
G4ParticleDefinition * G4MT_parent
G4Cache< G4double > current_parent_mass
G4ParticleDefinition ** G4MT_daughters
value_type & Get() const
Definition: G4Cache.hh:282
G4GLOB_DLL std::ostream G4cout
void DumpInfo() const
#define G4endl
Definition: G4ios.hh:61
G4int GetVerboseLevel() const
double G4double
Definition: G4Types.hh:76
void SetMass(G4double mass)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Pmx()

G4double G4PhaseSpaceDecayChannel::Pmx ( G4double  e,
G4double  p1,
G4double  p2 
)
static

Definition at line 732 of file G4PhaseSpaceDecayChannel.cc.

733 {
734  // calcurate momentum of daughter particles in two-body decay
735  G4double ppp = (e+p1+p2)*(e+p1-p2)*(e-p1+p2)*(e-p1-p2)/(4.0*e*e);
736  if (ppp>0) return std::sqrt(ppp);
737  else return -1.;
738 }
double G4double
Definition: G4Types.hh:76
Here is the caller graph for this function:

◆ SampleDaughterMasses()

G4bool G4PhaseSpaceDecayChannel::SampleDaughterMasses ( )

Definition at line 713 of file G4PhaseSpaceDecayChannel.cc.

714 {
715  useGivenDaughterMass = false;
716  return useGivenDaughterMass;
717 }

◆ SetDaughterMasses()

G4bool G4PhaseSpaceDecayChannel::SetDaughterMasses ( G4double  masses[])

Definition at line 704 of file G4PhaseSpaceDecayChannel.cc.

705 {
706  for (G4int idx=0; idx<numberOfDaughters; idx++){
707  givenDaughterMasses[idx] = masses[idx];
708  }
709  useGivenDaughterMass = true;
710  return useGivenDaughterMass;
711 }
G4double givenDaughterMasses[MAX_N_DAUGHTERS]
int G4int
Definition: G4Types.hh:78

◆ ThreeBodyDecayIt()

G4DecayProducts * G4PhaseSpaceDecayChannel::ThreeBodyDecayIt ( )
private

Definition at line 260 of file G4PhaseSpaceDecayChannel.cc.

262 {
263 #ifdef G4VERBOSE
264  if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()"<<G4endl;
265 #endif
266  // parent mass
267  G4double parentmass = current_parent_mass.Get();
268  //daughters'mass
269  G4double daughtermass[3], daughterwidth[3];
270  G4double sumofdaughtermass = 0.0;
271  G4double sumofdaughterwidthsq = 0.0;
272  G4bool withWidth = false;
273  for (G4int index=0; index<3; index++){
274  daughtermass[index] = G4MT_daughters_mass[index];
275  sumofdaughtermass += daughtermass[index];
276  daughterwidth[index] = G4MT_daughters_width[index];
277  sumofdaughterwidthsq += daughterwidth[index]*daughterwidth[index];
278  withWidth = withWidth ||(daughterwidth[index]>1.0e-3*daughtermass[index]);
279  }
280 
281  //create parent G4DynamicParticle at rest
282  G4ThreeVector dummy;
283  G4DynamicParticle * parentparticle = new G4DynamicParticle( G4MT_parent, dummy, 0.0, parentmass);
284 
285 
286  //create G4Decayproducts
287  G4DecayProducts *products = new G4DecayProducts(*parentparticle);
288  delete parentparticle;
289 
290  if (!useGivenDaughterMass) {
291  if (withWidth){
292  G4double maxDev = (parentmass - sumofdaughtermass )/std::sqrt(sumofdaughterwidthsq) ;
293  if (maxDev <= -1.0*rangeMass ){
294 #ifdef G4VERBOSE
295  if (GetVerboseLevel()>0) {
296  G4cout << "G4PhaseSpaceDecayChannel::ThreeBodyDecayIt "
297  << "sum of daughter mass is larger than parent mass" << G4endl;
298  G4cout << "parent :" << G4MT_parent->GetParticleName() << " " << current_parent_mass.Get()/GeV << G4endl;
299  G4cout << "daughter 1 :" << G4MT_daughters[0]->GetParticleName() << " " << daughtermass[0]/GeV << G4endl;
300  G4cout << "daughter 2:" << G4MT_daughters[1]->GetParticleName() << " " << daughtermass[1]/GeV << G4endl;
301  G4cout << "daughter 3:" << G4MT_daughters[2]->GetParticleName() << " " << daughtermass[2]/GeV << G4endl;
302  }
303 #endif
304  G4Exception("G4PhaseSpaceDecayChannel::ThreeBodyDecayIt",
305  "PART112", JustWarning,
306  "Can not create decay products: sum of daughter mass is larger than parent mass");
307  return products;
308  }
309  G4double dm1= DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
310  G4double dm2= DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
311  G4double dm3= DynamicalMass(daughtermass[2],daughterwidth[2], maxDev);
312  while (dm1+dm2+dm3>parentmass){ // Loop checking, 09.08.2015, K.Kurashige
313  dm1= DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
314  dm2= DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
315  dm3= DynamicalMass(daughtermass[2],daughterwidth[2], maxDev);
316  }
317  daughtermass[0] = dm1;
318  daughtermass[1] = dm2;
319  daughtermass[2] = dm3;
320  sumofdaughtermass = dm1+dm2+dm3;
321  }
322  } else {
323  // use given daughter mass;
324  daughtermass[0] = givenDaughterMasses[0];
325  daughtermass[1] = givenDaughterMasses[1];
326  daughtermass[2] = givenDaughterMasses[2];
327  sumofdaughtermass = daughtermass[0] + daughtermass[1] + daughtermass[2];
328  }
329 
330  if (sumofdaughtermass >parentmass) {
331 #ifdef G4VERBOSE
332  if (GetVerboseLevel()>0) {
333  G4cout << "G4PhaseSpaceDecayChannel::ThreeBodyDecayIt "
334  << "sum of daughter mass is larger than parent mass" << G4endl;
335  G4cout << "parent :" << G4MT_parent->GetParticleName() << " " << current_parent_mass.Get()/GeV << G4endl;
336  G4cout << "daughter 1 :" << G4MT_daughters[0]->GetParticleName() << " " << daughtermass[0]/GeV << G4endl;
337  G4cout << "daughter 2:" << G4MT_daughters[1]->GetParticleName() << " " << daughtermass[1]/GeV << G4endl;
338  G4cout << "daughter 3:" << G4MT_daughters[2]->GetParticleName() << " " << daughtermass[2]/GeV << G4endl;
339  }
340  if (useGivenDaughterMass) {
341  G4cout << "Daughter Mass is given " << G4endl;
342  }
343 #endif
344  G4Exception("G4PhaseSpaceDecayChannel::ThreeBodyDecayIt",
345  "PART112", JustWarning,
346  "Can not create decay products: sum of daughter mass is larger than parent mass");
347  return products;
348  }
349 
350 
351 
352  //calculate daughter momentum
353  // Generate two
354  G4double rd1, rd2, rd;
355  G4double daughtermomentum[3];
356  G4double momentummax=0.0, momentumsum = 0.0;
358  const size_t MAX_LOOP=10000;
359 
360  for (size_t loop_counter=0; loop_counter <MAX_LOOP; ++loop_counter){
361  rd1 = G4UniformRand();
362  rd2 = G4UniformRand();
363  if (rd2 > rd1) {
364  rd = rd1;
365  rd1 = rd2;
366  rd2 = rd;
367  }
368  momentummax = 0.0;
369  momentumsum = 0.0;
370  // daughter 0
371  energy = rd2*(parentmass - sumofdaughtermass);
372  daughtermomentum[0] = std::sqrt(energy*energy + 2.0*energy* daughtermass[0]);
373  if ( daughtermomentum[0] >momentummax )momentummax = daughtermomentum[0];
374  momentumsum += daughtermomentum[0];
375  // daughter 1
376  energy = (1.-rd1)*(parentmass - sumofdaughtermass);
377  daughtermomentum[1] = std::sqrt(energy*energy + 2.0*energy* daughtermass[1]);
378  if ( daughtermomentum[1] >momentummax )momentummax = daughtermomentum[1];
379  momentumsum += daughtermomentum[1];
380  // daughter 2
381  energy = (rd1-rd2)*(parentmass - sumofdaughtermass);
382  daughtermomentum[2] = std::sqrt(energy*energy + 2.0*energy* daughtermass[2]);
383  if ( daughtermomentum[2] >momentummax )momentummax = daughtermomentum[2];
384  momentumsum += daughtermomentum[2];
385  if (momentummax <= momentumsum - momentummax ) break;
386  }
387 
388  // output message
389 #ifdef G4VERBOSE
390  if (GetVerboseLevel()>1) {
391  G4cout << " daughter 0:" << daughtermomentum[0]/GeV << "[GeV/c]" <<G4endl;
392  G4cout << " daughter 1:" << daughtermomentum[1]/GeV << "[GeV/c]" <<G4endl;
393  G4cout << " daughter 2:" << daughtermomentum[2]/GeV << "[GeV/c]" <<G4endl;
394  G4cout << " momentum sum:" << momentumsum/GeV << "[GeV/c]" <<G4endl;
395  }
396 #endif
397 
398  //create daughter G4DynamicParticle
399  G4double costheta, sintheta, phi, sinphi, cosphi;
400  G4double costhetan, sinthetan, phin, sinphin, cosphin;
401  costheta = 2.*G4UniformRand()-1.0;
402  sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
403  phi = twopi*G4UniformRand()*rad;
404  sinphi = std::sin(phi);
405  cosphi = std::cos(phi);
406 
407  G4ThreeVector direction0(sintheta*cosphi,sintheta*sinphi,costheta);
408  G4double Ekin = std::sqrt(daughtermomentum[0]*daughtermomentum[0] + daughtermass[0]*daughtermass[0]) - daughtermass[0];
409  G4DynamicParticle * daughterparticle = new G4DynamicParticle( G4MT_daughters[0],
410  direction0,
411  Ekin, daughtermass[0]);
412  products->PushProducts(daughterparticle);
413 
414  costhetan = (daughtermomentum[1]*daughtermomentum[1]-daughtermomentum[2]*daughtermomentum[2]-daughtermomentum[0]*daughtermomentum[0])/(2.0*daughtermomentum[2]*daughtermomentum[0]);
415  sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
416  phin = twopi*G4UniformRand()*rad;
417  sinphin = std::sin(phin);
418  cosphin = std::cos(phin);
419  G4ThreeVector direction2;
420  direction2.setX( sinthetan*cosphin*costheta*cosphi - sinthetan*sinphin*sinphi + costhetan*sintheta*cosphi);
421  direction2.setY( sinthetan*cosphin*costheta*sinphi + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
422  direction2.setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
423  G4ThreeVector pmom = daughtermomentum[2]*direction2/direction2.mag();
424  Ekin = std::sqrt(pmom.mag2() + daughtermass[2]*daughtermass[2]) - daughtermass[2];
425  daughterparticle = new G4DynamicParticle( G4MT_daughters[2],
426  pmom/pmom.mag(),
427  Ekin, daughtermass[2]);
428  products->PushProducts(daughterparticle);
429 
430  pmom = (direction0*daughtermomentum[0] + direction2*(daughtermomentum[2]/direction2.mag()))*(-1.0);
431  Ekin = std::sqrt(pmom.mag2() + daughtermass[1]*daughtermass[1]) - daughtermass[1];
432  daughterparticle = new G4DynamicParticle(
433  G4MT_daughters[1],
434  pmom/pmom.mag(),
435  Ekin, daughtermass[1]);
436  products->PushProducts(daughterparticle);
437 
438 #ifdef G4VERBOSE
439  if (GetVerboseLevel()>1) {
440  G4cout << "G4PhaseSpaceDecayChannel::ThreeBodyDecayIt ";
441  G4cout << " create decay products in rest frame " <<G4endl;
442  products->DumpInfo();
443  }
444 #endif
445  return products;
446 }
G4double * G4MT_daughters_mass
Int_t index
G4int PushProducts(G4DynamicParticle *aParticle)
G4double givenDaughterMasses[MAX_N_DAUGHTERS]
G4ParticleDefinition * G4MT_parent
G4Cache< G4double > current_parent_mass
G4ParticleDefinition ** G4MT_daughters
value_type & Get() const
Definition: G4Cache.hh:282
G4double DynamicalMass(G4double massPDG, G4double width, G4double maxDev=+1.) const
int G4int
Definition: G4Types.hh:78
void setY(double)
void setZ(double)
void setX(double)
double mag2() const
const G4String & GetParticleName() const
#define G4UniformRand()
Definition: Randomize.hh:97
G4GLOB_DLL std::ostream G4cout
double energy
Definition: plottest35.C:25
bool G4bool
Definition: G4Types.hh:79
double mag() const
static const double twopi
Definition: G4SIunits.hh:75
static const double GeV
Definition: G4SIunits.hh:214
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
static const double rad
Definition: G4SIunits.hh:148
G4double * G4MT_daughters_width
void DumpInfo() const
#define G4endl
Definition: G4ios.hh:61
G4int GetVerboseLevel() const
double G4double
Definition: G4Types.hh:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TwoBodyDecayIt()

G4DecayProducts * G4PhaseSpaceDecayChannel::TwoBodyDecayIt ( )
private

Definition at line 157 of file G4PhaseSpaceDecayChannel.cc.

158 {
159 #ifdef G4VERBOSE
160  if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::TwoBodyDecayIt()"<<G4endl;
161 #endif
162  // parent mass
163  G4double parentmass = current_parent_mass.Get();
164 
165  //daughters'mass, width
166  G4double daughtermass[2], daughterwidth[2];
167  daughtermass[0] = G4MT_daughters_mass[0];
168  daughtermass[1] = G4MT_daughters_mass[1];
169  daughterwidth[0] = G4MT_daughters_width[0];
170  daughterwidth[1] = G4MT_daughters_width[1];
171 
172  //create parent G4DynamicParticle at rest
173  G4ThreeVector dummy;
174  G4DynamicParticle * parentparticle = new G4DynamicParticle( G4MT_parent, dummy, 0.0, parentmass);
175  //create G4Decayproducts
176  G4DecayProducts *products = new G4DecayProducts(*parentparticle);
177  delete parentparticle;
178 
179  if (!useGivenDaughterMass) {
180  G4bool withWidth = (daughterwidth[0]>1.0e-3*daughtermass[0])
181  || (daughterwidth[1]>1.0e-3*daughtermass[1]);
182  if (withWidth) {
183  G4double sumofdaughterwidthsq = daughterwidth[0]*daughterwidth[0]+daughterwidth[1]*daughterwidth[1];
184  // check parent mass and daughter mass
185  G4double maxDev = (parentmass - daughtermass[0] - daughtermass[1] )/std::sqrt(sumofdaughterwidthsq);
186  if (maxDev <= -1.0*rangeMass ){
187 #ifdef G4VERBOSE
188  if (GetVerboseLevel()>0) {
189  G4cout << "G4PhaseSpaceDecayChannel::TwoBodyDecayIt "
190  << "sum of daughter mass is larger than parent mass" << G4endl;
191  G4cout << "parent :" << G4MT_parent->GetParticleName() << " " << current_parent_mass.Get()/GeV << G4endl;
192  G4cout << "daughter 1 :" << G4MT_daughters[0]->GetParticleName() << " " << daughtermass[0]/GeV << G4endl;
193  G4cout << "daughter 2:" << G4MT_daughters[1]->GetParticleName() << " " << daughtermass[1]/GeV << G4endl;
194  }
195 #endif
196  G4Exception("G4PhaseSpaceDecayChannel::TwoBodyDecayIt",
197  "PART112", JustWarning,
198  "Can not create decay products: sum of daughter mass is larger than parent mass");
199  return products;
200  }
201  G4double dm1= DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
202  G4double dm2= DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
203  while (dm1+dm2>parentmass){ // Loop checking, 09.08.2015, K.Kurashige
204  dm1= DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
205  dm2= DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
206  }
207  daughtermass[0] = dm1;
208  daughtermass[1] = dm2;
209  }
210  } else {
211  // use given daughter mass;
212  daughtermass[0] = givenDaughterMasses[0];
213  daughtermass[1] = givenDaughterMasses[1];
214  }
215  if (parentmass < daughtermass[0] + daughtermass[1] ){
216 #ifdef G4VERBOSE
217  if (GetVerboseLevel()>0) {
218  G4cout << "G4PhaseSpaceDecayChannel::TwoBodyDecayIt "
219  << "sum of daughter mass is larger than parent mass" << G4endl;
220  G4cout << "parent :" << G4MT_parent->GetParticleName() << " " << current_parent_mass.Get()/GeV << G4endl;
221  G4cout << "daughter 1 :" << G4MT_daughters[0]->GetParticleName() << " " << daughtermass[0]/GeV << G4endl;
222  G4cout << "daughter 2:" << G4MT_daughters[1]->GetParticleName() << " " << daughtermass[1]/GeV << G4endl;
223  if (useGivenDaughterMass) {
224  G4cout << "Daughter Mass is given " << G4endl;
225  }
226  }
227 #endif
228  G4Exception("G4PhaseSpaceDecayChannel::TwoBodyDecayIt",
229  "PART112", JustWarning,
230  "Can not create decay products: sum of daughter mass is larger than parent mass");
231  return products;
232  }
233 
234  //calculate daughter momentum
235  G4double daughtermomentum = Pmx(parentmass,daughtermass[0],daughtermass[1]);
236 
237  G4double costheta = 2.*G4UniformRand()-1.0;
238  G4double sintheta = std::sqrt((1.0 - costheta)*(1.0 + costheta));
240  G4ThreeVector direction(sintheta*std::cos(phi),sintheta*std::sin(phi),costheta);
241 
242  //create daughter G4DynamicParticle
243  G4double Ekin = std::sqrt(daughtermomentum*daughtermomentum + daughtermass[0]*daughtermass[0]) - daughtermass[0];
244  G4DynamicParticle * daughterparticle = new G4DynamicParticle( G4MT_daughters[0], direction, Ekin, daughtermass[0]);
245  products->PushProducts(daughterparticle);
246  Ekin = std::sqrt(daughtermomentum*daughtermomentum + daughtermass[1]*daughtermass[1]) - daughtermass[1];
247  daughterparticle = new G4DynamicParticle( G4MT_daughters[1], -1.0*direction, Ekin, daughtermass[1]);
248  products->PushProducts(daughterparticle);
249 
250 #ifdef G4VERBOSE
251  if (GetVerboseLevel()>1) {
252  G4cout << "G4PhaseSpaceDecayChannel::TwoBodyDecayIt ";
253  G4cout << " create decay products in rest frame " <<G4endl;
254  products->DumpInfo();
255  }
256 #endif
257  return products;
258 }
G4double * G4MT_daughters_mass
G4int PushProducts(G4DynamicParticle *aParticle)
G4double givenDaughterMasses[MAX_N_DAUGHTERS]
G4ParticleDefinition * G4MT_parent
G4Cache< G4double > current_parent_mass
G4ParticleDefinition ** G4MT_daughters
value_type & Get() const
Definition: G4Cache.hh:282
G4double DynamicalMass(G4double massPDG, G4double width, G4double maxDev=+1.) const
const G4String & GetParticleName() const
#define G4UniformRand()
Definition: Randomize.hh:97
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
static const double twopi
Definition: G4SIunits.hh:75
static const double GeV
Definition: G4SIunits.hh:214
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
static const double rad
Definition: G4SIunits.hh:148
G4double * G4MT_daughters_width
void DumpInfo() const
#define G4endl
Definition: G4ios.hh:61
G4int GetVerboseLevel() const
double G4double
Definition: G4Types.hh:76
static G4double Pmx(G4double e, G4double p1, G4double p2)
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ current_parent_mass

G4Cache<G4double> G4PhaseSpaceDecayChannel::current_parent_mass
private

Definition at line 79 of file G4PhaseSpaceDecayChannel.hh.

◆ givenDaughterMasses

G4double G4PhaseSpaceDecayChannel::givenDaughterMasses[MAX_N_DAUGHTERS]
private

Definition at line 85 of file G4PhaseSpaceDecayChannel.hh.

◆ useGivenDaughterMass

G4bool G4PhaseSpaceDecayChannel::useGivenDaughterMass
private

Definition at line 84 of file G4PhaseSpaceDecayChannel.hh.


The documentation for this class was generated from the following files: