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,366 @@
// 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: G4PreCompoundModel.cc,v 1.13 1998/12/14 21:46:55 larazb Exp $
// GEANT4 tag $Name: geant4-00 $
//
// by V. Lara
#include "G4PreCompoundModel.hh"
G4PreCompoundModel::G4PreCompoundModel(G4ExcitationHandler * const value):
G4VPreCompoundModel(value)
{
// neutron
theChannels.insert(new G4PreCompoundNeutron());
// proton
theChannels.insert(new G4PreCompoundProton());
// deuterium
theChannels.insert(new G4PreCompoundDeuteron());
// triton
theChannels.insert(new G4PreCompoundTriton());
// helium3
theChannels.insert(new G4PreCompoundHe3());
// alpha
theChannels.insert(new G4PreCompoundAlpha());
}
G4PreCompoundModel::~G4PreCompoundModel()
{
theChannels.clearAndDestroy();
}
const G4PreCompoundModel & G4PreCompoundModel::operator=(const G4PreCompoundModel &right)
{
G4Exception("G4PreCompoundModel::operator= meant to not be accessable");
return *this;
}
G4bool G4PreCompoundModel::operator==(const G4PreCompoundModel &right) const
{
return false;
}
G4bool G4PreCompoundModel::operator!=(const G4PreCompoundModel &right) const
{
return true;
}
// Additional Declarations
G4VParticleChange * G4PreCompoundModel::ApplyYourself(const G4Track & thePrimary,
G4Nucleus & theNucleus)
{
theResult.Initialize(thePrimary);
// prepare fragment
G4Fragment anInitialState;
G4int anA=theNucleus.GetN();
anA += thePrimary.GetDynamicParticle()->GetDefinition()->GetBaryonNumber();
anInitialState.SetA(anA);
G4int aZ=theNucleus.GetZ();
aZ += thePrimary.GetDynamicParticle()->GetDefinition()->GetPDGCharge();
anInitialState.SetZ(aZ);
// Nucleus mass
// G4double nucleusMass =
// (theNucleus.GetN()-theNucleus.GetZ())*G4Neutron::Neutron()->GetPDGMass()
// + theNucleus.GetZ()*G4Proton::Proton()->GetPDGMass()
// - G4NucleiPropertiesTable::GetBindingEnergy(theNucleus.GetN() , theNucleus.GetZ());
G4double nucleusMass = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(theNucleus.GetZ()
,theNucleus.GetN());
// Excitation Energy
G4double anEnergy = 0;
anEnergy = nucleusMass + thePrimary.GetTotalEnergy();
// anEnergy += -aZ*G4Proton::Proton()->GetPDGMass()
// - (anA-aZ)*G4Neutron::Neutron()->GetPDGMass()
// -G4NucleiPropertiesTable::GetBindingEnergy(anA,aZ);
anEnergy -= G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(aZ,anA);
anInitialState.SetExcitationEnergy(anEnergy);
// Number of Excitons
anInitialState.SetNumberOfExcitons(thePrimary.GetDynamicParticle()->GetDefinition()->GetBaryonNumber());
// Number of Charged
anInitialState.SetNumberOfCharged(thePrimary.GetDynamicParticle()->GetDefinition()->GetPDGCharge());
// Number of Holes
anInitialState.SetNumberOfHoles(0);
// Momentum
G4ThreeVector p = thePrimary.GetDynamicParticle()->Get4Momentum().vect();
G4LorentzVector momentum(p, sqrt(p.mag2()+(anEnergy+nucleusMass) * (anEnergy+nucleusMass)) );
anInitialState.SetMomentum(momentum);
// call excitation handler
const G4Fragment aFragment(anInitialState);
G4DynamicParticleVector * result = DeExcite(aFragment);
// fill particle change
theResult.SetStatusChange(fStopAndKill);
theResult.SetNumberOfSecondaries(result->length());
for(G4int i=0; i<result->length(); i++)
{
theResult.AddSecondary(result->at(i));
}
delete result;
//return the filled particle change
return &theResult;
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
G4DynamicParticleVector* G4PreCompoundModel::DeExcite(const G4Fragment & theInitialState) const
{
G4DynamicParticleVector * Result = new G4DynamicParticleVector;
// result = GetExcitationHandler()->BreakItUp(aFragment);
G4Fragment aFragment(theInitialState);
// Main loop. It is performed until equilibrium deexcitation.
for (;;) {
// Compute atomic numbers and charges for rest nuclei
for (G4int i = 0; i < NumberOfPossibleFragments; i++) {
theChannels(i)->Init(aFragment);
}
// Equilibrium exciton number
G4double EquilibriumExcitonNumber = sqrt(1.19*G4PreCompoundParameters::GetAddress()->GetLevelDensity()*
aFragment.GetA()*aFragment.GetExcitationEnergy()/MeV+0.5);
// Loop for transitions, it is performed while there are preequilibrium transitions.
G4bool ThereIsTransition = false;
do {
if (aFragment.GetNumberOfExcitons() < EquilibriumExcitonNumber) {
if (aFragment.GetNumberOfParticles() < 1) {
aFragment.SetNumberOfHoles(aFragment.GetNumberOfHoles()+1);
aFragment.SetNumberOfExcitons(aFragment.GetNumberOfExcitons()+2);
}
G4double TotalEmissionProbability = 0.0;
G4int i;
for (i = 0; i < NumberOfPossibleFragments; i++) {
theChannels(i)->CalcExcitonLevelDensityRatios(
aFragment.GetNumberOfParticles()+aFragment.GetNumberOfHoles(),
aFragment.GetNumberOfParticles());
theChannels(i)->CalcCondensationProbability(aFragment.GetA());
// Calculate emission probailities
if (aFragment.GetNumberOfParticles() <= theChannels(i)->GetA()-0.01)
// if number of particles less than a fragment atomic number
// set probability to emit a fragment 0
theChannels(i)->SetEmissionProbability(0.0);
else if (aFragment.GetNumberOfExcitons() <= theChannels(i)->GetA()+0.01 &&
aFragment.GetNumberOfExcitons() != 1)
theChannels(i)->SetEmissionProbability(0.0);
else if (aFragment.GetNumberOfCharged() <= theChannels(i)->GetZ()-0.01)
// if number of charged particles (protons) is less than charge of fragment
// set probability to emit a fragment 0
theChannels(i)->SetEmissionProbability(0.0);
else if (theChannels(i)->GetMaximalKineticEnergy() <= 0.0)
// if the energy threshold for emitted fragment is less or equal 0
// set probability to emit a fragment 0
theChannels(i)->SetEmissionProbability(0.0);
else
// Compute total (integrated over kinetic energy) emission
// probability of a fragment and
// Summing channel emission probabilities
TotalEmissionProbability += theChannels(i)->CalcEmissionProbability(aFragment);
}
// Check if number of excitons is greater than 0
// else perform equilibrium emission
if (aFragment.GetNumberOfExcitons() <= 0) {
// Perform Equilibrium Emission
PerformEquilibriumEmission(aFragment,Result);
return Result;
}
G4PreCompoundTransitions aTransition(aFragment);
// Sum of transition probabilities
G4double TotalTransitionProbability = aTransition.GetTotalProbability();
// Sum of all probabilities
G4double TotalProbability = TotalEmissionProbability + TotalTransitionProbability;
// Select subprocess
if (G4UniformRand() > TotalEmissionProbability/TotalProbability) {
// It will be transition to state with a new number of excitons
ThereIsTransition = true;
G4int deltaN = aTransition.GetDeltaNExciton();
aFragment.SetNumberOfExcitons(aFragment.GetNumberOfExcitons()+deltaN);
aFragment.SetNumberOfHoles(aFragment.GetNumberOfHoles()+deltaN/2);
// With weight Z/A, number of charged particles is decreased on +1
if ((deltaN > 0 || aFragment.GetNumberOfCharged() > 0) &&
(G4UniformRand() <= aFragment.GetZ()/aFragment.GetA()))
aFragment.SetNumberOfCharged(aFragment.GetNumberOfCharged()+deltaN/2);
} else {
// It will be fragment emission
ThereIsTransition = false;
G4double * running = new G4double[NumberOfPossibleFragments];
running[0] = theChannels(0)->GetEmissionProbability();
for (i = 1; i < NumberOfPossibleFragments; i++)
running[i]=running[i-1]+theChannels(i)->GetEmissionProbability();
// Choose an emission channel
G4double ChoosedChannel = G4UniformRand()*TotalEmissionProbability;
G4int aChannel = -1;
for (i = 0; i < NumberOfPossibleFragments; i++) {
if (ChoosedChannel <= running[i]) {
aChannel = i;
break;
}
}
delete [] running;
// Compute Kinetic Energy of emitted fragment
G4double KineticEnergyOfEmittedFragment =
theChannels(aChannel)->GetKineticEnergy(aFragment);
// G4cout << "Kinetic energy of Emitted fragment " << KineticEnergyOfEmittedFragment << endl;
// Update nucleus parameters
// Number of excitons
aFragment.SetNumberOfExcitons(aFragment.GetNumberOfExcitons()-
G4int(theChannels(aChannel)->GetA()));
// Number of charges
aFragment.SetNumberOfCharged(aFragment.GetNumberOfCharged()-
G4int(theChannels(aChannel)->GetZ()));
// Excitation energy
// check that Excitation energy is > 0
G4double CheckU = theChannels(aChannel)->GetMaximalKineticEnergy() -
KineticEnergyOfEmittedFragment +
theChannels(aChannel)->GetCoulombBarrier();
if (CheckU < 0.0)
G4Exception("G4PreCompoundModel::DeExcite: Excitation energy less than 0! ");
aFragment.SetExcitationEnergy(CheckU);
// Atomic number
aFragment.SetA(theChannels(aChannel)->GetRestA());
// Charge
aFragment.SetZ(theChannels(aChannel)->GetRestZ());
// Emited fragment Velocity
// G4double EmittedFragmentVel = sqrt((2.0*KineticEnergyOfEmittedFragment)/
// ( (theChannels(aChannel)->GetNuclearMass()*
// theChannels(aChannel)->GetRestA())/
// (theChannels(aChannel)->GetRestA()+
// theChannels(aChannel)->GetA()))
// );
//G4ParticleMomentum momentum =
// IsotropicRandom3Vetor(EmittedFragmentVel*
// theChannels(aChannel)->GetNuclearMass()/
// (1.0+theChannels(aChannel)->GetA()/
// theChannels(aChannel)->GetRestA()));
G4double p = sqrt(KineticEnergyOfEmittedFragment*(KineticEnergyOfEmittedFragment+
2.0*theChannels(aChannel)->GetNuclearMass()));
G4ParticleMomentum momentum = IsotropicRandom3Vetor(p);
G4LorentzVector EmittedMomentum(momentum,
sqrt(momentum.mag2()+
theChannels(aChannel)->GetNuclearMass() *
theChannels(aChannel)->GetNuclearMass() )
);
G4LorentzVector RestMomentum(-momentum,
sqrt(momentum.mag2()+
(theChannels(aChannel)->GetRestNuclearMass()+
aFragment.GetExcitationEnergy()) *
(theChannels(aChannel)->GetRestNuclearMass()+
aFragment.GetExcitationEnergy()
))
);
// Perform Lorentz boosts
EmittedMomentum.boost(aFragment.GetMomentum().boostVector());
RestMomentum.boost(aFragment.GetMomentum().boostVector());
// Update nucleus momentum
aFragment.SetMomentum(RestMomentum);
// Set emitted fragment momentum
theChannels(aChannel)->SetMomentum(EmittedMomentum);
// Add emitted fragment to Result
G4DynamicParticle * MyDP = new G4DynamicParticle(theChannels(aChannel)->GetDynamicParticle());
Result->insert(MyDP);
}
} else {
// Perform Equilibrium Emission
PerformEquilibriumEmission(aFragment,Result);
return Result;
}
} while (ThereIsTransition); // end of do loop
} // end of for (;;) loop
}
G4ThreeVector G4PreCompoundModel::IsotropicRandom3Vetor(G4double Magnitude) const
// Create a unit vector with a random direction isotropically distributed
{
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;
}
void G4PreCompoundModel::PerformEquilibriumEmission(const G4Fragment & aFragment,
G4DynamicParticleVector * Result) const
{
for (G4int j = 0; j < Result->entries(); j++)
G4LorentzVector mom(Result->at(j)->Get4Momentum());
G4DynamicParticleVector * theEquilibriumResult;
theEquilibriumResult = GetExcitationHandler()->BreakItUp(aFragment);
while (theEquilibriumResult->entries() > 0)
Result->insert(theEquilibriumResult->removeFirst());
delete theEquilibriumResult;
return;
}
@@ -0,0 +1,62 @@
// 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.
//
//
// by V. Lara
// Corrections by V. Krylov
#include "G4PreCompoundNeutron.hh"
G4double G4PreCompoundNeutron::ProbabilityDistributionFunction(const G4double & eKin,
const G4Fragment & aFragment)
{
const G4double r0 = 1.5; // fm
const G4double SingleParticleLevelDensity =
0.595*G4PreCompoundParameters::GetAddress()->GetLevelDensity();
G4double R0J=0.76+2.2/pow(GetRestA(),1.0/3.0);;
G4double BN = (2.12/pow(GetRestA(),2.0/3.0)-0.05)/R0J;
G4double C1 = eKin + BN;
return 0.000234*r0*r0*pow(GetRestA(),2.0/3.0)*R0J*
GetExcitonLevelDensityRatio()/
(SingleParticleLevelDensity*(aFragment.GetExcitationEnergy()/MeV)*GetRestA())*
pow((1.0 - (eKin+GetBindingEnergy())/(aFragment.GetExcitationEnergy()/MeV)),
(aFragment.GetNumberOfExcitons()-2.0))*C1;
// Corrected some mistakes in return statement by V. Krylov:
// - First GetRestA() was GetA()
// - The C1 factor was inside of precedent pow( )
}
G4double G4PreCompoundNeutron::GetKineticEnergy(const G4Fragment & aFragment)
{
G4double DJ = (2.12/pow(GetRestA(),2.0/3.0)-0.05)/
(0.76+2.2/pow(GetRestA(),1.0/3.0));
G4double T = aFragment.GetNumberOfParticles() + aFragment.GetNumberOfHoles() - GetA() - 1.0;
G4double R2 = GetMaximalKineticEnergy();
G4double R1 = R2 + GetCoulombBarrier();
if (T <= -0.1) return R1;
else if (T <= 0.1) return -DJ + sqrt(DJ*DJ + (G4UniformRand()*(R2*R2 + 2.0*DJ*R2)));
else {
G4double E1 = (R1 - DJ*T)/(T + 1.0);
G4double E = 0.0;
G4double T3 = 0.0;
do {
E = GetCoulombBarrier()+G4UniformRand()*R2;
G4double T1 = (E + DJ)/(E1 + DJ);
G4double T2 = (R1 - E)/(R1 - E1);
T3 = T1*pow(T2,T);
} while (G4UniformRand() > T3);
return E;
}
}
@@ -0,0 +1,21 @@
// 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.
//
//
// by V. Lara
#include "G4PreCompoundParameters.hh"
const G4double theLevelDensity = 0.125;
G4PreCompoundParameters G4PreCompoundParameters::thePreCompoundParameters;
//G4PreCompoundParameters G4PreCompoundParameters::thePreCompoundParameters(1);
G4PreCompoundParameters * G4PreCompoundParameters::GetAddress()
{ return &thePreCompoundParameters; }
@@ -0,0 +1,62 @@
// 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.
//
//
// by V. Lara
// Correction by V. Krylov
#include "G4PreCompoundProton.hh"
G4double G4PreCompoundProton::ProbabilityDistributionFunction(const G4double & eKin,
const G4Fragment & aFragment)
{
const G4double r0 = 1.5; // fm
const G4double SingleParticleLevelDensity =
0.595*G4PreCompoundParameters::GetAddress()->GetLevelDensity(); // AC
G4double R0J=1.2;
G4double C1 = eKin - GetCoulombBarrier();
return 0.000234*r0*r0*pow(GetRestA(),2.0/3.0)*R0J*
GetExcitonLevelDensityRatio()/
(SingleParticleLevelDensity*(aFragment.GetExcitationEnergy()/MeV)*GetRestA())*
pow((1.0 - (eKin+GetBindingEnergy())/(aFragment.GetExcitationEnergy()/MeV)),
(aFragment.GetNumberOfExcitons()-2.0))*C1;
// Corrected some mistakes in return statement by V. Krylov:
// - First GetRestA() was GetA()
// - The C1 factor was inside of precedent pow( )
}
G4double G4PreCompoundProton::GetKineticEnergy(const G4Fragment & aFragment)
{
G4double DJ = - GetCoulombBarrier();
G4double T = aFragment.GetNumberOfParticles() + aFragment.GetNumberOfHoles() - GetA() - 1.0;
G4double R2 = GetMaximalKineticEnergy();
G4double R1 = R2 + GetCoulombBarrier();
if (T <= -0.1) return R1;
else if (T <= 0.1) return sqrt(G4UniformRand())*R2 + GetCoulombBarrier();
else {
G4double E1 = (R1 - DJ*T)/(T + 1.0);
G4double E = 0.0;
G4double T3 = 0.0;
do {
E = GetCoulombBarrier()+G4UniformRand()*R2;
G4double T1 = (E + DJ)/(E1 + DJ);
G4double T2 = (R1 - E)/(R1 - E1);
T3 = T1*pow(T2,T);
} while (G4UniformRand() > T3);
return E;
}
}
@@ -0,0 +1,103 @@
// 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.
//
//
// by V. Lara
#include "G4PreCompoundTransitions.hh"
G4PreCompoundTransitions::
G4PreCompoundTransitions(const G4Fragment & aFragment)
{
// Fermi energy; method internal units are MeV
const G4double FermiEnergy = 45.0;
// Number of holes
G4double H = aFragment.GetNumberOfHoles();
// Number of Particles
G4double P = aFragment.GetNumberOfParticles();
// Relative Energy (T_{rel})
G4double RelativeEnergy = (8.0/5.0)*FermiEnergy + (aFragment.GetExcitationEnergy()/MeV)/(H+P);
// (aFragment.GetExcitationEnergy()/MeV)/aFragment.GetNumberOfExcitons();
// Relative Velocity:
// <V_{rel}>^2
G4double RelativeVelocitySqr = 2.0*RelativeEnergy/(G4Proton::Proton()->GetPDGMass()/MeV);
// <V_{rel}>
G4double RelativeVelocity = sqrt(RelativeVelocitySqr);
// Proton-Proton Cross Section (in mbarn)
G4double ppXSection = 10.63/RelativeVelocitySqr - 29.93/RelativeVelocity + 42.9;
// Proton-Neutron Cross Section (in mbarn)
G4double npXSection = 34.10/RelativeVelocitySqr - 82.20/RelativeVelocity + 82.2;
// Averaged Cross Section: \sigma(V_{rel})
G4double AveragedXSection = (ppXSection+npXSection)/2.0;
// Fermi energy Relative energy ratio
G4double FermiRelRatio = FermiEnergy/RelativeEnergy;
// This factor is introduced to take into account the Pauli principle
G4double PauliFactor = 1.0 - (7.0/5.0)*FermiRelRatio;
if (FermiRelRatio > 0.5) PauliFactor += (2.0/5.0)*FermiRelRatio*pow(2.0 - (1.0/FermiRelRatio), 5.0/2.0);
// Transition probability for \Delta n = +2
TransitionProb1 = 0.00332*AveragedXSection*PauliFactor*sqrt(RelativeEnergy)/
pow(1.2 + 1.0/(4.7*RelativeVelocity), 3.0);
G4double GE = G4PreCompoundParameters::GetAddress()->GetLevelDensity()*
aFragment.GetA()*aFragment.GetExcitationEnergy()/MeV;
// Transition probability for \Delta n = -2 (at F(p,h) = 0)
// TransitionProb2 = max(0, (TransitionProb1*P*H*(P+H+1.0)*(P+H-2.0))/(GE*GE));
TransitionProb2 = (TransitionProb1*P*H*(P+H+1.0)*(P+H-2.0))/(GE*GE);
if (TransitionProb2 < 0.0) TransitionProb2 = 0.0;
// Transition probability for \Delta n = 0 (at F(p,h) = 0)
TransitionProb3 = TransitionProb1*(P+H+1.0)*(P*(P-1.0)+4.0*P*H+H*(H-1.0))/((P+H)*GE);
return;
}
const G4PreCompoundTransitions & G4PreCompoundTransitions::operator=(const G4PreCompoundTransitions &right)
{
G4Exception("G4PreCompoundTransitions::operator= meant to not be accessable");
return *this;
}
G4bool G4PreCompoundTransitions::operator==(const G4PreCompoundTransitions &right) const
{
return false;
}
G4bool G4PreCompoundTransitions::operator!=(const G4PreCompoundTransitions &right) const
{
return true;
}
G4int G4PreCompoundTransitions::GetDeltaNExciton()
{
G4int result = 0;
G4double ChosenTransition = G4UniformRand()*GetTotalProbability();
if (ChosenTransition <= TransitionProb1)
{
// Number of excitons is increased on \Delta n = +2
result = 2;
}
else if (ChosenTransition <= TransitionProb1+TransitionProb2)
{
// Number of excitons is increased on \Delta n = -2
result = -2;
}
return result;
}
@@ -0,0 +1,219 @@
// 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.
//
//
// by V. Lara
// corrections by V. Krylov
#include "G4VPreCompoundFragment.hh"
//G4VPreCompoundFragment::G4VPreCompoundFragment(): theA(0.0),theZ(0.0),
// theRestNucleusA(0.0),theRestNucleusZ(0.0),CoulombBarrier(0.0),MaximalKineticEnergy(-1.0),
// ExcitonLevelDensityRatio(0.0),EmissionProbability(0.0),CondensationProbability(0.0),
// Momentum(0.0,0.0,0.0,0.0)
//{
//}
G4VPreCompoundFragment::G4VPreCompoundFragment
(const G4VPreCompoundFragment & right)
{
theA = right.theA;
theZ = right.theZ;
theRestNucleusA = right.theRestNucleusA;
theRestNucleusZ = right.theRestNucleusZ;
CoulombBarrier = right.CoulombBarrier;
MaximalKineticEnergy = right.MaximalKineticEnergy;
ExcitonLevelDensityRatio = right.ExcitonLevelDensityRatio;
EmissionProbability = right.EmissionProbability;
CondensationProbability = right.CondensationProbability;
Momentum = right.Momentum;
}
G4VPreCompoundFragment::G4VPreCompoundFragment(const G4double anA, const G4double aZ):
theA(anA),theZ(aZ),theRestNucleusA(0.0),theRestNucleusZ(0.0),CoulombBarrier(0.0),
MaximalKineticEnergy(-1.0),ExcitonLevelDensityRatio(0.0),EmissionProbability(0.0),
CondensationProbability(0.0),Momentum(0.0,0.0,0.0,0.0)
{}
G4VPreCompoundFragment::~G4VPreCompoundFragment()
{
}
const G4VPreCompoundFragment & G4VPreCompoundFragment::operator=
(const G4VPreCompoundFragment & right)
{
if (this != &right) {
theA = right.theA;
theZ = right.theZ;
theRestNucleusA = right.theRestNucleusA;
theRestNucleusZ = right.theRestNucleusZ;
CoulombBarrier = right.CoulombBarrier;
MaximalKineticEnergy = right.MaximalKineticEnergy;
ExcitonLevelDensityRatio = right.ExcitonLevelDensityRatio;
EmissionProbability = right.EmissionProbability;
CondensationProbability = right.CondensationProbability;
Momentum = right.Momentum;
}
return *this;
}
G4int G4VPreCompoundFragment::operator==(const G4VPreCompoundFragment & right) const
{
return (this == (G4VPreCompoundFragment *) &right);
}
G4int G4VPreCompoundFragment::operator!=(const G4VPreCompoundFragment & right) const
{
return (this != (G4VPreCompoundFragment *) &right);
}
ostream& operator << (ostream &out, const G4VPreCompoundFragment &theFragment)
{
out << &theFragment;
return out;
}
ostream& operator << (ostream &out, const G4VPreCompoundFragment *theFragment)
{
long old_floatfield = out.setf(0,ios::floatfield);
out
<< "PreCompound Model Emitted Fragment: A = " << setprecision(3) << theFragment->theA
<< ", Z = " << setprecision(3) << theFragment->theZ;
out.setf(ios::scientific,ios::floatfield);
// out
// << ", U = " << theFragment->theExcitationEnergy/MeV
// << " MeV" << endl
// << " P = ("
// << theFragment->theMomentum.x()/MeV << ","
// << theFragment->theMomentum.y()/MeV << ","
// << theFragment->theMomentum.z()/MeV
// << ") MeV E = "
// << theFragment->theMomentum.t()/MeV << " MeV";
out.setf(old_floatfield,ios::floatfield);
return out;
}
void G4VPreCompoundFragment::Init(const G4Fragment & aFragment)
{
SetRestA(aFragment.GetA());
SetRestZ(aFragment.GetZ());
if ((GetRestA() < GetRestZ()) ||
(GetRestA() < GetA()) ||
(GetRestZ() < GetZ())) {
// for to be sure that emission probability will be 0.
SetMaximalKineticEnergy(0.0);
return;
}
// Compute nuclear radius (needed to calculate Coulomb barrier)
G4double NuclearRadius = 2.173*
(1.0+0.006103*GetZ()*GetRestZ())/
(1.0+0.009443*GetZ()*GetRestZ());
// Calculate Coulomb barrier
SetCoulombBarrier(CalcCoulombBarrier(NuclearRadius));
// Compute Binding Energies for fragments (needed to separate a fragment from the nucleus)
SetBindingEnergy(G4NucleiProperties::GetMassExcess(GetA(),GetZ())/MeV+
G4NucleiProperties::GetMassExcess(GetRestA(),GetRestZ())/MeV-
G4NucleiProperties::GetMassExcess(aFragment.GetA(),aFragment.GetZ())/MeV);
// Compute Maximal Kinetic Energy which can be carried by fragments after separation
SetMaximalKineticEnergy((aFragment.GetExcitationEnergy()/MeV)-
(GetBindingEnergy()+
GetCoulombBarrier()));
}
G4double G4VPreCompoundFragment::CalcCoulombBarrier(const G4double & NucRad)
// Calculation of Coulomb potential energy (barrier) for outgoing particles (in MeV)
{
// for neutron
G4double Barrier;
if (GetZ() == 0)
{
Barrier = 0.0;
}
else
{
Barrier = (1.44/NucRad)*
((GetZ()*GetRestZ())/
(pow(GetA(),1.0/3.0)+pow(GetRestA(),1.0/3.0)));
}
// return Barrier;
return Barrier;
}
G4double G4VPreCompoundFragment::
CalcEmissionProbability(const G4Fragment & aFragment)
{
if (GetMaximalKineticEnergy() <= 0.0) return 0.0;
// Coulomb barrier for fragment "index" (for nucleon it is 0) is the lower limit
// of integration over kinetic energy
G4double LowerLimit = GetCoulombBarrier();
// Excitation energy of nucleus after fragment emission is the upper limit
// of integration over kinetic energy
G4double UpperLimit = aFragment.GetExcitationEnergy()/MeV - GetBindingEnergy();
return EmissionProbability = IntegrateEmissionProbability(LowerLimit,UpperLimit,aFragment);
// Correction by V. Krylov:
// Emission probability was stored in a local variable but not in
// data member EmissionProbability, then the returned probability
// by GetEmissionProbability() method was always 0.0
}
G4double G4VPreCompoundFragment::
IntegrateEmissionProbability(const G4double & Low, const G4double & Up,
const G4Fragment & aFragment)
{
static const G4double w[8] = {0.1012285363,
0.2223810345,
0.3137066459,
0.3626837834,
0.3626837834,
0.3137066459,
0.2223810345,
0.1012285363};
static const G4double FIKS[8] = {0.9602898565,
0.7966664774,
0.5255324099,
0.1834346425,
-0.1834346425,
-0.5255324099,
-0.7966664774,
-0.9602898565};
G4double Total = 0.0;
for (G4int i = 0; i < 8; i++) {
G4double KineticE = ((Up-Low)*FIKS[i]+(Up+Low))/2.0;
Total += w[i]*ProbabilityDistributionFunction(KineticE, aFragment)
*(Up-Low)/2.0;
}
return Total;
}
@@ -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.
//
//
// by V. Lara
// Corrections by V. Krylov
#include "G4VPreCompoundIon.hh"
G4double G4VPreCompoundIon::
ProbabilityDistributionFunction(const G4double & eKin,
const G4Fragment & aFragment)
{
const G4double r0 = 1.5; // fm
const G4double SingleParticleLevelDensity =
0.595*G4PreCompoundParameters::GetAddress()->GetLevelDensity(); // AC
G4double R0J = 1.1;
G4double exEnergy = aFragment.GetExcitationEnergy()/MeV;
return GetCondensationProbability()*R0J*0.104/
(r0*pow(GetRestA(),1.0/3.0)*sqrt(GetA()*exEnergy))*
GetExcitonLevelDensityRatio()*
( (eKin-GetCoulombBarrier())/exEnergy )*
pow( ( (eKin+GetBindingEnergy() )/exEnergy), GetRestA()-1.5)*
pow(1.0 - (eKin + GetBindingEnergy())/exEnergy ,
aFragment.GetNumberOfExcitons()-GetA()-1.0 ) ;
// Corrections in return statemet by V. Krylov:
// - GetA() and GetRestA() were intechanged
}
G4double G4VPreCompoundIon::GetKineticEnergy(const G4Fragment & aFragment)
{
G4double DJ = - GetCoulombBarrier();
G4double T = aFragment.GetNumberOfParticles() + aFragment.GetNumberOfHoles() - GetA() - 1.0;
G4double R2 = GetMaximalKineticEnergy();
G4double R1 = R2 + GetCoulombBarrier();
if (T <= -0.1) return R1;
else if (T <= 0.1) {
G4double E1 = R1;
G4double E = 0.0;
G4double T3 = 0.0;
do {
G4double PJ1 = GetA() - 1.5;
G4double AbsBindingE = abs(GetBindingEnergy());
if (GetBindingEnergy() <= 0.0 && AbsBindingE > GetCoulombBarrier())
E = AbsBindingE + G4UniformRand()*(aFragment.GetExcitationEnergy()/MeV);
else
E = GetCoulombBarrier() + G4UniformRand()*R2;
T3 = pow((E+GetBindingEnergy())/(E1+GetBindingEnergy()),PJ1)*
((E+DJ)/(E1+DJ));
} while (G4UniformRand() > T3);
return E;
} else {
G4double PJ1 = GetA() - 1.5;
G4double ES = (aFragment.GetExcitationEnergy()/MeV)*(GetA()-0.5)+
((aFragment.GetExcitationEnergy()/MeV)-R2)*(aFragment.GetNumberOfParticles()+
aFragment.GetNumberOfHoles()-2.5);
G4double E1 = (ES + sqrt(ES*ES-((aFragment.GetExcitationEnergy()/MeV)-R2)*(GetA()-1.5)*
(aFragment.GetNumberOfParticles()+aFragment.GetNumberOfHoles()-1.5)*
4.0*(aFragment.GetExcitationEnergy()/MeV)))/
((aFragment.GetNumberOfParticles()+aFragment.GetNumberOfHoles()-1.5)*2.0)
- (aFragment.GetExcitationEnergy()/MeV) + R1;
G4double E = 0.0;
G4double T3 = 0.0;
do {
if (GetBindingEnergy() <= 0.0 && abs(GetBindingEnergy()) > GetCoulombBarrier())
E = abs(GetBindingEnergy()) + G4UniformRand()*(aFragment.GetExcitationEnergy()/MeV);
else
E = GetCoulombBarrier()+G4UniformRand()*R2;
T3 = (pow((E+GetBindingEnergy())/(E1+GetBindingEnergy()),PJ1)*
((E+DJ)/(E1+DJ))) * pow((R1-E)/(R1-E1),T);
} while (G4UniformRand() > T3);
return E;
}
}