Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
// 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: G4LCapture.cc,v 2.3 1998/07/13 17:24:07 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// G4 Model: Low-energy Neutron Capture
|
||||
// F.W. Jones, TRIUMF, 03-DEC-96
|
||||
//
|
||||
// This is a prototype of a low-energy neutron capture process.
|
||||
// Currently it is based on the GHEISHA routine CAPTUR,
|
||||
// and conforms fairly closely to the original Fortran.
|
||||
//
|
||||
// HPW Capture using models now. the code comes from the
|
||||
// original G4LCapture class.
|
||||
//
|
||||
// 25-JUN-98 FWJ: replaced missing Initialize for ParticleChange.
|
||||
//
|
||||
|
||||
|
||||
#include "G4LCapture.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4LCapture::G4LCapture() :
|
||||
G4HadronicInteraction()
|
||||
{
|
||||
theParticleChange.SetNumberOfSecondaries(2);
|
||||
|
||||
SetMinEnergy( 0.0*GeV );
|
||||
SetMaxEnergy( DBL_MAX );
|
||||
}
|
||||
|
||||
G4LCapture::~G4LCapture()
|
||||
{
|
||||
theParticleChange.Clear();
|
||||
}
|
||||
|
||||
G4VParticleChange*
|
||||
G4LCapture::ApplyYourself(const G4Track& aTrack, G4Nucleus& targetNucleus)
|
||||
{
|
||||
theParticleChange.Initialize(aTrack);
|
||||
|
||||
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
|
||||
const G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
G4double N = targetNucleus.GetN();
|
||||
G4double Z = targetNucleus.GetZ();
|
||||
|
||||
G4double P = aParticle->GetTotalMomentum()/GeV;
|
||||
G4double Px = P*(aParticle->GetMomentumDirection().x());
|
||||
G4double Py = P*(aParticle->GetMomentumDirection().y());
|
||||
G4double Pz = P*(aParticle->GetMomentumDirection().z());
|
||||
G4double E = aParticle->GetTotalEnergy()/GeV;
|
||||
G4double E0 = aParticle->GetDefinition()->GetPDGMass()/GeV;
|
||||
G4double Q = aParticle->GetDefinition()->GetPDGCharge();
|
||||
G4double pv6 = aParticle->GetDefinition()->GetPDGCharge();
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4LCapture:ApplyYourself: incident particle:" << endl;
|
||||
G4cout << "P " << P << " GeV/c" << endl;
|
||||
G4cout << "Px " << Px << " GeV/c" << endl;
|
||||
G4cout << "Py " << Py << " GeV/c" << endl;
|
||||
G4cout << "Pz " << Pz << " GeV/c" << endl;
|
||||
G4cout << "E " << E << " GeV" << endl;
|
||||
G4cout << "mass " << E0 << " GeV" << endl;
|
||||
G4cout << "charge " << Q << endl;
|
||||
}
|
||||
// GHEISHA ADD operation to get total energy, mass, charge:
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4LCapture:ApplyYourself: material:" << endl;
|
||||
G4cout << "A " << N << endl;
|
||||
G4cout << "Z " << Z << endl;
|
||||
G4cout << "atomic mass " <<
|
||||
Atomas(N, Z) << "GeV" << endl;
|
||||
}
|
||||
E = E + Atomas(N, Z);
|
||||
G4double E02 = E*E - P*P;
|
||||
E0 = sqrt(abs(E02));
|
||||
if (E02 < 0) E0 = -E0;
|
||||
Q = Q + Z;
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4LCapture:ApplyYourself: total:" << endl;
|
||||
G4cout << "E " << E << " GeV" << endl;
|
||||
G4cout << "mass " << E0 << " GeV" << endl;
|
||||
G4cout << "charge " << Q << endl;
|
||||
}
|
||||
Px = -Px;
|
||||
Py = -Py;
|
||||
Pz = -Pz;
|
||||
|
||||
// Make a gamma...
|
||||
|
||||
G4double ran = RandGauss::shoot();
|
||||
G4double p = 0.0065 + ran*0.0010;
|
||||
|
||||
G4double ran1 = G4UniformRand();
|
||||
G4double ran2 = G4UniformRand();
|
||||
G4double cost = -1. + 2.*ran1;
|
||||
G4double sint = sqrt(abs(1. - cost*cost));
|
||||
G4double phi = ran2*twopi;
|
||||
|
||||
G4double px = p*sint*sin(phi);
|
||||
G4double py = p*sint*cos(phi);
|
||||
G4double pz = p*cost;
|
||||
G4double e = p;
|
||||
G4double e0 = 0.;
|
||||
|
||||
G4double a = px*Px + py*Py + pz*Pz;
|
||||
a = (a/(E + E0) - e)/E0;
|
||||
|
||||
px = px + a*Px;
|
||||
py = py + a*Py;
|
||||
pz = pz + a*Pz;
|
||||
|
||||
G4DynamicParticle* aGamma;
|
||||
aGamma = new G4DynamicParticle(G4Gamma::GammaDefinition(),
|
||||
G4ThreeVector(px*GeV, py*GeV, pz*GeV));
|
||||
theParticleChange.AddSecondary(aGamma);
|
||||
|
||||
// Make another gamma if there is sufficient energy left over...
|
||||
|
||||
G4double xp = 0.008 - p;
|
||||
if (xp <= 0.) return &theParticleChange;
|
||||
|
||||
ran1 = G4UniformRand();
|
||||
ran2 = G4UniformRand();
|
||||
cost = -1. + 2.*ran1;
|
||||
sint = sqrt(abs(1. - cost*cost));
|
||||
phi = ran2*twopi;
|
||||
|
||||
px = xp*sint*sin(phi);
|
||||
py = xp*sint*cos(phi);
|
||||
pz = xp*cost;
|
||||
e = xp;
|
||||
e0 = 0.;
|
||||
|
||||
a = px*Px + py*Py + pz*Pz;
|
||||
a = (a/(E + E0) - e)/E0;
|
||||
|
||||
px = px + a*Px;
|
||||
py = py + a*Py;
|
||||
pz = pz + a*Pz;
|
||||
|
||||
aGamma = new G4DynamicParticle(G4Gamma::GammaDefinition(),
|
||||
G4ThreeVector(px*GeV, py*GeV, pz*GeV));
|
||||
theParticleChange.AddSecondary(aGamma);
|
||||
|
||||
return &theParticleChange;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// 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: G4LEAlphaInelastic.cc,v 2.9 1998/12/14 15:33:13 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Alpha Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 25-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
|
||||
#include "G4LEAlphaInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAlphaInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
G4double A = targetNucleus.GetN();
|
||||
G4double Z = targetNucleus.GetZ();
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEAlphaInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetc energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << endl;
|
||||
}
|
||||
|
||||
// Work-around for lack of model above 100 MeV
|
||||
if (originalIncident->GetKineticEnergy()/MeV > 100. ||
|
||||
originalIncident->GetKineticEnergy() <= 0.1*MeV) return &theParticleChange;
|
||||
|
||||
G4double theAtomicMass = targetNucleus.AtomicMass( A, Z )-Z*G4Electron::Electron()->GetPDGMass();
|
||||
G4double massVec[9];
|
||||
massVec[0] = targetNucleus.AtomicMass( A+4.0, Z+2.0 )-(Z+2.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[1] = targetNucleus.AtomicMass( A+3.0, Z+2.0 )-(Z+2.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[2] = targetNucleus.AtomicMass( A+3.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[3] = targetNucleus.AtomicMass( A+2.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[4] = targetNucleus.AtomicMass( A+1.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[5] = theAtomicMass;
|
||||
massVec[6] = targetNucleus.AtomicMass( A+2.0, Z+2.0 )-(Z+2.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[7] = massVec[3];
|
||||
massVec[8] = targetNucleus.AtomicMass( A+2.0, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
|
||||
G4FastVector<G4ReactionProduct,3> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
theReactionDynamics.NuclearReaction( vec, vecLen, originalIncident,
|
||||
targetNucleus, theAtomicMass, massVec );
|
||||
|
||||
G4double p = originalIncident->GetTotalMomentum();
|
||||
theParticleChange.SetMomentumChange( originalIncident->GetMomentum() * (1.0/p) );
|
||||
theParticleChange.SetEnergyChange( originalIncident->GetKineticEnergy() );
|
||||
|
||||
theParticleChange.SetNumberOfSecondaries( vecLen );
|
||||
G4DynamicParticle *pd;
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
pd = new G4DynamicParticle();
|
||||
pd->SetDefinition( vec[i]->GetDefinition() );
|
||||
pd->SetMomentum( vec[i]->GetMomentum() );
|
||||
theParticleChange.AddSecondary( pd );
|
||||
}
|
||||
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,631 @@
|
||||
// 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: G4LEAntiLambdaInelastic.cc,v 2.3 1998/07/13 17:24:10 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: AntiLambda Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 19-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEAntiLambdaInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAntiLambdaInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEAntiLambdaInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
const G4double anni = min( 1.3*currentParticle.GetTotalMomentum()/GeV, 0.4 );
|
||||
if( (originalIncident->GetKineticEnergy()/MeV > cutOff) || (G4UniformRand() > anni) )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEAntiLambdaInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int &vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASAL0 by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// AntiLambda undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum()/GeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numMulA = 400;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double protmulA[numMulA], protnormA[numSec]; // proton constants
|
||||
static G4double neutmulA[numMulA], neutnormA[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
G4int counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
//
|
||||
// do the same for annihilation channels
|
||||
//
|
||||
for( i=0; i<numMulA; ++i )protmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); ++np )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
protmulA[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnormA[nt-1] += protmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulA; ++i )neutmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
neutmulA[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnormA[nt-1] += neutmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnormA[i] > 0.0 )protnormA[i] = 1.0/protnormA[i];
|
||||
if( neutnormA[i] > 0.0 )neutnormA[i] = 1.0/neutnormA[i];
|
||||
}
|
||||
} // end of initialization
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
|
||||
G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
|
||||
G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
|
||||
G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
|
||||
G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
|
||||
G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
|
||||
G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
|
||||
const G4double anhl[] = {1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,0.97,0.88,
|
||||
0.85,0.81,0.75,0.64,0.64,0.55,0.55,0.45,0.47,0.40,
|
||||
0.39,0.36,0.33,0.10,0.01};
|
||||
G4int iplab = G4int( pOriginal*10.0 );
|
||||
if( iplab > 9 )iplab = G4int( (pOriginal- 1.0)*5.0 ) + 10;
|
||||
if( iplab > 14 )iplab = G4int( pOriginal- 2.0 ) + 15;
|
||||
if( iplab > 22 )iplab = G4int( (pOriginal-10.0)/10.0 ) + 23;
|
||||
if( iplab > 24 )iplab = 24;
|
||||
if( G4UniformRand() > anhl[iplab] )
|
||||
{
|
||||
if( availableEnergy <= aPiPlus->GetPDGMass()/MeV )
|
||||
{ // not energetically possible to produce pion(s)
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
G4int counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = min( 4, max( 1, np-nm+2 ) );
|
||||
switch( ncht )
|
||||
{
|
||||
case 1:
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
G4int counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = min( 4, max( 1, np-nm+3 ) );
|
||||
switch( ncht )
|
||||
{
|
||||
case 1:
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // random number <= anhl[iplab]
|
||||
{
|
||||
if( centerofmassEnergy <= aPiPlus->GetPDGMass()/MeV+aKaonPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
//
|
||||
// annihilation channels
|
||||
//
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( -centerofmassEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
G4int counter = -1;
|
||||
for( np=1; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmulA[counter]*protnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
G4int counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmulA[counter]*neutnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nz--;
|
||||
currentParticle.SetMass( 0.0 );
|
||||
targetParticle.SetMass( 0.0 );
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
if( currentParticle.GetMass() == 0.0 )
|
||||
{
|
||||
if( nz == 0 )
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
if( vec[i]->GetDefinition() == aPiMinus )
|
||||
{
|
||||
vec[i]->SetDefinitionAndUpdateE( aKaonMinus );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // nz > 0
|
||||
{
|
||||
if( nm == 0 )
|
||||
{
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
if( vec[i]->GetDefinition() == aPiZero )
|
||||
{
|
||||
vec[i]->SetDefinitionAndUpdateE( aKaonZL );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // nm > 0
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
if( vec[i]->GetDefinition() == aPiMinus )
|
||||
{
|
||||
vec[i]->SetDefinitionAndUpdateE( aKaonMinus );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // random number >= 0.5
|
||||
{
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
if( vec[i]->GetDefinition() == aPiZero )
|
||||
{
|
||||
vec[i]->SetDefinitionAndUpdateE( aKaonZL );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,523 @@
|
||||
// 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: G4LEAntiNeutronInelastic.cc,v 2.3 1998/07/13 17:24:12 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: AntiNeutron Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 18-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// J.P.Wellisch: 23-Apr-97: Added theNucleus.SetParameters call
|
||||
// J.P. Wellisch: 23-Apr-97: nm = np+1; in line 392
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEAntiNeutronInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAntiNeutronInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEAntiNeutronInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1*MeV;
|
||||
const G4double anni = min( 1.3*currentParticle.GetTotalMomentum()/GeV, 0.4 );
|
||||
|
||||
if( (currentParticle.GetKineticEnergy()/MeV > cutOff) ||
|
||||
(G4UniformRand() > anni) )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
else
|
||||
quasiElastic = true;
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEAntiNeutronInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASNB by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// AntiNeutron undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numMulA = 400;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double protmulA[numMulA], protnormA[numSec]; // proton constants
|
||||
static G4double neutmulA[numMulA], neutnormA[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.70 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
//
|
||||
// do the same for annihilation channels
|
||||
//
|
||||
for( i=0; i<numMulA; ++i )protmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); ++np )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
protmulA[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnormA[nt-1] += protmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulA; ++i )neutmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
neutmulA[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnormA[nt-1] += neutmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnormA[i] > 0.0 )protnormA[i] = 1.0/protnormA[i];
|
||||
if( neutnormA[i] > 0.0 )neutnormA[i] = 1.0/neutnormA[i];
|
||||
}
|
||||
} // end of initialization
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
|
||||
G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
|
||||
G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
|
||||
G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
|
||||
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
// otherwise quasi-elastic scattering
|
||||
|
||||
const G4double anhl[] = {1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,0.97,0.88,
|
||||
0.85,0.81,0.75,0.64,0.64,0.55,0.55,0.45,0.47,0.40,
|
||||
0.39,0.36,0.33,0.10,0.01};
|
||||
G4int iplab = G4int( pOriginal/GeV*10.0 );
|
||||
if( iplab > 9 )iplab = G4int( (pOriginal/GeV- 1.0)*5.0 ) + 10;
|
||||
if( iplab > 14 )iplab = G4int( pOriginal/GeV- 2.0 ) + 15;
|
||||
if( iplab > 22 )iplab = G4int( (pOriginal/GeV-10.0)/10.0 ) + 23;
|
||||
if( iplab > 24 )iplab = 24;
|
||||
if( G4UniformRand() > anhl[iplab] )
|
||||
{
|
||||
if( availableEnergy <= aPiPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4int ieab = availableEnergy*5.0/GeV;
|
||||
const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98};
|
||||
G4double w0, wp, wt, wm;
|
||||
if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one pion will be produced
|
||||
//
|
||||
np = nm = nz = 0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test;
|
||||
if( G4UniformRand() < w0/(w0+wp) )
|
||||
nz = 1;
|
||||
else
|
||||
np = 1;
|
||||
}
|
||||
else // target is a neutron
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test;
|
||||
test = exp( min( expxu, max( expxl, -(-1.0+b[1])*(-1.0+b[1])/(2.0*c*c) ) ) );
|
||||
wm = test;
|
||||
wt = w0+wp+wm;
|
||||
wp += w0;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
nz = 1;
|
||||
else if( ran < wp/wt )
|
||||
np = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
}
|
||||
else // (availableEnergy >= 2.0*GeV) || (random number < supp[ieab])
|
||||
{
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiProton );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiProton );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 0:
|
||||
if( G4UniformRand() < 0.33 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiProton );
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiProton );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // random number <= anhl[iplab]
|
||||
{
|
||||
if( centerofmassEnergy <= 2*aPiPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
//
|
||||
// annihilation channels
|
||||
//
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( -centerofmassEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmulA[counter]*protnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmulA[counter]*neutnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nz--;
|
||||
currentParticle.SetMass( 0.0 );
|
||||
targetParticle.SetMass( 0.0 );
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
// 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: G4LEAntiOmegaMinusInelastic.cc,v 2.4 1998/12/14 15:33:14 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: AntiOmegaMinus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 20-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
//
|
||||
// NOTE: The FORTRAN version of the cascade, CASAOM, simply called the
|
||||
// routine for the OmegaMinus particle. Hence, the Cascade function
|
||||
// below is just a copy of the Cascade from the OmegaMinus particle.
|
||||
|
||||
#include "G4LEAntiOmegaMinusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAntiOmegaMinusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
const G4double anni = min( 1.3*currentParticle.GetTotalMomentum()/GeV, 0.4 );
|
||||
|
||||
if( (currentParticle.GetKineticEnergy()/MeV > cutOff) || (G4UniformRand() > anni) )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEAntiOmegaMinusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASOM by H. Fesefeldt (31-Jan-1989)
|
||||
//
|
||||
// AntiOmegaMinus undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{ // not energetically possible to produce pion(s)
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aXiZero = G4XiZero::XiZero();
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
G4int nvefix = 0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
//
|
||||
// number of secondary mesons determined by kno distribution
|
||||
// check for total charge of final state mesons to determine
|
||||
// the kind of baryons to be produced, taking into account
|
||||
// charge and strangeness conservation
|
||||
//
|
||||
if( np < nm )
|
||||
{
|
||||
if( np+1 == nm )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
nvefix = 1;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
nvefix = 2;
|
||||
}
|
||||
}
|
||||
else if( np > nm )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
if( np+1 < nm )
|
||||
{
|
||||
if( np+2 == nm )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
nvefix = 1;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
nvefix = 2;
|
||||
}
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else if( np+1 == nm )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
for( G4int i=0; i<vecLen && nvefix>0; ++i )
|
||||
{
|
||||
if( vec[i]->GetDefinition() == G4PionMinus::PionMinus() )
|
||||
{
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
if( nvefix >= 1 )vec[i]->SetDefinitionAndUpdateE( aKaonMinus );
|
||||
--nvefix;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,525 @@
|
||||
// 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: G4LEAntiProtonInelastic.cc,v 2.5 1998/12/14 15:33:14 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: AntiProton Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 13-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// J.P. Wellisch: 23-Apr-97: Bug hunting
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEAntiProtonInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAntiProtonInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEAntiProtonInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
const G4double anni = min( 1.3*originalIncident->GetTotalMomentum()/GeV, 0.4 );
|
||||
|
||||
if( (currentParticle.GetKineticEnergy()/MeV > cutOff) ||
|
||||
(G4UniformRand() > anni) )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
else
|
||||
quasiElastic = true;
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEAntiProtonInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASPB by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// AntiProton undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numMulA = 400;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double protmulA[numMulA], protnormA[numSec]; // proton constants
|
||||
static G4double neutmulA[numMulA], neutnormA[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
//
|
||||
// do the same for annihilation channels
|
||||
//
|
||||
for( i=0; i<numMulA; ++i )protmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
protmulA[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnormA[nt-1] += protmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulA; ++i )neutmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
nm = np+1;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
neutmulA[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnormA[nt-1] += neutmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnormA[i] > 0.0 )protnormA[i] = 1.0/protnormA[i];
|
||||
if( neutnormA[i] > 0.0 )neutnormA[i] = 1.0/neutnormA[i];
|
||||
}
|
||||
} // end of initialization
|
||||
//
|
||||
// initialization is OK
|
||||
//
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
|
||||
G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
|
||||
G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
|
||||
G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
|
||||
|
||||
const G4double anhl[] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.90,
|
||||
0.6,0.52,0.47,0.44,0.41,0.39,0.37,0.35,0.34,0.24,
|
||||
0.19,0.15,0.12,0.10,0.09,0.07,0.06,0.05,0.0};
|
||||
|
||||
G4int iplab = G4int( pOriginal/GeV*10.0 );
|
||||
if( iplab > 9 )iplab = G4int( pOriginal/GeV ) + 9;
|
||||
if( iplab > 18 )iplab = G4int( pOriginal/GeV/10.0 ) + 18;
|
||||
if( iplab > 27 )iplab = 28;
|
||||
if( G4UniformRand() > anhl[iplab] )
|
||||
{
|
||||
if( availableEnergy <= aPiPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4int ieab = availableEnergy*5.0/GeV;
|
||||
const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98};
|
||||
G4double w0, wp, wt, wm;
|
||||
if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
//
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one pion will be produced
|
||||
//
|
||||
np = nm = nz = 0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test;
|
||||
test = exp( min( expxu, max( expxl, -(-1.0+b[1])*(-1.0+b[1])/(2.0*c*c) ) ) );
|
||||
wm = test;
|
||||
wt = w0+wp+wm;
|
||||
wp += w0;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
nz = 1;
|
||||
else if( ran < wp/wt )
|
||||
np = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
else // target is a neutron
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
test = exp( min( expxu, max( expxl, -(-1.0+b[0])*(-1.0+b[0])/(2.0*c*c) ) ) );
|
||||
wm = test;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/(w0+wm) )
|
||||
nz = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
}
|
||||
else // (availableEnergy >= 2.0*GeV) || (random number < supp[ieab])
|
||||
{
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 0:
|
||||
if( G4UniformRand() < 0.33 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiNeutron );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiNeutron );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case -1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiNeutron );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiNeutron );
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // random number <= anhl[iplab]
|
||||
{
|
||||
if( centerofmassEnergy <= 2*aPiPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
//
|
||||
// annihilation channels
|
||||
//
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( -centerofmassEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmulA[counter]*protnormA[nt-1]/(2.0*n*n);
|
||||
if( abs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
nm = np+1;
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmulA[counter]*neutnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nz--;
|
||||
currentParticle.SetMass( 0.0 );
|
||||
targetParticle.SetMass( 0.0 );
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,544 @@
|
||||
// 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: G4LEAntiSigmaMinusInelastic.cc,v 2.4 1998/12/14 15:33:14 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: AntiSigmaMinus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 19-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// J.P. Wellisch: 25.Apr-97: counter errors removed lines 426, 447
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEAntiSigmaMinusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAntiSigmaMinusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEAntiSigmaMinusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
const G4double anni = min( 1.3*currentParticle.GetTotalMomentum()/GeV, 0.4 );
|
||||
if( (currentParticle.GetKineticEnergy()/MeV > cutOff) || (G4UniformRand() > anni) )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEAntiSigmaMinusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASASM by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// AntiSigmaMinus undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numMulA = 400;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double protmulA[numMulA], protnormA[numSec]; // proton constants
|
||||
static G4double neutmulA[numMulA], neutnormA[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[2] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
//
|
||||
// do the same for annihilation channels
|
||||
//
|
||||
for( i=0; i<numMulA; ++i )protmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=2; np<(numSec/3); ++np )
|
||||
{
|
||||
nm = np-2;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
protmulA[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnormA[nt-1] += protmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulA; ++i )neutmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; ++np )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
neutmulA[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnormA[nt-1] += neutmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnormA[i] > 0.0 )protnormA[i] = 1.0/protnormA[i];
|
||||
if( neutnormA[i] > 0.0 )neutnormA[i] = 1.0/neutnormA[i];
|
||||
}
|
||||
} // end of initialization
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
|
||||
G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
|
||||
G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
|
||||
G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
|
||||
const G4double anhl[] = {1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,0.97,0.88,
|
||||
0.85,0.81,0.75,0.64,0.64,0.55,0.55,0.45,0.47,0.40,
|
||||
0.39,0.36,0.33,0.10,0.01};
|
||||
G4int iplab = G4int( pOriginal/GeV*10.0 );
|
||||
if( iplab > 9 )iplab = G4int( (pOriginal/GeV- 1.0)*5.0 ) + 10;
|
||||
if( iplab > 14 )iplab = G4int( pOriginal/GeV- 2.0 ) + 15;
|
||||
if( iplab > 23 )iplab = G4int( (pOriginal/GeV-10.0)/10.0 ) + 23;
|
||||
if( iplab > 24 )iplab = 24;
|
||||
if( G4UniformRand() > anhl[iplab] )
|
||||
{
|
||||
if( availableEnergy <= aPiPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = min( 3, max( 1, np-nm+1 ) );
|
||||
switch( ncht )
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = min( 3, max( 1, np-nm+2 ) );
|
||||
switch( ncht )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // random number <= anhl[iplab]
|
||||
{
|
||||
if( centerofmassEnergy <= aPiPlus->GetPDGMass()/MeV+aKaonPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( -centerofmassEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=2; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
nm=np-2;
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmulA[counter]*protnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nz--;
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmulA[counter]*neutnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nz--;
|
||||
}
|
||||
if( nz > 0 )
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
else // random number >= 0.5
|
||||
{
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonZL );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nz;
|
||||
}
|
||||
}
|
||||
else // nm == 0
|
||||
{
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonZL );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nz;
|
||||
}
|
||||
}
|
||||
else // nz == 0
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
currentParticle.SetMass( 0.0 );
|
||||
targetParticle.SetMass( 0.0 );
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,545 @@
|
||||
// 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: G4LEAntiSigmaPlusInelastic.cc,v 2.4 1998/12/14 15:33:14 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: AntiSigmaPlus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 19-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEAntiSigmaPlusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAntiSigmaPlusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEAntiSigmaPlusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
const G4double anni = min( 1.3*currentParticle.GetTotalMomentum()/GeV, 0.4 );
|
||||
if( (currentParticle.GetKineticEnergy()/MeV > cutOff) || (G4UniformRand() > anni) )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEAntiSigmaPlusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASASP by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// AntiSigmaPlus undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numMulA = 400;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double protmulA[numMulA], protnormA[numSec]; // proton constants
|
||||
static G4double neutmulA[numMulA], neutnormA[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
//
|
||||
// do the same for annihilation channels
|
||||
//
|
||||
for( i=0; i<numMulA; ++i )protmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); ++np )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
protmulA[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnormA[nt-1] += protmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulA; ++i )neutmulA[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnormA[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
nm = np+1;
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
neutmulA[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnormA[nt-1] += neutmulA[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnormA[i] > 0.0 )protnormA[i] = 1.0/protnormA[i];
|
||||
if( neutnormA[i] > 0.0 )neutnormA[i] = 1.0/neutnormA[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
|
||||
G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
|
||||
G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
|
||||
G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
|
||||
const G4double anhl[] = {1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,0.97,0.88,
|
||||
0.85,0.81,0.75,0.64,0.64,0.55,0.55,0.45,0.47,0.40,
|
||||
0.39,0.36,0.33,0.10,0.01};
|
||||
G4int iplab = G4int( pOriginal/GeV*10.0 );
|
||||
if( iplab > 9 )iplab = G4int( (pOriginal/GeV- 1.0)*5.0 ) + 10;
|
||||
if( iplab > 14 )iplab = G4int( pOriginal/GeV- 2.0 ) + 15;
|
||||
if( iplab > 22 )iplab = G4int( (pOriginal/GeV-10.0)/10.0 ) + 23;
|
||||
if( iplab > 24 )iplab = 24;
|
||||
if( G4UniformRand() > anhl[iplab] )
|
||||
{
|
||||
if( availableEnergy <= aPiPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = min( 3, max( 1, np-nm+2 ) );
|
||||
switch( ncht )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
case 3:
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = min( 3, max( 1, np-nm+3 ) );
|
||||
switch( ncht )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // random number <= anhl[iplab]
|
||||
{
|
||||
if( centerofmassEnergy <= aPiPlus->GetPDGMass()/MeV+aKaonPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( -centerofmassEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmulA[counter]*protnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nz--;
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
nm = np+1;
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMulA )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>1 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmulA[counter]*neutnormA[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nz--;
|
||||
}
|
||||
if( nz > 0 )
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p= new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p= new G4ReactionProduct ;
|
||||
p->SetDefinition( aKaonZL );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nz;
|
||||
}
|
||||
}
|
||||
else // nm == 0
|
||||
{
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonZL );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nz;
|
||||
}
|
||||
}
|
||||
else // nz == 0
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
currentParticle.SetMass( 0.0 );
|
||||
targetParticle.SetMass( 0.0 );
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
// 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: G4LEAntiXiMinusInelastic.cc,v 2.4 1998/12/14 15:33:14 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: AntiXiMinus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 20-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
//
|
||||
// NOTE: The FORTRAN version of the cascade, CASAXM, simply called the
|
||||
// routine for the XiMinus particle. Hence, the ApplyYourself function
|
||||
// below is just a copy of the ApplyYourself from the XiMinus particle.
|
||||
|
||||
#include "G4LEAntiXiMinusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAntiXiMinusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEAntiXiMinusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
const G4double anni = min( 1.3*currentParticle.GetTotalMomentum()/GeV, 0.4 );
|
||||
if( (currentParticle.GetKineticEnergy()/MeV > cutOff) || (G4UniformRand() > anni) )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEAntiXiMinusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASAXM by H. Fesefeldt (17-Jan-1989)
|
||||
// which is just a copy of casxm (cascade for Xi-).
|
||||
//
|
||||
// AntiXiMinus undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aXiZero = G4XiZero::XiZero();
|
||||
//
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
//
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
//
|
||||
// number of secondary mesons determined by kno distribution
|
||||
// check for total charge of final state mesons to determine
|
||||
// the kind of baryons to be produced, taking into account
|
||||
// charge and strangeness conservation
|
||||
//
|
||||
if( np < nm )
|
||||
{
|
||||
if( np+1 == nm )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
else if( np == nm )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
if( np+1 < nm )
|
||||
{
|
||||
if( np+2 == nm )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
else if( np+1 == nm )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
// 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: G4LEAntiXiZeroInelastic.cc,v 2.3 1998/07/13 17:24:20 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: AntiXiZero Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 20-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
//
|
||||
// NOTE: The FORTRAN version of the cascade, CASAXO, simply called the
|
||||
// routine for the XiZero particle. Hence, the ApplyYourself function
|
||||
// below is just a copy of the ApplyYourself from the XiZero particle.
|
||||
|
||||
#include "G4LEAntiXiZeroInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEAntiXiZeroInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEAntiXiZeroInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
const G4double anni = min( 1.3*currentParticle.GetTotalMomentum()/GeV, 0.4 );
|
||||
if( (currentParticle.GetKineticEnergy()/MeV > cutOff) || (G4UniformRand() > anni) )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEAntiXiZeroInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASAX0 by H. Fesefeldt (20-Jan-1989)
|
||||
// which is just a copy of CASX0 (cascade for Xi0)
|
||||
//
|
||||
// AntiXiZero undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aXiMinus = G4XiMinus::XiMinus();
|
||||
//
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
//
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
//
|
||||
// number of secondary mesons determined by kno distribution
|
||||
// check for total charge of final state mesons to determine
|
||||
// the kind of baryons to be produced, taking into account
|
||||
// charge and strangeness conservation
|
||||
//
|
||||
if( np < nm+1 )
|
||||
{
|
||||
if( np != nm ) // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
else if( np == nm+1 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiMinus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
if( np < nm )
|
||||
{
|
||||
if( np+1 == nm )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
else if( np == nm )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiMinus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// 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: G4LEDeuteronInelastic.cc,v 2.8 1998/12/14 15:33:14 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Deuteron Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 25-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
|
||||
#include "G4LEDeuteronInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEDeuteronInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEDeuteronInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
}
|
||||
|
||||
// Work-around for lack of model above 100 MeV
|
||||
if (originalIncident->GetKineticEnergy()/MeV > 100. ||
|
||||
originalIncident->GetKineticEnergy() <= 0.1*MeV) return &theParticleChange;
|
||||
|
||||
G4double N = targetNucleus.GetN();
|
||||
G4double Z = targetNucleus.GetZ();
|
||||
G4double theAtomicMass = targetNucleus.AtomicMass( N, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
G4double massVec[9];
|
||||
massVec[0] = targetNucleus.AtomicMass( N+2.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[1] = targetNucleus.AtomicMass( N+1.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[2] = targetNucleus.AtomicMass( N+1.0, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[3] = theAtomicMass;
|
||||
massVec[4] = targetNucleus.AtomicMass( N-1.0, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[5] = targetNucleus.AtomicMass( N-2.0, Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[6] = targetNucleus.AtomicMass( N, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[7] = massVec[3];
|
||||
massVec[8] = targetNucleus.AtomicMass( N, Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
|
||||
G4FastVector<G4ReactionProduct,3> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
theReactionDynamics.NuclearReaction( vec, vecLen, originalIncident,
|
||||
targetNucleus, theAtomicMass, massVec );
|
||||
|
||||
G4double p = originalIncident->GetTotalMomentum();
|
||||
theParticleChange.SetMomentumChange( originalIncident->GetMomentum() * (1.0/p) );
|
||||
theParticleChange.SetEnergyChange( originalIncident->GetKineticEnergy() );
|
||||
|
||||
theParticleChange.SetNumberOfSecondaries( vecLen );
|
||||
G4DynamicParticle *pd;
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
pd = new G4DynamicParticle();
|
||||
pd->SetDefinition( vec[i]->GetDefinition() );
|
||||
pd->SetMomentum( vec[i]->GetMomentum() );
|
||||
theParticleChange.AddSecondary( pd );
|
||||
}
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,515 @@
|
||||
// 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: G4LEKaonMinusInelastic.cc,v 2.4 1998/12/14 15:33:15 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Low Energy KaonMinus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 12-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// J.P.Wellisch 23-Apr-97: bug-hunting (missing initialization of np,nm,nz fixed)
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEKaonMinusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEKaonMinusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
|
||||
// create the target particle
|
||||
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
G4double targetMass = originalTarget->GetDefinition()->GetPDGMass();
|
||||
G4ReactionProduct targetParticle( originalTarget->GetDefinition() );
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEKaonMinusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy() << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
G4ReactionProduct currentParticle( originalIncident->GetDefinition() );
|
||||
currentParticle.SetMomentum( originalIncident->GetMomentum() );
|
||||
currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() );
|
||||
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
|
||||
G4double ek = originalIncident->GetKineticEnergy();
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass();
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
// calculate black track energies
|
||||
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
G4ReactionProduct modifiedOriginal = currentParticle;
|
||||
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1*MeV;
|
||||
if( currentParticle.GetKineticEnergy() > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEKaonMinusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASKM by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// K- undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass();
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy();
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum();
|
||||
const G4double targetMass = targetParticle.GetMass();
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int nt, np, nm, nz;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.70 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
G4int counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
|
||||
G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
|
||||
G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
|
||||
G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
|
||||
G4ParticleDefinition *aLambda = G4Lambda::Lambda();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
|
||||
G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
|
||||
const G4double cech[] = {1.,1.,1.,0.70,0.60,0.55,0.35,0.25,0.18,0.15};
|
||||
G4int iplab = min( 9.0, pOriginal/GeV*5.0 );
|
||||
if( (pOriginal <= 2.0*GeV) && (G4UniformRand() < cech[iplab]) )
|
||||
{
|
||||
np = nm = nz = nt = 0;
|
||||
iplab = min( 19.0, pOriginal/GeV*10.0 );
|
||||
const G4double cnk0[] = {0.17,0.18,0.17,0.24,0.26,0.20,0.22,0.21,0.34,0.45,
|
||||
0.58,0.55,0.36,0.29,0.29,0.32,0.32,0.33,0.33,0.33};
|
||||
if( G4UniformRand() <= cnk0[iplab] )
|
||||
{
|
||||
quasiElastic = true;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // random number > cnk0[iplab]
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < 0.25 ) // k- p --> pi- s+
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else if( ran < 0.50 ) // k- p --> pi0 s0 or k- n --> pi- s0
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else if( ran < 0.75 ) // k- p --> pi+ s- or k- n --> pi0 s-
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else // k- p --> pi0 L or k- n --> pi- L
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // (pOriginal > 2.0*GeV) || (random number >= cech[iplab])
|
||||
{
|
||||
if( availableEnergy < aPiPlus->GetPDGMass() )
|
||||
{ // not energetically possible to produce pion(s)
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, test, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
G4int counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
if( np == nm )
|
||||
{
|
||||
if( G4UniformRand() >= 0.75 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else if( np == nm+1 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
G4int counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
if( np == nm-1 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
else if( np != nm )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
if( (currentParticle.GetDefinition() == aKaonMinus &&
|
||||
targetParticle.GetDefinition() == aNeutron ) ||
|
||||
(currentParticle.GetDefinition() == aKaonZL &&
|
||||
targetParticle.GetDefinition() == aProton ) )
|
||||
{
|
||||
ran = G4UniformRand();
|
||||
if( ran < 0.68 )
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else if( ran < 0.84 )
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // ( current != aKaonMinus || target != aNeutron ) &&
|
||||
// ( current != aKaonZL || target != aProton )
|
||||
{
|
||||
ran = G4UniformRand();
|
||||
if( ran < 0.67 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else if( ran < 0.78 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else if( ran < 0.89 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( currentParticle.GetDefinition() == aKaonZL )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZS );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aKaonZL )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aKaonZS );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
// 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: G4LEKaonPlusInelastic.cc,v 2.4 1998/12/14 15:33:15 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Low Energy KaonPlus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 05-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEKaonPlusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEKaonPlusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
|
||||
// create the target particle
|
||||
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
G4double targetMass = originalTarget->GetDefinition()->GetPDGMass();
|
||||
G4ReactionProduct targetParticle( originalTarget->GetDefinition() );
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEKaonPlusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy() << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
G4ReactionProduct currentParticle( originalIncident->GetDefinition() );
|
||||
currentParticle.SetMomentum( originalIncident->GetMomentum() );
|
||||
currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() );
|
||||
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
|
||||
G4double ek = originalIncident->GetKineticEnergy();
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass();
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
// calculate black track energies
|
||||
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
G4ReactionProduct modifiedOriginal = currentParticle;
|
||||
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1*MeV;
|
||||
if( currentParticle.GetKineticEnergy() > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEKaonPlusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int &vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASKP by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// K+ undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass();
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy();
|
||||
const G4double targetMass = targetParticle.GetMass();
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy < G4PionPlus::PionPlus()->GetPDGMass() )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int nt=0, np=0, nm=0, nz=0;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.70 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
G4int counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
|
||||
G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4int ieab = availableEnergy*5.0/GeV;
|
||||
const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98};
|
||||
G4double test, w0, wp, wt, wm;
|
||||
if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one pion will be produced
|
||||
|
||||
nm = np = nz = 0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -sqr(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test*2.0;
|
||||
if( G4UniformRand() < w0/(w0+wp) )
|
||||
nz = 1;
|
||||
else
|
||||
np = 1;
|
||||
}
|
||||
else // target is a neutron
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -sqr(1.0+b[1])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test;
|
||||
test = exp( min( expxu, max( expxl, -sqr(-1.0+b[1])/(2.0*c*c) ) ) );
|
||||
wm = test;
|
||||
wt = w0+wp+wm;
|
||||
wp += w0;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
nz = 1;
|
||||
else if( ran < wp/wt )
|
||||
np = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
G4int counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); (nm<=np) && (ran>=excs); ++nm )
|
||||
{
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs )return; // 3 previous loops continued to the end
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
G4int counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); (nm<=(np+1)) && (ran>=excs); ++nm )
|
||||
{
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs )return; // 3 previous loops continued to the end
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZS );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZS );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target is a neutron
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 0:
|
||||
if( G4UniformRand() < 0.25 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZS );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZS );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
default: // assumes nm = np+1 so charge is conserved
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,486 @@
|
||||
// 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: G4LEKaonZeroLInelastic.cc,v 2.3 1998/07/13 17:24:25 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Low Energy KaonZeroLong Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 11-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEKaonZeroLInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEKaonZeroLInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEKaonZeroLInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
if( currentParticle.GetKineticEnergy()/MeV > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEKaonZeroLInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASK0B by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// K0Long undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
|
||||
G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
|
||||
G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
|
||||
G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
|
||||
G4ParticleDefinition *aLambda = G4Lambda::Lambda();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
|
||||
G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
|
||||
const G4double cech[] = {1.,1.,1.,0.70,0.60,0.55,0.35,0.25,0.18,0.15};
|
||||
G4int iplab = min( 9.0, 5.0*pOriginal*MeV/GeV );
|
||||
if( (pOriginal*MeV/GeV <= 2.0) && (G4UniformRand() < cech[iplab]) )
|
||||
{
|
||||
np = nm = nz = nt = 0;
|
||||
iplab = min( 19.0, pOriginal*MeV/GeV*10.0 );
|
||||
const G4double cnk0[] = {0.17,0.18,0.17,0.24,0.26,0.20,0.22,0.21,0.34,0.45,
|
||||
0.58,0.55,0.36,0.29,0.29,0.32,0.32,0.33,0.33,0.33};
|
||||
if( G4UniformRand() > cnk0[iplab] )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < 0.25 ) // k0Long n --> pi- s+
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else if( ran < 0.50 ) // k0Long p --> pi+ s0 or k0Long n --> pi0 s0
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else if( ran < 0.75 ) // k0Long n --> pi+ s-
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // k0Long p --> pi+ L or k0Long n --> pi0 L
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // ran <= cnk0
|
||||
{
|
||||
quasiElastic = true;
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // (pOriginal > 2.0*GeV) || (random number >= cech[iplab])
|
||||
{
|
||||
if( availableEnergy < aPiPlus->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, test, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
switch( np-nm )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonMinus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
switch( np-nm )
|
||||
{
|
||||
case 0:
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
case 1:
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonMinus );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
if( currentParticle.GetDefinition() == aKaonMinus &&
|
||||
targetParticle.GetDefinition() == aNeutron )
|
||||
{
|
||||
ran = G4UniformRand();
|
||||
if( ran < 0.68 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
}
|
||||
else if( ran < 0.84 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
}
|
||||
}
|
||||
else if( (currentParticle.GetDefinition() == aKaonZS ||
|
||||
currentParticle.GetDefinition() == aKaonZL ) &&
|
||||
targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
ran = G4UniformRand();
|
||||
if( ran < 0.68 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
}
|
||||
else if( ran < 0.84 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ran = G4UniformRand();
|
||||
if( ran < 0.67 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
}
|
||||
else if( ran < 0.78 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiMinus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
}
|
||||
else if( ran < 0.89 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
}
|
||||
}
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
if( currentParticle.GetDefinition() == aKaonZL )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZS );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aKaonZL )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aKaonZS );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
// 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: G4LEKaonZeroSInelastic.cc,v 2.3 1998/07/13 17:24:27 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Low Energy KaonZeroShort Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 11-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEKaonZeroSInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEKaonZeroSInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEKaonZeroSInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
if( currentParticle.GetKineticEnergy()/MeV > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEKaonZeroSInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASK0 by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// K0Short undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
|
||||
G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
|
||||
G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4int ieab = 5.0*availableEnergy*MeV/GeV;
|
||||
const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98};
|
||||
G4double test, w0, wp, wt, wm;
|
||||
if( (availableEnergy*MeV/GeV < 2.0) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
//
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one pion will be produced
|
||||
//
|
||||
nm = np = nz = 0;
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
w0 = test/2.0;
|
||||
test = exp( min( expxu, max( expxl, -(-1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
wm = test*1.5;
|
||||
if( G4UniformRand() < w0/(w0+wm) )
|
||||
nz = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
else // target is a proton
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test;
|
||||
test = exp( min( expxu, max( expxl, -(-1.0+b[1])*(-1.0+b[1])/(2.0*c*c) ) ) );
|
||||
wm = test;
|
||||
wt = w0+wp+wm;
|
||||
wp += w0;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
nz = 1;
|
||||
else if( ran < wp/wt )
|
||||
np = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
}
|
||||
else // (availableEnergy*MeV/GeV >= 2.0) || (G4UniformRand() < supp[ieab])
|
||||
{
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 0:
|
||||
if( G4UniformRand() < 0.25 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonPlus );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // targetParticle is a neutron
|
||||
{
|
||||
switch( np-nm ) // seems wrong, charge not conserved
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonPlus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( currentParticle.GetDefinition() == aKaonZS )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aKaonZL);
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aKaonZS )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aKaonZL );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
// 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: G4LELambdaInelastic.cc,v 2.3 1998/07/13 17:24:28 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Lambda Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 18-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LELambdaInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LELambdaInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LELambdaInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
if( currentParticle.GetKineticEnergy()/MeV > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LELambdaInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASL0 by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// Lambda undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.35 };
|
||||
if( first ) { // compute normalization constants, this will only be Done once
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np ) {
|
||||
for( nm=max(0,np-2); nm<=(np+1); ++nm ) {
|
||||
for( nz=0; nz<numSec/3; ++nz ) {
|
||||
if( ++counter < numMul ) {
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec ) {
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np ) {
|
||||
for( nm=max(0,np-1); nm<=(np+2); ++nm ) {
|
||||
for( nz=0; nz<numSec/3; ++nz ) {
|
||||
if( ++counter < numMul ) {
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec ) {
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i ) {
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
|
||||
G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
|
||||
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
// otherwise quasi-elastic scattering
|
||||
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton ) {
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np ) {
|
||||
for( nm=max(0,np-2); nm<=(np+1) && ran>=excs; ++nm ) {
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz ) {
|
||||
if( ++counter < numMul ) {
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec ) {
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 ) {
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
} else {
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = max( 1, np-nm );
|
||||
switch( ncht ) {
|
||||
case 1:
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
} else {
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
} else {
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np ) {
|
||||
for( nm=max(0,np-1); nm<=(np+2) && ran>=excs; ++nm ) {
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz ) {
|
||||
if( ++counter < numMul ) {
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec ) {
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 ) {
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
} else {
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = max( 1, np-nm+3 );
|
||||
switch( ncht ) {
|
||||
case 1:
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
} else {
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
} else {
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,500 @@
|
||||
// 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: G4LENeutronInelastic.cc,v 2.11 1998/12/07 12:34:07 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Low Energy Neutron Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 04-Feb-1997
|
||||
|
||||
#include "G4LENeutronInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LENeutronInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LENeutronInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
if( originalIncident->GetKineticEnergy()/MeV < 0.000001 )
|
||||
G4Exception("G4LENeutronInelastic: should be capture process!");
|
||||
if( originalIncident->GetMomentum().mag()/MeV < 0.000001 )
|
||||
G4Exception("G4LENeutronInelastic: should be capture process!");
|
||||
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
if( originalIncident->GetKineticEnergy()/GeV < 0.01 + 2.*G4UniformRand()/9. )
|
||||
{
|
||||
SlowNeutron( originalIncident, modifiedOriginal, targetParticle, targetNucleus );
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
const G4double cutOff = 0.1;
|
||||
if( modifiedOriginal.GetKineticEnergy()/MeV <= cutOff )
|
||||
{
|
||||
SlowNeutron( originalIncident, modifiedOriginal, targetParticle, targetNucleus );
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LENeutronInelastic::SlowNeutron(
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct &modifiedOriginal,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
|
||||
G4ParticleDefinition *aTriton = G4Triton::Triton();
|
||||
G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
|
||||
|
||||
const G4double aProtonMass = aProton->GetPDGMass()/MeV;
|
||||
const G4double aNeutronMass = aNeutron->GetPDGMass()/MeV;
|
||||
const G4double aDeuteronMass = aDeuteron->GetPDGMass()/MeV;
|
||||
const G4double aTritonMass = aTriton->GetPDGMass()/MeV;
|
||||
const G4double anAlphaMass = anAlpha->GetPDGMass()/MeV;
|
||||
|
||||
const G4double A = targetNucleus.GetN(); // atomic weight
|
||||
const G4double Z = targetNucleus.GetZ(); // atomic number
|
||||
|
||||
G4double currentKinetic = modifiedOriginal.GetKineticEnergy()/MeV;
|
||||
G4double currentMass = modifiedOriginal.GetMass()/MeV;
|
||||
if( A < 1.5 ) // Hydrogen
|
||||
{
|
||||
//
|
||||
// very simple simulation of scattering angle and energy
|
||||
// nonrelativistic approximation with isotropic angular
|
||||
// distribution in the cms system
|
||||
//
|
||||
G4double cost1, eka = 0.0;
|
||||
while (eka <= 0.0)
|
||||
{
|
||||
cost1 = -1.0 + 2.0*G4UniformRand();
|
||||
eka = 1.0 + 2.0*cost1*A + A*A;
|
||||
}
|
||||
G4double cost = min( 1.0, max( -1.0, (A*cost1+1.0)/sqrt(eka) ) );
|
||||
eka /= (1.0+A)*(1.0+A);
|
||||
G4double ek = currentKinetic*MeV/GeV;
|
||||
G4double amas = currentMass*MeV/GeV;
|
||||
ek *= eka;
|
||||
G4double en = ek + amas;
|
||||
G4double p = sqrt(abs(en*en-amas*amas));
|
||||
G4double sint = sqrt(abs(1.0-cost*cost));
|
||||
G4double phi = G4UniformRand()*twopi;
|
||||
G4double px = sint*sin(phi);
|
||||
G4double py = sint*cos(phi);
|
||||
G4double pz = cost;
|
||||
targetParticle.SetMomentum( px*GeV, py*GeV, pz*GeV );
|
||||
G4double pxO = originalIncident->GetMomentum().x()/GeV;
|
||||
G4double pyO = originalIncident->GetMomentum().y()/GeV;
|
||||
G4double pzO = originalIncident->GetMomentum().z()/GeV;
|
||||
G4double ptO = pxO*pxO + pyO+pyO;
|
||||
if( ptO > 0.0 )
|
||||
{
|
||||
G4double pO = sqrt(pxO*pxO+pyO*pyO+pzO*pzO);
|
||||
cost = pzO/pO;
|
||||
sint = 0.5*(sqrt(abs((1.0-cost)*(1.0+cost)))+sqrt(ptO)/pO);
|
||||
G4double ph = pi/2.0;
|
||||
if( pyO < 0.0 )ph = ph*1.5;
|
||||
if( abs(pxO) > 0.000001 )ph = atan2(pyO,pxO);
|
||||
G4double cosp = cos(ph);
|
||||
G4double sinp = sin(ph);
|
||||
px = cost*cosp*px - sinp*py+sint*cosp*pz;
|
||||
py = cost*sinp*px + cosp*py+sint*sinp*pz;
|
||||
pz = -sint*px + cost*pz;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pz < 0.0 )pz *= -1.0;
|
||||
}
|
||||
G4double pu = sqrt(px*px+py*py+pz*pz);
|
||||
modifiedOriginal.SetMomentum( targetParticle.GetMomentum() * (p/pu) );
|
||||
modifiedOriginal.SetKineticEnergy( ek*GeV );
|
||||
|
||||
targetParticle.SetMomentum(
|
||||
originalIncident->GetMomentum() - modifiedOriginal.GetMomentum() );
|
||||
G4double pp = targetParticle.GetMomentum().mag();
|
||||
G4double tarmas = targetParticle.GetMass();
|
||||
targetParticle.SetTotalEnergy( sqrt( pp*pp + tarmas*tarmas ) );
|
||||
|
||||
theParticleChange.SetEnergyChange( modifiedOriginal.GetKineticEnergy() );
|
||||
theParticleChange.SetNumberOfSecondaries( 1 );
|
||||
G4DynamicParticle *pd = new G4DynamicParticle;
|
||||
pd->SetDefinition( targetParticle.GetDefinition() );
|
||||
pd->SetMomentum( targetParticle.GetMomentum() );
|
||||
theParticleChange.AddSecondary( pd );
|
||||
return;
|
||||
}
|
||||
G4FastVector<G4ReactionProduct,3> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
G4double theAtomicMass = targetNucleus.AtomicMass( A, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
G4double massVec[9];
|
||||
massVec[0] = targetNucleus.AtomicMass( A+1.0, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[1] = theAtomicMass;
|
||||
massVec[2] = targetNucleus.AtomicMass( A , Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[3] = targetNucleus.AtomicMass( A-1.0, Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[4] = targetNucleus.AtomicMass( A-2.0, Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[5] = targetNucleus.AtomicMass( A-3.0, Z-2.0 )-(Z-2.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[6] = targetNucleus.AtomicMass( A-1.0, Z );
|
||||
massVec[7] = massVec[3];
|
||||
massVec[8] = targetNucleus.AtomicMass( A-1.0, Z-2.0 )-(Z-2.0)*G4Electron::Electron()->GetPDGMass();
|
||||
|
||||
theReactionDynamics.NuclearReaction( vec, vecLen, originalIncident,
|
||||
targetNucleus, theAtomicMass, massVec );
|
||||
|
||||
theParticleChange.SetStatusChange( fStopAndKill );
|
||||
theParticleChange.SetEnergyChange( 0.0 );
|
||||
|
||||
theParticleChange.SetNumberOfSecondaries( vecLen );
|
||||
G4DynamicParticle * pd;
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
pd = new G4DynamicParticle();
|
||||
pd->SetDefinition( vec[i]->GetDefinition() );
|
||||
pd->SetMomentum( vec[i]->GetMomentum() );
|
||||
theParticleChange.AddSecondary( pd );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G4LENeutronInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASN by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// Neutron undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.35, 0.0 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c) /
|
||||
( theReactionDynamics.Factorial(1-np+nm)*
|
||||
theReactionDynamics.Factorial(1+np-nm) );
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c) /
|
||||
( theReactionDynamics.Factorial(nm-np)*
|
||||
theReactionDynamics.Factorial(2-nm+np) );
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4int ieab = availableEnergy*5.0/GeV;
|
||||
const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98};
|
||||
G4double test, w0, wp, wt, wm;
|
||||
if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one pion will be produced
|
||||
|
||||
nm = np = nz = 0;
|
||||
if( targetParticle.GetDefinition() == aNeutron )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) );
|
||||
w0 = test/2.0;
|
||||
wm = test;
|
||||
if( G4UniformRand() < w0/(w0+wm) )
|
||||
nz = 1;
|
||||
else
|
||||
nm = 1;
|
||||
} else { // target is a proton
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test/2.0;
|
||||
test = exp( min( expxu, max( expxl, -(-1.0+b[0])*(-1.0+b[0])/(2.0*c*c) ) ) );
|
||||
wm = test/2.0;
|
||||
wt = w0+wp+wm;
|
||||
wp += w0;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
nz = 1;
|
||||
else if( ran < wp/wt )
|
||||
np = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
} else { // (availableEnergy >= 2.0*GeV) || (random number < supp[ieab])
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 ) {
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
} else {
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
} else { // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 ) {
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
} else {
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 0:
|
||||
if( G4UniformRand() < 0.33 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
}
|
||||
} else { // target must be a neutron
|
||||
switch( np-nm )
|
||||
{
|
||||
case -1: // changed from +1 by JLC, 7Jul97
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
} else {
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
// 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: G4LEOmegaMinusInelastic.cc,v 2.4 1998/12/14 15:33:15 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: OmegaMinus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 20-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEOmegaMinusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEOmegaMinusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
|
||||
// create the target particle
|
||||
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
G4double targetMass = originalTarget->GetDefinition()->GetPDGMass();
|
||||
G4ReactionProduct targetParticle( originalTarget->GetDefinition() );
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEOmegaMinusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy() << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
G4ReactionProduct currentParticle( originalIncident->GetDefinition() );
|
||||
currentParticle.SetMomentum( originalIncident->GetMomentum() );
|
||||
currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() );
|
||||
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
|
||||
G4double ek = originalIncident->GetKineticEnergy();
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass();
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
// calculate black track energies
|
||||
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
G4ReactionProduct modifiedOriginal = currentParticle;
|
||||
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1*MeV;
|
||||
if( currentParticle.GetKineticEnergy() > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEOmegaMinusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASOM by H. Fesefeldt (31-Jan-1989)
|
||||
//
|
||||
// OmegaMinus undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass();
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy();
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum();
|
||||
const G4double targetMass = targetParticle.GetMass();
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass() )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.70 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aXiZero = G4XiZero::XiZero();
|
||||
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
// number of secondary mesons determined by kno distribution
|
||||
// check for total charge of final state mesons to determine
|
||||
// the kind of baryons to be produced, taking into account
|
||||
// charge and strangeness conservation
|
||||
//
|
||||
G4int nvefix = 0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
if( nm > np )
|
||||
{
|
||||
if( nm == np+1 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
nvefix = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
nvefix = 2;
|
||||
}
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else if( nm < np )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // target is a neutron
|
||||
{
|
||||
if( np+1 < nm )
|
||||
{
|
||||
if( nm == np+2 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
nvefix = 1;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
nvefix = 2;
|
||||
}
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else if( nm == np+1 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
for( G4int i=0; i<vecLen && nvefix>0; ++i )
|
||||
{
|
||||
if( vec[i]->GetDefinition() == aPiMinus )
|
||||
{
|
||||
if( nvefix >= 1 )vec[i]->SetDefinitionAndUpdateE( aKaonMinus );
|
||||
--nvefix;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
// 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: G4LEPionMinusInelastic.cc,v 2.4 1998/12/14 15:33:15 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: PionMinus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 19-Nov-1996
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEPionMinusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEPionMinusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
|
||||
// create the target particle
|
||||
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
G4double targetMass = originalTarget->GetDefinition()->GetPDGMass();
|
||||
G4ReactionProduct targetParticle( originalTarget->GetDefinition() );
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4PionMinusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy() << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
G4ReactionProduct currentParticle( originalIncident->GetDefinition() );
|
||||
currentParticle.SetMomentum( originalIncident->GetMomentum() );
|
||||
currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() );
|
||||
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
|
||||
G4double ek = originalIncident->GetKineticEnergy();
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass();
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
// calculate black track energies
|
||||
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
G4ReactionProduct modifiedOriginal = currentParticle;
|
||||
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1*MeV;
|
||||
if( currentParticle.GetKineticEnergy() > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEPionMinusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASPIM by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// pi- undergoes interaction with nucleon within nucleus.
|
||||
// Check if energetically possible to produce pions/kaons.
|
||||
// If not assume nuclear excitation occurs and input particle
|
||||
// is degraded in energy. No other particles produced.
|
||||
// If reaction is possible find correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data.
|
||||
// Replace some pions or protons/neutrons by kaons or strange baryons
|
||||
// according to average multiplicity per inelastic reactions.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass();
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy();
|
||||
const G4double pOriginal = originalIncident->GetTotalMomentum();
|
||||
const G4double targetMass = targetParticle.GetMass();
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionMinus::PionMinus()->GetPDGMass() )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.70 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
|
||||
G4int ieab = availableEnergy*5.0/GeV;
|
||||
const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98};
|
||||
G4double test, w0, wp, wt, wm;
|
||||
if( (availableEnergy<2.0*GeV) && (G4UniformRand()>=supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one pion will be produced
|
||||
|
||||
// charge exchange reaction is included in inelastic cross section
|
||||
|
||||
const G4double cech[] = {1.,0.95,0.79,0.32,0.19,0.16,0.14,0.12,0.10,0.08};
|
||||
G4int iplab = min( 9.0, pOriginal/GeV*5.0 );
|
||||
if( G4UniformRand() <= cech[iplab] )
|
||||
{
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero ); // charge exchange
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
nm = np = nz = 0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = 10.0*test;
|
||||
test = exp( min( expxu, max( expxl, -(-1.0+b[0])*(-1.0+b[0])/(2.0*c*c) ) ) );
|
||||
wm = test;
|
||||
wt = w0+wp+wm;
|
||||
wp += w0;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
nz = 1;
|
||||
else if( ran < wp/wt )
|
||||
np = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
else // target is a neutron
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
test = exp( min( expxu, max( expxl, -(-1.0+b[1])*(-1.0+b[1])/(2.0*c*c) ) ) );
|
||||
wm = test;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/(w0+wm) )
|
||||
nz = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); (nm<=(np+1)) && (ran>=excs); ++nm )
|
||||
{
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np )
|
||||
{
|
||||
for( nm=np; (nm<=(np+2)) && (ran>=excs); ++nm )
|
||||
{
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 0:
|
||||
if( G4UniformRand() >= 0.75 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case -1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
} else {
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
// 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: G4LEPionPlusInelastic.cc,v 2.4 1998/12/14 15:33:15 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: PionPlus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 19-Nov-1996
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEPionPlusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEPionPlusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
|
||||
// create the target particle
|
||||
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
G4double targetMass = originalTarget->GetDefinition()->GetPDGMass();
|
||||
G4ReactionProduct targetParticle( originalTarget->GetDefinition() );
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEPionPlusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy() << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
G4ReactionProduct currentParticle( originalIncident->GetDefinition() );
|
||||
currentParticle.SetMomentum( originalIncident->GetMomentum() );
|
||||
currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() );
|
||||
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
|
||||
G4double ek = originalIncident->GetKineticEnergy();
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass();
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
// calculate black track energies
|
||||
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
currentParticle.SetKineticEnergy( ek );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = currentParticle.GetMomentum().mag();
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = currentParticle.GetMomentum();
|
||||
currentParticle.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
|
||||
G4ReactionProduct modifiedOriginal = currentParticle;
|
||||
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1*MeV;
|
||||
if( currentParticle.GetKineticEnergy() > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEPionPlusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASPIP by H. Fesefeldt (18-Sep-1987)
|
||||
//
|
||||
// pi+ undergoes interaction with nucleon within nucleus.
|
||||
// Check if energetically possible to produce pions/kaons.
|
||||
// If not assume nuclear excitation occurs and input particle
|
||||
// is degraded in energy. No other particles produced.
|
||||
// If reaction is possible find correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data.
|
||||
// Replace some pions or protons/neutrons by kaons or strange baryons
|
||||
// according to average multiplicity per inelastic reactions.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass();
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy();
|
||||
const G4double targetMass = targetParticle.GetMass();
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass() )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.70 };
|
||||
if( first ) { // compute normalization constants, this will only be Done once
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np ) {
|
||||
for( nm=max(0,np-2); nm<=np; ++nm ) {
|
||||
for( nz=0; nz<numSec/3; ++nz ) {
|
||||
if( ++counter < numMul ) {
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 ) {
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np ) {
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm ) {
|
||||
for( nz=0; nz<numSec/3; ++nz ) {
|
||||
if( ++counter < numMul ) {
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) ) {
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i ) {
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
|
||||
G4int ieab = availableEnergy*5.0/GeV;
|
||||
const G4double supp[] = {0.,0.2,0.45,0.55,0.65,0.75,0.85,0.90,0.94,0.98};
|
||||
G4double test, w0, wp, wt, wm;
|
||||
if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one pion will be produced
|
||||
|
||||
nm = np = nz = 0;
|
||||
if( targetParticle.GetDefinition() == aProton ) {
|
||||
test = exp( min( expxu, max( expxl, -sqr(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test;
|
||||
if( G4UniformRand() < w0/(w0+wp) )
|
||||
nz =1;
|
||||
else
|
||||
np = 1;
|
||||
} else { // target is a neutron
|
||||
test = exp( min( expxu, max( expxl, -sqr(1.0+b[1])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test;
|
||||
test = exp( min( expxu, max( expxl, -sqr(-1.0+b[1])/(2.0*c*c) ) ) );
|
||||
wm = test;
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
nz = 1;
|
||||
else if( ran < wp/wt )
|
||||
np = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
} else {
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton ) {
|
||||
counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np ) {
|
||||
for( nm=max(0,np-2); (nm<=np) && (ran>=excs); ++nm ) {
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz ) {
|
||||
if( ++counter < numMul ) {
|
||||
nt = np+nm+nz;
|
||||
if( nt > 0 ) {
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 ) {
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
} else {
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return; // 3 previous loops continued to the end
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
} else { // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; (np<numSec/3) && (ran>=excs); ++np ) {
|
||||
for( nm=max(0,np-1); (nm<=(np+1)) && (ran>=excs); ++nm ) {
|
||||
for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz ) {
|
||||
if( ++counter < numMul ) {
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) ) {
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 ) {
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
} else {
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return; // 3 previous loops continued to the end
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aProton ) {
|
||||
switch( np-nm ) {
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 ) {
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
incidentHasChanged = true;
|
||||
} else {
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch( np-nm ) {
|
||||
case 0:
|
||||
if( G4UniformRand() < 0.25 ) {
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
currentParticle.SetDefinitionAndUpdateE( aPiZero );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,430 @@
|
||||
// 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: G4LEProtonInelastic.cc,v 2.9 1998/12/14 15:33:15 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Low Energy Proton Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 19-Nov-1996
|
||||
|
||||
#include "G4LEProtonInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEProtonInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEProtonInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
if( originalIncident->GetKineticEnergy()/GeV < 0.01+2.*G4UniformRand()/9. )
|
||||
{
|
||||
SlowProton( originalIncident, targetNucleus );
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
const G4double cutOff = 0.1;
|
||||
if( modifiedOriginal.GetKineticEnergy()/MeV <= cutOff )
|
||||
{
|
||||
SlowProton( originalIncident, targetNucleus );
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the sec. particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEProtonInelastic::SlowProton(
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
const G4double N = targetNucleus.GetN(); // atomic weight
|
||||
const G4double Z = targetNucleus.GetZ(); // atomic number
|
||||
G4double currentKinetic = originalIncident->GetKineticEnergy()/MeV;
|
||||
//
|
||||
// calculate Q-value of reactions
|
||||
//
|
||||
G4double theAtomicMass = targetNucleus.AtomicMass( N, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
G4double massVec[9];
|
||||
massVec[0] = targetNucleus.AtomicMass( N+1.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[1] = targetNucleus.AtomicMass( N , Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[2] = theAtomicMass;
|
||||
massVec[3] = targetNucleus.AtomicMass( N-1.0, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[4] = targetNucleus.AtomicMass( N-2.0, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[5] = targetNucleus.AtomicMass( N-3.0, Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[6] = targetNucleus.AtomicMass( N-1.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[7] = massVec[3];
|
||||
massVec[8] = targetNucleus.AtomicMass( N-1.0, Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
|
||||
G4FastVector<G4ReactionProduct,3> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
theReactionDynamics.NuclearReaction( vec, vecLen, originalIncident,
|
||||
targetNucleus, theAtomicMass, massVec );
|
||||
|
||||
theParticleChange.SetStatusChange( fStopAndKill );
|
||||
theParticleChange.SetEnergyChange( 0.0 );
|
||||
|
||||
theParticleChange.SetNumberOfSecondaries( vecLen );
|
||||
G4DynamicParticle *pd;
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
pd = new G4DynamicParticle();
|
||||
pd->SetDefinition( vec[i]->GetDefinition() );
|
||||
pd->SetMomentum( vec[i]->GetMomentum() );
|
||||
theParticleChange.AddSecondary( pd );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G4LEProtonInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int &vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASP by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// Proton undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
// the center of mass energy is based on the initial energy, before
|
||||
// Fermi motion and evaporation effects are taken into account
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{ // not energetically possible to produce pion(s)
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.35 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c) /
|
||||
( theReactionDynamics.Factorial(2-np+nm)*
|
||||
theReactionDynamics.Factorial(np-nm) );
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c) /
|
||||
( theReactionDynamics.Factorial(1-np+nm)*
|
||||
theReactionDynamics.Factorial(1+np-nm) );
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4int ieab = availableEnergy*5.0/GeV;
|
||||
const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98};
|
||||
G4double test, w0, wp, wt, wm;
|
||||
if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one pion will be produced
|
||||
|
||||
np = nm = nz = 0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
test = exp( min( expxu, max(
|
||||
expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) );
|
||||
w0 = test/2.0;
|
||||
wp = test;
|
||||
if( G4UniformRand() < w0/(w0+wp) )
|
||||
nz = 1;
|
||||
else
|
||||
np = 1;
|
||||
}
|
||||
else // target is a neutron
|
||||
{
|
||||
test = exp( min( expxu, max(
|
||||
expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) );
|
||||
w0 = test;
|
||||
wp = test/2.0;
|
||||
test = exp( min( expxu, max(
|
||||
expxl, -(-1.0+b[1])*(-1.0+b[1])/(2.0*c*c) ) ) );
|
||||
wm = test/2.0;
|
||||
wt = w0+wp+wm;
|
||||
wp += w0;
|
||||
G4double ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
nz = 1;
|
||||
else if( ran < wp/wt )
|
||||
np = 1;
|
||||
else
|
||||
nm = 1;
|
||||
}
|
||||
}
|
||||
else // (availableEnergy >= 2.0*GeV) || (random number < supp[ieab])
|
||||
{
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=np && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
} else {
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
} else {
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
}
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
} else {
|
||||
currentParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
currentParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target is a neutron
|
||||
{
|
||||
switch( np-nm )
|
||||
{
|
||||
case 0:
|
||||
if( G4UniformRand() < 0.333333 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
incidentHasChanged = true;
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
currentParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
default:
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
// 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: G4LESigmaMinusInelastic.cc,v 2.4 1998/12/14 15:33:15 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: SigmaMinus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 19-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LESigmaMinusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LESigmaMinusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LESigmaMinusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
if( originalIncident->GetKineticEnergy()/MeV > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LESigmaMinusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASSM by H. Fesefeldt (13-Sep-1987)
|
||||
//
|
||||
// SigmaMinus undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per Inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.70, 0.70 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aLambda = G4Lambda::Lambda();
|
||||
G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
|
||||
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = max( 1, np-nm+2 );
|
||||
switch( ncht )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
G4int ncht = max( 1, np-nm+3 );
|
||||
switch( ncht )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
// 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: G4LESigmaPlusInelastic.cc,v 2.4 1998/12/14 15:33:15 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: SigmaPlus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 19-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LESigmaPlusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LESigmaPlusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LESigmaPlusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
if( currentParticle.GetKineticEnergy()/MeV > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LESigmaPlusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASSP by H. Fesefeldt (30-Nov-1987)
|
||||
//
|
||||
// SigmaPlus undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aLambda = G4Lambda::Lambda();
|
||||
G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
|
||||
//
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
//
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
switch( min( 3, max( 1, np-nm+3 ) ) )
|
||||
{
|
||||
case 1:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
switch( min( 3, max( 1, np-nm+2 ) ) )
|
||||
{
|
||||
case 1:
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
break;
|
||||
case 2:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if( G4UniformRand() < 0.5 )
|
||||
currentParticle.SetDefinitionAndUpdateE( aLambda );
|
||||
else
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
|
||||
incidentHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
// 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: G4LETritonInelastic.cc,v 2.8 1998/12/14 15:33:16 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: Triton Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 25-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
|
||||
#include "G4LETritonInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LETritonInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LETritonInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
}
|
||||
|
||||
// Work-around for lack of model above 100 MeV
|
||||
if (originalIncident->GetKineticEnergy()/MeV > 100. ||
|
||||
originalIncident->GetKineticEnergy() <= 0.) return &theParticleChange;
|
||||
|
||||
G4double N = targetNucleus.GetN();
|
||||
G4double Z = targetNucleus.GetZ();
|
||||
G4double theAtomicMass = targetNucleus.AtomicMass( N, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
G4double massVec[9];
|
||||
massVec[0] = targetNucleus.AtomicMass( N+3.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[1] = targetNucleus.AtomicMass( N+2.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[2] = targetNucleus.AtomicMass( N+2.0, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[3] = targetNucleus.AtomicMass( N+1.0, Z )-(Z)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[4] = theAtomicMass;
|
||||
massVec[5] = targetNucleus.AtomicMass( N-1.0, Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[6] = targetNucleus.AtomicMass( N+1.0, Z+1.0 )-(Z+1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
massVec[7] = massVec[3];
|
||||
massVec[8] = targetNucleus.AtomicMass( N+1.0, Z-1.0 )-(Z-1.0)*G4Electron::Electron()->GetPDGMass();
|
||||
|
||||
G4FastVector<G4ReactionProduct,3> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
theReactionDynamics.NuclearReaction( vec, vecLen, originalIncident,
|
||||
targetNucleus, theAtomicMass, massVec );
|
||||
|
||||
G4double p = originalIncident->GetTotalMomentum();
|
||||
theParticleChange.SetMomentumChange( originalIncident->GetMomentum() * (1.0/p) );
|
||||
theParticleChange.SetEnergyChange( originalIncident->GetKineticEnergy() );
|
||||
|
||||
theParticleChange.SetNumberOfSecondaries( vecLen );
|
||||
G4DynamicParticle *pd;
|
||||
for( G4int i=0; i<vecLen; ++i )
|
||||
{
|
||||
pd = new G4DynamicParticle();
|
||||
pd->SetDefinition( vec[i]->GetDefinition() );
|
||||
pd->SetMomentum( vec[i]->GetMomentum() );
|
||||
theParticleChange.AddSecondary( pd );
|
||||
}
|
||||
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
// 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: G4LEXiMinusInelastic.cc,v 2.4 1998/12/14 15:33:16 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: XiMinus Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 20-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEXiMinusInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEXiMinusInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEXiMinusInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
if( currentParticle.GetKineticEnergy()/MeV > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEXiMinusInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASXM by H. Fesefeldt (17-Jan-1989)
|
||||
//
|
||||
// XiMinus undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aXiZero = G4XiZero::XiZero();
|
||||
//
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
//
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
//
|
||||
// number of secondary mesons determined by kno distribution
|
||||
// check for total charge of final state mesons to determine
|
||||
// the kind of baryons to be produced, taking into account
|
||||
// charge and strangeness conservation
|
||||
//
|
||||
if( np < nm )
|
||||
{
|
||||
if( np+1 == nm )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
else if( np == nm )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=np; nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
if( np+1 < nm )
|
||||
{
|
||||
if( np+2 == nm )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
else if( np+1 == nm )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiZero );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
// 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: G4LEXiZeroInelastic.cc,v 2.4 1998/12/14 15:33:16 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Hadronic Process: XiZero Inelastic Process
|
||||
// J.L. Chuma, TRIUMF, 20-Feb-1997
|
||||
// Last modified: 27-Mar-1997
|
||||
// Modified by J.L.Chuma 30-Apr-97: added originalTarget for CalculateMomenta
|
||||
|
||||
#include "G4LEXiZeroInelastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VParticleChange *
|
||||
G4LEXiZeroInelastic::ApplyYourself( const G4Track &aTrack,
|
||||
G4Nucleus &targetNucleus )
|
||||
{
|
||||
theParticleChange.Initialize( aTrack );
|
||||
|
||||
const G4DynamicParticle *originalIncident = aTrack.GetDynamicParticle();
|
||||
if (originalIncident->GetKineticEnergy()<= 0.1*MeV) return &theParticleChange;
|
||||
//
|
||||
// create the target particle
|
||||
//
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4Material *targetMaterial = aTrack.GetMaterial();
|
||||
G4cout << "G4LEXiZeroInelastic::ApplyYourself called" << endl;
|
||||
G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, ";
|
||||
G4cout << "target material = " << targetMaterial->GetName() << ", ";
|
||||
G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()
|
||||
<< endl;
|
||||
}
|
||||
//
|
||||
// Fermi motion and evaporation
|
||||
// As of Geant3, the Fermi energy calculation had not been Done
|
||||
//
|
||||
G4double ek = originalIncident->GetKineticEnergy()/MeV;
|
||||
G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4ReactionProduct modifiedOriginal;
|
||||
modifiedOriginal = *originalIncident;
|
||||
|
||||
G4double tkin = targetNucleus.Cinema( ek );
|
||||
ek += tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
G4double et = ek + amas;
|
||||
G4double p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
G4double pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
//
|
||||
// calculate black track energies
|
||||
//
|
||||
tkin = targetNucleus.EvaporationEffects( ek );
|
||||
ek -= tkin;
|
||||
modifiedOriginal.SetKineticEnergy( ek*MeV );
|
||||
et = ek + amas;
|
||||
p = sqrt( abs((et-amas)*(et+amas)) );
|
||||
pp = modifiedOriginal.GetMomentum().mag()/MeV;
|
||||
if( pp > 0.0 )
|
||||
{
|
||||
G4ThreeVector momentum = modifiedOriginal.GetMomentum();
|
||||
modifiedOriginal.SetMomentum( momentum * (p/pp) );
|
||||
}
|
||||
G4ReactionProduct currentParticle = modifiedOriginal;
|
||||
G4ReactionProduct targetParticle;
|
||||
targetParticle = *originalTarget;
|
||||
currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
|
||||
targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
|
||||
G4bool incidentHasChanged = false;
|
||||
G4bool targetHasChanged = false;
|
||||
G4bool quasiElastic = false;
|
||||
G4FastVector<G4ReactionProduct,128> vec; // vec will contain the secondary particles
|
||||
G4int vecLen = 0;
|
||||
vec.Initialize( 0 );
|
||||
|
||||
const G4double cutOff = 0.1;
|
||||
if( currentParticle.GetKineticEnergy()/MeV > cutOff )
|
||||
Cascade( vec, vecLen,
|
||||
originalIncident, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
CalculateMomenta( vec, vecLen,
|
||||
originalIncident, originalTarget, modifiedOriginal,
|
||||
targetNucleus, currentParticle, targetParticle,
|
||||
incidentHasChanged, targetHasChanged, quasiElastic );
|
||||
|
||||
SetUpChange( vec, vecLen,
|
||||
currentParticle, targetParticle,
|
||||
incidentHasChanged );
|
||||
|
||||
delete originalTarget;
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4LEXiZeroInelastic::Cascade(
|
||||
G4FastVector<G4ReactionProduct,128> &vec,
|
||||
G4int& vecLen,
|
||||
const G4DynamicParticle *originalIncident,
|
||||
G4ReactionProduct ¤tParticle,
|
||||
G4ReactionProduct &targetParticle,
|
||||
G4bool &incidentHasChanged,
|
||||
G4bool &targetHasChanged,
|
||||
G4bool &quasiElastic )
|
||||
{
|
||||
// derived from original FORTRAN code CASX0 by H. Fesefeldt (20-Jan-1989)
|
||||
//
|
||||
// XiZero undergoes interaction with nucleon within a nucleus. Check if it is
|
||||
// energetically possible to produce pions/kaons. In not, assume nuclear excitation
|
||||
// occurs and input particle is degraded in energy. No other particles are produced.
|
||||
// If reaction is possible, find the correct number of pions/protons/neutrons
|
||||
// produced using an interpolation to multiplicity data. Replace some pions or
|
||||
// protons/neutrons by kaons or strange baryons according to the average
|
||||
// multiplicity per inelastic reaction.
|
||||
//
|
||||
const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV;
|
||||
const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV;
|
||||
const G4double targetMass = targetParticle.GetMass()/MeV;
|
||||
G4double centerofmassEnergy = sqrt( mOriginal*mOriginal +
|
||||
targetMass*targetMass +
|
||||
2.0*targetMass*etOriginal );
|
||||
G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal);
|
||||
if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV )
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
static G4bool first = true;
|
||||
const G4int numMul = 1200;
|
||||
const G4int numSec = 60;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
G4int counter, nt=0, np=0, nm=0, nz=0;
|
||||
G4double test;
|
||||
const G4double c = 1.25;
|
||||
const G4double b[] = { 0.7, 0.7 };
|
||||
if( first ) // compute normalization constants, this will only be Done once
|
||||
{
|
||||
first = false;
|
||||
G4int i;
|
||||
for( i=0; i<numMul; ++i )protmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )protnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<(numSec/3); ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=(np+1); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c);
|
||||
protnorm[nt-1] += protmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMul; ++i )neutmul[i] = 0.0;
|
||||
for( i=0; i<numSec; ++i )neutnorm[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+2); ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c);
|
||||
neutnorm[nt-1] += neutmul[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; ++i )
|
||||
{
|
||||
if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i];
|
||||
if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
const G4double expxu = 82.; // upper bound for arg. of exp
|
||||
const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
|
||||
G4ParticleDefinition *aProton = G4Proton::Proton();
|
||||
G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
|
||||
G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
|
||||
G4ParticleDefinition *aXiMinus = G4XiMinus::XiMinus();
|
||||
//
|
||||
// energetically possible to produce pion(s) --> inelastic scattering
|
||||
//
|
||||
G4double n, anpn;
|
||||
GetNormalizationConstant( availableEnergy, n, anpn );
|
||||
G4double ran = G4UniformRand();
|
||||
G4double dum, excs = 0.0;
|
||||
if( targetParticle.GetDefinition() == aProton )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-2); nm<=(np+1) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
//
|
||||
// number of secondary mesons determined by kno distribution
|
||||
// check for total charge of final state mesons to determine
|
||||
// the kind of baryons to be produced, taking into account
|
||||
// charge and strangeness conservation
|
||||
//
|
||||
if( np < nm+1 )
|
||||
{
|
||||
if( np != nm ) // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
else if( np == nm+1 )
|
||||
{
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiMinus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aNeutron );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else // target must be a neutron
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3 && ran>=excs; ++np )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=(np+2) && ran>=excs; ++nm )
|
||||
{
|
||||
for( nz=0; nz<numSec/3 && ran>=excs; ++nz )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( nt>0 && nt<=numSec )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
{
|
||||
if( test >= 1.0e-10 )excs += dum*test;
|
||||
}
|
||||
else
|
||||
excs += dum*test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ran >= excs ) // 3 previous loops continued to the end
|
||||
{
|
||||
quasiElastic = true;
|
||||
return;
|
||||
}
|
||||
np--; nm--; nz--;
|
||||
if( np < nm )
|
||||
{
|
||||
if( np+1 == nm )
|
||||
{
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
else // charge mismatch
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
//
|
||||
// correct the strangeness by replacing a pi- by a kaon-
|
||||
//
|
||||
vec.Initialize( 1 );
|
||||
G4ReactionProduct *p = new G4ReactionProduct;
|
||||
p->SetDefinition( aKaonMinus );
|
||||
(G4UniformRand() < 0.5) ? p->SetSide( -1 ) : p->SetSide( 1 );
|
||||
vec.SetElement( vecLen++, p );
|
||||
--nm;
|
||||
}
|
||||
}
|
||||
else if( np == nm )
|
||||
{
|
||||
if( G4UniformRand() >= 0.5 )
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiMinus );
|
||||
incidentHasChanged = true;
|
||||
targetParticle.SetDefinitionAndUpdateE( aProton );
|
||||
targetHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentParticle.SetDefinitionAndUpdateE( aXiMinus );
|
||||
incidentHasChanged = true;
|
||||
}
|
||||
}
|
||||
SetUpPions( np, nm, nz, vec, vecLen );
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
// 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: G4LElastic.cc,v 2.4 1998/12/14 15:33:16 hpw Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Physics model class G4LElastic
|
||||
//
|
||||
//
|
||||
// G4 Model: Low-energy Elastic scattering
|
||||
// F.W. Jones, TRIUMF, 04-JUN-96
|
||||
//
|
||||
// use -scheme for elastic scattering: HPW, 20th June 1997
|
||||
// most of the code comes from the old Low-energy Elastic class
|
||||
//
|
||||
// 25-JUN-98 FWJ: replaced missing Initialize for ParticleChange.
|
||||
//
|
||||
|
||||
|
||||
#include "G4LElastic.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
|
||||
G4VParticleChange*
|
||||
G4LElastic::ApplyYourself(const G4Track& aTrack, G4Nucleus& targetNucleus)
|
||||
{
|
||||
theParticleChange.Initialize(aTrack);
|
||||
|
||||
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
|
||||
G4double Z = targetNucleus.GetZ();
|
||||
G4double atno2 = targetNucleus.GetN();
|
||||
|
||||
// Elastic scattering off Hydrogen
|
||||
|
||||
G4DynamicParticle* aSecondary = 0;
|
||||
if (atno2 < 1.5) {
|
||||
G4ParticleDefinition* aParticleType = aParticle->GetDefinition();
|
||||
if (aParticleType == G4PionPlus::PionPlus())
|
||||
aSecondary = LightMedia.PionPlusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4PionMinus::PionMinus())
|
||||
aSecondary = LightMedia.PionMinusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4KaonPlus::KaonPlus())
|
||||
aSecondary = LightMedia.KaonPlusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4KaonZeroShort::KaonZeroShort())
|
||||
aSecondary = LightMedia.KaonZeroShortExchange(aParticle,targetNucleus);
|
||||
else if (aParticleType == G4KaonZeroLong::KaonZeroLong())
|
||||
aSecondary = LightMedia.KaonZeroLongExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4KaonMinus::KaonMinus())
|
||||
aSecondary = LightMedia.KaonMinusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4Proton::Proton())
|
||||
aSecondary = LightMedia.ProtonExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4AntiProton::AntiProton())
|
||||
aSecondary = LightMedia.AntiProtonExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4Neutron::Neutron())
|
||||
aSecondary = LightMedia.NeutronExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4AntiNeutron::AntiNeutron())
|
||||
aSecondary = LightMedia.AntiNeutronExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4Lambda::Lambda())
|
||||
aSecondary = LightMedia.LambdaExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4AntiLambda::AntiLambda())
|
||||
aSecondary = LightMedia.AntiLambdaExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4SigmaPlus::SigmaPlus())
|
||||
aSecondary = LightMedia.SigmaPlusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4SigmaMinus::SigmaMinus())
|
||||
aSecondary = LightMedia.SigmaMinusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4AntiSigmaPlus::AntiSigmaPlus())
|
||||
aSecondary = LightMedia.AntiSigmaPlusExchange(aParticle,targetNucleus);
|
||||
else if (aParticleType == G4AntiSigmaMinus::AntiSigmaMinus())
|
||||
aSecondary= LightMedia.AntiSigmaMinusExchange(aParticle,targetNucleus);
|
||||
else if (aParticleType == G4XiZero::XiZero())
|
||||
aSecondary = LightMedia.XiZeroExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4XiMinus::XiMinus())
|
||||
aSecondary = LightMedia.XiMinusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4AntiXiZero::AntiXiZero())
|
||||
aSecondary = LightMedia.AntiXiZeroExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4AntiXiMinus::AntiXiMinus())
|
||||
aSecondary = LightMedia.AntiXiMinusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4OmegaMinus::OmegaMinus())
|
||||
aSecondary = LightMedia.OmegaMinusExchange(aParticle, targetNucleus);
|
||||
else if (aParticleType == G4AntiOmegaMinus::AntiOmegaMinus())
|
||||
aSecondary= LightMedia.AntiOmegaMinusExchange(aParticle,targetNucleus);
|
||||
else if (aParticleType == G4KaonPlus::KaonPlus())
|
||||
aSecondary = LightMedia.KaonPlusExchange(aParticle, targetNucleus);
|
||||
}
|
||||
|
||||
// Has a charge or strangeness exchange occurred?
|
||||
if (aSecondary) {
|
||||
aSecondary->SetMomentum(aParticle->GetMomentum());
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
theParticleChange.AddSecondary(aSecondary);
|
||||
}
|
||||
|
||||
G4double p = aParticle->GetTotalMomentum()/GeV;
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "G4LElastic::DoIt: Incident particle p=" << p << " GeV" << endl;
|
||||
|
||||
if (p < 0.01) return &theParticleChange;
|
||||
|
||||
// Compute the direction of elastic scattering.
|
||||
// It is planned to replace this code with a method based on
|
||||
// parameterized functions and a Monte Carlo method to invert the CDF.
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double aa, bb, cc, dd, rr;
|
||||
if (atno2 <= 62.) {
|
||||
aa = pow(atno2, 1.63);
|
||||
bb = 14.5*pow(atno2, 0.66);
|
||||
cc = 1.4*pow(atno2, 0.33);
|
||||
dd = 10.;
|
||||
}
|
||||
else {
|
||||
aa = pow(atno2, 1.33);
|
||||
bb = 60.*pow(atno2, 0.33);
|
||||
cc = 0.4*pow(atno2, 0.40);
|
||||
dd = 10.;
|
||||
}
|
||||
aa = aa/bb;
|
||||
cc = cc/dd;
|
||||
rr = (aa + cc)*ran;
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "DoIt: aa,bb,cc,dd,rr" << endl;
|
||||
G4cout << aa << " " << bb << " " << cc << " " << dd << " " << rr << endl;
|
||||
}
|
||||
G4double t1 = -log(ran)/bb;
|
||||
G4double t2 = -log(ran)/dd;
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "log(FLT_MAX)=" << log(FLT_MAX) << endl;
|
||||
G4cout << "t1,Fctcos " << t1 << " " << Fctcos(t1, aa, bb, cc, dd, rr) <<
|
||||
endl;
|
||||
G4cout << "t2,Fctcos " << t2 << " " << Fctcos(t2, aa, bb, cc, dd, rr) <<
|
||||
endl;
|
||||
}
|
||||
G4double eps = 0.001;
|
||||
G4int ind1 = 10;
|
||||
G4double t, val;
|
||||
G4int ier1;
|
||||
ier1 = Rtmi(&t, t1, t2, eps, ind1,
|
||||
aa, bb, cc, dd, rr);
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "From Rtmi, ier1=" << ier1 << endl;
|
||||
G4cout << "t, Fctcos " << t << " " << Fctcos(t, aa, bb, cc, dd, rr) <<
|
||||
endl;
|
||||
}
|
||||
if (ier1 != 0) t = 0.25*(3.*t1 + t2);
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "t, Fctcos " << t << " " << Fctcos(t, aa, bb, cc, dd, rr) <<
|
||||
endl;
|
||||
}
|
||||
G4double phi = G4UniformRand()*twopi;
|
||||
rr = 0.5*t/(p*p);
|
||||
if (rr > 1.) rr = 0.;
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "rr=" << rr << endl;
|
||||
G4double cost = 1. - rr;
|
||||
G4double sint = sqrt(max(rr*(2. - rr), 0.));
|
||||
if (sint == 0.) return &theParticleChange;
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "cos(t)=" << cost << " sin(t)=" << sint << endl;
|
||||
// Scattered particle referred to axis of incident particle
|
||||
G4double px = p*sint*sin(phi);
|
||||
G4double py = p*sint*cos(phi);
|
||||
G4double pz = p*cost;
|
||||
// Incident particle
|
||||
G4double pxinc = p*(aParticle->GetMomentumDirection().x());
|
||||
G4double pyinc = p*(aParticle->GetMomentumDirection().y());
|
||||
G4double pzinc = p*(aParticle->GetMomentumDirection().z());
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "NOM SCAT " << px << " " << py << " " << pz << endl;
|
||||
G4cout << "INCIDENT " << pxinc << " " << pyinc << " " << pzinc << endl;
|
||||
}
|
||||
|
||||
// Transform scattered particle to reflect direction of incident particle
|
||||
G4double pxnew, pynew, pznew;
|
||||
Defs1(p, px, py, pz, pxinc, pyinc, pzinc, &pxnew, &pynew, &pznew);
|
||||
// Normalize:
|
||||
pxnew = pxnew/p;
|
||||
pynew = pynew/p;
|
||||
pznew = pznew/p;
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "DoIt: returning new momentum vector" << endl;
|
||||
G4cout << pxnew << " " << pynew << " " << pznew << endl;
|
||||
}
|
||||
|
||||
if (aSecondary)
|
||||
aSecondary->SetMomentumDirection(pxnew, pynew, pznew);
|
||||
else
|
||||
theParticleChange.SetMomentumChange(pxnew, pynew, pznew);
|
||||
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
|
||||
// The following is a "translation" of a root-finding routine
|
||||
// from GEANT3.21/GHEISHA. Some of the labelled block structure has
|
||||
// been retained for clarity. This routine will not be needed after
|
||||
// the planned revisions to DoIt().
|
||||
|
||||
G4int
|
||||
G4LElastic::Rtmi(G4double* x, G4double xli, G4double xri, G4double eps,
|
||||
G4int iend,
|
||||
G4double aa, G4double bb, G4double cc, G4double dd,
|
||||
G4double rr)
|
||||
{
|
||||
G4int ier = 0;
|
||||
G4double xl = xli;
|
||||
G4double xr = xri;
|
||||
*x = xl;
|
||||
G4double tol = *x;
|
||||
G4double f = Fctcos(tol, aa, bb, cc, dd, rr);
|
||||
if (f == 0.) return ier;
|
||||
G4double fl, fr;
|
||||
fl = f;
|
||||
*x = xr;
|
||||
tol = *x;
|
||||
f = Fctcos(tol, aa, bb, cc, dd, rr);
|
||||
if (f == 0.) return ier;
|
||||
fr = f;
|
||||
|
||||
// Error return in case of wrong input data
|
||||
if (fl*fr >= 0.) {
|
||||
ier = 2;
|
||||
return ier;
|
||||
}
|
||||
|
||||
// Basic assumption fl*fr less than 0 is satisfied.
|
||||
// Generate tolerance for function values.
|
||||
G4int i = 0;
|
||||
G4double tolf = 100.*eps;
|
||||
|
||||
// Start iteration loop
|
||||
label4:
|
||||
i++;
|
||||
|
||||
// Start bisection loop
|
||||
for (G4int k = 1; k <= iend; k++) {
|
||||
*x = 0.5*(xl + xr);
|
||||
tol = *x;
|
||||
f = Fctcos(tol, aa, bb, cc, dd, rr);
|
||||
if (f == 0.) return 0;
|
||||
if (f*fr < 0.) { // Interchange xl and xr in order to get the
|
||||
tol = xl; // same Sign in f and fr
|
||||
xl = xr;
|
||||
xr = tol;
|
||||
tol = fl;
|
||||
fl = fr;
|
||||
fr = tol;
|
||||
}
|
||||
tol = f - fl;
|
||||
G4double a = f*tol;
|
||||
a = a + a;
|
||||
if (a < fr*(fr - fl) && i <= iend) goto label17;
|
||||
xr = *x;
|
||||
fr = f;
|
||||
|
||||
// Test on satisfactory accuracy in bisection loop
|
||||
tol = eps;
|
||||
a = abs(xr);
|
||||
if (a > 1.) tol = tol*a;
|
||||
if (abs(xr - xl) <= tol && abs(fr - fl) <= tolf) goto label14;
|
||||
}
|
||||
// End of bisection loop
|
||||
|
||||
// No convergence after iend iteration steps followed by iend
|
||||
// successive steps of bisection or steadily increasing function
|
||||
// values at right bounds. Error return.
|
||||
ier = 1;
|
||||
|
||||
label14:
|
||||
if (abs(fr) > abs(fl)) {
|
||||
*x = xl;
|
||||
f = fl;
|
||||
}
|
||||
return ier;
|
||||
|
||||
// Computation of iterated x-value by inverse parabolic interp
|
||||
label17:
|
||||
G4double a = fr - f;
|
||||
G4double dx = (*x - xl)*fl*(1. + f*(a - tol)/(a*(fr - fl)))/tol;
|
||||
G4double xm = *x;
|
||||
G4double fm = f;
|
||||
*x = xl - dx;
|
||||
tol = *x;
|
||||
f = Fctcos(tol, aa, bb, cc, dd, rr);
|
||||
if (f == 0.) return ier;
|
||||
|
||||
// Test on satisfactory accuracy in iteration loop
|
||||
tol = eps;
|
||||
a = abs(*x);
|
||||
if (a > 1) tol = tol*a;
|
||||
if (abs(dx) <= tol && abs(f) <= tolf) return ier;
|
||||
|
||||
// Preparation of next bisection loop
|
||||
if (f*fl < 0.) {
|
||||
xr = *x;
|
||||
fr = f;
|
||||
}
|
||||
else {
|
||||
xl = *x;
|
||||
fl = f;
|
||||
xr = xm;
|
||||
fr = fm;
|
||||
}
|
||||
goto label4;
|
||||
}
|
||||
|
||||
|
||||
// Test function for root-finder
|
||||
|
||||
G4double
|
||||
G4LElastic::Fctcos(G4double t,
|
||||
G4double aa, G4double bb, G4double cc, G4double dd,
|
||||
G4double rr)
|
||||
{
|
||||
const G4double expxl = -82.;
|
||||
const G4double expxu = 82.;
|
||||
|
||||
G4double test1 = -bb*t;
|
||||
if (test1 > expxu) test1 = expxu;
|
||||
if (test1 < expxl) test1 = expxl;
|
||||
|
||||
G4double test2 = -dd*t;
|
||||
if (test2 > expxu) test2 = expxu;
|
||||
if (test2 < expxl) test2 = expxl;
|
||||
|
||||
return aa*exp(test1) + cc*exp(test2) - rr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
G4LElastic::Defs1(G4double p, G4double px, G4double py, G4double pz,
|
||||
G4double pxinc, G4double pyinc, G4double pzinc,
|
||||
G4double* pxnew, G4double* pynew, G4double* pznew)
|
||||
{
|
||||
// Transform scattered particle to reflect direction of incident particle
|
||||
G4double pt2 = pxinc*pxinc + pyinc*pyinc;
|
||||
if (pt2 > 0.) {
|
||||
G4double cost = pzinc/p;
|
||||
G4double sint1 = sqrt(abs((1. - cost )*(1.+cost)));
|
||||
G4double sint2 = sqrt(pt2)/p;
|
||||
G4double sint = 0.5*(sint1 + sint2);
|
||||
G4double ph = pi*0.5;
|
||||
if (pyinc < 0.) ph = pi*1.5;
|
||||
if (abs(pxinc) > 1.e-6) ph = atan2(pyinc, pxinc);
|
||||
G4double cosp = cos(ph);
|
||||
G4double sinp = sin(ph);
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "cost sint " << cost << " " << sint << endl;
|
||||
G4cout << "cosp sinp " << cosp << " " << sinp << endl;
|
||||
}
|
||||
*pxnew = cost*cosp*px - sinp*py + sint*cosp*pz;
|
||||
*pynew = cost*sinp*px + cosp*py + sint*sinp*pz;
|
||||
*pznew = -sint*px +cost*pz;
|
||||
}
|
||||
else {
|
||||
*pxnew = px;
|
||||
*pynew = py;
|
||||
*pznew = pz;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
// 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: G4LFission.cc,v 2.3 1998/07/13 17:24:44 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// G4 Model: Low Energy Fission
|
||||
// F.W. Jones, TRIUMF, 03-DEC-96
|
||||
//
|
||||
// This is a prototype of a low-energy fission process.
|
||||
// Currently it is based on the GHEISHA routine FISSIO,
|
||||
// and conforms fairly closely to the original Fortran.
|
||||
// Note: energy is in MeV and momentum is in MeV/c.
|
||||
//
|
||||
// use -scheme for elastic scattering: HPW, 20th June 1997
|
||||
// the code comes mostly from the old Low-energy Fission class
|
||||
//
|
||||
// 25-JUN-98 FWJ: replaced missing Initialize for ParticleChange.
|
||||
//
|
||||
|
||||
|
||||
#include "G4LFission.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4LFission::G4LFission() :
|
||||
G4HadronicInteraction()
|
||||
{
|
||||
init();
|
||||
theParticleChange.SetNumberOfSecondaries(1000);
|
||||
|
||||
SetMinEnergy( 0.0*GeV );
|
||||
SetMaxEnergy( DBL_MAX );
|
||||
|
||||
}
|
||||
|
||||
G4LFission::~G4LFission()
|
||||
{
|
||||
theParticleChange.Clear();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
G4LFission::init()
|
||||
{
|
||||
G4int i;
|
||||
G4double xx = 1. - 0.5;
|
||||
G4double xxx = sqrt(2.29*xx);
|
||||
spneut[0] = exp(-xx/0.965)*(exp(xxx) - exp(-xxx))/2.;
|
||||
for (i = 2; i <= 10; i++) {
|
||||
xx = i*1. - 0.5;
|
||||
xxx = sqrt(2.29*xx);
|
||||
spneut[i-1] = spneut[i-2] + exp(-xx/0.965)*(exp(xxx) - exp(-xxx))/2.;
|
||||
}
|
||||
for (i = 1; i <= 10; i++) {
|
||||
spneut[i-1] = spneut[i-1]/spneut[9];
|
||||
if (verboseLevel > 1) G4cout << "G4LFission::init: i=" << i <<
|
||||
" spneut=" << spneut[i-1] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange*
|
||||
G4LFission::ApplyYourself(const G4Track & aTrack,G4Nucleus & targetNucleus)
|
||||
{
|
||||
theParticleChange.Initialize(aTrack);
|
||||
|
||||
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
|
||||
const G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
G4double N = targetNucleus.GetN();
|
||||
G4double Z = targetNucleus.GetZ();
|
||||
// theParticleChange.SetKillSignal(1);
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
|
||||
G4double P = aParticle->GetTotalMomentum()/MeV;
|
||||
G4double Px = P*(aParticle->GetMomentumDirection().x());
|
||||
G4double Py = P*(aParticle->GetMomentumDirection().y());
|
||||
G4double Pz = P*(aParticle->GetMomentumDirection().z());
|
||||
G4double E = aParticle->GetTotalEnergy()/MeV;
|
||||
G4double E0 = aParticle->GetDefinition()->GetPDGMass()/MeV;
|
||||
G4double Q = aParticle->GetDefinition()->GetPDGCharge();
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4LFission:ApplyYourself: incident particle:" << endl;
|
||||
G4cout << "P " << P << " MeV/c" << endl;
|
||||
G4cout << "Px " << Px << " MeV/c" << endl;
|
||||
G4cout << "Py " << Py << " MeV/c" << endl;
|
||||
G4cout << "Pz " << Pz << " MeV/c" << endl;
|
||||
G4cout << "E " << E << " MeV" << endl;
|
||||
G4cout << "mass " << E0 << " MeV" << endl;
|
||||
G4cout << "charge " << Q << endl;
|
||||
}
|
||||
// GHEISHA ADD operation to get total energy, mass, charge:
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4LFission:ApplyYourself: material:" << endl;
|
||||
G4cout << "A " << N << endl;
|
||||
G4cout << "Z " << Z << endl;
|
||||
G4cout << "atomic mass " <<
|
||||
Atomas(N, Z) << "MeV" << endl;
|
||||
}
|
||||
E = E + Atomas(N, Z);
|
||||
G4double E02 = E*E - P*P;
|
||||
E0 = sqrt(abs(E02));
|
||||
if (E02 < 0) E0 = -E0;
|
||||
Q = Q + Z;
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "G4LFission:ApplyYourself: total:" << endl;
|
||||
G4cout << "E " << E << " MeV" << endl;
|
||||
G4cout << "mass " << E0 << " MeV" << endl;
|
||||
G4cout << "charge " << Q << endl;
|
||||
}
|
||||
Px = -Px;
|
||||
Py = -Py;
|
||||
Pz = -Pz;
|
||||
|
||||
G4double e1 = aParticle->GetKineticEnergy()/MeV;
|
||||
if (e1 < 1.) e1 = 1.;
|
||||
|
||||
// Average number of neutrons
|
||||
G4double avern = 2.569 + 0.559*log(e1);
|
||||
G4bool photofission = 0; // For now
|
||||
// Take the following value if photofission is not included
|
||||
if (!photofission) avern = 2.569 + 0.900*log(e1);
|
||||
|
||||
// Average number of gammas
|
||||
G4double averg = 9.500 + 0.600*log(e1);
|
||||
|
||||
G4double ran = RandGauss::shoot();
|
||||
// Number of neutrons
|
||||
G4int nn = avern + ran*1.23 + 0.5;
|
||||
ran = RandGauss::shoot();
|
||||
// Number of gammas
|
||||
G4int ng = averg + ran*3. + 0.5;
|
||||
if (nn < 1) nn = 1;
|
||||
if (ng < 1) ng = 1;
|
||||
G4double exn = 0.;
|
||||
G4double exg = 0.;
|
||||
|
||||
// Make secondary neutrons and distribute kinetic energy
|
||||
G4DynamicParticle* aNeutron;
|
||||
G4int i;
|
||||
for (i = 1; i <= nn; i++) {
|
||||
ran = G4UniformRand();
|
||||
G4int j;
|
||||
for (j = 1; j <= 10; j++) {
|
||||
if (ran < spneut[j-1]) goto label12;
|
||||
}
|
||||
j = 10;
|
||||
label12:
|
||||
ran = G4UniformRand();
|
||||
G4double ekin = (j - 1)*1. + ran;
|
||||
exn = exn + ekin;
|
||||
aNeutron = new G4DynamicParticle(G4Neutron::NeutronDefinition(),
|
||||
G4ParticleMomentum(1.,0.,0.),
|
||||
ekin*MeV);
|
||||
theParticleChange.AddSecondary(aNeutron);
|
||||
}
|
||||
|
||||
// Make secondary gammas and distribute kinetic energy
|
||||
G4DynamicParticle* aGamma;
|
||||
for (i = 1; i <= ng; i++) {
|
||||
ran = G4UniformRand();
|
||||
G4double ekin = -0.87*log(ran);
|
||||
exg = exg + ekin;
|
||||
aGamma = new G4DynamicParticle(G4Gamma::GammaDefinition(),
|
||||
G4ParticleMomentum(1.,0.,0.),
|
||||
ekin*MeV);
|
||||
theParticleChange.AddSecondary(aGamma);
|
||||
}
|
||||
|
||||
G4double ex = exn + exg;
|
||||
|
||||
// Distribute momentum vectors and do Lorentz transformation
|
||||
|
||||
G4Track* theSecondary;
|
||||
|
||||
for (i = 1; i <= nn + ng; i++) {
|
||||
G4double ran1 = G4UniformRand();
|
||||
G4double ran2 = G4UniformRand();
|
||||
G4double cost = -1. + 2.*ran1;
|
||||
G4double sint = sqrt(abs(1. - cost*cost));
|
||||
G4double phi = ran2*twopi;
|
||||
// G4cout << ran1 << " " << ran2 << endl;
|
||||
// G4cout << cost << " " << sint << " " << phi << endl;
|
||||
theSecondary = theParticleChange.GetSecondary(i - 1);
|
||||
G4double pp = theSecondary->GetDynamicParticle()->GetTotalMomentum()/MeV;
|
||||
G4double px = pp*sint*sin(phi);
|
||||
G4double py = pp*sint*cos(phi);
|
||||
G4double pz = pp*cost;
|
||||
// G4cout << pp << endl;
|
||||
// G4cout << px << " " << py << " " << pz << endl;
|
||||
G4double e = theSecondary->GetTotalEnergy()/MeV;
|
||||
G4double e0 = theSecondary->GetDefinition()->GetPDGMass()/MeV;
|
||||
|
||||
G4double a = px*Px + py*Py + pz*Pz;
|
||||
a = (a/(E + E0) - e)/E0;
|
||||
|
||||
px = px + a*Px;
|
||||
py = py + a*Py;
|
||||
pz = pz + a*Pz;
|
||||
G4double p2 = px*px + py*py + pz*pz;
|
||||
pp = sqrt(p2);
|
||||
e = sqrt(e0*e0 + p2);
|
||||
G4double ekin = e - theSecondary->GetDefinition()->GetPDGMass()/MeV;
|
||||
theSecondary->SetMomentumDirection(G4ParticleMomentum(px/pp,
|
||||
py/pp,
|
||||
pz/pp));
|
||||
theSecondary->SetKineticEnergy(ekin*MeV);
|
||||
}
|
||||
|
||||
return &theParticleChange;
|
||||
}
|
||||
|
||||
// Computes atomic mass in MeV (translation of GHEISHA routine ATOMAS)
|
||||
// Not optimized: conforms closely to original Fortran.
|
||||
|
||||
G4double
|
||||
G4LFission::Atomas(const G4double A, const G4double Z)
|
||||
{
|
||||
G4double rmel = G4Electron::ElectronDefinition()->GetPDGMass()/MeV;
|
||||
G4double rmp = G4Proton::ProtonDefinition()->GetPDGMass()/MeV;
|
||||
G4double rmn = G4Neutron::NeutronDefinition()->GetPDGMass()/MeV;
|
||||
G4double rmd = G4Deuteron::DeuteronDefinition()->GetPDGMass()/MeV;
|
||||
G4double rma = G4Alpha::AlphaDefinition()->GetPDGMass()/MeV;
|
||||
|
||||
G4int ia = A + 0.5;
|
||||
if (ia < 1) return 0;
|
||||
G4int iz = Z + 0.5;
|
||||
if (iz < 0) return 0;
|
||||
if (iz > ia) return 0;
|
||||
|
||||
if (ia == 1) {
|
||||
if (iz == 0) return rmn; //neutron
|
||||
if (iz == 1) return rmp + rmel; //Hydrogen
|
||||
}
|
||||
else if (ia == 2 && iz == 1) {
|
||||
return rmd; //Deuteron
|
||||
}
|
||||
else if (ia == 4 && iz == 2) {
|
||||
return rma; //Alpha
|
||||
}
|
||||
|
||||
G4double mass = (A - Z)*rmn + Z*rmp + Z*rmel
|
||||
- 15.67*A
|
||||
+ 17.23*pow(A, 2./3.)
|
||||
+ 93.15*(A/2. - Z)*(A/2. - Z)/A
|
||||
+ 0.6984523*Z*Z/pow(A, 1./3.);
|
||||
G4int ipp = (ia - iz)%2;
|
||||
G4int izz = iz%2;
|
||||
if (ipp == izz) mass = mass + (ipp + izz -1)*12.*pow(A, -0.5);
|
||||
|
||||
return mass;
|
||||
}
|
||||
Reference in New Issue
Block a user