Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# $Id: GNUmakefile,v 2.0 1998/07/02 16:27:15 gunter Exp $
|
||||
# -----------------------------------------------------------
|
||||
# GNUmakefile for hadronic library. Gabriele Cosmo, 18/9/96.
|
||||
# -----------------------------------------------------------
|
||||
|
||||
name := G4hadronic_HE
|
||||
|
||||
ifndef G4INSTALL
|
||||
G4INSTALL = ../../../../..
|
||||
endif
|
||||
|
||||
include $(G4INSTALL)/config/architecture.gmk
|
||||
|
||||
G4TMPDIR = $(G4TMP)/$(G4SYSTEM)/$(name)
|
||||
|
||||
CPPFLAGS += -I$(G4BASE)/global/management/include \
|
||||
-I$(G4BASE)/global/HEPRandom/include \
|
||||
-I$(G4BASE)/global/HEPGeometry/include \
|
||||
-I$(G4BASE)/track/include \
|
||||
-I$(G4BASE)/geometry/volumes/include \
|
||||
-I$(G4BASE)/geometry/management/include \
|
||||
-I$(G4BASE)/processes/management/include \
|
||||
-I$(G4BASE)/processes/hadronic/management/include/ \
|
||||
-I$(G4BASE)/processes/hadronic/util/include \
|
||||
-I$(G4BASE)/particles/management/include \
|
||||
-I$(G4BASE)/particles/leptons/include \
|
||||
-I$(G4BASE)/particles/bosons/include \
|
||||
-I$(G4BASE)/particles/hadrons/mesons/include \
|
||||
-I$(G4BASE)/particles/hadrons/barions/include \
|
||||
-I$(G4BASE)/particles/hadrons/ions/include \
|
||||
-I$(G4BASE)/materials/include
|
||||
|
||||
include $(G4INSTALL)/config/common.gmk
|
||||
|
||||
# Temporary fix for HP-CC compiler. It cannot handle full optimisation for
|
||||
# the specified files ...
|
||||
|
||||
ifneq (,$(findstring HP,$(G4SYSTEM)))
|
||||
CXXFLAGS_WITHOUT_O := $(filter-out +O% , $(CXXFLAGS))
|
||||
|
||||
$(G4TMPDIR)/G4GHEInelastic.o: src/G4GHEInelastic.cc
|
||||
$(CXX) $(CXXFLAGS_WITHOUT_O) $(CPPFLAGS) -c -o $@ src/G4GHEInelastic.cc
|
||||
|
||||
$(G4TMPDIR)/G4GHEInelasticModel.o: src/G4GHEInelasticModel.cc
|
||||
$(CXX) $(CXXFLAGS_WITHOUT_O) $(CPPFLAGS) -c -o $@ src/G4GHEInelasticModel.cc
|
||||
endif
|
||||
@@ -0,0 +1,39 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiKaonZeroInelastic_h
|
||||
#define G4HEAntiKaonZeroInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiKaonZeroInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiKaonZeroInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiKaonZeroInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiKaonZero(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiLambdaInelastic_h
|
||||
#define G4HEAntiLambdaInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiLambdaInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiLambdaInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiLambdaInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiLambda(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiNeutronInelastic_h
|
||||
#define G4HEAntiNeutronInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiNeutronInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiNeutronInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiNeutronInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiNeutron(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiOmegaMinusInelastic_h
|
||||
#define G4HEAntiOmegaMinusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiOmegaMinusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiOmegaMinusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiOmegaMinusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiOmegaMinus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiProtonInelastic_h
|
||||
#define G4HEAntiProtonInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiProtonInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiProtonInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiProtonInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiProton(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiSigmaMinusInelastic_h
|
||||
#define G4HEAntiSigmaMinusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiSigmaMinusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiSigmaMinusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiSigmaMinusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiSigmaMinus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiSigmaPlusInelastic_h
|
||||
#define G4HEAntiSigmaPlusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiSigmaPlusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiSigmaPlusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiSigmaPlusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiSigmaPlus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiSigmaZeroInelastic_h
|
||||
#define G4HEAntiSigmaZeroInelastic_h 1
|
||||
|
||||
#include "G4HEAntiLambdaInelastic.hh"
|
||||
|
||||
class G4HEAntiSigmaZeroInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiSigmaZeroInelastic() : G4HEInelastic()
|
||||
{
|
||||
}
|
||||
|
||||
~G4HEAntiSigmaZeroInelastic(){ };
|
||||
|
||||
G4int verboseLevel;
|
||||
G4int MAXPART;
|
||||
G4int vecLength;
|
||||
|
||||
void SetMaxNumberOfSecondaries(G4int maxnumber)
|
||||
{ MAXPART = maxnumber; };
|
||||
void SetVerboseLevel(G4int verbose)
|
||||
{ verboseLevel = verbose;};
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiXiMinusInelastic_h
|
||||
#define G4HEAntiXiMinusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiXiMinusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiXiMinusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiXiMinusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiXiMinus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEAntiXiZeroInelastic_h
|
||||
#define G4HEAntiXiZeroInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEAntiXiZeroInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEAntiXiZeroInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEAntiXiZeroInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasAntiXiZero(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
// G4 Gheisha High Energy (GHE) model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
// It includes all Physics Routines from Geant3,
|
||||
// relevant for simulation of hadronic processes
|
||||
// above approx. 20 GeV incident momentum.
|
||||
// Not included are the Physics Routines for
|
||||
// stopping particles, the low energy neutron
|
||||
// slowing down description and the low energy
|
||||
// nuclear reactions a(A,A')b.
|
||||
// All routines pass the compiler and give
|
||||
// some reasonable numbers as output.
|
||||
// A statistically significant comparison
|
||||
// with GEANT3 and experimental data has
|
||||
// still to be done.
|
||||
|
||||
#ifndef G4HEInelastic_h
|
||||
#define G4HEInelastic_h 1
|
||||
|
||||
#include "G4HEVector.hh"
|
||||
#include "G4HadronicInteraction.hh"
|
||||
|
||||
class G4HEInelastic : public G4HadronicInteraction
|
||||
{
|
||||
public:
|
||||
G4HEInelastic()
|
||||
{
|
||||
SetMinEnergy(20*GeV);
|
||||
SetMaxEnergy(10*TeV);
|
||||
MAXPART = 512;
|
||||
verboseLevel = 0;
|
||||
SetParticles();
|
||||
};
|
||||
~G4HEInelastic(){ };
|
||||
|
||||
void SetMaxNumberOfSecondaries( const G4int maxnumber )
|
||||
{ MAXPART = maxnumber;}
|
||||
|
||||
void SetVerboseLevel( const G4int level)
|
||||
{ verboseLevel = level;}
|
||||
|
||||
G4int verboseLevel;
|
||||
G4int MAXPART;
|
||||
|
||||
void FillParticleChange(G4HEVector pv[], G4int aVecLength);
|
||||
|
||||
G4double pmltpc(G4int np, G4int nm, G4int nz, G4int n, G4double b, G4double c);
|
||||
|
||||
G4int Factorial(G4int n);
|
||||
|
||||
G4double NuclearInelasticity(G4double incidentKineticEnergy,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber);
|
||||
G4double NuclearExcitation(G4double incidentKineticEnergy,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber,
|
||||
G4double& excitationEnergyCascade,
|
||||
G4double& excitationEnergyEvaporation);
|
||||
|
||||
void HighEnergyCascading(G4bool &successful,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4double &excitationEnergyGNP,
|
||||
G4double &excitationEnergyDTA,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber);
|
||||
|
||||
void HighEnergyClusterProduction(G4bool &successful,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4double &excitationEnergyGNP,
|
||||
G4double &excitationEnergyDTA,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber);
|
||||
|
||||
void TuningOfHighEnergyCascading( G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber);
|
||||
|
||||
void MediumEnergyCascading(G4bool &successful,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4double &excitationEnergyGNP,
|
||||
G4double &excitationEnergyDTA,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber);
|
||||
|
||||
void MediumEnergyClusterProduction(G4bool &successful,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4double &excitationEnergyGNP,
|
||||
G4double &excitationEnergyDTA,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber);
|
||||
|
||||
void QuasiElasticScattering(G4bool &successful,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4double &excitationEnergyGNP,
|
||||
G4double &excitationEnergyDTA,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber);
|
||||
|
||||
void ElasticScattering(G4bool &successful,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4double atomicWeight,
|
||||
G4double atomicNumber);
|
||||
|
||||
G4int rtmi(G4double *x, G4double xli, G4double xri, G4double eps,
|
||||
G4int iend,
|
||||
G4double aa, G4double bb, G4double cc, G4double dd, G4double rr);
|
||||
G4double fctcos(G4double t, G4double aa, G4double bb,G4double cc, G4double dd,
|
||||
G4double rr);
|
||||
|
||||
void StrangeParticlePairProduction(const G4double availableEnergy,
|
||||
const G4double centerOfMassEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle);
|
||||
|
||||
G4double NBodyPhaseSpace(const G4double totalEnergy,
|
||||
const G4bool constantCrossSection,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen);
|
||||
G4double NBodyPhaseSpace(G4int npart,
|
||||
G4HEVector pv[],
|
||||
G4double wmax,
|
||||
G4double wfcn,
|
||||
G4int maxtrial,
|
||||
G4int ntrial);
|
||||
|
||||
G4double gpdk(G4double a, G4double b, G4double c);
|
||||
void QuickSort(G4double arr[], const G4int lidx, const G4int ridx);
|
||||
G4double Alam(G4double a, G4double b, G4double c);
|
||||
G4double CalculatePhaseSpaceWeight( G4int npart);
|
||||
|
||||
G4double normal(void);
|
||||
G4double GammaRand(G4double avalue);
|
||||
G4double Erlang(G4int mvalue);
|
||||
G4int Poisson(G4double x);
|
||||
void SetParticles(void);
|
||||
|
||||
G4HEVector PionPlus;
|
||||
G4HEVector PionZero;
|
||||
G4HEVector PionMinus;
|
||||
G4HEVector KaonPlus;
|
||||
G4HEVector KaonZero;
|
||||
G4HEVector AntiKaonZero;
|
||||
G4HEVector KaonMinus;
|
||||
G4HEVector KaonZeroShort;
|
||||
G4HEVector KaonZeroLong;
|
||||
G4HEVector Proton;
|
||||
G4HEVector AntiProton;
|
||||
G4HEVector Neutron;
|
||||
G4HEVector AntiNeutron;
|
||||
G4HEVector Lambda;
|
||||
G4HEVector AntiLambda;
|
||||
G4HEVector SigmaPlus;
|
||||
G4HEVector SigmaZero;
|
||||
G4HEVector SigmaMinus;
|
||||
G4HEVector AntiSigmaPlus;
|
||||
G4HEVector AntiSigmaZero;
|
||||
G4HEVector AntiSigmaMinus;
|
||||
G4HEVector XiZero;
|
||||
G4HEVector XiMinus;
|
||||
G4HEVector AntiXiZero;
|
||||
G4HEVector AntiXiMinus;
|
||||
G4HEVector OmegaMinus;
|
||||
G4HEVector AntiOmegaMinus;
|
||||
G4HEVector Deuteron;
|
||||
G4HEVector Triton;
|
||||
G4HEVector Alpha;
|
||||
G4HEVector Gamma;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEKaonMinusInelastic_h
|
||||
#define G4HEKaonMinusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEKaonMinusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEKaonMinusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEKaonMinusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasKaonMinus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEKaonPlusInelastic_h
|
||||
#define G4HEKaonPlusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEKaonPlusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEKaonPlusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEKaonPlusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasKaonPlus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEKaonZeroInelastic_h
|
||||
#define G4HEKaonZeroInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEKaonZeroInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEKaonZeroInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEKaonZeroInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasKaonZero(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEKaonZeroLongInelastic_h
|
||||
#define G4HEKaonZeroLongInelastic_h 1
|
||||
|
||||
#include "G4HEKaonZeroInelastic.hh"
|
||||
#include "G4HEAntiKaonZeroInelastic.hh"
|
||||
|
||||
class G4HEKaonZeroLongInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEKaonZeroLongInelastic()
|
||||
{
|
||||
}
|
||||
|
||||
~G4HEKaonZeroLongInelastic(){ };
|
||||
|
||||
G4int verboseLevel;
|
||||
G4int MAXPART;
|
||||
G4int vecLength;
|
||||
|
||||
void SetMaxNumberOfSecondaries(G4int maxnumber)
|
||||
{ MAXPART = maxnumber;};
|
||||
void SetVerboseLevel(G4int verbose)
|
||||
{ verboseLevel = verbose;};
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength;};
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEKaonZeroShortInelastic_h
|
||||
#define G4HEKaonZeroShortInelastic_h 1
|
||||
|
||||
#include "G4HEKaonZeroInelastic.hh"
|
||||
#include "G4HEAntiKaonZeroInelastic.hh"
|
||||
|
||||
class G4HEKaonZeroShortInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEKaonZeroShortInelastic()
|
||||
{
|
||||
}
|
||||
|
||||
~G4HEKaonZeroShortInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
void SetMaxNumberOfSecondaries(G4int maxnumber)
|
||||
{ MAXPART = maxnumber;};
|
||||
void SetVerboseLevel(G4int verbose)
|
||||
{ verboseLevel = verbose;};
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength;};
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HELambdaInelastic_h
|
||||
#define G4HELambdaInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HELambdaInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HELambdaInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HELambdaInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasLambda(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HENeutronInelastic_h
|
||||
#define G4HENeutronInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HENeutronInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HENeutronInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HENeutronInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasNeutron(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEOmegaMinusInelastic_h
|
||||
#define G4HEOmegaMinusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEOmegaMinusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEOmegaMinusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEOmegaMinusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasOmegaMinus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEPionMinusInelastic_h
|
||||
#define G4HEPionMinusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEPionMinusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEPionMinusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEPionMinusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasPionMinus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEPionPlusInelastic_h
|
||||
#define G4HEPionPlusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEPionPlusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEPionPlusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEPionPlusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasPionPlus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// G4 Gheisha friend class G4HEPlot -- header file
|
||||
// last modified: H. Fesefeldt 18-November-1996
|
||||
|
||||
#include <stdio.h>
|
||||
#include "globals.hh"
|
||||
|
||||
class G4HEPlot
|
||||
{
|
||||
protected:
|
||||
G4double Xstart;
|
||||
G4double Xbin;
|
||||
G4double Weight;
|
||||
G4int Nbin;
|
||||
G4int Entries;
|
||||
G4int EntriesOverflow;
|
||||
G4int EntriesUnderflow;
|
||||
G4double WeightOverflow;
|
||||
G4double WeightUnderflow;
|
||||
G4double* Xvalue;
|
||||
G4double* Yvalue;
|
||||
|
||||
public:
|
||||
|
||||
G4HEPlot(){ };
|
||||
|
||||
~G4HEPlot(){ };
|
||||
|
||||
G4double getWeight()
|
||||
{ return Weight;};
|
||||
|
||||
G4double getWeightUnderflow()
|
||||
{ return WeightUnderflow; };
|
||||
|
||||
G4double getWeightOverflow()
|
||||
{ return WeightOverflow;};
|
||||
|
||||
G4int getNumberOfEntries()
|
||||
{ return Entries;};
|
||||
|
||||
G4int getNumberOfEntriesOverflow()
|
||||
{ return EntriesOverflow;};
|
||||
|
||||
G4int getNumberOfEntriesUnderflow()
|
||||
{ return EntriesUnderflow;};
|
||||
|
||||
G4int getNumberOfBins()
|
||||
{ return Nbin;};
|
||||
|
||||
G4double getBinsize()
|
||||
{ return Xbin;};
|
||||
|
||||
G4double getXstart()
|
||||
{ return Xstart;};
|
||||
|
||||
void Init(G4int nbin, G4double xstart, G4double Xbin);
|
||||
|
||||
void Add( G4double s1, G4double s2, const G4HEPlot & p1, const G4HEPlot & p2 );
|
||||
|
||||
void Multiply( G4double s1, G4double s2, const G4HEPlot & p1, const G4HEPlot & p2 );
|
||||
|
||||
void Divide( G4double s1, G4double s2, const G4HEPlot & p1, const G4HEPlot & p2 );
|
||||
|
||||
void Scale( G4double s, const G4HEPlot & p);
|
||||
|
||||
void XScale( G4double a, G4double b, const G4HEPlot & p);
|
||||
|
||||
void Log( G4double s, const G4HEPlot & p);
|
||||
|
||||
void Sqrt( G4double s, const G4HEPlot & p);
|
||||
|
||||
void Reset();
|
||||
|
||||
void Fill(G4double x, G4double w);
|
||||
|
||||
void Print(G4String name, G4int i);
|
||||
|
||||
void DumpToFile(G4int aPlot, G4String aName);
|
||||
|
||||
void GetFromFile(G4int aPlot, G4String aName);
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEProtonInelastic_h
|
||||
#define G4HEProtonInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEProtonInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEProtonInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEProtonInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasProton(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HESigmaMinusInelastic_h
|
||||
#define G4HESigmaMinusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HESigmaMinusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HESigmaMinusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HESigmaMinusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasSigmaMinus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HESigmaPlusInelastic_h
|
||||
#define G4HESigmaPlusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HESigmaPlusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HESigmaPlusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HESigmaPlusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasSigmaPlus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HESigmaZeroInelastic_h
|
||||
#define G4HESigmaZeroInelastic_h 1
|
||||
|
||||
#include "G4HELambdaInelastic.hh"
|
||||
|
||||
class G4HESigmaZeroInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HESigmaZeroInelastic() : G4HEInelastic()
|
||||
{
|
||||
}
|
||||
|
||||
~G4HESigmaZeroInelastic(){ };
|
||||
|
||||
G4int verboseLevel;
|
||||
G4int MAXPART;
|
||||
G4int vecLength;
|
||||
|
||||
void SetMaxNumberOfSecondaries(G4int maxnumber)
|
||||
{ MAXPART = maxnumber; };
|
||||
void SetVerboseLevel(G4int verbose)
|
||||
{ verboseLevel = verbose;};
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
// G4 Gheisha friend class G4KinematicParticle -- header file
|
||||
// J.L. Chuma, TRIUMF, 22-Feb-1996
|
||||
// last modified: H. Fesefeldt 18-November-1996
|
||||
|
||||
#ifndef G4HEVector_hh
|
||||
#define G4HEVector_hh 1
|
||||
|
||||
#include "G4ParticleMomentum.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
|
||||
class G4HEVector
|
||||
{
|
||||
protected:
|
||||
G4double px;
|
||||
G4double py;
|
||||
G4double pz;
|
||||
G4double energy;
|
||||
G4double kineticEnergy;
|
||||
G4double mass;
|
||||
G4double charge;
|
||||
G4double timeOfFlight;
|
||||
G4int side;
|
||||
G4bool flag;
|
||||
G4int code;
|
||||
G4String particleName;
|
||||
G4String particleType;
|
||||
G4int baryon;
|
||||
enum {NumberOfQuarkFlavor = 8};
|
||||
G4int theQuarkContent[NumberOfQuarkFlavor];
|
||||
G4int theAntiQuarkContent[NumberOfQuarkFlavor];
|
||||
|
||||
public:
|
||||
|
||||
G4HEVector(const G4DynamicParticle * aParticle)
|
||||
{
|
||||
G4ThreeVector aMom = 1./GeV*aParticle->GetMomentum();
|
||||
px = aMom.x();
|
||||
py = aMom.y();
|
||||
pz = aMom.z();
|
||||
energy = aParticle->GetTotalEnergy()/GeV;
|
||||
kineticEnergy = aParticle->GetKineticEnergy()/GeV;
|
||||
mass = aParticle->GetMass()/GeV;
|
||||
charge = aParticle->GetDefinition()->GetPDGCharge()/eplus;
|
||||
timeOfFlight = 0.0;
|
||||
side = 0;
|
||||
flag = false;
|
||||
code = aParticle->GetDefinition()->GetPDGEncoding();
|
||||
baryon = aParticle->GetDefinition()->GetBaryonNumber();
|
||||
particleName = getParticleName(code, baryon);
|
||||
particleType = aParticle->GetDefinition()->GetParticleType();
|
||||
}
|
||||
|
||||
G4HEVector()
|
||||
{
|
||||
px = 0.0;
|
||||
py = 0.0;
|
||||
pz = 0.0;
|
||||
energy = 0.0;
|
||||
kineticEnergy = 0.0;
|
||||
mass = 0.0;
|
||||
charge = 0.0;
|
||||
timeOfFlight = 0.0;
|
||||
side = 0;
|
||||
flag = false;
|
||||
code = 0;
|
||||
particleName = "";
|
||||
particleType = "";
|
||||
baryon = 0;
|
||||
}
|
||||
|
||||
|
||||
G4HEVector( const G4HEVector & p )
|
||||
{
|
||||
px = p.px;
|
||||
py = p.py;
|
||||
pz = p.pz;
|
||||
energy = p.energy;
|
||||
kineticEnergy = p.kineticEnergy;
|
||||
mass = p.mass;
|
||||
charge = p.charge;
|
||||
timeOfFlight = p.timeOfFlight;
|
||||
side = p.side;
|
||||
flag = p.flag;
|
||||
code = p.code;
|
||||
particleName = p.particleName;
|
||||
particleType = p.particleType;
|
||||
baryon = 0;
|
||||
}
|
||||
|
||||
|
||||
G4HEVector & operator = ( const G4HEVector & p )
|
||||
{
|
||||
px = p.px;
|
||||
py = p.py;
|
||||
pz = p.pz;
|
||||
energy = p.energy;
|
||||
kineticEnergy = p.kineticEnergy;
|
||||
mass = p.mass;
|
||||
charge = p.charge;
|
||||
timeOfFlight = p.timeOfFlight;
|
||||
side = p.side;
|
||||
flag = p.flag;
|
||||
code = p.code;
|
||||
particleName = p.particleName;
|
||||
particleType = p.particleType;
|
||||
baryon = p.baryon;
|
||||
return *this;
|
||||
}
|
||||
~G4HEVector(){ };
|
||||
|
||||
G4String getParticleName(G4int code, G4int baryon);
|
||||
|
||||
void setMomentum( G4ParticleMomentum mom );
|
||||
|
||||
void setMomentumAndUpdate( G4ParticleMomentum mom );
|
||||
|
||||
const G4ParticleMomentum getMomentum() const ;
|
||||
|
||||
G4double getTotalMomentum();
|
||||
|
||||
void setMomentum( G4double x, G4double y, G4double z);
|
||||
|
||||
void setMomentumAndUpdate( G4double x, G4double y, G4double z );
|
||||
|
||||
void setMomentum( G4double x, G4double y );
|
||||
|
||||
void setMomentumAndUpdate( G4double x, G4double y );
|
||||
|
||||
void setMomentum( G4double z );
|
||||
|
||||
void setMomentumAndUpdate( G4double z );
|
||||
|
||||
void setEnergy( G4double e );
|
||||
|
||||
void setEnergyAndUpdate( G4double e );
|
||||
|
||||
void setKineticEnergy( G4double ekin );
|
||||
|
||||
void setKineticEnergyAndUpdate(G4double ekin);
|
||||
|
||||
G4double getEnergy();
|
||||
|
||||
G4double getKineticEnergy();
|
||||
|
||||
void setMass( G4double m );
|
||||
|
||||
void setMassAndUpdate( G4double m );
|
||||
|
||||
G4double getMass();
|
||||
|
||||
void setCharge( G4double c );
|
||||
|
||||
G4double getCharge();
|
||||
|
||||
void setTOF( G4double t );
|
||||
|
||||
G4double getTOF();
|
||||
|
||||
void setSide( G4int s );
|
||||
|
||||
G4int getSide();
|
||||
|
||||
void setFlag( G4bool f );
|
||||
|
||||
G4bool getFlag();
|
||||
|
||||
void setCode( G4int c );
|
||||
|
||||
G4int getCode();
|
||||
|
||||
G4String getName();
|
||||
|
||||
G4int getBaryonNumber();
|
||||
|
||||
G4int getQuarkContent(G4int flavor);
|
||||
|
||||
G4int getAntiQuarkContent(G4int flavor);
|
||||
|
||||
void setZero();
|
||||
|
||||
G4String getType();
|
||||
void Add( const G4HEVector & p1, const G4HEVector & p2 );
|
||||
|
||||
void Sub( const G4HEVector & p1, const G4HEVector & p2 );
|
||||
|
||||
void Lor( const G4HEVector & p1, const G4HEVector & p2 );
|
||||
|
||||
G4double CosAng( const G4HEVector & p );
|
||||
|
||||
G4double Ang(const G4HEVector & p );
|
||||
|
||||
G4double Dot4( const G4HEVector & p1, const G4HEVector & p2);
|
||||
|
||||
G4double Impu( const G4HEVector & p1, const G4HEVector & p2);
|
||||
|
||||
void Add3( const G4HEVector & p1, const G4HEVector & p2);
|
||||
|
||||
void Sub3( const G4HEVector & p1, const G4HEVector & p2);
|
||||
|
||||
void Cross( const G4HEVector & p1, const G4HEVector & p2);
|
||||
|
||||
G4double Dot( const G4HEVector & p1, const G4HEVector & p2);
|
||||
|
||||
void Smul( const G4HEVector & p, G4double h);
|
||||
|
||||
void SmulAndUpdate( const G4HEVector & p, G4double h);
|
||||
|
||||
void Norz( const G4HEVector & p );
|
||||
|
||||
G4double Length();
|
||||
|
||||
void Exch( G4HEVector & p1);
|
||||
|
||||
void Defs1( const G4HEVector & p1, const G4HEVector & p2);
|
||||
|
||||
void Defs( const G4HEVector & p1, const G4HEVector & p2,
|
||||
G4HEVector & my, G4HEVector & mz );
|
||||
|
||||
void Trac( const G4HEVector & p1, const G4HEVector & mx,
|
||||
const G4HEVector & my, const G4HEVector & mz);
|
||||
|
||||
void setDefinition(G4String name);
|
||||
|
||||
G4int FillQuarkContent();
|
||||
|
||||
void Print( G4int L);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEXiMinusInelastic_h
|
||||
#define G4HEXiMinusInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEXiMinusInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEXiMinusInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEXiMinusInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasXiMinus(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// G4 Gheisha High Energy model class -- header file
|
||||
// H. Fesefeldt, RWTH Aachen 23-October-1996
|
||||
// Last modified: 10-December-1996
|
||||
|
||||
// A prototype of the Gheisha High Energy collision model.
|
||||
|
||||
#ifndef G4HEXiZeroInelastic_h
|
||||
#define G4HEXiZeroInelastic_h 1
|
||||
|
||||
#include "G4HEInelastic.hh"
|
||||
|
||||
class G4HEXiZeroInelastic : public G4HEInelastic
|
||||
{
|
||||
public:
|
||||
G4HEXiZeroInelastic() : G4HEInelastic()
|
||||
{
|
||||
G4int vecLen = 0;
|
||||
}
|
||||
|
||||
~G4HEXiZeroInelastic(){ };
|
||||
|
||||
G4int vecLength;
|
||||
|
||||
G4VParticleChange * ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus );
|
||||
|
||||
G4int GetNumberOfSecondaries()
|
||||
{ return vecLength; }
|
||||
|
||||
private:
|
||||
|
||||
void FirstIntInCasXiZero(G4bool &inElastic, const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,593 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiKaonZeroInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiKaonZeroInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double atomicWeight = targetNucleus.GetN();
|
||||
const G4double atomicNumber = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiKaonZeroInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiKaonZeroInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiKaonZero(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle );
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiKaonZeroInelastic::FirstIntInCasAntiKaonZero( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle )
|
||||
|
||||
// AntiKaon0 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
G4int kaonMinusCode = KaonMinus.getCode();
|
||||
G4int kaonZeroCode = KaonZero.getCode();
|
||||
G4int antiKaonZeroCode = AntiKaonZero.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if (!inElastic || (availableEnergy <= PionPlus.getMass()))
|
||||
return;
|
||||
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
G4double cech[] = { 1., 1., 1., 0.70, 0.60, 0.55, 0.35, 0.25, 0.18, 0.15};
|
||||
G4int iplab = G4int( incidentTotalMomentum*5.);
|
||||
if( (iplab < 10) && (G4UniformRand() < cech[iplab]) )
|
||||
{
|
||||
G4int iplab = min(19, G4int( incidentTotalMomentum*5.));
|
||||
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] )
|
||||
{
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = KaonMinus;
|
||||
pv[1] = Proton;
|
||||
return;
|
||||
}
|
||||
}
|
||||
G4double ran = G4UniformRand();
|
||||
if( targetCode == protonCode ) // target is a proton
|
||||
{
|
||||
if( ran < 0.25 )
|
||||
{
|
||||
}
|
||||
else if (ran < 0.50)
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // target is a neutron
|
||||
if( ran < 0.25 )
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else if (ran < 0.50)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (1+nm))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[0] = KaonMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = KaonMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.75)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = KaonMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if ( np == (1+nm))
|
||||
{
|
||||
pv[0] = KaonMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( ( (pv[0].getCode() == kaonMinusCode)
|
||||
&& (pv[1].getCode() == neutronCode) )
|
||||
|| ( (pv[0].getCode() == kaonZeroCode)
|
||||
&& (pv[1].getCode() == protonCode) )
|
||||
|| ( (pv[0].getCode() == antiKaonZeroCode)
|
||||
&& (pv[1].getCode() == protonCode) ) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( pv[1].getCode() == protonCode)
|
||||
{
|
||||
if(ran < 0.68)
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.84)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ran < 0.68)
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.84)
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if (ran < 0.67)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.78)
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else if (ran < 0.89)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,704 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiLambdaInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiLambdaInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double atomicWeight = targetNucleus.GetN();
|
||||
const G4double atomicNumber = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiLambdaInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiLambdaInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiLambda(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiLambdaInelastic::FirstIntInCasAntiLambda( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numMulAn = 400;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double protmulAn[numMulAn],protnormAn[numSec];
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double neutmulAn[numMulAn],neutnormAn[numSec];
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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];
|
||||
}
|
||||
// annihilation
|
||||
for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); np++ )
|
||||
{
|
||||
nm = max(0,np-1);
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
protmulAn[counter] = pmltpc(np,nm,nz,nt,protb,c);
|
||||
protnormAn[nt-1] += protmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
neutmulAn[counter] = pmltpc(np,nm,nz,nt,neutb,c);
|
||||
neutnormAn[nt-1] += neutmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; i++ )
|
||||
{
|
||||
if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
|
||||
if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // some two-body reactions
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
|
||||
G4int iplab = min(9, G4int( incidentTotalMomentum*2.5));
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
|
||||
if ( targetCode == protonCode)
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaMinus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
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( incidentTotalMomentum*10.);
|
||||
if ( iplab > 9) iplab = 10 + G4int( (incidentTotalMomentum -1.)*5. );
|
||||
if ( iplab > 14) iplab = 15 + G4int( incidentTotalMomentum -2. );
|
||||
if ( iplab > 22) iplab = 23 + G4int( (incidentTotalMomentum -10.)/10.);
|
||||
iplab = min(24, iplab);
|
||||
|
||||
if ( G4UniformRand() > anhl[iplab] )
|
||||
{ // non- annihilation channels
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.40)
|
||||
{
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( ran < 0.25)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.4)
|
||||
{
|
||||
}
|
||||
else if(ran < 0.8)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if ( np == (nm-1))
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // annihilation
|
||||
{
|
||||
if ( availableEnergy > 2. * PionPlus.getMass() )
|
||||
{
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=2; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*protmulAn[counter]*protnormAn[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) goto outOfLoopAn; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*neutmulAn[counter]*neutnormAn[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) goto outOfLoopAn; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
outOfLoopAn: // <------------------------------------------------------------------
|
||||
vecLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,645 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiNeutronInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiNeutronInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double atomicWeight = targetNucleus.GetN();
|
||||
const G4double atomicNumber = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiNeutronInelastic: incident energy < 1 GeV" << endl;;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiNeutronInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiNeutron(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiNeutronInelastic::FirstIntInCasAntiNeutron( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numMulAn = 400;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double protmulAn[numMulAn],protnormAn[numSec];
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double neutmulAn[numMulAn],neutnormAn[numSec];
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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];
|
||||
}
|
||||
// annihilation
|
||||
for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); np++ )
|
||||
{
|
||||
nm = max(0,np-1);
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
protmulAn[counter] = pmltpc(np,nm,nz,nt,protb,c);
|
||||
protnormAn[nt-1] += protmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
neutmulAn[counter] = pmltpc(np,nm,nz,nt,neutb,c);
|
||||
neutnormAn[nt-1] += neutmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; i++ )
|
||||
{
|
||||
if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
|
||||
if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // nb n --> pb p
|
||||
if( targetCode == neutronCode )
|
||||
{
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
|
||||
G4int iplab = min(9, G4int( incidentTotalMomentum*2.5));
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
pv[0] = AntiProton;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
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( incidentTotalMomentum*10.);
|
||||
if ( iplab > 9) iplab = 10 + G4int( (incidentTotalMomentum -1.)*5. );
|
||||
if ( iplab > 14) iplab = 15 + G4int( incidentTotalMomentum -2. );
|
||||
if ( iplab > 22) iplab = 23 + G4int( (incidentTotalMomentum -10.)/10.);
|
||||
iplab = min(24, iplab);
|
||||
|
||||
if ( G4UniformRand() > anhl[iplab] )
|
||||
{
|
||||
|
||||
G4double eab = availableEnergy;
|
||||
G4int ieab = G4int( eab*5.0 );
|
||||
|
||||
G4double supp[] = {0., 0.4, 0.55, 0.65, 0.75, 0.82, 0.86, 0.90, 0.94, 0.98};
|
||||
if( (ieab <= 9) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one additional pion will be produced
|
||||
G4double w0, wp, wm, wt, ran;
|
||||
if( targetCode == protonCode ) // target is a proton
|
||||
{
|
||||
w0 = - sqr(1.+protb)/(2.*c*c);
|
||||
w0 = wp = exp(w0);
|
||||
if( G4UniformRand() < w0/(w0+wp) )
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
}
|
||||
else
|
||||
{ // target is a neutron
|
||||
w0 = -sqr(1.+neutb)/(2.*c*c);
|
||||
w0 = wp = exp(w0);
|
||||
wm = -sqr(-1.+neutb)/(2.*c*c);
|
||||
wm = exp(wm);
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
ran = G4UniformRand();
|
||||
if( ran < w0/wt)
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else if( ran < wp/wt)
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiProton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiProton;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.25)
|
||||
{
|
||||
pv[0] = AntiProton;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if ( np == (nm-1))
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiProton;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // annihilation
|
||||
{
|
||||
if ( availableEnergy > 2. * PionPlus.getMass() )
|
||||
{
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=2; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*protmulAn[counter]*protnormAn[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) goto outOfLoopAn; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*neutmulAn[counter]*neutnormAn[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) goto outOfLoopAn; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
outOfLoopAn: // <------------------------------------------------------------------
|
||||
vecLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,700 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiOmegaMinusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiOmegaMinusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double atomicWeight = targetNucleus.GetN();
|
||||
const G4double atomicNumber = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiOmegaMinusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiOmegaMinusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiOmegaMinus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiOmegaMinusInelastic::FirstIntInCasAntiOmegaMinus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight )
|
||||
|
||||
// AntiOmega undergoes interaction with nucleon within a nucleus.
|
||||
// As in Geant3, we think that this routine has absolutely no influence
|
||||
// on the whole performance of the program. Take AntiLambda instaed.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numMulAn = 400;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double protmulAn[numMulAn],protnormAn[numSec];
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double neutmulAn[numMulAn],neutnormAn[numSec];
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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];
|
||||
}
|
||||
// annihilation
|
||||
for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); np++ )
|
||||
{
|
||||
nm = max(0,np-1);
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
protmulAn[counter] = pmltpc(np,nm,nz,nt,protb,c);
|
||||
protnormAn[nt-1] += protmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
neutmulAn[counter] = pmltpc(np,nm,nz,nt,neutb,c);
|
||||
neutnormAn[nt-1] += neutmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; i++ )
|
||||
{
|
||||
if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
|
||||
if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // some two-body reactions
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
|
||||
G4int iplab = min(9, G4int( incidentTotalMomentum*2.5 ));
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
|
||||
if ( targetCode == protonCode)
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaMinus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
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( incidentTotalMomentum*10.);
|
||||
if ( iplab > 9) iplab = 10 + G4int( (incidentTotalMomentum -1.)*5. );
|
||||
if ( iplab > 14) iplab = 15 + G4int( incidentTotalMomentum -2. );
|
||||
if ( iplab > 22) iplab = 23 + G4int( (incidentTotalMomentum -10.)/10.);
|
||||
iplab = min(24, iplab);
|
||||
|
||||
if ( G4UniformRand() > anhl[iplab] )
|
||||
{ // non- annihilation channels
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.40)
|
||||
{
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( ran < 0.25)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.4)
|
||||
{
|
||||
}
|
||||
else if(ran < 0.8)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if ( np == (nm-1))
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // annihilation
|
||||
{
|
||||
if ( availableEnergy > 2. * PionPlus.getMass() )
|
||||
{
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=2; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*protmulAn[counter]*protnormAn[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) goto outOfLoopAn; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*neutmulAn[counter]*neutnormAn[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) goto outOfLoopAn; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
outOfLoopAn: // <------------------------------------------------------------------
|
||||
vecLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,650 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiProtonInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiProtonInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double atomicWeight = targetNucleus.GetN();
|
||||
const G4double atomicNumber = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiProtonInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiProtonInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiProton(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiProtonInelastic::FirstIntInCasAntiProton( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numMulAn = 400;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double protmulAn[numMulAn],protnormAn[numSec];
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double neutmulAn[numMulAn],neutnormAn[numSec];
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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];
|
||||
}
|
||||
// annihilation
|
||||
for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
protmulAn[counter] = pmltpc(np,nm,nz,nt,protb,c);
|
||||
protnormAn[nt-1] += protmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np+1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
neutmulAn[counter] = pmltpc(np,nm,nz,nt,neutb,c);
|
||||
neutnormAn[nt-1] += neutmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; i++ )
|
||||
{
|
||||
if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
|
||||
if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // pb p --> nb n
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
G4double cech[] = {0.14, 0.170, 0.180, 0.180, 0.180, 0.170, 0.170, 0.160, 0.155, 0.145,
|
||||
0.11, 0.082, 0.065, 0.050, 0.041, 0.035, 0.028, 0.024, 0.010, 0.000};
|
||||
|
||||
G4int iplab = G4int( incidentTotalMomentum*10.);
|
||||
if (iplab > 9) iplab = min(19, G4int( incidentTotalMomentum) + 9);
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{ // charge exchange pi+ n -> pi0 p
|
||||
pv[0] = AntiNeutron;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
G4double anhl[] = {1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 0.90,
|
||||
0.60, 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.00};
|
||||
G4int iplab = G4int( incidentTotalMomentum*10.);
|
||||
if ( iplab > 9) iplab = 9 + G4int( incidentTotalMomentum);
|
||||
if ( iplab > 18) iplab = 18 + G4int( incidentTotalMomentum*10.);
|
||||
iplab = min(28, iplab);
|
||||
|
||||
if ( G4UniformRand() > anhl[iplab] )
|
||||
{
|
||||
|
||||
G4double eab = availableEnergy;
|
||||
G4int ieab = G4int( eab*5.0 );
|
||||
|
||||
G4double supp[] = {0., 0.4, 0.55, 0.65, 0.75, 0.82, 0.86, 0.90, 0.94, 0.98};
|
||||
if( (ieab <= 9) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one additional pion will be produced
|
||||
G4double w0, wp, wm, wt, ran;
|
||||
if( targetCode == neutronCode ) // target is a neutron
|
||||
{
|
||||
w0 = - sqr(1.+neutb)/(2.*c*c);
|
||||
w0 = exp(w0);
|
||||
wm = - sqr(-1.+neutb)/(2.*c*c);
|
||||
wm = exp(wm);
|
||||
if( G4UniformRand() < w0/(w0+wm) )
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
else
|
||||
{ // target is a proton
|
||||
w0 = -sqr(1.+protb)/(2.*c*c);
|
||||
w0 = exp(w0);
|
||||
wp = w0;
|
||||
wm = -sqr(-1.+protb)/(2.*c*c);
|
||||
wm = exp(wm);
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
ran = G4UniformRand();
|
||||
if( ran < w0/wt)
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else if( ran < wp/wt)
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == neutronCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiNeutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiNeutron;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.25)
|
||||
{
|
||||
pv[0] = AntiNeutron;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if ( np == (1+nm))
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiNeutron;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // annihilation
|
||||
{
|
||||
if ( availableEnergy > 2. * PionPlus.getMass() )
|
||||
{
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=2; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*protmulAn[counter]*protnormAn[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) goto outOfLoopAn; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np+1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*neutmulAn[counter]*neutnormAn[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) goto outOfLoopAn; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
outOfLoopAn: // <------------------------------------------------------------------
|
||||
vecLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,664 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiSigmaMinusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiSigmaMinusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double atomicWeight = targetNucleus.GetN();
|
||||
const G4double atomicNumber = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiSigmaMinusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiSigmaMinusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiSigmaMinus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiSigmaMinusInelastic::FirstIntInCasAntiSigmaMinus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// AntiSigma- 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numMulAn = 400;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double protmulAn[numMulAn],protnormAn[numSec];
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double neutmulAn[numMulAn],neutnormAn[numSec];
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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];
|
||||
}
|
||||
// annihilation
|
||||
for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); np++ )
|
||||
{
|
||||
nm = max(0,np-2);
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
protmulAn[counter] = pmltpc(np,nm,nz,nt,protb,c);
|
||||
protnormAn[nt-1] += protmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
neutmulAn[counter] = pmltpc(np,nm,nz,nt,neutb,c);
|
||||
neutnormAn[nt-1] += neutmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; i++ )
|
||||
{
|
||||
if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
|
||||
if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // some two-body reactions
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
|
||||
G4int iplab = min(9, G4int( incidentTotalMomentum*2.5 ));
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
|
||||
if ( targetCode == neutronCode)
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaMinus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaMinus;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
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( incidentTotalMomentum*10.);
|
||||
if ( iplab > 9) iplab = 10 + G4int( (incidentTotalMomentum -1.)*5. );
|
||||
if ( iplab > 14) iplab = 15 + G4int( incidentTotalMomentum -2. );
|
||||
if ( iplab > 22) iplab = 23 + G4int( (incidentTotalMomentum -10.)/10.);
|
||||
iplab = min(24, iplab);
|
||||
|
||||
if ( G4UniformRand() > anhl[iplab] )
|
||||
{ // non- annihilation channels
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( ran < 0.50)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
}
|
||||
else if(ran < 0.75)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if ( np == (nm+1))
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // annihilation
|
||||
{
|
||||
if ( availableEnergy > 2. * PionPlus.getMass() )
|
||||
{
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=2; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=2; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np-2;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*protmulAn[counter]*protnormAn[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) goto outOfLoopAn; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*neutmulAn[counter]*neutnormAn[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) goto outOfLoopAn; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
outOfLoopAn: // <------------------------------------------------------------------
|
||||
vecLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,664 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiSigmaPlusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiSigmaPlusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double atomicWeight = targetNucleus.GetN();
|
||||
const G4double atomicNumber = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiSigmaPlusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiSigmaPlusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiSigmaPlus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiSigmaPlusInelastic::FirstIntInCasAntiSigmaPlus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// AntiSigma+ 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numMulAn = 400;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double protmulAn[numMulAn],protnormAn[numSec];
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double neutmulAn[numMulAn],neutnormAn[numSec];
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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];
|
||||
}
|
||||
// annihilation
|
||||
for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
protmulAn[counter] = pmltpc(np,nm,nz,nt,protb,c);
|
||||
protnormAn[nt-1] += protmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np+1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
neutmulAn[counter] = pmltpc(np,nm,nz,nt,neutb,c);
|
||||
neutnormAn[nt-1] += neutmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; i++ )
|
||||
{
|
||||
if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
|
||||
if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // some two-body reactions
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
|
||||
G4int iplab = min(9, G4int( incidentTotalMomentum*2.5));
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
|
||||
if ( targetCode == protonCode)
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaPlus;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
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( incidentTotalMomentum*10.);
|
||||
if ( iplab > 9) iplab = 10 + G4int( (incidentTotalMomentum -1.)*5. );
|
||||
if ( iplab > 14) iplab = 15 + G4int( incidentTotalMomentum -2. );
|
||||
if ( iplab > 22) iplab = 23 + G4int( (incidentTotalMomentum -10.)/10.);
|
||||
iplab = min(24, iplab);
|
||||
|
||||
if ( G4UniformRand() > anhl[iplab] )
|
||||
{ // non- annihilation channels
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.50)
|
||||
{
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
if( ran < 0.50)
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if ( np == (nm-1))
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiLambda;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // annihilation
|
||||
{
|
||||
if ( availableEnergy > 2. * PionPlus.getMass() )
|
||||
{
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=2; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*protmulAn[counter]*protnormAn[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) goto outOfLoopAn; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np+1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*neutmulAn[counter]*neutnormAn[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) goto outOfLoopAn; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
outOfLoopAn: // <------------------------------------------------------------------
|
||||
vecLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiSigmaZeroInelastic.hh"
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiSigmaZeroInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
G4HEAntiLambdaInelastic theAntiLambdaInelastic;
|
||||
theAntiLambdaInelastic.SetMaxNumberOfSecondaries(MAXPART);
|
||||
theAntiLambdaInelastic.SetVerboseLevel(verboseLevel);
|
||||
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double pgam = G4UniformRand()*incidentTotalMomentum*0.75;
|
||||
G4HEVector incidentAntiLambda;
|
||||
incidentAntiLambda.SmulAndUpdate( incidentParticle,
|
||||
(incidentTotalMomentum - pgam)/incidentTotalMomentum);
|
||||
G4DynamicParticle * aLambda = new G4DynamicParticle();
|
||||
aLambda->SetDefinition(G4AntiLambda::AntiLambda());
|
||||
G4Track aLambdaTrack(aLambda, 0, aTrack.GetPosition());
|
||||
aLambda->SetMomentum(incidentAntiLambda.getMomentum());
|
||||
G4VParticleChange * result = theAntiLambdaInelastic.ApplyYourself(aLambdaTrack, targetNucleus);
|
||||
vecLength = theAntiLambdaInelastic.GetNumberOfSecondaries();
|
||||
pv[vecLength] = Gamma;
|
||||
pv[vecLength].setMomentum(incidentParticle.getMomentum());
|
||||
pv[vecLength].SmulAndUpdate( pv[vecLength],pgam/incidentTotalMomentum);
|
||||
G4DynamicParticle * aPhoton = new G4DynamicParticle();
|
||||
aPhoton->SetDefinition(G4Gamma::Gamma());
|
||||
aPhoton->SetMomentum(pv[vecLength].getMomentum());
|
||||
G4Track * aGammaTrack = new G4Track(aPhoton, aTrack.GetGlobalTime(), aTrack.GetPosition());
|
||||
result->AddSecondary(aGammaTrack);
|
||||
delete [] pv;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,703 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiXiMinusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiXiMinusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiXiMinusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiXiMinusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiXiMinus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles";
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiXiMinusInelastic::FirstIntInCasAntiXiMinus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// AntiXi- undergoes interaction with nucleon within a nucleus.
|
||||
// As in Geant3, we think that this routine has absolutely no influence
|
||||
// on the whole performance of the program. Take AntiLambda instaed.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numMulAn = 400;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double protmulAn[numMulAn],protnormAn[numSec];
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double neutmulAn[numMulAn],neutnormAn[numSec];
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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];
|
||||
}
|
||||
// annihilation
|
||||
for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); np++ )
|
||||
{
|
||||
nm = max(0,np-1);
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
protmulAn[counter] = pmltpc(np,nm,nz,nt,protb,c);
|
||||
protnormAn[nt-1] += protmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
neutmulAn[counter] = pmltpc(np,nm,nz,nt,neutb,c);
|
||||
neutnormAn[nt-1] += neutmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; i++ )
|
||||
{
|
||||
if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
|
||||
if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // some two-body reactions
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
|
||||
G4int iplab = min(9, G4int( incidentTotalMomentum*2.5));
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
|
||||
if ( targetCode == protonCode)
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaMinus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
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( incidentTotalMomentum*10.);
|
||||
if ( iplab > 9) iplab = 10 + G4int( (incidentTotalMomentum -1.)*5. );
|
||||
if ( iplab > 14) iplab = 15 + G4int( incidentTotalMomentum -2. );
|
||||
if ( iplab > 22) iplab = 23 + G4int( (incidentTotalMomentum -10.)/10.);
|
||||
iplab = min(24, iplab);
|
||||
|
||||
if ( G4UniformRand() > anhl[iplab] )
|
||||
{ // non- annihilation channels
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.40)
|
||||
{
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( ran < 0.25)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.4)
|
||||
{
|
||||
}
|
||||
else if(ran < 0.8)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if ( np == (nm-1))
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // annihilation
|
||||
{
|
||||
if ( availableEnergy > 2. * PionPlus.getMass() )
|
||||
{
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=2; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*protmulAn[counter]*protnormAn[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) goto outOfLoopAn; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*neutmulAn[counter]*neutnormAn[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) goto outOfLoopAn; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
outOfLoopAn: // <------------------------------------------------------------------
|
||||
vecLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,704 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEAntiXiZeroInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEAntiXiZeroInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEAntiXiZeroInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEAntiXiZeroInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasAntiXiZero(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEAntiXiZeroInelastic::FirstIntInCasAntiXiZero( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// AntiXi0 undergoes interaction with nucleon within a nucleus.
|
||||
// As in Geant3, we think that this routine has absolutely no influence
|
||||
// on the whole performance of the program. Take AntiLambda instaed.
|
||||
// ( decay Xi0 -> L Pi > 99 % )
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numMulAn = 400;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double protmulAn[numMulAn],protnormAn[numSec];
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
static G4double neutmulAn[numMulAn],neutnormAn[numSec];
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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];
|
||||
}
|
||||
// annihilation
|
||||
for( i=0; i<numMulAn ; i++ ) protmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec ; i++ ) protnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=1; np<(numSec/3); np++ )
|
||||
{
|
||||
nm = max(0,np-1);
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
protmulAn[counter] = pmltpc(np,nm,nz,nt,protb,c);
|
||||
protnormAn[nt-1] += protmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numMulAn; i++ ) neutmulAn[i] = 0.0;
|
||||
for( i=0; i<numSec; i++ ) neutnormAn[i] = 0.0;
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
neutmulAn[counter] = pmltpc(np,nm,nz,nt,neutb,c);
|
||||
neutnormAn[nt-1] += neutmulAn[counter];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i=0; i<numSec; i++ )
|
||||
{
|
||||
if( protnormAn[i] > 0.0 )protnormAn[i] = 1.0/protnormAn[i];
|
||||
if( neutnormAn[i] > 0.0 )neutnormAn[i] = 1.0/neutnormAn[i];
|
||||
}
|
||||
} // end of initialization
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // some two-body reactions
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
|
||||
G4int iplab = min(9, G4int( incidentTotalMomentum*2.5 ));
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
|
||||
if ( targetCode == protonCode)
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaMinus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiLambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
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( incidentTotalMomentum*10.);
|
||||
if ( iplab > 9) iplab = 10 + G4int( (incidentTotalMomentum -1.)*5. );
|
||||
if ( iplab > 14) iplab = 15 + G4int( incidentTotalMomentum -2. );
|
||||
if ( iplab > 22) iplab = 23 + G4int( (incidentTotalMomentum -10.)/10.);
|
||||
iplab = min(24, iplab);
|
||||
|
||||
if ( G4UniformRand() > anhl[iplab] )
|
||||
{ // non- annihilation channels
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.40)
|
||||
{
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( ran < 0.25)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.4)
|
||||
{
|
||||
}
|
||||
else if(ran < 0.8)
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if ( np == (nm-1))
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
pv[0] = AntiSigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiSigmaMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // annihilation
|
||||
{
|
||||
if ( availableEnergy > 2. * PionPlus.getMass() )
|
||||
{
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=2; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=1; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np-1;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*protmulAn[counter]*protnormAn[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) goto outOfLoopAn; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
nm = np;
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMulAn )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_PI/anpn)*nt*neutmulAn[counter]*neutnormAn[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) goto outOfLoopAn; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
outOfLoopAn: // <------------------------------------------------------------------
|
||||
vecLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getCode() << " " ;
|
||||
cout << pv[1].getCode() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getCode() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,600 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEKaonMinusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEKaonMinusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEKaonMinusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEKaonMinusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasKaonMinus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEKaonMinusInelastic::FirstIntInCasKaonMinus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle)
|
||||
|
||||
// Kaon- 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
G4int kaonMinusCode = KaonMinus.getCode();
|
||||
G4int kaonZeroCode = KaonZero.getCode();
|
||||
G4int antiKaonZeroCode = AntiKaonZero.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if (!inElastic || (availableEnergy <= PionPlus.getMass()))
|
||||
return;
|
||||
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
G4double cech[] = { 1., 1., 1., 0.70, 0.60, 0.55, 0.35, 0.25, 0.18, 0.15};
|
||||
G4int iplab = G4int( incidentTotalMomentum*5.);
|
||||
if( (iplab < 10) && (G4UniformRand() < cech[iplab]))
|
||||
{
|
||||
G4int iplab = min(19, G4int( incidentTotalMomentum*5.));
|
||||
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] )
|
||||
{
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
pv[0] = AntiKaonZero;
|
||||
pv[1] = Neutron;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
G4double ran = G4UniformRand();
|
||||
if( targetCode == protonCode ) // target is a proton
|
||||
{
|
||||
if( ran < 0.25 )
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else if (ran < 0.50)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // target is a neutron
|
||||
if( ran < 0.25 )
|
||||
{
|
||||
}
|
||||
else if (ran < 0.50)
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == (1+nm))
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.75)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiKaonZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiKaonZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == (nm-1))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiKaonZero;
|
||||
}
|
||||
}
|
||||
else if ( np == nm)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = AntiKaonZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
if( G4UniformRand() < 0.5 )
|
||||
{
|
||||
if( ( (pv[0].getCode() == kaonMinusCode)
|
||||
&& (pv[1].getCode() == neutronCode) )
|
||||
|| ( (pv[0].getCode() == kaonZeroCode)
|
||||
&& (pv[1].getCode() == protonCode) )
|
||||
|| ( (pv[0].getCode() == antiKaonZeroCode)
|
||||
&& (pv[1].getCode() == protonCode) ) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( pv[1].getCode() == protonCode)
|
||||
{
|
||||
if(ran < 0.68)
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.84)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ran < 0.68)
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.84)
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if (ran < 0.67)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.78)
|
||||
{
|
||||
pv[0] = PionMinus;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else if (ran < 0.89)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionPlus;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,508 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEKaonPlusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEKaonPlusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEKaonPlusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEKaonPlusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasKaonPlus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEKaonPlusInelastic::FirstIntInCasKaonPlus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// Kaon+ 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
if( targetCode == neutronCode )
|
||||
{
|
||||
G4double cech[] = {0.33,0.27,0.29,0.31,0.27,0.18,0.13,0.10,0.09,0.07};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*5. ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{ // charge exchange K+ n -> K0 p
|
||||
pv[0] = KaonZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
G4double eab = availableEnergy;
|
||||
G4int ieab = G4int( eab*5.0 );
|
||||
|
||||
G4double supp[] = {0., 0.4, 0.55, 0.65, 0.75, 0.82, 0.86, 0.90, 0.94, 0.98};
|
||||
if( (ieab <= 9) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one additional pion will be produced
|
||||
G4double w0, wp, wm, wt, ran;
|
||||
if( targetCode == protonCode ) // target is a proton
|
||||
{
|
||||
w0 = - sqr(1.+protb)/(2.*c*c);
|
||||
wp = w0 = exp(w0);
|
||||
wp *= 2.;
|
||||
if( G4UniformRand() < w0/(w0+wp) )
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
}
|
||||
else
|
||||
{ // target is a neutron
|
||||
w0 = -sqr(1.+neutb)/(2.*c*c);
|
||||
wp = w0 = exp(w0);
|
||||
wm = -sqr(-1.+neutb)/(2.*c*c);
|
||||
wm = exp(wm);
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
ran = G4UniformRand();
|
||||
if( ran < w0/wt)
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else if( ran < wp/wt)
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (1+nm))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = KaonZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = KaonZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.25)
|
||||
{
|
||||
pv[0] = KaonZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if ( np == (1+nm))
|
||||
{
|
||||
pv[0] = KaonZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,507 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEKaonZeroInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEKaonZeroInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEKaonZeroInelastic: incident energy < 1 GeV" << endl;;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEKaonZeroInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasKaonZero(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEKaonZeroInelastic::FirstIntInCasKaonZero( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// Kaon0 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
G4double cech[] = {0.33,0.27,0.29,0.31,0.27,0.18,0.13,0.10,0.09,0.07};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*5. ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{ // charge exchange K+ n -> K0 p
|
||||
pv[0] = KaonPlus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
G4double eab = availableEnergy;
|
||||
G4int ieab = G4int( eab*5.0 );
|
||||
|
||||
G4double supp[] = {0., 0.4, 0.55, 0.65, 0.75, 0.82, 0.86, 0.90, 0.94, 0.98};
|
||||
if( (ieab <= 9) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one additional pion will be produced
|
||||
G4double w0, wp, wm, wt, ran;
|
||||
if( targetCode == neutronCode ) // target is a neutron
|
||||
{
|
||||
w0 = - sqr(1.+protb)/(2.*c*c);
|
||||
w0 = exp(w0);
|
||||
wm = - sqr(-1.+protb)/(2.*c*c);
|
||||
wm = exp(wm);
|
||||
w0 = w0/2.;
|
||||
wm = wm*1.5;
|
||||
if( G4UniformRand() < w0/(w0+wm) ) { np = 0; nm = 0; nz = 1; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
else
|
||||
{ // target is a proton
|
||||
w0 = -sqr(1.+neutb)/(2.*c*c);
|
||||
wp = w0 = exp(w0);
|
||||
wm = -sqr(-1.+neutb)/(2.*c*c);
|
||||
wm = exp(wm);
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
ran = G4UniformRand();
|
||||
if( ran < w0/wt)
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else if( ran < wp/wt)
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == neutronCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[0] = KaonPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = KaonPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm )
|
||||
{
|
||||
if( G4UniformRand() < 0.25)
|
||||
{
|
||||
pv[0] = KaonPlus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if ( np == (nm+1))
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = KaonPlus;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEKaonZeroLongInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEKaonZeroLongInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEKaonZeroInelastic theKaonZeroInelastic;
|
||||
G4HEAntiKaonZeroInelastic theAntiKaonZeroInelastic;
|
||||
theKaonZeroInelastic.SetVerboseLevel(verboseLevel);
|
||||
theAntiKaonZeroInelastic.SetVerboseLevel(verboseLevel);
|
||||
|
||||
if(G4UniformRand() < 0.50)
|
||||
{
|
||||
return theKaonZeroInelastic.ApplyYourself(aTrack, targetNucleus);
|
||||
}
|
||||
else
|
||||
{
|
||||
return theAntiKaonZeroInelastic.ApplyYourself(aTrack, targetNucleus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEKaonZeroShortInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEKaonZeroShortInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEKaonZeroInelastic theKaonZeroInelastic;
|
||||
G4HEAntiKaonZeroInelastic theAntiKaonZeroInelastic;
|
||||
theKaonZeroInelastic.SetVerboseLevel(verboseLevel);
|
||||
theAntiKaonZeroInelastic.SetVerboseLevel(verboseLevel);
|
||||
|
||||
if(G4UniformRand() < 0.50)
|
||||
{
|
||||
return theKaonZeroInelastic.ApplyYourself(aTrack, targetNucleus);
|
||||
}
|
||||
else
|
||||
{
|
||||
return theAntiKaonZeroInelastic.ApplyYourself(aTrack, targetNucleus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,557 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HELambdaInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HELambdaInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHELambdaInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HELambdaInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasLambda(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HELambdaInelastic::FirstIntInCasLambda( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*2.5 ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( ran < 0.2)
|
||||
{
|
||||
pv[0] = SigmaPlus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if(ran < 0.4)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
}
|
||||
else if(ran < 0.6)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if(ran < 0.8)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
}
|
||||
else if(ran < 0.4)
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if(ran < 0.6)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if(ran < 0.8)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if (ran < 0.25)
|
||||
{
|
||||
}
|
||||
else if(ran < 0.5)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = SigmaPlus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( G4UniformRand() < 0.25)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if(ran < 0.5)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
pv[0] = SigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np == nm)
|
||||
{
|
||||
if(ran < 0.5)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
if( ran < 0.25)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if(ran < 0.5)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
}
|
||||
else if (np == (1+nm))
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = SigmaPlus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,507 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HENeutronInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HENeutronInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHENeutronInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HENeutronInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasNeutron(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HENeutronInelastic::FirstIntInCasNeutron( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.35;
|
||||
static const G4double neutb = 0.35;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,c)
|
||||
/(Factorial(1-np+nm)*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,neutb,c)
|
||||
/(Factorial(-np+nm)*Factorial(2+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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*2.5) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{ // charge exchange n p -> p n
|
||||
pv[0] = Proton;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
G4double eab = availableEnergy;
|
||||
G4int ieab = G4int( eab*5.0 );
|
||||
|
||||
G4double supp[] = {0., 0.4, 0.55, 0.65, 0.75, 0.82, 0.86, 0.90, 0.94, 0.98};
|
||||
if( (ieab <= 9) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one additional pion will be produced
|
||||
G4double w0, wp, wm, wt, ran;
|
||||
if( targetCode == neutronCode ) // target is a neutron
|
||||
{
|
||||
w0 = - sqr(1.+neutb)/(2.*c*c);
|
||||
wm = w0 = exp(w0);
|
||||
w0 = w0/2.;
|
||||
if( G4UniformRand() < w0/(w0+wm) )
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
else
|
||||
{ // target is a proton
|
||||
w0 = -sqr(1.+protb)/(2.*c*c);
|
||||
w0 = exp(w0);
|
||||
wp = w0/2.;
|
||||
wm = -sqr(-1.+protb)/(2.*c*c);
|
||||
wm = exp(wm)/2.;
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
ran = G4UniformRand();
|
||||
if( ran < w0/wt)
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else if( ran < wp/wt)
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == neutronCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.25)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if ( np == (1+nm))
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,498 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEOmegaMinusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEOmegaMinusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEOmegaMinusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEOmegaMinusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasOmegaMinus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEOmegaMinusInelastic::FirstIntInCasOmegaMinus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// Xi0 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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; 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,protb,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+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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*2.5 ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = XiZero;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = XiZero;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = XiZero;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = XiZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = OmegaMinus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = OmegaMinus;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = XiZero;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
pv[1] = XiZero;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = XiMinus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = XiMinus;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
for( nm=max(0,np-1); nm<=np; nm++ )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>0) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
counter = -1;
|
||||
for( np=0; np<numSec/3; np++ )
|
||||
{
|
||||
for( nm=np; nm<=(np+1); nm++ )
|
||||
{
|
||||
for( nz=0; nz<numSec/3; nz++ )
|
||||
{
|
||||
if( ++counter < numMul )
|
||||
{
|
||||
nt = np+nm+nz;
|
||||
if( (nt>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
// in the following we do not consider
|
||||
ran = G4UniformRand(); // strangeness transfer in high multiplicity
|
||||
if( targetCode == protonCode) // events. YK combinations are added in
|
||||
{ // StrangeParticlePairProduction
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np == nm)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,510 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEPionMinusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEPionMinusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEPionMinusInelastic: incident energy < 1 GeV" << endl ;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEPionMinusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
G4HEVector targetParticle;
|
||||
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasPionMinus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPionMinusInelastic::FirstIntInCasPionMinus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle)
|
||||
|
||||
// Pion- 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if (!inElastic || (availableEnergy <= PionPlus.getMass()))
|
||||
return;
|
||||
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
G4double eab = availableEnergy;
|
||||
G4int ieab = G4int( eab*5.0 );
|
||||
|
||||
G4double supp[] = {0., 0.4, 0.55, 0.65, 0.75, 0.82, 0.86, 0.90, 0.94, 0.98};
|
||||
if( (ieab <= 9) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one additional pion will be produced
|
||||
G4double cech[] = {1., 0.95, 0.79, 0.32, 0.19, 0.16, 0.14, 0.12, 0.10, 0.08};
|
||||
G4int iplab = max(9, G4int( incidentTotalMomentum*5.));
|
||||
if( G4UniformRand() < cech[iplab] )
|
||||
{
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Neutron;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
G4double w0, wp, wm, wt, ran;
|
||||
if( targetCode == protonCode ) // target is a proton
|
||||
{
|
||||
w0 = - sqr(1.+protb)/(2.*c*c);
|
||||
wp = w0 = exp(w0);
|
||||
wm = - sqr(-1.+protb)/(2.*c*c);
|
||||
wm = exp(wm);
|
||||
wp *= 10.;
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
ran = G4UniformRand();
|
||||
if( ran < w0/wt )
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else if ( ran < wp/wt )
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
else
|
||||
{ // target is a neutron
|
||||
w0 = -sqr(1.+neutb)/(2.*c*c);
|
||||
wm = -sqr(-1.+neutb)/(2.*c*c);
|
||||
w0 = exp(w0);
|
||||
wm = exp(wm);
|
||||
if( G4UniformRand() < w0/(w0+wm) )
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == (1+nm))
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.75)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[0] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == (nm-1))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
}
|
||||
}
|
||||
else if ( np == nm)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,506 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEPionPlusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEPionPlusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "G4HEPionPlusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEPionPlusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasPionPlus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPionPlusInelastic::FirstIntInCasPionPlus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// Pion+ 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
G4double pionMass = PionPlus.getMass();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
if( targetCode == neutronCode )
|
||||
{
|
||||
G4double cech[] = {0.33,0.27,0.29,0.31,0.27,0.18,0.13,0.10,0.09,0.07};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*5. ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{ // charge exchange pi+ n -> pi0 p
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= pionMass)
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
G4double eab = availableEnergy;
|
||||
G4int ieab = G4int( eab*5.0 );
|
||||
|
||||
G4double supp[] = {0., 0.2, 0.45, 0.55, 0.65, 0.75, 0.85, 0.90, 0.94, 0.98};
|
||||
if( (ieab <= 9) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one additional pion will be produced
|
||||
G4double w0, wp, wm, wt, ran;
|
||||
if( targetCode == protonCode ) // target is a proton
|
||||
{
|
||||
w0 = - sqr(1.+protb)/(2.*c*c);
|
||||
wp = w0 = exp(w0);
|
||||
if( G4UniformRand() < w0/(w0+wp) )
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
}
|
||||
else
|
||||
{ // target is a neutron
|
||||
w0 = -sqr(1.+neutb)/(2.*c*c);
|
||||
wp = w0 = exp(w0);
|
||||
wm = -sqr(-1.+neutb)/(2.*c*c);
|
||||
wm = exp(wm);
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
ran = G4UniformRand();
|
||||
if( ran < w0/wt)
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else if( ran < wp/wt)
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (1+nm))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.25)
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if ( np == (1+nm))
|
||||
{
|
||||
pv[0] = PionZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
// G4 Gheisha friend class G4GHEPlot
|
||||
// last modified: H. Fesefeldt 02-July--1998
|
||||
|
||||
#include "G4HEPlot.hh"
|
||||
|
||||
|
||||
void
|
||||
G4HEPlot::Init( G4int nbin, G4double xstart, G4double xbin )
|
||||
{
|
||||
Xbin = xbin;
|
||||
Nbin = nbin;
|
||||
Xstart = xstart;
|
||||
Entries = 0;
|
||||
EntriesOverflow = 0;
|
||||
EntriesUnderflow = 0;
|
||||
Weight = 0.;
|
||||
WeightOverflow = 0.;
|
||||
WeightUnderflow = 0.;
|
||||
Xvalue = new G4double[Nbin];
|
||||
Yvalue = new G4double[Nbin];
|
||||
for(G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
Xvalue[i] = Xstart + i*Xbin;
|
||||
Yvalue[i] = 0.;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Add( G4double s1, G4double s2,
|
||||
const G4HEPlot & p1, const G4HEPlot & p2 )
|
||||
{
|
||||
if(p1.Nbin != p2.Nbin)
|
||||
{
|
||||
cout << "G4HEPlot::Add: Plots must have same number of bins !" << endl;
|
||||
return;
|
||||
}
|
||||
if(Nbin != p1.Nbin)
|
||||
{
|
||||
cout << "G4HEPlot::Add: Plot must be initialized before using it !" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for(G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
Yvalue[i] = s1*p1.Yvalue[i] + s2*p2.Yvalue[i];
|
||||
}
|
||||
Entries = p1.Entries + p2.Entries;
|
||||
EntriesOverflow = p1.EntriesOverflow + p2.EntriesOverflow;
|
||||
EntriesUnderflow = p1.EntriesUnderflow + p2.EntriesUnderflow;
|
||||
Weight = s1*p1.Weight + s2*p2.Weight;
|
||||
WeightUnderflow = s1*p1.WeightUnderflow + s2*p2.WeightUnderflow;
|
||||
WeightOverflow = s1*p1.WeightOverflow + s2*p2.WeightOverflow;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Multiply( G4double s1, G4double s2,
|
||||
const G4HEPlot & p1, const G4HEPlot & p2 )
|
||||
{
|
||||
if(p1.Nbin != p2.Nbin)
|
||||
{
|
||||
cout << "G4HEPlot::Multiply: Plots must have same number of bins !" << endl;
|
||||
return;
|
||||
}
|
||||
if(Nbin != p1.Nbin)
|
||||
{
|
||||
cout << "G4HEPlot::Multiply: Plot must be initialized before using it !" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for(G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
Yvalue[i] = s1*p1.Yvalue[i]* s2*p2.Yvalue[i];
|
||||
}
|
||||
Entries = p1.Entries * p2.Entries;
|
||||
EntriesOverflow = p1.EntriesOverflow * p2.EntriesOverflow;
|
||||
EntriesUnderflow = p1.EntriesUnderflow * p2.EntriesUnderflow;
|
||||
Weight = s1*p1.Weight * s2*p2.Weight;
|
||||
WeightUnderflow = s1*p1.WeightUnderflow * s2*p2.WeightUnderflow;
|
||||
WeightOverflow = s1*p1.WeightOverflow * s2*p2.WeightOverflow;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Divide( G4double s1, G4double s2,
|
||||
const G4HEPlot & p1, const G4HEPlot & p2 )
|
||||
{
|
||||
if(p1.Nbin != p2.Nbin)
|
||||
{
|
||||
cout << "G4HEPlot::Divide: Plots must have same number of bins !" << endl;
|
||||
return;
|
||||
}
|
||||
if(Nbin != p1.Nbin)
|
||||
{
|
||||
cout << "G4HEPlot::Divide: Plot must be defined before using it !" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for(G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
if(p2.Yvalue[i] == 0.)
|
||||
{
|
||||
Yvalue[i] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
Yvalue[i] = (s1*p1.Yvalue[i]) / (s2*p2.Yvalue[i]);
|
||||
}
|
||||
}
|
||||
if(p2.Entries > 0)
|
||||
Entries = p1.Entries / p2.Entries;
|
||||
if(p2.EntriesOverflow > 0)
|
||||
EntriesOverflow = p1.EntriesOverflow / p2.EntriesOverflow;
|
||||
if(p2.EntriesUnderflow > 0)
|
||||
EntriesUnderflow = p1.EntriesUnderflow / p2.EntriesUnderflow;
|
||||
if(p2.Weight != 0.)
|
||||
Weight = s1*p1.Weight / s2*p2.Weight;
|
||||
if(p2.WeightUnderflow != 0.)
|
||||
WeightUnderflow = s1*p1.WeightUnderflow / s2*p2.WeightUnderflow;
|
||||
if(p2.WeightOverflow != 0.)
|
||||
WeightOverflow = s1*p1.WeightOverflow / s2*p2.WeightOverflow;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Scale( G4double s, const G4HEPlot & p)
|
||||
{
|
||||
if(Nbin != p.Nbin)
|
||||
{
|
||||
cout << "G4HEPlot::Add: Plot must be defined before using it !" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for(G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
Yvalue[i] = s*p.Yvalue[i];
|
||||
}
|
||||
Entries = p.Entries ;
|
||||
EntriesOverflow = p.EntriesOverflow;
|
||||
EntriesUnderflow = p.EntriesUnderflow;
|
||||
Weight = s*p.Weight;
|
||||
WeightUnderflow = s*p.WeightUnderflow;
|
||||
WeightOverflow = s*p.WeightOverflow;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::XScale(G4double a, G4double b, const G4HEPlot & p)
|
||||
{
|
||||
G4int i;
|
||||
Entries = 0;
|
||||
EntriesOverflow = 0;
|
||||
EntriesUnderflow = 0;
|
||||
Weight = 0.;
|
||||
WeightOverflow = 0.;
|
||||
WeightUnderflow = 0.;
|
||||
Xstart = p.Xstart;
|
||||
Xbin = p.Xbin;
|
||||
Nbin = p.Nbin;
|
||||
for(i=0; i<Nbin; i++)
|
||||
{
|
||||
Xvalue[i] = p.Yvalue[i];
|
||||
Yvalue[i] = 0.;
|
||||
}
|
||||
G4double xval = Xstart - Xbin/2.;
|
||||
for(i=0; i<Nbin; i++)
|
||||
{
|
||||
xval += Xbin;
|
||||
Fill(xval*a + b, Xvalue[i]);
|
||||
}
|
||||
for(i=0; i<Nbin; i++)
|
||||
{
|
||||
Xvalue[i] = Xstart + i*Xbin;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Log( G4double s, const G4HEPlot & p)
|
||||
{
|
||||
if(Nbin != p.Nbin)
|
||||
{
|
||||
cout << "G4HEPlot::Log: Plot must be defined before using it !" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for(G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
if(s*p.Yvalue[i] <= 0.) Yvalue[i] = 0.;
|
||||
else Yvalue[i] = log10(s*p.Yvalue[i]);
|
||||
}
|
||||
|
||||
Entries = p.Entries ;
|
||||
EntriesOverflow = p.EntriesOverflow;
|
||||
EntriesUnderflow = p.EntriesUnderflow;
|
||||
if(p.Weight > 0)
|
||||
Weight = log10(s*p.Weight);
|
||||
if(p.WeightUnderflow > 0)
|
||||
WeightUnderflow = log10(s*p.WeightUnderflow);
|
||||
if(p.WeightOverflow > 0)
|
||||
WeightOverflow = log10(s*p.WeightOverflow);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Sqrt(G4double s, const G4HEPlot & p)
|
||||
{
|
||||
if(Nbin != p.Nbin)
|
||||
{
|
||||
cout << " G4HEPlot::Sqrt: Plot must be defined before using it !" << endl;
|
||||
return;
|
||||
}
|
||||
for (G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
if(s*p.Yvalue[i] <= 0.) Yvalue[i] = 0.;
|
||||
else Yvalue[i] = sqrt(s*p.Yvalue[i]);
|
||||
}
|
||||
Entries = p.Entries;
|
||||
EntriesOverflow = p.EntriesOverflow;
|
||||
EntriesUnderflow = p.EntriesUnderflow;
|
||||
if(s*p.Weight > 0.) Weight = sqrt(s*p.Weight);
|
||||
if(s*p.WeightUnderflow > 0.) WeightUnderflow = sqrt(s*p.WeightUnderflow);
|
||||
if(s*p.WeightOverflow > 0.) WeightOverflow = sqrt(s*p.WeightOverflow);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Reset()
|
||||
{
|
||||
for(G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
Yvalue[i] = 0.;
|
||||
}
|
||||
Entries = 0;
|
||||
EntriesOverflow = 0;
|
||||
EntriesUnderflow = 0;
|
||||
Weight = 0.;
|
||||
WeightOverflow = 0.;
|
||||
WeightUnderflow = 0.;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Fill(G4double x, G4double weight)
|
||||
{
|
||||
G4int i = (int)((x - Xstart)/Xbin);
|
||||
if(i < 0)
|
||||
{
|
||||
EntriesUnderflow++;
|
||||
WeightUnderflow += weight;
|
||||
}
|
||||
else if(i >= Nbin)
|
||||
{
|
||||
EntriesOverflow++;
|
||||
WeightOverflow += weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entries++;
|
||||
Weight += weight;
|
||||
Yvalue[i] += weight;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::Print( G4String name, G4int iplot)
|
||||
{
|
||||
cout << name << iplot << " = new TH1F(" << '"' << iplot
|
||||
<< '"' << "," << '"' << '"' << "," << Nbin << ","
|
||||
<< Xstart << "," << Xstart+Nbin*Xbin << ");" << endl;
|
||||
cout << "for(I=1; I<=" << Nbin <<"; I++) {" << endl;
|
||||
cout << "Y[I] = 0.;" << endl;
|
||||
cout << "}" << endl;
|
||||
for (G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
cout << "Y[" << i+1 << "] = " << Yvalue[i] << ";" << endl;
|
||||
}
|
||||
cout << "XA = " << Xstart << ";" << endl;
|
||||
cout << "STEP2 = " << Xbin/2. << ";" << endl;
|
||||
cout << "for(I=1; I<=" << Nbin << "; I++) {" << endl;
|
||||
cout << "XA = XA + STEP2;" << endl;
|
||||
cout << name << iplot << "->Fill(XA,Y[I]);" << endl;
|
||||
cout << "XA = XA + STEP2;" << endl;
|
||||
cout << "}" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::DumpToFile(G4int aPlot, G4String aName)
|
||||
{
|
||||
FILE* fz;
|
||||
fz = fopen(aName, "a");
|
||||
fprintf(fz,"%3d %3d %12.5e %12.5e \n",aPlot, Nbin, Xstart, Xbin);
|
||||
G4double xval = Xstart - Xbin/2.;
|
||||
for(G4int i=0; i<Nbin; i++)
|
||||
{
|
||||
xval += Xbin;
|
||||
fprintf(fz,"%12.5e %12.5e \n", xval, Yvalue[i]);
|
||||
}
|
||||
fclose(fz);
|
||||
}
|
||||
|
||||
void
|
||||
G4HEPlot::GetFromFile(G4int aPlot, G4String aName)
|
||||
{
|
||||
FILE* fz;
|
||||
G4int ip, nb;
|
||||
G4double xs,xb,x,y;
|
||||
if((fz = fopen(aName, "r")) != NULL)
|
||||
{
|
||||
while(fscanf(fz,"%ld %ld %le %le", &ip, &nb, &xs, &xb)==4)
|
||||
{
|
||||
if(ip == aPlot)
|
||||
{
|
||||
if(Nbin != nb) Init(nb, xs, xb);
|
||||
}
|
||||
for (G4int i=0; i<nb; i++)
|
||||
{
|
||||
fscanf(fz,"%le %le", &x, &y);
|
||||
if(ip == aPlot) Fill(x,y);
|
||||
}
|
||||
if(ip == aPlot) break;
|
||||
}
|
||||
fclose(fz);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << " File " << aName << " not found " << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,512 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998.
|
||||
|
||||
#include "G4HEProtonInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEProtonInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
SetParticles();
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "Z , A = " << atomicNumber << " " << atomicWeight << endl;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentParticle.getKineticEnergy();
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEProtonInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEProtonInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName() << " "
|
||||
<< "mass " << incidentMass << " "
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << " " << excitationEnergyGNP << " "
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasProton(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEProtonInelastic::FirstIntInCasProton( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.35;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
G4double pionMass = PionPlus.getMass();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,c)
|
||||
/(Factorial(2-np+nm)*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,neutb,c)
|
||||
/(Factorial(1-np+nm)*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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
if( targetCode == neutronCode )
|
||||
{
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*2.5 ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{ // charge exchange pi+ n -> pi0 p
|
||||
pv[0] = PionZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= pionMass)
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
G4double eab = availableEnergy;
|
||||
G4int ieab = G4int( eab*5.0 );
|
||||
|
||||
G4double supp[] = {0., 0.4, 0.55, 0.65, 0.75, 0.82, 0.86, 0.90, 0.94, 0.98};
|
||||
if( (ieab <= 9) && (G4UniformRand() >= supp[ieab]) )
|
||||
{
|
||||
// suppress high multiplicity events at low momentum
|
||||
// only one additional pion will be produced
|
||||
G4double w0, wp, wm, wt, ran;
|
||||
if( targetCode == protonCode ) // target is a proton
|
||||
{
|
||||
w0 = - sqr(1.+protb)/(2.*c*c);
|
||||
wp = w0 = exp(w0);
|
||||
if( G4UniformRand() < w0/(w0+wp) )
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
}
|
||||
else
|
||||
{ // target is a neutron
|
||||
w0 = -sqr(1.+neutb)/(2.*c*c);
|
||||
w0 = exp(w0);
|
||||
wp = w0/2.;
|
||||
wm = -sqr(-1.+neutb)/(2.*c*c);
|
||||
wm = exp(wm)/2.;
|
||||
wt = w0+wp+wm;
|
||||
wp = w0+wp;
|
||||
ran = G4UniformRand();
|
||||
if( ran < w0/wt)
|
||||
{ np = 0; nm = 0; nz = 1; }
|
||||
else if( ran < wp/wt)
|
||||
{ np = 1; nm = 0; nz = 0; }
|
||||
else
|
||||
{ np = 0; nm = 1; nz = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
}
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (1+nm))
|
||||
{
|
||||
if( G4UniformRand() < 0.5)
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
if( G4UniformRand() < 0.25)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if ( np == (1+nm))
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,522 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HESigmaMinusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HESigmaMinusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHESigmaMinusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HESigmaMinusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasSigmaMinus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HESigmaMinusInelastic::FirstIntInCasSigmaMinus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// Sigma- 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*2.5 ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( targetCode == neutronCode)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if(ran < 0.4)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if(ran < 0.6)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else if(ran < 0.8)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0, nm = 0, nz = 0;
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
if( targetCode == neutronCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
if( ran < 0.25)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.5)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ran < 0.5)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np == nm)
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getCode() << " " ;
|
||||
cout << pv[1].getCode() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getCode() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,522 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HESigmaPlusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HESigmaPlusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHESigmaPlusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HESigmaPlusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasSigmaPlus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HESigmaPlusInelastic::FirstIntInCasSigmaPlus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// Sigma+ 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*2.5 ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ran < 0.2)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if(ran < 0.4)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else if(ran < 0.6)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else if(ran < 0.8)
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
ran = G4UniformRand();
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( ran < 0.25)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
}
|
||||
else if(ran < 0.5)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ran < 0.5)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np == nm)
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
}
|
||||
else if (ran < 0.75)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HESigmaZeroInelastic.hh"
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
G4VParticleChange * G4HESigmaZeroInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4HELambdaInelastic theLambdaInelastic;
|
||||
theLambdaInelastic.SetMaxNumberOfSecondaries(MAXPART);
|
||||
theLambdaInelastic.SetVerboseLevel(verboseLevel);
|
||||
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double pgam = G4UniformRand()*incidentTotalMomentum*0.75;
|
||||
G4HEVector incidentLambda;
|
||||
incidentLambda.SmulAndUpdate( incidentParticle,
|
||||
(incidentTotalMomentum - pgam)/incidentTotalMomentum);
|
||||
G4DynamicParticle * aLambda = new G4DynamicParticle();
|
||||
aLambda->SetDefinition(G4Lambda::Lambda());
|
||||
G4Track aLambdaTrack(aLambda, 0, aTrack.GetPosition());
|
||||
aLambda->SetMomentum(incidentLambda.getMomentum());
|
||||
G4VParticleChange * result = theLambdaInelastic.ApplyYourself(aLambdaTrack, targetNucleus);
|
||||
vecLength = theLambdaInelastic.GetNumberOfSecondaries();
|
||||
|
||||
pv[vecLength] = Gamma;
|
||||
pv[vecLength].setMomentum(incidentParticle.getMomentum());
|
||||
pv[vecLength].SmulAndUpdate( pv[vecLength],pgam/incidentTotalMomentum);
|
||||
G4DynamicParticle * aPhoton = new G4DynamicParticle();
|
||||
aPhoton->SetDefinition(G4Gamma::Gamma());
|
||||
aPhoton->SetMomentum(pv[vecLength].getMomentum());
|
||||
G4Track * aGammaTrack = new G4Track(aPhoton, aTrack.GetGlobalTime(), aTrack.GetPosition());
|
||||
result->AddSecondary(aGammaTrack);
|
||||
delete [] pv;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,532 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEXiMinusInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEXiMinusInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEXiMinusInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEXiMinusInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasXiMinus(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEXiMinusInelastic::FirstIntInCasXiMinus( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// Xi0 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*2.5 ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( targetCode == neutronCode)
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = XiMinus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.3)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.5)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.7)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = XiMinus;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
// in the following we do not consider
|
||||
ran = G4UniformRand(); // strangeness transfer in high multiplicity
|
||||
if( targetCode == neutronCode) // events. YK combinations are added in
|
||||
{ // StrangeParticlePairProduction
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
if( ran < 0.50)
|
||||
{
|
||||
pv[0] = XiZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = XiZero;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np == nm)
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = XiZero;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = XiZero;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getName() << " " ;
|
||||
cout << pv[1].getName() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getName() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,542 @@
|
||||
// G4 Process: Gheisha High Energy Collision model.
|
||||
// This includes the high energy cascading model, the two-body-resonance model
|
||||
// and the low energy two-body model. Not included are the low energy stuff like
|
||||
// nuclear reactions, nuclear fission without any cascading and all processes for
|
||||
// particles at rest.
|
||||
// First work done by J.L.Chuma and F.W.Jones, TRIUMF, June 96.
|
||||
// H. Fesefeldt, RWTH-Aachen, 23-October-1996
|
||||
// Last modified: 29-July-1998
|
||||
|
||||
#include "G4HEXiZeroInelastic.hh"
|
||||
|
||||
G4VParticleChange * G4HEXiZeroInelastic::
|
||||
ApplyYourself( const G4Track &aTrack, G4Nucleus &targetNucleus )
|
||||
{
|
||||
G4HEVector * pv = new G4HEVector[MAXPART];
|
||||
theParticleChange.Initialize( aTrack );
|
||||
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
|
||||
G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle();
|
||||
const G4double A = targetNucleus.GetN();
|
||||
const G4double Z = targetNucleus.GetZ();
|
||||
G4HEVector incidentParticle(aParticle);
|
||||
|
||||
G4double atomicNumber = Z;
|
||||
G4double atomicWeight = A;
|
||||
|
||||
G4int incidentCode = incidentParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentTotalEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
G4double incidentKineticEnergy = incidentTotalEnergy - incidentMass;
|
||||
|
||||
if(incidentKineticEnergy < 1.)
|
||||
{
|
||||
cout << "GHEXiZeroInelastic: incident energy < 1 GeV" << endl;
|
||||
}
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
cout << "G4HEXiZeroInelastic::ApplyYourself" << endl;
|
||||
cout << "incident particle " << incidentParticle.getName()
|
||||
<< "mass " << incidentMass
|
||||
<< "kinetic energy " << incidentKineticEnergy
|
||||
<< endl;
|
||||
cout << "target material with (A,Z) = ("
|
||||
<< atomicWeight << "," << atomicNumber << ")" << endl;
|
||||
}
|
||||
|
||||
G4double inelasticity = NuclearInelasticity(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear inelasticity = " << inelasticity << endl;
|
||||
|
||||
incidentKineticEnergy -= inelasticity;
|
||||
|
||||
G4double excitationEnergyGNP = 0.;
|
||||
G4double excitationEnergyDTA = 0.;
|
||||
|
||||
G4double excitation = NuclearExcitation(incidentKineticEnergy,
|
||||
atomicWeight, atomicNumber,
|
||||
excitationEnergyGNP,
|
||||
excitationEnergyDTA);
|
||||
if(verboseLevel > 1)
|
||||
cout << "nuclear excitation = " << excitation << excitationEnergyGNP
|
||||
<< excitationEnergyDTA << endl;
|
||||
|
||||
|
||||
incidentKineticEnergy -= excitation;
|
||||
incidentTotalEnergy = incidentKineticEnergy + incidentMass;
|
||||
incidentTotalMomentum = sqrt( (incidentTotalEnergy-incidentMass)
|
||||
*(incidentTotalEnergy+incidentMass));
|
||||
|
||||
|
||||
G4HEVector targetParticle;
|
||||
if(G4UniformRand() < atomicNumber/atomicWeight)
|
||||
{
|
||||
targetParticle.setDefinition("Proton");
|
||||
}
|
||||
else
|
||||
{
|
||||
targetParticle.setDefinition("Neutron");
|
||||
}
|
||||
|
||||
G4double targetMass = targetParticle.getMass();
|
||||
G4double centerOfMassEnergy = sqrt( incidentMass*incidentMass + targetMass*targetMass
|
||||
+ 2.0*targetMass*incidentTotalEnergy);
|
||||
G4double availableEnergy = centerOfMassEnergy - targetMass - incidentMass;
|
||||
|
||||
// this was the meaning of inElastic in the
|
||||
// original Gheisha stand-alone version.
|
||||
// G4bool inElastic = InElasticCrossSectionInFirstInt
|
||||
// (availableEnergy, incidentCode, incidentTotalMomentum);
|
||||
// by unknown reasons, it has been replaced
|
||||
// to the following code in Geant???
|
||||
G4bool inElastic = true;
|
||||
// if (G4UniformRand() < elasticCrossSection/totalCrossSection) inElastic = false;
|
||||
|
||||
vecLength = 0;
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself: CallFirstIntInCascade for particle "
|
||||
<< incidentCode << endl;
|
||||
|
||||
G4bool successful = false;
|
||||
|
||||
if(inElastic || (!inElastic && atomicWeight < 1.5))
|
||||
{
|
||||
FirstIntInCasXiZero(inElastic, availableEnergy, pv, vecLength,
|
||||
incidentParticle, targetParticle, atomicWeight);
|
||||
|
||||
if(verboseLevel > 1)
|
||||
cout << "ApplyYourself::StrangeParticlePairProduction" << endl;
|
||||
|
||||
|
||||
if ((vecLength > 0) && (availableEnergy > 1.))
|
||||
StrangeParticlePairProduction( availableEnergy, centerOfMassEnergy,
|
||||
pv, vecLength,
|
||||
incidentParticle, targetParticle);
|
||||
HighEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
HighEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
MediumEnergyCascading( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
|
||||
if (!successful)
|
||||
MediumEnergyClusterProduction( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
if (!successful)
|
||||
QuasiElasticScattering( successful, pv, vecLength,
|
||||
excitationEnergyGNP, excitationEnergyDTA,
|
||||
incidentParticle, targetParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
ElasticScattering( successful, pv, vecLength,
|
||||
incidentParticle,
|
||||
atomicWeight, atomicNumber);
|
||||
}
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
cout << "GHEInelasticInteraction::ApplyYourself fails to produce final state particles" << endl;
|
||||
}
|
||||
FillParticleChange(pv, vecLength);
|
||||
delete [] pv;
|
||||
theParticleChange.SetStatusChange(fStopAndKill);
|
||||
return & theParticleChange;
|
||||
}
|
||||
|
||||
void
|
||||
G4HEXiZeroInelastic::FirstIntInCasXiZero( G4bool &inElastic,
|
||||
const G4double availableEnergy,
|
||||
G4HEVector pv[],
|
||||
G4int &vecLen,
|
||||
G4HEVector incidentParticle,
|
||||
G4HEVector targetParticle,
|
||||
const G4double atomicWeight)
|
||||
|
||||
// Xi0 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.
|
||||
|
||||
{
|
||||
static const G4double expxu = log(MAXFLOAT); // upper bound for arg. of exp
|
||||
static const G4double expxl = -expxu; // lower bound for arg. of exp
|
||||
|
||||
static const G4double protb = 0.7;
|
||||
static const G4double neutb = 0.7;
|
||||
static const G4double c = 1.25;
|
||||
|
||||
static const G4int numMul = 1200;
|
||||
static const G4int numSec = 60;
|
||||
|
||||
G4int neutronCode = Neutron.getCode();
|
||||
G4int protonCode = Proton.getCode();
|
||||
|
||||
G4int targetCode = targetParticle.getCode();
|
||||
G4double incidentMass = incidentParticle.getMass();
|
||||
G4double incidentEnergy = incidentParticle.getEnergy();
|
||||
G4double incidentTotalMomentum = incidentParticle.getTotalMomentum();
|
||||
|
||||
static G4bool first = true;
|
||||
static G4double protmul[numMul], protnorm[numSec]; // proton constants
|
||||
static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants
|
||||
|
||||
// misc. local variables
|
||||
// np = number of pi+, nm = number of pi-, nz = number of pi0
|
||||
|
||||
G4int i, counter, nt, np, nm, nz;
|
||||
|
||||
if( first )
|
||||
{ // compute normalization constants, this will only be done once
|
||||
first = false;
|
||||
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,protb,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,neutb,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
|
||||
|
||||
|
||||
// initialize the first two places
|
||||
// the same as beam and target
|
||||
pv[0] = incidentParticle;
|
||||
pv[1] = targetParticle;
|
||||
vecLen = 2;
|
||||
|
||||
if( !inElastic )
|
||||
{ // quasi-elastic scattering, no pions produced
|
||||
G4double cech[] = {0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.06, 0.04, 0.005, 0.};
|
||||
G4int iplab = G4int( min( 9.0, incidentTotalMomentum*2.5 ) );
|
||||
if( G4UniformRand() < cech[iplab]/pow(atomicWeight,0.42) )
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if( targetCode == protonCode)
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = SigmaPlus;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = SigmaPlus;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = XiZero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ran < 0.2)
|
||||
{
|
||||
pv[0] = Neutron;
|
||||
pv[1] = XiZero;
|
||||
}
|
||||
else if (ran < 0.3)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.4)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.5)
|
||||
{
|
||||
pv[0] = SigmaZero;
|
||||
pv[1] = Lambda;
|
||||
}
|
||||
else if (ran < 0.6)
|
||||
{
|
||||
pv[0] = Lambda;
|
||||
pv[1] = SigmaZero;
|
||||
}
|
||||
else if (ran < 0.7)
|
||||
{
|
||||
pv[0] = SigmaPlus;
|
||||
pv[1] = SigmaMinus;
|
||||
}
|
||||
else if (ran < 0.8)
|
||||
{
|
||||
pv[0] = SigmaMinus;
|
||||
pv[1] = SigmaPlus;
|
||||
}
|
||||
else if (ran < 0.9)
|
||||
{
|
||||
pv[0] = XiMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = Proton;
|
||||
pv[1] = XiMinus;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (availableEnergy <= PionPlus.getMass())
|
||||
return;
|
||||
|
||||
// inelastic scattering
|
||||
|
||||
np = 0; nm = 0; nz = 0;
|
||||
|
||||
// number of total particles vs. centre of mass Energy - 2*proton mass
|
||||
|
||||
G4double aleab = log(availableEnergy);
|
||||
G4double n = 3.62567+aleab*(0.665843+aleab*(0.336514
|
||||
+ aleab*(0.117712+0.0136912*aleab))) - 2.0;
|
||||
|
||||
// normalization constant for kno-distribution.
|
||||
// calculate first the sum of all constants, check for numerical problems.
|
||||
G4double test, dum, anpn = 0.0;
|
||||
|
||||
for( nt=1; nt<=numSec; nt++ )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = M_PI*nt/(2.0*n*n);
|
||||
if( fabs(dum) < 1.0 )
|
||||
if( test >= 1.0e-10 )anpn += dum*test;
|
||||
else
|
||||
anpn += dum*test;
|
||||
}
|
||||
|
||||
G4double ran = G4UniformRand();
|
||||
G4double excs = 0.0;
|
||||
if( targetCode == protonCode )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; //----------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering
|
||||
return;
|
||||
}
|
||||
else
|
||||
{ // target must be a neutron
|
||||
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>=1) && (nt<=numSec) )
|
||||
{
|
||||
test = exp( min( expxu, max( expxl, -(M_PI/4.0)*(nt*nt)/(n*n) ) ) );
|
||||
dum = (M_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) goto outOfLoop; // -------------------------->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3 previous loops continued to the end
|
||||
inElastic = false; // quasi-elastic scattering.
|
||||
return;
|
||||
}
|
||||
|
||||
outOfLoop: // <------------------------------------------------------------------------
|
||||
|
||||
// in the following we do not consider
|
||||
ran = G4UniformRand(); // strangeness transfer in high multiplicity
|
||||
if( targetCode == protonCode) // events. YK combinations are added in
|
||||
{ // StrangeParticlePairProduction
|
||||
if( np == nm)
|
||||
{
|
||||
}
|
||||
else if (np == (nm+1))
|
||||
{
|
||||
if( ran < 0.50)
|
||||
{
|
||||
pv[0] = XiMinus;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = XiMinus;
|
||||
pv[1] = Neutron;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np == nm)
|
||||
{
|
||||
if (ran < 0.5)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = XiMinus;
|
||||
pv[1] = Proton;
|
||||
}
|
||||
}
|
||||
else if (np == (nm-1))
|
||||
{
|
||||
pv[1] = Proton;
|
||||
}
|
||||
else
|
||||
{
|
||||
pv[0] = XiMinus;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nt = np + nm + nz;
|
||||
while ( nt > 0)
|
||||
{
|
||||
G4double ran = G4UniformRand();
|
||||
if ( ran < (G4double)np/nt)
|
||||
{
|
||||
if( np > 0 )
|
||||
{ pv[vecLen++] = PionPlus;
|
||||
np--;
|
||||
}
|
||||
}
|
||||
else if ( ran < (G4double)(np+nm)/nt)
|
||||
{
|
||||
if( nm > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionMinus;
|
||||
nm--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nz > 0 )
|
||||
{
|
||||
pv[vecLen++] = PionZero;
|
||||
nz--;
|
||||
}
|
||||
}
|
||||
nt = np + nm + nz;
|
||||
}
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
cout << "Particles produced: " ;
|
||||
cout << pv[0].getCode() << " " ;
|
||||
cout << pv[1].getCode() << " " ;
|
||||
for (i=2; i < vecLen; i++)
|
||||
{
|
||||
cout << pv[i].getCode() << " " ;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user