Import Geant4 11.1.2 source tree
This commit is contained in:
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-06-02 Vladimir Ivanchenko (emhighenergy-V11-00-05)
|
||||
- G4GammaConversionToMuons - fixed FPE exception in compound, when selected
|
||||
element and address issue of cross section factor reported in #2543
|
||||
|
||||
## 2022-11-23 Gabriele Cosmo (emhighenergy-V11-00-04)
|
||||
- Fixed more compilation warnings for implicit type conversions.
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4Step.hh"
|
||||
#include <vector>
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -137,6 +138,7 @@ private:
|
||||
const G4ParticleDefinition* theGamma;
|
||||
const G4ParticleDefinition* theMuonPlus;
|
||||
const G4ParticleDefinition* theMuonMinus;
|
||||
std::vector<G4double> fTemp;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -91,9 +91,17 @@ G4bool G4GammaConversionToMuons::IsApplicable(const G4ParticleDefinition& part)
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4GammaConversionToMuons::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
// Build cross section and mean free path tables
|
||||
{ //here no tables, just calling PrintInfoDefinition
|
||||
{
|
||||
Energy5DLimit = G4EmParameters::Instance()->MaxEnergyFor5DMuPair();
|
||||
|
||||
auto table = G4Material::GetMaterialTable();
|
||||
std::size_t nelm = 0;
|
||||
for(auto const & mat : *table) {
|
||||
std::size_t n = mat->GetNumberOfElements();
|
||||
nelm = std::max(nelm, n);
|
||||
}
|
||||
fTemp.resize(nelm, 0);
|
||||
|
||||
if(Energy5DLimit > 0.0 && nullptr != f5Dmodel) {
|
||||
f5Dmodel = new G4BetheHeitler5DModel();
|
||||
f5Dmodel->SetLeptonPair(theMuonPlus, theMuonMinus);
|
||||
@@ -108,15 +116,12 @@ void G4GammaConversionToMuons::BuildPhysicsTable(const G4ParticleDefinition& p)
|
||||
|
||||
G4double G4GammaConversionToMuons::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double, G4ForceCondition*)
|
||||
|
||||
// returns the photon mean free path in GEANT4 internal units
|
||||
// (MeanFreePath is a private member of the class)
|
||||
|
||||
{
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
const G4Material* aMaterial = aTrack.GetMaterial();
|
||||
return ComputeMeanFreePath(GammaEnergy, aMaterial);
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
const G4Material* aMaterial = aTrack.GetMaterial();
|
||||
return ComputeMeanFreePath(GammaEnergy, aMaterial);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -192,12 +197,11 @@ G4double G4GammaConversionToMuons::ComputeCrossSectionPerAtom(
|
||||
sigfac=4.*fine_structure_const*Z*Z*Rc*Rc;
|
||||
PowThres=1.479+0.00799*Dn;
|
||||
Ecor=-18.+4347./(B*Zthird);
|
||||
|
||||
|
||||
G4double CorFuc=1.+.04*G4Log(1.+Ecor/Egam);
|
||||
//G4double Eg=pow(1.-4.*Mmuon/Egam,PowThres)*pow( pow(Wsatur,PowSat)+
|
||||
// pow(Egam,PowSat),1./PowSat); // threshold and saturation
|
||||
G4double Eg=G4Exp(G4Log(1.-4.*Mmuon/Egam)*PowThres)*
|
||||
G4Exp(G4Log( G4Exp(G4Log(Wsatur)*PowSat)+G4Exp(G4Log(Egam)*PowSat))/PowSat);
|
||||
G4Exp(G4Log(G4Exp(G4Log(Wsatur)*PowSat) + G4Exp(G4Log(Egam)*PowSat))/PowSat);
|
||||
|
||||
G4double CrossSection=7./9.*sigfac*G4Log(1.+WMedAppr*CorFuc*Eg);
|
||||
CrossSection *= CrossSecFactor; // increase the CrossSection by (by default 1)
|
||||
return CrossSection;
|
||||
@@ -210,8 +214,10 @@ void G4GammaConversionToMuons::SetCrossSecFactor(G4double fac)
|
||||
{
|
||||
if(fac < 0.0) return;
|
||||
CrossSecFactor=fac;
|
||||
G4cout << "The cross section for GammaConversionToMuons is artificially "
|
||||
<< "increased by the CrossSecFactor=" << CrossSecFactor << G4endl;
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "The cross section for GammaConversionToMuons is artificially "
|
||||
<< "increased by the CrossSecFactor=" << CrossSecFactor << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -243,7 +249,6 @@ G4VParticleChange* G4GammaConversionToMuons::PostStepDoIt(
|
||||
std::vector<G4DynamicParticle*> fvect;
|
||||
f5Dmodel->SampleSecondaries(&fvect, aTrack.GetMaterialCutsCouple(),
|
||||
aTrack.GetDynamicParticle(), 0.0, DBL_MAX);
|
||||
aParticleChange.SetNumberOfSecondaries((G4int)fvect.size());
|
||||
for(auto dp : fvect) { aParticleChange.AddSecondary(dp); }
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
@@ -276,33 +281,41 @@ G4VParticleChange* G4GammaConversionToMuons::PostStepDoIt(
|
||||
G4double GammaMuonInv=Mmuon/Egam;
|
||||
|
||||
// generate xPlus according to the differential cross section by rejection
|
||||
G4double xmin=(Egam < LimitEnergy) ? GammaMuonInv : .5-sqrt(.25-GammaMuonInv);
|
||||
G4double xmin=(Egam <= LimitEnergy) ? 0.5 : 0.5 - std::sqrt(0.25 - GammaMuonInv);
|
||||
G4double xmax=1.-xmin;
|
||||
|
||||
G4double Ds2=(Dn*sqrte-2.);
|
||||
G4double sBZ=sqrte*B*Zthird/electron_mass_c2;
|
||||
G4double LogWmaxInv=1./G4Log(Winfty*(1.+2.*Ds2*GammaMuonInv)
|
||||
/(1.+2.*sBZ*Mmuon*GammaMuonInv));
|
||||
G4double xPlus,xMinus,xPM,result,W;
|
||||
G4double xPlus = 0.5;
|
||||
G4double xMinus = 0.5;
|
||||
G4double xPM = 0.25;
|
||||
|
||||
G4int nn = 0;
|
||||
const G4int nmax = 1000;
|
||||
do {
|
||||
xPlus=xmin+G4UniformRand()*(xmax-xmin);
|
||||
xMinus=1.-xPlus;
|
||||
xPM=xPlus*xMinus;
|
||||
G4double del=Mmuon*Mmuon/(2.*Egam*xPM);
|
||||
W=Winfty*(1.+Ds2*del/Mmuon)/(1.+sBZ*del);
|
||||
G4double xxp=1.-4./3.*xPM; // the main xPlus dependence
|
||||
result=(xxp > 0.) ? xxp*G4Log(W)*LogWmaxInv : 0.0;
|
||||
if(result>1.) {
|
||||
G4cout << "G4GammaConversionToMuons::PostStepDoIt WARNING:"
|
||||
<< " in dSigxPlusGen, result=" << result << " > 1" << G4endl;
|
||||
|
||||
// sampling for Egam > LimitEnergy
|
||||
if (xmin < 0.5) {
|
||||
G4double result,W;
|
||||
do {
|
||||
xPlus=xmin+G4UniformRand()*(xmax-xmin);
|
||||
xMinus=1.-xPlus;
|
||||
xPM=xPlus*xMinus;
|
||||
G4double del=Mmuon*Mmuon/(2.*Egam*xPM);
|
||||
W=Winfty*(1.+Ds2*del/Mmuon)/(1.+sBZ*del);
|
||||
G4double xxp=1.-4./3.*xPM; // the main xPlus dependence
|
||||
result=(xxp > 0.) ? xxp*G4Log(W)*LogWmaxInv : 0.0;
|
||||
if(result>1.) {
|
||||
G4cout << "G4GammaConversionToMuons::PostStepDoIt WARNING:"
|
||||
<< " in dSigxPlusGen, result=" << result << " > 1" << G4endl;
|
||||
}
|
||||
++nn;
|
||||
if(nn >= nmax) { break; }
|
||||
}
|
||||
++nn;
|
||||
if(nn >= nmax) { break; }
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
while (G4UniformRand() > result);
|
||||
}
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
while (G4UniformRand() > result);
|
||||
|
||||
// now generate the angular variables via the auxilary variables t,psi,rho
|
||||
G4double t;
|
||||
@@ -406,7 +419,7 @@ G4VParticleChange* G4GammaConversionToMuons::PostStepDoIt(
|
||||
// rotate to actual gamma direction
|
||||
MuPlusDirection.rotateUz(GammaDirection);
|
||||
MuMinusDirection.rotateUz(GammaDirection);
|
||||
aParticleChange.SetNumberOfSecondaries(2);
|
||||
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1 =
|
||||
new G4DynamicParticle(theMuonPlus,MuPlusDirection,EPlus-Mmuon);
|
||||
@@ -431,18 +444,24 @@ const G4Element* G4GammaConversionToMuons::SelectRandomAtom(
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
const G4Element* elm = (*theElementVector)[0];
|
||||
|
||||
if (NumberOfElements > 1) {
|
||||
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double PartialSumSigma = 0.;
|
||||
G4double rval = G4UniformRand()/MeanFreePath;
|
||||
if (NumberOfElements > 1) {
|
||||
G4double e = std::max(aDynamicGamma->GetKineticEnergy(), LimitEnergy);
|
||||
const G4double* natom = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double sum = 0.;
|
||||
for (std::size_t i=0; i<NumberOfElements; ++i)
|
||||
{
|
||||
elm = (*theElementVector)[i];
|
||||
PartialSumSigma += NbOfAtomsPerVolume[i]
|
||||
*GetCrossSectionPerAtom(aDynamicGamma, elm);
|
||||
if (rval <= PartialSumSigma) { break; }
|
||||
sum += natom[i]*ComputeCrossSectionPerAtom(e, elm->GetZasInt());
|
||||
fTemp[i] = sum;
|
||||
}
|
||||
sum *= G4UniformRand();
|
||||
for (std::size_t i=0; i<NumberOfElements; ++i)
|
||||
{
|
||||
if(sum <= fTemp[i]) {
|
||||
elm = (*theElementVector)[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return elm;
|
||||
@@ -458,6 +477,7 @@ void G4GammaConversionToMuons::PrintInfoDefinition()
|
||||
G4cout << " good cross section parametrization from "
|
||||
<< G4BestUnit(LowestEnergyLimit,"Energy")
|
||||
<< " to " << HighestEnergyLimit/GeV << " GeV for all Z." << G4endl;
|
||||
G4cout << " cross section factor: " << CrossSecFactor << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -6,6 +6,15 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-04-10 V.Ivanchenko (emmuons-V11-00-08)
|
||||
- G4MuBremsstrahlung, G4MuPairProduction - fix problem #2531, spline flag
|
||||
was lost for mu-, pi-, K-, and pbar dedx and range tables, the max observed
|
||||
problem was for mu- with momentum ~50 MeV/c, ~5 % biased range
|
||||
- G4MuBetheBlochModel - enable option to use angular generator for sampling
|
||||
of delta-electron direction
|
||||
- G4MuIonisation - implement full schema of selection of the model of
|
||||
energy loss fluctuation
|
||||
|
||||
## 2022-11-23 Gabriele Cosmo (emmuons-V11-00-07)
|
||||
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ private:
|
||||
G4ParticleChangeForLoss* fParticleChange = nullptr;
|
||||
G4EmCorrections* corr = nullptr;
|
||||
|
||||
G4double limitRadCorrection;
|
||||
G4double limitKinEnergy;
|
||||
G4double logLimitKinEnergy;
|
||||
G4double mass = 1.0;
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#include "G4ParticleChangeForLoss.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4DeltaAngle.hh"
|
||||
|
||||
G4double G4MuBetheBlochModel::xgi[]={ 0.0199, 0.1017, 0.2372, 0.4083, 0.5917,
|
||||
0.7628, 0.8983, 0.9801 };
|
||||
@@ -76,6 +77,7 @@ G4double G4MuBetheBlochModel::wgi[]={ 0.0506, 0.1112, 0.1569, 0.1813, 0.1813,
|
||||
G4MuBetheBlochModel::G4MuBetheBlochModel(const G4ParticleDefinition* p,
|
||||
const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
limitRadCorrection(250.*CLHEP::MeV),
|
||||
limitKinEnergy(100.*CLHEP::keV),
|
||||
logLimitKinEnergy(G4Log(limitKinEnergy)),
|
||||
twoln10(2.0*G4Log(10.0)),
|
||||
@@ -125,6 +127,9 @@ void G4MuBetheBlochModel::Initialise(const G4ParticleDefinition* p,
|
||||
SetParticle(p);
|
||||
if(nullptr == fParticleChange) {
|
||||
fParticleChange = GetParticleChangeForLoss();
|
||||
if(UseAngularGeneratorFlag() && nullptr == GetAngularDistribution()) {
|
||||
SetAngularDistribution(new G4DeltaAngle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +155,7 @@ G4double G4MuBetheBlochModel::ComputeCrossSectionPerElectron(
|
||||
0.5*(maxEnergy - cutEnergy)/energy2;
|
||||
|
||||
// radiative corrections of R. Kokoulin
|
||||
if (maxEnergy > limitKinEnergy) {
|
||||
if (maxEnergy > limitKinEnergy && kineticEnergy > limitRadCorrection) {
|
||||
|
||||
G4double logtmax = G4Log(maxEnergy);
|
||||
G4double logtmin = G4Log(std::max(cutEnergy,limitKinEnergy));
|
||||
@@ -231,12 +236,11 @@ G4double G4MuBetheBlochModel::ComputeDEDXPerVolume(const G4Material* material,
|
||||
G4double x = G4Log(bg2)/twoln10;
|
||||
dedx -= material->GetIonisation()->DensityCorrection(x);
|
||||
|
||||
// shell correction
|
||||
// shell and high order corrections
|
||||
dedx -= 2.0*corr->ShellCorrection(p,material,kineticEnergy);
|
||||
dedx = std::max(dedx, 0.0);
|
||||
|
||||
// radiative corrections of R. Kokoulin
|
||||
if (cutEnergy > limitKinEnergy) {
|
||||
if (cutEnergy > limitKinEnergy && kineticEnergy > limitRadCorrection) {
|
||||
|
||||
G4double logtmax = G4Log(cutEnergy);
|
||||
G4double logstep = logtmax - logLimitKinEnergy;
|
||||
@@ -251,7 +255,6 @@ G4double G4MuBetheBlochModel::ComputeDEDXPerVolume(const G4Material* material,
|
||||
}
|
||||
dedx += dloss*logstep*alphaprime;
|
||||
}
|
||||
|
||||
dedx *= CLHEP::twopi_mc2_rcl2*eDensity/beta2;
|
||||
|
||||
//High order corrections
|
||||
@@ -264,7 +267,7 @@ G4double G4MuBetheBlochModel::ComputeDEDXPerVolume(const G4Material* material,
|
||||
|
||||
void G4MuBetheBlochModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vdp,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double minKinEnergy,
|
||||
G4double maxEnergy)
|
||||
@@ -279,7 +282,8 @@ void G4MuBetheBlochModel::SampleSecondaries(
|
||||
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/etot2;
|
||||
|
||||
G4double grej = 1.;
|
||||
if(tmax > limitKinEnergy) {
|
||||
G4bool radC = (tmax > limitKinEnergy && kineticEnergy > limitRadCorrection);
|
||||
if(radC) {
|
||||
G4double a0 = G4Log(2.*totEnergy/mass);
|
||||
grej += alphaprime*a0*a0;
|
||||
}
|
||||
@@ -292,7 +296,7 @@ void G4MuBetheBlochModel::SampleSecondaries(
|
||||
tkin = minKinEnergy*maxKinEnergy/(minKinEnergy*(1.0 - q) + maxKinEnergy*q);
|
||||
f = 1.0 - beta2*tkin/tmax + 0.5*tkin*tkin/etot2;
|
||||
|
||||
if(tkin > limitKinEnergy) {
|
||||
if(radC && tkin > limitKinEnergy) {
|
||||
G4double a1 = G4Log(1.0 + 2.0*tkin/CLHEP::electron_mass_c2);
|
||||
G4double a3 = G4Log(4.0*totEnergy*(totEnergy - tkin)/massSquare);
|
||||
f *= (1. + alphaprime*a1*(a3 - a1));
|
||||
@@ -308,29 +312,35 @@ void G4MuBetheBlochModel::SampleSecondaries(
|
||||
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
|
||||
} while( grej*G4UniformRand() > f );
|
||||
|
||||
G4double deltaMomentum =
|
||||
std::sqrt(tkin * (tkin + 2.0*CLHEP::electron_mass_c2));
|
||||
G4double totalMomentum = totEnergy*std::sqrt(beta2);
|
||||
G4double cost = tkin * (totEnergy + CLHEP::electron_mass_c2) /
|
||||
(deltaMomentum * totalMomentum);
|
||||
G4ThreeVector deltaDirection;
|
||||
|
||||
G4double sint = std::sqrt(1.0 - cost*cost);
|
||||
G4double phi = CLHEP::twopi * G4UniformRand();
|
||||
G4ThreeVector deltaDirection(sint*std::cos(phi), sint*std::sin(phi), cost);
|
||||
G4ThreeVector direction = dp->GetMomentumDirection();
|
||||
deltaDirection.rotateUz(direction);
|
||||
if(UseAngularGeneratorFlag()) {
|
||||
const G4Material* mat = couple->GetMaterial();
|
||||
deltaDirection = GetAngularDistribution()->SampleDirection(dp, tkin,
|
||||
SelectRandomAtomNumber(mat), mat);
|
||||
} else {
|
||||
|
||||
G4double deltaMom = std::sqrt(tkin * (tkin + 2.0*CLHEP::electron_mass_c2));
|
||||
G4double totalMom = totEnergy*std::sqrt(beta2);
|
||||
G4double cost = tkin * (totEnergy + CLHEP::electron_mass_c2) /
|
||||
(deltaMom * totalMom);
|
||||
cost = std::min(cost, 1.0);
|
||||
const G4double sint = std::sqrt((1.0 - cost)*(1.0 + cost));
|
||||
const G4double phi = twopi*G4UniformRand();
|
||||
|
||||
deltaDirection.set(sint*std::cos(phi),sint*std::sin(phi), cost) ;
|
||||
deltaDirection.rotateUz(dp->GetMomentumDirection());
|
||||
}
|
||||
// create G4DynamicParticle object for delta ray
|
||||
auto delta = new G4DynamicParticle(theElectron, deltaDirection, tkin);
|
||||
vdp->push_back(delta);
|
||||
|
||||
// primary change
|
||||
kineticEnergy -= tkin;
|
||||
G4ThreeVector dir = totalMomentum*direction - deltaMomentum*deltaDirection;
|
||||
direction = dir.unit();
|
||||
G4ThreeVector dir = dp->GetMomentum() - delta->GetMomentum();
|
||||
dir = dir.unit();
|
||||
fParticleChange->SetProposedKineticEnergy(kineticEnergy);
|
||||
fParticleChange->SetProposedMomentumDirection(direction);
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
G4DynamicParticle* delta =
|
||||
new G4DynamicParticle(theElectron, deltaDirection, tkin);
|
||||
vdp->push_back(delta);
|
||||
fParticleChange->SetProposedMomentumDirection(dir);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -79,7 +79,6 @@ G4MuBremsstrahlung::G4MuBremsstrahlung(const G4String& name)
|
||||
SetProcessSubType(fBremsstrahlung);
|
||||
SetSecondaryParticle(G4Gamma::Gamma());
|
||||
SetIonisation(false);
|
||||
SetSpline(false);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -124,6 +124,7 @@ G4MuIonisation::InitialiseEnergyLossProcess(const G4ParticleDefinition* part,
|
||||
theBaseParticle = bpart;
|
||||
|
||||
mass = theParticle->GetPDGMass();
|
||||
ratio = CLHEP::electron_mass_c2/mass;
|
||||
G4double q = theParticle->GetPDGCharge();
|
||||
|
||||
G4EmParameters* param = G4EmParameters::Instance();
|
||||
@@ -138,13 +139,11 @@ G4MuIonisation::InitialiseEnergyLossProcess(const G4ParticleDefinition* part,
|
||||
EmModel(0)->SetLowEnergyLimit(param->MinKinEnergy());
|
||||
EmModel(0)->SetHighEnergyLimit(elow);
|
||||
|
||||
// high energy fluctuation model
|
||||
// fluctuation model
|
||||
if (nullptr == FluctModel()) {
|
||||
SetFluctModel(G4EmStandUtil::ModelOfFluctuations());
|
||||
}
|
||||
// low-energy fluctuation model
|
||||
G4VEmFluctuationModel* f = G4EmStandUtil::ModelOfFluctuations(true);
|
||||
AddEmModel(1, EmModel(0), f);
|
||||
AddEmModel(1, EmModel(0), FluctModel());
|
||||
|
||||
// high energy model
|
||||
if (nullptr == EmModel(1)) { SetEmModel(new G4MuBetheBlochModel()); }
|
||||
@@ -152,7 +151,6 @@ G4MuIonisation::InitialiseEnergyLossProcess(const G4ParticleDefinition* part,
|
||||
EmModel(1)->SetHighEnergyLimit(emax);
|
||||
AddEmModel(1, EmModel(1), FluctModel());
|
||||
|
||||
ratio = CLHEP::electron_mass_c2/mass;
|
||||
isInitialised = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@ G4MuPairProduction::G4MuPairProduction(const G4String& name)
|
||||
SetProcessSubType(fPairProdByCharged);
|
||||
SetSecondaryParticle(G4Positron::Positron());
|
||||
SetIonisation(false);
|
||||
SetSpline(false);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -6,6 +6,23 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-06-13 V.Ivanchenko (emstand-V11-00-24)
|
||||
- G4LindhardSorensenIonModel - do not try to use ICRU73 data for projectile Z>80
|
||||
|
||||
## 2023-04-20 V.Ivanchenko (emstand-V11-00-23)
|
||||
- G4LindhardSorensenIonModel - updated effective charge of an ion at each
|
||||
step of simulation or at each call to G4EmCalculator
|
||||
|
||||
## 2023-04-17 V.Ivanchenko
|
||||
- G4LinhardSorensenModel - added extra protection and improved debug printout
|
||||
|
||||
## 2023-02-24 V.Ivanchenko
|
||||
- G4WentzelOKandVIxSection - fix numeric instability for the extreme case of
|
||||
very small kinetic energy (< 1 eV)
|
||||
|
||||
## 2023-02-21 V.Ivanchenko
|
||||
- G4WentzelOKandVIxSection - fix #2530, improved comments
|
||||
|
||||
## 2022-12-21 V.Ivanchenko (emstand-V11-00-22)
|
||||
- G4GoudsmithSoundersonMscModel - fixed warning when build CMSSW
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class G4WentzelOKandVIxSection
|
||||
|
||||
public:
|
||||
|
||||
explicit G4WentzelOKandVIxSection(G4bool comb=true);
|
||||
explicit G4WentzelOKandVIxSection(G4bool combined=true);
|
||||
|
||||
virtual ~G4WentzelOKandVIxSection();
|
||||
|
||||
@@ -139,7 +139,10 @@ protected:
|
||||
G4double coeff;
|
||||
G4double cosTetMaxElec = 1.0;
|
||||
G4double cosTetMaxNuc = 1.0;
|
||||
G4double cosThetaMax = -1.0;
|
||||
|
||||
// for the combined mode it is cos(thetaMax)
|
||||
// for single scattering it is cos(thetaMin)
|
||||
G4double cosThetaMax = 1.0;
|
||||
|
||||
G4double chargeSquare = 0.0;
|
||||
G4double charge3 = 0.0;
|
||||
|
||||
@@ -121,7 +121,8 @@ G4LindhardSorensenIonModel::GetChargeSquareRatio(const G4ParticleDefinition* p,
|
||||
const G4Material* mat,
|
||||
G4double kinEnergy)
|
||||
{
|
||||
return corr->EffectiveChargeSquareRatio(p,mat,kinEnergy);
|
||||
chargeSquare = corr->EffectiveChargeSquareRatio(p,mat,kinEnergy);
|
||||
return chargeSquare;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -258,15 +259,17 @@ void G4LindhardSorensenIonModel::CorrectionsAlongStep(
|
||||
const G4double q2 = corr->EffectiveChargeSquareRatio(p, mat, e);
|
||||
const G4int Z = p->GetAtomicNumber();
|
||||
|
||||
G4double res;
|
||||
G4double res = 0.0;
|
||||
if(escaled <= fElimit) {
|
||||
// data from ICRU73 or ICRU90
|
||||
res = fIonData->GetDEDX(mat, Z, escaled, G4Log(escaled));
|
||||
/*
|
||||
G4cout << "GetDEDX for Z=" << Z << " in " << mat->GetName()
|
||||
<< " Escaled=" << escaled << " E="
|
||||
<< e << " dEdx=" << res << G4endl;
|
||||
*/
|
||||
if(Z > 2 && Z <= 80) {
|
||||
res = fIonData->GetDEDX(mat, Z, escaled, G4Log(escaled));
|
||||
/*
|
||||
G4cout << "GetDEDX for Z=" << Z << " in " << mat->GetName()
|
||||
<< " Escaled=" << escaled << " E="
|
||||
<< e << " dEdx=" << res << G4endl;
|
||||
*/
|
||||
}
|
||||
if(res > 0.0) {
|
||||
auto pcuts = couple->GetProductionCuts();
|
||||
G4double cut = (nullptr == pcuts) ? tmax : pcuts->GetProductionCut(1);
|
||||
@@ -310,16 +313,16 @@ void G4LindhardSorensenIonModel::CorrectionsAlongStep(
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LindhardSorensenIonModel::SampleSecondaries(
|
||||
vector<G4DynamicParticle*>* vdp,
|
||||
std::vector<G4DynamicParticle*>* vdp,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double minKinEnergy,
|
||||
G4double cut,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
// take into account formfactor
|
||||
G4double tmax = MaxSecondaryEnergy(dp->GetDefinition(),kineticEnergy);
|
||||
|
||||
G4double minKinEnergy = std::min(cut, tmax);
|
||||
G4double maxKinEnergy = std::min(maxEnergy,tmax);
|
||||
if(minKinEnergy >= maxKinEnergy) { return; }
|
||||
|
||||
|
||||
@@ -346,34 +346,32 @@ G4WentzelOKandVIxSection::SampleSingleScattering(G4double cosTMin,
|
||||
}
|
||||
}
|
||||
if(cost1 > cost2) {
|
||||
|
||||
G4double w1 = 1. - cost1 + screenZ;
|
||||
G4double w2 = 1. - cost2 + screenZ;
|
||||
G4double z1 = w1*w2/(w1 + rndmEngineMod->flat()*(w2 - w1)) - screenZ;
|
||||
|
||||
G4double w1 = 1. - cost1;
|
||||
G4double w2 = 1. - cost2;
|
||||
G4double w3 = rndmEngineMod->flat()*(w2 - w1);
|
||||
G4double z1 = ((w2 - w3)*screenZ + w1*w2)/(screenZ + w1 + w3);
|
||||
G4double fm = 1.0;
|
||||
|
||||
if(fNucFormfactor == fExponentialNF) {
|
||||
fm += formf*z1;
|
||||
fm = 1.0/(fm*fm);
|
||||
} else if(fNucFormfactor == fGaussianNF) {
|
||||
fm = G4Exp(-2*formf*z1);
|
||||
} else if(fNucFormfactor == fFlatNF) {
|
||||
static const G4double ccoef = 0.00508/MeV;
|
||||
static const G4double ccoef = 0.00508/CLHEP::MeV;
|
||||
G4double x = std::sqrt(2.*mom2*z1)*ccoef*2.;
|
||||
fm = FlatFormfactor(x);
|
||||
fm *= FlatFormfactor(x*0.6
|
||||
*fG4pow->A13(fNistManager->GetAtomicMassAmu(targetZ)));
|
||||
fm *= FlatFormfactor(x*0.6*fG4pow->A13(fNistManager->GetAtomicMassAmu(targetZ)));
|
||||
}
|
||||
// G4cout << " fm=" << fm << " " << fMottXSection << G4endl;
|
||||
G4double grej;
|
||||
if(fMottXSection) {
|
||||
if(nullptr != fMottXSection) {
|
||||
fMottXSection->SetupKinematic(tkin, targetZ);
|
||||
grej = fMottXSection->RatioMottRutherfordCosT(std::sqrt(z1))*fm*fm;
|
||||
} else {
|
||||
grej = (1. - z1*factB + factB1*targetZ*sqrt(z1*factB)*(2. - z1))
|
||||
*fm*fm/(1.0 + z1*factD);
|
||||
}
|
||||
// G4cout << "SampleSingleScattering: E= " << tkin << " z1= "
|
||||
// << z1 << " grej= "<< grej << " mottFact= "<< fMottFactor<< G4endl;
|
||||
if(fMottFactor*rndmEngineMod->flat() <= grej ) {
|
||||
// exclude "false" scattering due to formfactor and spin effect
|
||||
G4double cost = 1.0 - z1;
|
||||
|
||||
@@ -6,6 +6,25 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-06-02 J.Hahnfeld (emutils-V11-00-40)
|
||||
- Fixes to `G4TransportationWithMsc`:
|
||||
* Protect code for MultipleScattering
|
||||
* Fix type of particle change
|
||||
|
||||
## 2023-04-08 V.Ivanchenko
|
||||
- G4LossTableManager - improved debug printout and removed unused lines of code
|
||||
|
||||
## 2023-03-20 V.Ivanchenko
|
||||
- G4VEnergyLossProcess - fixed static analyzer warning
|
||||
- G4EmTableUtil - fixed verbose output and class comments
|
||||
|
||||
## 2023-03-06 J.Allison
|
||||
- Allow /process/em/QuantumEntanglement in G4State_Idle.
|
||||
|
||||
## 2023-02-21 V.Ivanchenko
|
||||
- G4EmExtraParameters - fixed AddPAIModel(...) method and improved comments
|
||||
- G4EmExtraParametersMessenger - fixed broadcasting
|
||||
|
||||
## 2022-12-11 V.Ivanchenko (emutils-V11-00-39)
|
||||
- G4EmParameters, G4EmParametersMessenger, added parameter, UI command,
|
||||
GetSet methods - MscPositronCorrection
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
class G4EmModelManager;
|
||||
class G4LossTableManager;
|
||||
class G4ParticleChangeForMSC;
|
||||
class G4ParticleDefinition;
|
||||
class G4Region;
|
||||
class G4VMscModel;
|
||||
@@ -84,6 +85,9 @@ class G4TransportationWithMsc : public G4Transportation
|
||||
G4EmModelManager* fModelManager;
|
||||
const G4ParticleDefinition* fFirstParticle = nullptr;
|
||||
|
||||
// For ScatteringType::MultipleScattering
|
||||
G4ParticleChangeForMSC* fParticleChangeForMSC = nullptr;
|
||||
|
||||
G4DynamicParticle* fSubStepDynamicParticle;
|
||||
G4Track* fSubStepTrack;
|
||||
G4Step* fSubStep;
|
||||
|
||||
@@ -225,20 +225,22 @@ void G4EmExtraParameters::AddPAIModel(const G4String& particle,
|
||||
{
|
||||
G4String r = CheckRegion(region);
|
||||
std::size_t nreg = m_regnamesPAI.size();
|
||||
for(std::size_t i=0; i<nreg; ++i) {
|
||||
if((m_particlesPAI[i] == particle ||
|
||||
m_particlesPAI[i] == "all" ||
|
||||
particle == "all") &&
|
||||
(m_regnamesPAI[i] == r ||
|
||||
m_regnamesPAI[i] == "DefaultRegionForTheWorld" ||
|
||||
r == "DefaultRegionForTheWorld") ) {
|
||||
|
||||
m_typesPAI[i] = type;
|
||||
if(particle == "all") { m_particlesPAI[i] = particle; }
|
||||
if(r == "DefaultRegionForTheWorld") { m_regnamesPAI[i] = r; }
|
||||
return;
|
||||
// in previously defined region other particles may be already defined
|
||||
// type should be overrided for the same region and particle
|
||||
for(std::size_t i=0; i<nreg; ++i) {
|
||||
if(m_regnamesPAI[i] == r) {
|
||||
if (particle == "all") {
|
||||
m_particlesPAI[i] = particle;
|
||||
m_typesPAI[i] = type;
|
||||
return;
|
||||
} else if(m_particlesPAI[i] == particle || m_particlesPAI[i] == "all") {
|
||||
m_typesPAI[i] = type;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// new regions and/or particles
|
||||
m_particlesPAI.push_back(particle);
|
||||
m_regnamesPAI.push_back(r);
|
||||
m_typesPAI.push_back(type);
|
||||
|
||||
@@ -81,6 +81,7 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
mscoCmd->SetGuidance(" regName : G4Region name");
|
||||
mscoCmd->SetGuidance(" emType : G4EmStandard, G4EmStandard_opt1, ...");
|
||||
mscoCmd->AvailableForStates(G4State_PreInit);
|
||||
mscoCmd->SetToBeBroadcasted(false);
|
||||
|
||||
auto mregName = new G4UIparameter("regName",'s',false);
|
||||
mscoCmd->SetParameter(mregName);
|
||||
@@ -250,7 +251,7 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
|
||||
qeCmd = new G4UIcmdWithABool("/process/em/QuantumEntanglement",this);
|
||||
qeCmd->SetGuidance("Enable quantum entanglement");
|
||||
qeCmd->AvailableForStates(G4State_PreInit);
|
||||
qeCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
qeCmd->SetToBeBroadcasted(false);
|
||||
|
||||
dirSplitTargetCmd = new G4UIcmdWith3VectorAndUnit("/process/em/setDirectionalSplittingTarget",this);
|
||||
|
||||
@@ -98,7 +98,7 @@ G4EmTableUtil::PrepareEmProcess(G4VEmProcess* proc,
|
||||
const G4DataVector* cuts = modelManager->Initialise(part, secPart, verb);
|
||||
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VEmProcess::PreparePhysicsTable() done for "
|
||||
G4cout << "### G4EmTableUtil::PreparePhysicsTable() done for "
|
||||
<< proc->GetProcessName()
|
||||
<< " and particle " << part->GetParticleName()
|
||||
<< G4endl;
|
||||
@@ -118,7 +118,7 @@ void G4EmTableUtil::BuildEmProcess(G4VEmProcess* proc,
|
||||
{
|
||||
G4String num = part->GetParticleName();
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VEmProcess::BuildPhysicsTable() for "
|
||||
G4cout << "### G4EmTableUtil::BuildPhysicsTable() for "
|
||||
<< proc->GetProcessName() << " and particle " << num
|
||||
<< " buildLambdaTable=" << toBuild << " master= " << master
|
||||
<< G4endl;
|
||||
@@ -178,7 +178,7 @@ void G4EmTableUtil::BuildEmProcess(G4VEmProcess* proc,
|
||||
}
|
||||
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VEmProcess::BuildPhysicsTable() done for "
|
||||
G4cout << "### G4EmTableUtil::BuildPhysicsTable() done for "
|
||||
<< proc->GetProcessName() << " and particle " << num
|
||||
<< " baseMat=" << baseMat << G4endl;
|
||||
}
|
||||
@@ -201,7 +201,7 @@ void G4EmTableUtil::BuildLambdaTable(G4VEmProcess* proc,
|
||||
const G4bool splineFlag)
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmProcess::BuildLambdaTable() for process "
|
||||
G4cout << "G4EmTableUtil::BuildLambdaTable() for process "
|
||||
<< proc->GetProcessName() << " and particle "
|
||||
<< part->GetParticleName() << G4endl;
|
||||
}
|
||||
@@ -290,7 +290,7 @@ void G4EmTableUtil::BuildLambdaTable(G4VEnergyLossProcess* proc,
|
||||
const G4bool splineFlag)
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EnergyLossProcess::BuildLambdaTable() for process "
|
||||
G4cout << "G4EmTableUtil::BuildLambdaTable() for process "
|
||||
<< proc->GetProcessName() << " and particle "
|
||||
<< part->GetParticleName() << G4endl;
|
||||
}
|
||||
@@ -340,8 +340,9 @@ G4EmTableUtil::CheckIon(G4VEnergyLossProcess* proc,
|
||||
const G4int verb, G4bool& isIon)
|
||||
{
|
||||
if(1 < verb) {
|
||||
G4cout << "G4VEnergyLossProcess::PreparePhysicsTable for "
|
||||
G4cout << "G4EmTableUtil::CheckIon for "
|
||||
<< proc->GetProcessName() << " for " << part->GetParticleName()
|
||||
<< " should be called from G4VEnergyLossProcess::PreparePhysicsTable"
|
||||
<< G4endl;
|
||||
}
|
||||
const G4ParticleDefinition* particle = partLocal;
|
||||
@@ -356,6 +357,8 @@ G4EmTableUtil::CheckIon(G4VEnergyLossProcess* proc,
|
||||
const G4ParticleDefinition* theGIon = G4GenericIon::GenericIon();
|
||||
isIon = true;
|
||||
|
||||
// this is a loop to compare pointers of G4GenericIon processes in order
|
||||
// to confirm that for given particle the G4GenericIon physics is used
|
||||
if(particle != theGIon) {
|
||||
G4ProcessManager* pm = theGIon->GetProcessManager();
|
||||
G4ProcessVector* v = pm->GetAlongStepProcessVector();
|
||||
@@ -465,7 +468,7 @@ void G4EmTableUtil::BuildDEDXTable(G4VEnergyLossProcess* proc,
|
||||
for(std::size_t i=0; i<numOfCouples; ++i) {
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4VEnergyLossProcess::BuildDEDXVector idx= " << i
|
||||
G4cout << "G4EmTableUtil::BuildDEDXVector idx= " << i
|
||||
<< " flagTable=" << table->GetFlag(i)
|
||||
<< " flagBuilder=" << bld->GetFlag(i) << G4endl;
|
||||
}
|
||||
@@ -491,7 +494,7 @@ void G4EmTableUtil::BuildDEDXTable(G4VEnergyLossProcess* proc,
|
||||
}
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4VEnergyLossProcess::BuildDEDXTable(): table is built for "
|
||||
G4cout << "G4EmTableUtil::BuildDEDXTable(): table is built for "
|
||||
<< part->GetParticleName()
|
||||
<< " and process " << proc->GetProcessName()
|
||||
<< G4endl;
|
||||
@@ -517,7 +520,7 @@ void G4EmTableUtil::PrepareMscProcess(G4VMultipleScattering* proc,
|
||||
part.GetParticleName() == "GenericIon") { isIon = true; }
|
||||
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
|
||||
G4cout << "### G4EmTableUtil::PrepearPhysicsTable() for "
|
||||
<< proc->GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< " isIon: " << isIon << " isMaster: " << master
|
||||
@@ -590,7 +593,7 @@ void G4EmTableUtil::BuildMscProcess(G4VMultipleScattering* proc,
|
||||
}
|
||||
}
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VMultipleScattering::BuildPhysicsTable() done for "
|
||||
G4cout << "### G4EmTableUtil::BuildPhysicsTable() done for "
|
||||
<< proc->GetProcessName()
|
||||
<< " and particle " << part.GetParticleName() << G4endl;
|
||||
}
|
||||
@@ -651,7 +654,7 @@ G4bool G4EmTableUtil::StoreTable(G4VProcess* ptr,
|
||||
if (1 < verb) G4cout << "Stored: " << name << G4endl;
|
||||
} else {
|
||||
res = false;
|
||||
G4cout << "Fail to store: " << name << G4endl;
|
||||
G4cout << "G4EmTableUtil::StoreTable fail to store: " << name << G4endl;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@@ -668,8 +671,10 @@ G4bool G4EmTableUtil::RetrieveTable(G4VProcess* ptr,
|
||||
{
|
||||
G4bool res = true;
|
||||
if (nullptr == aTable) { return res; }
|
||||
G4cout << tname << " table for " << part->GetParticleName()
|
||||
<< " will be retrieved " << G4endl;
|
||||
if (0 < verb) {
|
||||
G4cout << tname << " table for " << part->GetParticleName()
|
||||
<< " will be retrieved " << G4endl;
|
||||
}
|
||||
const G4String& name =
|
||||
ptr->GetPhysicsTableFileName(part, dir, tname, ascii);
|
||||
if(G4PhysicsTableHelper::RetrievePhysicsTable(aTable, name, ascii, spline)) {
|
||||
@@ -685,8 +690,8 @@ G4bool G4EmTableUtil::RetrieveTable(G4VProcess* ptr,
|
||||
}
|
||||
} else {
|
||||
res = false;
|
||||
G4cout << "Fail to retrieve: " << tname << " from " << name << " for "
|
||||
<< part->GetParticleName() << G4endl;
|
||||
G4cout << "G4EmTableUtil::RetrieveTable fail to retrieve: " << tname
|
||||
<< " from " << name << " for " << part->GetParticleName() << G4endl;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -667,11 +667,6 @@ void G4LossTableManager::BuildPhysicsTable(
|
||||
base_part_vector[i] = el->BaseParticle();
|
||||
tables_are_built[i] = false;
|
||||
all_tables_are_built= false;
|
||||
if(!isActive[i]) {
|
||||
el->SetIonisation(false);
|
||||
tables_are_built[i] = true;
|
||||
}
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << i <<". "<< el->GetProcessName();
|
||||
if(el->Particle()) {
|
||||
@@ -900,7 +895,6 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
|
||||
// if(1<verbose) G4cout << *range << G4endl;
|
||||
|
||||
std::vector<G4PhysicsTable*> listSub;
|
||||
std::vector<G4PhysicsTable*> listCSDA;
|
||||
|
||||
for (i=0; i<n_dedx; ++i) {
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "G4EmConfigurator.hh"
|
||||
#include "G4VMscModel.hh"
|
||||
|
||||
#include "G4ParticleChangeForMSC.hh"
|
||||
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4StepPoint.hh"
|
||||
@@ -72,6 +74,11 @@ G4TransportationWithMsc::G4TransportationWithMsc(ScatteringType type,
|
||||
fEmManager = G4LossTableManager::Instance();
|
||||
fModelManager = new G4EmModelManager;
|
||||
|
||||
if(type == ScatteringType::MultipleScattering)
|
||||
{
|
||||
fParticleChangeForMSC = new G4ParticleChangeForMSC;
|
||||
}
|
||||
|
||||
G4ThreeVector zero;
|
||||
fSubStepDynamicParticle =
|
||||
new G4DynamicParticle(G4Electron::Definition(), zero);
|
||||
@@ -85,6 +92,8 @@ G4TransportationWithMsc::G4TransportationWithMsc(ScatteringType type,
|
||||
G4TransportationWithMsc::~G4TransportationWithMsc()
|
||||
{
|
||||
delete fModelManager;
|
||||
delete fParticleChangeForMSC;
|
||||
|
||||
// fSubStepDynamicParticle is owned and also deleted by fSubStepTrack!
|
||||
delete fSubStepTrack;
|
||||
delete fSubStep;
|
||||
@@ -103,7 +112,7 @@ void G4TransportationWithMsc::AddMscModel(G4VMscModel* mscModel, G4int order,
|
||||
}
|
||||
|
||||
fModelManager->AddEmModel(order, mscModel, nullptr, region);
|
||||
mscModel->SetParticleChange(&fParticleChange);
|
||||
mscModel->SetParticleChange(fParticleChangeForMSC);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -136,15 +145,18 @@ void G4TransportationWithMsc::PreparePhysicsTable(
|
||||
}
|
||||
|
||||
const G4int numberOfModels = fModelManager->NumberOfModels();
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
if(fType == ScatteringType::MultipleScattering)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
msc->SetMasterThread(master);
|
||||
msc->SetPolarAngleLimit(theParameters->MscThetaLimit());
|
||||
G4double emax =
|
||||
std::min(msc->HighEnergyLimit(), theParameters->MaxKinEnergy());
|
||||
msc->SetHighEnergyLimit(emax);
|
||||
msc->SetUseBaseMaterials(baseMat);
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
msc->SetMasterThread(master);
|
||||
msc->SetPolarAngleLimit(theParameters->MscThetaLimit());
|
||||
G4double emax =
|
||||
std::min(msc->HighEnergyLimit(), theParameters->MaxKinEnergy());
|
||||
msc->SetHighEnergyLimit(emax);
|
||||
msc->SetUseBaseMaterials(baseMat);
|
||||
}
|
||||
}
|
||||
|
||||
fModelManager->Initialise(fFirstParticle, G4Electron::Electron(),
|
||||
@@ -168,13 +180,16 @@ void G4TransportationWithMsc::BuildPhysicsTable(
|
||||
|
||||
// Initialisation of models.
|
||||
const G4int numberOfModels = fModelManager->NumberOfModels();
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
if(fType == ScatteringType::MultipleScattering)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
auto msc0 =
|
||||
static_cast<G4VMscModel*>(masterProcess->fModelManager->GetModel(i));
|
||||
msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false);
|
||||
msc->InitialiseLocal(fFirstParticle, msc0);
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
auto msc0 =
|
||||
static_cast<G4VMscModel*>(masterProcess->fModelManager->GetModel(i));
|
||||
msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false);
|
||||
msc->InitialiseLocal(fFirstParticle, msc0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,11 +217,14 @@ void G4TransportationWithMsc::StartTracking(G4Track* track)
|
||||
fSubStepDynamicParticle->SetDefinition(currParticle);
|
||||
|
||||
const G4int numberOfModels = fModelManager->NumberOfModels();
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
if(fType == ScatteringType::MultipleScattering)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
msc->StartTracking(track);
|
||||
msc->SetIonisation(ionisation, currParticle);
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
msc->StartTracking(track);
|
||||
msc->SetIonisation(ionisation, currParticle);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that field propagation state is also cleared / prepared
|
||||
@@ -348,15 +366,15 @@ G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
|
||||
static constexpr G4double sFact = 0.99;
|
||||
|
||||
// The call to SampleScattering() *may* directly fill in the changed
|
||||
// direction into fParticleChange, so we have to:
|
||||
// direction into fParticleChangeForMSC, so we have to:
|
||||
// 1) Make sure the momentum direction is initialized.
|
||||
fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir);
|
||||
fParticleChangeForMSC->ProposeMomentumDirection(fTransportEndMomentumDir);
|
||||
// 2) Call SampleScattering(), which *may* change it.
|
||||
const G4ThreeVector displacement =
|
||||
mscModel->SampleScattering(fTransportEndMomentumDir, minSafety);
|
||||
// 3) Get the changed direction and inform G4Transportation.
|
||||
fMomentumChanged = true;
|
||||
fTransportEndMomentumDir = *fParticleChange.GetMomentumDirection();
|
||||
fTransportEndMomentumDir = *fParticleChangeForMSC->GetProposedMomentumDirection();
|
||||
|
||||
const G4double r2 = displacement.mag2();
|
||||
if(r2 > kMinDisplacement2)
|
||||
|
||||
@@ -551,13 +551,10 @@ void G4VEnergyLossProcess::StartTracking(G4Track* track)
|
||||
if(nullptr != baseParticle) {
|
||||
massRatio = baseParticle->GetPDGMass()/newmass;
|
||||
logMassRatio = G4Log(massRatio);
|
||||
} else if(isIon) {
|
||||
} else {
|
||||
massRatio = CLHEP::proton_mass_c2/newmass;
|
||||
logMassRatio = G4Log(massRatio);
|
||||
} else {
|
||||
massRatio = 1.0;
|
||||
logMassRatio = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// forced biasing only for primary particles
|
||||
if(nullptr != biasManager) {
|
||||
|
||||
@@ -6,6 +6,17 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-04-17 Alberto Ribon (hadr-casc-V11-00-06)
|
||||
- G4BigBanger : added protection in the method G4BigBanger::generateBangInSCM
|
||||
to avoid very rare cases of unphysical negative energy of one of the
|
||||
secondaries produced by the Bertini model.
|
||||
(Note: this problem was never reproduced in our tests, but was reported by
|
||||
ATLAS with Geant4 10.6; the secondaries with negative - both total
|
||||
and kinetic - energy were always neutrons, produced by the internal
|
||||
Bertini nuclear de-excitation, after the intra-nuclear cascade.
|
||||
Many thanks to Mihaly Novak for providing detailed debugging
|
||||
information!)
|
||||
|
||||
## 2022-11-26 Gabriele Cosmo (hadr-casc-V11-00-05)
|
||||
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
|
||||
|
||||
|
||||
@@ -225,6 +225,17 @@ void G4BigBanger::generateBangInSCM(G4double etot, G4int a, G4int z) {
|
||||
particles.resize(a); // Use assignment to avoid temporaries
|
||||
for(G4int i = 0; i < a; i++) {
|
||||
G4int knd = i < z ? 1 : 2;
|
||||
|
||||
// Set to 0.0 the 4-th component (total energy) of the Lorentz momentum scm_momentums[i]
|
||||
// in order to avoid very rare cases of unphysical negative (total and kinetic) energy
|
||||
// (as reported by ATLAS with Geant4 10.6, but never reproduced in our tests).
|
||||
// Note that these 4-vectors are actually 3-vectors, with null 4-th component in nearly
|
||||
// all cases. After calling the method G4InuclElementaryParticle::fill (see below),
|
||||
// the 4-th component of the momentum is set (in the method G4InuclParticle::setMomentum
|
||||
// which in turn calls G4DynamicParticle::SetMomentum ) to the square root of the sum of
|
||||
// the square of the mass and the square of the magnitude of the 3-momentum.
|
||||
scm_momentums[i].setE( 0.0 );
|
||||
|
||||
particles[i].fill(scm_momentums[i], knd, G4InuclParticle::BigBanger);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-03-17 Alberto Ribon (hadr-inclxx-V11-00-09)
|
||||
- G4INCLNNToNLK2piChannel : fixed bug in the method fillFinalState.
|
||||
Thanks to Dmitri Konstantinov for reporting it.
|
||||
|
||||
## 2022-11-26 Gabriele Cosmo (hadr-inclxx-V11-00-08)
|
||||
- Fixed more compilation warnings for implicit type conversions.
|
||||
|
||||
|
||||
@@ -102,7 +102,8 @@ namespace G4INCL {
|
||||
Pion2Type = PiZero;
|
||||
}
|
||||
|
||||
}if(iso == -2){
|
||||
}
|
||||
else if(iso == -2){
|
||||
if(rdm*7. < 1.){
|
||||
particle1->setType(Neutron);
|
||||
KaonType = KZero;
|
||||
|
||||
@@ -6,6 +6,22 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-06-16 Vladimir Ivanchenko (hadr-hpp-V11-00-22)
|
||||
- G4ParticleHPInelasticBaseFS - real fix of memory leak reported by Coverity
|
||||
|
||||
## 2023-06-07 Vladimir Ivanchenko
|
||||
- G4ParticleHPInelasticBaseFS - fix potential memory leak reported by Coverity
|
||||
|
||||
## 2023-03-13 Vladimir Ivanchenko (hadr-hpp-V11-00-21)
|
||||
- G4ParticleHPNucLevel : added new data structure for nuclear levels
|
||||
- G4ParticleHPDeExGammas : rewitten in order to avoid usage of C-arrays,
|
||||
which provoked a problem for CMS static build; code now fully based on
|
||||
std::vector of G4ParticleHPNucLevel; public interfaces are not changed;
|
||||
if in DB probability of decay for a given level is zero, it is
|
||||
substituted by 1.e-6
|
||||
- G4ParticleHPInelasticBaseFS, G4ParticleHPInelasticCompFS - gamma cascade
|
||||
sampling is checked and simplified (removed unnecessary computations)
|
||||
|
||||
## 2023-02-06 Gabriele Cosmo (hadr-hpp-V11-00-20)
|
||||
- Minor cleanup in G4ParticleHPDeExGammas header for data initialisation.
|
||||
|
||||
|
||||
@@ -25,84 +25,41 @@
|
||||
//
|
||||
//
|
||||
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
|
||||
// V.Ivanchenko 23.04.2023 Rewritten
|
||||
//
|
||||
#ifndef G4ParticleHPDeExGammas_h
|
||||
#define G4ParticleHPDeExGammas_h 1
|
||||
|
||||
#include <fstream>
|
||||
#include <CLHEP/Units/PhysicalConstants.h>
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4ParticleHPNucLevel.hh"
|
||||
#include "G4ReactionProductVector.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ParticleHPLevel.hh"
|
||||
#include "G4ParticleHPGamma.hh"
|
||||
#include "G4ReactionProduct.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
class G4ParticleHPDeExGammas
|
||||
{
|
||||
public:
|
||||
|
||||
G4ParticleHPDeExGammas()
|
||||
{
|
||||
}
|
||||
~G4ParticleHPDeExGammas()
|
||||
{
|
||||
delete [] levelStart;
|
||||
delete [] levelSize;
|
||||
delete [] theLevels;
|
||||
}
|
||||
|
||||
void Init(std::istream & aDataFile);
|
||||
explicit G4ParticleHPDeExGammas();
|
||||
~G4ParticleHPDeExGammas();
|
||||
|
||||
inline G4ReactionProductVector * GetDecayGammas(G4int aLevel)
|
||||
{
|
||||
if(aLevel>nLevels-1 || aLevel<0) return nullptr;
|
||||
if(nLevels==0) return new G4ReactionProductVector();
|
||||
G4ReactionProductVector * result = new G4ReactionProductVector;
|
||||
G4DynamicParticleVector * theResult;
|
||||
void Init(std::istream& aDataFile);
|
||||
|
||||
theResult = theLevels[aLevel]. GetDecayGammas();
|
||||
G4ReactionProduct * theCurrent;
|
||||
for(unsigned int i=0; i<theResult->size(); ++i)
|
||||
G4ReactionProductVector* GetDecayGammas(G4int idx) const;
|
||||
|
||||
inline G4int GetNumberOfLevels() const { return nLevels; }
|
||||
|
||||
inline G4double GetLevelEnergy(G4int idx) const
|
||||
{
|
||||
theCurrent = new G4ReactionProduct;
|
||||
*theCurrent = *(theResult->operator[](i));
|
||||
delete theResult->operator[](i);
|
||||
G4double costheta = 2.*G4UniformRand()-1;
|
||||
G4double theta = std::acos(costheta);
|
||||
G4double phi = CLHEP::twopi*G4UniformRand();
|
||||
G4double sinth = std::sin(theta);
|
||||
G4double en = theCurrent->GetTotalMomentum();
|
||||
G4ThreeVector temp(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*costheta );
|
||||
theCurrent->SetMomentum( temp ) ;
|
||||
result->push_back(theCurrent);
|
||||
return (idx < nLevels && idx >= 0) ? theLevels[idx]->GetLevelEnergy() : 0.0;
|
||||
}
|
||||
delete theResult;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline G4ParticleHPLevel * GetLevel(G4int i)
|
||||
{
|
||||
if(i>nLevels-1) return nullptr;
|
||||
return theLevels+i;
|
||||
}
|
||||
|
||||
inline G4int GetNumberOfLevels() { return nLevels; }
|
||||
|
||||
inline G4double GetLevelEnergy(G4int aLevel)
|
||||
{
|
||||
if(aLevel>nLevels-1 || aLevel<0) return 0;
|
||||
G4double result = theLevels[aLevel].GetLevelEnergy();
|
||||
return result;
|
||||
}
|
||||
|
||||
G4ParticleHPDeExGammas(const G4ParticleHPDeExGammas&) = delete;
|
||||
const G4ParticleHPDeExGammas& operator=(const G4ParticleHPDeExGammas&) = delete;
|
||||
|
||||
private:
|
||||
|
||||
G4int * levelStart = nullptr;
|
||||
G4int * levelSize = nullptr;
|
||||
G4int nLevels = 0;
|
||||
G4ParticleHPLevel * theLevels = nullptr;
|
||||
G4int nLevels = 0;
|
||||
std::vector<G4ParticleHPNucLevel*> theLevels;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+17
-20
@@ -29,26 +29,25 @@
|
||||
#ifndef G4ParticleHPInelasticBaseFS_h
|
||||
#define G4ParticleHPInelasticBaseFS_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4HadProjectile.hh"
|
||||
#include "G4HadFinalState.hh"
|
||||
#include "G4ParticleHPFinalState.hh"
|
||||
#include "G4ParticleHPAngular.hh"
|
||||
#include "G4ParticleHPEnergyDistribution.hh"
|
||||
#include "G4ParticleHPEnAngCorrelation.hh"
|
||||
#include "G4ParticleHPPhotonDist.hh"
|
||||
#include "G4ParticleHPDeExGammas.hh"
|
||||
#include "G4HadProjectile.hh"
|
||||
#include "G4Nucleus.hh"
|
||||
#include "G4ParticleHPAngular.hh"
|
||||
#include "G4ParticleHPDeExGammas.hh"
|
||||
#include "G4ParticleHPEnAngCorrelation.hh"
|
||||
#include "G4ParticleHPEnergyDistribution.hh"
|
||||
#include "G4ParticleHPFinalState.hh"
|
||||
#include "G4ParticleHPPhotonDist.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
class G4ParticleHPInelasticBaseFS : public G4ParticleHPFinalState
|
||||
{
|
||||
public:
|
||||
|
||||
G4ParticleHPInelasticBaseFS()
|
||||
{
|
||||
hasXsec = true;
|
||||
hasXsec = true;
|
||||
theXsection = new G4ParticleHPVector;
|
||||
|
||||
|
||||
theEnergyDistribution = 0;
|
||||
theFinalStatePhotons = 0;
|
||||
theEnergyAngData = 0;
|
||||
@@ -66,33 +65,31 @@ class G4ParticleHPInelasticBaseFS : public G4ParticleHPFinalState
|
||||
if (theEnergyAngData != 0) delete theEnergyAngData;
|
||||
if (theAngularDistribution != 0) delete theAngularDistribution;
|
||||
}
|
||||
|
||||
void Init (G4double A, G4double Z, G4int M, G4String& dirName,
|
||||
G4String& bit, G4ParticleDefinition*);
|
||||
|
||||
void BaseApply(const G4HadProjectile& theTrack,
|
||||
G4ParticleDefinition** theDefs, G4int nDef);
|
||||
void Init(G4double A, G4double Z, G4int M, G4String& dirName, G4String& bit,
|
||||
G4ParticleDefinition*);
|
||||
|
||||
void BaseApply(const G4HadProjectile& theTrack, G4ParticleDefinition** theDefs, G4int nDef);
|
||||
|
||||
void InitGammas(G4double AR, G4double ZR);
|
||||
|
||||
virtual G4HadFinalState* ApplyYourself(const G4HadProjectile& theTrack) = 0;
|
||||
|
||||
virtual G4ParticleHPFinalState* New() = 0;
|
||||
|
||||
|
||||
virtual G4double GetXsec(G4double anEnergy)
|
||||
{
|
||||
return std::max(0., theXsection->GetY(anEnergy));
|
||||
}
|
||||
|
||||
virtual G4ParticleHPVector* GetXsec() {return theXsection;}
|
||||
virtual G4ParticleHPVector* GetXsec() { return theXsection; }
|
||||
|
||||
protected:
|
||||
|
||||
G4ParticleHPVector* theXsection;
|
||||
G4ParticleHPEnergyDistribution* theEnergyDistribution;
|
||||
G4ParticleHPAngular* theAngularDistribution;
|
||||
G4ParticleHPEnAngCorrelation* theEnergyAngData;
|
||||
|
||||
|
||||
G4ParticleHPPhotonDist* theFinalStatePhotons;
|
||||
G4double theNuclearMassDifference;
|
||||
G4ParticleHPDeExGammas theGammas;
|
||||
|
||||
+25
-31
@@ -27,36 +27,34 @@
|
||||
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
|
||||
//
|
||||
// June-2019 - E. Mendoza - re-build "two_body_reaction", to be used by
|
||||
// incident charged particles (now isotropic emission in the CMS).
|
||||
// Also restrict nresp use below 20 MeV (for future developments).
|
||||
// incident charged particles (now isotropic emission in the CMS).
|
||||
// Also restrict nresp use below 20 MeV (for future developments).
|
||||
// Add photon emission when no data available.
|
||||
|
||||
#ifndef G4ParticleHPInelasticCompFS_h
|
||||
#define G4ParticleHPInelasticCompFS_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4HadProjectile.hh"
|
||||
#include "G4HadFinalState.hh"
|
||||
#include "G4ParticleHPFinalState.hh"
|
||||
#include "G4ParticleHPAngular.hh"
|
||||
#include "G4ParticleHPEnergyDistribution.hh"
|
||||
#include "G4ParticleHPEnAngCorrelation.hh"
|
||||
#include "G4ParticleHPPhotonDist.hh"
|
||||
#include "G4ParticleHPDeExGammas.hh"
|
||||
#include "G4Nucleus.hh"
|
||||
|
||||
#include "G4HadProjectile.hh"
|
||||
#include "G4NRESP71M03.hh"
|
||||
#include "G4Nucleus.hh"
|
||||
#include "G4ParticleHPAngular.hh"
|
||||
#include "G4ParticleHPDeExGammas.hh"
|
||||
#include "G4ParticleHPEnAngCorrelation.hh"
|
||||
#include "G4ParticleHPEnergyDistribution.hh"
|
||||
#include "G4ParticleHPFinalState.hh"
|
||||
#include "G4ParticleHPPhotonDist.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
|
||||
{
|
||||
public:
|
||||
|
||||
G4ParticleHPInelasticCompFS()
|
||||
{
|
||||
QI.resize(51);
|
||||
LR.resize(51);
|
||||
for(G4int i=0; i<51; i++) {
|
||||
hasXsec = true;
|
||||
for (G4int i = 0; i < 51; i++) {
|
||||
hasXsec = true;
|
||||
theXsection[i] = 0;
|
||||
theEnergyDistribution[i] = 0;
|
||||
theAngularDistribution[i] = 0;
|
||||
@@ -69,7 +67,7 @@ class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
|
||||
|
||||
virtual ~G4ParticleHPInelasticCompFS()
|
||||
{
|
||||
for(G4int i=0; i<51; i++) {
|
||||
for (G4int i = 0; i < 51; i++) {
|
||||
if (theXsection[i] != 0) delete theXsection[i];
|
||||
if (theEnergyDistribution[i] != 0) delete theEnergyDistribution[i];
|
||||
if (theAngularDistribution[i] != 0) delete theAngularDistribution[i];
|
||||
@@ -78,8 +76,8 @@ class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
|
||||
}
|
||||
}
|
||||
|
||||
void Init(G4double A, G4double Z, G4int M, G4String& dirName,
|
||||
G4String& aSFType, G4ParticleDefinition*);
|
||||
void Init(G4double A, G4double Z, G4int M, G4String& dirName, G4String& aSFType,
|
||||
G4ParticleDefinition*);
|
||||
|
||||
void InitGammas(G4double AR, G4double ZR);
|
||||
|
||||
@@ -96,12 +94,10 @@ class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
|
||||
|
||||
G4int SelectExitChannel(G4double eKinetic);
|
||||
|
||||
void CompositeApply(const G4HadProjectile& theTrack,
|
||||
G4ParticleDefinition* aHadron);
|
||||
void CompositeApply(const G4HadProjectile& theTrack, G4ParticleDefinition* aHadron);
|
||||
|
||||
inline void InitDistributionInitialState(G4ReactionProduct& anIncidentPart,
|
||||
G4ReactionProduct& aTarget,
|
||||
G4int it)
|
||||
inline void InitDistributionInitialState(G4ReactionProduct& anIncidentPart,
|
||||
G4ReactionProduct& aTarget, G4int it)
|
||||
{
|
||||
if (theAngularDistribution[it] != 0) {
|
||||
theAngularDistribution[it]->SetTarget(aTarget);
|
||||
@@ -113,32 +109,30 @@ class G4ParticleHPInelasticCompFS : public G4ParticleHPFinalState
|
||||
theEnergyAngData[it]->SetProjectileRP(anIncidentPart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
G4ParticleHPVector* theXsection[51];
|
||||
G4ParticleHPEnergyDistribution* theEnergyDistribution[51];
|
||||
G4ParticleHPAngular* theAngularDistribution[51];
|
||||
G4ParticleHPEnAngCorrelation* theEnergyAngData[51];
|
||||
|
||||
|
||||
G4ParticleHPPhotonDist* theFinalStatePhotons[51];
|
||||
|
||||
|
||||
G4ParticleHPDeExGammas theGammas;
|
||||
G4String gammaPath;
|
||||
|
||||
|
||||
protected:
|
||||
std::vector<G4double> QI;
|
||||
std::vector<G4int> LR;
|
||||
|
||||
private:
|
||||
// (projectile, target, hadron, mu of hadron)
|
||||
// (projectile, target, hadron, mu of hadron)
|
||||
void two_body_reaction(G4ReactionProduct* proj, G4ReactionProduct* targ,
|
||||
G4ReactionProduct* product, G4double resExcitationEnergy);
|
||||
|
||||
G4NRESP71M03 nresp71_model;
|
||||
G4bool use_nresp71_model(const G4ParticleDefinition* aDefinition, const G4int it,
|
||||
G4bool use_nresp71_model(const G4ParticleDefinition* aDefinition, const G4int it,
|
||||
const G4ReactionProduct& theTarget, G4ReactionProduct& boosted);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+38
-40
@@ -24,56 +24,54 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
|
||||
// V. Ivanchenko, 21 April 2023
|
||||
//
|
||||
#ifndef G4ParticleHPLevel_h
|
||||
#define G4ParticleHPLevel_h 1
|
||||
// Data structure class for gamma levels to replace gamma data classes
|
||||
// of P. Arce
|
||||
//
|
||||
#ifndef G4ParticleHPNucLevel_h
|
||||
#define G4ParticleHPNucLevel_h 1
|
||||
|
||||
#include "G4ReactionProduct.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4ios.hh"
|
||||
#include <fstream>
|
||||
#include "G4DynamicParticleVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Gamma.hh"
|
||||
class G4ParticleHPGamma;
|
||||
|
||||
class G4ParticleHPLevel
|
||||
#include <vector>
|
||||
|
||||
class G4ParticleHPNucLevel
|
||||
{
|
||||
public:
|
||||
|
||||
G4ParticleHPLevel()
|
||||
{
|
||||
nGammas = 0;
|
||||
theGammas = 0;
|
||||
levelEnergy = 0.0;
|
||||
}
|
||||
explicit G4ParticleHPNucLevel(G4double e);
|
||||
~G4ParticleHPNucLevel() = default;
|
||||
|
||||
~G4ParticleHPLevel();
|
||||
|
||||
void SetNumberOfGammas(G4int aGammas);
|
||||
|
||||
void SetGamma(G4int i, G4ParticleHPGamma * aGamma);
|
||||
|
||||
G4DynamicParticleVector * GetDecayGammas();
|
||||
|
||||
inline void SetLevelEnergy(G4double anEnergy)
|
||||
{
|
||||
levelEnergy = anEnergy;
|
||||
}
|
||||
|
||||
inline G4double GetLevelEnergy()
|
||||
{
|
||||
return levelEnergy;
|
||||
}
|
||||
void AddGamma(G4double e, G4double w, G4int idx);
|
||||
|
||||
void Normalize();
|
||||
|
||||
G4ReactionProduct* GetDecayGamma(G4int& idx) const;
|
||||
|
||||
inline G4double GetLevelEnergy() const { return levelEnergy; }
|
||||
|
||||
inline G4double GetNumberOfGammas() const { return nGammas; }
|
||||
|
||||
inline G4double GetGammaEnergy(G4int idx) const
|
||||
{
|
||||
return (idx < nGammas && idx >= 0) ? gammas[idx].gammaEnergy : 0.0;
|
||||
}
|
||||
|
||||
G4ParticleHPNucLevel(const G4ParticleHPNucLevel&) = delete;
|
||||
const G4ParticleHPNucLevel& operator=(const G4ParticleHPNucLevel&) = delete;
|
||||
|
||||
G4double GetGammaEnergy(G4int i);
|
||||
|
||||
private:
|
||||
|
||||
G4double levelEnergy;
|
||||
G4int nGammas = 0;
|
||||
G4double levelEnergy;
|
||||
|
||||
G4int nGammas;
|
||||
G4ParticleHPGamma ** theGammas;
|
||||
struct gammaData
|
||||
{
|
||||
G4double gammaEnergy;
|
||||
G4double cumProbability;
|
||||
G4int next;
|
||||
};
|
||||
std::vector<gammaData> gammas;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,6 @@ geant4_add_module(G4had_par_hp
|
||||
G4NRESP71M03.hh
|
||||
G4ParticleHPList.hh
|
||||
G4ParticleHPIsoData.hh
|
||||
G4ParticleHPLevel.hh
|
||||
G4ParticleHP2AInelasticFS.hh
|
||||
G4ParticleHPNames.hh
|
||||
G4ParticleHP2N2AInelasticFS.hh
|
||||
@@ -66,7 +65,6 @@ geant4_add_module(G4had_par_hp
|
||||
G4ParticleHPFissionERelease.hh
|
||||
G4ParticleHPFissionFS.hh
|
||||
G4ParticleHPFissionSpectrum.hh
|
||||
G4ParticleHPGamma.hh
|
||||
G4ParticleHPHash.hh
|
||||
G4ParticleHPHe3InelasticFS.hh
|
||||
G4ParticleHPInelastic.hh
|
||||
@@ -98,6 +96,7 @@ geant4_add_module(G4had_par_hp
|
||||
G4ParticleHPNT2AInelasticFS.hh
|
||||
G4ParticleHPNTInelasticFS.hh
|
||||
G4ParticleHPNXInelasticFS.hh
|
||||
G4ParticleHPNucLevel.hh
|
||||
G4ParticleHPParticleYield.hh
|
||||
G4ParticleHPPAInelasticFS.hh
|
||||
G4ParticleHPPDInelasticFS.hh
|
||||
@@ -142,9 +141,10 @@ geant4_add_module(G4had_par_hp
|
||||
G4WattFissionSpectrumValues.hh
|
||||
### FissionFragment Generator - end
|
||||
### Headers of NeutronHP for backward compatibility - start
|
||||
G4NeutronHPGamma.hh
|
||||
G4NeutronHPLevel.hh
|
||||
G4NeutronHPList.hh
|
||||
G4NeutronHPIsoData.hh
|
||||
G4NeutronHPLevel.hh
|
||||
G4NeutronHP2AInelasticFS.hh
|
||||
G4NeutronHPNames.hh
|
||||
G4NeutronHP2N2AInelasticFS.hh
|
||||
@@ -201,7 +201,6 @@ geant4_add_module(G4had_par_hp
|
||||
G4NeutronHPFissionERelease.hh
|
||||
G4NeutronHPFissionFS.hh
|
||||
G4NeutronHPFissionSpectrum.hh
|
||||
G4NeutronHPGamma.hh
|
||||
G4NeutronHPHash.hh
|
||||
G4NeutronHPHe3InelasticFS.hh
|
||||
G4NeutronHPInelastic.hh
|
||||
@@ -261,7 +260,6 @@ geant4_add_module(G4had_par_hp
|
||||
G4InterpolationManager.cc
|
||||
G4NRESP71M03.cc
|
||||
G4ParticleHPIsoData.cc
|
||||
G4ParticleHPLevel.cc
|
||||
G4ParticleHP2AInelasticFS.cc
|
||||
G4ParticleHPList.cc
|
||||
G4ParticleHP2N2AInelasticFS.cc
|
||||
@@ -318,7 +316,6 @@ geant4_add_module(G4had_par_hp
|
||||
G4ParticleHPFissionBaseFS.cc
|
||||
G4ParticleHPFissionData.cc
|
||||
G4ParticleHPFissionFS.cc
|
||||
G4ParticleHPGamma.cc
|
||||
G4ParticleHPHe3InelasticFS.cc
|
||||
G4ParticleHPInelastic.cc
|
||||
G4ParticleHPInelasticBaseFS.cc
|
||||
@@ -348,6 +345,7 @@ geant4_add_module(G4had_par_hp
|
||||
G4ParticleHPNT2AInelasticFS.cc
|
||||
G4ParticleHPNTInelasticFS.cc
|
||||
G4ParticleHPNXInelasticFS.cc
|
||||
G4ParticleHPNucLevel.cc
|
||||
G4ParticleHPPAInelasticFS.cc
|
||||
G4ParticleHPPDInelasticFS.cc
|
||||
G4ParticleHPPInelasticFS.cc
|
||||
|
||||
@@ -32,117 +32,94 @@
|
||||
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
|
||||
//
|
||||
#include "G4ParticleHPDeExGammas.hh"
|
||||
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "G4ReactionProduct.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
void G4ParticleHPDeExGammas::Init(std::istream & aDataFile)
|
||||
G4ParticleHPDeExGammas::G4ParticleHPDeExGammas() {}
|
||||
|
||||
G4ParticleHPDeExGammas::~G4ParticleHPDeExGammas()
|
||||
{
|
||||
// G4cout << this << "ExGammas Init LEVEL " << G4endl; //GDEB
|
||||
G4ParticleHPGamma ** theGammas = new G4ParticleHPGamma * [50];
|
||||
G4int nGammas = 0;
|
||||
G4int nBuff = 50;
|
||||
for(;;)
|
||||
{
|
||||
G4ParticleHPGamma * theNew = new G4ParticleHPGamma;
|
||||
if(!theNew->Init(aDataFile))
|
||||
{
|
||||
delete theNew;
|
||||
for (auto& ptr : theLevels) {
|
||||
delete ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void G4ParticleHPDeExGammas::Init(std::istream& aDataFile)
|
||||
{
|
||||
// G4cout << "### G4ParticleHPDeExGammas::Init new file " << G4endl;
|
||||
// ground state
|
||||
auto level = new G4ParticleHPNucLevel(0.0);
|
||||
|
||||
G4double elevel0 = 0.0;
|
||||
G4double elevel = 0.0;
|
||||
G4double egamma = 0.0;
|
||||
G4double prob = 0.0;
|
||||
constexpr G4double eps = 1 * CLHEP::eV;
|
||||
for (;;) {
|
||||
if (aDataFile >> elevel) {
|
||||
// next line
|
||||
aDataFile >> egamma >> prob;
|
||||
egamma *= CLHEP::keV;
|
||||
elevel *= CLHEP::keV;
|
||||
prob = std::max(prob, 1.e-6);
|
||||
// G4cout << " El0=" << elevel0 << " El=" << elevel
|
||||
// << " Eg=" << egamma << " w=" << prob << G4endl;
|
||||
|
||||
// save previous level and start a new level
|
||||
if (std::abs(elevel - elevel0) > eps) {
|
||||
level->Normalize();
|
||||
theLevels.push_back(level);
|
||||
++nLevels;
|
||||
level = new G4ParticleHPNucLevel(elevel);
|
||||
elevel0 = elevel;
|
||||
// G4cout << " New level " << nLevels << " E=" << elevel << G4endl;
|
||||
}
|
||||
|
||||
// find the next level
|
||||
G4double e = elevel - egamma;
|
||||
G4int next = -1;
|
||||
G4double del = DBL_MAX;
|
||||
for (G4int i = 0; i < nLevels; ++i) {
|
||||
G4double de = std::abs(theLevels[i]->GetLevelEnergy() - e);
|
||||
if (de < del) {
|
||||
next = i;
|
||||
del = de;
|
||||
}
|
||||
}
|
||||
// save level data
|
||||
if (next >= 0) {
|
||||
level->AddGamma(egamma, prob, next);
|
||||
// G4cout << " NLevel=" << nLevels << " Elevel=" << elevel
|
||||
// << " Egamma=" << egamma << " W=" << prob << " next=" << next << G4endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// end of file - save recent level
|
||||
level->Normalize();
|
||||
theLevels.push_back(level);
|
||||
++nLevels;
|
||||
// G4cout << "### End of file Nlevels=" << nLevels << G4endl;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(nGammas==nBuff)
|
||||
{
|
||||
nBuff+=50;
|
||||
G4ParticleHPGamma ** buffer = new G4ParticleHPGamma * [nBuff];
|
||||
for(G4int i=0;i<nGammas;i++) buffer[i] = theGammas[i];
|
||||
delete [] theGammas;
|
||||
theGammas = buffer;
|
||||
}
|
||||
theGammas[nGammas] = theNew;
|
||||
nGammas++;
|
||||
}
|
||||
}
|
||||
// all gammas are in. Now sort them into levels.
|
||||
|
||||
// count the levels
|
||||
|
||||
G4double currentE = 0;
|
||||
G4double nextE = 0;
|
||||
G4int i;
|
||||
G4double epsilon = 0.01*keV;
|
||||
for(i=0; i<nGammas; i++)
|
||||
{
|
||||
nextE = theGammas[i]->GetLevelEnergy();
|
||||
if(std::abs(currentE-nextE)>epsilon) nLevels++;
|
||||
currentE = nextE;
|
||||
}
|
||||
|
||||
// G4cout << this << "LEVEL " << nLevels << G4endl; //GDEB
|
||||
// Build the levels
|
||||
|
||||
theLevels = new G4ParticleHPLevel[nLevels];
|
||||
levelStart = new G4int [nLevels];
|
||||
levelSize = new G4int [nLevels];
|
||||
|
||||
// fill the levels
|
||||
|
||||
currentE = 0;
|
||||
nextE = 0;
|
||||
G4int levelCounter=-1;
|
||||
for(i=0; i<nGammas; i++)
|
||||
{
|
||||
nextE = theGammas[i]->GetLevelEnergy();
|
||||
if(std::abs(currentE-nextE)>epsilon)
|
||||
{
|
||||
levelCounter++;
|
||||
levelStart[levelCounter] = i;
|
||||
levelSize[levelCounter] = 0;
|
||||
}
|
||||
levelSize[levelCounter]++;
|
||||
currentE = nextE;
|
||||
}
|
||||
|
||||
for(i=0; i<nLevels; i++)
|
||||
{
|
||||
theLevels[i].SetNumberOfGammas(levelSize[i]);
|
||||
for(G4int ii=levelStart[i]; ii<levelStart[i]+levelSize[i]; ii++)
|
||||
{
|
||||
theLevels[i].SetGamma(ii-levelStart[i], theGammas[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
// set the next relation in the gammas.
|
||||
G4double levelE, gammaE, currentLevelE;
|
||||
G4double min;
|
||||
for(i=0; i<nGammas; i++)
|
||||
{
|
||||
G4int it=-1;
|
||||
gammaE = theGammas[i]->GetGammaEnergy();
|
||||
currentLevelE = theGammas[i]->GetLevelEnergy();
|
||||
min = currentLevelE-gammaE-epsilon;
|
||||
for(G4int ii=0; ii<nLevels; ii++)
|
||||
{
|
||||
levelE = theLevels[ii].GetLevelEnergy();
|
||||
if(std::abs(currentLevelE-(levelE+gammaE))<min)
|
||||
{
|
||||
min = std::abs(currentLevelE-(levelE+gammaE));
|
||||
it = ii;
|
||||
}
|
||||
}
|
||||
//080728
|
||||
if ( it != -1 && currentLevelE == theLevels[it].GetLevelEnergy() )
|
||||
{
|
||||
//TK Comment; Some data file in /Inelastic/Gammas has inconsistent level data (no level to transit)
|
||||
//G4cout << "DeExGammas Transition level error: it " << it << " " << currentLevelE << " " << gammaE << " " << theLevels[it-1].GetLevelEnergy() << " " << currentLevelE - theLevels[it-1].GetLevelEnergy() << G4endl;
|
||||
// Forced to connect the next(previous) level
|
||||
it +=-1;
|
||||
}
|
||||
//080728
|
||||
if(it!=-1) theGammas[i]->SetNext(&theLevels[it]);
|
||||
}
|
||||
// some garbage collection
|
||||
|
||||
delete [] theGammas;
|
||||
|
||||
// and we are Done.
|
||||
}
|
||||
|
||||
G4ReactionProductVector* G4ParticleHPDeExGammas::GetDecayGammas(G4int i) const
|
||||
{
|
||||
G4int idx = i;
|
||||
if (idx >= nLevels || idx <= 0) return nullptr;
|
||||
G4ReactionProductVector* result = new G4ReactionProductVector();
|
||||
|
||||
for (;;) {
|
||||
if (idx <= 0) {
|
||||
break;
|
||||
}
|
||||
auto ptr = theLevels[idx]->GetDecayGamma(idx);
|
||||
if (nullptr != ptr) {
|
||||
result->push_back(ptr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// neutron_hp -- source file
|
||||
// J.P. Wellisch, Nov-1996
|
||||
// A prototype of the low energy neutron transport model.
|
||||
//
|
||||
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
|
||||
//
|
||||
#include "G4ParticleHPGamma.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4ThreadLocal int G4ParticleHPGamma::instancecount = 0;
|
||||
|
||||
G4ParticleHPGamma::G4ParticleHPGamma()
|
||||
{
|
||||
next = 0;
|
||||
instancecount ++;
|
||||
levelEnergy = 0.0;
|
||||
gammaEnergy = 0.0;
|
||||
probability = 0.0;
|
||||
}
|
||||
|
||||
G4ParticleHPGamma::~G4ParticleHPGamma() {instancecount--;}
|
||||
|
||||
G4bool G4ParticleHPGamma::Init(std::istream & aDataFile)
|
||||
{
|
||||
G4bool theResult = true;
|
||||
if(aDataFile >> levelEnergy)
|
||||
{
|
||||
aDataFile >> gammaEnergy >> probability;
|
||||
levelEnergy *= keV;
|
||||
gammaEnergy *= keV;
|
||||
}
|
||||
else
|
||||
{
|
||||
theResult=false;
|
||||
}
|
||||
return theResult;
|
||||
}
|
||||
@@ -34,218 +34,230 @@
|
||||
//
|
||||
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
|
||||
//
|
||||
// June-2019 - E. Mendoza --> Added protection against residual with Z<0 or A<Z + adjust_final_state is not applied when data is in MF=6 format (no correlated particle emission) + bug correction (add Q value info to G4ParticleHPNBodyPhaseSpace).
|
||||
|
||||
// June-2019 - E. Mendoza --> Added protection against residual with Z<0 or A<Z + adjust_final_state
|
||||
// is not applied when data is in MF=6 format (no correlated particle emission) + bug correction
|
||||
// (add Q value info to G4ParticleHPNBodyPhaseSpace).
|
||||
|
||||
#include "G4ParticleHPInelasticBaseFS.hh"
|
||||
#include "G4ParticleHPManager.hh"
|
||||
#include "G4Nucleus.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4He3.hh"
|
||||
|
||||
#include "G4Alpha.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4ParticleHPDataUsed.hh"
|
||||
#include "G4He3.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "G4NucleiProperties.hh"
|
||||
#include "G4Nucleus.hh"
|
||||
#include "G4ParticleHPDataUsed.hh"
|
||||
#include "G4ParticleHPManager.hh"
|
||||
|
||||
void G4ParticleHPInelasticBaseFS::InitGammas(G4double AR, G4double ZR)
|
||||
{
|
||||
std::ostringstream ost;
|
||||
ost <<gammaPath<<"z"<<ZR<<".a"<<AR;
|
||||
G4String aName = ost.str();
|
||||
std::ifstream from(aName, std::ios::in);
|
||||
std::ostringstream ost;
|
||||
ost << gammaPath << "z" << ZR << ".a" << AR;
|
||||
G4String aName = ost.str();
|
||||
std::ifstream from(aName, std::ios::in);
|
||||
|
||||
if(!from) return; // no data found for this isotope
|
||||
std::ifstream theGammaData(aName, std::ios::in);
|
||||
|
||||
G4double eps = 0.001;
|
||||
theNuclearMassDifference =
|
||||
G4NucleiProperties::GetBindingEnergy(static_cast<G4int>(AR+eps),static_cast<G4int>(ZR+eps)) -
|
||||
G4NucleiProperties::GetBindingEnergy(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps));
|
||||
theGammas.Init(theGammaData);
|
||||
if (!from) return; // no data found for this isotope
|
||||
std::ifstream theGammaData(aName, std::ios::in);
|
||||
|
||||
G4double eps = 0.001;
|
||||
theNuclearMassDifference =
|
||||
G4NucleiProperties::GetBindingEnergy(static_cast<G4int>(AR + eps), static_cast<G4int>(ZR + eps))
|
||||
- G4NucleiProperties::GetBindingEnergy(static_cast<G4int>(theBaseA + eps),
|
||||
static_cast<G4int>(theBaseZ + eps));
|
||||
theGammas.Init(theGammaData);
|
||||
}
|
||||
|
||||
void G4ParticleHPInelasticBaseFS::Init (G4double A, G4double Z, G4int M, G4String & dirName, G4String & bit, G4ParticleDefinition* )
|
||||
void G4ParticleHPInelasticBaseFS::Init(G4double A, G4double Z, G4int M, G4String& dirName,
|
||||
G4String& bit, G4ParticleDefinition*)
|
||||
{
|
||||
gammaPath = "/Inelastic/Gammas/";
|
||||
if(!G4FindDataDir("G4NEUTRONHPDATA"))
|
||||
throw G4HadronicException(__FILE__, __LINE__, "Please setenv G4NEUTRONHPDATA to point to the neutron cross-section files where Inelastic/Gammas data is found.");
|
||||
if (!G4FindDataDir("G4NEUTRONHPDATA"))
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"Please setenv G4NEUTRONHPDATA to point to the neutron cross-section "
|
||||
"files where Inelastic/Gammas data is found.");
|
||||
G4String tBase = G4FindDataDir("G4NEUTRONHPDATA");
|
||||
gammaPath = tBase+gammaPath;
|
||||
gammaPath = tBase + gammaPath;
|
||||
G4String tString = dirName;
|
||||
G4bool dbool;
|
||||
G4ParticleHPDataUsed aFile = theNames.GetName(static_cast<G4int>(A), static_cast<G4int>(Z), M,tString, bit, dbool);
|
||||
G4ParticleHPDataUsed aFile =
|
||||
theNames.GetName(static_cast<G4int>(A), static_cast<G4int>(Z), M, tString, bit, dbool);
|
||||
G4String filename = aFile.GetName();
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug") ) G4cout << " G4ParticleHPInelasticBaseFS::Init FILE " << filename << G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << " G4ParticleHPInelasticBaseFS::Init FILE " << filename << G4endl;
|
||||
#endif
|
||||
SetAZMs( A, Z, M, aFile);
|
||||
SetAZMs(A, Z, M, aFile);
|
||||
|
||||
if ( !dbool || ( Z<2.5 && ( std::abs(theNDLDataZ - Z)>0.0001 || std::abs(theNDLDataA - A)>0.0001)) )
|
||||
if (!dbool
|
||||
|| (Z < 2.5 && (std::abs(theNDLDataZ - Z) > 0.0001 || std::abs(theNDLDataA - A) > 0.0001)))
|
||||
{
|
||||
#ifdef G4PHPDEBUG
|
||||
if(std::getenv("G4ParticleHPDebug_NamesLogging")) G4cout << "Skipped = "<< filename <<" "<<A<<" "<<Z<<G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug_NamesLogging"))
|
||||
G4cout << "Skipped = " << filename << " " << A << " " << Z << G4endl;
|
||||
#endif
|
||||
hasAnyData = false;
|
||||
hasFSData = false;
|
||||
hasFSData = false;
|
||||
hasXsec = false;
|
||||
return;
|
||||
}
|
||||
|
||||
std::istringstream theData(std::ios::in);
|
||||
G4ParticleHPManager::GetInstance()->GetDataStream(filename,theData);
|
||||
G4ParticleHPManager::GetInstance()->GetDataStream(filename, theData);
|
||||
|
||||
if(!theData) //"!" is a operator of ios
|
||||
if (!theData) //"!" is a operator of ios
|
||||
{
|
||||
hasAnyData = false;
|
||||
hasFSData = false;
|
||||
hasFSData = false;
|
||||
hasXsec = false;
|
||||
// theData.close();
|
||||
return; // no data for exactly this isotope and FS
|
||||
return; // no data for exactly this isotope and FS
|
||||
}
|
||||
// here we go
|
||||
G4int infoType, dataType, dummy=INT_MAX;
|
||||
hasFSData = false;
|
||||
while (theData >> infoType) // Loop checking, 11.05.2015, T. Koi
|
||||
G4int infoType, dataType, dummy = INT_MAX;
|
||||
hasFSData = false;
|
||||
while (theData >> infoType) // Loop checking, 11.05.2015, T. Koi
|
||||
{
|
||||
theData >> dataType;
|
||||
|
||||
if(dummy==INT_MAX) theData >> Qvalue >> dummy;
|
||||
Qvalue*=CLHEP::eV;
|
||||
if (dummy == INT_MAX) theData >> Qvalue >> dummy;
|
||||
Qvalue *= CLHEP::eV;
|
||||
// In G4NDL4.5 this value is the MT number (<1000),
|
||||
// in others is que Q-value in eV
|
||||
|
||||
if(dataType==3)
|
||||
{
|
||||
if (dataType == 3) {
|
||||
G4int total;
|
||||
theData >> total;
|
||||
theXsection->Init(theData, total, CLHEP::eV);
|
||||
}
|
||||
else if(dataType==4)
|
||||
{
|
||||
else if (dataType == 4) {
|
||||
theAngularDistribution = new G4ParticleHPAngular;
|
||||
theAngularDistribution->Init(theData);
|
||||
hasFSData = true;
|
||||
hasFSData = true;
|
||||
}
|
||||
else if(dataType==5)
|
||||
{
|
||||
else if (dataType == 5) {
|
||||
theEnergyDistribution = new G4ParticleHPEnergyDistribution;
|
||||
theEnergyDistribution->Init(theData);
|
||||
hasFSData = true;
|
||||
hasFSData = true;
|
||||
}
|
||||
else if(dataType==6)
|
||||
{
|
||||
else if (dataType == 6) {
|
||||
theEnergyAngData = new G4ParticleHPEnAngCorrelation(theProjectile);
|
||||
theEnergyAngData->Init(theData);
|
||||
hasFSData = true;
|
||||
hasFSData = true;
|
||||
}
|
||||
else if(dataType==12)
|
||||
{
|
||||
else if (dataType == 12) {
|
||||
theFinalStatePhotons = new G4ParticleHPPhotonDist;
|
||||
theFinalStatePhotons->InitMean(theData);
|
||||
hasFSData = true;
|
||||
hasFSData = true;
|
||||
}
|
||||
else if(dataType==13)
|
||||
{
|
||||
else if (dataType == 13) {
|
||||
theFinalStatePhotons = new G4ParticleHPPhotonDist;
|
||||
theFinalStatePhotons->InitPartials(theData, theXsection);
|
||||
hasFSData = true;
|
||||
hasFSData = true;
|
||||
}
|
||||
else if(dataType==14)
|
||||
{
|
||||
else if (dataType == 14) {
|
||||
theFinalStatePhotons->InitAngular(theData);
|
||||
hasFSData = true;
|
||||
hasFSData = true;
|
||||
}
|
||||
else if(dataType==15)
|
||||
{
|
||||
else if (dataType == 15) {
|
||||
theFinalStatePhotons->InitEnergies(theData);
|
||||
hasFSData = true;
|
||||
hasFSData = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "Data-type unknown to G4ParticleHPInelasticBaseFS");
|
||||
else {
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"Data-type unknown to G4ParticleHPInelasticBaseFS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4ParticleHPInelasticBaseFS::BaseApply(const G4HadProjectile & theTrack,
|
||||
G4ParticleDefinition ** theDefs,
|
||||
G4int nDef)
|
||||
|
||||
void G4ParticleHPInelasticBaseFS::BaseApply(const G4HadProjectile& theTrack,
|
||||
G4ParticleDefinition** theDefs, G4int nDef)
|
||||
{
|
||||
// prepare neutron
|
||||
if ( theResult.Get() == NULL ) theResult.Put( new G4HadFinalState );
|
||||
if (theResult.Get() == NULL) theResult.Put(new G4HadFinalState);
|
||||
theResult.Get()->Clear();
|
||||
G4double eKinetic = theTrack.GetKineticEnergy();
|
||||
const G4HadProjectile *hadProjectile = &theTrack;
|
||||
G4ReactionProduct incidReactionProduct( const_cast<G4ParticleDefinition *>(hadProjectile->GetDefinition()) );
|
||||
incidReactionProduct.SetMomentum( hadProjectile->Get4Momentum().vect() );
|
||||
incidReactionProduct.SetKineticEnergy( eKinetic );
|
||||
const G4HadProjectile* hadProjectile = &theTrack;
|
||||
G4ReactionProduct incidReactionProduct(
|
||||
const_cast<G4ParticleDefinition*>(hadProjectile->GetDefinition()));
|
||||
incidReactionProduct.SetMomentum(hadProjectile->Get4Momentum().vect());
|
||||
incidReactionProduct.SetKineticEnergy(eKinetic);
|
||||
|
||||
// prepare target
|
||||
G4double targetMass;
|
||||
G4double eps = 0.0001;
|
||||
targetMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps))) /
|
||||
//theProjectile->GetPDGMass();
|
||||
targetMass = (G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA + eps),
|
||||
static_cast<G4int>(theBaseZ + eps)))
|
||||
/
|
||||
// theProjectile->GetPDGMass();
|
||||
G4Neutron::Neutron()->GetPDGMass();
|
||||
|
||||
// give priority to ENDF vales for target mass
|
||||
if(theEnergyAngData!=0)
|
||||
{ targetMass = theEnergyAngData->GetTargetMass(); }
|
||||
if(theAngularDistribution!=0)
|
||||
{ targetMass = theAngularDistribution->GetTargetMass(); }
|
||||
if (theEnergyAngData != 0) {
|
||||
targetMass = theEnergyAngData->GetTargetMass();
|
||||
}
|
||||
if (theAngularDistribution != 0) {
|
||||
targetMass = theAngularDistribution->GetTargetMass();
|
||||
}
|
||||
|
||||
// 110512 TKDB ENDF-VII.0 21Sc45 has trouble in MF4MT22 (n,np) targetMass is not properly recorded.
|
||||
if ( targetMass == 0 )
|
||||
{
|
||||
//G4cout << "TKDB targetMass = 0; ENDF-VII.0 21Sc45 has trouble in MF4MT22 (n,np) targetMass is not properly recorded. This could be a similar situation." << G4endl;
|
||||
//targetMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps))) / theProjectile->GetPDGMass();
|
||||
targetMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps))) / G4Neutron::Neutron()->GetPDGMass();
|
||||
// 110512 TKDB ENDF-VII.0 21Sc45 has trouble in MF4MT22 (n,np) targetMass is not properly
|
||||
// recorded.
|
||||
if (targetMass == 0) {
|
||||
// G4cout << "TKDB targetMass = 0; ENDF-VII.0 21Sc45 has trouble in MF4MT22 (n,np) targetMass is
|
||||
// not properly recorded. This could be a similar situation." << G4endl; targetMass = (
|
||||
// G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps),
|
||||
// static_cast<G4int>(theBaseZ+eps))) / theProjectile->GetPDGMass();
|
||||
targetMass = (G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA + eps),
|
||||
static_cast<G4int>(theBaseZ + eps)))
|
||||
/ G4Neutron::Neutron()->GetPDGMass();
|
||||
}
|
||||
|
||||
G4Nucleus aNucleus;
|
||||
G4ReactionProduct theTarget;
|
||||
G4ReactionProduct theTarget;
|
||||
|
||||
G4ThreeVector neuVelo = (1./G4Neutron::Neutron()->GetPDGMass())*incidReactionProduct.GetMomentum();
|
||||
theTarget = aNucleus.GetBiasedThermalNucleus( targetMass, neuVelo, theTrack.GetMaterial()->GetTemperature());
|
||||
G4ThreeVector neuVelo =
|
||||
(1. / G4Neutron::Neutron()->GetPDGMass()) * incidReactionProduct.GetMomentum();
|
||||
theTarget =
|
||||
aNucleus.GetBiasedThermalNucleus(targetMass, neuVelo, theTrack.GetMaterial()->GetTemperature());
|
||||
|
||||
theTarget.SetDefinition( G4IonTable::GetIonTable()->GetIon( G4int(theBaseZ), G4int(theBaseA) , 0.0 ) );
|
||||
theTarget.SetDefinition(G4IonTable::GetIonTable()->GetIon(G4int(theBaseZ), G4int(theBaseA), 0.0));
|
||||
|
||||
// prepare energy in target rest frame
|
||||
G4ReactionProduct boosted;
|
||||
boosted.Lorentz(incidReactionProduct, theTarget);
|
||||
eKinetic = boosted.GetKineticEnergy();
|
||||
G4double orgMomentum = boosted.GetMomentum().mag();
|
||||
|
||||
|
||||
// Take N-body phase-space distribution, if no other data present.
|
||||
if(!HasFSData()) // adding the residual is trivial here @@@
|
||||
if (!HasFSData()) // adding the residual is trivial here @@@
|
||||
{
|
||||
G4ParticleHPNBodyPhaseSpace thePhaseSpaceDistribution;
|
||||
G4double aPhaseMass=0;
|
||||
G4double aPhaseMass = 0;
|
||||
G4int ii;
|
||||
for(ii=0; ii<nDef; ++ii)
|
||||
{
|
||||
aPhaseMass+=theDefs[ii]->GetPDGMass();
|
||||
for (ii = 0; ii < nDef; ++ii) {
|
||||
aPhaseMass += theDefs[ii]->GetPDGMass();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
if(Qvalue<1.*CLHEP::keV && Qvalue>-1.*CLHEP::keV) {
|
||||
if (Qvalue < 1. * CLHEP::keV && Qvalue > -1. * CLHEP::keV) {
|
||||
// Not in the G4NDL lib or not calculated yet:
|
||||
|
||||
// Calculate residual:
|
||||
G4int ResidualA=theBaseA;
|
||||
G4int ResidualZ=theBaseZ;
|
||||
G4int ResidualA = theBaseA;
|
||||
G4int ResidualZ = theBaseZ;
|
||||
for (ii = 0; ii < nDef; ++ii) {
|
||||
ResidualZ -= theDefs[ii]->GetAtomicNumber();
|
||||
ResidualA -= theDefs[ii]->GetBaryonNumber();
|
||||
}
|
||||
|
||||
if (ResidualA > 0 && ResidualZ > 0) {
|
||||
G4ParticleDefinition* resid = G4IonTable::GetIonTable()->GetIon(ResidualZ,ResidualA);
|
||||
Qvalue = incidReactionProduct.GetMass()+theTarget.GetMass()-aPhaseMass-resid->GetPDGMass();
|
||||
G4ParticleDefinition* resid = G4IonTable::GetIonTable()->GetIon(ResidualZ, ResidualA);
|
||||
Qvalue =
|
||||
incidReactionProduct.GetMass() + theTarget.GetMass() - aPhaseMass - resid->GetPDGMass();
|
||||
}
|
||||
|
||||
if (Qvalue > 400*CLHEP::MeV || Qvalue < -400*CLHEP::MeV) {
|
||||
//Then Q value is probably too large ...
|
||||
Qvalue = 1.1*CLHEP::keV;
|
||||
if (Qvalue > 400 * CLHEP::MeV || Qvalue < -400 * CLHEP::MeV) {
|
||||
// Then Q value is probably too large ...
|
||||
Qvalue = 1.1 * CLHEP::keV;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -255,372 +267,341 @@ void G4ParticleHPInelasticBaseFS::BaseApply(const G4HadProjectile & theTrack,
|
||||
thePhaseSpaceDistribution.SetTarget(&theTarget);
|
||||
thePhaseSpaceDistribution.SetQValue(Qvalue);
|
||||
|
||||
for(ii=0; ii<nDef; ++ii)
|
||||
{
|
||||
G4double massCode = 1000.*std::abs(theDefs[ii]->GetPDGCharge());
|
||||
massCode += theDefs[ii]->GetBaryonNumber();
|
||||
for (ii = 0; ii < nDef; ++ii) {
|
||||
G4double massCode = 1000. * std::abs(theDefs[ii]->GetPDGCharge());
|
||||
massCode += theDefs[ii]->GetBaryonNumber();
|
||||
G4double dummy = 0;
|
||||
G4ReactionProduct * aSec = thePhaseSpaceDistribution.Sample(eKinetic, massCode, dummy);
|
||||
aSec->Lorentz(*aSec, -1.*theTarget);
|
||||
G4DynamicParticle * aPart = new G4DynamicParticle();
|
||||
G4ReactionProduct* aSec = thePhaseSpaceDistribution.Sample(eKinetic, massCode, dummy);
|
||||
aSec->Lorentz(*aSec, -1. * theTarget);
|
||||
G4DynamicParticle* aPart = new G4DynamicParticle();
|
||||
aPart->SetDefinition(aSec->GetDefinition());
|
||||
aPart->SetMomentum(aSec->GetMomentum());
|
||||
delete aSec;
|
||||
theResult.Get()->AddSecondary(aPart, secID);
|
||||
theResult.Get()->AddSecondary(aPart, secID);
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << this
|
||||
<< " G4ParticleHPInelasticBaseFS::BaseApply NoFSData add secondary "
|
||||
<< aPart->GetParticleDefinition()->GetParticleName()
|
||||
<< " E= " << aPart->GetKineticEnergy() << " NSECO "
|
||||
<< theResult.Get()->GetNumberOfSecondaries() << G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply NoFSData add secondary "
|
||||
<< aPart->GetParticleDefinition()->GetParticleName()
|
||||
<< " E= " << aPart->GetKineticEnergy() << " NSECO "
|
||||
<< theResult.Get()->GetNumberOfSecondaries() << G4endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
theResult.Get()->SetStatusChange(stopAndKill);
|
||||
// Final momentum check should be done before return
|
||||
G4ParticleDefinition* targ_pd = G4IonTable::GetIonTable()->GetIon ( (G4int)theBaseZ , (G4int)theBaseA , 0.0 );
|
||||
G4LorentzVector targ_4p_lab ( theTarget.GetMomentum() , std::sqrt( targ_pd->GetPDGMass()*targ_pd->GetPDGMass() + theTarget.GetMomentum().mag2() ) );
|
||||
G4ParticleDefinition* targ_pd =
|
||||
G4IonTable::GetIonTable()->GetIon((G4int)theBaseZ, (G4int)theBaseA, 0.0);
|
||||
G4LorentzVector targ_4p_lab(
|
||||
theTarget.GetMomentum(),
|
||||
std::sqrt(targ_pd->GetPDGMass() * targ_pd->GetPDGMass() + theTarget.GetMomentum().mag2()));
|
||||
G4LorentzVector proj_4p_lab = theTrack.Get4Momentum();
|
||||
G4LorentzVector init_4p_lab = proj_4p_lab + targ_4p_lab;
|
||||
adjust_final_state ( init_4p_lab );
|
||||
adjust_final_state(init_4p_lab);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// set target and neutron in the relevant exit channel
|
||||
if(theAngularDistribution!=0)
|
||||
{
|
||||
if (theAngularDistribution != 0) {
|
||||
theAngularDistribution->SetTarget(theTarget);
|
||||
theAngularDistribution->SetProjectileRP(incidReactionProduct);
|
||||
}
|
||||
else if(theEnergyAngData!=0)
|
||||
{
|
||||
else if (theEnergyAngData != 0) {
|
||||
theEnergyAngData->SetTarget(theTarget);
|
||||
theEnergyAngData->SetProjectileRP(incidReactionProduct);
|
||||
}
|
||||
|
||||
G4ReactionProductVector * tmpHadrons = 0;
|
||||
|
||||
G4ReactionProductVector* tmpHadrons = 0;
|
||||
#ifdef G4PHPDEBUG
|
||||
//To avoid compilation error around line 532.
|
||||
// To avoid compilation error around line 532.
|
||||
G4int ii(0);
|
||||
#endif
|
||||
G4int dummy;
|
||||
std::size_t i;
|
||||
|
||||
if(theEnergyAngData != 0)
|
||||
{
|
||||
if (theEnergyAngData != 0) {
|
||||
tmpHadrons = theEnergyAngData->Sample(eKinetic);
|
||||
|
||||
if ( ! G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState() ) {
|
||||
// Adjust A and Z in the case of miss much between selected data and target nucleus
|
||||
if ( tmpHadrons != nullptr ) {
|
||||
G4int sumA = 0;
|
||||
G4int sumZ = 0;
|
||||
G4int maxA = 0;
|
||||
G4int jAtMaxA = 0;
|
||||
for ( G4int j = 0 ; j != (G4int)tmpHadrons->size() ; ++j ) {
|
||||
//G4cout << __FILE__ << " " << __LINE__ << "th line: tmpHadrons->at(j)->GetDefinition()->GetParticleName() = " << tmpHadrons->at(j)->GetDefinition()->GetParticleName() << G4endl;
|
||||
if ( tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber() > maxA ) {
|
||||
maxA = tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber();
|
||||
jAtMaxA = j;
|
||||
}
|
||||
sumA += tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber();
|
||||
sumZ += G4int( tmpHadrons->at(j)->GetDefinition()->GetPDGCharge() + eps );
|
||||
}
|
||||
G4int dA = (G4int)theBaseA + hadProjectile->GetDefinition()->GetBaryonNumber() - sumA;
|
||||
G4int dZ = (G4int)theBaseZ + G4int( hadProjectile->GetDefinition()->GetPDGCharge() + eps ) - sumZ;
|
||||
if ( dA < 0 || dZ < 0 ) {
|
||||
G4int newA = tmpHadrons->at(jAtMaxA)->GetDefinition()->GetBaryonNumber() + dA ;
|
||||
G4int newZ = G4int( tmpHadrons->at(jAtMaxA)->GetDefinition()->GetPDGCharge() + eps ) + dZ;
|
||||
if(newA>newZ && newZ>0){
|
||||
G4ParticleDefinition* pd = G4IonTable::GetIonTable()->GetIon ( newZ , newA );
|
||||
tmpHadrons->at( jAtMaxA )->SetDefinition( pd );
|
||||
}
|
||||
}
|
||||
if (!G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState()) {
|
||||
// Adjust A and Z in the case of miss much between selected data and target nucleus
|
||||
if (tmpHadrons != nullptr) {
|
||||
G4int sumA = 0;
|
||||
G4int sumZ = 0;
|
||||
G4int maxA = 0;
|
||||
G4int jAtMaxA = 0;
|
||||
for (G4int j = 0; j != (G4int)tmpHadrons->size(); ++j) {
|
||||
// G4cout << __FILE__ << " " << __LINE__ << "th line:
|
||||
// tmpHadrons->at(j)->GetDefinition()->GetParticleName() = " <<
|
||||
// tmpHadrons->at(j)->GetDefinition()->GetParticleName() << G4endl;
|
||||
if (tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber() > maxA) {
|
||||
maxA = tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber();
|
||||
jAtMaxA = j;
|
||||
}
|
||||
sumA += tmpHadrons->at(j)->GetDefinition()->GetBaryonNumber();
|
||||
sumZ += G4int(tmpHadrons->at(j)->GetDefinition()->GetPDGCharge() + eps);
|
||||
}
|
||||
G4int dA = (G4int)theBaseA + hadProjectile->GetDefinition()->GetBaryonNumber() - sumA;
|
||||
G4int dZ =
|
||||
(G4int)theBaseZ + G4int(hadProjectile->GetDefinition()->GetPDGCharge() + eps) - sumZ;
|
||||
if (dA < 0 || dZ < 0) {
|
||||
G4int newA = tmpHadrons->at(jAtMaxA)->GetDefinition()->GetBaryonNumber() + dA;
|
||||
G4int newZ = G4int(tmpHadrons->at(jAtMaxA)->GetDefinition()->GetPDGCharge() + eps) + dZ;
|
||||
if (newA > newZ && newZ > 0) {
|
||||
G4ParticleDefinition* pd = G4IonTable::GetIonTable()->GetIon(newZ, newA);
|
||||
tmpHadrons->at(jAtMaxA)->SetDefinition(pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(theAngularDistribution!= 0)
|
||||
{
|
||||
G4bool * Done = new G4bool[nDef];
|
||||
else if (theAngularDistribution != 0) {
|
||||
G4bool* Done = new G4bool[nDef];
|
||||
G4int i0;
|
||||
for(i0=0; i0<nDef; ++i0) Done[i0] = false;
|
||||
for (i0 = 0; i0 < nDef; ++i0)
|
||||
Done[i0] = false;
|
||||
|
||||
tmpHadrons = new G4ReactionProductVector;
|
||||
G4ReactionProduct * aHadron;
|
||||
G4double localMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA+eps), static_cast<G4int>(theBaseZ+eps)));
|
||||
G4ThreeVector bufferedDirection(0,0,0);
|
||||
for(i0=0; i0<nDef; ++i0)
|
||||
{
|
||||
if(!Done[i0])
|
||||
{
|
||||
G4ReactionProduct* aHadron;
|
||||
G4double localMass = (G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theBaseA + eps),
|
||||
static_cast<G4int>(theBaseZ + eps)));
|
||||
G4ThreeVector bufferedDirection(0, 0, 0);
|
||||
for (i0 = 0; i0 < nDef; ++i0) {
|
||||
if (!Done[i0]) {
|
||||
aHadron = new G4ReactionProduct;
|
||||
if(theEnergyDistribution!=0)
|
||||
{
|
||||
aHadron->SetDefinition(theDefs[i0]);
|
||||
aHadron->SetKineticEnergy(theEnergyDistribution->Sample(eKinetic, dummy));
|
||||
}
|
||||
else if(nDef == 1)
|
||||
{
|
||||
aHadron->SetDefinition(theDefs[i0]);
|
||||
aHadron->SetKineticEnergy(eKinetic);
|
||||
}
|
||||
else if(nDef == 2)
|
||||
{
|
||||
aHadron->SetDefinition(theDefs[i0]);
|
||||
aHadron->SetKineticEnergy(50*CLHEP::MeV);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "No energy distribution to sample from in InelasticBaseFS::BaseApply");
|
||||
}
|
||||
theAngularDistribution->SampleAndUpdate(*aHadron);
|
||||
if(theEnergyDistribution==0 && nDef == 2)
|
||||
{
|
||||
if(i0==0)
|
||||
{
|
||||
G4double mass1 = theDefs[0]->GetPDGMass();
|
||||
G4double mass2 = theDefs[1]->GetPDGMass();
|
||||
G4double massn = theProjectile->GetPDGMass();
|
||||
G4int z1 = static_cast<G4int>(theBaseZ+eps-theDefs[0]->GetPDGCharge()-theDefs[1]->GetPDGCharge());
|
||||
G4int a1 = static_cast<G4int>(theBaseA+eps)-theDefs[0]->GetBaryonNumber()-theDefs[1]->GetBaryonNumber();
|
||||
G4double concreteMass = G4NucleiProperties::GetNuclearMass(a1, z1);
|
||||
G4double availableEnergy = eKinetic+massn+localMass-mass1-mass2-concreteMass;
|
||||
// available kinetic energy in CMS (non relativistic)
|
||||
G4double emin = availableEnergy+mass1+mass2 - std::sqrt((mass1+mass2)*(mass1+mass2)+orgMomentum*orgMomentum);
|
||||
G4double p1=std::sqrt(2.*mass2*emin);
|
||||
bufferedDirection = p1*aHadron->GetMomentum().unit();
|
||||
if (theEnergyDistribution != 0) {
|
||||
aHadron->SetDefinition(theDefs[i0]);
|
||||
aHadron->SetKineticEnergy(theEnergyDistribution->Sample(eKinetic, dummy));
|
||||
}
|
||||
else if (nDef == 1) {
|
||||
aHadron->SetDefinition(theDefs[i0]);
|
||||
aHadron->SetKineticEnergy(eKinetic);
|
||||
}
|
||||
else if (nDef == 2) {
|
||||
aHadron->SetDefinition(theDefs[i0]);
|
||||
aHadron->SetKineticEnergy(50 * CLHEP::MeV);
|
||||
}
|
||||
else {
|
||||
throw G4HadronicException(
|
||||
__FILE__, __LINE__,
|
||||
"No energy distribution to sample from in InelasticBaseFS::BaseApply");
|
||||
}
|
||||
theAngularDistribution->SampleAndUpdate(*aHadron);
|
||||
if (theEnergyDistribution == 0 && nDef == 2) {
|
||||
if (i0 == 0) {
|
||||
G4double mass1 = theDefs[0]->GetPDGMass();
|
||||
G4double mass2 = theDefs[1]->GetPDGMass();
|
||||
G4double massn = theProjectile->GetPDGMass();
|
||||
G4int z1 = static_cast<G4int>(theBaseZ + eps - theDefs[0]->GetPDGCharge()
|
||||
- theDefs[1]->GetPDGCharge());
|
||||
G4int a1 = static_cast<G4int>(theBaseA + eps) - theDefs[0]->GetBaryonNumber()
|
||||
- theDefs[1]->GetBaryonNumber();
|
||||
G4double concreteMass = G4NucleiProperties::GetNuclearMass(a1, z1);
|
||||
G4double availableEnergy = eKinetic + massn + localMass - mass1 - mass2 - concreteMass;
|
||||
// available kinetic energy in CMS (non relativistic)
|
||||
G4double emin =
|
||||
availableEnergy + mass1 + mass2
|
||||
- std::sqrt((mass1 + mass2) * (mass1 + mass2) + orgMomentum * orgMomentum);
|
||||
G4double p1 = std::sqrt(2. * mass2 * emin);
|
||||
bufferedDirection = p1 * aHadron->GetMomentum().unit();
|
||||
#ifdef G4PHPDEBUG
|
||||
if(std::getenv("G4ParticleHPDebug")) // @@@@@ verify the nucleon counting...
|
||||
{
|
||||
G4cout << "G4ParticleHPInelasticBaseFS "<<z1<<" "<<theBaseZ<<" "<<a1<<" "<<theBaseA<<" "<<availableEnergy<<" "
|
||||
<< emin<<G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug")) // @@@@@ verify the nucleon counting...
|
||||
{
|
||||
G4cout << "G4ParticleHPInelasticBaseFS " << z1 << " " << theBaseZ << " " << a1 << " "
|
||||
<< theBaseA << " " << availableEnergy << " " << emin << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferedDirection = -bufferedDirection;
|
||||
}
|
||||
// boost from cms to lab
|
||||
}
|
||||
else {
|
||||
bufferedDirection = -bufferedDirection;
|
||||
}
|
||||
// boost from cms to lab
|
||||
#ifdef G4PHPDEBUG
|
||||
if(std::getenv("G4ParticleHPDebug"))
|
||||
{
|
||||
G4cout << " G4ParticleHPInelasticBaseFS "<<bufferedDirection.mag2()<<G4endl;
|
||||
}
|
||||
if (std::getenv("G4ParticleHPDebug")) {
|
||||
G4cout << " G4ParticleHPInelasticBaseFS " << bufferedDirection.mag2() << G4endl;
|
||||
}
|
||||
#endif
|
||||
aHadron->SetTotalEnergy( std::sqrt(aHadron->GetMass()*aHadron->GetMass()
|
||||
+bufferedDirection.mag2()) );
|
||||
aHadron->SetMomentum(bufferedDirection);
|
||||
aHadron->Lorentz(*aHadron, -1.*(theTarget+incidReactionProduct));
|
||||
#ifdef G4PHPDEBUG
|
||||
if(std::getenv("G4ParticleHPDebug"))
|
||||
{
|
||||
G4cout << " G4ParticleHPInelasticBaseFS "<<aHadron->GetTotalEnergy()<<" "<<aHadron->GetMomentum()<<G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
tmpHadrons->push_back(aHadron);
|
||||
aHadron->SetTotalEnergy(
|
||||
std::sqrt(aHadron->GetMass() * aHadron->GetMass() + bufferedDirection.mag2()));
|
||||
aHadron->SetMomentum(bufferedDirection);
|
||||
aHadron->Lorentz(*aHadron, -1. * (theTarget + incidReactionProduct));
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug")) G4cout << " G4ParticleHPInelasticBaseFS::BaseApply FSData add secondary " << aHadron->GetDefinition()->GetParticleName() << " E= " << aHadron->GetKineticEnergy() << G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug")) {
|
||||
G4cout << " G4ParticleHPInelasticBaseFS " << aHadron->GetTotalEnergy() << " "
|
||||
<< aHadron->GetMomentum() << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
tmpHadrons->push_back(aHadron);
|
||||
#ifdef G4PHPDEBUG
|
||||
if (std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply FSData add secondary "
|
||||
<< aHadron->GetDefinition()->GetParticleName()
|
||||
<< " E= " << aHadron->GetKineticEnergy() << G4endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
delete [] Done;
|
||||
delete[] Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
throw G4HadronicException(__FILE__, __LINE__, "No data to create the neutrons in NInelasticFS");
|
||||
}
|
||||
|
||||
G4ReactionProductVector * thePhotons = nullptr;
|
||||
if(theFinalStatePhotons!=0)
|
||||
{
|
||||
G4ReactionProductVector* thePhotons = nullptr;
|
||||
if (theFinalStatePhotons != 0) {
|
||||
// the photon distributions are in the Nucleus rest frame.
|
||||
G4ReactionProduct boosted_tmp;
|
||||
boosted_tmp.Lorentz(incidReactionProduct, theTarget);
|
||||
G4double anEnergy = boosted_tmp.GetKineticEnergy();
|
||||
thePhotons = theFinalStatePhotons->GetPhotons(anEnergy);
|
||||
if(thePhotons!=0)
|
||||
{
|
||||
for(i=0; i<thePhotons->size(); ++i)
|
||||
{
|
||||
if (thePhotons != 0) {
|
||||
for (i = 0; i < thePhotons->size(); ++i) {
|
||||
// back to lab
|
||||
thePhotons->operator[](i)->Lorentz(*(thePhotons->operator[](i)), -1.*theTarget);
|
||||
thePhotons->operator[](i)->Lorentz(*(thePhotons->operator[](i)), -1. * theTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(theEnergyAngData!=0)
|
||||
{
|
||||
|
||||
else if (theEnergyAngData != 0) {
|
||||
// PA130927: do not create photons to adjust binding energy
|
||||
G4bool bAdjustPhotons = true;
|
||||
#ifdef PHP_AS_HP
|
||||
bAdjustPhotons = true;
|
||||
#ifdef PHP_AS_HP
|
||||
bAdjustPhotons = true;
|
||||
#else
|
||||
if ( G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState() )
|
||||
bAdjustPhotons = false;
|
||||
if (G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState()) bAdjustPhotons = false;
|
||||
#endif
|
||||
|
||||
if( bAdjustPhotons ) {
|
||||
|
||||
if (bAdjustPhotons) {
|
||||
G4double theGammaEnergy = theEnergyAngData->GetTotalMeanEnergy();
|
||||
G4double anEnergy = boosted.GetKineticEnergy();
|
||||
theGammaEnergy = anEnergy-theGammaEnergy;
|
||||
theGammaEnergy = anEnergy - theGammaEnergy;
|
||||
theGammaEnergy += theNuclearMassDifference;
|
||||
G4double eBindProducts = 0;
|
||||
G4double eBindN = 0;
|
||||
G4double eBindP = 0;
|
||||
G4double eBindD = G4NucleiProperties::GetBindingEnergy(2,1);
|
||||
G4double eBindT = G4NucleiProperties::GetBindingEnergy(3,1);
|
||||
G4double eBindHe3 = G4NucleiProperties::GetBindingEnergy(3,2);
|
||||
G4double eBindA = G4NucleiProperties::GetBindingEnergy(4,2);
|
||||
G4int ia=0;
|
||||
for(i=0; i<tmpHadrons->size(); i++)
|
||||
{
|
||||
if(tmpHadrons->operator[](i)->GetDefinition() == G4Neutron::Neutron())
|
||||
{
|
||||
eBindProducts+=eBindN;
|
||||
}
|
||||
else if(tmpHadrons->operator[](i)->GetDefinition() == G4Proton::Proton())
|
||||
{
|
||||
eBindProducts+=eBindP;
|
||||
}
|
||||
else if(tmpHadrons->operator[](i)->GetDefinition() == G4Deuteron::Deuteron())
|
||||
{
|
||||
eBindProducts+=eBindD;
|
||||
}
|
||||
else if(tmpHadrons->operator[](i)->GetDefinition() == G4Triton::Triton())
|
||||
{
|
||||
eBindProducts+=eBindT;
|
||||
}
|
||||
else if(tmpHadrons->operator[](i)->GetDefinition() == G4He3::He3())
|
||||
{
|
||||
eBindProducts+=eBindHe3;
|
||||
}
|
||||
else if(tmpHadrons->operator[](i)->GetDefinition() == G4Alpha::Alpha())
|
||||
{
|
||||
eBindProducts+=eBindA;
|
||||
ia++;
|
||||
}
|
||||
}
|
||||
|
||||
G4double eBindD = G4NucleiProperties::GetBindingEnergy(2, 1);
|
||||
G4double eBindT = G4NucleiProperties::GetBindingEnergy(3, 1);
|
||||
G4double eBindHe3 = G4NucleiProperties::GetBindingEnergy(3, 2);
|
||||
G4double eBindA = G4NucleiProperties::GetBindingEnergy(4, 2);
|
||||
G4int ia = 0;
|
||||
for (i = 0; i < tmpHadrons->size(); i++) {
|
||||
if (tmpHadrons->operator[](i)->GetDefinition() == G4Neutron::Neutron()) {
|
||||
eBindProducts += eBindN;
|
||||
}
|
||||
else if (tmpHadrons->operator[](i)->GetDefinition() == G4Proton::Proton()) {
|
||||
eBindProducts += eBindP;
|
||||
}
|
||||
else if (tmpHadrons->operator[](i)->GetDefinition() == G4Deuteron::Deuteron()) {
|
||||
eBindProducts += eBindD;
|
||||
}
|
||||
else if (tmpHadrons->operator[](i)->GetDefinition() == G4Triton::Triton()) {
|
||||
eBindProducts += eBindT;
|
||||
}
|
||||
else if (tmpHadrons->operator[](i)->GetDefinition() == G4He3::He3()) {
|
||||
eBindProducts += eBindHe3;
|
||||
}
|
||||
else if (tmpHadrons->operator[](i)->GetDefinition() == G4Alpha::Alpha()) {
|
||||
eBindProducts += eBindA;
|
||||
ia++;
|
||||
}
|
||||
}
|
||||
|
||||
theGammaEnergy += eBindProducts;
|
||||
|
||||
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug")) G4cout << " G4ParticleHPInelasticBaseFS::BaseApply gamma Energy " << theGammaEnergy << " eBindProducts " << eBindProducts << G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply gamma Energy " << theGammaEnergy
|
||||
<< " eBindProducts " << eBindProducts << G4endl;
|
||||
#endif
|
||||
|
||||
|
||||
// Special treatment for Be9 + n -> 2n + Be8 -> 2n + a + a
|
||||
if ( (G4int)(theBaseZ+eps) == 4 && (G4int)(theBaseA+eps) == 9 )
|
||||
{
|
||||
// This only valid for G4NDL3.13,,,
|
||||
if ( std::abs( theNuclearMassDifference -
|
||||
( G4NucleiProperties::GetBindingEnergy( 8 , 4 ) -
|
||||
G4NucleiProperties::GetBindingEnergy( 9 , 4 ) ) ) < 1*CLHEP::keV
|
||||
&& ia == 2 )
|
||||
{
|
||||
theGammaEnergy -= (2*eBindA);
|
||||
}
|
||||
}
|
||||
|
||||
G4ReactionProductVector * theOtherPhotons = nullptr;
|
||||
G4int iLevel;
|
||||
while(theGammaEnergy>=theGammas.GetLevelEnergy(0)) // Loop checking, 11.05.2015, T. Koi
|
||||
{
|
||||
for(iLevel=theGammas.GetNumberOfLevels()-1; iLevel>=0; --iLevel)
|
||||
{
|
||||
if(theGammas.GetLevelEnergy(iLevel)<theGammaEnergy) break;
|
||||
}
|
||||
if(iLevel==0||iLevel==theGammas.GetNumberOfLevels()-1)
|
||||
{
|
||||
theOtherPhotons = theGammas.GetDecayGammas(iLevel);
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply adding gamma from level "
|
||||
<< iLevel << " "
|
||||
<< theOtherPhotons->operator[](ii)->GetKineticEnergy(
|
||||
) << G4endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double random = G4UniformRand();
|
||||
G4double eLow = theGammas.GetLevelEnergy(iLevel);
|
||||
G4double eHigh = theGammas.GetLevelEnergy(iLevel+1);
|
||||
if(random > (eHigh-eLow)/(theGammaEnergy-eLow)) iLevel++;
|
||||
theOtherPhotons = theGammas.GetDecayGammas(iLevel);
|
||||
}
|
||||
if(thePhotons==0) thePhotons = new G4ReactionProductVector;
|
||||
if(theOtherPhotons != 0)
|
||||
{
|
||||
for(std::size_t iii=0; iii<theOtherPhotons->size(); ++iii)
|
||||
{
|
||||
thePhotons->push_back(theOtherPhotons->operator[](iii));
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << iii << " G4ParticleHPInelasticBaseFS::BaseApply adding gamma " << theOtherPhotons->operator[](iii)->GetKineticEnergy() << G4endl;
|
||||
#endif
|
||||
}
|
||||
delete theOtherPhotons;
|
||||
}
|
||||
theGammaEnergy -= theGammas.GetLevelEnergy(iLevel);
|
||||
if(iLevel == -1) break;
|
||||
}
|
||||
if ((G4int)(theBaseZ + eps) == 4 && (G4int)(theBaseA + eps) == 9) {
|
||||
// This only valid for G4NDL3.13,,,
|
||||
if (std::abs(theNuclearMassDifference
|
||||
- (G4NucleiProperties::GetBindingEnergy(8, 4)
|
||||
- G4NucleiProperties::GetBindingEnergy(9, 4)))
|
||||
< 1 * CLHEP::keV
|
||||
&& ia == 2)
|
||||
{
|
||||
theGammaEnergy -= (2 * eBindA);
|
||||
}
|
||||
}
|
||||
|
||||
if (theGammaEnergy > 0.0) {
|
||||
for (G4int iLevel = theGammas.GetNumberOfLevels() - 1; iLevel > 0; --iLevel) {
|
||||
G4double e = theGammas.GetLevelEnergy(iLevel);
|
||||
if (e < theGammaEnergy) {
|
||||
thePhotons = theGammas.GetDecayGammas(iLevel);
|
||||
theGammaEnergy -= e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill the result
|
||||
std::size_t nSecondaries = tmpHadrons->size();
|
||||
std::size_t nPhotons = 0;
|
||||
if(thePhotons!=0) { nPhotons = thePhotons->size(); }
|
||||
if (thePhotons != 0) {
|
||||
nPhotons = thePhotons->size();
|
||||
}
|
||||
nSecondaries += nPhotons;
|
||||
G4DynamicParticle * theSec;
|
||||
G4DynamicParticle* theSec;
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply N hadrons "
|
||||
<< nSecondaries-nPhotons << G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply N hadrons " << nSecondaries - nPhotons
|
||||
<< G4endl;
|
||||
#endif
|
||||
|
||||
for(i=0; i<nSecondaries-nPhotons; ++i)
|
||||
{
|
||||
theSec = new G4DynamicParticle;
|
||||
theSec->SetDefinition(tmpHadrons->operator[](i)->GetDefinition());
|
||||
theSec->SetMomentum(tmpHadrons->operator[](i)->GetMomentum());
|
||||
theResult.Get()->AddSecondary(theSec, secID);
|
||||
|
||||
for (i = 0; i < nSecondaries - nPhotons; ++i) {
|
||||
theSec = new G4DynamicParticle;
|
||||
theSec->SetDefinition(tmpHadrons->operator[](i)->GetDefinition());
|
||||
theSec->SetMomentum(tmpHadrons->operator[](i)->GetMomentum());
|
||||
theResult.Get()->AddSecondary(theSec, secID);
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug")) G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply add secondary2 " << theSec->GetParticleDefinition()->GetParticleName() << " E= " << theSec->GetKineticEnergy() << " NSECO " << theResult.Get()->GetNumberOfSecondaries() << G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply add secondary2 "
|
||||
<< theSec->GetParticleDefinition()->GetParticleName()
|
||||
<< " E= " << theSec->GetKineticEnergy() << " NSECO "
|
||||
<< theResult.Get()->GetNumberOfSecondaries() << G4endl;
|
||||
#endif
|
||||
delete tmpHadrons->operator[](i);
|
||||
}
|
||||
delete tmpHadrons->operator[](i);
|
||||
}
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug")) G4cout << " G4ParticleHPInelasticBaseFS::BaseApply N photons " << nPhotons << G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << " G4ParticleHPInelasticBaseFS::BaseApply N photons " << nPhotons << G4endl;
|
||||
#endif
|
||||
if(thePhotons != 0)
|
||||
{
|
||||
for(i=0; i<nPhotons; ++i)
|
||||
{
|
||||
theSec = new G4DynamicParticle;
|
||||
if (thePhotons != 0) {
|
||||
for (i = 0; i < nPhotons; ++i) {
|
||||
theSec = new G4DynamicParticle;
|
||||
theSec->SetDefinition(thePhotons->operator[](i)->GetDefinition());
|
||||
theSec->SetMomentum(thePhotons->operator[](i)->GetMomentum());
|
||||
theResult.Get()->AddSecondary(theSec, secID);
|
||||
theResult.Get()->AddSecondary(theSec, secID);
|
||||
#ifdef G4PHPDEBUG
|
||||
if( std::getenv("G4ParticleHPDebug")) G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply add secondary3 " << theSec->GetParticleDefinition()->GetParticleName() << " E= " << theSec->GetKineticEnergy() << " NSECO " << theResult.Get()->GetNumberOfSecondaries() << G4endl;
|
||||
if (std::getenv("G4ParticleHPDebug"))
|
||||
G4cout << this << " G4ParticleHPInelasticBaseFS::BaseApply add secondary3 "
|
||||
<< theSec->GetParticleDefinition()->GetParticleName()
|
||||
<< " E= " << theSec->GetKineticEnergy() << " NSECO "
|
||||
<< theResult.Get()->GetNumberOfSecondaries() << G4endl;
|
||||
#endif
|
||||
delete thePhotons->operator[](i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// some garbage collection
|
||||
delete thePhotons;
|
||||
delete tmpHadrons;
|
||||
|
||||
G4ParticleDefinition* targ_pd = G4IonTable::GetIonTable()->GetIon ( (G4int)theBaseZ , (G4int)theBaseA , 0.0 );
|
||||
G4LorentzVector targ_4p_lab ( theTarget.GetMomentum() , std::sqrt( targ_pd->GetPDGMass()*targ_pd->GetPDGMass() + theTarget.GetMomentum().mag2() ) );
|
||||
G4ParticleDefinition* targ_pd =
|
||||
G4IonTable::GetIonTable()->GetIon((G4int)theBaseZ, (G4int)theBaseA, 0.0);
|
||||
G4LorentzVector targ_4p_lab(
|
||||
theTarget.GetMomentum(),
|
||||
std::sqrt(targ_pd->GetPDGMass() * targ_pd->GetPDGMass() + theTarget.GetMomentum().mag2()));
|
||||
G4LorentzVector proj_4p_lab = theTrack.Get4Momentum();
|
||||
G4LorentzVector init_4p_lab = proj_4p_lab + targ_4p_lab;
|
||||
|
||||
//if data in MF=6 format (no correlated particle emission), then adjust_final_state can give severe errors:
|
||||
if(theEnergyAngData==0){adjust_final_state ( init_4p_lab );}
|
||||
// if data in MF=6 format (no correlated particle emission), then adjust_final_state can give
|
||||
// severe errors:
|
||||
if (theEnergyAngData == 0) {
|
||||
adjust_final_state(init_4p_lab);
|
||||
}
|
||||
|
||||
// clean up the primary neutron
|
||||
theResult.Get()->SetStatusChange(stopAndKill);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,89 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// neutron_hp -- source file
|
||||
// J.P. Wellisch, Nov-1996
|
||||
// A prototype of the low energy neutron transport model.
|
||||
//
|
||||
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
|
||||
//
|
||||
#include "G4ParticleHPLevel.hh"
|
||||
#include "G4ParticleHPGamma.hh"
|
||||
|
||||
G4ParticleHPLevel::~G4ParticleHPLevel()
|
||||
{
|
||||
if(theGammas != 0)
|
||||
{
|
||||
for(G4int i=0; i<nGammas; i++) delete theGammas[i];
|
||||
}
|
||||
delete [] theGammas;
|
||||
}
|
||||
|
||||
void G4ParticleHPLevel::SetNumberOfGammas(G4int aGammas)
|
||||
{
|
||||
nGammas = aGammas;
|
||||
if(theGammas != 0)
|
||||
{
|
||||
for(G4int i=0; i<nGammas; i++) delete theGammas[i];
|
||||
}
|
||||
delete [] theGammas;
|
||||
theGammas = new G4ParticleHPGamma * [nGammas];
|
||||
}
|
||||
|
||||
void G4ParticleHPLevel::SetGamma(G4int i, G4ParticleHPGamma * aGamma)
|
||||
{
|
||||
theGammas[i] = aGamma;
|
||||
SetLevelEnergy(aGamma->GetLevelEnergy());
|
||||
}
|
||||
|
||||
G4double G4ParticleHPLevel::GetGammaEnergy(G4int i)
|
||||
{
|
||||
return theGammas[i]->GetGammaEnergy();
|
||||
}
|
||||
|
||||
G4DynamicParticleVector * G4ParticleHPLevel::GetDecayGammas()
|
||||
{
|
||||
G4DynamicParticleVector * theResult;
|
||||
G4double sum = 0;
|
||||
G4double * running = new G4double[nGammas];
|
||||
running[0] = 0;
|
||||
G4int i;
|
||||
for(i=0; i<nGammas; i++)
|
||||
{
|
||||
if(i!=0) running[i]=running[i-1];
|
||||
running[i]+=theGammas[i]->GetWeight();
|
||||
}
|
||||
sum = running[nGammas-1];
|
||||
G4int it(0);
|
||||
G4double random = G4UniformRand();
|
||||
for(i=0; i<nGammas; i++)
|
||||
{
|
||||
it = i;
|
||||
if(random*sum < running[i]) break;
|
||||
}
|
||||
delete [] running;
|
||||
theResult = theGammas[it]->GetDecayGammas();
|
||||
return theResult;
|
||||
}
|
||||
+58
-63
@@ -23,75 +23,70 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// V. Ivanchenko, 21 April 2023 Data structure class for gamma levels
|
||||
//
|
||||
// P. Arce, June-2014 Conversion neutron_hp to particle_hp
|
||||
//
|
||||
#ifndef G4ParticleHPGamma_h
|
||||
#define G4ParticleHPGamma_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ios.hh"
|
||||
#include <fstream>
|
||||
#include "G4DynamicParticleVector.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleHPNucLevel.hh"
|
||||
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ParticleHPLevel.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
class G4ParticleHPGamma
|
||||
G4ParticleHPNucLevel::G4ParticleHPNucLevel(G4double e) : levelEnergy(e) {}
|
||||
|
||||
void G4ParticleHPNucLevel::AddGamma(G4double e, G4double w, G4int idx)
|
||||
{
|
||||
public:
|
||||
|
||||
G4ParticleHPGamma();
|
||||
~G4ParticleHPGamma();
|
||||
|
||||
G4bool Init(std::istream & aDataFile);
|
||||
|
||||
inline void SetNext(G4ParticleHPLevel * aLevel)
|
||||
{
|
||||
next = aLevel;
|
||||
gammaData x;
|
||||
x.gammaEnergy = e;
|
||||
x.cumProbability = w;
|
||||
x.next = idx;
|
||||
gammas.push_back(x);
|
||||
++nGammas;
|
||||
}
|
||||
|
||||
void G4ParticleHPNucLevel::Normalize()
|
||||
{
|
||||
if (gammas.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
G4DynamicParticleVector * GetDecayGammas()
|
||||
{
|
||||
G4DynamicParticleVector * theResult;
|
||||
if(next == 0)
|
||||
{
|
||||
theResult = new G4DynamicParticleVector;
|
||||
G4double sum = 0.0;
|
||||
for (auto& gam : gammas) {
|
||||
sum += gam.cumProbability;
|
||||
}
|
||||
if (sum <= 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
G4double norm = 1.0 / sum;
|
||||
sum = 0;
|
||||
for (auto& gam : gammas) {
|
||||
sum += norm * gam.cumProbability;
|
||||
gam.cumProbability = sum;
|
||||
}
|
||||
gammas[nGammas - 1].cumProbability = 1.0;
|
||||
}
|
||||
|
||||
G4ReactionProduct* G4ParticleHPNucLevel::GetDecayGamma(G4int& idx) const
|
||||
{
|
||||
if (gammas.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
G4double q = G4UniformRand();
|
||||
G4double e = 0.0;
|
||||
for (auto& gam : gammas) {
|
||||
if (q <= gam.cumProbability) {
|
||||
e = gam.gammaEnergy;
|
||||
idx = gam.next;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
theResult = next->GetDecayGammas();
|
||||
}
|
||||
G4DynamicParticle * theNew = new G4DynamicParticle;
|
||||
theNew->SetDefinition(G4Gamma::Gamma());
|
||||
theNew->SetKineticEnergy(gammaEnergy);
|
||||
theResult->push_back(theNew);
|
||||
return theResult;
|
||||
}
|
||||
|
||||
inline G4double GetLevelEnergy()
|
||||
{
|
||||
return levelEnergy;
|
||||
if (e <= 0.0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline G4double GetGammaEnergy()
|
||||
{
|
||||
return gammaEnergy;
|
||||
}
|
||||
|
||||
inline G4double GetWeight()
|
||||
{
|
||||
return probability;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
G4double levelEnergy;
|
||||
G4double gammaEnergy;
|
||||
G4double probability;
|
||||
|
||||
G4ParticleHPLevel * next;
|
||||
static G4ThreadLocal int instancecount;
|
||||
};
|
||||
|
||||
#endif
|
||||
G4ThreeVector p = G4RandomDirection();
|
||||
p *= e;
|
||||
auto res = new G4ReactionProduct(G4Gamma::Gamma());
|
||||
res->SetMomentum(p);
|
||||
res->SetKineticEnergy(e);
|
||||
return res;
|
||||
}
|
||||
@@ -7,6 +7,12 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-05-25 Alberto Ribon (hadr-util-V11-00-14)
|
||||
- G4Fragment : replaced (fatal) G4HadronicException with G4Exception.
|
||||
Note: in the method CalculateMassAndExcitationEnergy(), the exception type
|
||||
is "EventMustBeAborted" to avoid rare crashes seen in INCLXX, which
|
||||
are difficult to reproduce and fix.
|
||||
|
||||
## 2022-11-26 Gabriele Cosmo (hadr-util-V11-00-13)
|
||||
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#include "G4Fragment.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4Exception.hh"
|
||||
#include "G4ios.hh"
|
||||
#include <iomanip>
|
||||
|
||||
@@ -167,9 +167,10 @@ G4Fragment::G4Fragment(const G4LorentzVector& aMomentum,
|
||||
{
|
||||
if(aParticleDefinition->GetPDGEncoding() != 22 &&
|
||||
aParticleDefinition->GetPDGEncoding() != 11) {
|
||||
G4String text = "G4Fragment::G4Fragment constructor for gamma used for "
|
||||
+ aParticleDefinition->GetParticleName();
|
||||
throw G4HadronicException(__FILE__, __LINE__, text);
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Particle: " << aParticleDefinition->GetParticleName() << G4endl;
|
||||
G4Exception( "G4Fragment::G4Fragment: constructor for gamma used for another type of particle ! ",
|
||||
"HAD_FRAGMENT_01", FatalException, ed );
|
||||
}
|
||||
theGroundStateMass = aParticleDefinition->GetPDGMass();
|
||||
}
|
||||
@@ -178,11 +179,10 @@ void G4Fragment::CalculateMassAndExcitationEnergy()
|
||||
{
|
||||
// check input
|
||||
if(theZ > theA || theZ + theL > theA) {
|
||||
G4String text = "G4Fragment::CalculateMassAndExcitationEnergy: inconsistent number of nucleons is ignored";
|
||||
G4cout << text << G4endl;
|
||||
G4cout << " Z=" << theZ << " A=" << theA
|
||||
<< " nLambdas=" << theL << G4endl;
|
||||
throw G4HadronicException(__FILE__, __LINE__, text);
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Fragment: Z=" << theZ << " A=" << theA << " nLambdas=" << theL << G4endl;
|
||||
G4Exception( "G4Fragment::CalculateMassAndExcitationEnergy: inconsistent number of nucleons ! ",
|
||||
"HAD_FRAGMENT_02", EventMustBeAborted, ed );
|
||||
}
|
||||
// compute mass
|
||||
theGroundStateMass = ( theL == 0 )
|
||||
@@ -315,11 +315,10 @@ void G4Fragment::ExcitationEnergyWarning()
|
||||
|
||||
void G4Fragment::NumberOfExitationWarning(const G4String& value)
|
||||
{
|
||||
G4cout << "G4Fragment::"<< value << " ERROR "
|
||||
<< G4endl;
|
||||
G4cout << this << G4endl;
|
||||
G4String text = "G4Fragment::G4Fragment wrong exciton number ";
|
||||
throw G4HadronicException(__FILE__, __LINE__, text);
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Value=" << value << G4endl;
|
||||
G4Exception( "G4Fragment::NumberOfExitationWarning : wrong exciton number ! ",
|
||||
"HAD_FRAGMENT_03", FatalException, ed );
|
||||
}
|
||||
|
||||
void G4Fragment::SetAngularMomentum(const G4ThreeVector& v)
|
||||
|
||||
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-03-23 Anna Zaborowska (param-V11-00-05)
|
||||
- Added missing virtual destructor to G4VFastSimSensitiveDetector
|
||||
|
||||
## 2022-11-23 Gabriele Cosmo (param-V11-00-04)
|
||||
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
class G4VFastSimSensitiveDetector
|
||||
{
|
||||
public:
|
||||
virtual ~G4VFastSimSensitiveDetector() = default;
|
||||
/// Create a hit.
|
||||
///
|
||||
/// It checks if G4VSensitiveDetector is also used as a base class,
|
||||
|
||||
Reference in New Issue
Block a user