Import Geant4 11.0.1 source tree

This commit is contained in:
Gabriele Cosmo
2022-03-23 08:25:50 +01:00
parent 84f33a068c
commit de4f28d823
234 changed files with 61815 additions and 61766 deletions
+4
View File
@@ -16,6 +16,10 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
January. 19th, 2022 - V.Ivantchenko (proccuts-V10-07-06)
- G4VRangeToEnergyConverter - fixed construction/destruction of
static data (initial problem identified by I. Hrivnakova)
October. 12th, 2021 - V.Ivanchenko (proccuts-V10-07-05)
- G4PhysicsTableHelper - fixed Coverity warning due to index type,
removed G4ThreadLocal variable, substitute old cerr by
@@ -117,6 +117,7 @@ protected:
G4int fPDG = 0;
G4int verboseLevel = 1;
G4bool isFirstInstance = false;
};
// ------------------
@@ -52,7 +52,21 @@ G4VRangeToEnergyConverter::G4VRangeToEnergyConverter()
{
if(nullptr == Energy)
{
Energy = new std::vector<G4double>(Nbin + 1);
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&theMutex);
if(nullptr == Energy)
{
#endif
isFirstInstance = true;
Energy = new std::vector<G4double>(Nbin + 1);
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&theMutex);
#endif
}
// this method defines lock itself
if(isFirstInstance)
{
FillEnergyVector(1*CLHEP::keV, 10.0*CLHEP::GeV);
}
}
@@ -60,7 +74,7 @@ G4VRangeToEnergyConverter::G4VRangeToEnergyConverter()
// --------------------------------------------------------------------
G4VRangeToEnergyConverter::~G4VRangeToEnergyConverter()
{
if(nullptr != Energy)
if(isFirstInstance)
{
delete Energy;
Energy = nullptr;
@@ -145,25 +159,26 @@ void G4VRangeToEnergyConverter::SetMaxEnergyCut(const G4double value)
void G4VRangeToEnergyConverter::FillEnergyVector(const G4double emin,
const G4double emax)
{
if(emin == Emin && emax == Emax) { return; }
#ifdef G4MULTITHREADED
G4MUTEXLOCK(&theMutex);
if(emin == Emin && emax == Emax) { return; }
#endif
Emin = emin;
Emax = emax;
Nbin = NbinPerDecade*static_cast<G4int>(std::log10(emax/emin));
Energy->resize(Nbin + 1);
(*Energy)[0] = emin;
(*Energy)[Nbin] = emax;
G4double fact = G4Log(emax/emin)/Nbin;
for(G4int i=1; i<Nbin; ++i)
if(emin != Emin || emax != Emax)
{
(*Energy)[i] = emin*G4Exp(i * fact);
}
#ifdef G4MULTITHREADED
G4MUTEXUNLOCK(&theMutex);
G4MUTEXLOCK(&theMutex);
if(emin != Emin || emax != Emax)
{
#endif
Emin = emin;
Emax = emax;
Nbin = NbinPerDecade*static_cast<G4int>(std::log10(emax/emin));
Energy->resize(Nbin + 1);
(*Energy)[0] = emin;
(*Energy)[Nbin] = emax;
G4double fact = G4Log(emax/emin)/Nbin;
for(G4int i=1; i<Nbin; ++i) { (*Energy)[i] = emin*G4Exp(i * fact); }
#ifdef G4MULTITHREADED
}
G4MUTEXUNLOCK(&theMutex);
#endif
}
}
// --------------------------------------------------------------------
@@ -15,6 +15,24 @@ committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
06.02.2022 V. Ivanchenko, emlowen-V10-07-28
- G4MicroElecInelasticModel_new - removed not working if{} block
06.02.2022 V. Ivanchenko
- G4MicroElecInelasticModel_new - C. Inguimbert change interpolate method
making a choice between log-log, lin-log, and lin-lin interpolations and
added a protection for zero input energy. When sample transition the choice
the choice is implemented for transition from atomic level and Fermi level.
This MR should fix rare crash due to this model.
04.02.2022 V. Ivanchenko
- G4hIonEffChargeSquare, G4PenelopeRayleighModel, G4PenelopeRayleighModelMI
fixed compilation warning on unused variable
18.01.2022 J. Hahnfeld
- Prefer pointer to `const G4Material` if possible
25.11.2021 S. Guatelli, emlowen-V10-07-27
- Added option to activate the ANSTO fluorescence radiation yield (Z < 93)
@@ -127,7 +127,9 @@ public:
G4MicroElecInelasticModel_new & operator=(const G4MicroElecInelasticModel_new &right) = delete;
G4MicroElecInelasticModel_new(const G4MicroElecInelasticModel_new&) = delete;
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
private:
@@ -188,6 +190,7 @@ private:
G4int verboseLevel;
G4bool isInitialised ;
G4bool fasterCode;
G4bool SEFromFermiLevel;
};
#endif
@@ -126,8 +126,8 @@ private:
G4ThreeVector oldMomentum, previousMomentum;
G4ThreeVector theGlobalNormal;
G4ThreeVector theFacetNormal;
G4Material* material1;
G4Material* material2;
const G4Material* material1;
const G4Material* material2;
G4MicroElecSurfaceStatus theStatus;
G4double theParticleMomentum;
@@ -120,7 +120,9 @@ G4MicroElecInelasticModel_new::G4MicroElecInelasticModel_new(
// default generator
SetAngularDistribution(new G4DeltaAngle());
// Selection of computation method
fasterCode = true;
SEFromFermiLevel = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -687,23 +689,26 @@ void G4MicroElecInelasticModel_new::SampleSecondaries(std::vector<G4DynamicParti
G4int shellEnum = currentMaterialStructure->GetEADL_Enumerator(Shell);
if (currentMaterialStructure->IsShellWeaklyBound(Shell)) { shellEnum = -1; }
if(fAtomDeexcitation && shellEnum >=0) {
// G4cout << "enter if deex and shell 0" << G4endl;
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(shellEnum);
const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
secNumberInit = fvect->size();
fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
secNumberFinal = fvect->size();
}
if(fAtomDeexcitation && shellEnum >=0)
{
// G4cout << "enter if deex and shell 0" << G4endl;
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(shellEnum);
const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
secNumberInit = fvect->size();
fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
secNumberFinal = fvect->size();
}
G4double secondaryKinetic=-1000*eV;
SEFromFermiLevel = false;
if (!fasterCode)
{
secondaryKinetic = RandomizeEjectedElectronEnergy(PartDef, k, Shell, originalMass, originalZ);
}
else {
secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulatedDcs(PartDef, k, Shell) ;
}
else
{
secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulatedDcs(PartDef, k, Shell) ;
}
if (verboseLevel > 3)
{
@@ -731,17 +736,18 @@ void G4MicroElecInelasticModel_new::SampleSecondaries(std::vector<G4DynamicParti
G4ThreeVector direction;
direction.set(finalPx,finalPy,finalPz);
fParticleChangeForGamma->ProposeMomentumDirection(direction.unit()) ;
fParticleChangeForGamma->ProposeMomentumDirection(direction.unit());
}
else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection) ;
else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection);
// note that secondaryKinetic is the energy of the delta ray, not of all secondaries.
G4double deexSecEnergy = 0;
for (G4int j=secNumberInit; j < secNumberFinal; j++) {
deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();}
fParticleChangeForGamma->SetProposedKineticEnergy(ekin - secondaryKinetic-limitEnergy); //Ef = Ei-(Q-El)-El = Ei-Q
fParticleChangeForGamma->ProposeLocalEnergyDeposit(limitEnergy-deexSecEnergy);
for (G4int j=secNumberInit; j < secNumberFinal; ++j) {
deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();
}
if (SEFromFermiLevel) limitEnergy = currentMaterialStructure->GetEnergyGap();
fParticleChangeForGamma->SetProposedKineticEnergy(ekin - secondaryKinetic - limitEnergy); //Ef = Ei-(Q-El)-El = Ei-Q
fParticleChangeForGamma->ProposeLocalEnergyDeposit(limitEnergy - deexSecEnergy);
if (secondaryKinetic>0)
{
@@ -837,8 +843,11 @@ G4double G4MicroElecInelasticModel_new::RandomizeEjectedElectronEnergyFromCumula
secondaryElectronKineticEnergy = TransferedEnergy(particleDefinition, k, shell, random)
- currentMaterialStructure->GetLimitEnergy(shell) ;
if (isnan(secondaryElectronKineticEnergy)) { secondaryElectronKineticEnergy = k - currentMaterialStructure->GetLimitEnergy(shell); }
if (secondaryElectronKineticEnergy < 0.) {
secondaryElectronKineticEnergy = 0.;
secondaryElectronKineticEnergy = k - currentMaterialStructure->GetEnergyGap();
SEFromFermiLevel = true;
}
return secondaryElectronKineticEnergy;
}
@@ -1252,12 +1261,35 @@ G4double G4MicroElecInelasticModel_new::Interpolate(G4double e1,
G4double xs1,
G4double xs2)
{
G4double a = (std::log10(xs2)-std::log10(xs1)) / (std::log10(e2)-std::log10(e1));
G4double b = std::log10(xs2) - a*std::log10(e2);
G4double sigma = a*std::log10(e) + b;
G4double value = (std::pow(10.,sigma));
G4double value = 0.;
// Log-log interpolation by default
if (e1 != 0 && e2 != 0 && (e2-e1) != 0 && !fasterCode)
{
G4double a = std::log(xs2/xs1)/ std::log(e2/e1);
G4double b = std::log(xs2) - a * std::log(e2);
G4double sigma = a * std::log(e) + b;
value = (std::exp(sigma));
}
// Switch to log-lin interpolation for faster code
if ((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 && fasterCode)
{
G4double d1 = std::log(xs1);
G4double d2 = std::log(xs2);
value = std::exp((d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
}
// Switch to lin-lin interpolation for faster code
// in case one of xs1 or xs2 (=cum proba) value is zero
if ((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) && fasterCode)
{
G4double d1 = xs1;
G4double d2 = xs2;
value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
}
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -352,11 +352,6 @@ void G4PenelopeRayleighModel::BuildFormFactorTable(const G4Material* material)
for (G4int i=0;i<nElements;i++)
(*StechiometricFactors)[i] /= MaxStechiometricFactor;
// Equivalent atoms per molecule
G4double atomsPerMolecule = 0;
for (G4int i=0;i<nElements;i++)
atomsPerMolecule += (*StechiometricFactors)[i];
/*
CREATE THE FORM FACTOR TABLE
*/
@@ -574,11 +574,6 @@ void G4PenelopeRayleighModelMI::BuildFormFactorTable(const G4Material* material)
for (G4int i=0;i<nElements;i++)
(*StoichiometricFactors)[i] /= MaxStoichiometricFactor;
//Equivalent atoms per molecule
G4double atomsPerMolecule = 0;
for (G4int i=0;i<nElements;i++)
atomsPerMolecule += (*StoichiometricFactors)[i];
//Equivalent molecular weight (dimensionless)
G4double MolWeight = 0.;
for (G4int i=0;i<nElements;i++)
@@ -184,18 +184,6 @@ G4double G4hIonEffChargeSquare::IonEffChargeSquare(
0.66401, 0.84912, 0.88433, 0.80746, 0.43357, 0.41923, 0.43638, 0.51464, 0.73087, 0.81065,
1.9578, 1.0257} ;
static const G4double lFactor[92] = {
1.0, 1.0, 1.1, 1.06, 1.01, 1.03, 1.04, 0.99, 0.95, 0.9,
0.82, 0.81, 0.83, 0.88, 1.0, 0.95, 0.97, 0.99, 0.98, 0.97,
0.98, 0.97, 0.96, 0.93, 0.91, 0.9, 0.88, 0.9, 0.9, 0.9,
0.9, 0.85, 0.9, 0.9, 0.91, 0.92, 0.9, 0.9, 0.9, 0.9,
0.9, 0.88, 0.9, 0.88, 0.88, 0.9, 0.9, 0.88, 0.9, 0.9,
0.9, 0.9, 0.96, 1.2, 0.9, 0.88, 0.88, 0.85, 0.9, 0.9,
0.92, 0.95, 0.99, 1.03, 1.05, 1.07, 1.08, 1.1, 1.08, 1.08,
1.08, 1.08, 1.09, 1.09, 1.1, 1.11, 1.12, 1.13, 1.14, 1.15,
1.17, 1.2, 1.18, 1.17, 1.17, 1.16, 1.16, 1.16, 1.16, 1.16,
1.16, 1.16} ;
static const G4double c[6] = {0.2865, 0.1266, -0.001429,
0.02402,-0.01135, 0.001475} ;
@@ -207,7 +195,7 @@ G4double G4hIonEffChargeSquare::IonEffChargeSquare(
// loop for the elements in the material
// to find out average values Z, vF, lF
G4double z = 0.0, vF = 0.0, lF = 0.0, norm = 0.0 ;
G4double z = 0.0, vF = 0.0, norm = 0.0 ;
if( 1 == NumberOfElements ) {
z = material->GetZ() ;
@@ -215,7 +203,6 @@ G4double G4hIonEffChargeSquare::IonEffChargeSquare(
if(iz < 0) iz = 0 ;
else if(iz > 91) iz = 91 ;
vF = vFermi[iz] ;
lF = lFactor[iz] ;
} else {
for (G4int iel=0; iel<NumberOfElements; iel++)
@@ -229,11 +216,9 @@ G4double G4hIonEffChargeSquare::IonEffChargeSquare(
if(iz < 0) iz = 0 ;
else if(iz > 91) iz =91 ;
vF += vFermi[iz] * weight ;
lF += lFactor[iz] * weight ;
}
z /= norm ;
vF /= norm ;
lF /= norm ;
}
// Helium ion case
@@ -14,6 +14,31 @@ and keep track of all category-tags.
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
04 March 2022: V.Ivanchenko (emstand-V10-07-29)
- G4UniversalFluctuation - removed unnecessary "if"
18 February 2022: V.Ivanchenko
- G4UniversalFluctuation, G4UrbanFluctuation - L.Urban use the same fw=4 and a0=42
parameters of the model providing similar results for small steps or thin
layers to Geant4 10.7 version of fluctuations (fixed #2466)
14 February 2022: V.Ivanchenko
- G4UrbanMscModel - minor optimisation of arithmetic
- G4UniversalFluctuation - introduced a new protected method SampleGlandz(..),
which provides sampling of non-Gauss fluctuations; improved arithmetic;
results are identical to the version of the release
- G4UrbanFluctuation - reorganized version of fluctuation model from
Geant4 10.7 in SampleGlandz(...) method
- G4LossFluctuationDummy - new class with zero fluctuations
24 January 22: V.Ivanchenko
- G4UrbanMscModel - removed multiple initialisation of the cache data structure and
possible data race
08 January 22: V.Ivanchenko
- G4CoulombScattering - for single scattering used in restriced interval of large
angles use fEmIncreasing type of cross section shape
26 November 21: V.Ivanchenko (emstand-V10-07-28)
- G4PairProductionRelModel - reduce upper limit of parameterisation x-section
from 80 to 30 GeV
@@ -0,0 +1,78 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
//
// File name: G4LossFluctuationDummy
//
// Author: V.Ivanchenko
//
// Creation date: 14.02.2022
//
// -------------------------------------------------------------------
//
#ifndef G4LossFluctuationDummy_h
#define G4LossFluctuationDummy_h 1
#include "G4VEmFluctuationModel.hh"
class G4LossFluctuationDummy : public G4VEmFluctuationModel
{
public:
explicit G4LossFluctuationDummy(const G4String& nam = "DummyFluc");
~G4LossFluctuationDummy() override;
G4double SampleFluctuations(const G4MaterialCutsCouple*,
const G4DynamicParticle*,
const G4double, const G4double,
const G4double, const G4double) final;
G4double Dispersion(const G4Material*,
const G4DynamicParticle*,
const G4double, const G4double,
const G4double) final;
// Initialisation prestep
void SetParticleAndCharge(const G4ParticleDefinition*, G4double) final;
// hide assignment operator
G4LossFluctuationDummy & operator=
(const G4LossFluctuationDummy &right) = delete;
G4LossFluctuationDummy(const G4LossFluctuationDummy&) = delete;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
@@ -40,7 +39,7 @@
//
// Class Description:
//
// Implementation of energy loss fluctuations
// Implementation of energy loss fluctuations made by L.Urban in 2021
// -------------------------------------------------------------------
//
@@ -72,59 +71,64 @@ public:
const G4double, const G4double,
const G4double) override;
void InitialiseMe(const G4ParticleDefinition*) final;
// Initialisation for a new particle type
void InitialiseMe(const G4ParticleDefinition*) override;
// Initialisation prestep
void SetParticleAndCharge(const G4ParticleDefinition*,
G4double q2) final;
void SetParticleAndCharge(const G4ParticleDefinition*,
G4double q2) override;
// hide assignment operator
G4UniversalFluctuation & operator=(const G4UniversalFluctuation &right) = delete;
G4UniversalFluctuation(const G4UniversalFluctuation&) = delete;
G4UniversalFluctuation & operator=
(const G4UniversalFluctuation &right) = delete;
G4UniversalFluctuation(const G4UniversalFluctuation&) = delete;
private:
protected:
virtual G4double SampleGlandz(CLHEP::HepRandomEngine* rndm,
const G4Material*, const G4double tcut);
inline void AddExcitation(CLHEP::HepRandomEngine* rndm,
G4double a, G4double e, G4double& eav,
const G4double ax, const G4double ex,
G4double& eav,
G4double& eloss, G4double& esig2);
inline void SampleGauss(CLHEP::HepRandomEngine* rndm,
G4double eav, G4double esig2,
const G4double eav, const G4double esig2,
G4double& eloss);
const G4ParticleDefinition* particle = nullptr;
const G4Material* lastMaterial = nullptr;
// particle properties
G4double particleMass = 0.0;
// Derived quantities
G4double m_Inv_particleMass = DBL_MAX;
G4double m_massrate = DBL_MAX;
G4double chargeSquare = 1.0;
// data members to speed up the fluctuation calculation
// material properties
G4double ipotFluct = 0.0;
G4double ipotLogFluct = 0.0;
G4double e0 = 0.0;
G4double e1 = 0.0;
// model parameters
G4double minNumberInteractionsBohr = 10.0;
G4double minLoss;
G4double nmaxCont = 8.0;
G4double rate = 0.56;
G4double fw = 5.0;
G4double a0 = 15.0;
G4double fw = 4.0;
G4double a0 = 42.0;
G4double w2 = 0.0;
G4double meanLoss = 0.0;
G4int sizearray = 30;
const G4ParticleDefinition* particle = nullptr;
G4double* rndmarray = nullptr;
G4int sizearray = 30;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void
G4UniversalFluctuation::AddExcitation(CLHEP::HepRandomEngine* rndm,
G4double ax, G4double ex, G4double& eav,
const G4double ax, const G4double ex,
G4double& eav,
G4double& eloss, G4double& esig2)
{
if(ax > nmaxCont) {
@@ -136,9 +140,11 @@ G4UniversalFluctuation::AddExcitation(CLHEP::HepRandomEngine* rndm,
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void
G4UniversalFluctuation::SampleGauss(CLHEP::HepRandomEngine* rndm,
G4double eav, G4double esig2,
const G4double eav, const G4double esig2,
G4double& eloss)
{
G4double x = eav;
@@ -154,5 +160,7 @@ G4UniversalFluctuation::SampleGauss(CLHEP::HepRandomEngine* rndm,
eloss += x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,88 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
//
// File name: G4UrbanFluctuation
//
// Author: V.Ivanchenko make a class with the Laszlo Urban model
//
// Creation date: 14.02.2022
//
// Modifications:
//
//
// Class Description:
//
// Implementation of energy loss fluctuations made by L.Urban for
// Geant4 10.X series for updated design of 11.X by V.Ivanchenko
// -------------------------------------------------------------------
//
#ifndef G4UrbanFluctuation_h
#define G4UrbanFluctuation_h 1
#include "G4UniversalFluctuation.hh"
class G4UrbanFluctuation : public G4UniversalFluctuation
{
public:
explicit G4UrbanFluctuation(const G4String& nam = "UrbanFluc");
~G4UrbanFluctuation() override;
// hide assignment operator
G4UrbanFluctuation & operator =
(const G4UrbanFluctuation &right) = delete;
G4UrbanFluctuation(const G4UrbanFluctuation&) = delete;
protected:
G4double SampleGlandz(CLHEP::HepRandomEngine* rndm,
const G4Material*, const G4double tcut) override;
private:
// material properties
const G4Material* lastMaterial = nullptr;
G4double f1Fluct = 0.0;
G4double f2Fluct = 0.0;
G4double e1Fluct = 0.0;
G4double e2Fluct = 0.0;
G4double e1LogFluct = 0.0;
G4double e2LogFluct = 0.0;
G4double esmall = 0.0;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -186,14 +186,14 @@ private:
static std::vector<mscData*> msc;
// index of G4MaterialCutsCouple
G4int idx;
G4int idx;
G4bool firstStep;
G4bool insideskin;
G4bool latDisplasmentbackup;
G4bool dispAlg96;
G4bool firstStep;
G4bool insideskin;
G4bool latDisplasmentbackup;
G4bool dispAlg96;
G4bool isFirstInstance = false;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -34,6 +34,7 @@ geant4_add_module(G4emstandard
G4KleinNishinaModel.hh
G4LindhardSorensenData.hh
G4LindhardSorensenIonModel.hh
G4LossFluctuationDummy.hh
G4ModifiedTsai.hh
G4MollerBhabhaModel.hh
G4MottData.hh
@@ -54,6 +55,7 @@ geant4_add_module(G4emstandard
G4ScreeningMottCrossSection.hh
G4SeltzerBergerModel.hh
G4UniversalFluctuation.hh
G4UrbanFluctuation.hh
G4UrbanMscModel.hh
G4WaterStopping.hh
G4WentzelOKandVIxSection.hh
@@ -111,6 +113,7 @@ geant4_add_module(G4emstandard
G4KleinNishinaModel.cc
G4LindhardSorensenData.cc
G4LindhardSorensenIonModel.cc
G4LossFluctuationDummy.cc
G4ModifiedTsai.cc
G4MollerBhabhaModel.cc
G4NuclearStopping.cc
@@ -129,6 +132,7 @@ geant4_add_module(G4emstandard
G4ScreeningMottCrossSection.cc
G4SeltzerBergerModel.cc
G4UniversalFluctuation.cc
G4UrbanFluctuation.cc
G4UrbanMscModel.cc
G4WaterStopping.cc
G4WentzelOKandVIxSection.cc
@@ -97,7 +97,11 @@ void G4CoulombScattering::InitialiseProcess(const G4ParticleDefinition* p)
// restricted or non-restricted cross section table
G4bool yes = false;
if(theta == CLHEP::pi) { yes = true; }
if(theta == CLHEP::pi) {
yes = true;
// for restriced single scattering change cross section shape
SetCrossSectionType(fEmIncreasing);
}
SetStartFromNullFlag(yes);
/*
G4cout << "### G4CoulombScattering::InitialiseProcess: "
@@ -0,0 +1,90 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4LossFluctuationDummy
//
// Author: V. Ivanchenko
//
// Creation date: 14.02.2022
//
// Modifications:
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4LossFluctuationDummy.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4DynamicParticle.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4LossFluctuationDummy::G4LossFluctuationDummy(const G4String& nam)
: G4VEmFluctuationModel(nam)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4LossFluctuationDummy::~G4LossFluctuationDummy()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double
G4LossFluctuationDummy::SampleFluctuations(const G4MaterialCutsCouple*,
const G4DynamicParticle*,
const G4double,
const G4double,
const G4double,
const G4double averageLoss)
{
return averageLoss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4LossFluctuationDummy::Dispersion(const G4Material*,
const G4DynamicParticle*,
const G4double, const G4double,
const G4double)
{
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4LossFluctuationDummy::SetParticleAndCharge(const G4ParticleDefinition*,
G4double)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -47,13 +47,11 @@
#include "G4SystemOfUnits.hh"
#include "Randomize.hh"
#include "G4Poisson.hh"
#include "G4Step.hh"
#include "G4Material.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4DynamicParticle.hh"
#include "G4ParticleDefinition.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -104,7 +102,7 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
// (out of validity of the model)
//
if (averageLoss < minLoss) { return averageLoss; }
G4double meanLoss = averageLoss;
meanLoss = averageLoss;
const G4double tkin = dp->GetKineticEnergy();
//G4cout<< "Emean= "<< meanLoss<< " tmax= "<< tmax<< " L= "<<length<<G4endl;
@@ -151,38 +149,39 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
return loss;
}
// Glandz regime : initialisation
//
if (material != lastMaterial) {
ipotFluct = material->GetIonisation()->GetMeanExcitationEnergy();
ipotLogFluct = material->GetIonisation()->GetLogMeanExcEnergy();
e0 = material->GetIonisation()->GetEnergy0fluct();
lastMaterial = material;
}
auto ioni = material->GetIonisation();
e0 = ioni->GetEnergy0fluct();
// very small step or low-density material
if(tcut <= e0) { return meanLoss; }
ipotFluct = ioni->GetMeanExcitationEnergy();
ipotLogFluct = ioni->GetLogMeanExcEnergy();
// width correction for small cuts
const G4double scaling = std::min(1.+0.5*CLHEP::keV/tcut,1.50);
const G4double scaling = std::min(1.+0.5*CLHEP::keV/tcut, 1.50);
meanLoss /= scaling;
w2 = (tcut > ipotFluct) ?
G4Log(2.*CLHEP::electron_mass_c2*beta2*gam2)-beta2 : 0.0;
return SampleGlandz(rndmEngineF, material, tcut)*scaling;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double
G4UniversalFluctuation::SampleGlandz(CLHEP::HepRandomEngine* rndmEngineF,
const G4Material*,
const G4double tcut)
{
G4double a1(0.0), a3(0.0);
loss = 0.0;
G4double loss = 0.0;
G4double e1 = ipotFluct;
e1 = ipotFluct;
if(tcut > ipotFluct) {
const G4double w2 = G4Log(2.*CLHEP::electron_mass_c2*beta2*gam2)-beta2;
if(w2 > ipotLogFluct) {
const G4double C = meanLoss*(1.-rate)/(w2-ipotLogFluct);
a1 = C*(w2-ipotLogFluct)/ipotFluct;
} else {
a1 = meanLoss*(1.-rate)/e1;
}
if(tcut > e1) {
a1 = meanLoss*(1.-rate)/e1;
if(a1 < a0) {
const G4double fwnow = fw*a1/a0;
const G4double fwnow = 0.1+(fw-0.1)*std::sqrt(a1/a0);
a1 /= fwnow;
e1 *= fwnow;
} else {
@@ -192,12 +191,9 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
}
const G4double w1 = tcut/e0;
if(tcut > e0) {
a3 = rate*meanLoss*(tcut-e0)/(e0*tcut*G4Log(w1));
if(a1 <= 0.) {
a3 /= rate;
}
}
a3 = rate*meanLoss*(tcut - e0)/(e0*tcut*G4Log(w1));
if(a1 <= 0.) { a3 /= rate; }
//'nearly' Gaussian fluctuation if a1>nmaxCont&&a2>nmaxCont&&a3>nmaxCont
G4double emean = 0.;
G4double sig2e = 0.;
@@ -219,12 +215,12 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
const G4double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
emean += namean*e0*alfa1;
sig2e += e0*e0*namean*(alfa-alfa1*alfa1);
p3 = a3-namean;
p3 = a3 - namean;
}
const G4double w2 = alfa*e0;
if(tcut > w2) {
const G4double w = (tcut-w2)/tcut;
const G4double w3 = alfa*e0;
if(tcut > w3) {
const G4double w = (tcut-w3)/tcut;
const G4int nnb = G4Poisson(p3);
if(nnb > 0) {
if(nnb > sizearray) {
@@ -233,13 +229,13 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
rndmarray = new G4double[nnb];
}
rndmEngineF->flatArray(nnb, rndmarray);
for (G4int k=0; k<nnb; ++k) { loss += w2/(1.-w*rndmarray[k]); }
for (G4int k=0; k<nnb; ++k) { loss += w3/(1.-w*rndmarray[k]); }
}
}
if(sig2e > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
}
//G4cout << "### loss=" << loss << " scaling=" << scaling << G4endl;
return loss*scaling;
//G4cout << "### loss=" << loss << G4endl;
return loss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,158 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4UrbanFluctuation
//
// Author: V. Ivanchenko for Laszlo Urban
//
// Creation date: 14.02.2022
//
// Modifications:
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4UrbanFluctuation.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "Randomize.hh"
#include "G4Poisson.hh"
#include "G4Material.hh"
#include "G4Log.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UrbanFluctuation::G4UrbanFluctuation(const G4String& nam)
: G4UniversalFluctuation(nam)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UrbanFluctuation::~G4UrbanFluctuation()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4UrbanFluctuation::SampleGlandz(CLHEP::HepRandomEngine* rndmEngineF,
const G4Material* material,
const G4double tcut)
{
if (material != lastMaterial) {
auto ioni = material->GetIonisation();
f1Fluct = ioni->GetF1fluct();
f2Fluct = ioni->GetF2fluct();
e1Fluct = ioni->GetEnergy1fluct();
e2Fluct = ioni->GetEnergy2fluct();
e1LogFluct = ioni->GetLogEnergy1fluct();
e2LogFluct = ioni->GetLogEnergy2fluct();
esmall = 0.5*std::sqrt(e0*ipotFluct);
lastMaterial = material;
}
G4double a1(0.0), a2(0.0), a3(0.0);
G4double loss = 0.0;
G4double e1 = e1Fluct;
G4double e2 = e2Fluct;
if(tcut > ipotFluct) {
if(w2 > ipotLogFluct) {
if(w2 > e2LogFluct) {
const G4double C = meanLoss*(1.-rate)/(w2-ipotLogFluct);
a1 = C*f1Fluct*(w2-e1LogFluct)/e1Fluct;
a2 = C*f2Fluct*(w2-e2LogFluct)/e2Fluct;
} else {
a1 = meanLoss*(1.-rate)/e1;
}
if(a1 < a0) {
const G4double fwnow = 0.5+(fw-0.5)*std::sqrt(a1/a0);
a1 /= fwnow;
e1 *= fwnow;
} else {
a1 /= fw;
e1 *= fw;
}
}
}
const G4double w1 = tcut/e0;
a3 = rate*meanLoss*(tcut-e0)/(e0*tcut*G4Log(w1));
if(a1+a2 <= 0.) { a3 /= rate; }
//'nearly' Gaussian fluctuation if a1>nmaxCont&&a2>nmaxCont&&a3>nmaxCont
G4double emean = 0.;
G4double sig2e = 0.;
// excitation of type 1
if(a1 > 0.0) { AddExcitation(rndmEngineF, a1, e1, emean, loss, sig2e); }
// excitation of type 2
if(a2 > 0.0) { AddExcitation(rndmEngineF, a2, e2, emean, loss, sig2e); }
if(sig2e > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
// ionisation
if(a3 > 0.) {
emean = 0.;
sig2e = 0.;
G4double p3 = a3;
G4double alfa = 1.;
if(a3 > nmaxCont) {
alfa = w1*(nmaxCont+a3)/(w1*nmaxCont+a3);
const G4double alfa1 = alfa*G4Log(alfa)/(alfa-1.);
const G4double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
emean += namean*e0*alfa1;
sig2e += e0*e0*namean*(alfa-alfa1*alfa1);
p3 -= namean;
}
const G4double w3 = alfa*e0;
if(tcut > w3) {
const G4double w = (tcut-w3)/tcut;
const G4int nnb = G4Poisson(p3);
if(nnb > 0) {
if(nnb > sizearray) {
sizearray = nnb;
delete [] rndmarray;
rndmarray = new G4double[nnb];
}
rndmEngineF->flatArray(nnb, rndmarray);
for (G4int k=0; k<nnb; ++k) { loss += w3/(1.-w*rndmarray[k]); }
}
}
if(sig2e > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
}
//G4cout << "### loss=" << loss << G4endl;
return loss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -70,11 +70,17 @@
#include "globals.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
#include "G4Threading.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
std::vector<G4UrbanMscModel::mscData*> G4UrbanMscModel::msc;
namespace
{
G4Mutex theUrbanMutex = G4MUTEX_INITIALIZER;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
@@ -135,7 +141,7 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
G4UrbanMscModel::~G4UrbanMscModel()
{
if(IsMaster()) {
if(isFirstInstance) {
for(auto & ptr : msc) { delete ptr; }
msc.clear();
}
@@ -153,7 +159,19 @@ void G4UrbanMscModel::Initialise(const G4ParticleDefinition* p,
latDisplasmentbackup = latDisplasment;
dispAlg96 = (G4EmParameters::Instance()->LateralDisplacementAlg96());
if(IsMaster() || msc.size() == 0) { InitialiseModelCache(); }
// initialise cache only once
if(0 == msc.size()) {
G4AutoLock l(&theUrbanMutex);
if(0 == msc.size()) {
isFirstInstance = true;
msc.resize(1, nullptr);
}
l.unlock();
}
// initialise cache for each new run
if(isFirstInstance) { InitialiseModelCache(); }
/*
G4cout << "### G4UrbanMscModel::Initialise done for "
<< p->GetParticleName() << " type= " << steppingAlgorithm << G4endl;
@@ -788,8 +806,9 @@ G4double G4UrbanMscModel::ComputeTrueStepLength(G4double geomStepLength)
if(par1 < 0.) {
tlength = -lambda0*G4Log(1.-geomStepLength/lambda0) ;
} else {
if(par1*par3*geomStepLength < 1.) {
tlength = (1.-G4Exp(G4Log(1.-par1*par3*geomStepLength)/par3))/par1 ;
const G4double par4 = par1*par3;
if(par4*geomStepLength < 1.) {
tlength = (1.-G4Exp(G4Log(1.-par4*geomStepLength)/par3))/par1;
} else {
tlength = currentRange;
}
@@ -1214,14 +1233,14 @@ void G4UrbanMscModel::InitialiseModelCache()
// of a new G4MaterialCutsCouple is possible
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
if(numOfCouples != msc.size()) { msc.resize(numOfCouples); }
if(numOfCouples != msc.size()) { msc.resize(numOfCouples, nullptr); }
for(size_t j=0; j<numOfCouples; ++j) {
auto aCouple = theCoupleTable->GetMaterialCutsCouple(j);
// cut may be changed before runs
G4double cut = aCouple->GetProductionCuts()->GetProductionCut(1);
if(msc[j]) {
if(nullptr != msc[j]) {
msc[j]->ecut = cut;
continue;
}
@@ -16,6 +16,23 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
22 January 22: V.Ivanchenko (emutils-V10-07-39)
- G4EmParametersMessenger - added forgotten UI command to enable polarisation
08 January 22: V.Ivanchenko
- G4VEmProcess - fixed methods, which implementation based on assumption that
the lambda table defined for full energy range: LambdaPhysicsVector(..),
CrossSEctionPerVolume(...), FindLambdaMax(...). No change is expected for
the default physics configuration, fix mainly affect positron annihilation
processes at high energies.
05 January 22: V.Ivanchenko
- G4VMscModel, G4VEmProcess - move few methods and header files from header to
source in order to reduce dependencies between packages.
17 December 21: I.Hrivnacova
- Added info in setMaxBetaChange command description.
19 November 21: V.Ivanchenko (emutils-V10-07-38)
- G4EmCalculator - fixed computation of dedx for He3 and alpha
(complete fix of #2440)
@@ -97,6 +97,7 @@ private:
G4UIcmdWithABool* mottCmd;
G4UIcmdWithABool* birksCmd;
G4UIcmdWithABool* sharkCmd;
G4UIcmdWithABool* poCmd;
G4UIcmdWithABool* onIsolatedCmd;
G4UIcmdWithABool* sampleTCmd;
G4UIcmdWithABool* icru90Cmd;
@@ -53,13 +53,13 @@
#include "G4Material.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4Track.hh"
#include "G4EmModelManager.hh"
#include "G4UnitsTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4EmParameters.hh"
#include "G4EmDataHandler.hh"
#include "G4EmTableType.hh"
#include "G4EmModelManager.hh"
#include "G4EmSecondaryParticleType.hh"
class G4Step;
@@ -184,6 +184,9 @@ public:
// Max kinetic energy for tables
void SetMaxKinEnergy(G4double e);
// for cross section with one peak
void SetEnergyOfCrossSectionMax(std::vector<G4double>*);
// Cross section table pointers
inline G4PhysicsTable* LambdaTable() const;
inline G4PhysicsTable* LambdaTablePrim() const;
@@ -223,12 +226,12 @@ public:
// return a model from the local list
inline G4VEmModel* EmModel(size_t index = 0) const;
// Access to models
inline G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
// Access to active model
inline const G4VEmModel* GetCurrentModel() const;
// Access to models
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
// Access to the current G4Element
const G4Element* GetCurrentElement() const;
@@ -244,6 +247,8 @@ public:
void ActivateSecondaryBiasing(const G4String& region, G4double factor,
G4double energyLimit);
std::vector<G4double>* FindLambdaMax();
inline void SetEmMasterProcess(const G4VEmProcess*);
inline void SetCrossSectionType(G4CrossSectionType val);
@@ -324,8 +329,6 @@ private:
void StreamInfo(std::ostream& outFile, const G4ParticleDefinition&,
G4bool rst=false) const;
void FindLambdaMax();
void PrintWarning(G4String tit, G4double val);
void ComputeIntegralLambda(G4double kinEnergy, G4double logKinEnergy);
@@ -806,11 +809,4 @@ inline G4VEmModel* G4VEmProcess::EmModel(size_t index) const
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver) const
{
return modelManager->GetModel(idx, ver);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -55,13 +55,13 @@
#include "G4ThreeVector.hh"
#include "G4Track.hh"
#include "G4SafetyHelper.hh"
#include "G4VEnergyLossProcess.hh"
#include "G4PhysicsTable.hh"
#include "G4ThreeVector.hh"
#include <vector>
class G4ParticleChangeForMSC;
class G4ParticleDefinition;
class G4VEnergyLossProcess;
class G4VMscModel : public G4VEmModel
{
@@ -145,25 +145,25 @@ public:
inline G4double ComputeGeomLimit(const G4Track&, G4double& presafety,
G4double limit);
inline G4double GetDEDX(const G4ParticleDefinition* part,
G4double GetDEDX(const G4ParticleDefinition* part,
G4double kineticEnergy,
const G4MaterialCutsCouple* couple);
inline G4double GetDEDX(const G4ParticleDefinition* part,
G4double GetDEDX(const G4ParticleDefinition* part,
G4double kineticEnergy,
const G4MaterialCutsCouple* couple,
G4double logKineticEnergy);
inline G4double GetRange(const G4ParticleDefinition* part,
G4double GetRange(const G4ParticleDefinition* part,
G4double kineticEnergy,
const G4MaterialCutsCouple* couple);
inline G4double GetRange(const G4ParticleDefinition* part,
G4double GetRange(const G4ParticleDefinition* part,
G4double kineticEnergy,
const G4MaterialCutsCouple* couple,
G4double logKineticEnergy);
inline G4double GetEnergy(const G4ParticleDefinition* part,
G4double GetEnergy(const G4ParticleDefinition* part,
G4double range,
const G4MaterialCutsCouple* couple);
@@ -299,99 +299,6 @@ inline G4double G4VMscModel::ComputeGeomLimit(const G4Track& track,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double
G4VMscModel::GetDEDX(const G4ParticleDefinition* part, G4double kinEnergy,
const G4MaterialCutsCouple* couple)
{
G4double x;
if (nullptr != ionisation) {
x = ionisation->GetDEDX(kinEnergy, couple);
} else {
const G4double q = part->GetPDGCharge()*inveplus;
x = dedx*q*q;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double
G4VMscModel::GetDEDX(const G4ParticleDefinition* part, G4double kinEnergy,
const G4MaterialCutsCouple* couple, G4double logKinEnergy)
{
G4double x;
if (nullptr != ionisation) {
x = ionisation->GetDEDX(kinEnergy, couple, logKinEnergy);
} else {
const G4double q = part->GetPDGCharge()*inveplus;
x = dedx*q*q;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double
G4VMscModel::GetRange(const G4ParticleDefinition* part, G4double kinEnergy,
const G4MaterialCutsCouple* couple)
{
//G4cout << "G4VMscModel::GetRange E(MeV)= " << kinEnergy << " "
// << ionisation << " " << part->GetParticleName()
// << G4endl;
localtkin = kinEnergy;
if (nullptr != ionisation) {
localrange = ionisation->GetRange(kinEnergy, couple);
} else {
const G4double q = part->GetPDGCharge()*inveplus;
localrange = kinEnergy/(dedx*q*q*couple->GetMaterial()->GetDensity());
}
//G4cout << "R(mm)= " << localrange << " " << ionisation << G4endl;
return localrange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double
G4VMscModel::GetRange(const G4ParticleDefinition* part,G4double kinEnergy,
const G4MaterialCutsCouple* couple, G4double logKinEnergy)
{
//G4cout << "G4VMscModel::GetRange E(MeV)= " << kinEnergy << " "
// << ionisation << " " << part->GetParticleName()
// << G4endl;
localtkin = kinEnergy;
if (nullptr != ionisation) {
localrange = ionisation->GetRange(kinEnergy, couple, logKinEnergy);
} else {
const G4double q = part->GetPDGCharge()*inveplus;
localrange = kinEnergy/(dedx*q*q*couple->GetMaterial()->GetDensity());
}
//G4cout << "R(mm)= " << localrange << " " << ionisation << G4endl;
return localrange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4double
G4VMscModel::GetEnergy(const G4ParticleDefinition* part,
G4double range, const G4MaterialCutsCouple* couple)
{
G4double e;
//G4cout << "G4VMscModel::GetEnergy R(mm)= " << range << " " << ionisation
// << " Rlocal(mm)= " << localrange << " Elocal(MeV)= " << localtkin
// << G4endl;
if(nullptr != ionisation) { e = ionisation->GetKineticEnergy(range, couple); }
else {
e = localtkin;
if(localrange > range) {
G4double q = part->GetPDGCharge()*inveplus;
e -= (localrange - range)*dedx*q*q*couple->GetMaterial()->GetDensity();
}
}
return e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4VEnergyLossProcess* G4VMscModel::GetIonisation() const
{
return ionisation;
@@ -156,6 +156,11 @@ G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
sharkCmd->AvailableForStates(G4State_PreInit);
sharkCmd->SetToBeBroadcasted(false);
poCmd = new G4UIcmdWithABool("/process/em/Polarisation",this);
poCmd->SetGuidance("Enable polarisation");
poCmd->AvailableForStates(G4State_PreInit);
poCmd->SetToBeBroadcasted(false);
sampleTCmd = new G4UIcmdWithABool("/process/em/enableSamplingTable",this);
sampleTCmd->SetGuidance("Enable usage of sampling table for secondary generation");
sampleTCmd->SetParameterName("sampleT",true);
@@ -436,6 +441,7 @@ G4EmParametersMessenger::~G4EmParametersMessenger()
delete sharkCmd;
delete onIsolatedCmd;
delete sampleTCmd;
delete poCmd;
delete icru90Cmd;
delete mudatCmd;
@@ -515,6 +521,8 @@ void G4EmParametersMessenger::SetNewValue(G4UIcommand* command,
theParameters->SetUseICRU90Data(icru90Cmd->GetNewBoolValue(newValue));
} else if (command == sharkCmd) {
theParameters->SetGeneralProcessActive(sharkCmd->GetNewBoolValue(newValue));
} else if (command == poCmd) {
theParameters->SetEnablePolarisation(poCmd->GetNewBoolValue(newValue));
} else if (command == sampleTCmd) {
theParameters->SetEnableSamplingTable(sampleTCmd->GetNewBoolValue(newValue));
} else if (command == mudatCmd) {
@@ -123,7 +123,7 @@ G4OpticalParametersMessenger::G4OpticalParametersMessenger(
fCerenkovMaxBetaChangeCmd =
new G4UIcmdWithADouble("/process/optical/cerenkov/setMaxBetaChange", this);
fCerenkovMaxBetaChangeCmd->SetGuidance(
"Set maximum change of beta of parent particle per step");
"Set maximum change of beta of parent particle per step (in percent)");
fCerenkovMaxBetaChangeCmd->SetParameterName("CerenkovMaxBetaChange", false);
fCerenkovMaxBetaChangeCmd->SetRange("CerenkovMaxBetaChange>=0");
fCerenkovMaxBetaChangeCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
@@ -165,6 +165,13 @@ void G4VEmProcess::SetEmModel(G4VEmModel* ptr, G4int)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver) const
{
return modelManager->GetModel(idx, ver);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
{
isTheMaster = lManager->IsMaster();
@@ -321,7 +328,9 @@ void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
if(!isTheMaster) {
theLambdaTable = masterProc->LambdaTable();
theLambdaTablePrim = masterProc->LambdaTablePrim();
theEnergyOfCrossSectionMax = masterProc->EnergyOfCrossSectionMax();
if(fXSType == fEmOnePeak) {
SetEnergyOfCrossSectionMax(masterProc->EnergyOfCrossSectionMax());
}
baseMat = masterProc->UseBaseMaterial();
// local initialisation of models
@@ -339,6 +348,11 @@ void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
if(buildLambdaTable || minKinEnergyPrim < maxKinEnergy) {
BuildLambdaTable();
}
if(fXSType == fEmOnePeak) {
delete theEnergyOfCrossSectionMax;
theEnergyOfCrossSectionMax = nullptr;
SetEnergyOfCrossSectionMax(FindLambdaMax());
}
}
}
// protection against double printout
@@ -451,8 +465,6 @@ void G4VEmProcess::BuildLambdaTable()
}
}
if(buildLambdaTable && fXSType == fEmOnePeak) { FindLambdaMax(); }
if(1 < verboseLevel) {
G4cout << "Lambda table is built for "
<< particle->GetParticleName()
@@ -963,25 +975,11 @@ G4bool G4VEmProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy,
const G4MaterialCutsCouple* couple,
G4double logKinEnergy)
G4double G4VEmProcess::CrossSectionPerVolume(G4double kinEnergy,
const G4MaterialCutsCouple* couple,
G4double)
{
// Cross section per atom is calculated
DefineMaterial(couple);
G4double cross = 0.0;
if(buildLambdaTable) {
cross = GetCurrentLambda(kineticEnergy,
(logKinEnergy < DBL_MAX) ? logKinEnergy : G4Log(kineticEnergy));
} else {
SelectModel(kineticEnergy, currentCoupleIndex);
if(currentModel) {
cross = fFactor*currentModel->CrossSectionPerVolume(currentMaterial,
currentParticle,
kineticEnergy);
}
}
G4double cross = RecalculateLambda(kinEnergy, couple);
return std::max(cross, 0.0);
}
@@ -1020,54 +1018,73 @@ G4VEmProcess::ComputeCrossSectionPerAtom(G4double kinEnergy,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::FindLambdaMax()
std::vector<G4double>* G4VEmProcess::FindLambdaMax()
{
if(1 < verboseLevel) {
G4cout << "### G4VEmProcess::FindLambdaMax: "
<< particle->GetParticleName()
<< " and process " << GetProcessName() << " " << G4endl;
}
size_t n = theLambdaTable->length();
G4PhysicsVector* pv;
G4double e, ss, emax, smax;
std::vector<G4double>* ptr = nullptr;
if(fXSType != fEmOnePeak) { return ptr; }
size_t i;
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t n = theCoupleTable->GetTableSize();
ptr = new std::vector<G4double>;
ptr->resize(n, DBL_MAX);
// first loop on existing vectors
for (i=0; i<n; ++i) {
pv = (*theLambdaTable)[i];
if(nullptr != pv) {
size_t nb = pv->GetVectorLength();
emax = DBL_MAX;
smax = 0.0;
if(nb > 0) {
for (size_t j=0; j<nb; ++j) {
e = pv->Energy(j);
ss = (*pv)(j);
if(ss > smax) {
smax = ss;
emax = e;
} else {
break;
}
}
}
(*theEnergyOfCrossSectionMax)[i] = emax;
if(1 < verboseLevel) {
G4cout << "For " << particle->GetParticleName()
<< " Max CS at i= " << i << " emax(MeV)= " << emax/MeV
<< " lambda= " << smax << G4endl;
G4bool isPeak = false;
const G4double g4log10 = G4Log(10.);
const G4double scale = theParameters->NumberOfBinsPerDecade()/g4log10;
for(size_t i=0; i<n; ++i) {
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
G4double emin = std::max(minKinEnergy, MinPrimaryEnergy(particle, couple->GetMaterial()));
G4double emax = std::max(maxKinEnergy, emin + emin);
G4double ee = G4Log(emax/emin);
G4int nbin = G4lrint(ee*scale);
if(nbin < 4) { nbin = 4; }
G4double x = G4Exp(ee/nbin);
G4double sm = 0.0;
G4double em = emin;
G4double e = emin;
for(G4int j=0; j<=nbin; ++j) {
G4double sig = RecalculateLambda(e, couple);
//G4cout << j << " E=" << e << " Lambda=" << sig << G4endl;
if(sig >= sm) {
em = e;
sm = sig;
e *= x;
} else {
isPeak = true;
(*ptr)[i] = em;
break;
}
}
if(1 < verboseLevel) {
G4cout << " " << i << ". Epeak(GeV)=" << em/GeV
<< " SigmaMax(1/mm)=" << sm
<< " Emin(GeV)=" << emin/GeV << " Emax(GeV)=" << emax/GeV
<< " " << couple->GetMaterial()->GetName() << G4endl;
}
}
// second loop using base materials
for (i=0; i<n; ++i) {
pv = (*theLambdaTable)[i];
if(nullptr == pv) {
G4int j = (*theDensityIdx)[i];
(*theEnergyOfCrossSectionMax)[i] = (*theEnergyOfCrossSectionMax)[j];
}
// there is no peak for any material
if(!isPeak) {
delete ptr;
ptr = nullptr;
}
return ptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetEnergyOfCrossSectionMax(std::vector<G4double>* ptr)
{
if(nullptr == ptr) {
fXSType = fEmIncreasing;
} else {
theEnergyOfCrossSectionMax = ptr;
}
}
@@ -1077,13 +1094,8 @@ G4PhysicsVector*
G4VEmProcess::LambdaPhysicsVector(const G4MaterialCutsCouple* couple)
{
DefineMaterial(couple);
G4PhysicsVector* newv = nullptr;
if(nullptr == theLambdaTable) {
newv = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy,
nLambdaBins, splineFlag);
} else {
newv = new G4PhysicsVector(*((*theLambdaTable)[basedCoupleIndex]));
}
G4PhysicsVector* newv = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy,
nLambdaBins, splineFlag);
return newv;
}
@@ -154,4 +154,88 @@ void G4VMscModel::SampleSecondaries(std::vector<G4DynamicParticle*>*,
G4double, G4double)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VMscModel::GetDEDX(const G4ParticleDefinition* part, G4double kinEnergy,
const G4MaterialCutsCouple* couple)
{
G4double x;
if (nullptr != ionisation) {
x = ionisation->GetDEDX(kinEnergy, couple);
} else {
const G4double q = part->GetPDGCharge()*inveplus;
x = dedx*q*q;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VMscModel::GetDEDX(const G4ParticleDefinition* part, G4double kinEnergy,
const G4MaterialCutsCouple* couple, G4double logKinEnergy)
{
G4double x;
if (nullptr != ionisation) {
x = ionisation->GetDEDX(kinEnergy, couple, logKinEnergy);
} else {
const G4double q = part->GetPDGCharge()*inveplus;
x = dedx*q*q;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VMscModel::GetRange(const G4ParticleDefinition* part, G4double kinEnergy,
const G4MaterialCutsCouple* couple)
{
// << ionisation << " " << part->GetParticleName() << G4endl;
localtkin = kinEnergy;
if (nullptr != ionisation) {
localrange = ionisation->GetRange(kinEnergy, couple);
} else {
const G4double q = part->GetPDGCharge()*inveplus;
localrange = kinEnergy/(dedx*q*q*couple->GetMaterial()->GetDensity());
}
//G4cout << "R(mm)= " << localrange << " " << ionisation << G4endl;
return localrange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VMscModel::GetRange(const G4ParticleDefinition* part,G4double kinEnergy,
const G4MaterialCutsCouple* couple, G4double logKinEnergy)
{
//G4cout << "G4VMscModel::GetRange E(MeV)= " << kinEnergy << " "
// << ionisation << " " << part->GetParticleName() << G4endl;
localtkin = kinEnergy;
if (nullptr != ionisation) {
localrange = ionisation->GetRange(kinEnergy, couple, logKinEnergy);
} else {
const G4double q = part->GetPDGCharge()*inveplus;
localrange = kinEnergy/(dedx*q*q*couple->GetMaterial()->GetDensity());
}
//G4cout << "R(mm)= " << localrange << " " << ionisation << G4endl;
return localrange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4VMscModel::GetEnergy(const G4ParticleDefinition* part,
G4double range, const G4MaterialCutsCouple* couple)
{
G4double e;
//G4cout << "G4VMscModel::GetEnergy R(mm)= " << range << " " << ionisation
// << " Rlocal(mm)= " << localrange << " Elocal(MeV)= " << localtkin << G4endl;
if(nullptr != ionisation) { e = ionisation->GetKineticEnergy(range, couple); }
else {
e = localtkin;
if(localrange > range) {
G4double q = part->GetPDGCharge()*inveplus;
e -= (localrange - range)*dedx*q*q*couple->GetMaterial()->GetDensity();
}
}
return e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -16,6 +16,14 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
21 Jan 22: D. Sawkey (xrays-V10-07-10)
- G4Scintillation - remove unused YieldFactor declarations
Addresses bug 2470.
18 Jan 22: D. Sawkey (xrays-V10-07-09)
- Fix MaxBetaChange value in Cerenkov process.
Addressing problem report 2456.
19 Oct 21: D. Sawkey (xrays-V10-07-08)
- G4Cerenkov, G4Scintillation - update G4OpticalParameters when process
parameters updated directly. Addresses bug 2425.
@@ -133,14 +133,6 @@ class G4Scintillation : public G4VRestDiscreteProcess
G4bool GetFiniteRiseTime() const;
// Returns the boolean flag for a finite scintillation rise time.
void SetScintillationYieldFactor(const G4double yieldfactor);
// Called to set the scintillation photon yield factor, needed when
// the yield is different for different types of particles. This
// scales the yield obtained from the G4MaterialPropertiesTable.
G4double GetScintillationYieldFactor() const;
// Returns the photon yield factor.
G4PhysicsTable* GetIntegralTable1() const;
// Returns the address of scintillation integral table #1.
@@ -584,7 +584,7 @@ void G4Cerenkov::SetTrackSecondariesFirst(const G4bool state)
void G4Cerenkov::SetMaxBetaChangePerStep(const G4double value)
{
fMaxBetaChange = value * CLHEP::perCent;
G4OpticalParameters::Instance()->SetCerenkovMaxBetaChange(fMaxBetaChange);
G4OpticalParameters::Instance()->SetCerenkovMaxBetaChange(value);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -14,6 +14,14 @@ code and to keep track of all tags.
* Please list in reverse chronological order (last date on top)
---------------------------------------------------------------
03 January 2022 - Alberto Ribon (hadr-cross-V10-07-22)
- G4ComponentAntiNuclNuclearXS : extension, by Vladimir Uzhinsky, of
the class to compute the cross sections of light anti-nuclei on
hydrogen. This relies on the isospin symmetry assumption, according
to which the properties of the reactions between anti-proton and
light nuclei are equivalent to those between light anti-nuclei and
hydrogen.
21 October 2021 - Alberto Ribon (hadr-cross-V10-07-21)
- G4IonsShenCrossSection : reintroduced this (old) ion-ion cross section
(that was removed in 10.7.ref03), as required by Vladimir Uzhinsky
@@ -49,7 +49,7 @@
#include "G4AntiTriton.hh"
#include "G4AntiAlpha.hh"
#include "G4Nucleus.hh"
#include "G4Pow.hh"
#include "G4VComponentCrossSection.hh"
@@ -83,7 +83,6 @@ class G4ComponentAntiNuclNuclearXS : public G4VComponentCrossSection {
private:
G4double fRadiusEff; // Effective Radius for AntiNucleus
G4double fRadiusNN2; // Sqr of radius of NN collision
G4double fTotalXsc, fElasticXsc, fInelasticXsc;
G4double fAntiHadronNucleonTotXsc, fAntiHadronNucleonElXsc;
G4double Elab, S, SqrtS ;
@@ -95,6 +94,18 @@ class G4ComponentAntiNuclNuclearXS : public G4VComponentCrossSection {
G4ParticleDefinition* theAAlpha;
G4ParticleDefinition* theAHe3;
const G4double ReffTot[5][5] = { {0.000, 3.800, 3.300, 3.300, 2.376}, // Pbar + p, d, t, He3, He4
{3.800, 3.238, 3.144, 3.144, 2.544}, // Dbar + p, d, t, He3, He4
{3.300, 3.144, 3.075, 3.075, 3.589}, // Tbar + p, d, t, He3, He4
{3.300, 3.144, 3.075, 3.075, 2.589}, // He3bar + p, d, t, He3, He4
{2.376, 2.544, 3.589, 3.598, 2.241} }; // He4bar + p, d, t, He3, He4
const G4double ReffInel[5][5] = { {0.000, 3.582, 3.105, 3.105, 2.209}, // Pbar + p, d, t, He3, He4
{3.582, 3.169, 3.066, 3.066, 2.498}, // Dbar + p, d, t, He3, He4
{3.105, 3.066, 2.973, 2.973, 2.508}, // Tbar + p, d, t, He3, He4
{3.105, 3.066, 2.973, 2.973, 2.508}, // He3bar + p, d, t, He3, He4
{2.209, 2.498, 2.508, 2.508, 2.158} }; // He4bar + p, d, t, He3, He4
const G4Pow* theG4Pow = G4Pow::GetInstance();
};
#endif
@@ -41,14 +41,14 @@
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4Pow.hh"
#include "G4HadronicException.hh"
/////////////////////////////////////////////////////////////////////////////
G4ComponentAntiNuclNuclearXS::G4ComponentAntiNuclNuclearXS()
: G4VComponentCrossSection("AntiAGlauber"),
fRadiusEff(0.0), fRadiusNN2(0.0),
fRadiusEff(0.0),
fTotalXsc(0.0), fElasticXsc(0.0), fInelasticXsc(0.0),
fAntiHadronNucleonTotXsc(0.0), fAntiHadronNucleonElXsc(0.0),
Elab(0.0), S(0.0), SqrtS(0)
@@ -82,61 +82,56 @@ G4ComponentAntiNuclNuclearXS::~G4ComponentAntiNuclNuclearXS()
G4double G4ComponentAntiNuclNuclearXS::GetTotalElementCrossSection
(const G4ParticleDefinition* aParticle, G4double kinEnergy, G4int Z, G4double A)
{
G4double xsection, sigmaTotal, sigmaElastic;
const G4ParticleDefinition* theParticle = aParticle;
sigmaTotal = GetAntiHadronNucleonTotCrSc(theParticle,kinEnergy);
sigmaElastic = GetAntiHadronNucleonElCrSc(theParticle,kinEnergy);
G4double sigmaTotal = GetAntiHadronNucleonTotCrSc(theParticle,kinEnergy);
// calculation of squared radius of NN-collision
fRadiusNN2=sigmaTotal*sigmaTotal*0.1/(8.*sigmaElastic*pi) ; //fm^2
G4int i(-1), j(-1);
if ( theParticle == theAProton ||
theParticle == theANeutron ) { i=0; }
else if ( theParticle == theADeuteron ) { i=1; }
else if ( theParticle == theATriton ) { i=2; }
else if ( theParticle == theAHe3 ) { i=3; }
else if ( theParticle == theAAlpha ) { i=4; }
else {};
// calculation of effective nuclear radius for Pbar and Nbar interactions (can be changed)
//A.R. 29-Jan-2013 : use antiprotons/antineutrons as the default case,
// to be used for instance, as first approximation
// without validation, for anti-hyperons.
if (A==1) {
fTotalXsc = sigmaTotal * millibarn;
return fTotalXsc;
}
fRadiusEff = 1.34*G4Pow::GetInstance()->powA(A,0.23)+1.35/G4Pow::GetInstance()->powA(A,1./3.); //fm
if ( (Z==1) && (A==2) ) fRadiusEff = 3.800; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.300;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.300;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.376;
// calculation of effective nuclear radius for AntiDeuteron interaction (can be changed)
if (theParticle == theADeuteron) {
fRadiusEff = 1.46 * G4Pow::GetInstance()->powA(A,0.21) + 1.45 / G4Pow::GetInstance()->powA(A,1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 3.238; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.144;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.144;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.544;
if ( i < 0 ) {
G4ExceptionDescription ed;
ed << "Unknown anti-nucleus : "
<< ( theParticle != nullptr ? theParticle->GetParticleName() : "nullptr" ) << G4endl
<< "Target (Z, A)=(" << Z << "," << A << ")" << G4endl;
G4Exception( "G4ComponentAntiNuclNuclearXS::GetTotalElementCrossSection",
"antiNuclNuclearXS001", JustWarning, ed );
}
// calculation of effective nuclear radius for AntiHe3 interaction (can be changed)
if ( (theParticle ==theAHe3) || (theParticle ==theATriton) ) {
fRadiusEff = 1.40* G4Pow::GetInstance()->powA(A,0.21)+1.63/G4Pow::GetInstance()->powA(A,1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 3.144; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.075;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.075;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.589;
}
if ( Z == 1 && A == 1 ) { j=0; }
else if ( Z == 1 && A == 2 ) { j=1; }
else if ( Z == 1 && A == 3 ) { j=2; }
else if ( Z == 2 && A == 3 ) { j=3; }
else if ( Z == 2 && A == 4 ) { j=4; }
else {}
// calculation of effective nuclear radius for AntiAlpha interaction (can be changed)
if (theParticle == theAAlpha) {
fRadiusEff = 1.35* G4Pow::GetInstance()->powA(A,0.21)+1.1/G4Pow::GetInstance()->powA(A,1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 2.544; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 2.589;
if ( (Z==2) && (A==3) ) fRadiusEff = 2.589;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.241;
if ( i == 0 && j == 0 ) return sigmaTotal * millibarn; // Pbar/Nbar + P
if ( i > 0 && j >= 0 ) { fRadiusEff = ReffTot[i][j]; } // Light anti-nuclei + Light nuclei
if ( j < 0 ) {
if ( i == 0 ) { fRadiusEff = 1.34 * theG4Pow->powA(A, 0.23) // Anti-proton/Anti-neutron + Nucleus
+ 1.35 / theG4Pow->A13(A); }
else if ( i == 1 ) { fRadiusEff = 1.46 * theG4Pow->powA(A, 0.21) // Anti-deuteron + Nucleus
+ 1.45 / theG4Pow->A13(A); }
else if ( i == 2 ) { fRadiusEff = 1.40 * theG4Pow->powA(A, 0.21) // Anti-Tritium + Nucleus
+ 1.63 / theG4Pow->A13(A); }
else if ( i == 3 ) { fRadiusEff = 1.40 * theG4Pow->powA(A, 0.21) // Anti-He3 + Nucleus
+ 1.63 / theG4Pow->A13(A); }
else if ( i == 4 ) { fRadiusEff = 1.35 * theG4Pow->powA(A, 0.21) // Anti-Tritium + Nucleus
+ 1.10 / theG4Pow->A13(A); }
else {}
}
G4double R2 = fRadiusEff*fRadiusEff;
G4double REf2 = R2+fRadiusNN2;
G4double ApAt = std::abs(theParticle->GetBaryonNumber()) * A;
xsection = 2*pi*REf2*10.*G4Log(1+(ApAt*sigmaTotal/(2*pi*REf2*10.))); //mb
xsection = xsection *millibarn;
G4double xsection = millibarn*2.*pi*R2*10.*G4Log(1.+(ApAt*sigmaTotal/(2.*pi*R2*10.))); //mb
fTotalXsc = xsection;
return fTotalXsc;
@@ -160,61 +155,57 @@ G4double G4ComponentAntiNuclNuclearXS::GetTotalIsotopeCrossSection
G4double G4ComponentAntiNuclNuclearXS::GetInelasticElementCrossSection
(const G4ParticleDefinition* aParticle, G4double kinEnergy, G4int Z, G4double A)
{
G4double inelxsection, sigmaTotal, sigmaElastic;
const G4ParticleDefinition* theParticle = aParticle;
sigmaTotal = GetAntiHadronNucleonTotCrSc(theParticle,kinEnergy);
sigmaElastic = GetAntiHadronNucleonElCrSc(theParticle,kinEnergy);
G4double sigmaTotal = GetAntiHadronNucleonTotCrSc(theParticle,kinEnergy);
G4double sigmaElastic = GetAntiHadronNucleonElCrSc(theParticle,kinEnergy);
// calculation of sqr of radius NN-collision
fRadiusNN2=sigmaTotal*sigmaTotal*0.1/(8.*sigmaElastic*pi); // fm^2
G4int i(-1), j(-1);
if ( theParticle == theAProton ||
theParticle == theANeutron ) { i=0; }
else if ( theParticle == theADeuteron ) { i=1; }
else if ( theParticle == theATriton ) { i=2; }
else if ( theParticle == theAHe3 ) { i=3; }
else if ( theParticle == theAAlpha ) { i=4; }
else {};
// calculation of effective nuclear radius for Pbar and Nbar interaction (can be changed)
//A.R. 29-Jan-2013 : use antiprotons/antineutrons as the default case,
// to be used for instance, as first approximation
// without validation, for anti-hyperons.
if (A==1) {
fInelasticXsc = (sigmaTotal - sigmaElastic) * millibarn;
return fInelasticXsc;
}
fRadiusEff = 1.31*G4Pow::GetInstance()->powA(A, 0.22)+0.9/G4Pow::GetInstance()->powA(A, 1./3.); //fm
if ( (Z==1) && (A==2) ) fRadiusEff = 3.582; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.105;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.105;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.209;
// calculation of effective nuclear radius for AntiDeuteron interaction (can be changed)
if (theParticle ==theADeuteron) {
fRadiusEff = 1.38*G4Pow::GetInstance()->powA(A, 0.21)+1.55/G4Pow::GetInstance()->powA(A, 1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 3.169; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 3.066;
if ( (Z==2) && (A==3) ) fRadiusEff = 3.066;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.498;
if ( i < 0 ) {
G4ExceptionDescription ed;
ed << "Unknown anti-nucleus : "
<< ( theParticle != nullptr ? theParticle->GetParticleName() : "nullptr" ) << G4endl
<< "Target (Z, A)=(" << Z << "," << A << ")" << G4endl;
G4Exception( "G4ComponentAntiNuclNuclearXS::GetInelasticElementCrossSection",
"antiNuclNuclearXS002", JustWarning, ed );
}
// calculation of effective nuclear radius for AntiHe3 interaction (can be changed)
if ( (theParticle ==theAHe3) || (theParticle ==theATriton) ) {
fRadiusEff = 1.34 * G4Pow::GetInstance()->powA(A, 0.21)+1.51/G4Pow::GetInstance()->powA(A, 1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 3.066; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 2.973;
if ( (Z==2) && (A==3) ) fRadiusEff = 2.973;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.508;
}
if ( Z == 1 && A == 1 ) { j=0; }
else if ( Z == 1 && A == 2 ) { j=1; }
else if ( Z == 1 && A == 3 ) { j=2; }
else if ( Z == 2 && A == 3 ) { j=3; }
else if ( Z == 2 && A == 4 ) { j=4; }
else {}
// calculation of effective nuclear radius for AntiAlpha interaction (can be changed)
if (theParticle == theAAlpha) {
fRadiusEff = 1.3*G4Pow::GetInstance()->powA(A, 0.21)+1.05/G4Pow::GetInstance()->powA(A, 1./3.);
if ( (Z==1) && (A==2) ) fRadiusEff = 2.498; //fm
if ( (Z==1) && (A==3) ) fRadiusEff = 2.508;
if ( (Z==2) && (A==3) ) fRadiusEff = 2.508;
if ( (Z==2) && (A==4) ) fRadiusEff = 2.158;
if ( i == 0 && j == 0 ) return (sigmaTotal - sigmaElastic) * millibarn; // Pbar/Nbar + P
if ( i > 0 && j >= 0 ) { fRadiusEff = ReffInel[i][j]; } // Light anti-nuclei + Light nuclei
if ( j < 0) {
if ( i == 0 ) { fRadiusEff = 1.31*theG4Pow->powA(A, 0.22) // Anti-proton/Anti-neutron + Nucleus
+ 0.90/theG4Pow->A13(A); }
else if ( i == 1 ) { fRadiusEff = 1.38*theG4Pow->powA(A, 0.21) // Anti-deuteron + Nucleus
+ 1.55/theG4Pow->A13(A); }
else if ( i == 2 ) { fRadiusEff = 1.34*theG4Pow->powA(A, 0.21) // Anti-Tritium + Nucleus
+ 1.51/theG4Pow->A13(A); }
else if ( i == 3 ) { fRadiusEff = 1.34*theG4Pow->powA(A, 0.21) // Anti-He3 + Nucleus
+ 1.51/theG4Pow->A13(A); }
else if ( i == 4 ) { fRadiusEff = 1.30*theG4Pow->powA(A, 0.21) // Anti-Tritium + Nucleus
+ 1.05/theG4Pow->A13(A); }
else {}
}
G4double R2 = fRadiusEff*fRadiusEff;
G4double REf2 = R2+fRadiusNN2;
G4double ApAt = std::abs(theParticle->GetBaryonNumber()) * A;
inelxsection = pi*REf2 *10* G4Log(1+(ApAt*sigmaTotal/(pi*REf2*10.))); //mb
inelxsection = inelxsection * millibarn;
G4double inelxsection = millibarn*pi*R2*10.*G4Log(1.+(ApAt*sigmaTotal/(pi*R2*10.))); //mb
fInelasticXsc = inelxsection;
return fInelasticXsc;
@@ -283,9 +274,9 @@ G4double G4ComponentAntiNuclNuclearXS::GetAntiHadronNucleonTotCrSc
d2 = 12.38;
d3 = -12.43;
xsection = SigAss * ( 1 + 1./(std::sqrt(S-4.*Mn*Mn)) / (G4Pow::GetInstance()->powA(R0, 3.))
* C * ( 1 + d1/SqrtS + d2/(G4Pow::GetInstance()->powA(SqrtS,2.))
+ d3/(G4Pow::GetInstance()->powA(SqrtS,3.)) ) );
xsection = SigAss * ( 1 + 1./(std::sqrt(S-4.*Mn*Mn)) / (theG4Pow->powN(R0, 3))
* C * ( 1 + d1/SqrtS + d2/(theG4Pow->powN(SqrtS, 2))
+ d3/(theG4Pow->powN(SqrtS, 3)) ) );
//xsection *= millibarn;
fAntiHadronNucleonTotXsc = xsection;
@@ -310,9 +301,9 @@ GetAntiHadronNucleonElCrSc(const G4ParticleDefinition* aParticle, G4double kinEn
d2 = 23.54;
d3 = -25.34;
xsection = SigAss * ( 1 + 1. / (std::sqrt(S-4.*Mn*Mn)) / (G4Pow::GetInstance()->powA(R0, 3.))
* C * ( 1 + d1/SqrtS + d2/(G4Pow::GetInstance()->powA(SqrtS,2.))
+ d3/(G4Pow::GetInstance()->powA(SqrtS,3.)) ) );
xsection = SigAss * ( 1 + 1. / (std::sqrt(S-4.*Mn*Mn)) / (theG4Pow->powN(R0, 3))
* C * ( 1 + d1/SqrtS + d2/(theG4Pow->powN(SqrtS, 2))
+ d3/(theG4Pow->powN(SqrtS, 3)) ) );
//xsection *= millibarn;
fAntiHadronNucleonElXsc = xsection;
@@ -14,6 +14,13 @@ code and to keep track of all tags.
* Please list in reverse chronological order (last date on top)
---------------------------------------------------------------
03 January 2022 - A.Ribon (hadr-cohe-V10-07-05)
--------------------------------------------------
- G4AntiNuclElastic : Vladimir Uzhinsky's correction in the SampleInvariantT
method of the highest momentum transfer (which was causing the cosine of
the polar angle in the center-of-mass system to be larger than 1 in some
cases). This should fix the bug #2204.
04 August 2021 - A.Ribon (hadr-cohe-V10-07-04)
--------------------------------------------------
- G4HadronElastic, G4LEnp, G4LEpp, G4LEHadronProtonElastic,
@@ -108,13 +108,13 @@ G4double G4AntiNuclElastic::SampleInvariantT(const G4ParticleDefinition* particl
const G4ParticleDefinition* theParticle = particle;
G4ParticleDefinition * theDef = 0;
G4ParticleDefinition * theTargetDef = 0;
if(Z == 1 && A == 1) theDef = theProton;
else if (Z == 1 && A == 2) theDef = theDeuteron;
else if (Z == 1 && A == 3) theDef = G4Triton::Triton();
else if (Z == 2 && A == 3) theDef = G4He3::He3();
else if (Z == 2 && A == 4) theDef = theAlpha;
if (Z == 1 && A == 1) theTargetDef = theProton;
else if (Z == 1 && A == 2) theTargetDef = theDeuteron;
else if (Z == 1 && A == 3) theTargetDef = G4Triton::Triton();
else if (Z == 2 && A == 3) theTargetDef = G4He3::He3();
else if (Z == 2 && A == 4) theTargetDef = theAlpha;
G4double TargMass =G4NucleiProperties::GetNuclearMass(A,Z);
@@ -133,11 +133,21 @@ G4double G4AntiNuclElastic::SampleInvariantT(const G4ParticleDefinition* particl
fbst = bst;
fptot= ptot;
fTmax = 4.0*ptot*ptot;
fTmax = 4.0*ptot*ptot; // In (MeV/c)^2
if(Plab < (std::abs(particle->GetBaryonNumber())*100)*MeV) // Uzhi 24 Nov. 2011
{return fTmax*G4UniformRand();} // Uzhi 24 Nov. 2011
if(Plab < (std::abs(particle->GetBaryonNumber())*100)*MeV)
{return fTmax*G4UniformRand();}
// Calculation of NN collision properties
G4double PlabPerN = Plab/std::abs(theParticle->GetBaryonNumber());
G4double NucleonMass = 0.5*( theProton->GetPDGMass() + theNeutron->GetPDGMass() );
G4double PrNucleonMass(0.); // Projectile average nucleon mass
if( std::abs(theParticle->GetBaryonNumber()) == 1 ) { PrNucleonMass = theParticle->GetPDGMass(); }
else { PrNucleonMass = NucleonMass; }
G4double energyPerN = std::sqrt( sqr(PlabPerN) + sqr(PrNucleonMass));
energyPerN -= PrNucleonMass;
//---
G4double Z1 = particle->GetPDGCharge();
G4double Z2 = Z;
@@ -147,239 +157,210 @@ G4double G4AntiNuclElastic::SampleInvariantT(const G4ParticleDefinition* particl
fWaveVector = ptot; // /hbarc;
G4LorentzVector Fproj(0.,0.,0.,0.);
G4double XsCoulomb = sqr(n/fWaveVector)*pi*(1+ctet1)/(1.+Am)/(1.+2.*Am-ctet1);
XsCoulomb=XsCoulomb*0.38938e+6;
const G4double mevToBarn = 0.38938e+6;
G4double XsCoulomb = mevToBarn*sqr(n/fWaveVector)*pi*(1+ctet1)/(1.+Am)/(1.+2.*Am-ctet1);
G4double XsElastHad =cs->GetElasticElementCrossSection(particle, energy, Z, (G4double)A);
G4double XstotalHad =cs->GetTotalElementCrossSection(particle, energy, Z, (G4double)A);
G4double XsElastHadronic =cs->GetElasticElementCrossSection(particle, energy, Z, (G4double)A);
G4double XsTotalHadronic =cs->GetTotalElementCrossSection(particle, energy, Z, (G4double)A);
XsElastHad/=millibarn; XstotalHad/=millibarn;
XsElastHadronic/=millibarn; XsTotalHadronic/=millibarn;
G4double CoulombProb = XsCoulomb/(XsCoulomb+XsElastHad);
// G4cout<<" XselastHadron " << XsElastHad << " XsCol "<< XsCoulomb <<G4endl;
// G4cout <<" XsTotal" << XstotalHad <<G4endl;
// G4cout<<"XsInel"<< XstotalHad-XsElastHad<<G4endl;
G4double CoulombProb = XsCoulomb/(XsCoulomb+XsElastHadronic);
if(G4UniformRand() < CoulombProb)
{ // Simulation of Coulomb scattering
G4double phi = twopi * G4UniformRand();
G4double Ksi = G4UniformRand();
G4double phi = twopi * G4UniformRand();
G4double Ksi = G4UniformRand();
G4double par1 = 2.*(1.+Am)/(1.+ctet1);
G4double par1 = 2.*(1.+Am)/(1.+ctet1);
// ////sample ThetaCMS in Coulomb part
// ////sample ThetaCMS in Coulomb part
G4double cosThetaCMS = (par1*ctet1- Ksi*(1.+2.*Am))/(par1-Ksi);
G4double PtZ=ptot*cosThetaCMS;
Fproj.setPz(PtZ);
G4double PtProjCMS = ptot*std::sqrt(1.0 - cosThetaCMS*cosThetaCMS);
G4double PtX= PtProjCMS * std::cos(phi);
G4double PtY= PtProjCMS * std::sin(phi);
Fproj.setPx(PtX);
Fproj.setPy(PtY);
Fproj.setE(std::sqrt(PtX*PtX+PtY*PtY+PtZ*PtZ+Mproj*Mproj));
T = -(Pproj-Fproj).mag2();
} else
G4double cosThetaCMS = (par1*ctet1- Ksi*(1.+2.*Am))/(par1-Ksi);
G4double PtZ=ptot*cosThetaCMS;
Fproj.setPz(PtZ);
G4double PtProjCMS = ptot*std::sqrt(1.0 - cosThetaCMS*cosThetaCMS);
G4double PtX= PtProjCMS * std::cos(phi);
G4double PtY= PtProjCMS * std::sin(phi);
Fproj.setPx(PtX);
Fproj.setPy(PtY);
Fproj.setE(std::sqrt(PtX*PtX+PtY*PtY+PtZ*PtZ+Mproj*Mproj));
T = -(Pproj-Fproj).mag2();
}
else
{
///////Simulation of strong interaction scattering////////////////////////////
// Simulation of strong interaction scattering
// G4double Qmax = 2.*ptot*197.33; // in fm^-1
G4double Qmax = 2.*3.0*197.33; // in fm^-1
G4double Amag = 70*70; // A1 in Magora funct:A1*exp(-q*A2)
G4double SlopeMag = 2.*3.0; // A2 in Magora funct:A1*exp(-q*A2)
G4double Qmax = 2.*ptot/197.33; // in fm^-1
G4double sig_pbarp= cs->GetAntiHadronNucleonTotCrSc(particle,energy);
fRa = 1.113*G4Pow::GetInstance()->Z13(A) -
0.227/G4Pow::GetInstance()->Z13(A);
if(A == 3) fRa=1.81;
if(A == 4) fRa=1.37;
G4double Amag = 1.0; // A1 in Majorant funct:A1*exp(-q*A2)
G4double SlopeMag = 0.5; // A2 in Majorant funct:A1*exp(-q*A2)
G4double sig_pbarp = cs->GetAntiHadronNucleonTotCrSc(theAProton,energyPerN); //mb
fRa = 1.113*G4Pow::GetInstance()->Z13(A) -
0.227/G4Pow::GetInstance()->Z13(A);
if(A == 3) fRa=1.81;
if(A == 4) fRa=1.37;
if((A>=12.) && (A<27) ) fRa=fRa*0.85;
if((A>=27.) && (A<48) ) fRa=fRa*0.90;
if((A>=48.) && (A<65) ) fRa=fRa*0.95;
if((A>=12.) && (A<27) ) fRa=fRa*0.85;
if((A>=27.) && (A<48) ) fRa=fRa*0.90;
if((A>=48.) && (A<65) ) fRa=fRa*0.95;
G4double Ref2 = 0;
G4double ceff2 =0;
G4double rho = 0;
if ((theParticle == theAProton) || (theParticle == theANeutron))
{
if(theDef == theProton)
{
// G4double Mp2=sqr(theDef->GetPDGMass()/GeV );
G4double Ref2 = XsTotalHadronic/10./2./pi; // in fm^2
G4double ceff2 =0;
G4double rho = 0;
// change 30 October
if(Plab < 610.)
{ rho = 1.3347-10.342*Plab/1000.+22.277*Plab/1000.*Plab/1000.-
13.634*Plab/1000.*Plab/1000.*Plab/1000. ;}
if((Plab < 5500.)&&(Plab >= 610.) )
{ rho = 0.22; }
if((Plab >= 5500.)&&(Plab < 12300.) )
{ rho = -0.32; }
if( Plab >= 12300.)
{ rho = 0.135-2.26/(std::sqrt(S)) ;}
Ref2 = 0.35 + 0.9/std::sqrt(std::sqrt(S-4.*0.88))+0.04*G4Log(S) ;
ceff2 = 0.375 - 2./S + 0.44/(sqr(S-4.)+1.5) ;
/*
Ref2=0.8/std::sqrt(std::sqrt(S-4.*Mp2)) + 0.55;
if(S>1000.) Ref2=0.62+0.02*G4Log(S) ;
ceff2 = 0.035/(sqr(S-4.3)+0.4) + 0.085 * G4Log(S) ;
if(S>1000.) ceff2 = 0.005 * G4Log(S) + 0.29;
*/
Ref2=Ref2*Ref2;
ceff2 = ceff2*ceff2;
SlopeMag = 0.5; // Uzhi
Amag= 1.; // Uzhi
}
if(Z>2)
{ Ref2 = fRa*fRa +2.48*0.01*sig_pbarp*fRa - 2.23e-6*sig_pbarp*sig_pbarp*fRa*fRa;
ceff2 = 0.16+3.3e-4*sig_pbarp+0.35*G4Exp(-0.03*sig_pbarp);
}
if( (Z==2)&&(A==4) )
{ Ref2 = fRa*fRa -0.46 +0.03*sig_pbarp - 2.98e-6*sig_pbarp*sig_pbarp;
ceff2= 0.078 + 6.657e-4*sig_pbarp + 0.3359*G4Exp(-0.03*sig_pbarp);
}
if( (Z==1)&&(A==3) )
{ Ref2 = fRa*fRa - 1.36 + 0.025 * sig_pbarp - 3.69e-7 * sig_pbarp*sig_pbarp;
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*G4Exp(-0.03*sig_pbarp);
}
if( (Z==2)&&(A==3) )
{ Ref2 = fRa*fRa - 1.36 + 0.025 * sig_pbarp - 3.69e-7 * sig_pbarp*sig_pbarp;
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*G4Exp(-0.03*sig_pbarp);
}
if( (Z==1)&&(A==2) )
if ((theParticle == theAProton) || (theParticle == theANeutron))
{
Ref2 = fRa*fRa - 0.28 + 0.019 * sig_pbarp + 2.06e-6 * sig_pbarp*sig_pbarp;
ceff2 = 0.297 + 7.853e-04*sig_pbarp + 0.2899*G4Exp(-0.03*sig_pbarp);
}
}
if(theTargetDef == theProton)
{
// Determination of the real part of Pbar+N amplitude
if(Plab < 610.)
{ rho = 1.3347-10.342*Plab/1000.+22.277*Plab/1000.*Plab/1000.-
13.634*Plab/1000.*Plab/1000.*Plab/1000. ;}
if((Plab < 5500.)&&(Plab >= 610.) )
{ rho = 0.22; }
if((Plab >= 5500.)&&(Plab < 12300.) )
{ rho = -0.32; }
if( Plab >= 12300.)
{ rho = 0.135-2.26/(std::sqrt(S)) ;}
Ref2 = 0.35 + 0.9/std::sqrt(std::sqrt(S-4.*0.88))+0.04*G4Log(S) ;
ceff2 = 0.375 - 2./S + 0.44/(sqr(S-4.)+1.5) ;
Ref2 =Ref2*Ref2;
ceff2 = ceff2*ceff2;
}
if (theParticle == theADeuteron)
{
sig_pbarp= cs->GetAntiHadronNucleonTotCrSc(particle,energy/2.);
Ref2 = XstotalHad/10./2./pi ;
if(Z>2)
{
ceff2 = 0.38 + 2.0e-4 *sig_pbarp + 0.5 * G4Exp(-0.03*sig_pbarp);
}
if(theDef == theProton)
{
ceff2 = 0.297 + 7.853e-04*sig_pbarp + 0.2899*G4Exp(-0.03*sig_pbarp);
}
if(theDef == theDeuteron)
{
ceff2 = 0.65 + 3.0e-4*sig_pbarp + 0.55 * G4Exp(-0.03*sig_pbarp);
}
if( (theDef == G4Triton::Triton()) || (theDef == G4He3::He3() ) )
{
ceff2 = 0.57 + 2.5e-4*sig_pbarp + 0.65 * G4Exp(-0.02*sig_pbarp);
}
if(theDef == theAlpha)
{
ceff2 = 0.40 + 3.5e-4 *sig_pbarp + 0.45 * G4Exp(-0.02*sig_pbarp);
}
}
if( (Z==1)&&(A==2) )
{
Ref2 = fRa*fRa - 0.28 + 0.019 * sig_pbarp + 2.06e-6 * sig_pbarp*sig_pbarp;
ceff2 = 0.297 + 7.853e-04*sig_pbarp + 0.2899*G4Exp(-0.03*sig_pbarp);
}
if( (Z==1)&&(A==3) )
{
Ref2 = fRa*fRa - 1.36 + 0.025 * sig_pbarp - 3.69e-7 * sig_pbarp*sig_pbarp;
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*G4Exp(-0.03*sig_pbarp);
}
if( (Z==2)&&(A==3) )
{
Ref2 = fRa*fRa - 1.36 + 0.025 * sig_pbarp - 3.69e-7 * sig_pbarp*sig_pbarp;
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*G4Exp(-0.03*sig_pbarp);
}
if( (Z==2)&&(A==4) )
{
Ref2 = fRa*fRa -0.46 +0.03*sig_pbarp - 2.98e-6*sig_pbarp*sig_pbarp;
ceff2= 0.078 + 6.657e-4*sig_pbarp + 0.3359*G4Exp(-0.03*sig_pbarp);
}
if(Z>2)
{
Ref2 = fRa*fRa +2.48*0.01*sig_pbarp*fRa - 2.23e-6*sig_pbarp*sig_pbarp*fRa*fRa;
ceff2 = 0.16+3.3e-4*sig_pbarp+0.35*G4Exp(-0.03*sig_pbarp);
}
} // End of if ((theParticle == theAProton) || (theParticle == theANeutron))
if( (theParticle ==theAHe3) || (theParticle ==theATriton) )
{
sig_pbarp = cs->GetAntiHadronNucleonTotCrSc(particle,energy/3.);
Ref2 = XstotalHad/10./2./pi ;
if(Z>2)
if (theParticle == theADeuteron)
{
ceff2 = 0.26 + 2.2e-4*sig_pbarp + 0.33*G4Exp(-0.03*sig_pbarp);
}
if(theDef == theProton)
{
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*G4Exp(-0.03*sig_pbarp);
if(theTargetDef == theProton)
{
ceff2 = 0.297 + 7.853e-04*sig_pbarp + 0.2899*G4Exp(-0.03*sig_pbarp);
}
if(theTargetDef == theDeuteron)
{
ceff2 = 0.65 + 3.0e-4*sig_pbarp + 0.55 * G4Exp(-0.03*sig_pbarp);
}
if( (theTargetDef == G4Triton::Triton()) || (theTargetDef == G4He3::He3() ) )
{
ceff2 = 0.57 + 2.5e-4*sig_pbarp + 0.65 * G4Exp(-0.02*sig_pbarp);
}
if(theTargetDef == theAlpha)
{
ceff2 = 0.40 + 3.5e-4 *sig_pbarp + 0.45 * G4Exp(-0.02*sig_pbarp);
}
if(Z>2)
{
ceff2 = 0.38 + 2.0e-4 *sig_pbarp + 0.5 * G4Exp(-0.03*sig_pbarp);
}
}
if(theDef == theDeuteron)
{
ceff2 = 0.57 + 2.5e-4*sig_pbarp + 0.65 * G4Exp(-0.02*sig_pbarp);
}
if( (theDef == G4Triton::Triton()) || (theDef == G4He3::He3() ) )
{
ceff2 = 0.39 + 2.7e-4*sig_pbarp + 0.7 * G4Exp(-0.02*sig_pbarp);
}
if(theDef == theAlpha)
{
ceff2 = 0.24 + 3.5e-4*sig_pbarp + 0.75 * G4Exp(-0.03*sig_pbarp);
}
}
if (theParticle == theAAlpha)
{
sig_pbarp = cs->GetAntiHadronNucleonTotCrSc(particle,energy/3.);
Ref2 = XstotalHad/10./2./pi ;
if(Z>2)
if( (theParticle ==theAHe3) || (theParticle ==theATriton) )
{
ceff2 = 0.22 + 2.0e-4*sig_pbarp + 0.2 * G4Exp(-0.03*sig_pbarp);
if(theTargetDef == theProton)
{
ceff2 = 0.149 + 7.091e-04*sig_pbarp + 0.3743*G4Exp(-0.03*sig_pbarp);
}
if(theTargetDef == theDeuteron)
{
ceff2 = 0.57 + 2.5e-4*sig_pbarp + 0.65 * G4Exp(-0.02*sig_pbarp);
}
if( (theTargetDef == G4Triton::Triton()) || (theTargetDef == G4He3::He3() ) )
{
ceff2 = 0.39 + 2.7e-4*sig_pbarp + 0.7 * G4Exp(-0.02*sig_pbarp);
}
if(theTargetDef == theAlpha)
{
ceff2 = 0.24 + 3.5e-4*sig_pbarp + 0.75 * G4Exp(-0.03*sig_pbarp);
}
if(Z>2)
{
ceff2 = 0.26 + 2.2e-4*sig_pbarp + 0.33*G4Exp(-0.03*sig_pbarp);
}
}
if(theDef == theProton)
if (theParticle == theAAlpha)
{
ceff2= 0.078 + 6.657e-4*sig_pbarp + 0.3359*G4Exp(-0.03*sig_pbarp);
if(theTargetDef == theProton)
{
ceff2= 0.078 + 6.657e-4*sig_pbarp + 0.3359*G4Exp(-0.03*sig_pbarp);
}
if(theTargetDef == theDeuteron)
{
ceff2 = 0.40 + 3.5e-4 *sig_pbarp + 0.45 * G4Exp(-0.02*sig_pbarp);
}
if( (theTargetDef == G4Triton::Triton()) || (theTargetDef == G4He3::He3() ) )
{
ceff2 = 0.24 + 3.5e-4*sig_pbarp + 0.75 * G4Exp(-0.03*sig_pbarp);
}
if(theTargetDef == theAlpha)
{
ceff2 = 0.17 + 3.5e-4*sig_pbarp + 0.45 * G4Exp(-0.03*sig_pbarp);
}
if(Z>2)
{
ceff2 = 0.22 + 2.0e-4*sig_pbarp + 0.2 * G4Exp(-0.03*sig_pbarp);
}
}
if(theDef == theDeuteron)
fRef=std::sqrt(Ref2);
fceff = std::sqrt(ceff2);
G4double Q = 0.0 ;
G4double BracFunct;
const G4int maxNumberOfLoops = 10000;
G4int loopCounter = 0;
do
{
ceff2 = 0.40 + 3.5e-4 *sig_pbarp + 0.45 * G4Exp(-0.02*sig_pbarp);
}
if( (theDef == G4Triton::Triton()) || (theDef == G4He3::He3() ) )
{
ceff2 = 0.24 + 3.5e-4*sig_pbarp + 0.75 * G4Exp(-0.03*sig_pbarp);
Q = -G4Log(1.-(1.- G4Exp(-SlopeMag * Qmax))* G4UniformRand() )/SlopeMag;
G4double x = fRef * Q;
BracFunct = ( ( sqr(BesselOneByArg(x))+sqr(rho/2. * BesselJzero(x)) )
* sqr(DampFactor(pi*fceff*Q))) /(Amag*G4Exp(-SlopeMag*Q));
BracFunct = BracFunct * Q;
}
while ( (G4UniformRand()>BracFunct) &&
++loopCounter < maxNumberOfLoops ); /* Loop checking, 10.08.2015, A.Ribon */
if ( loopCounter >= maxNumberOfLoops ) {
fTetaCMS = 0.0;
return 0.0;
}
if(theDef == theAlpha)
{
ceff2 = 0.17 + 3.5e-4*sig_pbarp + 0.45 * G4Exp(-0.03*sig_pbarp);
}
}
fRef=std::sqrt(Ref2);
fceff = std::sqrt(ceff2);
// G4cout<<" Ref "<<fRef<<" c_eff "<<fceff<< " rho "<< rho<<G4endl;
T= sqr(Q);
T*=3.893913e+4; // fm^(-2) -> MeV^2
G4double Q = 0.0 ;
G4double BracFunct;
const G4int maxNumberOfLoops = 10000;
G4int loopCounter = 0;
do
{
Q = -G4Log(1.-(1.- G4Exp(-SlopeMag * Qmax))* G4UniformRand() )/SlopeMag;
G4double x = fRef * Q;
BracFunct = ( ( sqr(BesselOneByArg(x))+sqr(rho/2. * BesselJzero(x)) )
* sqr(DampFactor(pi*fceff*Q))) /(Amag*G4Exp(-SlopeMag*Q));
} // End of simulation of strong interaction scattering
BracFunct = BracFunct * Q * sqr(sqr(fRef));
}
while ( (G4UniformRand()>BracFunct) &&
++loopCounter < maxNumberOfLoops ); /* Loop checking, 10.08.2015, A.Ribon */
if ( loopCounter >= maxNumberOfLoops ) {
fTetaCMS = 0.0;
return 0.0;
}
T= sqr(Q);
T*=3.893913e+4; // fm -> MeV^2
}
// VI: 29.04.2019 unnecessary computation of trigonometry
/*
G4double cosTet=1.0-T/(2.*ptot*ptot);
if(cosTet > 1.0 ) cosTet= 1.; // Uzhi 30 Nov.
if(cosTet < -1.0 ) cosTet=-1.; // Uzhi 30 Nov.
fTetaCMS=std::acos(cosTet);
*/
return T;
return T;
}
/////////////////////////////////////////////////////////////////////
@@ -404,17 +385,17 @@ G4double G4AntiNuclElastic::SampleInvariantT(const G4ParticleDefinition* particl
}
if(fptot > 0.) // Uzhi 24 Nov. 2011
if(fptot > 0.)
{
G4double cosTet=1.0-T/(2.*fptot*fptot);
if(cosTet > 1.0 ) cosTet= 1.; // Uzhi 30 Nov.
if(cosTet < -1.0 ) cosTet=-1.; // Uzhi 30 Nov.
if(cosTet > 1.0 ) cosTet= 1.;
if(cosTet < -1.0 ) cosTet=-1.;
fTetaCMS=std::acos(cosTet);
return fTetaCMS;
} else // Uzhi 24 Nov. 2011
{ // Uzhi 24 Nov. 2011
return 2.*G4UniformRand()-1.; // Uzhi 24 Nov. 2011
} // Uzhi 24 Nov. 2011
} else
{
return 2.*G4UniformRand()-1.;
}
}
@@ -442,7 +423,7 @@ G4double G4AntiNuclElastic::SampleInvariantT(const G4ParticleDefinition* particl
G4double phi = G4UniformRand()*twopi;
G4double cost(1.);
if(fTmax > 0.) {cost = 1. - 2.0*T/fTmax;} // Uzhi 24 Nov. 2011
if(fTmax > 0.) {cost = 1. - 2.0*T/fTmax;}
G4double sint;
if( cost >= 1.0 )
@@ -15,6 +15,16 @@ code and to keep track of all tags.
* Please list in reverse chronological order (last date on top)
---------------------------------------------------------------
03 March 2022 - Alberto Ribon (hadr-inclxx-V10-07-07)
-------------------------------------------------------
- G4INCLXXInterface : fixed treatment of kaon0, anti_kaon0, kaon0L, and kaon0S.
In current reference physics lists, INCLXX is never used for handling kaons,
although it is capable of doing so, but at process-level or in custom
physics lists one could observe crashes when trying to use INCLXX for
neutral kaon projectiles. The change (provided by Jean-Christophe David)
fixes this misbehavior.
09 November 2021 - Alberto Ribon (hadr-inclxx-V10-07-06)
-------------------------------------------------------
- G4INCLNuclearPotentialIsospin : improved nuclear potential for
@@ -527,19 +527,24 @@ G4ReactionProductVector* G4INCLXXInterface::Propagate(G4KineticTrackVector* , G4
}
G4INCL::ParticleType G4INCLXXInterface::toINCLParticleType(G4ParticleDefinition const * const pdef) const {
if( pdef == G4Proton::Proton()) return G4INCL::Proton;
else if(pdef == G4Neutron::Neutron()) return G4INCL::Neutron;
else if(pdef == G4PionPlus::PionPlus()) return G4INCL::PiPlus;
else if(pdef == G4PionMinus::PionMinus()) return G4INCL::PiMinus;
else if(pdef == G4PionZero::PionZero()) return G4INCL::PiZero;
else if(pdef == G4KaonPlus::KaonPlus()) return G4INCL::KPlus;
else if(pdef == G4KaonMinus::KaonMinus()) return G4INCL::KMinus;
else if(pdef == G4Deuteron::Deuteron()) return G4INCL::Composite;
else if(pdef == G4Triton::Triton()) return G4INCL::Composite;
else if(pdef == G4He3::He3()) return G4INCL::Composite;
else if(pdef == G4Alpha::Alpha()) return G4INCL::Composite;
if( pdef == G4Proton::Proton()) return G4INCL::Proton;
else if(pdef == G4Neutron::Neutron()) return G4INCL::Neutron;
else if(pdef == G4PionPlus::PionPlus()) return G4INCL::PiPlus;
else if(pdef == G4PionMinus::PionMinus()) return G4INCL::PiMinus;
else if(pdef == G4PionZero::PionZero()) return G4INCL::PiZero;
else if(pdef == G4KaonPlus::KaonPlus()) return G4INCL::KPlus;
else if(pdef == G4KaonZero::KaonZero()) return G4INCL::KZero;
else if(pdef == G4KaonMinus::KaonMinus()) return G4INCL::KMinus;
else if(pdef == G4AntiKaonZero::AntiKaonZero()) return G4INCL::KZeroBar;
// For K0L & K0S we do not take into account K0/K0B oscillations
else if(pdef == G4KaonZeroLong::KaonZeroLong()) return G4UniformRand() < 0.5 ? G4INCL::KZeroBar : G4INCL::KZero;
else if(pdef == G4KaonZeroShort::KaonZeroShort()) return G4UniformRand() < 0.5 ? G4INCL::KZeroBar : G4INCL::KZero;
else if(pdef == G4Deuteron::Deuteron()) return G4INCL::Composite;
else if(pdef == G4Triton::Triton()) return G4INCL::Composite;
else if(pdef == G4He3::He3()) return G4INCL::Composite;
else if(pdef == G4Alpha::Alpha()) return G4INCL::Composite;
else if(pdef->GetParticleType() == G4GenericIon::GenericIon()->GetParticleType()) return G4INCL::Composite;
else return G4INCL::UnknownParticle;
else return G4INCL::UnknownParticle;
}
G4INCL::ParticleSpecies G4INCLXXInterface::toINCLParticleSpecies(G4HadProjectile const &aTrack) const {
+4
View File
@@ -16,6 +16,10 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
10 Jan 22: D. Sawkey (op-V10-07-06)
- Remove G4lrint/G4lint to calculate angle bin for Davis/LBNL LUT. Fixes crash
when angle = 0. Addresses issue 116.
21 Oct 21: D. Sawkey (op-V10-07-05)
- G4OpBoundaryProcess - rename variables: class start with f; lowercase
- make comparison to nullptr explicit
@@ -801,7 +801,7 @@ void G4OpBoundaryProcess::DielectricLUT()
// Calculate Angle between Normal and Photon Momentum
G4double anglePhotonToNormal = fOldMomentum.angle(-fGlobalNormal);
// Round to closest integer: LBNL model array has 91 values
G4int angleIncident = G4lrint(anglePhotonToNormal / CLHEP::deg);
G4int angleIncident = std::lrint(anglePhotonToNormal / CLHEP::deg);
// Take random angles THETA and PHI,
// and see if below Probability - if not - Redo
@@ -857,7 +857,9 @@ void G4OpBoundaryProcess::DielectricLUTDAVIS()
anglePhotonToNormal = fOldMomentum.angle(-fGlobalNormal);
// Davis model has 90 reflection bins: round down
angleIncident = G4lint(anglePhotonToNormal / CLHEP::deg);
// don't allow angleIncident to be 90 for anglePhotonToNormal close to 90
angleIncident = std::min(static_cast<G4int>(
std::floor(anglePhotonToNormal / CLHEP::deg)), 89);
reflectivityValue = fOpticalSurface->GetReflectivityLUTValue(angleIncident);
if(rand > reflectivityValue)