Import Geant4 0.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 15:09:25 +02:00
parent b97f8d0df7
commit aaa409b6ee
2922 changed files with 55107 additions and 81674 deletions
@@ -67,7 +67,7 @@ G4FragmentVector * G4Be8FermiFragment::GetFragment(const G4LorentzVector & aMome
// 2.0*G4NucleiPropertiesTable::GetMassExcess(2,4); // alphas
G4double AvalKineticE = sqrt(aMomentum.e()*aMomentum.e() -
aMomentum.vect().mag2()) -// Be8
2.0*AtomNum[0]; // alphas
2.0*Masses[0]; // alphas
RWTPtrOrderedVector<G4LorentzVector> * SubFragsMomentum =
@@ -40,7 +40,7 @@
// Constructor
//
G4ContinuumGammaDeexcitation::G4ContinuumGammaDeexcitation(): _Z(0), _A(0)
G4ContinuumGammaDeexcitation::G4ContinuumGammaDeexcitation(): _nucleusZ(0), _nucleusA(0)
{ }
@@ -55,11 +55,11 @@ G4VGammaTransition* G4ContinuumGammaDeexcitation::CreateTransition()
G4int A = nucleus.GetA();
G4double excitation = nucleus.GetExcitationEnergy();
if (_A != A || _Z != Z)
if (_nucleusA != A || _nucleusZ != Z)
{
_levelManager.SetNucleus(Z,A);
_A = A;
_Z = Z;
_nucleusA = A;
_nucleusZ = Z;
}
if (_verbose > 1)
@@ -21,6 +21,9 @@
//
// Modifications:
//
// 15 April 1999, Alessandro Brunengo (Alessandro.Brunengo@ge.infn.it)
// Added creation time evaluation for products of evaporation
//
// -------------------------------------------------------------------
//
// Class G4ContinuumGammaTransition.cc
@@ -34,25 +37,28 @@
// Constructor
//
G4ContinuumGammaTransition::G4ContinuumGammaTransition(const G4NuclearLevelManager& levelManager,
G4int Z, G4int A, G4double excitation,
G4int verbose):
_Z(Z), _A(A), _excitation(excitation), _levelManager(levelManager)
G4ContinuumGammaTransition::G4ContinuumGammaTransition(
const G4NuclearLevelManager& levelManager,
G4int Z, G4int A,
G4double excitation,
G4int verbose):
_nucleusZ(Z), _nucleusA(A), _excitation(excitation), _levelManager(levelManager)
{
const G4PtrLevelVector* levels = levelManager.GetLevels();
G4double eTolerance = 0.;
if (levels != 0)
{
G4int lastButOne = levelManager.NumberOfLevels() - 2;
if (lastButOne >= 0)
{
G4int lastButOne = levelManager.NumberOfLevels() - 2;
if (lastButOne >= 0)
{
eTolerance = levelManager.MaxLevelEnergy() - levels->at(lastButOne)->Energy();
if (eTolerance < 0.) eTolerance = 0.;
}
eTolerance = levelManager.MaxLevelEnergy() - levels->at(lastButOne)->Energy();
if (eTolerance < 0.) eTolerance = 0.;
}
}
_verbose = verbose;
_eGamma = 0.;
_gammaCreationTime = 0.;
_maxLevelE = levelManager.MaxLevelEnergy() + eTolerance;
_minLevelE = levelManager.MinLevelEnergy();
@@ -60,7 +66,7 @@ G4ContinuumGammaTransition::G4ContinuumGammaTransition(const G4NuclearLevelManag
// Energy range for photon generation; upper limit is defined 5*Gamma(GDR) from GDR peak
_eMin = 0.001 * MeV;
// Giant Dipole Resonance energy
G4double energyGDR = (40.3 / pow(_A,0.2) ) * MeV;
G4double energyGDR = (40.3 / pow(_nucleusA,0.2) ) * MeV;
// Giant Dipole Resonance width
G4double widthGDR = 0.30 * energyGDR;
// Extend
@@ -80,7 +86,7 @@ G4ContinuumGammaTransition::~G4ContinuumGammaTransition() {}
// Override GammaEnergy function from G4VGammaTransition
//
G4double G4ContinuumGammaTransition::GammaEnergy()
void G4ContinuumGammaTransition::SelectGamma()
{
_eGamma = 0.;
@@ -109,7 +115,8 @@ G4double G4ContinuumGammaTransition::GammaEnergy()
<< " finalExcitation = " << finalExcitation
<< " random = " << random << endl;
if (finalExcitation < 0)
// if (finalExcitation < 0)
if(finalExcitation < _minLevelE/2.)
{
_eGamma = _excitation;
finalExcitation = 0.;
@@ -122,15 +129,23 @@ G4double G4ContinuumGammaTransition::GammaEnergy()
_eGamma = _eGamma + diff;
}
return _eGamma;
_gammaCreationTime = GammaTime();
if(_verbose > 10)
G4cout << "*---*---* G4ContinuumTransition: _gammaCreationTime = "
<< _gammaCreationTime/second << endl;
return;
}
G4double G4ContinuumGammaTransition::GetEnergyTo() const
G4double G4ContinuumGammaTransition::GetGammaEnergy()
{
G4double excitation = _excitation - _eGamma;
if (excitation < 0.) excitation = 0.;
return excitation ;
return _eGamma;
}
G4double G4ContinuumGammaTransition::GetGammaCreationTime()
{
return _gammaCreationTime;
}
@@ -150,13 +165,13 @@ G4double G4ContinuumGammaTransition::E1Pdf(G4double e)
if( (_excitation - e) < 0.0 || e < 0 || _excitation < 0) return theProb;
G4ConstantLevelDensityParameter ldPar;
G4double aLevelDensityParam = ldPar.LevelDensityParameter(_A,_Z,_excitation);
G4double aLevelDensityParam = ldPar.LevelDensityParameter(_nucleusA,_nucleusZ,_excitation);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*_excitation));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(_excitation - e)));
if(_verbose > 20)
G4cout << _A << " LevelDensityParameter = " << aLevelDensityParam
G4cout << _nucleusA << " LevelDensityParameter = " << aLevelDensityParam
<< " Bef Aft " << levelDensBef << " " << levelDensAft << endl;
// Now form the probability density
@@ -164,10 +179,10 @@ G4double G4ContinuumGammaTransition::E1Pdf(G4double e)
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
// G4double sigma0 = 2.5 * _A * millibarn;
G4double sigma0 = 2.5 * _A;
// G4double sigma0 = 2.5 * _nucleusA * millibarn;
G4double sigma0 = 2.5 * _nucleusA;
G4double Egdp = (40.3 / pow(_A,0.2) )*MeV;
G4double Egdp = (40.3 / pow(_nucleusA,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / (pi * hbarc)*(pi * hbarc);
@@ -189,3 +204,41 @@ G4double G4ContinuumGammaTransition::E1Pdf(G4double e)
return theProb;
}
G4double G4ContinuumGammaTransition::GammaTime()
{
G4double GammaR = 0.30 * (40.3 / pow(_nucleusA,0.2) )*MeV;
G4double tau = hbar_Planck/GammaR;
G4double tMin = 0;
G4double tMax = 10.0 * tau;
G4int nBins = 200;
G4double sampleArray[200];
for(G4int i = 0;i<nBins;i++)
{
G4double t = tMin + ((tMax-tMin)/nBins)*i;
sampleArray[i] = (exp(-t/tau))/tau;
}
G4RandGeneralTmp randGeneral(sampleArray, nBins);
G4double random = randGeneral.shoot();
G4double creationTime = tMin + (tMax - tMin) * random;
return creationTime;
}
@@ -27,7 +27,7 @@
#include "G4NuclearLevelManager.hh"
G4DiscreteGammaDeexcitation::G4DiscreteGammaDeexcitation(): _Z(0),_A(0)
G4DiscreteGammaDeexcitation::G4DiscreteGammaDeexcitation(): _nucleusZ(0),_nucleusA(0)
{
_tolerance = 0.1 * MeV;
}
@@ -49,11 +49,11 @@ G4VGammaTransition* G4DiscreteGammaDeexcitation::CreateTransition()
<< "G4DiscreteGammaDeexcitation::CreateTransition - (A,Z) is valid "
<< endl;
if (_A != A || _Z != Z)
if (_nucleusA != A || _nucleusZ != Z)
{
_levelManager.SetNucleus(Z,A);
_A = A;
_Z = Z;
_nucleusA = A;
_nucleusZ = Z;
}
G4double excitation = nucleus.GetExcitationEnergy();
@@ -20,14 +20,18 @@
//
// Modifications:
//
// 15 April 1999, Alessandro Brunengo (Alessandro.Brunengo@ge.infn.it)
// Added creation time evaluation for products of evaporation
//
// -------------------------------------------------------------------
#include "G4DiscreteGammaTransition.hh"
#include "Randomize.hh"
#include "G4RandGeneralTmp.hh"
G4DiscreteGammaTransition::G4DiscreteGammaTransition(const G4NuclearLevel& level):
_level(level), _excitation(0.), _gammaEnergy(0.)
_level(level), _excitation(0.), _gammaEnergy(0.), _gammaCreationTime(0.)
{ }
@@ -35,52 +39,86 @@ G4DiscreteGammaTransition::~G4DiscreteGammaTransition()
{ }
G4double G4DiscreteGammaTransition::GammaEnergy()
void G4DiscreteGammaTransition::SelectGamma()
{
_gammaEnergy = 0.;
G4int nGammas = _level.NumberOfGammas();
if (nGammas > 0)
{
G4double random = G4UniformRand();
G4int iGamma = 0;
if (random <= _level.GammaCumulativeProbabilities().at(0)) iGamma = 0;
else
{
G4int i;
for (i=1; i<nGammas; i++)
{
if (random > _level.GammaCumulativeProbabilities().at(i-1) &&
random <= _level.GammaCumulativeProbabilities().at(i))
{ iGamma = i; }
}
}
G4int nGammas = _level.NumberOfGammas();
if (nGammas > 0)
{
G4double random = G4UniformRand();
// Small correction due to the fact that there are mismatches between
// nominal level energies and emitted gamma energies
G4double eCorrection = _level.Energy() - _excitation;
G4int iGamma = 0;
for(iGamma=0;iGamma < nGammas;iGamma++)
{
if(random <= _level.GammaCumulativeProbabilities().at(iGamma))
break;
}
_gammaEnergy = _level.GammaEnergies().at(iGamma) - eCorrection;
if (_gammaEnergy < 0.) _gammaEnergy = 0.;
}
// Small correction due to the fact that there are mismatches between
// nominal level energies and emitted gamma energies
G4double eCorrection = _level.Energy() - _excitation;
_gammaEnergy = _level.GammaEnergies().at(iGamma) - eCorrection;
// Warning: the following check is needed to avoid loops:
// Due essentially to missing nuclear levels in data files, it is
// possible that _gammaEnergy is so low as the nucleus doesn't change
// its level after the transition.
// When such case is found, force the full deexcitation of the nucleus.
//
// NOTE: you should force the transition to the next lower level,
// but this change needs a more complex revision of actual design.
// I leave this for a later revision.
if (_gammaEnergy < _level.Energy()*10e-5) _gammaEnergy = _excitation;
}
G4double tau = _level.HalfLife() / log(2.0);
G4double tMin = 0;
G4double tMax = 10.0 * tau;
G4int nBins = 200;
G4double sampleArray[200];
for(G4int i = 0;i<nBins;i++)
{
G4double t = tMin + ((tMax-tMin)/nBins)*i;
sampleArray[i] = (exp(-t/tau))/tau;
}
G4RandGeneralTmp randGeneral(sampleArray, nBins);
G4double random = randGeneral.shoot();
_gammaCreationTime = tMin + (tMax - tMin) * random;
// if(_verbose > 10)
// G4cout << "*---*---* G4DiscreteTransition: _gammaCreationTime = "
// << _gammaCreationTime/second << endl;
return;
}
G4double G4DiscreteGammaTransition::GetGammaEnergy()
{
return _gammaEnergy;
}
G4double G4DiscreteGammaTransition::GetEnergyTo() const
G4double G4DiscreteGammaTransition::GetGammaCreationTime()
{
G4double energyTo = _excitation - _gammaEnergy;
if (energyTo < 0.) energyTo = 0.;
return energyTo;
return _gammaCreationTime;
}
void G4DiscreteGammaTransition::SetEnergyFrom(const G4double energy)
{
_excitation = energy;
return;
}
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4DummyMF.cc,v 1.1 1998/08/22 08:53:45 hpw Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4DummyMF.cc,v 1.1 1999/01/07 16:11:50 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
@@ -96,7 +96,8 @@ void G4EvaporationChannel::Initialize(const G4Fragment & fragment)
// Coulomb Barrier calculation
CoulombBarrier = CalcCoulombBarrier(AResidual,ZResidual)*MeV;
// Binding Enegy (for separate fragment from nucleus)
BindingEnergy = CalcBindingEnergy(anA,aZ)*MeV;
@@ -145,6 +146,13 @@ G4FragmentVector * G4EvaporationChannel::BreakUp(const G4Fragment & theNucleus)
G4LorentzVector EvaporatedMomentum( momentum, EvaporatedEnergy );
EvaporatedMomentum.boost( theNucleus.GetMomentum().boostVector() );
// to avoid rounding errors in Lorentz boost which then produce
// evaporated fragments with excitation energies ~10^-10 eV
EvaporatedMomentum.setE(sqrt(EvaporatedMomentum.vect().mag2()+EvaporatedMass*EvaporatedMass));
G4Fragment * EvaporatedFragment = new G4Fragment( A, Z, EvaporatedMomentum );
if ( !EvaporatedFragment )
@@ -152,13 +160,15 @@ G4FragmentVector * G4EvaporationChannel::BreakUp(const G4Fragment & theNucleus)
G4LorentzVector FragmentMomentum( theNucleus.GetMomentum() );
FragmentMomentum.boost( -theNucleus.GetMomentum().boostVector() );
G4LorentzVector ResidualMomentum( -momentum, FragmentMomentum.e() - EvaporatedEnergy );
ResidualMomentum.boost( theNucleus.GetMomentum().boostVector() );
G4Fragment * ResidualFragment = new G4Fragment( AResidual, ZResidual, ResidualMomentum );
if ( !ResidualFragment )
G4Exception( "G4EvaporationChannel::BreakUp: Can't create G4Fragment! ");
G4Exception( "G4EvaporationChannel::BreakUp: Can't create G4Fragment! ");
G4FragmentVector * theResult = new G4FragmentVector;
@@ -186,6 +196,7 @@ G4double G4EvaporationChannel::CalcCoulombBarrier(const G4int ARes, const G4int
}
G4double G4EvaporationChannel::CalcBindingEnergy(const G4int anA, const G4int aZ)
// Calculate Binding Energy for separate fragment from nucleus
{
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ExcitationHandler.cc,v 1.12 1998/12/15 19:27:42 hpw Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4ExcitationHandler.cc,v 1.3 1999/05/28 17:14:41 hpw Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
@@ -72,7 +72,7 @@ G4bool G4ExcitationHandler::operator!=(const G4ExcitationHandler &right) const
}
G4DynamicParticleVector * G4ExcitationHandler::BreakItUp(const G4Fragment &theInitialState) const
G4ReactionProductVector * G4ExcitationHandler::BreakItUp(const G4Fragment &theInitialState) const
{
G4FragmentVector* theResult = 0;
@@ -84,7 +84,8 @@ G4DynamicParticleVector * G4ExcitationHandler::BreakItUp(const G4Fragment &theIn
// Initial State De-Excitation
if(A<GetMaxA()&&Z<GetMaxZ()) {
if(A<GetMaxA()&&Z<GetMaxZ()&&
exEnergy>G4NucleiPropertiesTable::GetBindingEnergy(Z,A)) {
theResult = theFermiModel->BreakItUp(theInitialState);
@@ -115,7 +116,8 @@ G4DynamicParticleVector * G4ExcitationHandler::BreakItUp(const G4Fragment &theIn
Z = theResult->at(i)->GetZ();
theExcitedNucleus = *(theResult->at(i));
// try to de-excite this fragment
if(A<GetMaxA()&&Z<GetMaxZ()) {
if(A<GetMaxA()&&Z<GetMaxZ()&&
exEnergy>G4NucleiPropertiesTable::GetBindingEnergy(Z,A)) {
theTempResult = theFermiModel->BreakItUp(theExcitedNucleus);
@@ -134,12 +136,13 @@ G4DynamicParticleVector * G4ExcitationHandler::BreakItUp(const G4Fragment &theIn
// If so :
// Remove excited fragment from the result
delete theResult->removeAt(i);
delete theResult->removeAt(i--);
// and add theTempResult elements to theResult
while (theTempResult->entries() > 0)
theResult->insert(theTempResult->removeFirst());
i--;
delete theTempResult;
} else { // If not :
// it doesn't matter, we Follow with the next fragment but
// I have to make
@@ -187,12 +190,12 @@ G4DynamicParticleVector * G4ExcitationHandler::BreakItUp(const G4Fragment &theIn
return Transform(theResult);
}
G4DynamicParticleVector *
G4ReactionProductVector *
G4ExcitationHandler::Transform(G4FragmentVector * theFragmentVector) const
{
if (theFragmentVector == 0) return 0;
// Conversion from G4FragmentVector to G4DynamicParticleVector
// Conversion from G4FragmentVector to G4ReactionProductVector
G4ParticleDefinition *theGamma = G4Gamma::GammaDefinition();
G4ParticleDefinition *theNeutron = G4Neutron::NeutronDefinition();
G4ParticleDefinition *theProton = G4Proton::ProtonDefinition();
@@ -202,7 +205,7 @@ G4ExcitationHandler::Transform(G4FragmentVector * theFragmentVector) const
G4ParticleDefinition *theAlpha = G4Alpha::AlphaDefinition();
G4ParticleDefinition *theKindOfFragment = 0;
theNeutron->SetVerboseLevel(2);
G4DynamicParticleVector * theDynamicParticleVector = new G4DynamicParticleVector;
G4ReactionProductVector * theReactionProductVector = new G4ReactionProductVector;
G4int theFragmentA, theFragmentZ;
G4LorentzVector theFragmentMomentum;
@@ -230,15 +233,20 @@ G4ExcitationHandler::Transform(G4FragmentVector * theFragmentVector) const
theKindOfFragment = theTableOfParticles->FindIon(theFragmentZ,theFragmentA,0,theFragmentZ);
}
if (theKindOfFragment != 0)
theDynamicParticleVector->insert(new G4DynamicParticle(theKindOfFragment,
theFragmentMomentum.vect()));
{
G4ReactionProduct * theNew = new G4ReactionProduct(theKindOfFragment);
theNew->SetMomentum(theFragmentMomentum.vect());
theNew->SetTotalEnergy(theFragmentMomentum.e());
theNew->SetFormationTime(theFragmentVector->at(i)->GetCreationTime());
theReactionProductVector->insert(theNew);
}
}
if (theFragmentVector != 0)
{
theFragmentVector->clearAndDestroy();
delete theFragmentVector;
}
return theDynamicParticleVector;
return theReactionProductVector;
}
@@ -47,39 +47,41 @@ G4bool G4FermiBreakUp::operator!=(const G4FermiBreakUp &right) const
G4FragmentVector * G4FermiBreakUp::BreakItUp(const G4Fragment &theNucleus)
{
// CHECK that Excitation Energy != 0
if (theNucleus.GetExcitationEnergy() == 0) {
G4FragmentVector * theResult = new G4FragmentVector;
theResult->insert(new G4Fragment(theNucleus));
return theResult;
}
// CHECK that Excitation Energy > 0
if (theNucleus.GetExcitationEnergy() <= theNucleus.GetBindingEnergy()) {
G4FragmentVector * theResult = new G4FragmentVector;
theResult->insert(new G4Fragment(theNucleus));
return theResult;
}
// Total energy of nucleus in nucleus rest frame (MeV)
G4double TotalEnergyRF = theNucleus.GetExcitationEnergy()/MeV +
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(theNucleus.GetZ(),theNucleus.GetA())/MeV;
// Total energy of nucleus in nucleus rest frame
G4double TotalEnergyRF = theNucleus.GetExcitationEnergy() +
G4ParticleTable::GetParticleTable()->GetIonTable()->
GetIonMass(theNucleus.GetZ(),theNucleus.GetA());
G4FermiConfigurationList theConfigurationList;
G4FermiConfigurationList theConfigurationList;
// Split the nucleus
G4bool Split = theConfigurationList.Initialize(theNucleus.GetA(), theNucleus.GetZ(),
TotalEnergyRF);
if ( !Split ) {
G4FragmentVector * theResult = new G4FragmentVector;
theResult->insert(new G4Fragment(theNucleus));
// Split the nucleus
G4bool Split = theConfigurationList.Initialize(theNucleus.GetA(),
theNucleus.GetZ(),
TotalEnergyRF);
if ( !Split ) {
G4FragmentVector * theResult = new G4FragmentVector;
theResult->insert(new G4Fragment(theNucleus));
return theResult;
}
return theResult;
}
// Chose a configuration
G4FermiConfiguration theConfiguration(theConfigurationList.ChooseConfiguration());
// Chose a configuration
G4FermiConfiguration theConfiguration(theConfigurationList.ChooseConfiguration());
// Get the fragments corresponding to chosen configuration.
G4FragmentVector * theResult = theConfiguration.GetFragments(theNucleus);
return theResult;
// Get the fragments corresponding to chosen configuration.
G4FragmentVector * theResult = theConfiguration.GetFragments(theNucleus);
return theResult;
}
@@ -8,15 +8,21 @@
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
// V. Lara (Apr 1999)
// Corrected a bug in calculation of probabilities found by N. Ameline
//
#include "G4FermiConfiguration.hh"
// Kappa = V/V_0 it is used in calculation of Coulomb energy
// Kappa is adimensional
const G4double G4FermiConfiguration::Kappa = 1.0;
// r0 is the nuclear radius
const G4double G4FermiConfiguration::r0 = 1.3*fermi;
// A Z Pol ExcitE
// A Z Pol ExcitE
G4StableFermiFragment G4FermiConfiguration::Fragment00( 1, 0, 2, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment01( 1, 1, 2, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment02( 2, 1, 3, 0.00*keV );
@@ -358,19 +364,20 @@ G4bool G4FermiConfiguration::SplitNucleus(const G4int A, const G4int Z)
G4double G4FermiConfiguration::CoulombBarrier(void)
{
// Calculates Coulomb Barrier (MeV) for given channel with K fragments.
const G4double Coef = ((3. * 1.44) / (5. * 1.3)) * pow(1./(1.+Kappa), 1./3.);
G4double SumA = 0, SumZ = 0;
G4double CoulombEnergy = 0.;
for (G4int i = 0; i < Index.entries(); i++) {
G4double z = theListOfFragments[Index[i]-1]->GetZ();
G4double a = theListOfFragments[Index[i]-1]->GetA();
CoulombEnergy += (z*z) / pow(a, 1./3.);
SumA += a;
SumZ += z;
}
CoulombEnergy -= SumZ*SumZ/pow(SumA, 1./3.);
return -Coef * CoulombEnergy;
// Calculates Coulomb Barrier (MeV) for given channel with K fragments.
const G4double Coef = (3./5.)*1.44*MeV*fermi* pow(1./(1.+Kappa), 1./3.)/r0;
G4double SumA = 0, SumZ = 0;
G4double CoulombEnergy = 0.;
for (G4int i = 0; i < Index.entries(); i++) {
G4double z = theListOfFragments[Index[i]-1]->GetZ();
G4double a = theListOfFragments[Index[i]-1]->GetA();
CoulombEnergy += (z*z) / pow(a, 1./3.);
SumA += a;
SumZ += z;
}
CoulombEnergy -= SumZ*SumZ/pow(SumA, 1./3.);
return -Coef * CoulombEnergy;
}
@@ -380,57 +387,66 @@ G4double G4FermiConfiguration::DecayProbability(const G4int A, const G4double To
// Decay probability for a given channel with K fragments
{
// A: Atomic Weight
// TotalE: Total energy of nucleus (MeV)
// TotalE: Total energy of nucleus (MeV)
G4int K = Index.entries();
G4int i;
const G4double VAK = (1.3/(0.21*sqrt(0.94)))*(1.3/(0.21*sqrt(0.94)))*(1.3/(0.21*sqrt(0.94)))*
Kappa*sqrt(2.0/pi)/3.0;
G4int K = Index.entries();
G4int i;
G4double * GAF = new G4double[K];
GAF[0] = 0.0;
GAF[1] = 1.0/sqrt(pi);
for (i = 2; i < K; i++) {
G4double qk = 1./(1.5*i-2.5);
G4double gq = 1. + qk*(1./12. + qk*(1./288. - qk*(139./51840.)));
GAF[i] = sqrt(0.1591549*qk)/gq;
}
const G4double NucleonMass = 938.0*MeV;
const G4double DimCoeff = pow(r0*sqrt(NucleonMass)/hbarc,3.0)*Kappa*sqrt(2.0/pi)/3.0;
G4double DeltaEnergy = TotalE; // MeV
G4double Weight = 0.;
G4double ProdAMass = 1.;
G4double ProdSpin = 1.;
// Calculation of 1/Gamma(3(n-1)/2)
G4double InvGammaFunc = 1.0;
if (K <= 1) InvGammaFunc = 0.0;
else {
G4double arg = 3.0*(K-1)/2.0 - 1.0;
while (arg > 1.1) {
InvGammaFunc *= arg;
arg--;
}
if ((K-1)%2 == 1) InvGammaFunc *= sqrt(pi)/2.0;
InvGammaFunc = 1.0/InvGammaFunc;
}
G4double DeltaEnergy = TotalE; // MeV
G4double Weight = 0.;
G4double ProdAMass = 1.;
G4double ProdSpin = 1.;
for (i = 0; i<K; i++) {
ProdAMass *= theListOfFragments[Index[i]-1]->GetA();
ProdSpin *= theListOfFragments[Index[i]-1]->GetPolarization();
DeltaEnergy -= (theListOfFragments[Index[i]-1]->GetFragmentMass()/MeV +
theListOfFragments[Index[i]-1]->GetExcitationEnergy()/MeV);
};
if ((DeltaEnergy -= CoulombBarrier()) <= 0.0) {
delete [] GAF;
return Weight;
}
ProdAMass /= A;
ProdAMass *= sqrt(ProdAMass)*ProdSpin;
for (i = 0; i<K; i++) {
ProdAMass *= theListOfFragments[Index[i]-1]->GetA();
// Spin factor S_n
ProdSpin *= theListOfFragments[Index[i]-1]->GetPolarization();
DeltaEnergy -= theListOfFragments[Index[i]-1]->GetFragmentMass() +
theListOfFragments[Index[i]-1]->GetExcitationEnergy();
};
if (K <= 2) {
Weight = 1.1283792*A*Kappa*ProdAMass*sqrt(DeltaEnergy);
if (Index[0] == Index[1]) Weight *= 0.5;
} else {
DeltaEnergy *= 2.71828183/(1.5*K-2.5);
G4double VTK = A*Kappa*DeltaEnergy*sqrt(DeltaEnergy);
G4double VMK = 1.0, RPM= 1.0;
for (G4int i = 0; i < K-1; i++) {
VMK *= VTK;
G4int MRS = 1;
for (G4int j = i+1; j<K; j++) if(Index[i] == Index[j]) MRS++;
RPM *= MRS;
};
Weight = VMK*ProdAMass*GAF[K-1]/(DeltaEnergy*RPM);
}
delete [] GAF;
return Weight;
// Check that there is enough energy to produce K fragments
if ((DeltaEnergy -= CoulombBarrier()) <= 0.0) return Weight; // return 0.0
ProdAMass /= A;
ProdAMass *= sqrt(ProdAMass);
if (K <= 2) {
Weight = InvGammaFunc*A*DimCoeff*ProdAMass*ProdSpin*sqrt(DeltaEnergy);
if (Index[0] == Index[1]) Weight *= 0.5; //Permutation factor G_n
} else {
G4double Base = A*DimCoeff*DeltaEnergy*sqrt(DeltaEnergy);
G4double Powered = 1.0;
G4double PermutationFactor = 1.0;
for (G4int i = 0; i < K-1; i++) {
Powered *= Base;
G4int N = 1;
for (G4int j = i+1; j<K; j++) if(Index[i] == Index[j]) N++;
PermutationFactor *= N;
};
Weight = Powered*ProdAMass*ProdSpin*InvGammaFunc/(DeltaEnergy*PermutationFactor);
}
return Weight;
}
@@ -440,17 +456,17 @@ G4FragmentVector * G4FermiConfiguration::GetFragments(const G4Fragment & theNucl
G4int K = Index.entries();
// Avalaible kinetic energy of system.
G4double AvalKineticEnergy = theNucleus.GetExcitationEnergy()/MeV +
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(theNucleus.GetZ(),theNucleus.GetA())/MeV;
G4double AvalKineticEnergy = theNucleus.GetExcitationEnergy() +
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(theNucleus.GetZ(),theNucleus.GetA());
G4int i;
for (i = 0; i < K; i++)
AvalKineticEnergy -= theListOfFragments[Index[i]-1]->GetFragmentMass()/MeV;
AvalKineticEnergy -= theListOfFragments[Index[i]-1]->GetFragmentMass();
// Calculate Momenta of K fragments
RWTPtrOrderedVector<G4LorentzVector>* MomentumComponents =
FragmentsMomentum(AvalKineticEnergy*MeV);
FragmentsMomentum(AvalKineticEnergy);
G4FragmentVector * theResult = new G4FragmentVector;
@@ -550,19 +566,19 @@ G4FermiConfiguration::FragmentsMomentum(G4double KineticEnergy)
G4double G4FermiConfiguration::RNKSI(const G4int K)
{
G4double csim = (3.0*K-5.0)/(3.0*K-4.0);
G4double pex = 1.5*K-2.5;
G4double fcsim = sqrt(1.0-csim)*pow(csim,pex);
G4double csim = (3.0*K-5.0)/(3.0*K-4.0);
G4double pex = (3.0*K-5.0)/2.0;
G4double fcsim = sqrt(1.0-csim)*pow(csim,pex);
G4double csi = 0.0;
G4double fcsi= 0.0;
G4double rf = 0.0;
do {
csi = G4UniformRand();
fcsi = sqrt(1.0-csi)*pow(csi,pex);
rf = fcsim*G4UniformRand();
} while (rf > fcsi);
return csi;
G4double csi = 0.0;
G4double fcsi= 0.0;
G4double rf = 0.0;
do {
csi = G4UniformRand();
fcsi = sqrt(1.0-csi)*pow(csi,pex);
rf = fcsim*G4UniformRand();
} while (rf > fcsi);
return csi;
}
G4ParticleMomentum G4FermiConfiguration::IsotropicVector(const G4double Magnitude)
@@ -49,45 +49,43 @@ G4bool G4FermiConfigurationList::Initialize(const G4int A, const G4int Z, const
//
// let's split nucleus into k = 2,...,6 fragments
//
Configurations.clear();
NormalizedWeights.clear();
G4FermiConfiguration aConfiguration;
RWTValOrderedVector<G4double> NOTNormalizedWeights;
G4double NormStatWeight = 0.0;
for (G4int k = 2; k <= 6; k++) {
// Initialize Configuration for k fragments
aConfiguration.Initialize(k);
G4bool SplitSuccesed;
do {
// Splits the nucleus into k fragments
SplitSuccesed = aConfiguration.SplitNucleus(A,Z);
if (SplitSuccesed) {
TotNumOfConfigurations++;
NumOfConfigurations[k-1]++;
Configurations.clear();
NormalizedWeights.clear();
G4FermiConfiguration aConfiguration;
RWTValOrderedVector<G4double> NOTNormalizedWeights;
G4double NormStatWeight = 0.0;
for (G4int k = 2; k <= 6; k++) {
// Initialize Configuration for k fragments
aConfiguration.Initialize(k);
G4bool SplitSuccesed;
do {
// Splits the nucleus into k fragments
SplitSuccesed = aConfiguration.SplitNucleus(A,Z);
if (SplitSuccesed) {
TotNumOfConfigurations++;
NumOfConfigurations[k-1]++;
// Non-Normalized statistical weight (decay probavility) for given channel with k fragments
// Decay probability returns very big numbers--> I put a temporal scale factor 10^-6
G4double StatWeight = aConfiguration.DecayProbability(A,TotalEnergyRF)*1.0e-6;
NormStatWeight += StatWeight;
// Statistical weights (it will be normalized...)
NOTNormalizedWeights.insert(StatWeight);
// Non-Normalized statistical weight for given channel with k fragments
G4double StatWeight = aConfiguration.DecayProbability(A,TotalEnergyRF);
NormStatWeight += StatWeight;
// Statistical weights (it will be normalized...)
NOTNormalizedWeights.insert(StatWeight);
G4int NumeroDeConf = Configurations.entries();
// Store configuration
Configurations.insert(aConfiguration);
}
// Repeat splitting into k fragments (it may be several posibilities for a choosen K)
} while (SplitSuccesed);
}
// Store configuration
Configurations.insert(aConfiguration);
}
// Repeat splitting into k fragments (it may be several posibilities for a choosen K)
} while (SplitSuccesed);
}
if (NormStatWeight > 0.0) {
// Let's normalize statistical weights of channels
for (G4int i = 0; i < TotNumOfConfigurations; i++)
NormalizedWeights.insert(NOTNormalizedWeights(i)/NormStatWeight);
if (NormStatWeight > 0.0) {
// Let's normalize statistical weights of channels
for (G4int i = 0; i < TotNumOfConfigurations; i++)
NormalizedWeights.insert(NOTNormalizedWeights(i)/NormStatWeight);
return true;
}
else return false;
return true;
}
else return false;
}
@@ -95,14 +93,14 @@ G4bool G4FermiConfigurationList::Initialize(const G4int A, const G4int Z, const
G4FermiConfiguration G4FermiConfigurationList::ChooseConfiguration(void)
{
G4double RandomWeight = G4UniformRand();
G4double AcumWeight = 0.0;
G4int thisConfig = 0;
do {
AcumWeight += NormalizedWeights(thisConfig); // We are adding the prob. of each configuration
thisConfig++;
} while ((thisConfig <= TotNumOfConfigurations) && (AcumWeight < RandomWeight));
G4double RandomWeight = G4UniformRand();
G4double AcumWeight = 0.0;
G4int thisConfig = 0;
do {
AcumWeight += NormalizedWeights(thisConfig); // We are adding the prob. of each configuration
thisConfig++;
} while ((thisConfig <= TotNumOfConfigurations) && (AcumWeight < RandomWeight));
return Configurations(thisConfig - 1);
return Configurations(thisConfig - 1);
}
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4FissionBarrier.cc,v 1.1 1998/10/15 07:56:56 larazb Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4FissionBarrier.cc,v 1.1 1999/01/07 16:11:54 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4MultiFragmentation.cc,v 1.1 1998/08/22 08:53:49 hpw Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4MultiFragmentation.cc,v 1.1 1999/01/07 16:11:55 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
@@ -20,21 +20,31 @@
//
// Modifications:
//
// 15 April 1999, Alessandro Brunengo (Alessandro.Brunengo@ge.infn.it)
// Added half-life, angular momentum, parity, emissioni type
// reading from experimental data.
//
// -------------------------------------------------------------------
#include "G4NuclearLevel.hh"
#include "globals.hh"
G4NuclearLevel::G4NuclearLevel(const G4double energy,
const G4DataVector& eGamma, const G4DataVector& wGamma)
G4NuclearLevel::G4NuclearLevel(const G4double energy, const G4double halfLife,
const G4double angularMomentum,
const G4DataVector& eGamma,
const G4DataVector& wGamma,
const G4DataVector& polarities)
{
_energy = energy;
_halfLife = halfLife;
_angularMomentum = angularMomentum;
G4int i;
for (i=0; i<eGamma.entries(); i++)
{
_energies.insert(eGamma.at(i));
_weights.insert(wGamma.at(i));
_polarities.insert(polarities.at(i));
}
_nGammas = _energies.entries();
MakeProbabilities();
@@ -87,11 +97,26 @@ const G4DataVector& G4NuclearLevel::GammaCumulativeProbabilities() const
}
const G4DataVector& G4NuclearLevel::GammaPolarities() const
{
return _polarities;
}
G4double G4NuclearLevel::Energy() const
{
return _energy;
}
G4double G4NuclearLevel::AngularMomentum() const
{
return _angularMomentum;
}
G4double G4NuclearLevel::HalfLife() const
{
return _halfLife;
}
G4int G4NuclearLevel::NumberOfGammas() const
{
@@ -101,7 +126,9 @@ G4int G4NuclearLevel::NumberOfGammas() const
void G4NuclearLevel::PrintAll() const
{
G4cout << "---- Level energy = " << _energy << ", " << _nGammas << " photons" << endl;
G4cout << "---- Level energy = " << _energy << ", angular momentum = "
<< _angularMomentum << ", half life " << _halfLife
<< ", " << _nGammas << " photons" << endl;
G4int i;
G4cout << " Gammas: ";
for (i=0; i<_nGammas; i++) { G4cout << _energies.at(i) << " "; }
@@ -111,6 +138,8 @@ void G4NuclearLevel::PrintAll() const
for (i=0; i<_nGammas; i++) { G4cout << _prob.at(i) << " "; }
G4cout << endl << " Cumulative probabilities: ";
for (i=0; i<_nGammas; i++) { G4cout << _cumProb.at(i) << " "; }
G4cout << endl << " Polarities: ";
for (i=0; i<_nGammas; i++) { G4cout << _polarities.at(i) << " "; }
G4cout << endl;
return;
@@ -20,6 +20,10 @@
//
// Modifications:
//
// 15 April 1999, Alessandro Brunengo (Alessandro.Brunengo@ge.infn.it)
// Added half-life, angular momentum, parity, emissioni type
// reading from experimental data.
//
// -------------------------------------------------------------------
#include "G4NuclearLevelManager.hh"
@@ -29,13 +33,17 @@
#include "G4ios.hh"
#include <stdlib.h>
#include <fstream.h>
#ifdef WIN32
#include <strstrea.h>
#else
#include <strstream.h>
#endif
G4NuclearLevelManager::G4NuclearLevelManager():
_A(0), _Z(0), _levels(0), _levelEnergy(0), _gammaEnergy(0), _probability(0)
_nucleusA(0), _nucleusZ(0), _levels(0), _levelEnergy(0), _gammaEnergy(0), _probability(0)
{ }
G4NuclearLevelManager::G4NuclearLevelManager(G4int Z, G4int A): _Z(Z), _A(A)
G4NuclearLevelManager::G4NuclearLevelManager(G4int Z, G4int A): _nucleusZ(Z), _nucleusA(A)
{
@@ -59,10 +67,10 @@ G4NuclearLevelManager::~G4NuclearLevelManager()
void G4NuclearLevelManager::SetNucleus(G4int Z, G4int A)
{
if (_Z != Z || _A != A)
if (_nucleusZ != Z || _nucleusA != A)
{
_A = A;
_Z = Z;
_nucleusA = A;
_nucleusZ = Z;
MakeLevels();
}
@@ -74,15 +82,18 @@ G4bool G4NuclearLevelManager::IsValid(G4int Z, G4int A) const
if (A < 0 || Z < 0 || A < Z) valid = false;
G4String dirName = getenv("G4LEVELGAMMADATA");
char* env = getenv("G4LEVELGAMMADATA");
if (env == 0)
G4Exception("G4NuclearLevelManager - Please set the G4LEVELGAMMADATA environment variable");
G4String dirName(env);
char name[100] = {""};
ostrstream ost(name, 100, ios::out);
ost << dirName << "/" << "z" << Z << ".a" << A;
G4String file(name);
ifstream inFile(file);
if (! inFile) valid = false;
return valid;
}
@@ -171,9 +182,11 @@ G4bool G4NuclearLevelManager::Read(ifstream& dataFile)
if (dataFile >> _levelEnergy)
{
dataFile >> _gammaEnergy >> _probability;
dataFile >> _gammaEnergy >> _probability >> _polarity >> _halfLife
>> _angularMomentum;
_levelEnergy *= keV;
_gammaEnergy *= keV;
_halfLife *= second;
// The following adjustment is needed to take care of anomalies in
// data files, where some transitions show up with relative probability
@@ -193,17 +206,20 @@ G4bool G4NuclearLevelManager::Read(ifstream& dataFile)
void G4NuclearLevelManager::MakeLevels()
{
G4String dirName = getenv("G4LEVELGAMMADATA");
char* env = getenv("G4LEVELGAMMADATA");
if (env == 0)
G4Exception("G4NuclearLevelManager: please set the G4LEVELGAMMADATA environment variable");
G4String dirName(env);
char name[100] = {""};
ostrstream ost(name, 100, ios::out);
ost << dirName << "/" << "z" << _Z << ".a" << _A;
ost << dirName << "/" << "z" << _nucleusZ << ".a" << _nucleusA;
G4String file(name);
ifstream inFile(file, ios::in);
if (! inFile)
{
// G4cout << " G4NuclearLevelManager: (" << _Z << "," << _A
// G4cout << " G4NuclearLevelManager: (" << _nucleusZ << "," << _nucleusA
// << ") does not have LevelsAndGammas file" << endl;
return;
}
@@ -219,12 +235,18 @@ void G4NuclearLevelManager::MakeLevels()
G4DataVector eLevel;
G4DataVector eGamma;
G4DataVector wGamma;
G4DataVector pGamma; // polarity
G4DataVector hLevel; // half life
G4DataVector aLevel; // angular momentum
while (Read(inFile))
{
eLevel.insert(_levelEnergy);
eGamma.insert(_gammaEnergy);
wGamma.insert(_probability);
pGamma.insert(_polarity);
hLevel.insert(_halfLife);
aLevel.insert(_angularMomentum);
}
// ---- MGP ---- Don't forget to close the file
@@ -235,8 +257,11 @@ void G4NuclearLevelManager::MakeLevels()
// G4cout << " ==== MakeLevels ===== " << nData << " data read " << endl;
G4double thisLevelEnergy = eLevel.at(0);
G4double thisLevelHalfLife = 0.;
G4double thisLevelAngMom = 0.;
G4DataVector thisLevelEnergies;
G4DataVector thisLevelWeights;
G4DataVector thisLevelPolarities;
G4double e = -1.;
G4int i;
@@ -244,26 +269,39 @@ void G4NuclearLevelManager::MakeLevels()
{
e = eLevel.at(i);
if (e != thisLevelEnergy)
{
// G4cout << "Making a new level... " << e << " "
// << thisLevelEnergies.entries() << " "
// << thisLevelWeights.entries() << endl;
G4NuclearLevel* newLevel = new G4NuclearLevel(thisLevelEnergy,thisLevelEnergies,thisLevelWeights);
{
// G4cout << "Making a new level... " << e << " "
// << thisLevelEnergies.entries() << " "
// << thisLevelWeights.entries() << endl;
G4NuclearLevel* newLevel = new G4NuclearLevel(thisLevelEnergy,
thisLevelHalfLife,
thisLevelAngMom,
thisLevelEnergies,
thisLevelWeights,
thisLevelPolarities);
_levels->insert(newLevel);
// Reset data vectors
thisLevelEnergies.clear();
thisLevelWeights.clear();
thisLevelPolarities.clear();
thisLevelEnergy = e;
}
// Append current data
thisLevelEnergies.insert(eGamma.at(i));
thisLevelWeights.insert(wGamma.at(i));
thisLevelPolarities.insert(pGamma.at(i));
thisLevelHalfLife = hLevel.at(i);
thisLevelAngMom = aLevel.at(i);
}
// Make last level
if (e > 0.)
{
G4NuclearLevel* newLevel = new G4NuclearLevel(e,thisLevelEnergies,thisLevelWeights);
G4NuclearLevel* newLevel = new G4NuclearLevel(e,thisLevelHalfLife,
thisLevelAngMom,
thisLevelEnergies,
thisLevelWeights,
thisLevelPolarities);
_levels->insert(newLevel);
}
@@ -276,10 +314,11 @@ void G4NuclearLevelManager::PrintAll()
G4int nLevels = 0;
if (_levels != 0) nLevels = _levels->entries();
G4cout << " ==== G4NuclearLevelManager ==== (" << _Z << ", " << _A << ") has "
<< nLevels << " levels" << endl
<< "Highest level is at energy " << MaxLevelEnergy() << " MeV " << endl
<< "Lowest level is at energy " << MinLevelEnergy() << " MeV " << endl;
G4cout << " ==== G4NuclearLevelManager ==== (" << _nucleusZ << ", " << _nucleusA
<< ") has " << nLevels << " levels" << endl
<< "Highest level is at energy " << MaxLevelEnergy() << " MeV "
<< endl << "Lowest level is at energy " << MinLevelEnergy()
<< " MeV " << endl;
G4int i = 0;
for (i=0; i<nLevels; i++)
@@ -292,8 +331,11 @@ G4NuclearLevelManager::G4NuclearLevelManager(const G4NuclearLevelManager &right)
_levelEnergy = right._levelEnergy;
_gammaEnergy = right._gammaEnergy;
_probability = right._probability;
_A = right._A;
_Z = right._Z;
_polarity = right._polarity;
_halfLife = right._halfLife;
_angularMomentum = right._angularMomentum;
_nucleusA = right._nucleusA;
_nucleusZ = right._nucleusZ;
if (right._levels != 0)
{
_levels = new G4PtrLevelVector;
@@ -309,3 +351,12 @@ G4NuclearLevelManager::G4NuclearLevelManager(const G4NuclearLevelManager &right)
_levels = 0;
}
}
@@ -1,4 +1,4 @@
// $Id: G4StatMFMicrocanonical.cc,v 1.3 1998/11/12 16:19:51 allison Exp $
// $Id: G4StatMFMicrocanonical.cc,v 1.1 1999/01/07 16:11:57 gunter Exp $
#include "G4StatMFMicrocanonical.hh"
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VFissionBarrier.cc,v 1.1 1998/10/15 07:58:35 larazb Exp $
// GEANT4 tag $Name: geant4-00 $
// $Id: G4VFissionBarrier.cc,v 1.1 1999/01/07 16:11:59 gunter Exp $
// GEANT4 tag $Name: geant4-00-01 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
@@ -20,6 +20,10 @@
//
// Modifications:
//
// 15 April 1999, Alessandro Brunengo (Alessandro.Brunengo@ge.infn.it)
// Added creation time evaluation for products of evaporation
//
//
// -------------------------------------------------------------------
#include "G4VGammaDeexcitation.hh"
@@ -32,6 +36,8 @@
#include "G4Fragment.hh"
#include "G4FragmentVector.hh"
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
G4VGammaDeexcitation::G4VGammaDeexcitation(): _verbose(0), _transition(0)
{ }
@@ -57,7 +63,7 @@ G4FragmentVector* G4VGammaDeexcitation::DoTransition()
{
products->append(gamma);
UpdateNucleus(gamma);
Update(gamma);
Update();
}
}
@@ -84,7 +90,7 @@ G4FragmentVector* G4VGammaDeexcitation::DoChain()
products->append(gamma);
UpdateNucleus(gamma);
}
Update(gamma);
Update();
}
if (_verbose > 1)
@@ -112,39 +118,49 @@ G4Fragment* G4VGammaDeexcitation::GenerateGamma()
{
G4double eGamma = 0.;
if (_transition != 0) eGamma = _transition->GammaEnergy();
if (_transition != 0)
{
_transition->SelectGamma();
eGamma = _transition->GetGammaEnergy();
}
if (_verbose > 1 && _transition != 0)
{
G4cout << "G4VGammaDeexcitation::GenerateGamma - Gamma energy " << eGamma
<< " ** New excitation " << _transition->GetEnergyTo() << endl;
}
{
G4cout << "G4VGammaDeexcitation::GenerateGamma - Gamma energy " << eGamma
<< " ** New excitation " << _nucleus.GetExcitationEnergy() - eGamma
<< endl;
}
// Photon momentum isotropically generated
if (eGamma > 0.)
{
G4double cosTheta = 1. - 2. * G4UniformRand();
G4double sinTheta = sqrt(1. - cosTheta * cosTheta);
G4double phi = twopi * G4UniformRand();
if (eGamma > 0.)
{
G4double cosTheta = 1. - 2. * G4UniformRand();
G4double sinTheta = sqrt(1. - cosTheta * cosTheta);
G4double phi = twopi * G4UniformRand();
G4ThreeVector pGamma( eGamma * sinTheta * cos(phi),
eGamma * sinTheta * sin(phi),
eGamma * cosTheta );
G4LorentzVector gamma(pGamma, eGamma);
// gamma.boost(_nucleus.GetMomentum().boostVector() );
G4Fragment* gammaFragment = new G4Fragment(gamma,G4Gamma::GammaDefinition());
G4ThreeVector pGamma( eGamma * sinTheta * cos(phi),
eGamma * sinTheta * sin(phi),
eGamma * cosTheta );
if (_verbose > 1)
G4cout << "G4VGammaDeexcitation::GenerateGamma - Gamma fragment generated " << endl;
G4LorentzVector gamma(pGamma, eGamma);
// gamma.boost(_nucleus.GetMomentum().boostVector() );
G4Fragment* gammaFragment = new
G4Fragment(gamma,G4Gamma::GammaDefinition());
return gammaFragment;
}
else
{
return 0;
}
G4double gammaTime = _transition->GetGammaCreationTime();
gammaTime += _nucleus.GetCreationTime();
gammaFragment->SetCreationTime(gammaTime);
if (_verbose > 1)
G4cout << "G4VGammaDeexcitation::GenerateGamma - Gamma fragment generated " << endl;
return gammaFragment;
}
else
{
return 0;
}
}
@@ -157,26 +173,45 @@ void G4VGammaDeexcitation::UpdateNucleus(const G4Fragment* gamma)
G4LorentzVector p4Nucleus(_nucleus.GetMomentum() );
// p4Nucleus.boost(-_nucleus.GetMomentum().boostVector() );
G4LorentzVector p4Residual(p4Nucleus - pGamma, p4Nucleus.e() - eGamma);
// G4LorentzVector p4Residual(p4Nucleus - pGamma, p4Nucleus.e() - eGamma);
//
// Due to a rounding error calculation in G4Fragment excitation energy,
// we must correct p4Residual.e() when we are near to 0.
//
// New tetravector calculation:
G4double Mass = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(_nucleus.GetZ(),_nucleus.GetA());
G4double newExcitation = p4Nucleus.mag() - Mass - eGamma;
if(newExcitation < 0)
newExcitation = 0;
G4ThreeVector p3Residual(p4Nucleus - pGamma);
G4double newEnergy = sqrt(p3Residual * p3Residual +
(Mass + newExcitation) * (Mass + newExcitation));
G4LorentzVector p4Residual(p3Residual, newEnergy);
// G4LorentzVector p4Residual(-pGamma, p4Nucleus.e() - eGamma);
// p4Residual.boost( _nucleus.GetMomentum().boostVector() );
// Update excited nucleus parameters
_nucleus.SetMomentum(p4Residual);
_nucleus.SetCreationTime(gamma->GetCreationTime());
if (_transition != 0)
{
G4double excitation =_transition->GetEnergyTo();
if (excitation < 0.) excitation = 0.0;
_nucleus.SetExcitationEnergy(excitation);
}
// if (_transition != 0)
// {
// G4double excitation =_transition->GetEnergyTo();
// if (excitation < 0.) excitation = 0.0;
// _nucleus.SetExcitationEnergy(excitation);
// }
return;
}
void G4VGammaDeexcitation::Update(const G4Fragment* gamma)
void G4VGammaDeexcitation::Update()
{
if (_transition != 0)
{
@@ -212,3 +247,8 @@ void G4VGammaDeexcitation::SetVerboseLevel(G4int verbose)