Import Geant4 0.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-01 15:25:35 +02:00
parent 54d6b71f95
commit b97f8d0df7
3237 changed files with 807095 additions and 0 deletions
@@ -0,0 +1,96 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4B9FermiFragment.hh"
G4B9FermiFragment::G4B9FermiFragment()
{
}
G4B9FermiFragment::G4B9FermiFragment(const G4B9FermiFragment &right)
{
G4Exception("G4B9FermiFragment::copy_constructor meant to not be accessable");
}
G4B9FermiFragment::~G4B9FermiFragment()
{
}
const G4B9FermiFragment & G4B9FermiFragment::operator=(const G4B9FermiFragment &right)
{
G4Exception("G4B9FermiFragment::operator= meant to not be accessable");
return *this;
}
G4bool G4B9FermiFragment::operator==(const G4B9FermiFragment &right) const
{
return false;
}
G4bool G4B9FermiFragment::operator!=(const G4B9FermiFragment &right) const
{
return true;
}
G4FragmentVector * G4B9FermiFragment::GetFragment(const G4LorentzVector & aMomentum)
// B9 ----> alpha + alpha + proton
{
const G4int NumSubFrag = 3;
G4double Masses[NumSubFrag];
G4double Charges[NumSubFrag];
G4double AtomNum[NumSubFrag];
Masses[0] = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(2,4); // alpha
Masses[1] = Masses[0]; // alpha
Masses[2] = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1); // proton
AtomNum[0] = 4;
AtomNum[1] = 4;
AtomNum[2] = 1;
Charges[0] = 2;
Charges[1] = 2;
Charges[2] = 1;
// G4double AvalKineticE = G4NucleiPropertiesTable::GetMassExcess(Z,A) + ExcitEnergy - // B9
// G4NucleiPropertiesTable::GetMassExcess(1,1) - // proton
// 2.0*G4NucleiPropertiesTable::GetMassExcess(2,4);
G4double AvalKineticE = sqrt(aMomentum.e()*aMomentum.e() -
aMomentum.vect().mag2()) - // B9
Masses[2] - // proton
2.0*Masses[0];
RWTPtrOrderedVector<G4LorentzVector> * SubFragsMomentum =
FragmentsMomentum(AvalKineticE, NumSubFrag,Masses);
G4FragmentVector * theResult = new G4FragmentVector;
for (G4int i = 0; i < NumSubFrag; i++) {
// Lorentz boost
SubFragsMomentum->at(i)->boost(aMomentum.boostVector());
theResult->insert(new G4Fragment(AtomNum[i],Charges[i],*(SubFragsMomentum->at(i))));
}
SubFragsMomentum->clearAndDestroy();
delete SubFragsMomentum;
return theResult;
}
@@ -0,0 +1,92 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4Be8FermiFragment.hh"
G4Be8FermiFragment::G4Be8FermiFragment()
{
}
G4Be8FermiFragment::G4Be8FermiFragment(const G4Be8FermiFragment &right)
{
G4Exception("G4Be8FermiFragment::copy_constructor meant to not be accessable");
}
G4Be8FermiFragment::~G4Be8FermiFragment()
{
}
const G4Be8FermiFragment & G4Be8FermiFragment::operator=(const G4Be8FermiFragment &right)
{
G4Exception("G4Be8FermiFragment::operator= meant to not be accessable");
return *this;
}
G4bool G4Be8FermiFragment::operator==(const G4Be8FermiFragment &right) const
{
return false;
}
G4bool G4Be8FermiFragment::operator!=(const G4Be8FermiFragment &right) const
{
return true;
}
G4FragmentVector * G4Be8FermiFragment::GetFragment(const G4LorentzVector & aMomentum)
// Be8 ----> alpha + alpha
{
const G4int NumSubFrag = 2;
G4double Masses[NumSubFrag];
G4double Charges[NumSubFrag];
G4double AtomNum[NumSubFrag];
Masses[0] = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(2,4); // alpha
Masses[1] = Masses[0]; // alpha
AtomNum[0] = 4;
AtomNum[1] = 4;
Charges[0] = 2;
Charges[1] = 2;
// G4double AvalKineticE = G4NucleiPropertiesTable::GetMassExcess(Z,A) + ExcitEnergy - // Be8
// 2.0*G4NucleiPropertiesTable::GetMassExcess(2,4); // alphas
G4double AvalKineticE = sqrt(aMomentum.e()*aMomentum.e() -
aMomentum.vect().mag2()) -// Be8
2.0*AtomNum[0]; // alphas
RWTPtrOrderedVector<G4LorentzVector> * SubFragsMomentum =
FragmentsMomentum(AvalKineticE, NumSubFrag,Masses);
G4FragmentVector * theResult = new G4FragmentVector;
for (G4int i = 0; i < NumSubFrag; i++) {
// Lorentz boost
SubFragsMomentum->at(i)->boost(aMomentum.boostVector());
theResult->insert(new G4Fragment(AtomNum[i],Charges[i],*(SubFragsMomentum->at(i))));
}
SubFragsMomentum->clearAndDestroy();
delete SubFragsMomentum;
return theResult;
}
@@ -0,0 +1,460 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
// some corrections by V. Krylov (Oct. 1988)
// some corrections to V. Krylov by V. Lara (Dec. 1988)
#include "G4CompetitiveFission.hh"
G4CompetitiveFission::G4CompetitiveFission()
{
theFissionBarrierPtr = new G4FissionBarrier;
MyOwnFissionBarrier = true;
theFissionProbabilityPtr = new G4FissionProbability(this);
MyOwnFissionProbability = true;
theLevelDensityPtr = new G4FissionLevelDensityParameter;
MyOwnLevelDensity = true;
MaximalKineticEnergy = -1000.0*MeV;
FissionBarrier = 0.0;
FissionProbability = 0.0;
LevelDensityParameter = 0.0;
}
G4CompetitiveFission::G4CompetitiveFission(const G4CompetitiveFission &right)
{
}
G4CompetitiveFission::~G4CompetitiveFission()
{
if (MyOwnFissionBarrier) delete theFissionBarrierPtr;
if (MyOwnFissionProbability) delete theFissionProbabilityPtr;
if (MyOwnLevelDensity) delete theLevelDensityPtr;
}
const G4CompetitiveFission & G4CompetitiveFission::operator=(const G4CompetitiveFission &right)
{
G4Exception("G4CompetitiveFission::operator= meant to not be accessable");
return *this;
}
G4bool G4CompetitiveFission::operator==(const G4CompetitiveFission &right) const
{
return (this == (G4CompetitiveFission *) &right);
}
G4bool G4CompetitiveFission::operator!=(const G4CompetitiveFission &right) const
{
return (this != (G4CompetitiveFission *) &right);
}
void G4CompetitiveFission::Initialize(const G4Fragment & fragment)
{
G4int anA = fragment.GetA();
G4int aZ = fragment.GetZ();
G4double ExEnergy = fragment.GetExcitationEnergy();
// Calculate Fission Barrier
FissionBarrier = theFissionBarrierPtr->FissionBarrier(anA,aZ);
// Saddle point excitation energy ---> A = 65
// Fission is excluded for A < 65
if (anA >= 65) {
MaximalKineticEnergy = ExEnergy - FissionBarrier;
LevelDensityParameter = theLevelDensityPtr->LevelDensityParameter(anA,aZ,ExEnergy);
FissionProbability = theFissionProbabilityPtr->EmissionProbability(fragment,0);
}
else {
MaximalKineticEnergy = -1000.0*MeV;
LevelDensityParameter = 0.0;
FissionProbability = 0.0;
}
return;
}
G4FragmentVector * G4CompetitiveFission::BreakUp(const G4Fragment & theNucleus)
{
// Nucleus data
// Excitation energy (in MeV)
G4double U = theNucleus.GetExcitationEnergy()/MeV;
// Check that U > 0
if (U <= 0.0) {
G4FragmentVector * theResult = new G4FragmentVector;
theResult->insert(new G4Fragment(theNucleus));
return theResult;
}
// Atomic number of nucleus
G4int A = theNucleus.GetA();
// Charge of nucleus
G4int Z = theNucleus.GetZ();
// Atomic Mass of Nucleus (in MeV)
G4double M = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(Z,A)/MeV;
// Nucleus Momentum
G4LorentzVector theNucleusMomentum = theNucleus.GetMomentum();
// Calculate fission parameters
G4FissionParameters theParameters(A,Z,U*MeV,FissionBarrier);
// First fragment
G4int A1 = 0;
G4int Z1 = 0;
G4double M1 = 0.0;
// Second fragment
G4int A2 = 0;
G4int Z2 = 0;
G4double M2 = 0.0;
G4double FragmentsExcitationEnergy = 0.0;
G4double FragmentsKineticEnergy = 0.0;
G4int Trials = 0;
do {
// First fragment
A1 = FissionAtomicNumber(A,theParameters);
Z1 = FissionCharge(A,Z,A1);
M1 = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(Z1,A1)/MeV;
// Second Fragment
A2 = A - A1;
Z2 = Z - Z1;
if (A2 < 1 || Z2 < 0)
G4Exception("G4CompetitiveFission::BreakUp: Can't define second fragment! ");
M2 = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(Z2,A2)/MeV;
// Check that fragment masses are less or equal than total energy
// if (M1 + M2 > theNucleusMomentum.mag()/MeV)
if (M1 + M2 > theNucleusMomentum.e()/MeV)
G4Exception("G4CompetitiveFission::BreakUp: Fragments Mass > Total Energy");
// Maximal Kinetic Energy (available energy for fragments)
// G4double Tmax = theNucleusMomentum.mag()/MeV - M1 - M2;
G4double Tmax = M + U - M1 - M2;
FragmentsKineticEnergy = FissionKineticEnergy( A , Z,
A1, Z1,
A2, Z2,
U , Tmax,
theParameters);
// Excitation Energy
FragmentsExcitationEnergy = Tmax - FragmentsKineticEnergy;
} while (FragmentsExcitationEnergy < 0.0 && Trials++ < 100);
if (FragmentsExcitationEnergy <= 0.0)
G4Exception("G4CompetitiveFission::BreakItUp: Excitation energy for fragments < 0.0!");
// while (FragmentsExcitationEnergy < 0 && Trials < 100);
// Fragment 1
G4double U1 = FragmentsExcitationEnergy * (G4double(A1)/G4double(A));
// Fragment 2
G4double U2 = FragmentsExcitationEnergy * (G4double(A2)/G4double(A));
G4double Pmax = sqrt( 2 * ( ( (M1+U1)*(M2+U2) ) /
( (M1+U1)+(M2+U2) ) ) * FragmentsKineticEnergy);
G4ParticleMomentum momentum1 = IsotropicVector( Pmax );
G4ParticleMomentum momentum2( -momentum1 );
// Perform a Galileo boost for fragments
momentum1 += (theNucleusMomentum.boostVector() * (M1+U1));
momentum2 += (theNucleusMomentum.boostVector() * (M2+U2));
// Create 4-momentum for first fragment
// Warning!! Energy conservation is broken
G4LorentzVector FourMomentum1( momentum1 , sqrt(momentum1.mag2() + (M1+U1)*(M1+U1)));
// Create 4-momentum for second fragment
// Warning!! Energy conservation is broken
G4LorentzVector FourMomentum2( momentum2 , sqrt(momentum2.mag2() + (M2+U2)*(M2+U2)));
// Create Fragments
G4Fragment * Fragment1 = new G4Fragment( A1, Z1, FourMomentum1);
if (!Fragment1) G4Exception("G4CompetitiveFission::BreakItUp: Can't create Fragment1! ");
G4Fragment * Fragment2 = new G4Fragment( A2, Z2, FourMomentum2);
if (!Fragment2) G4Exception("G4CompetitiveFission::BreakItUp: Can't create Fragment2! ");
// Create Fragment Vector
G4FragmentVector * theResult = new G4FragmentVector;
theResult->insert(Fragment1);
theResult->insert(Fragment2);
return theResult;
}
G4int G4CompetitiveFission::FissionAtomicNumber(const G4int A, const G4FissionParameters & theParam)
// Calculates the atomic number of a fission product
{
// For Simplicity reading code
const G4double A1 = theParam.GetA1();
const G4double A2 = theParam.GetA2();
const G4double As = theParam.GetAs();
const G4double Sigma1 = theParam.GetSigma1();
const G4double Sigma2 = theParam.GetSigma2();
const G4double SigmaS = theParam.GetSigmaS();
const G4double w = theParam.GetW();
G4double FasymAsym = 2.0*exp(-((A2-As)*(A2-As))/(2.0*Sigma2*Sigma2)) +
exp(-((A1-As)*(A1-As))/(2.0*Sigma1*Sigma1));
G4double FsymA1A2 = exp(-((As-(A1+A2))*(As-(A1+A2)))/(2.0*SigmaS*SigmaS));
G4double C2A = A2 + 3.72*Sigma2;
G4double C2S = As + 3.72*SigmaS;
G4double C2 = 0.0;
if (w > 1000.0 ) C2 = C2S;
else if (w < 0.001) C2 = C2A;
else C2 = max(C2A,C2S);
G4double C1 = A-C2;
if (C1 < 30.0) {
C2 = A-30.0;
C1 = 30.0;
}
G4double Am1 = (As + A1)/2.0;
G4double Am2 = (A1 + A2)/2.0;
// Get Mass distributions as sum of symmetric and asymmetric Gasussians
G4double Mass1 = MassDistribution(As,A,theParam);
G4double Mass2 = MassDistribution(Am1,A,theParam);
G4double Mass3 = MassDistribution(A1,A,theParam);
G4double Mass4 = MassDistribution(Am2,A,theParam);
G4double Mass5 = MassDistribution(A2,A,theParam);
// get maximal value among Mass1,...,Mass5
G4double MassMax = Mass1;
if (Mass2 > MassMax) MassMax = Mass2;
if (Mass3 > MassMax) MassMax = Mass3;
if (Mass4 > MassMax) MassMax = Mass4;
if (Mass5 > MassMax) MassMax = Mass5;
// Sample a fragment mass number, which lies between C1 and C2
G4double m;
G4double Pm;
do {
m = C1+G4UniformRand()*(C2-C1);
Pm = MassDistribution(m,A,theParam);
} while (G4UniformRand() > Pm/MassMax);
// return static_cast<G4int>(m+0.5);
return G4int(m+0.5);
}
G4double G4CompetitiveFission::MassDistribution(const G4double x, const G4double A,
const G4FissionParameters & theParam)
// This method gives mass distribution F(x) = F_{asym}(x)+w*F_{sym}(x)
// which consist of symmetric and asymmetric sum of gaussians components.
{
G4double Xsym = exp(-0.5*(x-theParam.GetAs())*(x-theParam.GetAs())/
(theParam.GetSigmaS()*theParam.GetSigmaS()));
G4double Xasym = exp(-0.5*(x-theParam.GetA2())*(x-theParam.GetA2())/
(theParam.GetSigma2()*theParam.GetSigma2())) +
exp(-0.5*(x-(A-theParam.GetA2()))*(x-(A-theParam.GetA2()))/
(theParam.GetSigma2()*theParam.GetSigma2())) +
0.5*exp(-0.5*(x-theParam.GetA1())*(x-theParam.GetA1())/
(theParam.GetSigma1()*theParam.GetSigma1())) +
0.5*exp(-0.5*(x-(A-theParam.GetA1()))*(x-(A-theParam.GetA1()))/
(theParam.GetSigma1()*theParam.GetSigma1()));
if (theParam.GetW() > 1000) return Xsym;
else if (theParam.GetW() < 0.001) return Xasym;
else return theParam.GetW()*Xsym+Xasym;
}
G4int G4CompetitiveFission::FissionCharge(const G4double A,
const G4double Z,
const G4double Af)
// Calculates the charge of a fission product for a given atomic number Af
{
const G4double sigma = 0.6;
G4double DeltaZ = 0.0;
if (Af >= 134.0) DeltaZ = -0.45; // 134 <= Af
else if (A <= (A-134.0)) DeltaZ = 0.45; // Af <= (A-134)
else DeltaZ = -0.45*(Af-(A/2.0))/(134.0-(A/2.0)); // (A-134) < Af < 134
G4double Zmean = (Af/A)*Z + DeltaZ;
G4double theZ;
do {
theZ = RandGauss::shoot(Zmean,sigma);
} while (theZ < 1.0 || theZ > (Z-1.0) || theZ > Af);
// return static_cast<G4int>(theZ+0.5);
return G4int(theZ+0.5);
}
G4double G4CompetitiveFission::FissionKineticEnergy(const G4double A, const G4double Z,
const G4double Af1, const G4double Zf1,
const G4double Af2, const G4double Zf2,
const G4double U, const G4double Tmax,
const G4FissionParameters & theParam)
// Gives the kinetic energy of fission products
{
// Find maximal value of A for fragments
G4double AfMax = max(Af1,Af2);
if (AfMax < (A/2.0)) AfMax = A - AfMax;
// Weights for symmetric and asymmetric components
G4double Pas;
if (theParam.GetW() > 1000) Pas = 0.0;
else {
G4double P1 = 0.5*exp(-0.5*(AfMax-theParam.GetA1())*(AfMax-theParam.GetA1())/
(theParam.GetSigma1()*theParam.GetSigma1()));
G4double P2 = exp(-0.5*(AfMax-theParam.GetA2())*(AfMax-theParam.GetA2())/
(theParam.GetSigma2()*theParam.GetSigma2()));
Pas = P1+P2;
}
G4double Ps;
if (theParam.GetW() < 0.001) Ps = 0.0;
else
Ps = theParam.GetW()*exp(-0.5*(AfMax-theParam.GetAs())*(AfMax-theParam.GetAs())/
(theParam.GetSigmaS()*theParam.GetSigmaS()));
G4double Psy = Ps/(Pas+Ps);
// Fission fractions Xsy and Xas formed in symmetric and asymmetric modes
G4double PPas = theParam.GetSigma1() + 2.0 * theParam.GetSigma2();
G4double PPsy = theParam.GetW() * theParam.GetSigmaS();
G4double Xas = PPas / (PPas+PPsy);
G4double Xsy = PPsy / (PPas+PPsy);
// Average kinetic energy for symmetric and asymmetric components
G4double Eaverage = 0.1071*(Z*Z)/pow(A,1.0/3.0) + 22.2;
// Compute maximal average kinetic energy of fragments and Energy Dispersion (sqrt)
G4double TaverageAfMax;
G4double ESigma;
// Select randomly fission mode (symmetric or asymmetric)
if (G4UniformRand() > Psy) { // Asymmetric Mode
G4double A11 = theParam.GetA1()-0.7979*theParam.GetSigma1();
G4double A12 = theParam.GetA1()+0.7979*theParam.GetSigma1();
G4double A21 = theParam.GetA2()-0.7979*theParam.GetSigma2();
G4double A22 = theParam.GetA2()+0.7979*theParam.GetSigma2();
// scale factor
G4double ScaleFactor = 0.5*theParam.GetSigma1()*(AsymmetricRatio(A,A11)+AsymmetricRatio(A,A12))+
theParam.GetSigma2()*(AsymmetricRatio(A,A21)+AsymmetricRatio(A,A22));
// Compute average kinetic energy for fragment with AfMax
TaverageAfMax = (Eaverage + 12.5 * Xsy) * (PPas/ScaleFactor) * AsymmetricRatio(A,AfMax);
ESigma = 10.0; // MeV
} else { // Symmetric Mode
G4double As0 = theParam.GetAs() + 0.7979*theParam.GetSigmaS();
// scale factor
G4double ScaleFactor = theParam.GetW()*theParam.GetSigmaS()*SymmetricRatio(A,As0);
// Compute average kinetic energy for fragment with AfMax
TaverageAfMax = (Eaverage - 12.5*Xas) * (PPsy/ScaleFactor) * SymmetricRatio(A,AfMax);
ESigma = 8.0; // MeV
}
// Select randomly, in accordance with Gaussian distribution, fragment kinetic energy
G4double KineticEnergy;
G4int i = 0;
do {
KineticEnergy = RandGauss::shoot(TaverageAfMax,ESigma);
if (i++ > 100) return Eaverage;
} while (KineticEnergy < Eaverage-3.72*ESigma ||
KineticEnergy > Eaverage+3.72*ESigma ||
KineticEnergy > Tmax);
return KineticEnergy;
}
G4double G4CompetitiveFission::AsymmetricRatio(const G4double A,const G4double A11)
{
const G4double B1 = 23.5;
const G4double A00 = 134.0;
return Ratio(A,A11,B1,A00);
}
G4double G4CompetitiveFission::SymmetricRatio(const G4double A,const G4double A11)
{
const G4double B1 = 5.32;
const G4double A00 = A/2.0;
return Ratio(A,A11,B1,A00);
}
G4double G4CompetitiveFission::Ratio(const G4double A,const G4double A11,
const G4double B1,const G4double A00)
{
if (A == 0) G4Exception("G4CompetitiveFission::Ratio: A == 0!");
if (A11 >= A/2.0 && A11 <= (A00+10.0)) return 1.0-B1*((A11-A00)/A)*((A11-A00)/A);
else return 1.0-B1*(10.0/A)*(10.0/A)-2.0*(10.0/A)*B1*((A11-A00-10.0)/A);
}
G4ThreeVector G4CompetitiveFission::IsotropicVector(const G4double Magnitude)
// Samples a isotropic random vectorwith a magnitud given by Magnitude.
// By default Magnitude = 1.0
{
G4double CosTheta = 1.0 - 2.0*G4UniformRand();
G4double SinTheta = sqrt(1.0 - CosTheta*CosTheta);
G4double Phi = twopi*G4UniformRand();
G4ThreeVector Vector(Magnitude*cos(Phi)*SinTheta,
Magnitude*sin(Phi)*SinTheta,
Magnitude*CosTheta);
return Vector;
}
@@ -0,0 +1,46 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// Constant level density parameter (for photon evaporation)
//
// by C. Dallapiccola (Nov 1998)
//
#include "G4ConstantLevelDensityParameter.hh"
G4ConstantLevelDensityParameter::
G4ConstantLevelDensityParameter(const G4ConstantLevelDensityParameter& right) :
EvapLevelDensityParameter(0.125*(1./MeV))
{
G4Exception("G4ConstantLevelDensityParameter::copy_constructor meant to not be accessable");
}
const G4ConstantLevelDensityParameter & G4ConstantLevelDensityParameter::
operator=(const G4ConstantLevelDensityParameter &right)
{
G4Exception("G4ConstantLevelDensityParameter::operator= meant to not be accessable");
return *this;
}
G4bool G4ConstantLevelDensityParameter::operator==(const G4ConstantLevelDensityParameter &right) const
{
return false;
}
G4bool G4ConstantLevelDensityParameter::operator!=(const G4ConstantLevelDensityParameter &right) const
{
return true;
}
@@ -0,0 +1,131 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4ContinuumGammaDeexcitation
//
// Authors: Carlo Dallapiccola (dallapiccola@umdhep.umd.edu)
// Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 23 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
//
// Class G4ContinuumGammaDeexcitation.cc
//
// Concrete class derived from G4VGammaDeexcitation
//
//
#include "G4ContinuumGammaDeexcitation.hh"
#include "G4Gamma.hh"
#include "G4ContinuumGammaTransition.hh"
#include "G4NuclearLevelManager.hh"
#include "G4Fragment.hh"
#include "G4ConstantLevelDensityParameter.hh"
//
// Constructor
//
G4ContinuumGammaDeexcitation::G4ContinuumGammaDeexcitation(): _Z(0), _A(0)
{ }
G4ContinuumGammaDeexcitation::~G4ContinuumGammaDeexcitation()
{ }
G4VGammaTransition* G4ContinuumGammaDeexcitation::CreateTransition()
{
G4Fragment nucleus = GetNucleus();
G4int Z = nucleus.GetZ();
G4int A = nucleus.GetA();
G4double excitation = nucleus.GetExcitationEnergy();
if (_A != A || _Z != Z)
{
_levelManager.SetNucleus(Z,A);
_A = A;
_Z = Z;
}
if (_verbose > 1)
G4cout << "G4ContinuumGammaDeexcitation::CreateTransition - Created" << endl;
return new G4ContinuumGammaTransition(_levelManager,Z,A,excitation,_verbose );
}
G4bool G4ContinuumGammaDeexcitation::CanDoTransition() const
{
G4bool canDo = true;
if (_transition == 0)
{
canDo = false;
if (_verbose > 0)
G4cout
<< "G4ContinuumGammaDeexcitation::CanDoTransition - Null transition "
<< endl;
}
G4Fragment nucleus = GetNucleus();
G4double excitation = nucleus.GetExcitationEnergy();
G4double A = nucleus.GetA();
G4double Z = nucleus.GetZ();
if (A <2 || Z<3)
{
canDo = false;
if (_verbose > 0)
G4cout
<< "G4ContinuumGammaDeexcitation::CanDoTransition - n/p/H"
<< endl;
}
if (excitation <= 0.)
{
canDo = false;
if (_verbose > 0)
G4cout
<< "G4ContinuumGammaDeexcitation::CanDoTransition - Excitation <= 0"
<< endl;
}
if (excitation <= _levelManager.MaxLevelEnergy())
{
canDo = false;
if (_verbose > 0)
G4cout << "G4ContinuumGammaDeexcitation::CanDoTransition - Excitation "
<< excitation << " below max discrete level "
<< _levelManager.MaxLevelEnergy() << endl;
}
if (canDo)
{ if (_verbose > 1)
G4cout <<"G4ContinuumGammaDeexcitation::CanDoTransition - CanDo"
<< endl;
}
return canDo;
}
@@ -0,0 +1,191 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4ContinuumGammaTransition
//
// Authors: Carlo Dallapiccola (dallapiccola@umdhep.umd.edu)
// Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 23 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
//
// Class G4ContinuumGammaTransition.cc
//
#include "G4ContinuumGammaTransition.hh"
#include "G4VLevelDensityParameter.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "G4RandGeneralTmp.hh"
//
// Constructor
//
G4ContinuumGammaTransition::G4ContinuumGammaTransition(const G4NuclearLevelManager& levelManager,
G4int Z, G4int A, G4double excitation,
G4int verbose):
_Z(Z), _A(A), _excitation(excitation), _levelManager(levelManager)
{
const G4PtrLevelVector* levels = levelManager.GetLevels();
G4double eTolerance = 0.;
if (levels != 0)
{
G4int lastButOne = levelManager.NumberOfLevels() - 2;
if (lastButOne >= 0)
{
eTolerance = levelManager.MaxLevelEnergy() - levels->at(lastButOne)->Energy();
if (eTolerance < 0.) eTolerance = 0.;
}
}
_verbose = verbose;
_eGamma = 0.;
_maxLevelE = levelManager.MaxLevelEnergy() + eTolerance;
_minLevelE = levelManager.MinLevelEnergy();
// 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;
// Giant Dipole Resonance width
G4double widthGDR = 0.30 * energyGDR;
// Extend
G4double factor = 5;
_eMax = energyGDR + factor * widthGDR;
if (_eMax > excitation) _eMax = _excitation;
}
//
// Destructor
//
G4ContinuumGammaTransition::~G4ContinuumGammaTransition() {}
//
// Override GammaEnergy function from G4VGammaTransition
//
G4double G4ContinuumGammaTransition::GammaEnergy()
{
_eGamma = 0.;
G4int nBins = 200;
G4double sampleArray[200];
G4int i;
for (i=0; i<nBins; i++)
{
G4double e = _eMin + ( (_eMax - _eMin) / nBins) * i;
sampleArray[i] = E1Pdf(e);
if(_verbose > 10)
G4cout << "*---* G4ContinuumTransition: e = " << e
<< " pdf = " << sampleArray[i] << endl;
}
G4RandGeneralTmp randGeneral(sampleArray, nBins);
G4double random = randGeneral.shoot();
_eGamma = _eMin + (_eMax - _eMin) * random;
G4double finalExcitation = _excitation - _eGamma;
if(_verbose > 10)
G4cout << "*---*---* G4ContinuumTransition: eGamma = " << _eGamma
<< " finalExcitation = " << finalExcitation
<< " random = " << random << endl;
if (finalExcitation < 0)
{
_eGamma = _excitation;
finalExcitation = 0.;
}
if (finalExcitation < _maxLevelE && finalExcitation > 0.)
{
G4double levelE = _levelManager.NearestLevel(finalExcitation)->Energy();
G4double diff = finalExcitation - levelE;
_eGamma = _eGamma + diff;
}
return _eGamma;
}
G4double G4ContinuumGammaTransition::GetEnergyTo() const
{
G4double excitation = _excitation - _eGamma;
if (excitation < 0.) excitation = 0.;
return excitation ;
}
void G4ContinuumGammaTransition::SetEnergyFrom(const G4double energy)
{
if (energy > 0.) _excitation = energy;
return;
}
G4double G4ContinuumGammaTransition::E1Pdf(G4double e)
{
G4double theProb = 0.0;
if( (_excitation - e) < 0.0 || e < 0 || _excitation < 0) return theProb;
G4ConstantLevelDensityParameter ldPar;
G4double aLevelDensityParam = ldPar.LevelDensityParameter(_A,_Z,_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
<< " Bef Aft " << levelDensBef << " " << levelDensAft << endl;
// Now form the probability density
// 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 Egdp = (40.3 / pow(_A,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / (pi * hbarc)*(pi * hbarc);
G4double numerator = sigma0 * e*e * GammaR*GammaR;
G4double denominator = (e*e - Egdp*Egdp)* (e*e - Egdp*Egdp) + GammaR*GammaR*e*e;
// if (denominator < 1.0e-9) denominator = 1.0e-9;
G4double sigmaAbs = numerator/denominator ;
if(_verbose > 20)
G4cout << ".. " << Egdp << " .. " << GammaR
<< " .. " << normC << " .. " << sigmaAbs
<< " .. " << e*e << " .. " << levelDensAft/levelDensBef
<< endl;
// theProb = normC * sigmaAbs * e*e * levelDensAft/levelDensBef;
theProb = sigmaAbs * e*e * levelDensAft/levelDensBef;
return theProb;
}
@@ -0,0 +1,151 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4DiscreteGammaDeexcitation
//
// Author: Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 23 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
#include "G4DiscreteGammaDeexcitation.hh"
#include "G4DiscreteGammaTransition.hh"
#include "G4NuclearLevelManager.hh"
G4DiscreteGammaDeexcitation::G4DiscreteGammaDeexcitation(): _Z(0),_A(0)
{
_tolerance = 0.1 * MeV;
}
G4DiscreteGammaDeexcitation::~G4DiscreteGammaDeexcitation() {}
G4VGammaTransition* G4DiscreteGammaDeexcitation::CreateTransition()
{
G4Fragment nucleus = GetNucleus();
G4int A = nucleus.GetA();
G4int Z = nucleus.GetZ();
if (_levelManager.IsValid(Z,A))
{
if (_verbose > 1)
G4cout
<< "G4DiscreteGammaDeexcitation::CreateTransition - (A,Z) is valid "
<< endl;
if (_A != A || _Z != Z)
{
_levelManager.SetNucleus(Z,A);
_A = A;
_Z = Z;
}
G4double excitation = nucleus.GetExcitationEnergy();
// const G4NuclearLevel* level =_levelManager.NearestLevel(excitation, _tolerance);
const G4NuclearLevel* level =_levelManager.NearestLevel(excitation);
if (level != 0)
{
if (_verbose > 0)
G4cout
<< "G4DiscreteGammaDeexcitation::CreateTransition - Created from level energy "
<< level->Energy() << ", excitation is "
<< excitation << endl;
return new G4DiscreteGammaTransition(*level);
}
else
{
if (_verbose > 0)
G4cout
<< "G4DiscreteGammaDeexcitation::CreateTransition - No transition created from "
<< excitation << " within tolerance " << _tolerance << endl;
return 0;
}
}
else return 0;
}
G4bool G4DiscreteGammaDeexcitation::CanDoTransition() const
{
G4bool canDo = true;
if (_transition == 0)
{
canDo = false;
if (_verbose > 0)
G4cout
<< "G4DiscreteGammaDeexcitation::CanDoTransition - Null transition "
<< endl;
}
G4Fragment nucleus = GetNucleus();
G4double A = nucleus.GetA();
G4double Z = nucleus.GetZ();
if (A <2 || Z<3 || Z>92)
{
canDo = false;
if (_verbose > 0)
G4cout
<< "G4DiscreteGammaDeexcitation::CanDoTransition - n/p/H/>U"
<< endl;
}
G4double excitation = nucleus.GetExcitationEnergy();
if (excitation <= 0.)
{
canDo = false;
if (_verbose > 0)
G4cout
<< "G4DiscreteGammaDeexcitation::CanDoTransition - Excitation <= 0"
<< endl;
}
if (excitation > _levelManager.MaxLevelEnergy() + _tolerance) canDo = false;
if (excitation < _levelManager.MinLevelEnergy() - _tolerance) canDo = false;
// The following is a protection to avoid looping in case of elements with very low
// ensdf levels
if (excitation < _levelManager.MinLevelEnergy() * 0.9) canDo = false;
if (_verbose > 0)
{
G4cout << "G4DiscreteGammaDeexcitation::CanDoTransition - Excitation "
<< excitation << ", Min-Max are "
<< _levelManager.MinLevelEnergy() << " "
<< _levelManager.MaxLevelEnergy() << endl;
}
if (canDo)
{ if (_verbose > 0)
G4cout <<"G4DiscreteGammaDeexcitation::CanDoTransition - CanDo" << endl; }
// else
// {
// delete _transition;
// _transition = 0;
// }
return canDo;
}
@@ -0,0 +1,86 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4ContDiscrGammaTransition
//
// Author: Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 23 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
#include "G4DiscreteGammaTransition.hh"
#include "Randomize.hh"
G4DiscreteGammaTransition::G4DiscreteGammaTransition(const G4NuclearLevel& level):
_level(level), _excitation(0.), _gammaEnergy(0.)
{ }
G4DiscreteGammaTransition::~G4DiscreteGammaTransition()
{ }
G4double G4DiscreteGammaTransition::GammaEnergy()
{
_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; }
}
}
// 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;
if (_gammaEnergy < 0.) _gammaEnergy = 0.;
}
return _gammaEnergy;
}
G4double G4DiscreteGammaTransition::GetEnergyTo() const
{
G4double energyTo = _excitation - _gammaEnergy;
if (energyTo < 0.) energyTo = 0.;
return energyTo;
}
void G4DiscreteGammaTransition::SetEnergyFrom(const G4double energy)
{
_excitation = energy;
return;
}
@@ -0,0 +1,51 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// 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 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
#include "G4DummyMF.hh"
G4DummyMF::G4DummyMF()
{
}
G4DummyMF::G4DummyMF(const G4DummyMF &right)
{
}
G4DummyMF::~G4DummyMF()
{
}
const G4DummyMF & G4DummyMF::operator=(const G4DummyMF &right)
{
G4Exception("G4DummyMF::operator= meant to not be accessable");
return *this;
}
int G4DummyMF::operator==(const G4DummyMF &right) const
{
return 0;
}
int G4DummyMF::operator!=(const G4DummyMF &right) const
{
return 1;
}
G4FragmentVector * G4DummyMF::BreakItUp(const G4Fragment &theNucleus)
{
// G4cout << "G4DummyMF::BreakItUp called"<<endl;
G4FragmentVector * theResult =
new G4FragmentVector;
// all calculations here
return theResult;
}
@@ -0,0 +1,75 @@
//
// Class G4DummyProbability.cc
//
#include "G4DummyProbability.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4DummyProbability::G4DummyProbability(const G4DummyProbability& right)
{
G4Exception("G4DummyProbability::copy_constructor meant to not be accessible");
}
const G4DummyProbability& G4DummyProbability::
operator=(const G4DummyProbability& right)
{
G4Exception("G4DummyProbability::operator= meant to not be accessible");
return *this;
}
G4bool G4DummyProbability::operator==(const G4DummyProbability& right) const
{
return false;
}
G4bool G4DummyProbability::operator!=(const G4DummyProbability& right) const
{
return true;
}
// Calculate the emission probability
//
G4double G4DummyProbability::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
G4double theProb = 0.0;
return theProb;
}
G4double G4DummyProbability::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to last ground level.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
// Fall-back is a uniform random number
G4double uniformNum = G4UniformRand();
theProb = uniformNum;
return theProb;
}
G4DummyProbability::~G4DummyProbability() {}
@@ -0,0 +1,188 @@
//
// Class G4E1Probability.cc
//
#include "G4E1Probability.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1Probability::G4E1Probability(const G4E1Probability& right)
{
G4Exception("G4E1Probability::copy_constructor meant to not be accessible");
}
const G4E1Probability& G4E1Probability::
operator=(const G4E1Probability& right)
{
G4Exception("G4E1Probability::operator= meant to not be accessible");
return *this;
}
G4bool G4E1Probability::operator==(const G4E1Probability& right) const
{
return false;
}
G4bool G4E1Probability::operator!=(const G4E1Probability& right) const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1Probability::EmissionProbDensity(const G4Fragment& frag,
const G4double gammaE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - gammaE
// (U = nucleus excitation energy, gammaE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-gammaE) < 0.0 || gammaE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-gammaE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, gammaE = "<<Uexcite<<" "<<gammaE<<endl;
//cout<<" Uexcite, gammaE = "<<Uexcite*MeV<<" "<<gammaE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * gammaE*gammaE * GammaR*GammaR;
G4double denominator = (gammaE*gammaE - Egdp*Egdp)*
(gammaE*gammaE - Egdp*Egdp) + GammaR*GammaR*gammaE*gammaE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * gammaE*gammaE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1Probability::EmissionProbability(const G4Fragment& frag,
const G4double gammaE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to last ground level.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double Uafter = 0.0;
const G4double Uexcite = frag.GetExcitationEnergy();
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 100;
// Fall-back is a uniform random number
//G4double uniformNum = G4UniformRand();
//theProb = uniformNum;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,gammaE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ/(upperLim-lowerLim);
return theProb;
}
G4double G4E1Probability::EmissionIntegration(const G4Fragment& frag,
const G4double gammaE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)*Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1Probability::~G4E1Probability() {}
@@ -0,0 +1,189 @@
//
// Class G4E1Probability001.cc
//
#include "G4E1Probability001.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1Probability001::G4E1Probability001(const G4E1Probability001& right)
{
G4Exception("G4E1Probability001::copy_constructor meant to not be accessible");
}
const G4E1Probability001& G4E1Probability001::
operator=(const G4E1Probability001& right)
{
G4Exception("G4E1Probability001::operator= meant to not be accessible");
return *this;
}
G4bool G4E1Probability001::operator==(const G4E1Probability001& right) const
{
return false;
}
G4bool G4E1Probability001::operator!=(const G4E1Probability001& right) const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1Probability001::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1Probability001::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to last ground level.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 0.001;
G4double Uafter = 0.0;
const G4double Uexcite = frag.GetExcitationEnergy();
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Fall-back is a uniform random number
//G4double uniformNum = G4UniformRand();
//theProb = uniformNum;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1Probability001::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1Probability001::~G4E1Probability001() {}
@@ -0,0 +1,189 @@
//
// Class G4E1Probability01.cc
//
#include "G4E1Probability01.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1Probability01::G4E1Probability01(const G4E1Probability01& right)
{
G4Exception("G4E1Probability01::copy_constructor meant to not be accessible");
}
const G4E1Probability01& G4E1Probability01::
operator=(const G4E1Probability01& right)
{
G4Exception("G4E1Probability01::operator= meant to not be accessible");
return *this;
}
G4bool G4E1Probability01::operator==(const G4E1Probability01& right) const
{
return false;
}
G4bool G4E1Probability01::operator!=(const G4E1Probability01& right) const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1Probability01::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1Probability01::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to last ground level.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 0.01;
G4double Uafter = 0.0;
const G4double Uexcite = frag.GetExcitationEnergy();
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Fall-back is a uniform random number
//G4double uniformNum = G4UniformRand();
//theProb = uniformNum;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1Probability01::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1Probability01::~G4E1Probability01() {}
@@ -0,0 +1,189 @@
//
// Class G4E1Probability10.cc
//
#include "G4E1Probability10.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1Probability10::G4E1Probability10(const G4E1Probability10& right)
{
G4Exception("G4E1Probability10::copy_constructor meant to not be accessible");
}
const G4E1Probability10& G4E1Probability10::
operator=(const G4E1Probability10& right)
{
G4Exception("G4E1Probability10::operator= meant to not be accessible");
return *this;
}
G4bool G4E1Probability10::operator==(const G4E1Probability10& right) const
{
return false;
}
G4bool G4E1Probability10::operator!=(const G4E1Probability10& right) const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1Probability10::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1Probability10::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to last ground level.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 10.0;
G4double Uafter = 0.0;
const G4double Uexcite = frag.GetExcitationEnergy();
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Fall-back is a uniform random number
//G4double uniformNum = G4UniformRand();
//theProb = uniformNum;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1Probability10::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1Probability10::~G4E1Probability10() {}
@@ -0,0 +1,189 @@
//
// Class G4E1Probability100.cc
//
#include "G4E1Probability100.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1Probability100::G4E1Probability100(const G4E1Probability100& right)
{
G4Exception("G4E1Probability100::copy_constructor meant to not be accessible");
}
const G4E1Probability100& G4E1Probability100::
operator=(const G4E1Probability100& right)
{
G4Exception("G4E1Probability100::operator= meant to not be accessible");
return *this;
}
G4bool G4E1Probability100::operator==(const G4E1Probability100& right) const
{
return false;
}
G4bool G4E1Probability100::operator!=(const G4E1Probability100& right) const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1Probability100::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1Probability100::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to last ground level.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 100.0;
G4double Uafter = 0.0;
const G4double Uexcite = frag.GetExcitationEnergy();
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Fall-back is a uniform random number
//G4double uniformNum = G4UniformRand();
//theProb = uniformNum;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1Probability100::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1Probability100::~G4E1Probability100() {}
@@ -0,0 +1,190 @@
//
// Class G4E1SingleProbability001.cc
//
#include "G4E1SingleProbability001.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1SingleProbability001::G4E1SingleProbability001(
const G4E1SingleProbability001& right)
{
G4Exception("G4E1SingleProbability001::copy_constructor meant to not be accessible");
}
const G4E1SingleProbability001& G4E1SingleProbability001::
operator=(const G4E1SingleProbability001& right)
{
G4Exception("G4E1SingleProbability001::operator= meant to not be accessible");
return *this;
}
G4bool G4E1SingleProbability001::operator==(const G4E1SingleProbability001&
right) const
{
return false;
}
G4bool G4E1SingleProbability001::operator!=(const G4E1SingleProbability001&
right)
const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1SingleProbability001::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1SingleProbability001::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to the level
// Uexcite-exciteE.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 0.01; // playing with scale factors
const G4double Uexcite = frag.GetExcitationEnergy();
G4double Uafter = Uexcite - exciteE;
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1SingleProbability001::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1SingleProbability001::~G4E1SingleProbability001() {}
@@ -0,0 +1,190 @@
//
// Class G4E1SingleProbability01.cc
//
#include "G4E1SingleProbability01.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1SingleProbability01::G4E1SingleProbability01(
const G4E1SingleProbability01& right)
{
G4Exception("G4E1SingleProbability01::copy_constructor meant to not be accessible");
}
const G4E1SingleProbability01& G4E1SingleProbability01::
operator=(const G4E1SingleProbability01& right)
{
G4Exception("G4E1SingleProbability01::operator= meant to not be accessible");
return *this;
}
G4bool G4E1SingleProbability01::operator==(const G4E1SingleProbability01&
right) const
{
return false;
}
G4bool G4E1SingleProbability01::operator!=(const G4E1SingleProbability01&
right)
const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1SingleProbability01::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1SingleProbability01::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to the level
// Uexcite-exciteE.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 0.1; // playing with scale factors
const G4double Uexcite = frag.GetExcitationEnergy();
G4double Uafter = Uexcite - exciteE;
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1SingleProbability01::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1SingleProbability01::~G4E1SingleProbability01() {}
@@ -0,0 +1,189 @@
//
// Class G4E1SingleProbability1.cc
//
#include "G4E1SingleProbability1.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1SingleProbability1::G4E1SingleProbability1(const G4E1SingleProbability1&
right)
{
G4Exception("G4E1SingleProbability1::copy_constructor meant to not be accessible");
}
const G4E1SingleProbability1& G4E1SingleProbability1::
operator=(const G4E1SingleProbability1& right)
{
G4Exception("G4E1SingleProbability1::operator= meant to not be accessible");
return *this;
}
G4bool G4E1SingleProbability1::operator==(const G4E1SingleProbability1&
right) const
{
return false;
}
G4bool G4E1SingleProbability1::operator!=(const G4E1SingleProbability1& right)
const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1SingleProbability1::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1SingleProbability1::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to the level
// Uexcite-exciteE.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 1.0; // playing with scale factors
const G4double Uexcite = frag.GetExcitationEnergy();
G4double Uafter = Uexcite - exciteE;
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1SingleProbability1::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1SingleProbability1::~G4E1SingleProbability1() {}
@@ -0,0 +1,190 @@
//
// Class G4E1SingleProbability10.cc
//
#include "G4E1SingleProbability10.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1SingleProbability10::G4E1SingleProbability10(const G4E1SingleProbability10&
right)
{
G4Exception("G4E1SingleProbability10::copy_constructor meant to not be accessible");
}
const G4E1SingleProbability10& G4E1SingleProbability10::
operator=(const G4E1SingleProbability10& right)
{
G4Exception("G4E1SingleProbability10::operator= meant to not be accessible");
return *this;
}
G4bool G4E1SingleProbability10::operator==(const G4E1SingleProbability10&
right) const
{
return false;
}
G4bool G4E1SingleProbability10::operator!=(const G4E1SingleProbability10&
right)
const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1SingleProbability10::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1SingleProbability10::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to the level
// Uexcite-exciteE.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 10.0; // playing with scale factors
const G4double Uexcite = frag.GetExcitationEnergy();
G4double Uafter = Uexcite - exciteE;
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1SingleProbability10::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1SingleProbability10::~G4E1SingleProbability10() {}
@@ -0,0 +1,190 @@
//
// Class G4E1SingleProbability100.cc
//
#include "G4E1SingleProbability100.hh"
#include "G4ConstantLevelDensityParameter.hh"
#include "Randomize.hh"
// Constructors and operators
//
G4E1SingleProbability100::G4E1SingleProbability100(
const G4E1SingleProbability100& right)
{
G4Exception("G4E1SingleProbability100::copy_constructor meant to not be accessible");
}
const G4E1SingleProbability100& G4E1SingleProbability100::
operator=(const G4E1SingleProbability100& right)
{
G4Exception("G4E1SingleProbability100::operator= meant to not be accessible");
return *this;
}
G4bool G4E1SingleProbability100::operator==(const G4E1SingleProbability100&
right) const
{
return false;
}
G4bool G4E1SingleProbability100::operator!=(const G4E1SingleProbability100&
right)
const
{
return true;
}
// Calculate the emission probability
//
G4double G4E1SingleProbability100::EmissionProbDensity(const G4Fragment& frag,
const G4double exciteE)
{
// Calculate the probability density here
// From nuclear fragment properties and the excitation energy, calculate
// the probability density for photon evaporation from U to U - exciteE
// (U = nucleus excitation energy, exciteE = total evaporated photon
// energy).
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
const G4double Afrag = frag.GetA();
const G4double Zfrag = frag.GetZ();
const G4double Uexcite = frag.GetExcitationEnergy();
if( (Uexcite-exciteE) < 0.0 || exciteE < 0 || Uexcite <= 0) return theProb;
// Need a level density parameter.
// For now, just use the constant approximation (not reliable near magic
// nuclei).
G4ConstantLevelDensityParameter a;
G4double aLevelDensityParam = a.LevelDensityParameter(Afrag,Zfrag,Uexcite);
G4double levelDensBef = exp(2.0*sqrt(aLevelDensityParam*Uexcite));
G4double levelDensAft = exp(2.0*sqrt(aLevelDensityParam*(Uexcite-exciteE)));
// Now form the probability density
// Define constants for the photoabsorption cross-section (the reverse
// process of our de-excitation)
G4double sigma0 = 2.5 * Afrag * millibarn; // millibarns
G4double Egdp = (40.3 / pow(Afrag,0.2) )*MeV;
G4double GammaR = 0.30 * Egdp;
G4double normC = 1.0 / ((pi * hbarc)*(pi * hbarc));
// CD
//cout<<" PROB TESTS "<<endl;
//cout<<" hbarc = "<<hbarc<<endl;
//cout<<" pi = "<<pi<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite<<" "<<exciteE<<endl;
//cout<<" Uexcite, exciteE = "<<Uexcite*MeV<<" "<<exciteE*MeV<<endl;
//cout<<" lev density param = "<<aLevelDensityParam<<endl;
//cout<<" level densities = "<<levelDensBef<<" "<<levelDensAft<<endl;
//cout<<" sigma0 = "<<sigma0<<endl;
//cout<<" Egdp, GammaR = "<<Egdp<<" "<<GammaR<<endl;
//cout<<" normC = "<<normC<<endl;
G4double numerator = sigma0 * exciteE*exciteE * GammaR*GammaR;
G4double denominator = (exciteE*exciteE - Egdp*Egdp)*
(exciteE*exciteE - Egdp*Egdp) + GammaR*GammaR*exciteE*exciteE;
G4double sigmaAbs = numerator/denominator;
theProb = normC * sigmaAbs * exciteE*exciteE *
levelDensAft/levelDensBef;
// CD
//cout<<" sigmaAbs = "<<sigmaAbs<<endl;
//cout<<" Probability = "<<theProb<<endl;
return theProb;
}
G4double G4E1SingleProbability100::EmissionProbability(const G4Fragment& frag,
const G4double exciteE)
{
// From nuclear fragment properties and the excitation energy, calculate
// the probability for photon evaporation down to the level
// Uexcite-exciteE.
// fragment = nuclear fragment BEFORE de-excitation
G4double theProb = 0.0;
G4double ScaleFactor = 100.0; // playing with scale factors
const G4double Uexcite = frag.GetExcitationEnergy();
G4double Uafter = Uexcite - exciteE;
G4double normC = 3.0;
const G4double upperLim = Uexcite;
const G4double lowerLim = Uafter;
const G4int numIters = 25;
// Need to integrate EmissionProbDensity from lowerLim to upperLim
// and multiply by normC
G4double integ = normC *
EmissionIntegration(frag,exciteE,lowerLim,upperLim,numIters);
if(integ > 0.0) theProb = integ;
return theProb * ScaleFactor;
}
G4double G4E1SingleProbability100::EmissionIntegration(const G4Fragment& frag,
const G4double exciteE,
const G4double lowLim, const G4double upLim,
const G4int numIters)
{
// Simple Gaussian quadrature integration
G4double x;
G4double root3 = 1.0/sqrt(3.0);
G4double Step = (upLim-lowLim)/(2.0*numIters);
G4double Delta = Step*root3;
G4double mean = 0.0;
G4double theInt = 0.0;
for(G4int i = 0; i < numIters; i++) {
x = (2*i + 1)/Step;
G4double E1ProbDensityA = EmissionProbDensity(frag,x+Delta);
G4double E1ProbDensityB = EmissionProbDensity(frag,x-Delta);
mean += E1ProbDensityA + E1ProbDensityB;
}
if(mean*Step > 0.0) theInt = mean*Step;
return theInt;
}
G4E1SingleProbability100::~G4E1SingleProbability100() {}
@@ -0,0 +1,526 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
#include "G4Evaporation.hh"
G4Evaporation::G4Evaporation()
{
ExcitEnergyChann00.reshape(NumExcitedStates);
ExcitEnergyChann01.reshape(NumExcitedStates);
ExcitEnergyChann02.reshape(NumExcitedStates);
ExcitEnergyChann03.reshape(NumExcitedStates);
ExcitEnergyChann04.reshape(NumExcitedStates);
ExcitEnergyChann05.reshape(NumExcitedStates);
ExcitEnergyChann06.reshape(NumExcitedStates);
ExcitEnergyChann07.reshape(NumExcitedStates);
ExcitEnergyChann08.reshape(NumExcitedStates);
ExcitEnergyChann09.reshape(NumExcitedStates);
ExcitEnergyChann10.reshape(NumExcitedStates);
ExcitEnergyChann11.reshape(NumExcitedStates);
ExcitEnergyChann12.reshape(NumExcitedStates);
ExcitEnergyChann13.reshape(NumExcitedStates);
ExcitEnergyChann14.reshape(NumExcitedStates);
ExcitEnergyChann15.reshape(NumExcitedStates);
ExcitEnergyChann16.reshape(NumExcitedStates);
ExcitEnergyChann17.reshape(NumExcitedStates);
ExcitEnergyChann18.reshape(NumExcitedStates);
ExcitEnergyChann19.reshape(NumExcitedStates);
ExcitEnergyChann20.reshape(NumExcitedStates);
ExcitEnergyChann21.reshape(NumExcitedStates);
ExcitEnergyChann22.reshape(NumExcitedStates);
ExcitEnergyChann23.reshape(NumExcitedStates);
ExcitEnergyChann24.reshape(NumExcitedStates);
ExcitEnergyChann25.reshape(NumExcitedStates);
ExcitEnergyChann26.reshape(NumExcitedStates);
ExcitEnergyChann27.reshape(NumExcitedStates);
ExcitEnergyChann28.reshape(NumExcitedStates);
ExcitEnergyChann29.reshape(NumExcitedStates);
ExcitEnergyChann30.reshape(NumExcitedStates);
ExcitEnergyChann31.reshape(NumExcitedStates);
ExcitSpinChann00.reshape(NumExcitedStates);
ExcitSpinChann01.reshape(NumExcitedStates);
ExcitSpinChann02.reshape(NumExcitedStates);
ExcitSpinChann03.reshape(NumExcitedStates);
ExcitSpinChann04.reshape(NumExcitedStates);
ExcitSpinChann05.reshape(NumExcitedStates);
ExcitSpinChann06.reshape(NumExcitedStates);
ExcitSpinChann07.reshape(NumExcitedStates);
ExcitSpinChann08.reshape(NumExcitedStates);
ExcitSpinChann09.reshape(NumExcitedStates);
ExcitSpinChann10.reshape(NumExcitedStates);
ExcitSpinChann11.reshape(NumExcitedStates);
ExcitSpinChann12.reshape(NumExcitedStates);
ExcitSpinChann13.reshape(NumExcitedStates);
ExcitSpinChann14.reshape(NumExcitedStates);
ExcitSpinChann15.reshape(NumExcitedStates);
ExcitSpinChann16.reshape(NumExcitedStates);
ExcitSpinChann17.reshape(NumExcitedStates);
ExcitSpinChann18.reshape(NumExcitedStates);
ExcitSpinChann19.reshape(NumExcitedStates);
ExcitSpinChann20.reshape(NumExcitedStates);
ExcitSpinChann21.reshape(NumExcitedStates);
ExcitSpinChann22.reshape(NumExcitedStates);
ExcitSpinChann23.reshape(NumExcitedStates);
ExcitSpinChann24.reshape(NumExcitedStates);
ExcitSpinChann25.reshape(NumExcitedStates);
ExcitSpinChann26.reshape(NumExcitedStates);
ExcitSpinChann27.reshape(NumExcitedStates);
ExcitSpinChann28.reshape(NumExcitedStates);
ExcitSpinChann29.reshape(NumExcitedStates);
ExcitSpinChann30.reshape(NumExcitedStates);
ExcitSpinChann31.reshape(NumExcitedStates);
for (G4int i = 0; i < NumExcitedStates; i++) {
ExcitEnergyChann00(i) = 0.0;
ExcitEnergyChann01(i) = 0.0;
ExcitEnergyChann02(i) = 0.0;
ExcitEnergyChann03(i) = 0.0;
ExcitEnergyChann04(i) = 0.0;
ExcitEnergyChann05(i) = 0.0;
ExcitEnergyChann06(i) = 0.0;
ExcitEnergyChann07(i) = 0.0;
ExcitEnergyChann08(i) = 0.0;
ExcitEnergyChann09(i) = 0.0;
ExcitEnergyChann10(i) = 0.0;
ExcitEnergyChann11(i) = 0.0;
ExcitEnergyChann12(i) = 0.0;
ExcitEnergyChann13(i) = 0.0;
ExcitEnergyChann14(i) = 0.0;
ExcitEnergyChann15(i) = 0.0;
ExcitEnergyChann16(i) = 0.0;
ExcitEnergyChann17(i) = 0.0;
ExcitEnergyChann18(i) = 0.0;
ExcitEnergyChann19(i) = 0.0;
ExcitEnergyChann20(i) = 0.0;
ExcitEnergyChann21(i) = 0.0;
ExcitEnergyChann22(i) = 0.0;
ExcitEnergyChann23(i) = 0.0;
ExcitEnergyChann24(i) = 0.0;
ExcitEnergyChann25(i) = 0.0;
ExcitEnergyChann26(i) = 0.0;
ExcitEnergyChann27(i) = 0.0;
ExcitEnergyChann28(i) = 0.0;
ExcitEnergyChann29(i) = 0.0;
ExcitEnergyChann30(i) = 0.0;
ExcitEnergyChann31(i) = 0.0;
ExcitSpinChann00(i) = 0;
ExcitSpinChann01(i) = 0;
ExcitSpinChann02(i) = 0;
ExcitSpinChann03(i) = 0;
ExcitSpinChann04(i) = 0;
ExcitSpinChann05(i) = 0;
ExcitSpinChann06(i) = 0;
ExcitSpinChann07(i) = 0;
ExcitSpinChann08(i) = 0;
ExcitSpinChann09(i) = 0;
ExcitSpinChann10(i) = 0;
ExcitSpinChann11(i) = 0;
ExcitSpinChann12(i) = 0;
ExcitSpinChann13(i) = 0;
ExcitSpinChann14(i) = 0;
ExcitSpinChann15(i) = 0;
ExcitSpinChann16(i) = 0;
ExcitSpinChann17(i) = 0;
ExcitSpinChann18(i) = 0;
ExcitSpinChann19(i) = 0;
ExcitSpinChann20(i) = 0;
ExcitSpinChann21(i) = 0;
ExcitSpinChann22(i) = 0;
ExcitSpinChann23(i) = 0;
ExcitSpinChann24(i) = 0;
ExcitSpinChann25(i) = 0;
ExcitSpinChann26(i) = 0;
ExcitSpinChann27(i) = 0;
ExcitSpinChann28(i) = 0;
ExcitSpinChann29(i) = 0;
ExcitSpinChann30(i) = 0;
ExcitSpinChann31(i) = 0;
}
// (in MeV)
// neutrons
ExcitEnergyChann00( 9) = 3.56;
ExcitEnergyChann00(10) = 0.48;
ExcitEnergyChann00(11) = 0.98;
ExcitEnergyChann00(12) = 0.43;
ExcitEnergyChann00(15) = 3.37;
ExcitEnergyChann00(17) = 0.72;
ExcitEnergyChann00(18) = 2.13;
ExcitEnergyChann00(19) = 0.95;
ExcitEnergyChann00(20) = 2.00;
ExcitEnergyChann00(21) = 4.44;
ExcitEnergyChann00(22) = 3.09;
ExcitEnergyChann00(23) = 6.09;
ExcitEnergyChann00(25) = 2.31;
ExcitEnergyChann00(26) = 5.28;
ExcitEnergyChann00(27) = 0.12;
ExcitEnergyChann00(28) = 5.22;
ExcitEnergyChann00(29) = 6.10;
ExcitEnergyChann00(30) = 0.87;
ExcitEnergyChann00(31) = 1.98;
// protons
ExcitEnergyChann01(15) = 5.96;
ExcitEnergyChann01(17) = 1.74;
ExcitEnergyChann01(18) = 4.44;
ExcitEnergyChann01(19) = 1.67;
ExcitEnergyChann01(20) = 4.32;
ExcitEnergyChann01(22) = 3.68;
ExcitEnergyChann01(23) = 6.69;
ExcitEnergyChann01(25) = 3.95;
ExcitEnergyChann01(26) = 6.32;
ExcitEnergyChann01(27) = 0.30;
ExcitEnergyChann01(28) = 6.18;
ExcitEnergyChann01(29) = 6.92;
ExcitEnergyChann01(30) = 3.06;
ExcitEnergyChann01(31) = 3.57;
// deuterons
ExcitEnergyChann02(15) = 6.18;
ExcitEnergyChann02(17) = 2.15;
ExcitEnergyChann02(18) = 5.02;
ExcitEnergyChann02(19) = 2.65;
ExcitEnergyChann02(20) = 4.80;
ExcitEnergyChann02(22) = 3.85;
ExcitEnergyChann02(23) = 6.96;
ExcitEnergyChann02(25) = 4.92;
ExcitEnergyChann02(26) = 7.22;
ExcitEnergyChann02(27) = 0.40;
ExcitEnergyChann02(28) = 6.83;
ExcitEnergyChann02(29) = 7.12;
ExcitEnergyChann02(30) = 3.84;
ExcitEnergyChann02(31) = 3.92;
// tritons
ExcitEnergyChann03(15) = 6.26;
ExcitEnergyChann03(17) = 3.59;
ExcitEnergyChann03(18) = 6.76;
ExcitEnergyChann03(20) = 6.34;
ExcitEnergyChann03(23) = 7.34;
ExcitEnergyChann03(25) = 5.11;
ExcitEnergyChann03(26) = 7.57;
ExcitEnergyChann03(28) = 7.28;
ExcitEnergyChann03(31) = 4.46;
// He3
ExcitEnergyChann04(18) = 7.29;
ExcitEnergyChann04(20) = 6.48;
ExcitEnergyChann04(25) = 5.69;
ExcitEnergyChann04(26) = 8.31;
ExcitEnergyChann04(31) = 5.10;
// alphas
ExcitEnergyChann05(18) = 7.98;
ExcitEnergyChann05(20) = 6.90;
ExcitEnergyChann05(25) = 5.83;
ExcitEnergyChann05(26) = 8.57;
ExcitEnergyChann05(31) = 5.33;
// He5
ExcitEnergyChann06(18) = 8.56;
ExcitEnergyChann06(20) = 7.50;
ExcitEnergyChann06(25) = 6.20;
ExcitEnergyChann06(26) = 9.15;
ExcitEnergyChann06(31) = 5.53;
// He6
ExcitEnergyChann07(20) = 8.10;
ExcitEnergyChann07(25) = 6.44;
ExcitEnergyChann07(26) = 9.79;
ExcitEnergyChann07(31) = 6.20;
// Li5
ExcitEnergyChann08(20) = 8.42;
ExcitEnergyChann08(25) = 7.03;
ExcitEnergyChann08(26) = 10.0;
ExcitEnergyChann08(31) = 6.38;
// Li6
ExcitEnergyChann09(20) = 8.66;
ExcitEnergyChann09(31) = 6.88;
// Spin (2s+1)
// neutrons
ExcitSpinChann00( 9) = 1;
ExcitSpinChann00(10) = 2;
ExcitSpinChann00(11) = 3;
ExcitSpinChann00(12) = 2;
ExcitSpinChann00(15) = 5;
ExcitSpinChann00(17) = 3;
ExcitSpinChann00(18) = 2;
ExcitSpinChann00(19) = 5;
ExcitSpinChann00(20) = 2;
ExcitSpinChann00(21) = 5;
ExcitSpinChann00(22) = 2;
ExcitSpinChann00(23) = 3;
ExcitSpinChann00(25) = 1;
ExcitSpinChann00(26) = 8;
ExcitSpinChann00(27) = 1;
ExcitSpinChann00(28) = 8;
ExcitSpinChann00(29) = 8;
ExcitSpinChann00(30) = 2;
ExcitSpinChann00(31) = 5;
// protons
ExcitSpinChann01(15) = 8;
ExcitSpinChann01(17) = 1;
ExcitSpinChann01(18) = 6;
ExcitSpinChann01(19) = 5;
ExcitSpinChann01(20) = 6;
ExcitSpinChann01(22) = 4;
ExcitSpinChann01(23) = 8;
ExcitSpinChann01(25) = 3;
ExcitSpinChann01(26) = 4;
ExcitSpinChann01(27) = 7;
ExcitSpinChann01(28) = 4;
ExcitSpinChann01(29) = 5;
ExcitSpinChann01(30) = 2;
ExcitSpinChann01(31) = 10;
// deuterons
ExcitSpinChann02(15) = 1;
ExcitSpinChann02(17) = 3;
ExcitSpinChann02(18) = 4;
ExcitSpinChann02(19) = 4;
ExcitSpinChann02(20) = 4;
ExcitSpinChann02(22) = 6;
ExcitSpinChann02(23) = 6;
ExcitSpinChann02(25) = 1;
ExcitSpinChann02(26) = 10;
ExcitSpinChann02(27) = 3;
ExcitSpinChann02(28) = 10;
ExcitSpinChann02(29) = 3;
ExcitSpinChann02(30) = 6;
ExcitSpinChann02(31) = 5;
// tritons
ExcitSpinChann03(15) = 5;
ExcitSpinChann03(17) = 5;
ExcitSpinChann03(18) = 10;
ExcitSpinChann03(20) = 2;
ExcitSpinChann03(23) = 5;
ExcitSpinChann03(25) = 5;
ExcitSpinChann03(26) = 8;
ExcitSpinChann03(28) = 8;
ExcitSpinChann03(31) = 3;
// He3
ExcitSpinChann04(18) = 6;
ExcitSpinChann04(20) = 8;
ExcitSpinChann04(25) = 3;
ExcitSpinChann04(26) = 2;
ExcitSpinChann04(31) = 7;
// alphas
ExcitSpinChann05(18) = 4;
ExcitSpinChann05(20) = 6;
ExcitSpinChann05(25) = 7;
ExcitSpinChann05(26) = 4;
ExcitSpinChann05(31) = 13;
// He5
ExcitSpinChann06(18) = 6;
ExcitSpinChann06(20) = 4;
ExcitSpinChann06(25) = 3;
ExcitSpinChann06(26) = 14;
ExcitSpinChann06(31) = 5;
// He6
ExcitSpinChann07(20) = 4;
ExcitSpinChann07(25) = 7;
ExcitSpinChann07(26) = 14;
ExcitSpinChann07(31) = 3;
// Li5
ExcitSpinChann08(20) = 6;
ExcitSpinChann08(25) = 5;
ExcitSpinChann08(26) = 8;
ExcitSpinChann08(31) = 12;
// Li6
ExcitSpinChann09(20) = 8;
ExcitSpinChann09(31) = 1;
// |Gamma|A| Z|
// +-----+-+--+
theChannels[ 0] = new G4EvaporationChannel( 2, 1, 0, &ExcitEnergyChann00, &ExcitSpinChann00); // n
theChannels[ 1] = new G4EvaporationChannel( 2, 1, 1, &ExcitEnergyChann01, &ExcitSpinChann01); // p
theChannels[ 2] = new G4EvaporationChannel( 6, 2, 1, &ExcitEnergyChann02, &ExcitSpinChann02); // H2
theChannels[ 3] = new G4EvaporationChannel( 6, 3, 1, &ExcitEnergyChann03, &ExcitSpinChann03); // H3
theChannels[ 4] = new G4EvaporationChannel( 6, 3, 2, &ExcitEnergyChann04, &ExcitSpinChann04); // He3
theChannels[ 5] = new G4EvaporationChannel( 4, 4, 2, &ExcitEnergyChann05, &ExcitSpinChann05); // He4
theChannels[ 6] = new G4EvaporationChannel( 20, 5, 2, &ExcitEnergyChann06, &ExcitSpinChann06); // He5
theChannels[ 7] = new G4EvaporationChannel( 30, 6, 2, &ExcitEnergyChann07, &ExcitSpinChann07); // He6
theChannels[ 8] = new G4EvaporationChannel( 20, 5, 3, &ExcitEnergyChann08, &ExcitSpinChann08); // Li5
theChannels[ 9] = new G4EvaporationChannel( 54, 6, 3, &ExcitEnergyChann09, &ExcitSpinChann09); // Li6
theChannels[10] = new G4EvaporationChannel( 73, 7, 3, &ExcitEnergyChann10, &ExcitSpinChann10); // Li7
theChannels[11] = new G4EvaporationChannel(101, 8, 3, &ExcitEnergyChann11, &ExcitSpinChann11); // Li8
theChannels[12] = new G4EvaporationChannel( 73, 7, 4, &ExcitEnergyChann12, &ExcitSpinChann12); // Be7
theChannels[13] = new G4EvaporationChannel( 8, 8, 4, &ExcitEnergyChann13, &ExcitSpinChann13); // Be8
theChannels[14] = new G4EvaporationChannel(146, 9, 4, &ExcitEnergyChann14, &ExcitSpinChann14); // Be9
theChannels[15] = new G4EvaporationChannel(100, 10, 4, &ExcitEnergyChann15, &ExcitSpinChann15); // Be10
theChannels[16] = new G4EvaporationChannel(100, 9, 5, &ExcitEnergyChann16, &ExcitSpinChann16); // B9
theChannels[17] = new G4EvaporationChannel(343, 10, 5, &ExcitEnergyChann17, &ExcitSpinChann17); // B10
theChannels[18] = new G4EvaporationChannel(174, 11, 5, &ExcitEnergyChann18, &ExcitSpinChann18); // B11
theChannels[19] = new G4EvaporationChannel(393, 12, 5, &ExcitEnergyChann19, &ExcitSpinChann19); // B12
theChannels[20] = new G4EvaporationChannel(186, 11, 6, &ExcitEnergyChann20, &ExcitSpinChann20); // C11
theChannels[21] = new G4EvaporationChannel( 61, 12, 6, &ExcitEnergyChann21, &ExcitSpinChann21); // C12
theChannels[22] = new G4EvaporationChannel(202, 13, 6, &ExcitEnergyChann22, &ExcitSpinChann22); // C13
theChannels[23] = new G4EvaporationChannel(113, 14, 6, &ExcitEnergyChann23, &ExcitSpinChann23); // C14
theChannels[24] = new G4EvaporationChannel(213, 13, 7, &ExcitEnergyChann24, &ExcitSpinChann24); // N13
theChannels[25] = new G4EvaporationChannel(233, 14, 7, &ExcitEnergyChann25, &ExcitSpinChann25); // N14
theChannels[26] = new G4EvaporationChannel(180, 15, 7, &ExcitEnergyChann26, &ExcitSpinChann26); // N15
theChannels[27] = new G4EvaporationChannel(696, 16, 7, &ExcitEnergyChann27, &ExcitSpinChann27); // N16
theChannels[28] = new G4EvaporationChannel(194, 15, 8, &ExcitEnergyChann28, &ExcitSpinChann28); // O15
theChannels[29] = new G4EvaporationChannel(120, 16, 8, &ExcitEnergyChann29, &ExcitSpinChann29); // O16
theChannels[30] = new G4EvaporationChannel(458, 17, 8, &ExcitEnergyChann30, &ExcitSpinChann30); // O17
theChannels[31] = new G4EvaporationChannel(590, 18, 8, &ExcitEnergyChann31, &ExcitSpinChann31); // O18
theChannels[32] = new G4CompetitiveFission(); // Fission Channel
theChannels[33] = new G4PhotonEvaporation(); // Photon Channel
}
G4Evaporation::G4Evaporation(const G4Evaporation &right)
{
G4Exception("G4Evaporation::copy_constructor meant to not be accessable.");
}
G4Evaporation::~G4Evaporation()
{
for (G4int i = 0; i < TotNumberOfChannels; i++)
delete theChannels[i];
}
const G4Evaporation & G4Evaporation::operator=(const G4Evaporation &right)
{
G4Exception("G4Evaporation::operator= meant to not be accessable.");
return *this;
}
G4bool G4Evaporation::operator==(const G4Evaporation &right) const
{
return false;
}
G4bool G4Evaporation::operator!=(const G4Evaporation &right) const
{
return true;
}
G4FragmentVector * G4Evaporation::BreakItUp(const G4Fragment &theNucleus)
{
G4FragmentVector * theResult = new G4FragmentVector;
// CHECK that Excitation Energy != 0
if (theNucleus.GetExcitationEnergy() == 0) {
theResult->insert(new G4Fragment(theNucleus));
return theResult;
}
// The residual nucleus (after evaporation of each fragment)
G4Fragment theResidualNucleus = theNucleus;
// Starts loop over evaporated particles
for (;;) {
// loop over evaporation channels
G4int i;
for (i=0; i < TotNumberOfChannels; i++)
theChannels[i]->Initialize(theResidualNucleus);
// Work out total decay probability by summing over channels
G4double TotalProbability = 0;
for (i=0; i < TotNumberOfChannels; i++)
TotalProbability += theChannels[i]->GetEmissionProbability();
// G4cout << "---------------- " << theResidualNucleus.GetExcitationEnergy()/MeV << "-----------------------" << endl;
// G4cout << "Prob of neutron: " << theChannels[0]->GetEmissionProbability()/TotalProbability << endl;
// G4cout << "Prob of proton : " << theChannels[1]->GetEmissionProbability()/TotalProbability<< endl;
// G4cout << "Prob of alpha : " << theChannels[5]->GetEmissionProbability()/TotalProbability<< endl;
// G4cout << "Prob of fission: " << theChannels[NumberOfFissionChannel]->GetEmissionProbability()/TotalProbability<< endl;
if (TotalProbability <= 0.0) {
// Will be no evaporation more
// write information about residual nucleus
theResult->insert(new G4Fragment(theResidualNucleus));
break;
} else {
// Selection of evaporation channel, fission or gamma
G4double EmissionProbChannel[TotNumberOfChannels];
EmissionProbChannel[0] = theChannels[0]->GetEmissionProbability();
for (i=1; i < TotNumberOfChannels; i++)
EmissionProbChannel[i] = EmissionProbChannel[i-1] + theChannels[i]->GetEmissionProbability();
G4double shoot = G4UniformRand() * TotalProbability;
for (i=0; i < TotNumberOfChannels; i++)
if (shoot < EmissionProbChannel[i])
break;
if( i == TotNumberOfChannels )
G4Exception( "Can't define emission probability of the channels (G4Evaporation::BreakItUp)" );
else if (i == NumberOfFissionChannel) {
// Fission has to be performed
G4FragmentVector * theFissionResult = theChannels[i]->BreakUp(theResidualNucleus);
while (theFissionResult->entries() > 0)
theResult->insert(theFissionResult->removeFirst());
theFissionResult->clearAndDestroy();
delete theFissionResult;
break;
} else if (i == NumberOfGammaChannel) {
// Gamma evaporation has to be performed
G4FragmentVector * theGammaResult = theChannels[i]->BreakUp(theResidualNucleus);
while (theGammaResult->entries() > 0)
theResult->insert(theGammaResult->removeFirst());
theGammaResult->clearAndDestroy();
delete theGammaResult;
break;
} else {
// Evaporation has to be performed
G4FragmentVector * theEvaporationResult = theChannels[i]->BreakUp(theResidualNucleus);
while (theEvaporationResult->entries() > 1)
theResult->insert(theEvaporationResult->removeFirst());
theResidualNucleus = *(theEvaporationResult->at(0));
theEvaporationResult->clearAndDestroy();
delete theEvaporationResult;
}
}
}
return theResult;
}
@@ -0,0 +1,310 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
// some corrections V.Krylov
//
#include "G4EvaporationChannel.hh"
G4EvaporationChannel::G4EvaporationChannel(const G4int theGamma,
const G4int theA,
const G4int theZ,
RWTValVector<G4double> * theExcitationEnergies,
RWTValVector<G4int> * theExcitationSpins):
Gamma(theGamma),
A(theA),
Z(theZ),
ExcitationEnergies(theExcitationEnergies),
ExcitationSpins(theExcitationSpins),
AResidual(0),
ZResidual(0),
CoulombBarrier(0.0),
BindingEnergy(0.0),
MaximalKineticEnergy(-1000.0),
EmissionProbability(0.0)
{
theEvaporationProbabilityPtr = new G4EvaporationProbability(this);
MyOwnEvaporationProbability = true;
theLevelDensityPtr = new G4EvaporationLevelDensityParameter;
MyOwnLevelDensity = true;
}
G4EvaporationChannel::~G4EvaporationChannel()
{
if (MyOwnEvaporationProbability) delete theEvaporationProbabilityPtr;
if (MyOwnLevelDensity) delete theLevelDensityPtr;
}
G4EvaporationChannel::G4EvaporationChannel(const G4EvaporationChannel & right)
{
G4Exception("G4EvaporationChannel::copy_costructor meant to not be accessable");
}
const G4EvaporationChannel & G4EvaporationChannel::operator=(const G4EvaporationChannel & right)
{
G4Exception("G4EvaporationChannel::operator= meant to not be accessable");
return *this;
}
G4bool G4EvaporationChannel::operator==(const G4EvaporationChannel & right) const
{
return (this == (G4EvaporationChannel *) &right);
// return false;
}
G4bool G4EvaporationChannel::operator!=(const G4EvaporationChannel & right) const
{
return (this != (G4EvaporationChannel *) &right);
// return true;
}
void G4EvaporationChannel::Initialize(const G4Fragment & fragment)
{
G4int anA = fragment.GetA();
G4int aZ = fragment.GetZ();
G4double ExEnergy = fragment.GetExcitationEnergy();
AResidual = anA - A;
ZResidual = aZ - Z;
// We only take into account channels which are physically allowed
if (AResidual <= 0 || ZResidual <= 0 || AResidual < ZResidual ||
(AResidual == ZResidual && AResidual > 1)) {
LevelDensityParameter = 0.0;
CoulombBarrier = 0.0;
BindingEnergy = 0.0;
MaximalKineticEnergy = -1000.0*MeV;
EmissionProbability = 0.0;
} else {
// Get Level Density
LevelDensityParameter = theLevelDensityPtr->LevelDensityParameter(anA,aZ,ExEnergy);
// Coulomb Barrier calculation
CoulombBarrier = CalcCoulombBarrier(AResidual,ZResidual)*MeV;
// Binding Enegy (for separate fragment from nucleus)
BindingEnergy = CalcBindingEnergy(anA,aZ)*MeV;
// Maximal Kinetic Energy
MaximalKineticEnergy = CalcMaximalKineticEnergy(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(aZ,anA)+ExEnergy)*MeV;
// Emission probability
if (MaximalKineticEnergy <= 0.0) EmissionProbability = 0.0;
else {
// Total emission probability for this channel
EmissionProbability = theEvaporationProbabilityPtr->EmissionProbability(fragment,0.0);
// Next is a loop over excited states for this channel summing probabilities
G4double SavedGamma = Gamma;
G4double SavedMaximalKineticEnergy = MaximalKineticEnergy;
for (G4int i = 0; i < ExcitationEnergies->length(); i++) {
if (ExcitationSpins->operator()(i) < 0.1) continue;
Gamma = ExcitationSpins->operator()(i)*A;
// substract excitation energies
MaximalKineticEnergy -= ExcitationEnergies->operator()(i)/MeV;
// update probability
G4double tmp = theEvaporationProbabilityPtr->EmissionProbability(fragment,0.0);
EmissionProbability += tmp;
}
// restore Gamma and MaximalKineticEnergy
MaximalKineticEnergy = SavedMaximalKineticEnergy;
Gamma = SavedGamma;
}
}
return;
}
G4FragmentVector * G4EvaporationChannel::BreakUp(const G4Fragment & theNucleus)
{
// calculate kinetic energy of evaporated fragment
G4double EvaporatedKineticEnergy = CalcKineticEnergy(); // MeV
G4double EvaporatedMass = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(Z,A)/MeV; // MeV
G4double EvaporatedEnergy = EvaporatedKineticEnergy + EvaporatedMass;
G4ThreeVector momentum( IsotropicVector( sqrt( EvaporatedEnergy*EvaporatedEnergy -
EvaporatedMass*EvaporatedMass )
) );
G4LorentzVector EvaporatedMomentum( momentum, EvaporatedEnergy );
EvaporatedMomentum.boost( theNucleus.GetMomentum().boostVector() );
G4Fragment * EvaporatedFragment = new G4Fragment( A, Z, EvaporatedMomentum );
if ( !EvaporatedFragment )
G4Exception( "G4EvaporationChannel::BreakUp: Can't create G4Fragment! ");
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! ");
G4FragmentVector * theResult = new G4FragmentVector;
if ( !theResult )
G4Exception( "G4EvaporationChannel::BreakUp: Can't create G4FragmentVector! ");
theResult->insert(EvaporatedFragment);
theResult->insert(ResidualFragment);
return theResult;
}
G4double G4EvaporationChannel::CalcCoulombBarrier(const G4int ARes, const G4int ZRes)
// Calculation of Coulomb potential energy (barrier) in MeV for outgoing fragment
{
G4double Barrier = 0.0;
if (Z == 0 && A == 1) return 0.0; // for neutron
else {
G4int nZZRes = Z * ZRes;
G4double r0 = 2.173*(1.0+0.006103 * nZZRes)/(1.0+0.009443 * nZZRes);
Barrier = 1.44/r0 * nZZRes / (pow( A,1./3. ) + pow( ARes,1./3. ));
}
return Barrier;
}
G4double G4EvaporationChannel::CalcBindingEnergy(const G4int anA, const G4int aZ)
// Calculate Binding Energy for separate fragment from nucleus
{
// Mass Excess for residual nucleus
G4double ResNucMassExcess = G4NucleiProperties::GetMassExcess(AResidual,ZResidual)/MeV;
// Mass Excess for fragment
G4double FragmentMassExcess = G4NucleiProperties::GetMassExcess(A,Z)/MeV;
// Mass Excess for Nucleus
G4double NucleusMassExcess = G4NucleiProperties::GetMassExcess(anA,aZ)/MeV;
return ResNucMassExcess + FragmentMassExcess - NucleusMassExcess;
}
G4double G4EvaporationChannel::CalcMaximalKineticEnergy(const G4double NucleusTotalE)
// Calculate maximal kinetic energy that can be carried by fragment (in MeV)
{
// // Odd-Even term correction (for maximal kinetic energy)
// G4double odd = 0.0;
// if (A < 65) {
// G4int NCorr = A - Z;
// NCorr = 2*(NCorr/2) - NCorr;
// G4int ZCorr = 2*(Z/2) - Z;
// odd = 11.0*(2+NCorr+ZCorr)/sqrt(G4double(A));
// }
// if (A <= 55) return U/MeV -
// (BindingEnergy + CoulombBarrier)/MeV - odd;
// else if (A > 55 && A < 65) return U/MeV -
// (BindingEnergy + CoulombBarrier)/MeV -
// odd * (1.0 - (A-55)/10.);
// else return U/MeV - (BindingEnergy + CoulombBarrier);
G4double ResidualMass = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass( ZResidual, AResidual )/MeV;
G4double EvaporatedMass = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass( Z, A )/MeV;
return ( (NucleusTotalE/MeV)*(NucleusTotalE/MeV) +
EvaporatedMass*EvaporatedMass - ResidualMass*ResidualMass)/
(2.0*NucleusTotalE ) -
EvaporatedMass - CoulombBarrier/MeV;
}
G4double G4EvaporationChannel::CalcKineticEnergy(void)
// Samples fragment kinetic energy (in MeV).
// It uses Dostrovsky's approximation for the inverse reaction cross
// in the probability for fragment emisson
{
if (MaximalKineticEnergy < 0.0)
G4Exception("G4EvaporationChannel::CalcKineticEnergy: maximal kinetic energy is less than 0");
// G4double Rb = 4.0*LevelDensityParameter/(1./MeV)*AResidual*MaximalKineticEnergy/MeV;
// G4double RbSqrt = sqrt(Rb);
// G4double PEX1 = 0.0;
// if (RbSqrt < 160.0) PEX1 = exp(-RbSqrt);
// G4double Rk = 0.0;
// G4double FRk = 0.0;
// do {
// G4double RandNumber = G4UniformRand();
// Rk = 1.0 + (1./RbSqrt)*log(RandNumber + (1.0-RandNumber)*PEX1);
// G4double Q1 = 1.0;
// G4double Q2 = 1.0;
// if (Z == 0) { // for emitted neutron
// G4double Beta = (2.12/pow(AResidual,2./3.) - 0.05)/
// (0.76 + 2.2/pow(AResidual,1./3.));
// Q1 = 1.0 + Beta/(MaximalKineticEnergy/MeV);
// Q2 = Q1*sqrt(Q1);
// }
// FRk = (3.0*sqrt(3.0)/2.0)/Q2 * Rk * (Q1 - Rk*Rk);
// } while (FRk < G4UniformRand());
G4double Rb = 4.0*LevelDensityParameter/(1./MeV)*AResidual*(MaximalKineticEnergy)/MeV;
G4double RbSqrt = sqrt(Rb);
G4double PEX1 = 0.0;
if (RbSqrt < 160.0) PEX1 = exp(-RbSqrt);
G4double Rk = 0.0;
G4double FRk = 0.0;
do {
G4double RandNumber = G4UniformRand();
Rk = 1.0 + (1./RbSqrt)*log(RandNumber + (1.0-RandNumber)*PEX1);
G4double Q1 = 1.0;
G4double Q2 = 1.0;
if (Z == 0) { // for emitted neutron
G4double Beta = (2.12/pow(AResidual,2./3.) - 0.05)/
(0.76 + 2.2/pow(AResidual,1./3.));
Q1 = 1.0 + Beta/(MaximalKineticEnergy/MeV);
Q2 = Q1*sqrt(Q1);
}
FRk = (3.0*sqrt(3.0)/2.0)/Q2 * Rk * (Q1 - Rk*Rk);
} while (FRk < G4UniformRand());
G4double result = (MaximalKineticEnergy)/MeV * (1.0-Rk*Rk) + CoulombBarrier/MeV;
return result;
}
G4ThreeVector G4EvaporationChannel::IsotropicVector(const G4double Magnitude)
// Samples a isotropic random vectorwith a magnitud given by Magnitude.
// By default Magnitude = 1.0
{
G4double CosTheta = 1.0 - 2.0*G4UniformRand();
G4double SinTheta = sqrt(1.0 - CosTheta*CosTheta);
G4double Phi = twopi*G4UniformRand();
G4ThreeVector Vector(Magnitude*cos(Phi)*SinTheta,
Magnitude*sin(Phi)*SinTheta,
Magnitude*CosTheta);
return Vector;
}
@@ -0,0 +1,47 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
//
#include "G4EvaporationLevelDensityParameter.hh"
//const G4double G4EvaporationLevelDensityParameter::EvapLevelDensityParameter = 0.125*(1./MeV);
G4EvaporationLevelDensityParameter::
G4EvaporationLevelDensityParameter(const G4EvaporationLevelDensityParameter &right) :
EvapLevelDensityParameter(0.125*(1./MeV))
{
G4Exception("G4EvaporationLevelDensityParameter::copy_constructor meant to not be accessable");
}
const G4EvaporationLevelDensityParameter & G4EvaporationLevelDensityParameter::
operator=(const G4EvaporationLevelDensityParameter &right)
{
G4Exception("G4EvaporationLevelDensityParameter::operator= meant to not be accessable");
return *this;
}
G4bool G4EvaporationLevelDensityParameter::operator==(const G4EvaporationLevelDensityParameter &right) const
{
return false;
}
G4bool G4EvaporationLevelDensityParameter::operator!=(const G4EvaporationLevelDensityParameter &right) const
{
return true;
}
@@ -0,0 +1,185 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
//
#include "G4EvaporationProbability.hh"
G4EvaporationProbability::G4EvaporationProbability(const G4EvaporationProbability &right)
{
G4Exception("G4EvaporationProbability::copy_constructor meant to not be accessable");
}
const G4EvaporationProbability & G4EvaporationProbability::
operator=(const G4EvaporationProbability &right)
{
G4Exception("G4EvaporationProbability::operator= meant to not be accessable");
return *this;
}
G4bool G4EvaporationProbability::operator==(const G4EvaporationProbability &right) const
{
return false;
}
G4bool G4EvaporationProbability::operator!=(const G4EvaporationProbability &right) const
{
return true;
}
G4double G4EvaporationProbability::EmissionProbability(const G4Fragment & fragment, const G4double photonExcitation)
// Calculate integrated probability (width) for rvaporation channel:
// If fragment has A_f <= 4 it will be used Dostrovsky's
// approximation for the inverse reaction cross section. If
// fragment has A_f > 4 it will be used Botvina's approximation for
// the inverse reaction cross section.
{
// first af all a test
if (theChannel->GetMaximalKineticEnergy() <= 0.0 || fragment.GetExcitationEnergy() <= 0.0) return 0.0;
// We take decision on which approximation we'll use.
if (theChannel->GetA() <= 4) return DostrovskyApproximation(fragment.GetA(),fragment.GetExcitationEnergy());
else return BotvinaApproximation(fragment.GetA(),fragment.GetExcitationEnergy());
}
G4double G4EvaporationProbability::DostrovskyApproximation(const G4int A, const G4double U)
// Width for evaporation channel with Dostrovsky's approximation for
// inverse cross section.
{
G4double SystemEntropy = 2.0*sqrt((theChannel->GetLevelDensityParameter()/(1./MeV)) *
A * U/MeV);
// r0 -> Absorption Radius R=r0 A^(1/3)
G4double r0 = 2.173*(1.0+0.006103*theChannel->GetZ()*theChannel->GetResidualZ())/
(1.0+0.009443*theChannel->GetZ()*theChannel->GetResidualZ());
// compute the integrated probability of evaporation channel
G4double RN = 1.5;
G4double CC;
if (theChannel->GetA() == 1) CC = 0.2; // neutron, proton
// deuterium, triton, alpha,
else if ((theChannel->GetZ() == 1 && (theChannel->GetA() == 2 || theChannel->GetA() == 3)) ||
(theChannel->GetZ() == 2 && (theChannel->GetA() == 3 || theChannel->GetA() == 4)))
CC = 0.1;
// He5, He6, Li5, Li6, ...., O17, O18
else CC = pow(G4double(theChannel->GetA())/G4double(theChannel->GetResidualA()),2.0/3.0);
G4double ALFA;
G4double BETA;
if (theChannel->GetZ() == 0) { // neutron
ALFA = 0.76+2.2/pow(theChannel->GetResidualA(),1.0/3.0);
BETA = (2.12/pow(theChannel->GetResidualA(),2.0/3.0) - 0.05)/ALFA;
} else {
ALFA = 1.0 + CC;
BETA = 0.0;
}
G4double Q1 = (theChannel->GetLevelDensityParameter()/(1./MeV)) * theChannel->GetResidualA();
G4double Q2 = Q1*theChannel->GetMaximalKineticEnergy()/MeV;
G4double Q3 = (theChannel->GetGamma()*pow(theChannel->GetResidualA(),2.0/3.0))*(ALFA/(Q1*Q1))*
(G4double(theChannel->GetResidualA())/G4double(theChannel->GetResidualA()+theChannel->GetA()))*
(pi*RN*RN)/(2.0*41.5*pi2);
G4double Q4 = (2.0*BETA*Q1-3.0)/2.0 + Q2;
G4double Q5 = (2.0*BETA*Q1-3.0)*(sqrt(Q2)-0.5)+2.0*Q2;
G4double PEX1;
if (SystemEntropy > 160.0) PEX1 = 0.0;
else PEX1 = Q4*exp(-SystemEntropy);
G4double PP2 = SystemEntropy - 2.0*sqrt(Q2);
G4double PEX2;
if (PP2 > 160.0) PEX2 = 0.0;
else PEX2 = Q5*exp(-PP2);
return Q3*(PEX1+PEX2);
}
G4double G4EvaporationProbability::BotvinaApproximation(const G4int A, const G4double U)
// Width for evaporation channel with Botvina's approximation for
// inverse cross section.
{
G4double SystemEntropy = 2.0*sqrt((theChannel->GetLevelDensityParameter()/(1./MeV))*
A * U/MeV);
// r0 -> Absorption Radius R=r0 A^(1/3)
G4double r0 = 2.173*(1.0+0.006103*theChannel->GetZ()*theChannel->GetResidualZ())/
(1.0+0.009443*theChannel->GetZ()*theChannel->GetResidualZ());
// compute the integrated probability of evaporation channel
G4double DALF = 0.869+9.91/theChannel->GetResidualZ();
G4double KinPlusCoul = theChannel->GetMaximalKineticEnergy()/MeV + theChannel->GetCoulombBarrier()/MeV;
if (KinPlusCoul <= theChannel->GetCoulombBarrier()/(5.0*MeV) || theChannel->GetZ() == 0) return 0.0;
G4double CC = pow(G4double(theChannel->GetA())/G4double(theChannel->GetResidualA()),2.0/3.0);
G4double ALFA = 1.0+CC;
G4double Q1 = (theChannel->GetLevelDensityParameter()/(1./MeV)) * theChannel->GetResidualA();
G4double Q3 = theChannel->GetGamma() * pow(theChannel->GetResidualA(),2.0/3.0) * (ALFA/(Q1*Q1))
*(G4double(theChannel->GetResidualA())/G4double(theChannel->GetResidualA()+theChannel->GetA()))*
((pi*r0*r0)/(2.0*41.5*pi2));
G4double TempMKE = theChannel->GetMaximalKineticEnergy()/MeV - 1.0;
G4double prob3 = 0.0;
if (TempMKE > 0.0) {
G4double Q2 = Q1*TempMKE;
G4double Q4 = (2.0*Q1-3.0)/2.0 + Q2;
G4double Q5 = (2.0*Q1-3.0)*(sqrt(Q2)-0.5)+2.0*Q2;
prob3 = Q3*(Q4*exp(-SystemEntropy)+Q5*exp(2.0*sqrt(Q2)-SystemEntropy));
}
G4double EX = theChannel->GetCoulombBarrier()/MeV + 1.0;
G4double EM = KinPlusCoul-Q1/(DALF*DALF);
G4double prob4 = 0.0;
G4double SQ = 0.0;
G4double CSI = 0.0;
G4double F1CSI = 0.0;
if (EM >= EX) {
SQ = sqrt(Q1/(KinPlusCoul-EX));
G4double F1X = DALF-SQ;
G4double F2X = SQ/(2.0*(KinPlusCoul-EX));
if (F1X >= (0.5*F2X)) {
CSI = 0.693/F1X;
G4double SQCSI = sqrt(Q1/(KinPlusCoul-EX+CSI));
G4double F2CSI = SQCSI/(2.0*(KinPlusCoul-EX+CSI));
prob4 = Q3*2.0*Q1*Q1*(1.0/F1X)*
exp(2.0*sqrt(Q1*(KinPlusCoul-EX))-SystemEntropy-F2CSI*CSI*CSI/2.0);
} else {
CSI = 0.48/sqrt(0.5*F2X);
F1CSI = DALF-sqrt(Q1/(KinPlusCoul-EX+CSI));
prob4 = Q3*Q1*Q1*sqrt(6.2832/F2X)*
exp(2.0*sqrt(Q1*(KinPlusCoul-EX))-SystemEntropy-F1CSI*CSI);
}
} else if (EM < EX && EM > theChannel->GetCoulombBarrier()/(5.0*MeV)) {
SQ = sqrt(Q1/(KinPlusCoul-EM));
G4double F2M = SQ/(2.0*(KinPlusCoul-EM));
CSI = 0.48/sqrt(0.5*F2M);
F1CSI = DALF - sqrt(Q1/(KinPlusCoul-EM+CSI));
prob4 = Q3*2.0*Q1*Q1*sqrt(6.2832/F2M)*
exp(DALF*(EM-EX)+2.0*sqrt(Q1*(KinPlusCoul-EM))-SystemEntropy-F1CSI*CSI);
} else return prob3;
return prob3+prob4;
}
@@ -0,0 +1,249 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// 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 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
// Modif (30 June 1998) by V. Lara:
// -Modified the Transform method for use G4ParticleTable and
// therefore G4IonTable. It makes possible to convert all kind
// of fragments (G4Fragment) produced in deexcitation to
// G4DynamicParticle
// -It uses default algorithms for:
// Evaporation: G4StatEvaporation
// MultiFragmentation: G4DummyMF (a dummy one)
// Fermi Breakup model: G4StatFermiBreakUp
#include "G4ExcitationHandler.hh"
G4ExcitationHandler::G4ExcitationHandler():MyOwnEvaporationClass(true),
MyOwnMultiFragmentationClass(true),MyOwnFermiBreakUpClass(true),
MyOwnPhotonEvaporationClass(true),
maxAForFermiBreakUp(16),maxZForFermiBreakUp(8),minEForMultiFrag(1000.0*MeV) // make Multifrag. unavailable
{ // change by 3.0
theTableOfParticles = G4ParticleTable::GetParticleTable();
theEvaporation = new G4Evaporation;
theMultiFragmentation = new G4StatMF;
theFermiModel = new G4FermiBreakUp;
thePhotonEvaporation = new G4PhotonEvaporation;
}
G4ExcitationHandler::G4ExcitationHandler(const G4ExcitationHandler &right)
{
G4Exception("G4ExcitationHandler::copy_constructor: is meant to not be accessable! ");
}
G4ExcitationHandler::~G4ExcitationHandler()
{
if (MyOwnEvaporationClass) delete theEvaporation;
if (MyOwnMultiFragmentationClass) delete theMultiFragmentation;
if (MyOwnFermiBreakUpClass) delete theFermiModel;
if (MyOwnPhotonEvaporationClass) delete thePhotonEvaporation;
}
const G4ExcitationHandler & G4ExcitationHandler::operator=(const G4ExcitationHandler &right)
{
G4Exception("G4ExcitationHandler::operator=: is meant to not be accessable! ");
return *this;
}
G4bool G4ExcitationHandler::operator==(const G4ExcitationHandler &right) const
{
G4Exception("G4ExcitationHandler::operator==: is meant to not be accessable! ");
return false;
}
G4bool G4ExcitationHandler::operator!=(const G4ExcitationHandler &right) const
{
G4Exception("G4ExcitationHandler::operator!=: is meant to not be accessable! ");
return true;
}
G4DynamicParticleVector * G4ExcitationHandler::BreakItUp(const G4Fragment &theInitialState) const
{
G4FragmentVector* theResult = 0;
G4double exEnergy = theInitialState.GetExcitationEnergy();
G4double A = theInitialState.GetA();
G4int Z = theInitialState.GetZ();
G4int Zmax = GetMaxZ();
G4double Amax = GetMaxA();
// Initial State De-Excitation
if(A<GetMaxA()&&Z<GetMaxZ()) {
theResult = theFermiModel->BreakItUp(theInitialState);
} else if (exEnergy>GetMinE()*A) {
theResult = theMultiFragmentation->BreakItUp(theInitialState);
} else {
theResult = theEvaporation->BreakItUp(theInitialState);
}
// De-Excitation loop
G4Fragment theExcitedNucleus;
G4FragmentVector* theTempResult = 0;
// Check if there are excited fragments
G4int i;
for (i = 0; i < theResult->entries(); i++) {
exEnergy = theResult->at(i)->GetExcitationEnergy();
if (exEnergy > 0.0) {
A = theResult->at(i)->GetA();
Z = theResult->at(i)->GetZ();
theExcitedNucleus = *(theResult->at(i));
// try to de-excite this fragment
if(A<GetMaxA()&&Z<GetMaxZ()) {
theTempResult = theFermiModel->BreakItUp(theExcitedNucleus);
} else if(exEnergy>GetMinE()*A) {
theTempResult = theMultiFragmentation->BreakItUp(theExcitedNucleus);
} else {
theTempResult = theEvaporation->BreakItUp(theExcitedNucleus);
}
// The Nucleus has been fragmented?
if (theTempResult->entries() > 1) {
// If so :
// Remove excited fragment from the result
delete theResult->removeAt(i);
// and add theTempResult elements to theResult
while (theTempResult->entries() > 0)
theResult->insert(theTempResult->removeFirst());
i--;
} else { // If not :
// it doesn't matter, we Follow with the next fragment but
// I have to make
theTempResult->clearAndDestroy();
delete theTempResult;
}
}
}
// if (theTempResult != 0 )
// {
// theTempResult->clearAndDestroy();
// delete theTempResult;
// }
// Now we try to deexcite by means of PhotonEvaporation those fragments
// which are excited.
// In next version the Photon Evaporation has to be integrated in the main loop
theTempResult = 0;
for (i = 0; i < theResult->entries(); i++) {
if (theResult->at(i)->GetExcitationEnergy() > 0.0 && theResult->at(i)->GetA() > 1) {
theExcitedNucleus = *(theResult->at(i));
theTempResult = thePhotonEvaporation->BreakItUp(theExcitedNucleus);
// Remove excited fragment from the result
delete theResult->removeAt(i);
// and add theTempResult elements to theResult
while (theTempResult->entries() > 0)
theResult->insert(theTempResult->removeFirst());
theTempResult->clearAndDestroy();
delete theTempResult;
}
}
for (i = 0; i < theResult->entries(); i++)
G4LorentzVector mom(theResult->at(i)->GetMomentum());
// Change G4FragmentVector by G4DynamicParticle
return Transform(theResult);
}
G4DynamicParticleVector *
G4ExcitationHandler::Transform(G4FragmentVector * theFragmentVector) const
{
if (theFragmentVector == 0) return 0;
// Conversion from G4FragmentVector to G4DynamicParticleVector
G4ParticleDefinition *theGamma = G4Gamma::GammaDefinition();
G4ParticleDefinition *theNeutron = G4Neutron::NeutronDefinition();
G4ParticleDefinition *theProton = G4Proton::ProtonDefinition();
G4ParticleDefinition *theDeuteron = G4Deuteron::DeuteronDefinition();
G4ParticleDefinition *theTriton = G4Triton::TritonDefinition();
G4ParticleDefinition *theHelium3 = G4He3::He3Definition();
G4ParticleDefinition *theAlpha = G4Alpha::AlphaDefinition();
G4ParticleDefinition *theKindOfFragment = 0;
theNeutron->SetVerboseLevel(2);
G4DynamicParticleVector * theDynamicParticleVector = new G4DynamicParticleVector;
G4int theFragmentA, theFragmentZ;
G4LorentzVector theFragmentMomentum;
for (G4int i = 0; i < theFragmentVector->entries(); i++) {
// theFragmentVector->at(i)->DumpInfo();
theFragmentA = theFragmentVector->at(i)->GetA();
theFragmentZ = theFragmentVector->at(i)->GetZ();
theFragmentMomentum = theFragmentVector->at(i)->GetMomentum();
theKindOfFragment = 0;
if (theFragmentA == 0 && theFragmentZ == 0) { // photon
theKindOfFragment = theGamma;
} else if (theFragmentA == 1 && theFragmentZ == 0) { // neutron
theKindOfFragment = theNeutron;
} else if (theFragmentA == 1 && theFragmentZ == 1) { // proton
theKindOfFragment = theProton;
} else if (theFragmentA == 2 && theFragmentZ == 1) { // deuteron
theKindOfFragment = theDeuteron;
} else if (theFragmentA == 3 && theFragmentZ == 1) { // triton
theKindOfFragment = theTriton;
} else if (theFragmentA == 3 && theFragmentZ == 2) { // helium3
theKindOfFragment = theHelium3;
} else if (theFragmentA == 4 && theFragmentZ == 2) { // alpha
theKindOfFragment = theAlpha;
} else {
theKindOfFragment = theTableOfParticles->FindIon(theFragmentZ,theFragmentA,0,theFragmentZ);
}
if (theKindOfFragment != 0)
theDynamicParticleVector->insert(new G4DynamicParticle(theKindOfFragment,
theFragmentMomentum.vect()));
}
if (theFragmentVector != 0)
{
theFragmentVector->clearAndDestroy();
delete theFragmentVector;
}
return theDynamicParticleVector;
}
@@ -0,0 +1,85 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4FermiBreakUp.hh"
G4FermiBreakUp::G4FermiBreakUp()
{
}
G4FermiBreakUp::G4FermiBreakUp(const G4FermiBreakUp &right)
{
G4Exception("G4FermiBreakUp::copy_constructor meant to not be accessable");
}
G4FermiBreakUp::~G4FermiBreakUp()
{
}
const G4FermiBreakUp & G4FermiBreakUp::operator=(const G4FermiBreakUp &right)
{
G4Exception("G4FermiBreakUp::operator= meant to not be accessable");
return *this;
}
G4bool G4FermiBreakUp::operator==(const G4FermiBreakUp &right) const
{
return false;
}
G4bool G4FermiBreakUp::operator!=(const G4FermiBreakUp &right) const
{
return true;
}
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;
}
// Total energy of nucleus in nucleus rest frame (MeV)
G4double TotalEnergyRF = theNucleus.GetExcitationEnergy()/MeV +
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(theNucleus.GetZ(),theNucleus.GetA())/MeV;
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));
return theResult;
}
// Chose a configuration
G4FermiConfiguration theConfiguration(theConfigurationList.ChooseConfiguration());
// Get the fragments corresponding to chosen configuration.
G4FragmentVector * theResult = theConfiguration.GetFragments(theNucleus);
return theResult;
}
@@ -0,0 +1,579 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4FermiConfiguration.hh"
// Kappa = V/V_0 it is used in calculation of Coulomb energy
// Kappa is adimensional
const G4double G4FermiConfiguration::Kappa = 1.0;
// 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 );
G4StableFermiFragment G4FermiConfiguration::Fragment03( 3, 1, 2, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment04( 3, 2, 2, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment05( 4, 2, 1, 0.00*keV );
G4He5FermiFragment G4FermiConfiguration::Fragment06( 5, 2, 4, 16.76*keV ); // He5
G4Li5FermiFragment G4FermiConfiguration::Fragment07( 5, 3, 4, 16.66*keV ); // Li5
G4StableFermiFragment G4FermiConfiguration::Fragment08( 6, 2, 1, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment09( 6, 3, 3, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment10( 6, 3, 1, 3.56*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment11( 7, 3, 4, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment12( 7, 3, 2, 0.48*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment13( 7, 4, 4, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment14( 7, 4, 2, 0.43*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment15( 8, 3, 5, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment16( 8, 3, 3, 0.98*keV );
G4Be8FermiFragment G4FermiConfiguration::Fragment17( 8, 4, 1, 0.00*keV ); // Be8
G4StableFermiFragment G4FermiConfiguration::Fragment18( 9, 4, 4, 0.00*keV );
G4B9FermiFragment G4FermiConfiguration::Fragment19( 9, 5, 4, 0.00*keV ); // B9
G4StableFermiFragment G4FermiConfiguration::Fragment20( 10, 4, 1, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment21( 10, 4, 5, 3.37*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment22( 10, 4, 8, 5.96*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment23( 10, 4, 1, 6.18*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment24( 10, 4, 5, 6.26*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment25( 10, 5, 7, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment26( 10, 5, 3, 0.72*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment27( 10, 5, 1, 1.74*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment28( 10, 5, 3, 2.15*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment29( 10, 5, 5, 3.59*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment30( 10, 6, 3, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment31( 10, 6, 5, 3.35*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment32( 11, 5, 4, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment33( 11, 5, 2, 2.13*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment34( 11, 5, 6, 4.44*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment35( 11, 5, 4, 5.02*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment36( 11, 5, 10, 6.76*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment37( 11, 5, 6, 7.29*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment38( 11, 5, 4, 7.98*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment39( 11, 5, 6, 8.56*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment40( 11, 6, 4, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment41( 11, 6, 2, 2.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment42( 11, 6, 6, 4.32*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment43( 11, 6, 4, 4.80*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment44( 11, 6, 2, 6.34*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment45( 11, 6, 8, 6.48*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment46( 11, 6, 6, 6.90*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment47( 11, 6, 4, 7.50*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment48( 11, 6, 4, 8.10*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment49( 11, 6, 6, 8.42*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment50( 11, 6, 8, 8.66*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment51( 12, 5, 3, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment52( 12, 5, 5, 0.95*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment53( 12, 5, 5, 1.67*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment54( 12, 5, 4, 2.65*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment55( 12, 6, 1, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment56( 12, 6, 5, 4.44*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment57( 13, 6, 2, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment58( 13, 6, 2, 3.09*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment59( 13, 6, 4, 3.68*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment60( 13, 6, 6, 3.85*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment61( 13, 7, 2, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment62( 14, 6, 1, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment63( 14, 6, 3, 6.09*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment64( 14, 6, 8, 6.69*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment65( 14, 6, 6, 6.96*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment66( 14, 6, 5, 7.34*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment67( 14, 7, 3, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment68( 14, 7, 1, 2.31*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment69( 14, 7, 3, 3.95*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment70( 14, 7, 1, 4.92*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment71( 14, 7, 5, 5.11*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment72( 14, 7, 3, 5.69*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment73( 14, 7, 7, 5.83*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment74( 14, 7, 3, 6.20*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment75( 14, 7, 7, 6.44*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment76( 14, 7, 5, 7.03*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment77( 15, 7, 2, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment78( 15, 7, 8, 5.28*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment79( 15, 7, 4, 6.32*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment80( 15, 7, 10, 7.22*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment81( 15, 7, 8, 7.57*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment82( 15, 7, 2, 8.31*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment83( 15, 7, 4, 8.57*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment84( 15, 7, 14, 9.15*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment85( 15, 7, 14, 9.79*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment86( 15, 7, 8, 10.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment87( 15, 8, 2, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment88( 15, 8, 8, 5.22*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment89( 15, 8, 4, 6.18*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment90( 15, 8, 10, 6.83*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment91( 15, 8, 8, 7.28*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment92( 16, 7, 5, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment93( 16, 7, 1, 0.12*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment94( 16, 7, 7, 0.30*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment95( 16, 7, 3, 0.40*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment96( 16, 8, 1, 0.00*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment97( 16, 8, 8, 6.10*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment98( 16, 8, 5, 6.92*keV );
G4StableFermiFragment G4FermiConfiguration::Fragment99( 16, 8, 3, 7.12*keV );
G4VFermiFragment * G4FermiConfiguration::theListOfFragments[NumberOfFragments] = {
&G4FermiConfiguration::Fragment00,
&G4FermiConfiguration::Fragment01,
&G4FermiConfiguration::Fragment02,
&G4FermiConfiguration::Fragment03,
&G4FermiConfiguration::Fragment04,
&G4FermiConfiguration::Fragment05,
&G4FermiConfiguration::Fragment06,
&G4FermiConfiguration::Fragment07,
&G4FermiConfiguration::Fragment08,
&G4FermiConfiguration::Fragment09,
&G4FermiConfiguration::Fragment10,
&G4FermiConfiguration::Fragment11,
&G4FermiConfiguration::Fragment12,
&G4FermiConfiguration::Fragment13,
&G4FermiConfiguration::Fragment14,
&G4FermiConfiguration::Fragment15,
&G4FermiConfiguration::Fragment16,
&G4FermiConfiguration::Fragment17,
&G4FermiConfiguration::Fragment18,
&G4FermiConfiguration::Fragment19,
&G4FermiConfiguration::Fragment20,
&G4FermiConfiguration::Fragment21,
&G4FermiConfiguration::Fragment22,
&G4FermiConfiguration::Fragment23,
&G4FermiConfiguration::Fragment24,
&G4FermiConfiguration::Fragment25,
&G4FermiConfiguration::Fragment26,
&G4FermiConfiguration::Fragment27,
&G4FermiConfiguration::Fragment28,
&G4FermiConfiguration::Fragment29,
&G4FermiConfiguration::Fragment30,
&G4FermiConfiguration::Fragment31,
&G4FermiConfiguration::Fragment32,
&G4FermiConfiguration::Fragment33,
&G4FermiConfiguration::Fragment34,
&G4FermiConfiguration::Fragment35,
&G4FermiConfiguration::Fragment36,
&G4FermiConfiguration::Fragment37,
&G4FermiConfiguration::Fragment38,
&G4FermiConfiguration::Fragment39,
&G4FermiConfiguration::Fragment40,
&G4FermiConfiguration::Fragment41,
&G4FermiConfiguration::Fragment42,
&G4FermiConfiguration::Fragment43,
&G4FermiConfiguration::Fragment44,
&G4FermiConfiguration::Fragment45,
&G4FermiConfiguration::Fragment46,
&G4FermiConfiguration::Fragment47,
&G4FermiConfiguration::Fragment48,
&G4FermiConfiguration::Fragment49,
&G4FermiConfiguration::Fragment50,
&G4FermiConfiguration::Fragment51,
&G4FermiConfiguration::Fragment52,
&G4FermiConfiguration::Fragment53,
&G4FermiConfiguration::Fragment54,
&G4FermiConfiguration::Fragment55,
&G4FermiConfiguration::Fragment56,
&G4FermiConfiguration::Fragment57,
&G4FermiConfiguration::Fragment58,
&G4FermiConfiguration::Fragment59,
&G4FermiConfiguration::Fragment60,
&G4FermiConfiguration::Fragment61,
&G4FermiConfiguration::Fragment62,
&G4FermiConfiguration::Fragment63,
&G4FermiConfiguration::Fragment64,
&G4FermiConfiguration::Fragment65,
&G4FermiConfiguration::Fragment66,
&G4FermiConfiguration::Fragment67,
&G4FermiConfiguration::Fragment68,
&G4FermiConfiguration::Fragment69,
&G4FermiConfiguration::Fragment70,
&G4FermiConfiguration::Fragment71,
&G4FermiConfiguration::Fragment72,
&G4FermiConfiguration::Fragment73,
&G4FermiConfiguration::Fragment74,
&G4FermiConfiguration::Fragment75,
&G4FermiConfiguration::Fragment76,
&G4FermiConfiguration::Fragment77,
&G4FermiConfiguration::Fragment78,
&G4FermiConfiguration::Fragment79,
&G4FermiConfiguration::Fragment80,
&G4FermiConfiguration::Fragment81,
&G4FermiConfiguration::Fragment82,
&G4FermiConfiguration::Fragment83,
&G4FermiConfiguration::Fragment84,
&G4FermiConfiguration::Fragment85,
&G4FermiConfiguration::Fragment86,
&G4FermiConfiguration::Fragment87,
&G4FermiConfiguration::Fragment88,
&G4FermiConfiguration::Fragment89,
&G4FermiConfiguration::Fragment90,
&G4FermiConfiguration::Fragment91,
&G4FermiConfiguration::Fragment92,
&G4FermiConfiguration::Fragment93,
&G4FermiConfiguration::Fragment94,
&G4FermiConfiguration::Fragment95,
&G4FermiConfiguration::Fragment96,
&G4FermiConfiguration::Fragment97,
&G4FermiConfiguration::Fragment98,
&G4FermiConfiguration::Fragment99
};
G4FermiConfiguration::G4FermiConfiguration()
{
}
G4FermiConfiguration::G4FermiConfiguration(const G4FermiConfiguration &right)
{
Index = right.Index;
}
G4FermiConfiguration::~G4FermiConfiguration()
{
}
const G4FermiConfiguration & G4FermiConfiguration::operator=(const G4FermiConfiguration &right)
{
Index = right.Index;
return *this;
}
G4bool G4FermiConfiguration::operator==(const G4FermiConfiguration &right) const
{
if (Index.entries() == right.Index.entries()) {
for (G4int i = 0; i < Index.entries(); i++) {
if (Index(i) != right.Index(i)) return false;
}
return true;
}
else return false;
}
G4bool G4FermiConfiguration::operator!=(const G4FermiConfiguration &right) const
{
return !(*this == right);
}
void G4FermiConfiguration::Initialize(const G4int max)
{
Index.clear();
for (G4int i = 0; i < max; i++) Index.insert(1);
}
G4bool G4FermiConfiguration::SplitNucleus(const G4int A, const G4int Z)
{
// Splits nucleus (A,Z) into K fragments
// Returns TRUE if splitting is succesful and FALSE in other case
G4int K = Index.entries();
G4int L = 0;
G4int SumA = 0, SumZ = 0;
for (;;) {
L++;
if (L < K) {
Index[L-1]++;
if (Index[L-1] > Index[L]) {
Index[L-1] = 1;
continue;
} else {
SumA = 0;
for (G4int i = 1; i <= K; i++) SumA += theListOfFragments[Index[i-1]-1]->GetA();
if (SumA > A) {
Index[L-1] = 1;
continue;
} else if (SumA < A) {
L = 0;
continue;
} else {
SumZ = 0;
for (G4int i = 1; i <= K; i++) SumZ += theListOfFragments[Index[i-1]-1]->GetZ();
if (SumZ != Z) {
L = 0;
continue;
} else {
return true;
}
}
}
} else {
Index[L-1]++;
if (Index[L-1] > 100) {
return false;
} else {
SumA = 0;
for (G4int i = 1; i <= K; i++) SumA += theListOfFragments[Index[i-1]-1]->GetA();
if (SumA < A) {
L = 0;
continue;
} else if (SumA == A) {
SumZ = 0;
for (G4int i = 1; i <= K; i++) SumZ += theListOfFragments[Index[i-1]-1]->GetZ();
if (SumZ != Z) {
L = 0;
continue;
} else {
return true;
}
} else {
return false;
}
}
}
}
}
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;
}
G4double G4FermiConfiguration::DecayProbability(const G4int A, const G4double TotalE)
// Decay probability for a given channel with K fragments
{
// A: Atomic Weight
// 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;
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;
}
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;
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;
}
G4FragmentVector * G4FermiConfiguration::GetFragments(const G4Fragment & theNucleus)
{
G4int K = Index.entries();
// Avalaible kinetic energy of system.
G4double AvalKineticEnergy = theNucleus.GetExcitationEnergy()/MeV +
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(theNucleus.GetZ(),theNucleus.GetA())/MeV;
G4int i;
for (i = 0; i < K; i++)
AvalKineticEnergy -= theListOfFragments[Index[i]-1]->GetFragmentMass()/MeV;
// Calculate Momenta of K fragments
RWTPtrOrderedVector<G4LorentzVector>* MomentumComponents =
FragmentsMomentum(AvalKineticEnergy*MeV);
G4FragmentVector * theResult = new G4FragmentVector;
// Go back to the Lab Frame
for (i = 0; i < K; i++) {
G4LorentzVector FourMomentum(*(MomentumComponents->at(i)));
// Lorentz boost
FourMomentum.boost(theNucleus.GetMomentum().boostVector());
G4FragmentVector * fragment = theListOfFragments[Index[i]-1]->GetFragment(FourMomentum);
do {
theResult->insert(fragment->removeFirst());
} while (fragment->entries() > 0);
delete fragment;
}
MomentumComponents->clearAndDestroy();
delete MomentumComponents;
return theResult;
}
RWTPtrOrderedVector<G4LorentzVector>*
G4FermiConfiguration::FragmentsMomentum(G4double KineticEnergy)
{
// Calculates momentum for K fragments (Kopylov's method of sampling is used)
// KinetEnergy is the available kinetic energy
G4int K = Index.entries();
RWTPtrOrderedVector<G4LorentzVector>* MomentumList =
new RWTPtrOrderedVector<G4LorentzVector>(K);
G4double AvalaibleMass = 0;
for (G4int i=0; i<K; i++) AvalaibleMass += theListOfFragments[Index[i]-1]->GetFragmentMass();
G4double PFragMagCM = 0.0;
G4double Mass = AvalaibleMass+KineticEnergy;
G4LorentzVector PFragCM(0.0,0.0,0.0,0.0);
G4LorentzVector PFragLab(0.0,0.0,0.0,0.0);
G4LorentzVector PRestCM(0.0,0.0,0.0,0.0);
G4LorentzVector PRestLab(0.0,0.0,0.0,Mass);
for (G4int l = 0; l < K-1; l++) {
G4int LK = K - l;
G4double FragMass = theListOfFragments[Index[LK-1]-1]->GetFragmentMass();
AvalaibleMass -= FragMass;
if (LK > 2) KineticEnergy *= RNKSI(LK-1);
else KineticEnergy = 0.0;
G4double RestMass = AvalaibleMass + KineticEnergy;
PFragMagCM = sqrt(
abs((Mass*Mass - (FragMass + RestMass)*(FragMass + RestMass))*
(Mass*Mass - (FragMass - RestMass)*(FragMass - RestMass)))
)/ (2.0*Mass);
// Create a unit vector with a random direction isotropically distributed
G4ParticleMomentum RandVector(IsotropicVector(PFragMagCM));
PFragCM.setVect(RandVector);
// PFragCM.setE((Mass*Mass + FragMass*FragMass - RestMass*RestMass)/(2.0*Mass));
PFragCM.setE(sqrt(RandVector.mag2()+FragMass*FragMass));
PRestCM.setVect(-RandVector);
// PRestCM.setE((Mass*Mass + RestMass*RestMass - FragMass*FragMass)/(2.0*Mass));
PRestCM.setE(sqrt(RandVector.mag2()+RestMass*RestMass));
G4ThreeVector BoostV = PRestLab.boostVector();
PFragLab = PFragCM;
PFragLab.boost(BoostV);
PRestLab = PRestCM;
PRestLab.boost(BoostV);
MomentumList->prepend(new G4LorentzVector(PFragLab));
Mass = RestMass;
}
MomentumList->prepend(new G4LorentzVector(PRestLab));
return MomentumList;
}
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 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)
// Samples a isotropic random vectorwith a magnitud given by Magnitude.
// By default Magnitude = 1.0
{
G4double CosTheta = 1.0 - 2.0*G4UniformRand();
G4double SinTheta = sqrt(1.0 - CosTheta*CosTheta);
G4double Phi = twopi*G4UniformRand();
G4ParticleMomentum Vector(Magnitude*cos(Phi)*SinTheta,
Magnitude*sin(Phi)*SinTheta,
Magnitude*CosTheta);
return Vector;
}
@@ -0,0 +1,108 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4FermiConfigurationList.hh"
G4FermiConfigurationList::G4FermiConfigurationList():
TotNumOfConfigurations(0)
{
for (G4int i = 0; i < MaxNumOfFragments; i++) NumOfConfigurations[i] = 0;
}
G4FermiConfigurationList::G4FermiConfigurationList(const G4FermiConfigurationList &right)
{
G4Exception("G4FermiConfigurationList::copy_constructor meant to not be accessable");
}
const G4FermiConfigurationList & G4FermiConfigurationList::operator=(const G4FermiConfigurationList &right)
{
G4Exception("G4FermiConfigurationList::operator= meant to not be accessable");
return *this;
}
G4bool G4FermiConfigurationList::operator==(const G4FermiConfigurationList &right) const
{
return false;
}
G4bool G4FermiConfigurationList::operator!=(const G4FermiConfigurationList &right) const
{
return true;
}
G4bool G4FermiConfigurationList::Initialize(const G4int A, const G4int Z, const G4double TotalEnergyRF)
{
//
// 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]++;
// 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);
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);
}
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;
}
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));
return Configurations(thisConfig - 1);
}
@@ -0,0 +1,143 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// 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 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
#include "G4FissionBarrier.hh"
G4FissionBarrier::G4FissionBarrier(const G4FissionBarrier & right)
{
G4Exception("G4FissionBarrier::copy_constructor meant to not be accessable.");
}
const G4FissionBarrier & G4FissionBarrier::operator=(const G4FissionBarrier & right)
{
G4Exception("G4FissionBarrier::operator= meant to not be accessable.");
return *this;
}
G4bool G4FissionBarrier::operator==(const G4FissionBarrier & right) const
{
return false;
}
G4bool G4FissionBarrier::operator!=(const G4FissionBarrier & right) const
{
return true;
}
G4double G4FissionBarrier::FissionBarrier(const G4int A, const G4int Z)
// Compute fission barrier according with Barashenkov's prescription for A >= 65
{
if (A >= 65) return BarashenkovFissionBarrier(A,Z)*MeV;
else return 1.0*GeV;
}
G4double G4FissionBarrier::BarashenkovFissionBarrier(const G4int A, const G4int Z)
// Calculates Fission Barrier heights (in MeV), which are function of the nuclear
// fissility parameteter x = Z*Z/A.
// Barashenkov V., Iljinov A. and Toneev V. parametrization (1972)
{
const G4double ShellCorr1[130] = {
20.80, 15.80, 21.00, 16.80, 19.80,
16.50, 18.80, 16.50, 18.50, 17.20,
18.26, 15.05, 16.01, 12.04, 13.27,
11.09, 12.17, 10.26, 11.04, 8.41,
9.79, 7.36, 8.15, 5.63, 5.88,
3.17, 3.32, 0.82, 1.83, 0.97,
2.33, 1.27, 2.92, 1.61, 2.91,
1.35, 2.40, 0.89, 1.74, 0.36,
0.95, -0.65, -0.04, -1.73, -0.96,
-2.87, -2.05, -4.05, -3.40, -5.72,
-3.75, -4.13, -2.42, -2.85, -1.01,
-1.33, 0.54, -0.02, 1.74, 0.75,
2.24, 1.00, 1.98, 0.79, 1.54,
0.39, 1.08, 0.00, 0.78, -0.35,
0.58, -0.55, 0.59, -0.61, 0.59,
-0.35, 0.32, -0.96, -0.52, -2.08,
-2.46, -3.64, -1.55, -0.96, 0.97,
0.88, 2.37, 1.75, 2.72, 1.90,
2.55, 1.46, 1.93, 0.86, 1.17,
0.08, 0.39, -0.76, -0.39, -1.51,
-1.17, -2.36, -1.95, -3.06, -2.62,
-3.55, -2.95, -3.75, -3.07, -3.79,
-3.06, -3.77, -3.05, -3.78, -3.12,
-3.90, -3.35, -4.24, -3.86, -4.92,
-5.06, -6.77, -7.41, -9.18, -10.16,
-11.12, -9.76, -9.23, -7.96, -7.65};
const G4double ShellCorr2[200] = {
-8.40, -12.90, -8.00, -11.90, -9.20,
-12.50, -10.80, -13.60, -11.20, -12.20,
-12.81, -15.40, -13.07, -15.80, -13.81,
-14.98, -12.63, -13.76, -11.37, -12.38,
-9.23, -9.65, -7.64, -9.17, -8.05,
-9.72, -8.87, -10.76, -8.64, -8.89,
-6.60, -7.13, -4.77, -5.33, -3.06,
-3.79, -1.72, -2.79, -0.93, -2.19,
-0.52, -1.90, -0.45, -2.20, -1.22,
-3.07, -2.42, -4.37, -3.94, -6.08,
-4.49, -4.50, -3.14, -2.93, -1.04,
-1.36, 0.69, 0.21, 2.11, 1.33,
3.29, 2.46, 4.30, 3.32, 4.79,
3.62, 4.97, 3.64, 4.63, 3.07,
4.06, 2.49, 3.30, 1.46, 2.06,
0.51, 0.74, -1.18, -1.26, -3.54,
-3.97, -5.26, -4.18, -3.71, -2.10,
-1.70, -0.08, -0.18, 0.94, 0.27,
1.13, 0.08, 0.91, -0.31, 0.49,
-0.78, 0.08, -1.15, -0.23, -1.41,
-0.42, -1.55, -0.55, -1.66, -0.66,
-1.73, -0.75, -1.74, -0.78, -1.69,
-0.78, -1.60, -0.75, -1.46, -0.67,
-1.26, -0.51, -1.04, -0.53, -1.84,
-2.42, -4.52, -4.76, -6.33, -6.76,
-7.81, -5.80, -5.37, -3.63, -3.35,
-1.75, -1.88, -0.61, -0.90, 0.09,
-0.32, 0.55, -0.13, 0.70, -0.06,
0.49, -0.20, 0.40, -0.22, 0.36,
-0.09, 0.58, 0.12, 0.75, 0.15,
0.70, 0.17, 1.11, 0.89, 1.85,
1.62, 2.54, 2.29, 3.20, 2.91,
3.84, 3.53, 4.48, 4.15, 5.12,
4.78, 5.75, 5.39, 6.31, 5.91,
6.87, 6.33, 7.13, 6.61, 7.30,
6.31, 6.27, 4.83, 4.49, 2.85,
2.32, 0.58, -0.11, -0.98, 0.81,
1.77, 3.37, 4.13, 5.60, 6.15,
7.29, 7.35, 7.95, 7.67, 8.16,
7.83, 8.31, 8.01, 8.53, 8.27};
const G4int N = A - Z;
// const G4double x = (static_cast<G4double>(Z)*static_cast<G4double>(Z))/
// static_cast<G4double>(A);
const G4double x = (G4double(Z)*G4double(Z))/G4double(A);
G4double BF0 = 0.0;
if (x <= 33.5) BF0 = 12.5 + 4.7*pow((33.5-x),0.75);
else BF0 = 12.5 - 2.7*pow((x-33.5),2.0/3.0);
// Determine which kind of nucleus is: even-even, odd-odd, even-odd, odd-even
G4double D = 0.0;
G4int I = 2*(Z/2);
G4int J = 2*(N/2);
if (I < Z) D = 0.0;
else D = -0.5;
if (J < N) D += 1.0;
if (Z > 130 || N > 200) return BF0 + D;
else return BF0 + D - ShellCorr1[Z-1] - ShellCorr2[N-1];
}
@@ -0,0 +1,52 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
//
#include "G4FissionLevelDensityParameter.hh"
G4FissionLevelDensityParameter::
G4FissionLevelDensityParameter(const G4FissionLevelDensityParameter &right)
{
G4Exception("G4FissionLevelDensityParameter::copy_constructor meant to not be accessable");
}
const G4FissionLevelDensityParameter & G4FissionLevelDensityParameter::
operator=(const G4FissionLevelDensityParameter &right)
{
G4Exception("G4FissionLevelDensityParameter::operator= meant to not be accessable");
return *this;
}
G4bool G4FissionLevelDensityParameter::
operator==(const G4FissionLevelDensityParameter &right) const
{
return false;
}
G4bool G4FissionLevelDensityParameter::
operator!=(const G4FissionLevelDensityParameter &right) const
{
return true;
}
G4double G4FissionLevelDensityParameter::
LevelDensityParameter(const G4int A,const G4int Z,const G4double U) const
{
G4double EvapLDP = theEvaporationLevelDensityParameter.LevelDensityParameter(A,Z,U);
if (Z >= 89) return 1.04*EvapLDP;
else if (Z >= 85) return (1.04*(1./MeV) + 0.01*(89-Z))*EvapLDP;
else return 1.08*EvapLDP;
}
@@ -0,0 +1,92 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
//
#include "G4FissionParameters.hh"
const G4double G4FissionParameters::A1 = 134.0;
const G4double G4FissionParameters::A2 = 141.0;
G4FissionParameters::G4FissionParameters(const G4int A, const G4int Z, const G4double ExEnergy,
const G4double FissionBarrier)
{
G4double U = ExEnergy/MeV;
As = A/2.0;
if (A >= 235) Sigma2 = 5.6; // MeV
else Sigma2 = 5.6 + 0.096*(A-235); // MeV
Sigma1 = 0.5*Sigma2; // MeV
SigmaS = exp(0.00553*U + 4.1386); // MeV
G4double FasymAsym = 2.0*exp(-((A2-As)*(A2-As))/(2.0*Sigma2*Sigma2)) +
exp(-((A1-As)*(A1-As))/(2.0*Sigma1*Sigma1));
G4double FsymA1A2 = exp(-((As-(A1+A2))*(As-(A1+A2)))/(2.0*SigmaS*SigmaS));
G4double wa;
G4double w1,w2;
w = 0.0;
if (Z >= 90) { // Z >= 90
if (U <= 16.25) wa = exp(0.5385*U-9.9564); // U <= 16.25 MeV
else wa = exp(0.09197*U-2.7003); // U > 16.25 MeV
} else if (Z == 89) { // Z == 89
wa = exp(0.09197*U-1.0808);
} else if (Z >= 82) { // 82 <= Z <= 88
G4double X = FissionBarrier/MeV - 7.5;
if (X < 0.0) X = 0.0;
wa = exp(0.09197*(U-X)-1.0808);
} else { // Z < 82
w = 1001.0;
}
if (w == 0.0) {
w1 = max(1.03*wa - FasymAsym, 0.0001);
w2 = max(1.0 - FsymA1A2*wa, 0.0001);
w = w1/w2;
if (82 <= Z && Z < 89 && A < 227) w *= exp(0.3*(A-227));
}
}
G4FissionParameters::G4FissionParameters(const G4FissionParameters &right)
{
G4Exception("G4FissionParameters::copy_constructor meant to not be accessable");
}
const G4FissionParameters & G4FissionParameters::operator=(const G4FissionParameters &right)
{
G4Exception("G4FissionParameters::operator= meant to not be accessable");
return *this;
}
G4bool G4FissionParameters::operator==(const G4FissionParameters &right) const
{
return false;
}
G4bool G4FissionParameters::operator!=(const G4FissionParameters &right) const
{
return true;
}
@@ -0,0 +1,71 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
//
#include "G4FissionProbability.hh"
G4FissionProbability::G4FissionProbability(const G4FissionProbability &right)
{
G4Exception("G4FissionProbability::copy_constructor meant to not be accessable");
}
const G4FissionProbability & G4FissionProbability::operator=(const G4FissionProbability &right)
{
G4Exception("G4FissionProbability::operator= meant to not be accessable");
return *this;
}
G4bool G4FissionProbability::operator==(const G4FissionProbability &right) const
{
return false;
}
G4bool G4FissionProbability::operator!=(const G4FissionProbability &right) const
{
return true;
}
G4double G4FissionProbability::EmissionProbability(const G4Fragment & fragment, const G4double photonExcitation)
//
{
G4double A = fragment.GetA();
G4double Z = fragment.GetZ();
G4double U = fragment.GetExcitationEnergy();
G4double SystemEntropy = 2.0*sqrt((theEvapLDP.LevelDensityParameter(A,Z,U)/(1./MeV))*A*U/MeV);
// Compute integrated probability of fission channel
if (theChannel->GetMaximalKineticEnergy() <= 0.0) return 0.0;
G4double Q1 = 2.0*sqrt((theFissLDP.LevelDensityParameter(A,Z,U)/(1./MeV))*A*
theChannel->GetMaximalKineticEnergy()/MeV);
G4double Q2 = 1./(4.0*pi);
// G4double Tfis = 21.e-6*940.0;
//return min(Tfis,(Q2/((theFissLDP.LevelDensityParameter(A,Z,U)/(1./MeV))*A))*
// ((Q1-1.0)*exp(Q1-SystemEntropy)+exp(-SystemEntropy)));
return (Q2/((theFissLDP.LevelDensityParameter(A,Z,U)/(1./MeV))*A))*
((Q1-1.0)*exp(Q1-SystemEntropy)+exp(-SystemEntropy));
}
@@ -0,0 +1,94 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4He5FermiFragment.hh"
G4He5FermiFragment::G4He5FermiFragment()
{
}
G4He5FermiFragment::G4He5FermiFragment(const G4He5FermiFragment &right)
{
G4Exception("G4He5FermiFragment::copy_constructor meant to not be accessable");
}
G4He5FermiFragment::~G4He5FermiFragment()
{
}
const G4He5FermiFragment & G4He5FermiFragment::operator=(const G4He5FermiFragment &right)
{
G4Exception("G4He5FermiFragment::operator= meant to not be accessable");
return *this;
}
G4bool G4He5FermiFragment::operator==(const G4He5FermiFragment &right) const
{
return false;
}
G4bool G4He5FermiFragment::operator!=(const G4He5FermiFragment &right) const
{
return true;
}
G4FragmentVector * G4He5FermiFragment::GetFragment(const G4LorentzVector & aMomentum)
// He5 ----> alpha + neutron
{
const G4int NumSubFrag = 2;
G4double Masses[NumSubFrag];
G4double Charges[NumSubFrag];
G4double AtomNum[NumSubFrag];
Masses[0] = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(2,4); // alpha
Masses[1] = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(0,1); // neutron
AtomNum[0] = 4;
AtomNum[1] = 1;
Charges[0] = 2;
Charges[1] = 0;
// G4double AvalKineticE = G4NucleiPropertiesTable::GetMassExcess(Z,A) + ExcitEnergy - // He5
// G4NucleiPropertiesTable::GetMassExcess(0,1) - // neutron
// G4NucleiPropertiesTable::GetMassExcess(2,4); // alpha
G4double AvalKineticE = sqrt(aMomentum.e()*aMomentum.e() -
aMomentum.vect().mag2()) - // He5
Masses[1] - // neutron
Masses[0]; // alpha
RWTPtrOrderedVector<G4LorentzVector> * SubFragsMomentum =
FragmentsMomentum(AvalKineticE, NumSubFrag,Masses);
G4FragmentVector * theResult = new G4FragmentVector;
for (G4int i = 0; i < NumSubFrag; i++) {
// Lorentz boost
SubFragsMomentum->at(i)->boost(aMomentum.boostVector());
theResult->insert(new G4Fragment(AtomNum[i],Charges[i],*(SubFragsMomentum->at(i))));
}
SubFragsMomentum->clearAndDestroy();
delete SubFragsMomentum;
return theResult;
}
@@ -0,0 +1,92 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4Li5FermiFragment.hh"
G4Li5FermiFragment::G4Li5FermiFragment()
{
}
G4Li5FermiFragment::G4Li5FermiFragment(const G4Li5FermiFragment &right)
{
G4Exception("G4Li5FermiFragment::copy_constructor meant to not be accessable");
}
G4Li5FermiFragment::~G4Li5FermiFragment()
{
}
const G4Li5FermiFragment & G4Li5FermiFragment::operator=(const G4Li5FermiFragment &right)
{
G4Exception("G4Li5FermiFragment::operator= meant to not be accessable");
return *this;
}
G4bool G4Li5FermiFragment::operator==(const G4Li5FermiFragment &right) const
{
return false;
}
G4bool G4Li5FermiFragment::operator!=(const G4Li5FermiFragment &right) const
{
return true;
}
G4FragmentVector * G4Li5FermiFragment::GetFragment(const G4LorentzVector & aMomentum)
// Li5 ----> alpha + proton
{
const G4int NumSubFrag = 2;
G4double Masses[NumSubFrag];
G4double Charges[NumSubFrag];
G4double AtomNum[NumSubFrag];
Masses[0] = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(2,4); // alpha
Masses[1] = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1); // proton
AtomNum[0] = 4;
AtomNum[1] = 1;
Charges[0] = 2;
Charges[1] = 1;
// G4double AvalKineticE = G4NucleiPropertiesTable::GetMassExcess(Z,A) + ExcitEnergy - // Li5
// G4NucleiPropertiesTable::GetMassExcess(1,1) - // proton
// G4NucleiPropertiesTable::GetMassExcess(2,4); // alpha
G4double AvalKineticE = sqrt(aMomentum.e()*aMomentum.e() -
aMomentum.vect().mag2()) - // Li5
Masses[0] - // proton
Masses[1]; // alpha
RWTPtrOrderedVector<G4LorentzVector> * SubFragsMomentum =
FragmentsMomentum(AvalKineticE, NumSubFrag,Masses);
G4FragmentVector * theResult = new G4FragmentVector;
for (G4int i = 0; i < NumSubFrag; i++) {
// Lorentz boost
SubFragsMomentum->at(i)->boost(aMomentum.boostVector());
theResult->insert(new G4Fragment(AtomNum[i],Charges[i],*(SubFragsMomentum->at(i))));
}
SubFragsMomentum->clearAndDestroy();
delete SubFragsMomentum;
return theResult;
}
@@ -0,0 +1,46 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// 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 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
#include "G4MultiFragmentation.hh"
G4MultiFragmentation::G4MultiFragmentation()
{
}
G4MultiFragmentation::G4MultiFragmentation(const G4MultiFragmentation &right)
{
}
G4MultiFragmentation::~G4MultiFragmentation()
{
}
const G4MultiFragmentation & G4MultiFragmentation::operator=(const G4MultiFragmentation &right)
{
G4Exception("G4MultiFragmentation::operator= meant to not be accessable");
return *this;
}
int G4MultiFragmentation::operator==(const G4MultiFragmentation &right) const
{
return (this == (G4MultiFragmentation *) &right);
}
int G4MultiFragmentation::operator!=(const G4MultiFragmentation &right) const
{
return (this != (G4MultiFragmentation *) &right);
}
@@ -0,0 +1,153 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4NuclearLevel
//
// Author: Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 24 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
#include "G4NuclearLevel.hh"
#include "globals.hh"
G4NuclearLevel::G4NuclearLevel(const G4double energy,
const G4DataVector& eGamma, const G4DataVector& wGamma)
{
_energy = energy;
G4int i;
for (i=0; i<eGamma.entries(); i++)
{
_energies.insert(eGamma.at(i));
_weights.insert(wGamma.at(i));
}
_nGammas = _energies.entries();
MakeProbabilities();
MakeCumProb();
}
G4NuclearLevel::~G4NuclearLevel()
{ }
G4bool G4NuclearLevel::operator==(const G4NuclearLevel &right) const
{
return (this == (G4NuclearLevel *) &right);
}
G4bool G4NuclearLevel::operator!=(const G4NuclearLevel &right) const
{
return (this != (G4NuclearLevel *) &right);
}
G4bool G4NuclearLevel::operator<(const G4NuclearLevel &right) const
{
if (_energy < right.Energy()) return true;
else return false;
}
const G4DataVector& G4NuclearLevel::GammaEnergies() const
{
return _energies;
}
const G4DataVector& G4NuclearLevel::GammaWeights() const
{
return _weights;
}
const G4DataVector& G4NuclearLevel::GammaProbabilities() const
{
return _prob;
}
const G4DataVector& G4NuclearLevel::GammaCumulativeProbabilities() const
{
return _cumProb;
}
G4double G4NuclearLevel::Energy() const
{
return _energy;
}
G4int G4NuclearLevel::NumberOfGammas() const
{
return _nGammas;
}
void G4NuclearLevel::PrintAll() const
{
G4cout << "---- Level energy = " << _energy << ", " << _nGammas << " photons" << endl;
G4int i;
G4cout << " Gammas: ";
for (i=0; i<_nGammas; i++) { G4cout << _energies.at(i) << " "; }
G4cout << endl << " Weights: ";
for (i=0; i<_nGammas; i++) { G4cout << _weights.at(i) << " "; }
G4cout << endl << " Relative transition probabilities ";
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;
return;
}
void G4NuclearLevel::MakeProbabilities()
{
G4double sum = 0.;
G4int i = 0;
for (i=0; i<_nGammas; i++)
{
sum += _weights.at(i);
}
for (i=0; i<_nGammas; i++)
{
if (sum > 0.) { _prob.insert(_weights.at(i) / sum); }
else { _prob.insert(1./_nGammas); }
}
return;
}
void G4NuclearLevel::MakeCumProb()
{
if (_nGammas > 0)
{
G4double sum = _prob.at(0);
_cumProb.insert(sum);
G4int i = 0;
for (i=1; i<_nGammas; i++)
{
sum += _prob.at(i);
_cumProb.insert(sum);
}
}
return;
}
@@ -0,0 +1,311 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4NuclearLevelManager
//
// Author: Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 24 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
#include "G4NuclearLevelManager.hh"
#include "globals.hh"
#include "G4NuclearLevel.hh"
#include "G4ios.hh"
#include <stdlib.h>
#include <fstream.h>
#include <strstream.h>
G4NuclearLevelManager::G4NuclearLevelManager():
_A(0), _Z(0), _levels(0), _levelEnergy(0), _gammaEnergy(0), _probability(0)
{ }
G4NuclearLevelManager::G4NuclearLevelManager(G4int Z, G4int A): _Z(Z), _A(A)
{
if (A <= 0 || Z <= 0 || Z > A )
G4Exception("==== G4NuclearLevelManager ==== (Z,A) <0, or Z>A");
_levels = 0;
MakeLevels();
}
G4NuclearLevelManager::~G4NuclearLevelManager()
{
if ( _levels ) {
if (_levels->entries()>0) _levels->clearAndDestroy();
delete _levels;
_levels = 0;
}
}
void G4NuclearLevelManager::SetNucleus(G4int Z, G4int A)
{
if (_Z != Z || _A != A)
{
_A = A;
_Z = Z;
MakeLevels();
}
}
G4bool G4NuclearLevelManager::IsValid(G4int Z, G4int A) const
{
G4bool valid = true;
if (A < 0 || Z < 0 || A < Z) valid = false;
G4String dirName = getenv("G4LEVELGAMMADATA");
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;
}
G4int G4NuclearLevelManager::NumberOfLevels() const
{
G4int n = 0;
if (_levels != 0) n = _levels->entries();
return n;
}
const G4PtrLevelVector* G4NuclearLevelManager::GetLevels() const
{
return _levels;
}
const G4NuclearLevel* G4NuclearLevelManager::NearestLevel(G4double energy, G4double eDiffMax) const
{
G4int iNear = -1;
G4double diff = 9999. * GeV;
if (_levels != 0)
{
G4int i = 0;
for (i=0; i<_levels->entries(); i++)
{
G4double e = _levels->at(i)->Energy();
G4double eDiff = abs(e - energy);
if (eDiff < diff && eDiff <= eDiffMax)
{
diff = eDiff;
iNear = i;
}
}
}
if (_levels != 0 && iNear >= 0 && iNear < _levels->entries())
{ return _levels->at(iNear); }
else
{ return 0; }
}
G4double G4NuclearLevelManager::MinLevelEnergy() const
{
G4double eMin = 9999.*GeV;
if (_levels != 0)
{
if (_levels->entries() > 0) eMin = _levels->first()->Energy();
}
return eMin;
}
G4double G4NuclearLevelManager::MaxLevelEnergy() const
{
G4double eMax = 0.;
if (_levels != 0)
{
if (_levels->entries() > 0) eMax = _levels->last()->Energy();
}
return eMax;
}
const G4NuclearLevel* G4NuclearLevelManager::HighestLevel() const
{
if (_levels!= 0 && _levels->entries() > 0) return _levels->first();
else return 0;
}
const G4NuclearLevel* G4NuclearLevelManager::LowestLevel() const
{
if (_levels != 0 && _levels->entries() > 0) return _levels->last();
else return 0;
}
G4bool G4NuclearLevelManager::Read(ifstream& dataFile)
{
const G4double minProbability = 0.001;
G4bool result = true;
if (dataFile >> _levelEnergy)
{
dataFile >> _gammaEnergy >> _probability;
_levelEnergy *= keV;
_gammaEnergy *= keV;
// The following adjustment is needed to take care of anomalies in
// data files, where some transitions show up with relative probability
// zero
if (_probability < minProbability) _probability = minProbability;
// G4cout << "Read " << _levelEnergy << " " << _gammaEnergy << " " << _probability << endl;
}
else
{
result = false;
}
return result;
}
void G4NuclearLevelManager::MakeLevels()
{
G4String dirName = getenv("G4LEVELGAMMADATA");
char name[100] = {""};
ostrstream ost(name, 100, ios::out);
ost << dirName << "/" << "z" << _Z << ".a" << _A;
G4String file(name);
ifstream inFile(file, ios::in);
if (! inFile)
{
// G4cout << " G4NuclearLevelManager: (" << _Z << "," << _A
// << ") does not have LevelsAndGammas file" << endl;
return;
}
if (_levels != 0)
{
if (_levels->entries()>0) _levels->clearAndDestroy();
delete _levels;
}
_levels = new G4PtrLevelVector;
G4DataVector eLevel;
G4DataVector eGamma;
G4DataVector wGamma;
while (Read(inFile))
{
eLevel.insert(_levelEnergy);
eGamma.insert(_gammaEnergy);
wGamma.insert(_probability);
}
// ---- MGP ---- Don't forget to close the file
inFile.close();
G4int nData = eLevel.entries();
// G4cout << " ==== MakeLevels ===== " << nData << " data read " << endl;
G4double thisLevelEnergy = eLevel.at(0);
G4DataVector thisLevelEnergies;
G4DataVector thisLevelWeights;
G4double e = -1.;
G4int i;
for (i=0; i<nData; i++)
{
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);
_levels->insert(newLevel);
// Reset data vectors
thisLevelEnergies.clear();
thisLevelWeights.clear();
thisLevelEnergy = e;
}
// Append current data
thisLevelEnergies.insert(eGamma.at(i));
thisLevelWeights.insert(wGamma.at(i));
}
// Make last level
if (e > 0.)
{
G4NuclearLevel* newLevel = new G4NuclearLevel(e,thisLevelEnergies,thisLevelWeights);
_levels->insert(newLevel);
}
return;
}
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;
G4int i = 0;
for (i=0; i<nLevels; i++)
{ _levels->at(i)->PrintAll(); }
}
G4NuclearLevelManager::G4NuclearLevelManager(const G4NuclearLevelManager &right)
{
_levelEnergy = right._levelEnergy;
_gammaEnergy = right._gammaEnergy;
_probability = right._probability;
_A = right._A;
_Z = right._Z;
if (right._levels != 0)
{
_levels = new G4PtrLevelVector;
G4int n = right._levels->entries();
G4int i;
for (i=0; i<n; i++)
{
_levels->insert(new G4NuclearLevel(*(right._levels->at(i))));
}
}
else
{
_levels = 0;
}
}
@@ -0,0 +1,229 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4PhotonEvaporation
//
// Author: Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 23 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
#include "G4PhotonEvaporation.hh"
#include "globals.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
#include "G4LorentzVector.hh"
#include "G4VGammaTransition.hh"
#include "G4Fragment.hh"
#include "G4FragmentVector.hh"
#include "G4ContinuumGammaDeexcitation.hh"
#include "G4DiscreteGammaDeexcitation.hh"
#include "G4E1Probability.hh"
G4PhotonEvaporation::G4PhotonEvaporation()
{
_probAlgorithm = new G4E1Probability;
_myOwnProbAlgorithm = true;
_discrDeexcitation = new G4DiscreteGammaDeexcitation;
_contDeexcitation = new G4ContinuumGammaDeexcitation;
_verbose = 0;
_gammaE = 0.;
}
G4PhotonEvaporation::~G4PhotonEvaporation()
{
if(_myOwnProbAlgorithm) delete _probAlgorithm;
delete _discrDeexcitation;
delete _contDeexcitation;
}
void G4PhotonEvaporation::Initialize(const G4Fragment& fragment)
{
_nucleus = fragment;
return;
}
G4FragmentVector* G4PhotonEvaporation::BreakUp(const G4Fragment& nucleus)
{
_nucleus = nucleus;
G4FragmentVector* products = new G4FragmentVector;
_contDeexcitation->SetNucleus(nucleus);
_discrDeexcitation->SetNucleus(nucleus);
// Do one photon emission
// Products from continuum gamma transitions
G4FragmentVector* contProducts = _contDeexcitation->DoTransition();
G4int nCont = 0;
if (contProducts != 0) nCont = contProducts->entries();
G4int i;
if (nCont > 0)
{
G4Fragment modifiedNucleus = _contDeexcitation->GetNucleus();
_discrDeexcitation->SetNucleus(modifiedNucleus);
for (i=0; i<nCont; i++)
{
products->insert(contProducts->at(i));
}
}
else
{
// Products from discrete gamma transitions
G4FragmentVector* discrProducts = _discrDeexcitation->DoTransition();
G4int nDiscr = 0;
if (discrProducts != 0) nDiscr = discrProducts->entries();
if (_verbose > 0)
G4cout << " = BreakUp = " << nDiscr
<< " gammas from DiscreteDeexcitation "
<< endl;
for (i=0; i<nDiscr; i++)
{
products->insert(discrProducts->at(i));
}
delete discrProducts;
}
_gammaE = 0.;
if (products->entries() > 0)
{
_gammaE = products->at(0)->GetMomentum().e();
}
delete contProducts; // delete vector, not fragments
// Add deexcited nucleus to products
G4Fragment* finalNucleus = new G4Fragment(_discrDeexcitation->GetNucleus());
products->insert(finalNucleus);
if (_verbose > 0)
G4cout << "*-*-*-* Photon evaporation: " << products->entries() << endl;
return products;
}
G4FragmentVector* G4PhotonEvaporation::BreakItUp(const G4Fragment& nucleus)
{
_nucleus = nucleus;
G4FragmentVector* products = new G4FragmentVector;
_contDeexcitation->SetNucleus(nucleus);
_discrDeexcitation->SetNucleus(nucleus);
// Do the whole gamma chain
G4FragmentVector* contProducts = _contDeexcitation->DoChain();
// Products from continuum gamma transitions
G4int nCont = 0;
if (contProducts != 0) nCont = contProducts->entries();
if (_verbose > 0)
G4cout << " = BreakItUp = " << nCont
<< " gammas from ContinuumDeexcitation " << endl;
G4int i;
if (nCont > 0)
{
G4Fragment modifiedNucleus = _contDeexcitation->GetNucleus();
_discrDeexcitation->SetNucleus(modifiedNucleus);
for (i=0; i<nCont; i++)
{
products->insert(contProducts->at(i));
}
}
// Products from discrete gamma transitions
G4FragmentVector* discrProducts = _discrDeexcitation->DoChain();
G4int nDiscr = 0;
if (discrProducts != 0) nDiscr = discrProducts->entries();
if (_verbose > 0)
G4cout << " = BreakItUp = " << nDiscr
<< " gammas from DiscreteDeexcitation " << endl;
for (i=0; i<nDiscr; i++)
{
products->insert(discrProducts->at(i));
}
// Add deexcited nucleus to products
G4Fragment* finalNucleus = new G4Fragment(_discrDeexcitation->GetNucleus());
products->insert(finalNucleus);
if (_verbose > 0)
G4cout << " = BreakItUp = Nucleus added to products" << endl;
delete contProducts; // delete vector, not fragments
delete discrProducts;
if (_verbose > 0)
G4cout << "*-*-* Photon evaporation: " << products->entries() << endl;
return products;
}
G4double G4PhotonEvaporation::GetEmissionProbability() const
{
G4double prob = 0.;
if (_probAlgorithm != 0) prob = _probAlgorithm->EmissionProbability(_nucleus,_gammaE);
return prob;
}
void G4PhotonEvaporation::SetEmissionStrategy(G4VEmissionProbability * probAlgorithm)
{
// CD - not sure about always wanting to delete this pointer....
if(_myOwnProbAlgorithm) delete _probAlgorithm;
_probAlgorithm = probAlgorithm;
_myOwnProbAlgorithm = false;
return;
}
void G4PhotonEvaporation::SetVerboseLevel(G4int verbose)
{
_verbose = verbose;
_contDeexcitation->SetVerboseLevel(verbose);
_discrDeexcitation->SetVerboseLevel(verbose);
return;
}
@@ -0,0 +1,139 @@
//
// -----------------------------------------------------------------------
// HEP Random
// --- RandGeneralTmp ---
// class implementation file
// -----------------------------------------------------------------------
// Class defining methods for shooting generally distributed random values,
// given a user-defined probability distribution function.
// =======================================================================
// S.Magni & G.Pieri - Created: 29th April 1998
// G.Cosmo - Added constructor using default engine from the
// static generator. Simplified shoot() and
// shootArray() (not needed in principle!): 20 Aug 1998
// =======================================================================
#include "globals.hh"
#include "G4RandGeneralTmp.hh"
//////////////////
// Constructors
//////////////////
G4RandGeneralTmp::G4RandGeneralTmp(HepDouble* aProbFunc, HepInt theProbSize )
: deleteEngine(false), nBins(theProbSize)
{
localEngine = HepRandom::getTheEngine();
register HepInt ptn;
theIntegralPdf = new HepDouble[theProbSize];
theIntegralPdf[0] = 0;
for ( ptn = 1; ptn<theProbSize; ++ptn ) {
theIntegralPdf[ptn] = 0;
theIntegralPdf[ptn] = theIntegralPdf[ptn-1] + aProbFunc[ptn];
}
for ( ptn = 0; ptn < theProbSize; ++ptn )
{
if (theIntegralPdf[ptn-1] != 0.) theIntegralPdf[ptn] /= theIntegralPdf[nBins-1];
}
}
G4RandGeneralTmp::G4RandGeneralTmp(HepRandomEngine& anEngine,
HepDouble* aProbFunc, HepInt theProbSize )
: localEngine(&anEngine), deleteEngine(false), nBins(theProbSize)
{
register HepInt ptn;
theIntegralPdf = new HepDouble[theProbSize];
theIntegralPdf[0] = 0;
for ( ptn = 1; ptn<theProbSize; ++ptn ) {
theIntegralPdf[ptn] = 0;
theIntegralPdf[ptn] = theIntegralPdf[ptn-1] + aProbFunc[ptn];
}
for ( ptn = 0; ptn < theProbSize; ++ptn )
theIntegralPdf[ptn] /= theIntegralPdf[nBins-1];
}
G4RandGeneralTmp::G4RandGeneralTmp(HepRandomEngine* anEngine,
HepDouble* aProbFunc, HepInt theProbSize )
: localEngine(anEngine), deleteEngine(true), nBins(theProbSize)
{
register HepInt ptn;
theIntegralPdf = new HepDouble[nBins];
theIntegralPdf[0] = 0.;
for ( ptn = 1; ptn<nBins; ++ptn ) {
theIntegralPdf[ptn] = 0;
theIntegralPdf[ptn] = theIntegralPdf[ptn-1] + aProbFunc[ptn];
}
for ( ptn = 0; ptn < nBins; ++ptn )
theIntegralPdf[ptn] /= theIntegralPdf[nBins-1];
}
//////////////////
// Destructor
//////////////////
G4RandGeneralTmp::~G4RandGeneralTmp() {
if ( deleteEngine ) delete localEngine;
delete theIntegralPdf;
}
HepDouble G4RandGeneralTmp::operator()() {
return fire();
}
HepDouble G4RandGeneralTmp::shoot( HepRandomEngine* anEngine )
{
HepDouble rand;
HepInt nabove, nbelow = 0, middle;
nabove = nBins+1;
rand = anEngine->flat();
while(nabove-nbelow > 1) {
middle = ( nabove + nbelow ) / 2;
if (rand == theIntegralPdf[middle-1]) break;
if (rand < theIntegralPdf[middle-1]) nabove = middle;
else nbelow = middle;
}
return ((HepDouble)nbelow - 1) / nBins;
}
void G4RandGeneralTmp::shootArray( HepRandomEngine* anEngine,
const HepInt size, HepDouble* vect )
{
register HepInt i;
for (i=0; i<size; ++i)
vect[i] = shoot(anEngine);
}
HepDouble G4RandGeneralTmp::fire()
{
HepDouble rand;
HepInt nabove, nbelow = 0, middle;
nabove = nBins+1;
rand = localEngine->flat();
while(nabove-nbelow > 1) {
middle = ( nabove + nbelow ) / 2;
if (rand == theIntegralPdf[middle-1]) break;
if (rand < theIntegralPdf[middle-1]) nabove = middle;
else nbelow = middle;
}
return ((HepDouble)nbelow - 1) / nBins;
}
void G4RandGeneralTmp::fireArray( const HepInt size, HepDouble* vect )
{
register HepInt i;
for (i=0; i<size; ++i)
vect[i] = fire();
}
@@ -0,0 +1,55 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4StableFermiFragment.hh"
G4StableFermiFragment::G4StableFermiFragment()
{
}
G4StableFermiFragment::G4StableFermiFragment(const G4StableFermiFragment &right)
{
G4Exception("G4StableFermiFragment::copy_constructor meant to not be accessable");
}
G4StableFermiFragment::~G4StableFermiFragment()
{
}
const G4StableFermiFragment & G4StableFermiFragment::operator=(const G4StableFermiFragment &right)
{
G4Exception("G4StableFermiFragment::operator= meant to not be accessable");
return *this;
}
G4bool G4StableFermiFragment::operator==(const G4StableFermiFragment &right) const
{
return false;
}
G4bool G4StableFermiFragment::operator!=(const G4StableFermiFragment &right) const
{
return true;
}
G4FragmentVector * G4StableFermiFragment::GetFragment(const G4LorentzVector & aMomentum)
{
G4FragmentVector * theResult = new G4FragmentVector;
theResult->insert(new G4Fragment(A,Z,aMomentum));
return theResult;
}
@@ -0,0 +1,635 @@
#include "G4StatMF.hh"
// Default constructor
G4StatMF::G4StatMF() : theSim(0)
//:theMicrocanonicalSim(0),theMacrocanonicalSim(0)
{
}
// Destructor
G4StatMF::~G4StatMF()
{
// if (theMicrocanonicalSim != 0) delete theMicrocanonicalSim;
// if (theMacrocanonicalSim != 0) delete theMacrocanonicalSim;
}
// Operators
G4StatMF & G4StatMF::operator=(const G4StatMF & right)
{
G4Exception("G4StatMF::operator= meant to not be accessable");
return *this;
}
G4bool G4StatMF::operator==(const G4StatMF & right)
{
return false;
}
G4bool G4StatMF::operator!=(const G4StatMF & right)
{
return true;
}
G4FragmentVector * G4StatMF::BreakItUp(const G4Fragment &theFragment)
{
G4StatMFMicrocanonical * theMicrocanonicalSim = 0;
G4StatMFMacrocanonical * theMacrocanonicalSim = 0;
// Maximun average multiplicity: M_0 = 2.6 for A ~ 200 and M_0 = 3.3 for A <= 110
G4double MaxAverageMultiplicity = 2.6;
if (theFragment.GetA() <= 110) MaxAverageMultiplicity = 3.3;
if (theFragment.GetExcitationEnergy()/MeV <= 0.0) return 0;
//-------------------------------------------------------
// The first part of simulation procedure
// Direct simulation part (Microcanonical simulation)
//-------------------------------------------------------
theMicrocanonicalSim = new G4StatMFMicrocanonical(theFragment);
G4int Iterations = 0;
G4double Temperature = 0.0;
G4double EnergyCoulomb = 0.0;
G4bool FirstTime = true;
do {
G4bool StrangeFragment = false;
do {
// if (theMicrocanonicalSim->GetMeanMultiplicity() <= MaxAverageMultiplicity) {
G4double theMeanMult = theMicrocanonicalSim->GetMeanMultiplicity();
if (theMeanMult <= MaxAverageMultiplicity) {
// choose fragments atomic numbers and charges from direct simulation
theMicrocanonicalSim->ChooseAandZ(theFragment);
theSim = theMicrocanonicalSim;
} else {
//-------------------------------------------------
// Non direct part (Macrocanonical Simulation)
//-------------------------------------------------
if (FirstTime) {
theMacrocanonicalSim = new G4StatMFMacrocanonical(theFragment);
theSim = theMacrocanonicalSim;
FirstTime = false;
}
// Select calculated fragment total multiplicity,
// fragment atomic numbers and fragment charges.
theMacrocanonicalSim->ChooseAandZ(theFragment);
}
StrangeFragment = false;
for (G4int i = 0; i < theSim->GetMeanMultiplicity(); i++) {
G4int A = theSim->GetFragmentA(i);
G4int Z = theSim->GetFragmentZ(i);
if (A > 1 && (Z >= A || Z <= 0)) {
StrangeFragment = true;
break;
}
}
} while (StrangeFragment);
// I don't know what to do with this
// ????????????????????????????????????
// if (theSim->GetMultiplicity() <= 1) Evaporation();
//--------------------------------------
// Second part of simulation procedure.
//--------------------------------------
// Find temperature of breaking channel.
Temperature = theSim->GetMeanTemperature();
if (FindTemperatureOfBreakingChannel(theFragment,theSim->GetMultiplicity(),
Temperature,EnergyCoulomb)) break;
} while (Iterations++ < 10);
// Separate neutrons from charged fragments
theSim->SortFragments();
G4ThreeVector * FragmentsMomenta = new G4ThreeVector[theSim->GetMultiplicity()];
CoulombImpulse(theFragment,theSim->GetNumOfCharged(),theSim->GetMultiplicity(),
theSim->GetMeanTemperature(),EnergyCoulomb,FragmentsMomenta);
if (theSim->GetNumOfCharged() < theSim->GetMultiplicity())
CalculateFragmentsMomentum(theSim->GetNumOfNeutrons(),theSim->GetNumOfCharged(),Temperature,
1.5*Temperature*theSim->GetNumOfNeutrons(),FragmentsMomenta);
// Perform Lorentz boost
G4LorentzVector * FourMomenta = new G4LorentzVector[theSim->GetMultiplicity()];
G4int i;
for (i = 0; i < theSim->GetMultiplicity(); i ++) {
FourMomenta[i].setVect(FragmentsMomenta[i]);
FourMomenta[i].setE(sqrt(FragmentsMomenta[i].mag2()+
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)*theSim->GetFragmentA(i)*
G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)*theSim->GetFragmentA(i)));
FourMomenta[i].boost(theFragment.GetMomentum().boostVector());
}
// Calculate Fragments excitation energies
G4double * UFragments = new G4double[theSim->GetMultiplicity()];
for (i = 0; i < theSim->GetMultiplicity(); i ++) {
if (G4int(theSim->GetFragmentA(i)) < 3) UFragments[i] = 0.0;
else UFragments[i] = CalculateFragmentExcitationEnergy(i,Temperature);
}
// insert fragments in vector
G4FragmentVector * theResult = new G4FragmentVector;
for (i = 0; i < theSim->GetMultiplicity(); i++) {
G4Fragment * afragment = new G4Fragment(theSim->GetFragmentA(i),theSim->GetFragmentZ(i),
FourMomenta[i]);
afragment->SetExcitationEnergy(UFragments[i]*MeV);
theResult->insert(afragment);
}
delete theMicrocanonicalSim;
if (theMacrocanonicalSim != 0) delete theMacrocanonicalSim;
delete [] FragmentsMomenta;
delete [] FourMomenta;
delete [] UFragments;
return theResult;
}
G4bool G4StatMF::FindTemperatureOfBreakingChannel(const G4Fragment & theFragment,
const G4double & Multiplicity,
G4double & Temperature,
G4double & EnergyCol)
// This finds temperature of breaking channel.
{
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
G4double U = theFragment.GetExcitationEnergy()/MeV;
G4double A13 = pow(A,1./3.);
G4double PkP13 = pow(1.0+G4StatMFParameters::GetKappaCoulomb(),1./3.);
const G4double HT = 0.5;
G4double H = 0.0;
G4int counter = 0;
G4int id = 0;
G4int K1 = 0, K2 = 0;
G4double T = max(Temperature,0.0012);
G4double MassExcess0 = G4NucleiProperties::GetMassExcess(A,Z);
do {
G4double ExchangeEnergy = 0.0;
G4double EB = -MassExcess0;
G4double ECP = 0.0;
G4double ETP = 1.5*T*Multiplicity;
G4int i ;
for (i = 0; i < Multiplicity; i++) {
EB += G4NucleiProperties::GetMassExcess(theSim->GetFragmentA(i),theSim->GetFragmentZ(i));
G4double PA13 = pow(theSim->GetFragmentA(i),1.0/3.0);
ECP += (3./5.)*(1.66/G4StatMFParameters::Getr0())*
(theSim->GetFragmentZ(i)*theSim->GetFragmentZ(i)/PA13);
if (G4int(theSim->GetFragmentA(i)) <= 3) continue;
G4double ESUF = theSim->GetFragmentA(i)*T*T*2.5*G4StatMFParameters::GetBeta0()/
(G4StatMFParameters::GetCriticalTemp()*G4StatMFParameters::GetCriticalTemp()*PA13);
if (theSim->DBetaDT(T) == 0.0) ESUF = 0.0;
ExchangeEnergy += theSim->GetFragmentA(i)*T*T/theSim->GetFragmentInvLevelDensity(i) + ESUF;
if (G4int(theSim->GetFragmentA(i)) == 4) ExchangeEnergy -= ESUF;
}
EnergyCol = (3./5.)*(1.44/G4StatMFParameters::Getr0())*Z*Z*PkP13/A13 - ECP*PkP13;
G4double TotalEnergy = ETP + ExchangeEnergy + EB + EnergyCol;
G4double D = (U - TotalEnergy)/U;
if (abs(D) < 0.003) {
Temperature = T;
return false;
}
counter++;
if (D < 0.0) H = -HT;
else H = HT;
if (D <= 0.0) {
for (;;) {
K1 = 1;
if (K1 ==1 && K2 == 1) id++;
if (id > 30) return true;
T += H/pow(2.0,id);
if ( T >= 0.001) break;
K2 = 1;
H = HT;
}
} else {
for (;;) {
K2 = 1;
if (K1 ==1 && K2 == 1) id++;
if (id > 30) return true;
T += H/pow(2.0,id);
if ( T >= 0.001) break;
K1 = 1;
H = HT;
}
}
} while (counter <= 120);
return true;
}
void G4StatMF::CoulombImpulse(const G4Fragment & theFragment,
const G4int & NumberOfChargedFragments,
const G4int & Multiplicity,
const G4double & Temperature,
const G4double & CoulombEnergy,
G4ThreeVector * MomentumOfFragments)
// Calculate asymptotic fragments momenta (after breakup fragments
// will fly away under Coulomb field)
{
G4ThreeVector * Position = new G4ThreeVector[Multiplicity];
Place(theFragment,Multiplicity,Position);
G4double TotalKineticEnergyOfFragments = (3./2.)*NumberOfChargedFragments*Temperature;
G4double pedo = NumberOfChargedFragments;
G4ThreeVector * Velocities = new G4ThreeVector[NumberOfChargedFragments];
CalculateFragmentsMomentum(NumberOfChargedFragments,0,Temperature,
TotalKineticEnergyOfFragments,Velocities);
G4int i;
for (i = 0; i < NumberOfChargedFragments; i++)
// Velocities[i].setMag(Velocities[i].mag()/(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)*theSim->GetFragmenA(i)/MeV));
Velocities[i] *= (G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)*theSim->GetFragmentA(i)/MeV);
// Solve equations of motion for fragments
SolveEqOfMotion(Position,Velocities,MomentumOfFragments,NumberOfChargedFragments,
CoulombEnergy,TotalKineticEnergyOfFragments);
for (i = 0; i < NumberOfChargedFragments; i++)
MomentumOfFragments[i] = Velocities[i]*(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)*theSim->GetFragmentA(i)/MeV);
delete [] Velocities;
delete [] Position;
return;
}
void G4StatMF::Place(const G4Fragment & theFragment,
const G4int & Multiplicity,
G4ThreeVector * Position)
// Randomly samples fragments positions inside prolongated ellipsoid
{
const G4double RN = 1.17;
const G4double RSys = 2.0*RN*pow(theFragment.GetA(),1./3.);
G4int i;
for (;;) {
i = 1;
// This gives the position at the breakup instant
G4double R = (RSys - RN*pow(theSim->GetFragmentA(0),1./3.))*pow(G4UniformRand(),1./3.);
Position[0] = IsotropicVector(R);
G4bool again = false;
for (;;) {
G4int k = i;
G4int kk = 0;
i++;
G4double RR = 0.0;
G4double RMin = 0.0;
do {
kk++;
if (again = (kk > 1000)) break;
R = (RSys - RN*pow(theSim->GetFragmentA(0),1./3.))*pow(G4UniformRand(),1./3.);
Position[i] = IsotropicVector(R);
for (G4int j = 0; j < k; j++) {
G4ThreeVector tmp = Position[i] - Position[j];
RR = tmp.mag2();
RMin = RN*(pow(theSim->GetFragmentA(i),1./3.)+pow(theSim->GetFragmentA(j),1./3.));
if (RR < RMin*RMin) break;
}
} while (RR < RMin*RMin);
if (again) {
again = false;
break;
}
if (i == Multiplicity) return;
}
}
}
void G4StatMF::SolveEqOfMotion(G4ThreeVector * InitialPos,
G4ThreeVector * InitialVel,
G4ThreeVector * FinalVel,
const G4int & Multiplicity,
const G4double & CoulombEnergy,
const G4double & KineticEnergy)
// This method will find a solution of Newton's equation of motion
// for fragments in the self-consistent time-dependent Coulomb field
{
if (CoulombEnergy <= 0.0) return;
G4int Iterations = 0;
G4double TN = 0.0;
G4double TS = 0.0;
G4double DT = 2.0;
G4ThreeVector * A = new G4ThreeVector[Multiplicity];
G4ThreeVector * Pos = new G4ThreeVector[Multiplicity];
G4int i;
for (i = 0; i < Multiplicity; i++) {
FinalVel[i] = InitialVel[i];
Pos[i] = InitialPos[i];
}
G4ThreeVector ** Force = new G4ThreeVector*[Multiplicity];
for (i = 0; i < Multiplicity; i++)
Force[i] = new G4ThreeVector[Multiplicity];
G4ThreeVector * ForceS = new G4ThreeVector[Multiplicity];
G4ThreeVector * Accel = new G4ThreeVector[Multiplicity];
G4ThreeVector * SavedVelo = new G4ThreeVector[Multiplicity];
do {
G4int i;
G4ThreeVector distance;
for (i = 0; i < Multiplicity; i++) {
for (G4int j = 0; j < Multiplicity; j++) {
if (i != j) {
distance = InitialPos[i] - InitialPos[j];
Force[i][j] = (1.44*(theSim->GetFragmentA(i)*theSim->GetFragmentA(j))/
(distance.mag2()*distance.mag()))*distance;
}
}
}
for ( i = 0; i < Multiplicity; i++) {
for (G4int j = 0; j < Multiplicity; j++) {
if (i != j) ForceS[i] += Force[i][j];
}
}
for ( i = 0; i < Multiplicity; i++) {
Accel[i] = ForceS[i];
Accel[i] *= 1./(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)*theSim->GetFragmentA(i)/MeV);
}
TN = TS + DT;
for ( i = 0; i < Multiplicity; i++) {
SavedVelo[i] = FinalVel[i];
FinalVel[i] = Accel[i]*(TN-TS);
Pos[i] += (SavedVelo[i]+FinalVel[i])*(TN-TS)*0.5;
}
if (Iterations >= 50 && Iterations < 75) DT = 4.;
else if (Iterations >= 75) DT = 10.;
TS = TN;
} while (Iterations++ < 100);
// Summed fragment kinetic energy
G4double SummedKineticEnergy = 0.0;
for ( i = 0; i < Multiplicity; i++) SummedKineticEnergy +=
theSim->GetFragmentA(i)*(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)/MeV)*
0.5*FinalVel[i].mag2();
// Scaling of fragment velocities
G4double Eta = ( CoulombEnergy + KineticEnergy ) / SummedKineticEnergy;
for ( i = 0; i < Multiplicity; i++) FinalVel[i] *= Eta;
// Garbage collection
delete [] A;
delete [] Pos;
for ( i = 0; i < Multiplicity; i++) delete [] Force[i];
delete [] Force;
delete [] ForceS;
delete [] SavedVelo;
return;
}
void G4StatMF::CalculateFragmentsMomentum(const G4int & INET,
const G4int & NFrags,
const G4double & T,
const G4double & TotKineticE,
G4ThreeVector * Momentum)
// Calculates fragments momentum components at the breakup instant.
// Fragment kinetic energies will be calculated according to the
// Boltzamann distribution at given temperature.
{
if (INET <= 0) return;
G4int NFrags1 = NFrags;
G4int NFragsM = NFrags + INET;
if (INET == 1) {
// INET == 1 only one fragment and absolute moment value will be
Momentum[NFrags1] =
IsotropicVector(sqrt(2.*(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)/MeV)*
theSim->GetFragmentA(NFrags1)*TotKineticE));
} else if (INET == 2) {
Momentum[NFrags1] = IsotropicVector(sqrt(2.*(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)/MeV)*
(theSim->GetFragmentA(NFrags1)*theSim->GetFragmentA(NFragsM))/
(theSim->GetFragmentA(NFrags1)+theSim->GetFragmentA(NFragsM))*
TotKineticE));
Momentum[NFragsM] = Momentum[NFrags1];
} else { // INET > 2
// Sample kinetic energy sccording to Boltzmann distribution
// Calculate the absolute values of fragments momenta
// Calculate fragments momenta components (using isotropicl angular distrib.)
// Sum fragments kinetic energies and fragments momentum components to check constraints.
G4double EE = 0.0, Em = 0.0;
G4int i1 = 0, i2 = 0;
G4ThreeVector p;
G4double Esum = 0.0;
G4ThreeVector Psum(0.0,0.0,0.0);
do {
G4int NFragsM2 = NFragsM - 2;
G4double FEMT = sqrt(0.5*T)*exp(-0.5);
for (G4int i = NFrags1; i < NFragsM2; i++) {
for (;;) {
G4double E = G4UniformRand()*9.0*T;
G4double FE = sqrt(E)*exp(-E/T);
G4double FErand = G4UniformRand()*FEMT;
if (FErand <= FE) {
Momentum[i] = IsotropicVector(sqrt(2.0*E*(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)/MeV)*theSim->GetFragmentA(i)));
Esum += E;
Psum += Momentum[i];
break;
}
}
}
// calculate momenta of two last fragments
// to satisfy constraint
i1 = NFragsM2;
i2 = NFragsM2 + 1;
p = -Psum;
EE = TotKineticE - Esum;
// Kinetic energy EE should be shared between two last fragments
Em = p.mag2()/((G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)/MeV)*(theSim->GetFragmentA(i1)+theSim->GetFragmentA(i2)));
} while (EE <= Em);
G4double H = 1.0 + theSim->GetFragmentA(i2)/theSim->GetFragmentA(i1);
G4double CTM12 = H*(1.0 - 2.0*theSim->GetFragmentA(i2)*(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)/MeV)*EE/p.mag2());
G4double CosTheta1;
G4int zn;
for (;;) {
do {
CosTheta1 = 1.0 - 2.0*G4UniformRand();
} while (CosTheta1*CosTheta1 < CTM12);
if (CTM12 < 0.0) {
zn = 1.0;
break;
} else {
if (CosTheta1 < 0.0) continue;
else {
if (G4UniformRand() <= 0.5) {
zn = -1.0;
break;
} else {
zn = 1.0;
break;
}
}
}
}
G4double P1 = (p.mag()*CosTheta1+zn*sqrt(p.mag2()*CosTheta1*CosTheta1-p.mag2()*CTM12))/H;
G4double P2 = sqrt(P1*P1+p.mag2() - 2.0*P1*p.mag()*CosTheta1);
G4double Phi = twopi*G4UniformRand();
G4double SinTheta1 = sqrt(1.0 - CosTheta1*CosTheta1);
G4double CosPhi1 = cos(Phi);
G4double SinPhi1 = sin(Phi);
G4double CosPhi2 = -CosPhi1;
G4double SinPhi2 = -SinPhi1;
G4double CosTheta2 = (p.mag2() + P2*P2 - P1*P1)/(2.0*p.mag()*P2);
G4double SinTheta2 = 0.0;
if (CosTheta2 > -1.0 && CosTheta2 < 1.0) SinTheta2 = sqrt(1.0 - CosTheta2*CosTheta2);
G4ThreeVector Pi(P1*SinTheta1*CosPhi1,P1*SinTheta1*SinPhi1,P1*CosTheta1);
G4ThreeVector Pj(P2*SinTheta2*CosPhi2,P2*SinTheta2*SinPhi2,P2*CosTheta2);
G4ThreeVector a = p;
G4ThreeVector b(1.0,0.0,0.0);
Momentum[i1] = Rotor(Pi,a,b);
Momentum[i2] = Rotor(Pj,a,b);
Psum += Momentum[i1] + Momentum[i2];
Esum += Momentum[i1].mag2()/(2.0*(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)/MeV)*theSim->GetFragmentA(i1))
+ Momentum[i2].mag2()/(2.0*(G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(1,1)/MeV)*theSim->GetFragmentA(i2));
}
return;
}
G4ThreeVector G4StatMF::Rotor(const G4ThreeVector & P,
const G4ThreeVector & A,
const G4ThreeVector & B)
// Rotates a 3-vector P to close momentum triangle P + A + B = 0
{
G4double ScalarProd = A * B;
G4double Alpha1 = ScalarProd/A.mag();
G4double Alpha2 = sqrt(B.mag2() - Alpha1*Alpha1);
G4ThreeVector NewV(A.y()*B.z()-A.z()*B.y(),
A.z()*B.x()-A.x()*B.z(),
A.x()*B.y()-A.y()*B.x());
G4ThreeVector TheRotatedVector;
TheRotatedVector.setX(P.x()*B.x()/Alpha2 +
(P.z()-Alpha1*P.x()/Alpha2)*A.x()/A.mag() +
(P.y()*A.x())/(Alpha2*A.mag()));
TheRotatedVector.setX(P.x()*B.y()/Alpha2 +
(P.z()-Alpha1*P.x()/Alpha2)*A.y()/A.mag() +
(P.y()*A.y())/(Alpha2*A.mag()));
TheRotatedVector.setX(P.x()*B.z()/Alpha2 +
(P.z()-Alpha1*P.x()/Alpha2)*A.z()/A.mag() +
(P.y()*A.z())/(Alpha2*A.mag()));
return TheRotatedVector;
}
G4double G4StatMF::CalculateFragmentExcitationEnergy(const G4int & index, const G4double & T)
{
G4double EvapEnergy = theSim->GetFragmentA(index)*T*T/theSim->GetFragmentInvLevelDensity(index);
// For alpha particles
if (theSim->GetFragmentA(index) == 4) return EvapEnergy;
else {
// Term connected with surface energy
G4double ESurf;
if (theSim->DBetaDT(T) == 0.0) ESurf = 0.0;
else ESurf = (theSim->GetFragmentA(index)*T*T*2.5*G4StatMFParameters::GetBeta0())/
(G4StatMFParameters::GetCriticalTemp()*G4StatMFParameters::GetCriticalTemp()*
pow(theSim->GetFragmentA(index),1.0/3.0));
EvapEnergy += ESurf;
}
return EvapEnergy;
}
G4ThreeVector G4StatMF::IsotropicVector(const G4double Magnitude)
// Samples a isotropic random vectorwith a magnitud given by Magnitude.
// By default Magnitude = 1
{
G4double CosTheta = 1.0 - 2.0*G4UniformRand();
G4double SinTheta = sqrt(1.0 - CosTheta*CosTheta);
G4double Phi = twopi*G4UniformRand();
G4ThreeVector Vector(Magnitude*cos(Phi)*SinTheta,
Magnitude*cos(Phi)*CosTheta,
Magnitude*sin(Phi));
return Vector;
}
@@ -0,0 +1,33 @@
#include "G4StatMFFragment.hh"
// Copy constructor
G4StatMFFragment::G4StatMFFragment(const G4StatMFFragment & right)
{
G4Exception("G4StatMFFragment::copy_constructor menat to not be accessable");
}
// Operators
const G4StatMFFragment & G4StatMFFragment::operator=(const G4StatMFFragment & right)
{
G4Exception("G4StatMFFragment::operator= meant to not be accessable");
return *this;
}
G4bool G4StatMFFragment::operator==(const G4StatMFFragment & right) const
{
return false;
}
G4bool G4StatMFFragment::operator!=(const G4StatMFFragment & right) const
{
return true;
}
@@ -0,0 +1,666 @@
#include "G4StatMFMacrocanonical.hh"
// constructor
G4StatMFMacrocanonical::G4StatMFMacrocanonical(const G4Fragment & theFragment)
{
// Get memory for channels
for (G4int i = 0; i < theFragment.GetA(); i++)
theChannels.insert(new G4StatMFFragment);
// Perform class initialization
Initialize(theFragment);
}
// destructor
G4StatMFMacrocanonical::~G4StatMFMacrocanonical()
{
// garbage collection
theChannels.clearAndDestroy();
}
// operators definitions
G4StatMFMacrocanonical &
G4StatMFMacrocanonical::operator=(const G4StatMFMacrocanonical & right)
{
G4Exception("G4StatMFMacrocanonical::operator= meant to not be accessable");
return *this;
}
G4bool G4StatMFMacrocanonical::operator==(const G4StatMFMacrocanonical & right) const
{
return false;
}
G4bool G4StatMFMacrocanonical::operator!=(const G4StatMFMacrocanonical & right) const
{
return true;
}
// Initialization method
void G4StatMFMacrocanonical::Initialize(const G4Fragment & theFragment)
{
// Excitation Energy (in MeV)
G4double U = theFragment.GetExcitationEnergy()/MeV;
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
for (G4int i = 0; i < A; i++) {
// Calculate Inverse Density Levels for channels
theChannels(i)->SetInvLevelDensity(i);
}
// Free Internal energy at T = 0
FreeInternalE0 = A*( -G4StatMFParameters::GetE0() + // Volume term (for T = 0)
G4StatMFParameters::GetGamma0()*(1.0-2.0*Z/A)*(1.0-2.0*Z/A) ) + // Symmetry term
G4StatMFParameters::GetBeta0()*pow(A,2.0/3.0) + // Surface term (for T = 0)
(3.0/5.0)*1.44*Z*Z/(G4StatMFParameters::Getr0()*pow(A,1.0/3.0)); // Coulomb term
CalculateTemperature(theFragment);
return;
}
void G4StatMFMacrocanonical::CalculateTemperature(const G4Fragment & theFragment)
{
// Excitation Energy (in MeV)
G4double U = theFragment.GetExcitationEnergy()/MeV;
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
// Fragment Multiplicity
G4double FragMult = min((1.0+2.31*(U/A - 3.5))*A/100.0,
2.0);
// Parameter Kappa
G4double Kappa = (1.0+1.44*(pow(FragMult,1./3.)-1)/(1.17*pow(A,1./3.)));
Kappa = Kappa*Kappa*Kappa - 1.0;
// Temperature
G4double Ta = max(sqrt(U/(0.125*A)),0.0012);
G4double Tb = Ta;
G4double ExcitEnergyPerNucleon, TotalMultiplicity;
MeanTemperature = Ta;
FragmentsExcitationEnergyAndEntropy(theFragment,Kappa,ExcitEnergyPerNucleon,TotalMultiplicity);
G4double Da = ((U/A) - ExcitEnergyPerNucleon)/(U/A);
G4double Db = 0.0;
// bracketing the solution
if (Da == 0.0) {
MeanTemperature = Ta;
return;
} else if (Da < 0.0) {
do {
Tb -= 0.5*Tb; MeanTemperature = Tb;
FragmentsExcitationEnergyAndEntropy(theFragment,Kappa,ExcitEnergyPerNucleon,TotalMultiplicity);
Db = ((U/A) - ExcitEnergyPerNucleon)/(U/A);
} while (Db < 0.0);
} else {
do {
Tb += 0.5*Tb; MeanTemperature = Tb;
FragmentsExcitationEnergyAndEntropy(theFragment,Kappa,ExcitEnergyPerNucleon,TotalMultiplicity);
Db = ((U/A) - ExcitEnergyPerNucleon)/(U/A);
} while (Db > 0.0);
}
G4double eps = 1.0e-14 * abs(Tb-Ta);
for (G4int i = 0; i < 1000; i++) {
G4double Tc = (Ta+Tb)/2.0;
if (abs(Ta-Tb) <= eps) {
MeanTemperature = Tc;
return;
}
MeanTemperature = Tc;
FragmentsExcitationEnergyAndEntropy(theFragment,Kappa,ExcitEnergyPerNucleon,TotalMultiplicity);
G4double Dc = ((U/A) - ExcitEnergyPerNucleon)/(U/A);
if (Dc == 0.0) {
MeanTemperature = Tc;
return;
}
if (Da*Dc < 0.0) {
Tb = Tc;
Db = Dc;
} else {
Ta = Tc;
Da = Dc;
}
}
G4cerr << "G4StatMFMacrocanoncal::CalculateTemperature: I can't calculate the temperature";
return;
// // Temperature
// G4double T = max(sqrt(U/(0.125*A)),0.0012);
// const G4double HT = 0.5;
// G4double H = 0.0;
// G4int counter = 0;
// do {
// G4int id = 0;
// G4double ExcitEnergyPerNucleon, TotalMultiplicity;
// FragmentsExcitationEnergyAndEntropy(theFragment,Kappa,
// ExcitEnergyPerNucleon,
// TotalMultiplicity);
// G4double D = ((U/A) - ExcitEnergyPerNucleon)/(U/A);
// if (abs(D) < 0.003) {
// MeanMultiplicity = TotalMultiplicity;
// return;
// }
// if (D <= 0.0) H = -HT;
// else H = HT;
// if (D <= 0.0) {
// do {
// T += H/pow(2.0,id);
// if (T > 0.001) break;
// H = HT;
// } while (id++ < 30);
// } else {
// do {
// T += H/pow(2.0,id);
// if (T > 0.001) break;
// H = HT;
// } while (id++ < 30);
// }
// if (id >= 30) {
// G4cerr << "G4StatMFMacrocanoncal::CalculateTemperature: suspecting nucleus" << endl;
// return;
// }
// } while (counter++ <= 60);
// G4cerr << "G4StatMFMicrocanoncal::CalculateTemperature: suspecting nucleus" << endl;
// return;
}
void G4StatMFMacrocanonical::FragmentsExcitationEnergyAndEntropy(const G4Fragment & theFragment,
const G4double Kappa,
G4double & ExcitEnergyPerNucleon,
G4double & TotalMultiplicity)
// Calculates excitation energy per nucleon and summed fragment multiplicity and entropy
{
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
// Model Parameters
G4double A13 = pow(A,1./3.);
G4double A23 = A13*A13;
G4double R0 = G4StatMFParameters::Getr0()*A13;
G4double R = R0*pow(1.0+G4StatMFParameters::GetKappaCoulomb(), 1./3.);
// Calculate fragment charges over fragment atomic numbers ratios.
CalculateZARatio(theFragment,Kappa);
// Compute fragment energies
FragmentEnergies(theFragment,Kappa);
// Compute summed fragment entropy
MeanEntropy = TotalFragmentsEntropy(A,Kappa); // En realidad deberia ser TotalEntropy???
// Average total fragment energy
G4double AverTotalFragEnergy = 0.0;
G4int i;
for (i = 0; i < A; i++) AverTotalFragEnergy +=
theChannels(i)->GetMultiplicity()*theChannels(i)->GetEnergy();
// Add Coulomb energy
AverTotalFragEnergy += 0.6*1.44*Z*Z/R;
// Excitation energy per nucleon
ExcitEnergyPerNucleon = (AverTotalFragEnergy - FreeInternalE0)/A;
TotalMultiplicity = 0.0;
for (i = 0; i< A; i++) TotalMultiplicity += theChannels(i)->GetMultiplicity();
return;
}
void G4StatMFMacrocanonical::CalculateZARatio(const G4Fragment & theFragment, const G4double & Kappa)
// This calculates fragment charges over fragment atomic numbers
{
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
G4double CP = (0.6*1.44/G4StatMFParameters::Getr0())*
(1.0-1.0/pow(1.0+G4StatMFParameters::GetKappaCoulomb(),1.0/3.0));
// RWTValOrderedVector<G4int> C1;
// RWTValOrderedVector<G4int> C2;
RWTValVector<G4int> C1; C1.reshape(G4int(A+0.5));
RWTValVector<G4int> C2; C2.reshape(G4int(A+0.5));
G4int i;
for (i = 4; i < A; i++) {
G4double a = i+1.0;
G4double CC = 8.0*G4StatMFParameters::GetGamma0()+2.0*CP*pow(a,2.0/3.0);
C1(i) = 4.0*G4StatMFParameters::GetGamma0()/CC;
C2(i) = 1.0/CC;
}
ChemPotentialNu = (Z/A)*(8.0*G4StatMFParameters::GetGamma0()+2.0*CP*pow(A,2./3.)) -
4.0*G4StatMFParameters::GetGamma0();
G4int K = 0;
G4int K1 = 0, K2 = 0;
G4int id = 0;
const G4double HM = 1.0;
do {
theChannels(1)->SetZARatio(0.5);
theChannels(2)->SetZARatio(0.5);
theChannels(3)->SetZARatio(0.5);
for (i = 4; i < A; i++)
{ G4int temp = C2(i);
theChannels(i)->SetZARatio(C1(i) + temp * ChemPotentialNu); }
// Calculate fragment multiplicities
CalculateMultiplicities(theFragment,Kappa);
theChannels(0)->SetZARatio(YP/(YP+YN));
G4double ZTotal = 0.0;
for (i = 0; i < Z; i++) ZTotal += G4double(i)*theChannels(i)->GetZARatio()*
theChannels(i)->GetMultiplicity();
K++;
G4double D = (Z - ZTotal)/Z;
if (abs(D) < 0.002) break;
G4double H;
if (D < 0.0) H = -HM;
else H = HM;
if (D <= 0.0) {
K1 = 1;
if (K1 == 1 && K2 == 2) id++;
ChemPotentialNu += pow(H/2.0,id);
} else {
K2 = 1;
if (K1 == 1 && K2 == 2) id++;
ChemPotentialNu += pow(H/2.0,id);
}
} while (K <= 60 && id <= 30);
if (K > 60 || id > 30) G4cerr << "G4StatMFMacrocanonical::CalculateZARatio: suspecting nucleus" << endl;
return;
}
void G4StatMFMacrocanonical::CalculateMultiplicities(const G4Fragment & theFragment, const G4double & Kappa)
//
{
G4double A = theFragment.GetA();
G4double CP = (0.6*1.44/G4StatMFParameters::Getr0())*
(1.0-1.0/pow(1.0+G4StatMFParameters::GetKappaCoulomb(),1.0/3.0));
// calculation of chemical potential \mu
ChemPotentialMu = -G4StatMFParameters::GetE0()+
MeanTemperature*MeanTemperature/theChannels(3)->GetInvLevelDensity() -
ChemPotentialNu*theChannels(3)->GetZARatio() +
G4StatMFParameters::GetGamma0()*(1.0-2.0*theChannels(3)->GetZARatio())*(1.0-2.0*theChannels(3)->GetZARatio()) +
(2.0/3.0)*Beta(MeanTemperature)/1.71 +
5.0*CP*theChannels(3)->GetZARatio()*theChannels(3)->GetZARatio()*2.92/3.0 -
1.5*MeanTemperature/5.0;
G4int K = 0;
G4int K1 = 0, K2 = 0;
G4int id = 0;
G4double H = 0.0;
const G4double HM = 1.0;
do {
// Calculate mean fragment multiplicities
MeanFragmentMultiplicities(theFragment, Kappa);
// found fragment multiplicities should satisfy constraint: \sum_f N(f) A_f = A
// using this constraint, chemical potential \mu is defined by iterations
G4double Atot = 0.0;
for (G4int i = 0; i < A; i++) Atot += i*theChannels(i)->GetMultiplicity();
K++;
G4double D = (A-Atot)/A;
if (abs(D) < 0.001) break; // or break;
if (D < 0.0) H = -HM;
else H = HM;
if ( D<= 0.0 ) {
K1 = 1;
if (K1 == 1 && K2 == 1) id++;
ChemPotentialMu += H/pow(2.0,id);
} else {
K2 = 1;
if (K1 == 1 && K2 == 1) id++;
ChemPotentialMu += H/pow(2.0,id);
}
} while (K <= 60 && id <= 30);
if (K > 60 || id > 30) G4cerr << "G4StatMFMacrocanonical::CalculateMultiplicities: suspecting nucleus" << endl;
return;
}
void G4StatMFMacrocanonical::MeanFragmentMultiplicities(const G4Fragment & theFragment, const G4double & Kappa)
// Calculates fragment multiplicities
{
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
G4double A13 = pow(A,1.0/3.0);
G4double R0 = G4StatMFParameters::Getr0()*A13;
G4double V0 = (4.0/3.0)*pi*R0*R0*R0;
G4double CP = (0.6*1.44/G4StatMFParameters::Getr0())*
(1.0-1.0/pow(1.0+G4StatMFParameters::GetKappaCoulomb(),1.0/3.0));
G4double ThermalWaveLenght = 16.15/sqrt(MeanTemperature);
G4double ThermalWaveLenght3 = ThermalWaveLenght*ThermalWaveLenght*ThermalWaveLenght;
YN = (2.0*Kappa*V0/ThermalWaveLenght3)*
exp(ChemPotentialMu/MeanTemperature);
YP = (2.0*Kappa*V0/ThermalWaveLenght3)*
exp((ChemPotentialMu+ChemPotentialNu-CP)/MeanTemperature);
Y2 = (3.0*2.0*sqrt(2.0)*Kappa*V0/ThermalWaveLenght3)*
exp((2.796+2.0*(ChemPotentialMu+ChemPotentialNu*theChannels(1)->GetZARatio())-
CP*theChannels(1)->GetZARatio()*theChannels(1)->GetZARatio()*
pow(2.0,5.0/3.0))/MeanTemperature);
Y3 = (4.0*3.0*sqrt(3.0)*Kappa*V0/ThermalWaveLenght3)*
exp((9.224+3.0*(ChemPotentialMu+ChemPotentialNu*theChannels(2)->GetZARatio())-
CP*theChannels(2)->GetZARatio()*theChannels(2)->GetZARatio()*
pow(3.0,5.0/3.0))/MeanTemperature);
Y4 = (8.0*Kappa*V0/ThermalWaveLenght3)*
exp((30.11+4.0*(ChemPotentialMu+ChemPotentialNu*theChannels(3)->GetZARatio()+
MeanTemperature*MeanTemperature/theChannels(3)->GetInvLevelDensity())-
CP*theChannels(3)->GetZARatio()*theChannels(3)->GetZARatio()*pow(4.0,5.0/3.0))/MeanTemperature);
// Nucleon multiplicity
theChannels(0)->SetMultiplicity(YN+YP);
// A_f = 2 multiplicity
theChannels(1)->SetMultiplicity(Y2);
// A_f = 3 multiplicity
theChannels(2)->SetMultiplicity(Y3);
// A_f = 4 multiplicity
theChannels(3)->SetMultiplicity(Y4);
for (G4int i = 4; i < A; i++) {
G4double a = G4double(i) + 1.0;
G4double a23 = pow(a,2.0/3.0);
G4double VNE = (ChemPotentialMu+ChemPotentialNu*theChannels(i)->GetZARatio()+
G4StatMFParameters::GetE0()+
MeanTemperature*MeanTemperature/theChannels(i)->GetInvLevelDensity()-
G4StatMFParameters::GetGamma0()*(1.0-2.0*theChannels(i)->GetZARatio())*
(1.0-2.0*theChannels(i)->GetZARatio()))*a -
Beta(MeanTemperature)*a23 -
CP*theChannels(i)->GetZARatio()*theChannels(i)->GetZARatio()*a*a23;
VNE /= MeanTemperature;
if (VNE > 30.0) theChannels(i)->SetMultiplicity(999.0);
else {
G4double VN = exp(VNE);
VN *= Kappa*V0*sqrt(a)*a/ThermalWaveLenght3;
if (VN < 1.0e-30) theChannels(i)->SetMultiplicity(0.0);
else theChannels(i)->SetMultiplicity(VN);
}
}
return;
}
void G4StatMFMacrocanonical::FragmentEnergies(const G4Fragment & theFragment,const G4double & Kappa)
// Calculate Fragment energies at actual temperature
{
G4double A = theFragment.GetA();
G4double PkP13 = pow(1./(1. + G4StatMFParameters::GetKappaCoulomb()),1./3.);
// factor needed for calculate Coulomb energy
G4double CP = (0.6*1.44/G4StatMFParameters::Getr0())*(1.-PkP13);
theChannels(0)->SetEnergy(CP*theChannels(0)->GetZARatio() + 1.5*MeanTemperature);
theChannels(1)->SetEnergy(-2.796 +
CP*theChannels(1)->GetZARatio()*theChannels(1)->GetZARatio()*pow(2.,5./3.) +
1.5*MeanTemperature);
theChannels(2)->SetEnergy(-9.224 +
CP*theChannels(2)->GetZARatio()*theChannels(2)->GetZARatio()*pow(3.,5./3.) +
1.5*MeanTemperature);
theChannels(3)->SetEnergy(-30.11 +
CP*theChannels(3)->GetZARatio()*theChannels(3)->GetZARatio()*pow(4.,5./3.) +
1.5*MeanTemperature +
4.0*MeanTemperature*MeanTemperature/theChannels(3)->GetInvLevelDensity());
for (G4int i = 4; i < A; i++) {
G4double a = i+1.0;
G4double a23 = pow(a,2./3.);
// Volume and symmetry terms
G4double EV = a*(MeanTemperature*MeanTemperature/theChannels(i)->GetInvLevelDensity() -
G4StatMFParameters::GetE0() +
G4StatMFParameters::GetGamma0()*
(1.-2.*theChannels(i)->GetZARatio()*theChannels(i)->GetZARatio()));
// Surface term
G4double ES = (Beta(MeanTemperature) - MeanTemperature*DBetaDT(MeanTemperature))*a23;
// Coulomb term
G4double EC = CP*a23*a*theChannels(i)->GetZARatio()*theChannels(i)->GetZARatio();
// translational term
G4double ET = 1.5*MeanTemperature;
// Total Energy
theChannels(i)->SetEnergy( EV + ES + EC + ET );
}
return;
}
G4double G4StatMFMacrocanonical::TotalFragmentsEntropy(const G4double & A, const G4double & Kappa)
// Calculates summed fragments entropy
{
// Thermal Wave Length at actual temperature
G4double ThermalWaveLength = 16.15/sqrt(MeanTemperature);
G4double ThermalWaveLength3 = ThermalWaveLength*ThermalWaveLength*ThermalWaveLength;
G4double R0 = G4StatMFParameters::Getr0()*pow(A,2./3.);
G4double V0 = (4.*pi/3.)*R0*R0*R0;
// Entropy
G4double S = 0.0;
if (YN > 0.0) S += YN*(2.5+log(2.*Kappa*V0/(ThermalWaveLength3*YN)));
if (YP > 0.0) S += YP*(2.5+log(2.*Kappa*V0/(ThermalWaveLength3*YP)));
if (Y2 > 0.0) S += Y2*(2.5+log(3.*Kappa*V0*2.*sqrt(2.)/(ThermalWaveLength3*Y2)));
if (Y3 > 0.0) S += Y3*(2.5+log(4.*Kappa*V0*3.*sqrt(3.)/(ThermalWaveLength3*Y3)));
if (Y4 > 0.0) S += Y4*(2.5+log(8.*Kappa*V0/(ThermalWaveLength3*Y4)) +
8.0*MeanTemperature/theChannels(3)->GetInvLevelDensity());
for (G4int i = 4; i < A; i++) {
if (theChannels(i)->GetMultiplicity() <= 0.0) continue;
G4double a = G4double(i)+1.0;
G4double SV = 2.0*a*MeanTemperature/theChannels(i)->GetInvLevelDensity();
G4double SS = -DBetaDT(MeanTemperature)*pow(a,2./3.);
G4double ST = 2.5+log(Kappa*V0*sqrt(a)*a/(ThermalWaveLength3*theChannels(i)->GetMultiplicity()));
S += (SV+SS+ST)*theChannels(i)->GetMultiplicity();
}
return S;
}
void G4StatMFMacrocanonical::ChooseAandZ(const G4Fragment &theFragment)
// Calculate total fragments multiplicity, fragment atomic numbers and charges
{
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
RWTValVector<G4double> ANumbers(A);
Multiplicity = ChooseA(A,ANumbers);
G4int i;
for (i = 0; i < Multiplicity; i++) {
FragmentsA.insert(0.0);
FragmentsZ.insert(0.0);
}
G4int s = 0;
for (i = 0; i < A; i++) {
if (ANumbers(i) == 0) continue;
for (G4int j = 0; j < ANumbers(i); j++) FragmentsA(s+j) = i+1;
s += ANumbers(i) - 1;
}
G4int im = 0;
for (G4int j = 0; j < Multiplicity; j++) {
G4double FragmentsAMax = 0.0;
for (i = j; i < Multiplicity; i++) {
if (FragmentsA(i) <= FragmentsAMax) continue;
else {
im = i;
FragmentsAMax = FragmentsA(im);
}
}
FragmentsA(im) = FragmentsA(j);
FragmentsA(j) = FragmentsAMax;
}
ChooseZ(Z,Multiplicity);
return;
}
G4double G4StatMFMacrocanonical::ChooseA(const G4double A, RWTValVector<G4double> & ANumbers)
// Determines fragments multiplicities and compute total fragment multiplicity
{
G4double multiplicity = 0.0;
G4double GH = 0.0;
G4int i;
for (i = 0; i < A; i++) GH += theChannels(i)->GetMultiplicity();
G4double SqrtGH = sqrt(GH) + 0.5;
RWTValVector<G4double> AcumMultiplicity;
AcumMultiplicity(0) = theChannels(0)->GetMultiplicity();
for (i = 1; i < A; i++) AcumMultiplicity(i) = AcumMultiplicity(i-1) + theChannels.at(i)->GetMultiplicity();
do {
G4int CheckA = -1;
G4int SumA = 0;
G4int ThisOne = 0;
do {
if (CheckA < 0) {
SumA = 0;
ThisOne = 0;
for (i = 0; i < A; i++) ANumbers(i) = 0.0;
multiplicity = 0.0;
}
G4double RandNumber = G4UniformRand()*GH;
for (i = 0; i < A; i++) {
if (RandNumber < AcumMultiplicity(i)) {
ThisOne = i;
break;
}
}
multiplicity++;
ANumbers(ThisOne) = ANumbers(ThisOne)+1;
SumA += ThisOne+1;
CheckA = A - SumA;
} while (CheckA != 0);
} while (abs(GH - multiplicity) > SqrtGH);
return multiplicity;
}
void G4StatMFMacrocanonical::ChooseZ(const G4int & Z, const G4double multiplicity)
//
{
G4double DeltaZ = 0.0;
G4double CP = (0.6*1.44/G4StatMFParameters::Getr0())*
(1.0 - 1.0/pow(1.0+G4StatMFParameters::GetKappaCoulomb(),1./3.));
do {
G4int SumZ = 0;
for (G4int i = 0; i < multiplicity; i++) {
G4double A = FragmentsA(i);
if (A <= 1.0) {
G4double RandNumber = G4UniformRand();
FragmentsZ.insert(0.0); // FragmentsZ(i) = 0.0;
if (RandNumber > (YN/(YN+YP))) {
FragmentsZ(i) = FragmentsZ(i) + 1.;
SumZ += FragmentsZ(i);
}
} else {
G4double RandZ;
G4double CC = 8.0*G4StatMFParameters::GetGamma0()+2.0*CP*pow(FragmentsA(i),2./3.);
G4double ZMean;
if (FragmentsA(i) > 1.5 && FragmentsA(i) < 4.5) ZMean = 0.5*FragmentsA(i);
else ZMean = FragmentsZ(i)*(4.*G4StatMFParameters::GetGamma0()+ChemPotentialNu)/CC;
G4double ZDispersion = sqrt(FragmentsA(i)*MeanTemperature/CC);
G4int z;
do {
RandZ = RandGauss::shoot(ZMean,ZDispersion);
z = G4int(RandZ);
} while (z < 0 || z > Z);
FragmentsZ(i) = RandZ;
SumZ += z;
}
}
DeltaZ = Z - SumZ;
} while (abs(DeltaZ) > 1.1);
// DeltaZ can be 0, 1 or -1
FragmentsZ(0) += DeltaZ;
return;
}
@@ -0,0 +1,763 @@
// $Id: G4StatMFMicrocanonical.cc,v 1.3 1998/11/12 16:19:51 allison Exp $
#include "G4StatMFMicrocanonical.hh"
// constructor
G4StatMFMicrocanonical::G4StatMFMicrocanonical(const G4Fragment & theFragment)
{
// Get memory for channels
for (G4int i = 0; i < theFragment.GetA(); i++)
theChannels.insert(new G4StatMFFragment);
// Perform class initialization
Initialize(theFragment);
}
// destructor
G4StatMFMicrocanonical::~G4StatMFMicrocanonical()
{
// garbage collection
theChannels.clearAndDestroy();
W2.clear();
W3.clear();
W4.clear();
G4int i;
for (i = 0; i < ANum2.entries(); i++) delete ANum2(i);
ANum2.clear();
for (i = 0; i < ANum3.entries(); i++) delete ANum3(i);
ANum3.clear();
for (i = 0; i < ANum4.entries(); i++) delete ANum4(i);
ANum4.clear();
}
// operators definitions
G4StatMFMicrocanonical &
G4StatMFMicrocanonical::operator=(const G4StatMFMicrocanonical & right)
{
G4Exception("G4StatMFMicrocanonical::operator= meant to not be accessable");
return *this;
}
G4bool G4StatMFMicrocanonical::operator==(const G4StatMFMicrocanonical & right) const
{
return false;
}
G4bool G4StatMFMicrocanonical::operator!=(const G4StatMFMicrocanonical & right) const
{
return true;
}
// Initialization method
void G4StatMFMicrocanonical::Initialize(const G4Fragment & theFragment)
{
G4int i;
// Excitation Energy (in MeV)
G4double U = theFragment.GetExcitationEnergy()/MeV;
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
for (i = 0; i < A; i++) {
// Calculate Inverse Density Levels for channels
// Epsilon0*(1 + 3 (Af - 1)) ???? --> Ask to Nikolai
// and correct in G4StatMFFragment
theChannels(i)->SetInvLevelDensity(i);
// Z/A ratios
theChannels(i)->SetZARatio(Z/A); // optimzation ?
// Degeneracy factors
theChannels(i)->SetDegeneracyFactor(1.0);
// Multiplicities
theChannels(i)->SetMultiplicity(0.0);
}
// Z/A ratios are for Af > 4
theChannels(1)->SetZARatio(0.5);
theChannels(2)->SetZARatio(0.5);
theChannels(3)->SetZARatio(0.5);
// Que pasa con theChannels(0).SetZARatio(0.5) ???? --> Ask to Nikolai
// Degeneracy factors are statistical factors
// DegeneracyFactor for nucleon is (2S_n + 1)(2I_n + 1) = 4
theChannels(0)->SetDegeneracyFactor(4.0); // nucleon
theChannels(1)->SetDegeneracyFactor(3.0); // .
theChannels(2)->SetDegeneracyFactor(4.0); // .
theChannels(3)->SetDegeneracyFactor(1.0); // alpha
// Configuration temperature
G4double TConfiguration = sqrt(U/(0.125*A));
// Free internal energy at Temperature T = 0
FreeInternalE0 = A*( -G4StatMFParameters::GetE0() + // Volume term (for T = 0)
G4StatMFParameters::GetGamma0()*(1.0-2.0*Z/A)*(1.0-2.0*Z/A) ) + // Symmetry term
G4StatMFParameters::GetBeta0()*pow(A,2.0/3.0) + // Surface term (for T = 0)
(3.0/5.0)*1.44*Z*Z/(G4StatMFParameters::Getr0()*pow(A,1.0/3.0)); // Coulomb term
// Statistical weights
W = 0.0;
WW2 = 0.0;
WW3 = 0.0;
WW4 = 0.0;
// Number of configurations for breakups with multiplicities 2, 3 and 4
M2 = 0;
M3 = 0;
M4 = 0;
// Mean breakup multiplicity
MeanMultiplicity = 0.0;
// Mean channel temperature
MeanTemperature = 0.0;
// Mean channel entropy
MeanEntropy = 0.0;
// Calculate entropy of compound nucleus
G4double SCompoundNucleus = CalcEntropyOfCompoundNucleus(theFragment,TConfiguration);
// I have to change this:
// -----------------------
// Statistical weight of compound nucleus
WCompoundNucleus = 1.0; // exp(SCompoundNucleus - SCompoundNucleus);
W += WCompoundNucleus;
MeanMultiplicity += 1.0 * WCompoundNucleus;
MeanTemperature += TConfiguration * WCompoundNucleus;
MeanEntropy += SCompoundNucleus * WCompoundNucleus;
theChannels(G4int(A) - 1)->SetMultiplicity(
theChannels(G4int(A) - 1)->GetMultiplicity()+
WCompoundNucleus);
// -----------------------
// Maximal fragment multiplicity allowed in direct simulation
G4int MaxMult = 4;
if (A > 110) MaxMult = 3;
// Keep fragment atomic numbers
G4int * FragmentAtomicNumbers = new G4int(G4int(A+0.5));
// We distribute A nucleons between m fragments mantaining the order
// FragmentAtomicNumbers[m-1]>FragmentAtomicNumbers[m-2]>...>FragmentAtomicNumbers[0]
// Our initial distribution is
// FragmentAtomicNumbers[m-1]=A, FragmentAtomicNumbers[m-2]=0, ..., FragmentAtomicNumbers[0]=0
for (G4int m = 2; m <= MaxMult; m++) {
FragmentAtomicNumbers[m-1] = A;
G4int M1 = m - 1;
for (i = 0; i < M1; i++) FragmentAtomicNumbers[i] = 0;
// We try to distribute A nucleons between m fragments
// DistributeNucleonsBetweenFragments return true if it is possible
// and false if not
while (DistributeNucleonsBetweenFragments(m,FragmentAtomicNumbers)) {
// For allowed distributions of nucleons
// we calculate the configuration probability
G4double ConfigurationProbability = CalcFragmentsConfigProbability(theFragment,m,
FragmentAtomicNumbers,
SCompoundNucleus);
// Es la suma de todas las probabilidades para cada configuracion
W += ConfigurationProbability;
for (G4int j = 0; j < m; j++) theChannels(j)->SetMultiplicity(theChannels(j)->GetMultiplicity()+
ConfigurationProbability);
MeanMultiplicity += m*ConfigurationProbability;
MeanTemperature += TConfiguration * ConfigurationProbability;
if (m == 2) {
WW2 += ConfigurationProbability;
M2 += 1;
W2.insert(ConfigurationProbability); // W2(M2-1)
// G4StatMF1DVector tmp(2);
// RWTValVector<G4int> tmp(2);
G4int * tmp = new G4int[2];
// tmp(0) = FragmentAtomicNumbers[m-1];
tmp[0] = FragmentAtomicNumbers[m-1];
// tmp(1) = FragmentAtomicNumbers[m-2];
tmp[1] = FragmentAtomicNumbers[m-2];
ANum2.insert(tmp);
} else if (m == 3) {
WW3 += ConfigurationProbability;
M3 += 1;
W3.insert(ConfigurationProbability); // W3(M3-1)
G4int * tmp = new G4int[3];
tmp[0] = FragmentAtomicNumbers[m-1];
tmp[1] = FragmentAtomicNumbers[m-2];
tmp[3] = FragmentAtomicNumbers[m-3];
ANum3.insert(tmp);
} else if (m == 4) {
WW4 += ConfigurationProbability;
M4 += 1;
if (M4 > 10000) continue;
W4.insert(ConfigurationProbability); // W4(M4-1)
G4int * tmp = new G4int[4];
tmp[0] = FragmentAtomicNumbers[m-1];
tmp[1] = FragmentAtomicNumbers[m-2];
tmp[2] = FragmentAtomicNumbers[m-3];
tmp[3] = FragmentAtomicNumbers[m-4];
ANum4.insert(tmp);
}
}
}
if (M4 > 10000) M4 = 10000;
// Normalization of statistical weights
for (i = 0; i < M2; i++) W2(i) = W2(i)/W;
for (i = 0; i < M3; i++) W3(i) = W3(i)/W;
for (i = 0; i < M4; i++) W4(i) = W4(i)/W;
WW2 /= W;
WW3 /= W;
WW4 /= W;
MeanMultiplicity /= W;
MeanTemperature /= W;
MeanEntropy /= W;
WCompoundNucleus /= W;
// garbage collection
delete [] FragmentAtomicNumbers;
}
G4double G4StatMFMicrocanonical::CalcFreeInternalEnergy(const G4Fragment & theFragment, const G4double & T)
{
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
G4double A13 = pow(A,1.0/3.0);
G4int Indx = G4int(A)-1;
G4double VolumeTerm = (-G4StatMFParameters::GetE0()+T*T/theChannels(Indx)->GetInvLevelDensity())*A;
G4double SymmetryTerm = G4StatMFParameters::GetGamma0()*(1.0-2.0*theChannels(Indx)->GetZARatio())*
(1.0-2.0*theChannels(Indx)->GetZARatio())*A;
G4double SurfaceTerm = (Beta(T)-T*DBetaDT(T))*A13*A13;
G4double CoulombTerm = (3.0/5.0)*1.44*Z*Z/(G4StatMFParameters::Getr0()*A13);
return VolumeTerm + SymmetryTerm + SurfaceTerm + CoulombTerm;
// return (-G4StatMFParameters::GetE0()+T*T/theChannels(Indx)->GetInvLevelDensity() + // volume
// G4StatMFParameters::GetGamma0()*(1.0-2.0*theChannels(Indx)->GetZARatio())*
// (1.0-2.0*theChannels(Indx)->GetZARatio())*A + // symmetry
// (Beta(T)-T*DBetaDT(T))*A13*A13 + // surface
// (3.0/5.0)*1.44*Z*Z/(G4StatMFParameters::Getr0()*A13)); // Coulomb
}
G4double G4StatMFMicrocanonical::CalcEntropyOfCompoundNucleus(const G4Fragment & theFragment,G4double & TConf)
// Calculates Temperature and Entropy of compound nucleus
{
const G4double A = theFragment.GetA();
const G4double Z = theFragment.GetZ();
const G4double U = theFragment.GetExcitationEnergy()/MeV;
const G4double A13 = pow(A,1.0/3.0);
G4double Ta = max(sqrt(U/(0.125*A)),0.0012);
G4double Tb = Ta;
G4double ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Ta);
G4double Da = (U+G4StatMFParameters::GetE0()-ECompoundNucleus)/U;
G4double Db = 0.0;
// bracketing the solution
if (Da == 0.0) {
TConf = Ta;
return 2*Ta*A/theChannels(G4int(A)-1)->GetInvLevelDensity() -
DBetaDT(Ta)*A13*A13;
} else if (Da < 0.0) {
do {
Tb -= 0.5*Tb;
ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tb);
Db = (U+G4StatMFParameters::GetE0()-ECompoundNucleus)/U;
} while (Db < 0.0);
} else {
do {
Tb += 0.5*Tb;
ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tb);
Db = (U+G4StatMFParameters::GetE0()-ECompoundNucleus)/U;
} while (Db > 0.0);
}
G4double eps = 1.0e-14 * abs(Tb-Ta);
for (G4int i = 0; i < 1000; i++) {
G4double Tc = (Ta+Tb)/2.0;
if (abs(Ta-Tb) <= eps) {
TConf = Tc;
return 2*Tc*A/theChannels(G4int(A)-1)->GetInvLevelDensity() -
DBetaDT(Tc)*A13*A13;
}
ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tc);
G4double Dc = (U+G4StatMFParameters::GetE0()-ECompoundNucleus)/U;
if (Dc == 0.0) {
TConf = Tc;
return 2*Tc*A/theChannels(G4int(A)-1)->GetInvLevelDensity() -
DBetaDT(Tc)*A13*A13;
}
if (Da*Dc < 0.0) {
Tb = Tc;
Db = Dc;
} else {
Ta = Tc;
Da = Dc;
}
}
// const G4double HT = 0.5;
// G4double H = 0.0;
// G4int counter = 0;
// do {
// G4int id = 0;
// G4double ECompoundNucleus = CalcFreeInternalEnergy(theFragment,T);
// G4double D = (U+G4StatMFParameters::GetE0()-ECompoundNucleus)/U;
// if (abs(D) < 0.003) {
// TConf = T;
// return 2*T*A/theChannels(G4int(A)-1)->GetInvLevelDensity() -
// DBetaDT(T)*A13*A13;
// }
// if (D <= 0.0) H = -HT;
// else H = HT;
// if (D < 0.0) {
// do {
// T += H/pow(2.0,id);
// if (T > 0.001) break;
// H = HT;
// } while (id++ < 30);
// } else {
// do {
// T += H/pow(2.0,id);
// if (T > 0.001) break;
// H = HT;
// } while (id++ < 30);
//
// if (id >= 30) {
// G4cerr << "G4StatMFMicrocanoncal::CalcEntropyOfCompoundNucleus: suspecting nucleus";
// return 0.0;
// }
// } while (counter++ <= 120);
// G4cerr << "G4StatMFMicrocanoncal::CalcEntropyOfCompoundNucleus: suspecting nucleus";
G4cerr << "G4StatMFMicrocanoncal::CalcEntropyOfCompoundNucleus: I can't calculate the temperature";
return 0.0;
}
G4bool G4StatMFMicrocanonical::DistributeNucleonsBetweenFragments(const G4int & k,
G4int * ANumbers)
// Distributes A nucleons between k fragments
// mantaining the order ANumbers[k-1] > ANumbers[k-2] > ... > ANumbers[0]
// If it is possible returns true. In other case returns false
{
G4int l = 1;
while (l < k) {
G4int tmp = ANumbers[l-1] + ANumbers[k-1];
ANumbers[l-1] += 1;
ANumbers[k-1] -= 1;
if (ANumbers[l-1] > ANumbers[l] || ANumbers[k-2] > ANumbers[k-1]) {
ANumbers[l-1] = 1;
ANumbers[k-1] = tmp - 1;
l++;
} else
return true;
}
return false;
}
G4double G4StatMFMicrocanonical::CalcFragmentsConfigProbability(const G4Fragment & theFragment,
const G4int & M,
const G4int * ANumbers,
const G4double & SCompound)
// Calculates the probability of a fragment configuration, where M is the multiplicity,
// ANumbers keeps the fragments atomic numbers and SCompound is the entropy of the
// compound nucleus
{
G4int i;
G4double A = theFragment.GetA();
G4double Z = theFragment.GetZ();
G4double U = theFragment.GetExcitationEnergy();
// Free volume avalible to the traslational motion of fragment
// Vf = \kappa*V0
// V0 is system volume
G4double V0 = (4.0/3.0)*pi*A*G4StatMFParameters::Getr0()*
G4StatMFParameters::Getr0()*G4StatMFParameters::Getr0();
G4double kappa = (1.0 + (1.44/(G4StatMFParameters::Getr0()*pow(A,1.0/3.0)))*
(pow(M,1.0/3.0) - 1.0));
kappa = kappa*kappa*kappa;
kappa -= 1.0;
G4double FreeVolume = kappa*V0;
// Factorial of fragment multiplicity
G4double Fact = 1.0;
for (i = 1; i < M; i++) {
G4double f = 1.0;
for (G4int ii = i+1; i<= M; i++) if (ANumbers[i-1] == ANumbers[ii-1]) f++;
Fact *= f;
}
// Calculate energies
G4double ProbDegeneracy = 1.0;
G4double ProbA32 = 1.0;
G4double EnergyConfiguration = 0.0;
G4double EnergyCoulomb = 0.0;
G4double pkp13 = 1.0/pow(1.0+G4StatMFParameters::GetKappaCoulomb(),1.0/3.0);
G4double cp = (3./5.)*1.44*(1. - pkp13)/G4StatMFParameters::Getr0();
G4double * ECOLA = new G4double[G4int(A+0.5)];
G4double * EA = new G4double[G4int(A+0.5)];
for (i = 0; i < M; i++) {
G4int intAf = ANumbers[i] - 1;
ProbDegeneracy *= theChannels(intAf)->GetDegeneracyFactor();
ProbA32 *= ANumbers[i]*sqrt(double(ANumbers[i]));
if (ANumbers[i] == 0 || ANumbers[i] == 1) {
ECOLA[intAf] = cp*theChannels(intAf)->GetZARatio()*theChannels(intAf)->GetZARatio();
EA[intAf] = ECOLA[intAf];
} else {
ECOLA[intAf] = cp*theChannels(intAf)->GetZARatio()*theChannels(intAf)->GetZARatio()*
pow(ANumbers[i],5.0/3.0);
if (ANumbers[i] == 2) EA[intAf] = -2.796*+ECOLA[intAf];
else if (ANumbers[i] == 3) EA[intAf] = -9.224*+ECOLA[intAf];
else if (ANumbers[i] == 4) EA[intAf] = -30.224*+ECOLA[intAf];
else EA[intAf] = (-G4StatMFParameters::GetE0() + G4StatMFParameters::GetGamma0()*
(1.0-2.0*theChannels(intAf)->GetZARatio())*
(1.0-2.0*theChannels(intAf)->GetZARatio()))*ANumbers[i] +
G4StatMFParameters::GetBeta0()*pow(ANumbers[i],2.0/3.0) +
ECOLA[intAf];
}
EnergyConfiguration += EA[intAf];
EnergyCoulomb += ECOLA[intAf];
}
EnergyConfiguration += (3.0/5.0)*1.44*Z*Z*pkp13/
(G4StatMFParameters::Getr0()*pow(A,1.0/3.0));
EnergyCoulomb += (3.0/5.0)*1.44*Z*Z*pkp13/
(G4StatMFParameters::Getr0()*pow(A,1.0/3.0));
for (i = 0; i < M; i++)
EnergyCoulomb += -(3.0/5.0)*1.44*theChannels(ANumbers[i]-1)->GetZARatio()*
theChannels(ANumbers[i]-1)->GetZARatio()*pow(ANumbers[i],5.0/3.0)/
G4StatMFParameters::Getr0();
if (U+FreeInternalE0-EnergyConfiguration < 0.003) return 0.0;
// Calculate temperature by iteration
G4double T = 0.0;
G4double Ta = max(sqrt(U/(A*0.125)),0.0012); // initial value
G4double Tb = Ta;
G4double EConfiguration = CalcEnergyConfiguration(A,Z,M,ECOLA,EA,ANumbers,Ta);
G4double Da = (U+G4StatMFParameters::GetE0()-EnergyConfiguration)/U;
G4double Db = 0.0;
// bracketing the solution
if (Da == 0.0) T = Ta;
else if (Da < 0.0) {
do {
Tb -= 0.5*Tb;
EConfiguration = CalcEnergyConfiguration(A,Z,M,ECOLA,EA,ANumbers,Tb);
Db = (U+G4StatMFParameters::GetE0()-EConfiguration)/U;
} while (Db < 0.0);
} else {
do {
Tb += 0.5*Tb;
EConfiguration = CalcEnergyConfiguration(A,Z,M,ECOLA,EA,ANumbers,Tb);
Db = (U+G4StatMFParameters::GetE0()-EConfiguration)/U;
} while (Db > 0.0);
}
G4double eps = 1.0e-14*abs(Ta-Tb);
for ( i = 0; i < 1000; i++) {
G4double Tc = (Ta+Tb)/2.0;
if (abs(Ta-Tb) <= eps) {
T = Tc;
break;
}
EConfiguration = CalcEnergyConfiguration(A,Z,M,ECOLA,EA,ANumbers,Tc);
G4double Dc = (U+G4StatMFParameters::GetE0()-EConfiguration)/U;
if (Dc == 0.0) {
T = Tc;
break;
}
if (Da*Dc < 0.0) {
Tb = Tc;
Db = Dc;
} else {
Ta = Tc;
Da = Dc;
}
}
if (i == 1000)
G4cerr << "G4StatMFMicrocanoncal::CalcFragmentsCongifProbability: I can't calculate the temperature";
// // Calculate temperature by iteration
// G4double T = max(sqrt(U/(A*0.125)),0.0012); // initial value
// G4double HT = 0.5;
// G4double H = 0.0;
// G4int id = 0;
// G4int counter = 0;
// do {
// EnergyConfiguration = 0.0;
// for (i = 0; i < M; i++) {
// G4int intAf = ANumbers[i] - 1;
// if (ANumbers[i] == 0 || ANumbers[i] == 1) {
// EA[intAf] = ECOLA[intAf];
// } else {
// if (ANumbers[i] == 2) EA[intAf] = -2.796*ECOLA[intAf];
// if (ANumbers[i] == 3) EA[intAf] = -9.224*ECOLA[intAf];
// if (ANumbers[i] == 4) EA[intAf] = -30.11*ECOLA[intAf];
// else EA[intAf] = (-G4StatMFParameters::GetE0() + T*T/theChannels(intAf)->GetInvLevelDensity() +
// G4StatMFParameters::GetGamma0()*
// (1.0-2.0*theChannels(intAf)->GetZARatio())*
// (1.0-2.0*theChannels(intAf)->GetZARatio()))*ANumbers[i] +
// (Beta(T)-T*DBetaDT(T))*pow(ANumbers[i],2.0/3.0) +
// ECOLA[intAf];
// }
// EnergyConfiguration += EA[intAf];
// }
// EnergyConfiguration += (3.0/5.0)*1.44*Z*Z*pkp13/(G4StatMFParameters::Getr0()*pow(A,1.0/3.0)) +
// 1.5*T*(M-1.0);
// G4double D = (U+G4StatMFParameters::GetE0()-EnergyConfiguration)/U;
// if (abs(D) < 0.003) break;
// if (D <= 0.0) H = -HT;
// else H = HT;
// if (D < 0.0) {
// do {
// T += H/pow(2.0,id);
// if (T > 0.001) break;
// H = HT;
// } while (id++ < 30);
// } else {
// do {
// T += H/pow(2.0,id);
// if (T > 0.001) break;
// H = HT;
// } while (id++ < 30);
// }
// if (id >= 30) {
// G4cerr << "G4StatMFMicrocanoncal::CalcFragmentsConfigProbability: suspecting nucleus";
// return 0.0;
// }
// } while (counter++ <= 120);
// Compute entropy
G4double SConfiguration = 0.0;
for (i = 0; i < M; i++) {
// interaction entropy for alpha
if (ANumbers[i] == 4) SConfiguration +=
2.0*T*ANumbers[i]/theChannels(ANumbers[i]-1)->GetInvLevelDensity();
// interaction entropy for Af > 4
else if (ANumbers[i] > 4) SConfiguration +=
2.0*T*ANumbers[i]/theChannels(ANumbers[i]-1)->GetInvLevelDensity() -
DBetaDT(T)*pow(ANumbers[i],2.0/3.0);
}
// Thermal Wave Lenght
G4double ThermalWaveLenght = 16.15/sqrt(15.0);
// Translational Entropy
G4double STranslational = max(log(ProbA32/Fact) +
(M-1.0)*log(FreeVolume/ThermalWaveLenght*ThermalWaveLenght*ThermalWaveLenght) +
1.5*(M-1.0) - log(A*sqrt(A)),0.0);
SConfiguration += log(ProbDegeneracy) + STranslational;
// Garbage collection
delete [] ECOLA;
delete [] EA;
// And finally compute probability of fragment configuration
return exp(SConfiguration-SCompound);
}
void G4StatMFMicrocanonical::ChooseAandZ(const G4Fragment & theFragment)
// Choice of fragment atomic numbers and charges
{
G4int FragmentMultiplicity = 0;
G4double RandNumber = G4UniformRand();
if (RandNumber < WCompoundNucleus) FragmentMultiplicity = 1;
else if (RandNumber < (WCompoundNucleus + WW2)) FragmentMultiplicity = 2;
else if (RandNumber < (WCompoundNucleus + WW2 + WW3)) FragmentMultiplicity = 3;
else FragmentMultiplicity = 4;
FragmentsA.clear();
FragmentsZ.clear();
G4int borrar = FragmentsA.entries();
borrar = FragmentsZ.entries();
if (FragmentMultiplicity == 1) {
FragmentsA.insert(theFragment.GetA());
FragmentsZ.insert(theFragment.GetZ());
return;
} else if (FragmentMultiplicity == 2) {
G4double Wp = WCompoundNucleus;
G4int j = 0;
for (G4int i = 0; i < M2; i++) {
Wp += W2(i);
if (Wp > RandNumber) break;
j++;
}
FragmentsA.insert(ANum2(j)[0]);
FragmentsA.insert(ANum2(j)[1]);
} else if (FragmentMultiplicity == 3) {
G4double Wp = WCompoundNucleus + WW2;
G4int j = 0;
for (G4int i = 0; i < M3; i++) {
Wp += W3(i);
if (Wp > RandNumber) break;
j++;
}
FragmentsA.insert(ANum3(j)[0]);
FragmentsA.insert(ANum3(j)[1]);
FragmentsA.insert(ANum3(j)[2]);
} else if (FragmentMultiplicity == 4) {
G4double Wp = WCompoundNucleus + WW2 + WW3;
G4int j = 0;
for (G4int i = 0; i < M4; i++) {
Wp += W4(i);
if (Wp > RandNumber) break;
j++;
}
FragmentsA.insert(ANum4(j)[0]);
FragmentsA.insert(ANum4(j)[1]);
FragmentsA.insert(ANum4(j)[2]);
FragmentsA.insert(ANum4(j)[3]);
} else {
G4Exception("G4StatMFMicrocanonical::ChooseAandZ: FragmentMultiplicity value not allowed");
}
for (G4int v = 0; v < FragmentMultiplicity; v++) FragmentsZ.insert(0);
borrar = FragmentsA.entries();
borrar = FragmentsZ.entries();
ChooseZ(theFragment,FragmentMultiplicity);
Multiplicity = FragmentMultiplicity;
return;
}
void G4StatMFMicrocanonical::ChooseZ(const G4Fragment & theFragment,
const G4int & FragmentMultiplicity)
// Gives fragments charges
{
G4int ZBalance = 0;
do {
G4double CC = G4StatMFParameters::GetGamma0()*0.8;
G4int SumZ = 0;
for (G4int i = 0; i < FragmentMultiplicity; i++) {
G4double ZMean = FragmentsA(i)*theFragment.GetZ()/theFragment.GetA();
if (FragmentsA(i) > 1.5 && FragmentsA(i) < 4.5) ZMean = 0.5*FragmentsA(i);
G4double ZDispersion = sqrt(FragmentsA(i)*MeanTemperature/CC);
G4int Zf;
do {
Zf = G4int(RandGauss::shoot(ZMean,ZDispersion)+0.5);
} while (Zf < 0 || Zf > FragmentsA(i));
FragmentsZ(i) = Zf;
SumZ += Zf;
}
ZBalance = theFragment.GetZ() - SumZ;
} while (abs(ZBalance) > 1.1);
FragmentsZ(0) += ZBalance;
return;
}
G4double G4StatMFMicrocanonical::CalcEnergyConfiguration(const G4double A, const G4double Z, const G4int M,
G4double * ECOLA, G4double * EA, const G4int * ANumbers,
const G4double T)
{
const G4double pkp13 = 1.0/pow(1.0+G4StatMFParameters::GetKappaCoulomb(),1.0/3.0);
G4double EnergyConfiguration = 0.0;
for (G4int i = 0; i < M; i++) {
G4int intAf = ANumbers[i] - 1;
if (ANumbers[i] == 0 || ANumbers[i] == 1) {
EA[intAf] = ECOLA[intAf];
} else {
if (ANumbers[i] == 2) EA[intAf] = -2.796*ECOLA[intAf];
if (ANumbers[i] == 3) EA[intAf] = -9.224*ECOLA[intAf];
if (ANumbers[i] == 4) EA[intAf] = -30.11*ECOLA[intAf];
else EA[intAf] = (-G4StatMFParameters::GetE0() + T*T/theChannels(intAf)->GetInvLevelDensity() +
G4StatMFParameters::GetGamma0()*
(1.0-2.0*theChannels(intAf)->GetZARatio())*
(1.0-2.0*theChannels(intAf)->GetZARatio()))*ANumbers[i] +
(Beta(T)-T*DBetaDT(T))*pow(ANumbers[i],2.0/3.0) +
ECOLA[intAf];
}
EnergyConfiguration += EA[intAf];
}
EnergyConfiguration += (3.0/5.0)*1.44*Z*Z*pkp13/(G4StatMFParameters::Getr0()*pow(A,1.0/3.0)) +
1.5*T*(M-1.0);
return EnergyConfiguration;
}
@@ -0,0 +1,24 @@
#include "G4StatMFParameters.hh"
const G4double G4StatMFParameters::Kappa = 1.0;
const G4double G4StatMFParameters::KappaCoulomb = 2.0;
const G4double G4StatMFParameters::Epsilon0 = 16.0; // MeV
// Bethe-Weizsacker coefficients
const G4double G4StatMFParameters::E0 = 16.0; // MeV
const G4double G4StatMFParameters::Beta0 = 18.0; // MeV
const G4double G4StatMFParameters::Gamma0 = 25.0; // MeV
// Critical temperature (for liquid-gas phase transitions)
const G4double G4StatMFParameters::CriticalTemp = 18.0; // MeV
// Nuclear radius
const G4double G4StatMFParameters::r0 = 1.17; // fm
G4StatMFParameters G4StatMFParameters::theStatMFParameters;
G4StatMFParameters * G4StatMFParameters::GetAddress()
{ return &theStatMFParameters; }
@@ -0,0 +1,146 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4UnstableFermiFragment.hh"
G4UnstableFermiFragment::G4UnstableFermiFragment()
{
}
G4UnstableFermiFragment::G4UnstableFermiFragment(const G4UnstableFermiFragment &right)
{
G4Exception("G4UnstableFermiFragment::copy_constructor meant to not be accessable");
}
G4UnstableFermiFragment::~G4UnstableFermiFragment()
{
}
const G4UnstableFermiFragment & G4UnstableFermiFragment::operator=(const G4UnstableFermiFragment &right)
{
G4Exception("G4UnstableFermiFragment::operator= meant to not be accessable");
return *this;
}
G4bool G4UnstableFermiFragment::operator==(const G4UnstableFermiFragment &right) const
{
return false;
}
G4bool G4UnstableFermiFragment::operator!=(const G4UnstableFermiFragment &right) const
{
return true;
}
RWTPtrOrderedVector<G4LorentzVector> *
G4UnstableFermiFragment::FragmentsMomentum(G4double KinE, const G4int K, const G4double * Masses)
// Calculates momentum for K fragments (Kopylov's method of sampling is used)
// KinetEnergy is the available kinetic energy
{
RWTPtrOrderedVector<G4LorentzVector>* MomentumList =
new RWTPtrOrderedVector<G4LorentzVector>(K);
G4double AvalaibleMass = 0;
for (G4int i=0; i<K; i++) AvalaibleMass += Masses[i];
G4double PFragMagCM = 0.0;
G4double Mass = AvalaibleMass+KinE;
G4LorentzVector PFragCM(0.0,0.0,0.0,0.0);
G4LorentzVector PFragLab(0.0,0.0,0.0,0.0);
G4LorentzVector PRestCM(0.0,0.0,0.0,0.0);
G4LorentzVector PRestLab(0.0,0.0,0.0,Mass);
for (G4int l = 0; l < K-1; l++) {
G4int LK = K - l;
G4double FragMass = Masses[LK-1];
AvalaibleMass -= FragMass;
if (LK > 2) KinE *= RNKSI(LK-1);
else KinE = 0.0;
G4double RestMass = AvalaibleMass + KinE;
PFragMagCM = sqrt(
abs((Mass*Mass - (FragMass + RestMass)*(FragMass + RestMass))*
(Mass*Mass - (FragMass - RestMass)*(FragMass - RestMass)))
)/(2.0*Mass);
// Create a unit vector with a random direction isotropically distributed
G4ParticleMomentum RandVector(IsotropicVector(PFragMagCM));
PFragCM.setVect(RandVector);
PFragCM.setE(sqrt(RandVector.mag2()+FragMass*FragMass));
PRestCM.setVect(-RandVector);
PRestCM.setE(sqrt(RandVector.mag2()+RestMass*RestMass));
G4ThreeVector BoostV = PRestLab.boostVector();
PFragLab = PFragCM;
PFragLab.boost(BoostV);
PRestLab = PRestCM;
PRestLab.boost(BoostV);
MomentumList->prepend(new G4LorentzVector(PFragLab));
Mass = RestMass;
}
MomentumList->prepend(new G4LorentzVector(PRestLab));
return MomentumList;
}
G4double G4UnstableFermiFragment::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 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 G4UnstableFermiFragment::IsotropicVector(const G4double Magnitude)
// Samples a isotropic random vectorwith a magnitud given by Magnitude.
// By default Magnitude = 1.0
{
G4double CosTheta = 1.0 - 2.0*G4UniformRand();
G4double SinTheta = sqrt(1.0 - CosTheta*CosTheta);
G4double Phi = twopi*G4UniformRand();
G4ParticleMomentum Vector(Magnitude*cos(Phi)*SinTheta,
Magnitude*sin(Phi)*SinTheta,
Magnitude*CosTheta);
return Vector;
}
@@ -0,0 +1,44 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
//
#include "G4VEmissionProbability.hh"
G4VEmissionProbability::G4VEmissionProbability(const G4VEmissionProbability &right)
{
G4Exception("G4VEmissionProbability::copy_constructor meant to not be accessable");
}
const G4VEmissionProbability & G4VEmissionProbability::operator=(const G4VEmissionProbability &right)
{
G4Exception("G4VEmissionProbability::operator= meant to not be accessable");
return *this;
}
G4bool G4VEmissionProbability::operator==(const G4VEmissionProbability &right) const
{
return false;
}
G4bool G4VEmissionProbability::operator!=(const G4VEmissionProbability &right) const
{
return true;
}
@@ -0,0 +1,44 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998) writen from G4Evaporation.cc (May 1998)
//
#include "G4VEvaporation.hh"
G4VEvaporation::G4VEvaporation(const G4VEvaporation &right)
{
G4Exception("G4VEvaporation::copy_constructor meant to not be accessable");
}
const G4VEvaporation & G4VEvaporation::operator=(const G4VEvaporation &right)
{
G4Exception("G4VEvaporation::operator= meant to not be accessable");
return *this;
}
G4bool G4VEvaporation::operator==(const G4VEvaporation &right) const
{
return false;
}
G4bool G4VEvaporation::operator!=(const G4VEvaporation &right) const
{
return true;
}
@@ -0,0 +1,41 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
//
#include "G4VEvaporationChannel.hh"
G4VEvaporationChannel::G4VEvaporationChannel(const G4VEvaporationChannel &right)
{
G4Exception("G4VEvaporationChannel::copy_constructor meant to not be accessable");
}
const G4VEvaporationChannel & G4VEvaporationChannel::operator=(const G4VEvaporationChannel &right)
{
G4Exception("G4VEvaporationChannel::operator= meant to not be accessable");
return *this;
}
G4bool G4VEvaporationChannel::operator==(const G4VEvaporationChannel &right) const
{
return (this == (G4VEvaporationChannel *) &right);
// return false;
}
G4bool G4VEvaporationChannel::operator!=(const G4VEvaporationChannel &right) const
{
return (this != (G4VEvaporationChannel *) &right);
// return true;
}
@@ -0,0 +1,47 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4VFermiBreakUp.hh"
G4VFermiBreakUp::G4VFermiBreakUp()
{
}
G4VFermiBreakUp::G4VFermiBreakUp(const G4VFermiBreakUp &right)
{
G4Exception("G4VFermiBreakUp::copy_constructor meant to not be accessable");
}
G4VFermiBreakUp::~G4VFermiBreakUp()
{
}
const G4VFermiBreakUp & G4VFermiBreakUp::operator=(const G4VFermiBreakUp &right)
{
G4Exception("G4VFermiBreakUp::operator= meant to not be accessable");
return *this;
}
G4bool G4VFermiBreakUp::operator==(const G4VFermiBreakUp &right) const
{
return false;
}
G4bool G4VFermiBreakUp::operator!=(const G4VFermiBreakUp &right) const
{
return true;
}
@@ -0,0 +1,38 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Nov 1998)
#include "G4VFermiFragment.hh"
G4VFermiFragment::G4VFermiFragment(const G4VFermiFragment &right)
{
G4Exception("G4VFermiFragment::copy_constructor meant to not be accessable");
}
const G4VFermiFragment & G4VFermiFragment::operator=(const G4VFermiFragment &right)
{
G4Exception("G4VFermiFragment::operator= meant to not be accessable");
return *this;
}
G4bool G4VFermiFragment::operator==(const G4VFermiFragment &right) const
{
return false;
}
G4bool G4VFermiFragment::operator!=(const G4VFermiFragment &right) const
{
return true;
}
@@ -0,0 +1,38 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// 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 $
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
#include "G4VFissionBarrier.hh"
G4VFissionBarrier::G4VFissionBarrier(const G4VFissionBarrier & right)
{
G4Exception("G4VFissionBarrier::copy_constructor meant to not be accessable.");
}
const G4VFissionBarrier & G4VFissionBarrier::operator=(const G4VFissionBarrier & right)
{
G4Exception("G4VFissionBarrier::operator= meant to not be accessable.");
return *this;
}
G4bool G4VFissionBarrier::operator==(const G4VFissionBarrier & right) const
{
return false;
}
G4bool G4VFissionBarrier::operator!=(const G4VFissionBarrier & right) const
{
return true;
}
@@ -0,0 +1,214 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4VGammaDeexcitation
//
// Author: Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 23 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
#include "G4VGammaDeexcitation.hh"
#include "globals.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
#include "G4LorentzVector.hh"
#include "G4VGammaTransition.hh"
#include "G4Fragment.hh"
#include "G4FragmentVector.hh"
G4VGammaDeexcitation::G4VGammaDeexcitation(): _verbose(0), _transition(0)
{ }
G4VGammaDeexcitation::~G4VGammaDeexcitation()
{
// if (_transition != 0) delete _transition;
}
G4FragmentVector* G4VGammaDeexcitation::DoTransition()
{
// Template method
Initialize();
G4FragmentVector* products = new G4FragmentVector;
if (CanDoTransition())
{
G4Fragment* gamma = GenerateGamma();
if (gamma != 0)
{
products->append(gamma);
UpdateNucleus(gamma);
Update(gamma);
}
}
if (_verbose > 1)
G4cout << "G4VGammaDeexcitation::DoTransition - Transition deleted " << endl;
if (_transition != 0) delete _transition;
return products;
}
G4FragmentVector* G4VGammaDeexcitation::DoChain()
{
Initialize();
G4FragmentVector* products = new G4FragmentVector;
while (CanDoTransition())
{
if (_verbose > 5) G4cout << "G4VGammaDeexcitation::DoChain - Looping" << endl;
G4Fragment* gamma = GenerateGamma();
if (gamma != 0)
{
products->append(gamma);
UpdateNucleus(gamma);
}
Update(gamma);
}
if (_verbose > 1)
G4cout << "G4VGammaDeexcitation::DoChain - Transition deleted, end of chain " << endl;
if (_transition != 0) delete _transition;
return products;
}
const G4Fragment& G4VGammaDeexcitation::GetNucleus() const
{
return _nucleus;
}
void G4VGammaDeexcitation::SetNucleus(const G4Fragment& nucleus)
{
_nucleus = G4Fragment(nucleus);
}
G4Fragment* G4VGammaDeexcitation::GenerateGamma()
{
G4double eGamma = 0.;
if (_transition != 0) eGamma = _transition->GammaEnergy();
if (_verbose > 1 && _transition != 0)
{
G4cout << "G4VGammaDeexcitation::GenerateGamma - Gamma energy " << eGamma
<< " ** New excitation " << _transition->GetEnergyTo() << endl;
}
// Photon momentum isotropically generated
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());
if (_verbose > 1)
G4cout << "G4VGammaDeexcitation::GenerateGamma - Gamma fragment generated " << endl;
return gammaFragment;
}
else
{
return 0;
}
}
void G4VGammaDeexcitation::UpdateNucleus(const G4Fragment* gamma)
{
G4LorentzVector p4Gamma = gamma->GetMomentum();
G4ThreeVector pGamma(p4Gamma);
G4double eGamma = gamma->GetMomentum().e();
G4LorentzVector p4Nucleus(_nucleus.GetMomentum() );
// p4Nucleus.boost(-_nucleus.GetMomentum().boostVector() );
G4LorentzVector p4Residual(p4Nucleus - pGamma, p4Nucleus.e() - eGamma);
// G4LorentzVector p4Residual(-pGamma, p4Nucleus.e() - eGamma);
// p4Residual.boost( _nucleus.GetMomentum().boostVector() );
// Update excited nucleus parameters
_nucleus.SetMomentum(p4Residual);
if (_transition != 0)
{
G4double excitation =_transition->GetEnergyTo();
if (excitation < 0.) excitation = 0.0;
_nucleus.SetExcitationEnergy(excitation);
}
return;
}
void G4VGammaDeexcitation::Update(const G4Fragment* gamma)
{
if (_transition != 0)
{
delete _transition;
_transition = 0;
if (_verbose > 1)
G4cout << "G4VGammaDeexcitation::Update - Transition deleted " << endl;
}
_transition = CreateTransition();
if (_transition != 0)
{
_transition->SetEnergyFrom(_nucleus.GetExcitationEnergy());
}
return;
}
void G4VGammaDeexcitation::Initialize()
{
_transition = CreateTransition();
if (_transition != 0) _transition->SetEnergyFrom(_nucleus.GetExcitationEnergy());
return;
}
void G4VGammaDeexcitation::SetVerboseLevel(G4int verbose)
{
_verbose = verbose;
return;
}
@@ -0,0 +1,48 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
//
#include "G4VLevelDensityParameter.hh"
G4VLevelDensityParameter::
G4VLevelDensityParameter(const G4VLevelDensityParameter &right)
{
G4Exception("G4VLevelDensityParameter::copy_constructor meant to not be accessable");
}
const G4VLevelDensityParameter & G4VLevelDensityParameter::
operator=(const G4VLevelDensityParameter &right)
{
G4Exception("G4VLevelDensityParameter::operator= meant to not be accessable");
return *this;
}
G4bool G4VLevelDensityParameter::
operator==(const G4VLevelDensityParameter &right) const
{
return false;
}
G4bool G4VLevelDensityParameter::
operator!=(const G4VLevelDensityParameter &right) const
{
return true;
}
@@ -0,0 +1,39 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// CERN, Geneva, Switzerland
//
// File name: G4VPhotonEvaporation
//
// Author: Maria Grazia Pia (pia@genova.infn.it)
//
// Creation date: 28 October 1998
//
// Modifications:
//
// -------------------------------------------------------------------
#include "G4VPhotonEvaporation.hh"
G4bool G4VPhotonEvaporation::operator==(const G4VPhotonEvaporation &right) const
{
return (this == (G4VPhotonEvaporation*) &right);
}
G4bool G4VPhotonEvaporation::operator!=(const G4VPhotonEvaporation &right) const
{
return (this != (G4VPhotonEvaporation*) &right);
}
@@ -0,0 +1,76 @@
#include "G4VStatMFCanonical.hh"
G4VStatMFCanonical & G4VStatMFCanonical::operator=(const G4VStatMFCanonical & right)
{
G4Exception("G4VStatMFCanonical::operator= meant to not be accessable");
return *this;
}
G4bool G4VStatMFCanonical::operator==(const G4VStatMFCanonical & right)
{
return false;
}
G4bool G4VStatMFCanonical::operator!=(const G4VStatMFCanonical & right)
{
return true;
}
G4double G4VStatMFCanonical::Beta(const G4double & T) const
{
if (T > G4StatMFParameters::GetCriticalTemp()) return 0.0;
else {
G4double CriticalTempSqr = G4StatMFParameters::GetCriticalTemp()*
G4StatMFParameters::GetCriticalTemp();
G4double TempSqr = T*T;
G4double tmp = (CriticalTempSqr-TempSqr)/(CriticalTempSqr+TempSqr);
return G4StatMFParameters::GetBeta0()*tmp*pow(tmp,1.0/4.0);
}
}
G4double G4VStatMFCanonical::DBetaDT(const G4double & T) const
{
if (T > G4StatMFParameters::GetCriticalTemp()) return 0.0;
else {
G4double CriticalTempSqr = G4StatMFParameters::GetCriticalTemp()*
G4StatMFParameters::GetCriticalTemp();
G4double TempSqr = T*T;
G4double tmp = (CriticalTempSqr-TempSqr)/(CriticalTempSqr+TempSqr);
return -0.5*G4StatMFParameters::GetBeta0()*pow(tmp,1.0/4.0)*
(CriticalTempSqr*T)/((CriticalTempSqr+TempSqr)*(CriticalTempSqr+TempSqr));
}
}
void G4VStatMFCanonical::SortFragments(void)
{
NumOfCharged = 0;
G4int i;
for (i = 0; i < Multiplicity; i++) {
if (FragmentsZ(i) > 0 ) {
OrderedA.insert(FragmentsA(i));
OrderedZ.insert(FragmentsZ(i));
NumOfCharged++;
}
}
NumOfNeutrons = 0;
for ( i = 0; i < Multiplicity; i++) {
if (FragmentsZ(i) <= 0 ) {
OrderedA.insert(FragmentsA(i));
OrderedZ.insert(0);
NumOfNeutrons++;
}
}
if (NumOfCharged <= 1) NumOfCharged = Multiplicity;
}