Import Geant4 11.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2022-12-09 14:43:28 +01:00
parent c07cea1fe0
commit 9f34590941
3810 changed files with 200490 additions and 182326 deletions
@@ -6,6 +6,40 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2022-11-26 Gabriele Cosmo (hadr-proc-V11-00-11)
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
## 2022-11-02 Vladimir Grichine (hadr-proc-V11-00-10)
- G4TauNeutrinoNucleusProcess - added for tau-neutrino hadronic inelastic processes
## 2022-09-25 Vladimir Ivanchenko (hadr-proc-V11-00-09)
- G4NeutronGeneralProcess - added SetTimeLimit(..) method
## 2022-09-05 Ben Morgan (hadr-proc-V11-00-08)
- Update dependencies to address warnings from consistency check
## 2022-08-30 Vladimir Ivanchenko (hadr-proc-V11-00-07)
- G4NeutronGeneralProcess - added fatal G4Exception at initialisation
in the case of incomplete configuration of the process
## 2022-08-22 Vladimir Ivanchenko (hadr-proc-V11-00-06)
- G4NeutronGeneralProcess - use enumerator for neutron general process
instead of hard-coded number; do not apply energy cut
## 2022-08-22 Vladimir Ivanchenko (hadr-proc-V11-00-05)
- G4NeutronGeneralProcess - make it work with QBBC physics list
- G4HadronElasticProcess - extended debug printout
## 2022-08-18 Vladimir Ivanchenko (hadr-proc-V11-00-04)
- G4NeutronGeneralProcess - improved the code, added possible cut on
neutron kinetic energy, always elastic initialisation/printout
before the inelastic
- G4NeutronCaptureProcess - avoid double instantiation of the cross
section
## 2022-08-13 Vladimir Ivanchenko (hadr-proc-V11-00-03)
- G4NeutronGeneralProcess - new combined process
## 2022-02-09 Gabriele Cosmo (hadr-proc-V11-00-02)
- Fixed compilation warning on Intel compilers for unused variables.
@@ -49,16 +49,16 @@
#include "globals.hh"
#include "G4HadronicProcess.hh"
class G4NeutronCaptureProcess : public G4HadronicProcess
class G4NeutronCaptureProcess final : public G4HadronicProcess
{
public:
public:
explicit G4NeutronCaptureProcess(const G4String& processName ="nCapture");
explicit G4NeutronCaptureProcess(const G4String& processName ="nCapture");
virtual ~G4NeutronCaptureProcess();
~G4NeutronCaptureProcess() final = default;
G4bool IsApplicable(const G4ParticleDefinition& aParticleType) final;
G4bool IsApplicable(const G4ParticleDefinition&) final;
void ProcessDescription(std::ostream& outFile) const final;
void ProcessDescription(std::ostream& outFile) const final;
};
#endif
@@ -0,0 +1,275 @@
//
// ********************************************************************
// * 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: G4NeutronGeneralProcess
//
// Author: Vladimir Ivanchenko
//
// Creation date: 08.08.2022
//
// Modifications:
//
// Class Description:
//
// It is the neutron super process
// -------------------------------------------------------------------
//
#ifndef G4NeutronGeneralProcess_h
#define G4NeutronGeneralProcess_h 1
#include "G4HadronicProcess.hh"
#include "globals.hh"
#include "G4HadDataHandler.hh"
#include <vector>
class G4Step;
class G4Track;
class G4ParticleDefinition;
class G4VParticleChange;
class G4VCrossSectionDataSet;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class G4NeutronGeneralProcess : public G4HadronicProcess
{
public:
explicit G4NeutronGeneralProcess(const G4String& pname="NeutronGeneralProc");
~G4NeutronGeneralProcess() override;
G4bool IsApplicable(const G4ParticleDefinition&) override;
void ProcessDescription(std::ostream& outFile) const override;
// Initialise for build of tables
void PreparePhysicsTable(const G4ParticleDefinition&) override;
// Build physics table during initialisation
void BuildPhysicsTable(const G4ParticleDefinition&) override;
// Store internal tables after initialisation
G4bool StorePhysicsTable(const G4ParticleDefinition* part,
const G4String& directory, G4bool ascii) override;
// Called before tracking of each new G4Track
void StartTracking(G4Track*) override;
// implementation of virtual method, specific for G4NeutronGeneralProcess
G4double PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition) override;
// implementation of virtual method, specific for G4NeutronGeneralProcess
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&) override;
const G4VProcess* GetCreatorProcess() const override;
// Temporary method
const G4String& GetSubProcessName() const;
// Temporary method
G4int GetSubProcessSubType() const;
inline const G4VProcess* GetSelectedProcess() const;
inline void SetInelasticProcess(G4HadronicProcess*);
inline void SetElasticProcess(G4HadronicProcess*);
inline void SetCaptureProcess(G4HadronicProcess*);
inline void SetTimeLimit(G4double val);
// hide copy constructor and assignment operator
G4NeutronGeneralProcess(G4NeutronGeneralProcess &) = delete;
G4NeutronGeneralProcess & operator=
(const G4NeutronGeneralProcess &right) = delete;
protected:
G4double GetMeanFreePath(const G4Track& track, G4double previousStepSize,
G4ForceCondition* condition) override;
inline G4double ComputeGeneralLambda(size_t idxe, size_t idxt);
inline G4double GetProbability(size_t idxt);
inline void SelectedProcess(const G4Step& step, G4HadronicProcess* ptr,
G4VCrossSectionDataSet* xs);
void SelectHadProcess(const G4Track&, const G4Step&, G4HadronicProcess*);
private:
// partial cross section
G4double ComputeCrossSection(G4VCrossSectionDataSet*, const G4Material*,
G4double kinEnergy, G4double loge);
// total cross section
inline void CurrentCrossSection(const G4Track&);
static G4HadDataHandler* theHandler;
static const size_t nTables = 5;
static G4String nameT[nTables];
G4HadronicProcess* fInelastic = nullptr;
G4HadronicProcess* fElastic = nullptr;
G4HadronicProcess* fCapture = nullptr;
G4HadronicProcess* fSelectedProc = nullptr;
G4VCrossSectionDataSet* fInelasticXS;
G4VCrossSectionDataSet* fElasticXS;
G4VCrossSectionDataSet* fCaptureXS;
G4VCrossSectionDataSet* fXS = nullptr;
const G4ParticleDefinition* fNeutron;
const G4Material* fCurrMat = nullptr;
G4double fMinEnergy;
G4double fMiddleEnergy;
G4double fMaxEnergy;
G4double fTimeLimit;
G4double fXSFactorInel = 1.0;
G4double fXSFactorEl = 1.0;
G4double fCurrE = 0.0;
G4double fCurrLogE = 0.0;
G4double fLambda = 0.0;
// number of bins per decade
std::size_t nLowE = 100;
std::size_t nHighE = 10;
std::size_t idxEnergy = 0;
std::size_t matIndex = 0;
G4bool isMaster = true;
std::vector<G4double> fXsec;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void
G4NeutronGeneralProcess::SetInelasticProcess(G4HadronicProcess* ptr)
{
fInelastic = ptr;
ptr->AddDataSet(fInelasticXS);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4NeutronGeneralProcess::SetElasticProcess(G4HadronicProcess* ptr)
{
fElastic = ptr;
ptr->AddDataSet(fElasticXS);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4NeutronGeneralProcess::SetCaptureProcess(G4HadronicProcess* ptr)
{
fCapture = ptr;
ptr->AddDataSet(fCaptureXS);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double
G4NeutronGeneralProcess::ComputeGeneralLambda(std::size_t idxe, std::size_t idxt)
{
idxEnergy = idxe;
return theHandler->GetVector(idxt, matIndex)
->LogVectorValue(fCurrE, fCurrLogE);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4NeutronGeneralProcess::GetProbability(std::size_t idxt)
{
return theHandler->GetVector(idxt, matIndex)
->LogVectorValue(fCurrE, fCurrLogE);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void
G4NeutronGeneralProcess::SelectedProcess(const G4Step& step,
G4HadronicProcess* ptr,
G4VCrossSectionDataSet* xs)
{
fSelectedProc = ptr;
fXS = xs;
step.GetPostStepPoint()->SetProcessDefinedStep(ptr);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4VProcess* G4NeutronGeneralProcess::GetSelectedProcess() const
{
return fSelectedProc;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4NeutronGeneralProcess::CurrentCrossSection(const G4Track& track)
{
G4double energy = track.GetKineticEnergy();
const G4Material* mat = track.GetMaterial();
G4bool recompute = false;
if(mat != fCurrMat) {
fCurrMat = mat;
matIndex = mat->GetIndex();
recompute = true;
}
if(energy != fCurrE) {
fCurrE = energy;
fCurrLogE = track.GetDynamicParticle()->GetLogKineticEnergy();
recompute = true;
}
if(recompute) {
fLambda = (energy <= fMiddleEnergy) ? ComputeGeneralLambda(0, 0)
: ComputeGeneralLambda(1, 3);
currentInteractionLength = 1.0/fLambda;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4NeutronGeneralProcess::SetTimeLimit(G4double val)
{
fTimeLimit = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -0,0 +1,87 @@
//
// ********************************************************************
// * 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 muon neutrino nucleus scattering Process -- header file
//
// Created from G4MuNeutrinoNucleusProcess 1.11.22 V. Grichine
//
// Class Description
// Hadronic inelastic process for tau neutrino nucleus 2->X scattering
// Class Description - End
#ifndef G4TauNeutrinoNucleusProcess_h
#define G4TauNeutrinoNucleusProcess_h 1
#include "globals.hh"
#include "G4HadronicProcess.hh"
class G4ParticleDefinition;
class G4CrossSectionDataStore;
class G4LogicalVolume;
class G4TauNeutrinoNucleusTotXsc;
class G4SafetyHelper;
class G4TauNeutrinoNucleusProcess : public G4HadronicProcess
{
public:
G4TauNeutrinoNucleusProcess(G4String anEnvelopeName , const G4String& procName = "tau-neutrino-nucleus");
virtual ~G4TauNeutrinoNucleusProcess();
G4VParticleChange* PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep) override;
// initialise thresholds
void PreparePhysicsTable(const G4ParticleDefinition&) override;
// set internal limit
virtual void SetLowestEnergy(G4double);
void ProcessDescription(std::ostream& outFile) const override;
void SetBiasingFactors(G4double bfCc, G4double bfNc);
void SetBiasingFactor(G4double bf);
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *) override;
private:
// hide assignment operator as private
G4TauNeutrinoNucleusProcess& operator=(const G4TauNeutrinoNucleusProcess &right);
G4TauNeutrinoNucleusProcess(const G4TauNeutrinoNucleusProcess& );
G4double lowestEnergy;
G4bool isInitialised, fBiased;
G4LogicalVolume* fEnvelope;
G4String fEnvelopeName;
G4TauNeutrinoNucleusTotXsc* fTotXsc;
G4double fNuNuclCcBias, fNuNuclNcBias, fNuNuclTotXscBias;
G4SafetyHelper* safetyHelper;
};
#endif
@@ -12,7 +12,9 @@ geant4_add_module(G4hadronic_proc
G4NeutrinoElectronProcess.hh
G4NeutronCaptureProcess.hh
G4NeutronFissionProcess.hh
G4NeutronGeneralProcess.hh
G4PositronNuclearProcess.hh
G4TauNeutrinoNucleusProcess.hh
G4UCNProcessSubType.hh
G4UCNBoundaryProcess.hh
G4UCNBoundaryProcessMessenger.hh
@@ -29,7 +31,9 @@ geant4_add_module(G4hadronic_proc
G4NeutrinoElectronProcess.cc
G4NeutronCaptureProcess.cc
G4NeutronFissionProcess.cc
G4NeutronGeneralProcess.cc
G4PositronNuclearProcess.cc
G4TauNeutrinoNucleusProcess.cc
G4UCNBoundaryProcess.cc
G4UCNBoundaryProcessMessenger.cc
G4UCNLoss.cc
@@ -41,6 +45,7 @@ geant4_module_link_libraries(G4hadronic_proc
G4baryons
G4globman
G4hadronic_mgt
G4hadronic_util
G4intercoms
G4materials
G4procman
@@ -48,7 +53,6 @@ geant4_module_link_libraries(G4hadronic_proc
G4cuts
G4detector
G4geometrymng
G4hadronic_util
G4hadronic_xsect
G4ions
G4leptons
@@ -216,8 +216,10 @@ G4HadronElasticProcess::PostStepDoIt(const G4Track& track,
else { status = fStopAndKill; }
theTotalResult->ProposeTrackStatus(status);
}
//G4cout << "Efinal= " << efinal << " TrackStatus= " << status << G4endl;
/*
G4cout << "Efinal= " << efinal << " TrackStatus= " << status
<< " time(ns)=" << track.GetGlobalTime()/ns << G4endl;
*/
theTotalResult->SetNumberOfSecondaries(0);
// recoil
@@ -51,9 +51,6 @@ G4NeutronCaptureProcess::G4NeutronCaptureProcess(const G4String& processName) :
AddDataSet(new G4NeutronCaptureXS());
}
G4NeutronCaptureProcess::~G4NeutronCaptureProcess()
{}
G4bool
G4NeutronCaptureProcess::IsApplicable(const G4ParticleDefinition& aParticleType)
{
@@ -0,0 +1,478 @@
//
// ********************************************************************
// * 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: G4NeutronGeneralProcess
//
// Author: Vladimir Ivanchenko
//
// Creation date: 08.08.2022
//
// Modifications:
//
// Class Description:
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4NeutronGeneralProcess.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4ProcessManager.hh"
#include "G4HadronicProcess.hh"
#include "G4Step.hh"
#include "G4Track.hh"
#include "G4ParticleDefinition.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsLogVector.hh"
#include "G4VParticleChange.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4HadronicParameters.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "G4Element.hh"
#include "G4Neutron.hh"
#include "G4Nucleus.hh"
#include "G4NeutronInelasticXS.hh"
#include "G4NeutronElasticXS.hh"
#include "G4NeutronCaptureXS.hh"
#include "G4Threading.hh"
#include "G4Log.hh"
#include <iostream>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4HadDataHandler* G4NeutronGeneralProcess::theHandler = nullptr;
G4String G4NeutronGeneralProcess::nameT[nTables] = {"0","1","2","3","4"};
G4NeutronGeneralProcess::G4NeutronGeneralProcess(const G4String& pname)
: G4HadronicProcess(pname),
fMinEnergy(1*CLHEP::keV),
fMiddleEnergy(20*CLHEP::MeV),
fMaxEnergy(100*CLHEP::TeV),
fTimeLimit(10*CLHEP::microsecond)
{
SetVerboseLevel(1);
SetProcessSubType(fNeutronGeneral);
fElasticXS = new G4NeutronElasticXS();
fInelasticXS = new G4NeutronInelasticXS();
fCaptureXS = new G4NeutronCaptureXS();
AddDataSet(fElasticXS);
AddDataSet(fInelasticXS);
AddDataSet(fCaptureXS);
fNeutron = G4Neutron::Neutron();
if(G4Threading::IsWorkerThread()) {
isMaster = false;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4NeutronGeneralProcess::~G4NeutronGeneralProcess()
{
if(isMaster) {
delete theHandler;
theHandler = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4NeutronGeneralProcess::IsApplicable(const G4ParticleDefinition&)
{
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4NeutronGeneralProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
{
if(1 < verboseLevel) {
G4cout << "G4NeutronGeneralProcess::PreparePhysicsTable() for "
<< GetProcessName()
<< " and particle " << part.GetParticleName()
<< " isMaster: " << isMaster << G4endl;
}
G4bool noEl = (nullptr == fElastic);
G4bool noInel = (nullptr == fInelastic);
G4bool noCap = (nullptr == fCapture);
if(noEl || noInel || noCap) {
G4ExceptionDescription ed;
ed << "Incomplete configuration of the neutron general process." << G4endl;
if(noEl) { ed << "Neutron elastic process is not defined" << G4endl; }
if(noInel) { ed << "Neutron inelastic process is not defined" << G4endl; }
if(noCap) { ed << "Neutron capture process is not defined" << G4endl; }
G4Exception ("G4NeutronGeneralProcess::PreparePhysicsTable(..)", "had001",
FatalException, ed, "");
return;
}
G4HadronicParameters* param = G4HadronicParameters::Instance();
SetVerboseLevel(param->GetVerboseLevel());
fMaxEnergy = std::max(100*MeV, param->GetMaxEnergy());
if(param->ApplyFactorXS()) {
fXSFactorEl = param->XSFactorNucleonElastic();
fXSFactorInel = param->XSFactorNucleonInelastic();
}
fElastic->PreparePhysicsTable(part);
fInelastic->PreparePhysicsTable(part);
fCapture->PreparePhysicsTable(part);
std::size_t nmat = G4Material::GetNumberOfMaterials();
G4MaterialTable* matTable = G4Material::GetMaterialTable();
std::size_t nmax = 0;
for(std::size_t i=0; i<nmat; ++i) {
std::size_t nelm = (*matTable)[i]->GetNumberOfElements();
nmax = std::max(nmax, nelm);
}
fXsec.resize(nmax);
if(isMaster) {
if(nullptr == theHandler) {
theHandler = new G4HadDataHandler(nTables);
}
fMaxEnergy = std::max(fMaxEnergy, param->GetMaxEnergy());
nLowE *= G4lrint(std::log10(fMiddleEnergy/fMinEnergy));
nHighE *= G4lrint(std::log10(fMaxEnergy/fMiddleEnergy));
G4PhysicsVector* vec = nullptr;
G4PhysicsLogVector aVector(fMinEnergy, fMiddleEnergy, nLowE, false);
G4PhysicsLogVector bVector(fMiddleEnergy, fMaxEnergy, nHighE, false);
for(std::size_t i=0; i<nTables; ++i) {
G4PhysicsTable* table = new G4PhysicsTable();
theHandler->UpdateTable(table, i);
table->resize(nmat);
for(std::size_t j=0; j<nmat; ++j) {
vec = (*table)[j];
if (nullptr == vec) {
if(i <= 2) {
vec = new G4PhysicsVector(aVector);
} else {
vec = new G4PhysicsVector(bVector);
}
G4PhysicsTableHelper::SetPhysicsVector(table, j, vec);
}
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4NeutronGeneralProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
{
if(1 < verboseLevel) {
G4cout << "### G4NeutronGeneralProcess::BuildPhysicsTable() for "
<< GetProcessName()
<< " and particle " << part.GetParticleName()
<< G4endl;
}
fElastic->BuildPhysicsTable(part);
fInelastic->BuildPhysicsTable(part);
fCapture->BuildPhysicsTable(part);
fCaptureXS->BuildPhysicsTable(part);
if(isMaster) {
std::size_t nmat = G4Material::GetNumberOfMaterials();
G4MaterialTable* matTable = G4Material::GetMaterialTable();
auto tables = theHandler->GetTables();
G4double sigEl(0.), sigInel(0.), sigCap(0.), val(0.), sum(0.);
for(std::size_t i=0; i<nmat; ++i) {
const G4Material* mat = (*matTable)[i];
// energy interval 0
std::size_t nn = (*(tables[0]))[i]->GetVectorLength();
if(1 < verboseLevel) {
G4cout << "======= Zone 0 ======= N= " << nn
<< " for " << mat->GetName() << G4endl;
}
for(std::size_t j=0; j<nn; ++j) {
G4double e = (*(tables[0]))[i]->Energy(j);
G4double loge = G4Log(e);
sigEl = fXSFactorEl*ComputeCrossSection(fElasticXS, mat, e, loge);
sigInel = fXSFactorInel*ComputeCrossSection(fInelasticXS, mat, e, loge);
sigCap = ComputeCrossSection(fCaptureXS, mat, e, loge);
sum = sigEl + sigInel + sigCap;
if(1 < verboseLevel) {
G4cout << j << ". E= " << e << " xs=" << sum << " sigEl=" << sigEl
<< " sigInel=" << sigInel << " sigCap=" << sigCap << G4endl;
}
(*(tables[0]))[i]->PutValue(j, sum);
val = sigEl/sum;
(*(tables[1]))[i]->PutValue(j, val);
val = (sigEl + sigInel)/sum;
(*(tables[2]))[i]->PutValue(j, val);
}
// energy interval 1
nn = (*(tables[3]))[0]->GetVectorLength();
if(1 < verboseLevel) {
G4cout << "======= Zone 1 ======= N= " << nn << G4endl;
}
for(std::size_t j=0; j<nn; ++j) {
G4double e = (*(tables[3]))[i]->Energy(j);
G4double loge = G4Log(e);
sigEl = fXSFactorEl*ComputeCrossSection(fElasticXS, mat, e, loge);
sigInel = fXSFactorInel*ComputeCrossSection(fInelasticXS, mat, e, loge);
sum = sigEl + sigInel;
if(1 < verboseLevel) {
G4cout << j << ". E= " << e << " xs=" << sum << " sigEl=" << sigEl
<< " sigInel=" << sigInel << " factInel=" << fXSFactorInel
<< G4endl;
}
(*(tables[3]))[i]->PutValue(j, sum);
val = sigInel/sum;
(*(tables[4]))[i]->PutValue(j, val);
}
}
}
if(1 < verboseLevel) {
G4cout << "### G4VEmProcess::BuildPhysicsTable() done for "
<< GetProcessName()
<< " and particle " << part.GetParticleName()
<< G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4NeutronGeneralProcess::ComputeCrossSection(G4VCrossSectionDataSet* xs,
const G4Material* mat,
G4double e, G4double loge)
{
const G4double* natom = mat->GetVecNbOfAtomsPerVolume();
G4int nelm = (G4int)mat->GetNumberOfElements();
G4double sig = 0.0;
for(G4int i=0; i<nelm; ++i) {
sig += natom[i]*xs->ComputeCrossSectionPerElement(e, loge, fNeutron,
mat->GetElement(i), mat);
}
return sig;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4NeutronGeneralProcess::StartTracking(G4Track*)
{
theNumberOfInteractionLengthLeft = -1.0;
fCurrMat = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4NeutronGeneralProcess::PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition)
{
*condition = NotForced;
// time limit
if(track.GetGlobalTime() >= fTimeLimit) {
fLambda = 0.0;
return 0.0;
}
// recompute total cross section if needed
CurrentCrossSection(track);
if (theNumberOfInteractionLengthLeft < 0.0) {
// beggining of tracking (or just after DoIt of this process)
theNumberOfInteractionLengthLeft = -G4Log( G4UniformRand() );
theInitialNumberOfInteractionLength = theNumberOfInteractionLengthLeft;
} else {
theNumberOfInteractionLengthLeft -=
previousStepSize/currentInteractionLength;
theNumberOfInteractionLengthLeft =
std::max(theNumberOfInteractionLengthLeft, 0.0);
}
G4double x = theNumberOfInteractionLengthLeft * currentInteractionLength;
/*
G4cout << "PostStepGetPhysicalInteractionLength: e= " << energy
<< " idxe= " << idxEnergy << " xs= " << fLambda
<< " x= " << x << G4endl;
*/
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange* G4NeutronGeneralProcess::PostStepDoIt(const G4Track& track,
const G4Step& step)
{
fSelectedProc = nullptr;
// time limit
if(0.0 == fLambda) {
theTotalResult->Initialize(track);
theTotalResult->ProposeTrackStatus(fStopAndKill);
return theTotalResult;
}
// In all cases clear number of interaction lengths
theNumberOfInteractionLengthLeft = -1.0;
G4double q = G4UniformRand();
/*
G4cout << "PostStep: preStepLambda= " << fLambda << " idxE= " << idxEnergy
<< " matIndex=" << matIndex << G4endl;
*/
if (0 == idxEnergy) {
if(q <= GetProbability(1)) {
SelectedProcess(step, fElastic, fElasticXS);
} else if(q <= GetProbability(2)) {
SelectedProcess(step, fInelastic, fInelasticXS);
} else {
SelectedProcess(step, fCapture, fCaptureXS);
}
} else {
if(q <= GetProbability(4)) {
SelectedProcess(step, fInelastic, fInelasticXS);
} else {
SelectedProcess(step, fElastic, fElasticXS);
}
}
const G4Element* elm = fCurrMat->GetElement(0);
G4int nelm = (G4int)fCurrMat->GetNumberOfElements();
if(1 < nelm) {
auto natom = fCurrMat->GetVecNbOfAtomsPerVolume();
G4double sig = 0.0;
for(G4int i=0; i<nelm; ++i) {
sig += natom[i] *
fXS->ComputeCrossSectionPerElement(fCurrE, fCurrLogE, fNeutron,
fCurrMat->GetElement(i),
fCurrMat);
fXsec[i] = sig;
}
sig *= G4UniformRand();
for(G4int i=0; i<nelm; ++i) {
if(fXsec[i] >= sig) {
elm = fCurrMat->GetElement(i);
break;
}
}
}
fSelectedProc->GetCrossSectionDataStore()->SetForcedElement(elm);
const G4Isotope* iso = fXS->SelectIsotope(elm, fCurrE, fCurrLogE);
fSelectedProc->GetTargetNucleusPointer()->SetIsotope(iso);
/*
G4cout << "## neutron E(MeV)=" << fCurrE << " "
<< fSelectedProc->GetProcessName()
<< " on Z=" << iso->GetZ() << " A=" << iso->GetN()
<< " time(ns)=" << track.GetGlobalTime()/ns << G4endl;
*/
// sample secondaries
return fSelectedProc->PostStepDoIt(track, step);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool
G4NeutronGeneralProcess::StorePhysicsTable(const G4ParticleDefinition* part,
const G4String& directory,
G4bool ascii)
{
G4bool yes = true;
if(!isMaster) { return yes; }
for(std::size_t i=0; i<nTables; ++i) {
G4String nam = (0==i || 3==i)
? "LambdaNeutronGeneral" + nameT[i] : "ProbNeutronGeneral" + nameT[i];
G4String fnam = GetPhysicsTableFileName(part, directory, nam, ascii);
auto table = theHandler->Table(i);
if(nullptr == table || !table->StorePhysicsTable(fnam, ascii)) {
yes = false;
}
}
return yes;
}
//....Ooooo0ooooo ........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4NeutronGeneralProcess::GetMeanFreePath(const G4Track& track,
G4double,
G4ForceCondition* condition)
{
*condition = NotForced;
// recompute total cross section if needed
CurrentCrossSection(track);
return currentInteractionLength;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4NeutronGeneralProcess::ProcessDescription(std::ostream& out) const
{
fElastic->ProcessDescription(out);
fInelastic->ProcessDescription(out);
fCapture->ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4String& G4NeutronGeneralProcess::GetSubProcessName() const
{
return (fSelectedProc) ? fSelectedProc->GetProcessName()
: G4VProcess::GetProcessName();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4int G4NeutronGeneralProcess::GetSubProcessSubType() const
{
return (fSelectedProc) ? fSelectedProc->GetProcessSubType() : 16;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4VProcess* G4NeutronGeneralProcess::GetCreatorProcess() const
{
return fSelectedProc;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -0,0 +1,414 @@
//
// ********************************************************************
// * 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 Hadron Inelastic Scattering Process
//
// Created from G4MuNeutrinoNucleusProcess
//
#include <iostream>
#include <typeinfo>
#include "G4TauNeutrinoNucleusProcess.hh"
#include "G4SystemOfUnits.hh"
#include "G4Nucleus.hh"
#include "G4ProcessManager.hh"
#include "G4CrossSectionDataStore.hh"
#include "G4ProductionCutsTable.hh"
#include "G4HadronicException.hh"
#include "G4HadronicInteraction.hh"
#include "G4VCrossSectionRatio.hh"
#include "G4VDiscreteProcess.hh"
#include "G4TauNeutrinoNucleusTotXsc.hh"
//#include "G4NuMuNucleusCcModel.hh"
//#include "G4NuMuNucleusNcModel.hh"
#include "G4RotationMatrix.hh"
#include "G4ThreeVector.hh"
#include "G4AffineTransform.hh"
#include "G4DynamicParticle.hh"
#include "G4StepPoint.hh"
#include "G4VSolid.hh"
#include "G4LogicalVolume.hh"
#include "G4SafetyHelper.hh"
#include "G4TransportationManager.hh"
///////////////////////////////////////////////////////////////////////////////
G4TauNeutrinoNucleusProcess::G4TauNeutrinoNucleusProcess( G4String anEnvelopeName, const G4String& pName)
: G4HadronicProcess( pName, fHadronInelastic ), isInitialised(false), fBiased(true) // fHadronElastic???
{
lowestEnergy = 1.*keV;
fEnvelope = nullptr;
fEnvelopeName = anEnvelopeName;
fTotXsc = nullptr; // new G4TauNeutrinoNucleusTotXsc();
fNuNuclCcBias=1.;
fNuNuclNcBias=1.;
fNuNuclTotXscBias=1.;
safetyHelper = G4TransportationManager::GetTransportationManager()->GetSafetyHelper();
safetyHelper->InitialiseHelper();
}
G4TauNeutrinoNucleusProcess::~G4TauNeutrinoNucleusProcess()
{
if( fTotXsc ) delete fTotXsc;
}
///////////////////////////////////////////////////////
void G4TauNeutrinoNucleusProcess::SetBiasingFactor(G4double bf)
{
fNuNuclTotXscBias = bf;
fTotXsc = new G4TauNeutrinoNucleusTotXsc();
fTotXsc->SetBiasingFactor(bf);
}
///////////////////////////////////////////////////////
void G4TauNeutrinoNucleusProcess::SetBiasingFactors(G4double bfCc, G4double bfNc)
{
fNuNuclCcBias = bfCc;
fNuNuclNcBias = bfNc;
fTotXsc = new G4TauNeutrinoNucleusTotXsc();
// fTotXsc->SetBiasingFactors(bfCc, bfNc);
}
//////////////////////////////////////////////////
G4double G4TauNeutrinoNucleusProcess::
GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)
{
//G4cout << "GetMeanFreePath " << aTrack.GetDefinition()->GetParticleName()
// << " Ekin= " << aTrack.GetKineticEnergy() << G4endl;
G4String rName = aTrack.GetStep()->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetRegion()->GetName();
G4double totxsc(0.);
if( rName == fEnvelopeName && fNuNuclTotXscBias > 1.)
{
totxsc = fNuNuclTotXscBias*
GetCrossSectionDataStore()->ComputeCrossSection(aTrack.GetDynamicParticle(),
aTrack.GetMaterial());
}
else
{
totxsc = GetCrossSectionDataStore()->ComputeCrossSection(aTrack.GetDynamicParticle(),
aTrack.GetMaterial());
}
G4double res = (totxsc>0.0) ? 1.0/totxsc : DBL_MAX;
//G4cout << " xsection= " << totxsc << G4endl;
return res;
}
///////////////////////////////////////////////////
void G4TauNeutrinoNucleusProcess::ProcessDescription(std::ostream& outFile) const
{
outFile << "G4TauNeutrinoNucleusProcess handles the inelastic scattering of \n"
<< "tau-neutrino on nucleus by invoking the following model(s) and \n"
<< "cross section(s).\n";
}
///////////////////////////////////////////////////////////////////////
G4VParticleChange*
G4TauNeutrinoNucleusProcess::PostStepDoIt(const G4Track& track, const G4Step& step)
{
// track.GetVolume()->GetLogicalVolume()->GetName()
// if( track.GetVolume()->GetLogicalVolume() != fEnvelope )
G4String rName = track.GetStep()->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetRegion()->GetName();
if( rName != fEnvelopeName )
{
if( verboseLevel > 0 )
{
G4cout<<"Go out from G4TauNeutrinoNucleusProcess::PostStepDoIt: wrong volume "<<G4endl;
}
return G4VDiscreteProcess::PostStepDoIt( track, step );
}
theTotalResult->Clear();
theTotalResult->Initialize(track);
G4double weight = track.GetWeight();
theTotalResult->ProposeWeight(weight);
if( track.GetTrackStatus() != fAlive )
{
return theTotalResult;
}
// Next check for illegal track status
//
if (track.GetTrackStatus() != fAlive &&
track.GetTrackStatus() != fSuspend)
{
if (track.GetTrackStatus() == fStopAndKill ||
track.GetTrackStatus() == fKillTrackAndSecondaries ||
track.GetTrackStatus() == fPostponeToNextEvent)
{
G4ExceptionDescription ed;
ed << "G4TauNeutrinoNucleusProcess: track in unusable state - "
<< track.GetTrackStatus() << G4endl;
ed << "G4TauNeutrinoNucleusProcess: returning unchanged track " << G4endl;
DumpState(track,"PostStepDoIt",ed);
G4Exception("G4TauNeutrinoNucleusProcess::PostStepDoIt", "had004", JustWarning, ed);
}
// No warning for fStopButAlive which is a legal status here
return theTotalResult;
}
// For elastic scattering, _any_ result is considered an interaction
ClearNumberOfInteractionLengthLeft();
G4double kineticEnergy = track.GetKineticEnergy();
const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
const G4ParticleDefinition* part = dynParticle->GetDefinition();
const G4String pName = part->GetParticleName();
// NOTE: Very low energy scatters were causing numerical (FPE) errors
// in earlier releases; these limits have not been changed since.
if ( kineticEnergy <= lowestEnergy ) return theTotalResult;
const G4Material* material = track.GetMaterial();
G4Nucleus* targNucleus = GetTargetNucleusPointer();
//////////////// uniform random spread of the neutrino interaction point ////////////
const G4StepPoint* pPostStepPoint = step.GetPostStepPoint();
const G4DynamicParticle* aParticle = track.GetDynamicParticle();
G4ThreeVector position = pPostStepPoint->GetPosition(), newPosition=position;
G4ParticleMomentum direction = aParticle->GetMomentumDirection();
if( fNuNuclCcBias > 1.0 || fNuNuclNcBias > 1.0) // = true, if fBiasingfactor != 1., i.e. xsc is biased
{
const G4RotationMatrix* rotM = pPostStepPoint->GetTouchable()->GetRotation();
G4ThreeVector transl = pPostStepPoint->GetTouchable()->GetTranslation();
G4AffineTransform transform = G4AffineTransform(rotM,transl);
transform.Invert();
G4ThreeVector localP = transform.TransformPoint(position);
G4ThreeVector localV = transform.TransformAxis(direction);
G4double forward = track.GetVolume()->GetLogicalVolume()->GetSolid()->DistanceToOut(localP, localV);
G4double backward = track.GetVolume()->GetLogicalVolume()->GetSolid()->DistanceToOut(localP, -localV);
G4double distance = forward+backward;
// G4cout<<distance/cm<<", ";
// uniform sampling of nu-e interaction point
// along neutrino direction in current volume
G4double range = -backward+G4UniformRand()*distance;
newPosition = position + range*direction;
safetyHelper->ReLocateWithinVolume(newPosition);
theTotalResult->ProposePosition(newPosition); // G4Exception : GeomNav1002
}
G4HadProjectile theProj( track );
G4HadronicInteraction* hadi = nullptr;
G4HadFinalState* result = nullptr;
G4double ccTotRatio = fTotXsc->GetCcTotRatio();
if( G4UniformRand() < ccTotRatio ) // Cc-model
{
// Initialize the hadronic projectile from the track
thePro.Initialise(track);
if (pName == "nu_tau" ) hadi = (GetHadronicInteractionList())[0];
else hadi = (GetHadronicInteractionList())[2];
result = hadi->ApplyYourself( thePro, *targNucleus);
result->SetTrafoToLab(thePro.GetTrafoToLab());
ClearNumberOfInteractionLengthLeft();
FillResult(result, track);
}
else // Nc-model
{
if (pName == "nu_tau" ) hadi = (GetHadronicInteractionList())[1];
else hadi = (GetHadronicInteractionList())[3];
size_t idx = track.GetMaterialCutsCouple()->GetIndex();
G4double tcut = (*(G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsVector(3)))[idx];
hadi->SetRecoilEnergyThreshold(tcut);
if( verboseLevel > 1 )
{
G4cout << "G4TauNeutrinoNucleusProcess::PostStepDoIt for "
<< part->GetParticleName()
<< " in " << material->GetName()
<< " Target Z= " << targNucleus->GetZ_asInt()
<< " A= " << targNucleus->GetA_asInt() << G4endl;
}
try
{
result = hadi->ApplyYourself( theProj, *targNucleus);
}
catch(G4HadronicException & aR)
{
G4ExceptionDescription ed;
aR.Report(ed);
ed << "Call for " << hadi->GetModelName() << G4endl;
ed << " Z= "
<< targNucleus->GetZ_asInt()
<< " A= " << targNucleus->GetA_asInt() << G4endl;
DumpState(track,"ApplyYourself",ed);
ed << " ApplyYourself failed" << G4endl;
G4Exception("G4TauNeutrinoNucleusProcess::PostStepDoIt", "had006",
FatalException, ed);
}
// directions
G4ThreeVector indir = track.GetMomentumDirection();
G4double phi = CLHEP::twopi*G4UniformRand();
G4ThreeVector it(0., 0., 1.);
G4ThreeVector outdir = result->GetMomentumChange();
if(verboseLevel>1)
{
G4cout << "Efin= " << result->GetEnergyChange()
<< " de= " << result->GetLocalEnergyDeposit()
<< " nsec= " << result->GetNumberOfSecondaries()
<< " dir= " << outdir
<< G4endl;
}
// energies
G4double edep = result->GetLocalEnergyDeposit();
G4double efinal = result->GetEnergyChange();
if(efinal < 0.0) { efinal = 0.0; }
if(edep < 0.0) { edep = 0.0; }
// NOTE: Very low energy scatters were causing numerical (FPE) errors
// in earlier releases; these limits have not been changed since.
if(efinal <= lowestEnergy)
{
edep += efinal;
efinal = 0.0;
}
// primary change
theTotalResult->ProposeEnergy(efinal);
G4TrackStatus status = track.GetTrackStatus();
if(efinal > 0.0)
{
outdir.rotate(phi, it);
outdir.rotateUz(indir);
theTotalResult->ProposeMomentumDirection(outdir);
}
else
{
if( part->GetProcessManager()->GetAtRestProcessVector()->size() > 0)
{
status = fStopButAlive;
}
else
{
status = fStopAndKill;
}
theTotalResult->ProposeTrackStatus(status);
}
//G4cout << "Efinal= " << efinal << " TrackStatus= " << status << G4endl;
theTotalResult->SetNumberOfSecondaries(0);
// recoil
if( result->GetNumberOfSecondaries() > 0 )
{
G4DynamicParticle* p = result->GetSecondary(0)->GetParticle();
if(p->GetKineticEnergy() > tcut)
{
theTotalResult->SetNumberOfSecondaries(1);
G4ThreeVector pdir = p->GetMomentumDirection();
// G4cout << "recoil " << pdir << G4endl;
//!! is not needed for models inheriting G4TauNeutrinoNucleus
pdir.rotate(phi, it);
pdir.rotateUz(indir);
// G4cout << "recoil rotated " << pdir << G4endl;
p->SetMomentumDirection(pdir);
// in elastic scattering time and weight are not changed
G4Track* t = new G4Track(p, track.GetGlobalTime(),
track.GetPosition());
t->SetWeight(weight);
t->SetTouchableHandle(track.GetTouchableHandle());
theTotalResult->AddSecondary(t);
}
else
{
edep += p->GetKineticEnergy();
delete p;
}
}
theTotalResult->ProposeLocalEnergyDeposit(edep);
theTotalResult->ProposeNonIonizingEnergyDeposit(edep);
result->Clear();
}
return theTotalResult;
}
void
G4TauNeutrinoNucleusProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
{
if(!isInitialised) {
isInitialised = true;
// if(G4Neutron::Neutron() == &part) { lowestEnergy = 1.e-6*eV; }
}
G4HadronicProcess::PreparePhysicsTable(part);
}
void
G4TauNeutrinoNucleusProcess::SetLowestEnergy(G4double val)
{
lowestEnergy = val;
}