Import Geant4 10.7.0 source tree

This commit is contained in:
Gabriele Cosmo
2020-12-04 12:30:43 +01:00
parent 67ba86d073
commit dab42d2018
3770 changed files with 226369 additions and 286486 deletions
@@ -15,6 +15,46 @@ committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
17.11.2020 V.Ivanchenko, emlowen-V10-06-13
- G4MicroElecInelasticModel_new, G4MicroElecInelastic_new,
G4MicroElecSurface - fixed Coverity warnings (non-initialized
class members or dereferences)
26.10.2020 V.Ivanchenko, emlowen-V10-06-12
- removed obsolete G4MuElec* classes
- Added new classes developed by ONERA and CEA group and provided
by D. Lambert: G4MicroElecElasticModel_new,
G4MicroElecInelasticModel_new, G4MicroElecInelastic_new,
G4MicroElecLOPhononModel, G4MicroElecLOPhononModel.
G4MicroElecSiStructure is moved to material category
- G4MicroElecSurface - new boundary process for e- The code is
updated compared with the original: instead of name comparisons
pointers are compared; condition on surface is defined by kCarTolerance;
initialisation is done in the new BuildPhysicsTable(..) method
instead of Initialise(); no dependence on G4Electron; changed
process type and sub-types from optical to electromagnetic.
15.10.2020 L. Pandola, emlowen-V10-06-11
- Fix Coverity defects and material list in G4PenelopeRayleighModelMI
12.10.2020 L. Pandola, emlowen-V10-06-10
- replace std::log with G4Log in Penelope and Livermore models
- use GetZasInt() in Penelope models, when applicable
- fix typo in material name in G4PenelopeRayleighModelMI
07.10.2020 L. Pandola, emlowen-V10-06-09
- finalize G4PenelopeRayleighModelMI model of emlowen-V10-06-08:
make it compatible with Unit Tests, revise verbosity
24.09.2020 G. Paternò, L. Pandola, emlowen-V10-06-08
- added G4PenelopeRayleighModelMI model and ancillary class G4MIData
(provided by G. Paternò, INFN Ferrara)
- create tests/CMakeLists.txt for Unit Tests and reshape Unit Test
G4PenelopeRayleighTest.cc
04.09.2020 M. Omer, R. Hajima, L. Pandola, emlowen-V10-06-07
- Added protections in G4JAEAPolarizedElasticScatteringModel.cc
11.06.2020 Z. Li, emlowen-V10-06-06
- Add InitialiseForElement() in G4LivermoreGammaConversionModel
and G4LivermoreGammaConversion5DModel, which was missing before
@@ -1608,7 +1648,7 @@ M. Omer and R. Hajima
25.06.2009, A. Mantero, tag emlowen-V09-02-40
Design update, Bug Fixes and models update for
atomic shell hadronic CS calulation.
atomic shell hadronic CS calculation.
02.06.2009, A.Lechner, tag emlowen-V09-02-39
Bug fix in class G4IonDEDXScalingICRU73: Compilation
@@ -98,7 +98,7 @@ public:
// Given the atomic number and the vacancy intial shell index returns
// Given the atomic number and the vacancy initial shell index returns
// the AugerTransition object related to that shell
G4AugerTransition* GetAugerTransition(G4int Z, G4int vacancyShellIndex);
@@ -28,7 +28,7 @@
// 30 October 2008
// on base of G4LowEnergyPhotoElectric developed by A.Forti and M.G.Pia
//
// 15 Mar 2010 L. Pandola, removed methods to set explicitely fluorescence cuts.
// 15 Mar 2010 L. Pandola, removed methods to set explicitly fluorescence cuts.
// Main cuts from G4ProductionCutsTable are always used
// 30 May 2011 A Mantero & V Ivanchenko Migration to model design for deexcitation
// 22 Oct 2012 A & V Ivanchenko Migration data structure to G4PhysicsVector
@@ -28,7 +28,7 @@
// 30 October 2008
// on base of G4LowEnergyPhotoElectric developed by A.Forti and M.G.Pia
//
// 15 Mar 2010 L. Pandola, removed methods to set explicitely fluorescence cuts.
// 15 Mar 2010 L. Pandola, removed methods to set explicitly fluorescence cuts.
// Main cuts from G4ProductionCutsTable are always used
// 30 May 2011 A Mantero & V Ivanchenko Migration to model design for deexcitation
// 22 Oct 2012 A & V Ivanchenko Migration data structure to G4PhysicsVector
@@ -23,50 +23,51 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// gpaterno, March 2019
//
// G4MuElecElastic.hh, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66 - 73, 2012.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#ifndef G4MuElecElastic_h
#define G4MuElecElastic_h 1
#ifndef G4MIData_h
#define G4MIData_h 1
#include "G4VEmProcess.hh"
#include "G4Electron.hh"
// Available models
#include "G4MuElecElasticModel.hh"
#include "globals.hh"
#include "G4VMaterialExtension.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4MuElecElastic : public G4VEmProcess
class G4MIData : public G4VMaterialExtension {
{
public:
G4MuElecElastic(const G4String& processName ="MuElecElastic",
G4ProcessType type = fElectromagnetic);
virtual ~G4MuElecElastic();
virtual G4bool IsApplicable(const G4ParticleDefinition&);
public:
G4MIData(const G4String&);
virtual ~G4MIData();
public:
void Print() const override
{G4cout << "Molecular Interference data for Rayleigh scattering" << G4endl;};
void SetFilenameFF(const G4String& filenameff) {fFilenameFF = filenameff;};
void SetFilenameCS(const G4String& filenamecs) {fFilenameCS = filenamecs;};
void SetMolWeight(const G4double mw) {fMolWeight = mw;};
public:
const G4String& GetFilenameFF() {return fFilenameFF;};
const G4String& GetFilenameCS() {return fFilenameCS;};
const G4double& GetMolWeight() {return fMolWeight;};
virtual void PrintInfo();
protected:
virtual void InitialiseProcess(const G4ParticleDefinition*);
private:
G4bool isInitialised;
G4String fFilenameFF;
G4String fFilenameCS;
G4double fMolWeight;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -27,90 +27,65 @@
// Based on G4DNACrossSectionDataSet
//
#ifndef G4MUELECCROSSSECTIONDATASET_HH
#define G4MUELECCROSSSECTIONDATASET_HH 1
#ifndef G4MICROELECCROSSSECTIONDATASET_HH
#define G4MICROELECCROSSSECTIONDATASET_HH 1
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4ShellEMDataSet.hh"
class G4MuElecCrossSectionDataSet : public G4VEMDataSet
class G4MicroElecCrossSectionDataSet_new : public G4VEMDataSet
{
public:
G4MuElecCrossSectionDataSet(G4VDataSetAlgorithm* algo,
G4MicroElecCrossSectionDataSet_new(G4VDataSetAlgorithm* algo,
G4double xUnit=CLHEP::MeV,
G4double dataUnit=CLHEP::barn);
~G4MicroElecCrossSectionDataSet_new() override;
virtual ~G4MuElecCrossSectionDataSet();
virtual G4double FindValue(G4double e, G4int componentId=0) const;
virtual void PrintData(void) const;
virtual const G4VEMDataSet* GetComponent(G4int componentId) const
{ return components[componentId]; }
virtual void AddComponent(G4VEMDataSet* dataSet)
{ components.push_back(dataSet); }
virtual size_t NumberOfComponents(void) const
{ return components.size(); }
virtual const G4DataVector& GetEnergies(G4int componentId) const
{ return GetComponent(componentId)->GetEnergies(0); }
virtual const G4DataVector& GetData(G4int componentId) const
{ return GetComponent(componentId)->GetData(0); }
virtual const G4DataVector& GetLogEnergies(G4int componentId) const
{ return GetComponent(componentId)->GetLogEnergies(0); }
virtual const G4DataVector& GetLogData(G4int componentId) const
{ return GetComponent(componentId)->GetLogData(0); }
virtual void SetEnergiesData(G4DataVector* x, G4DataVector* values, G4int componentId);
virtual void SetLogEnergiesData(G4DataVector* x,
G4DataVector* values,
G4DataVector* log_x,
G4DataVector* log_values,
G4int componentId);
virtual G4bool LoadData(const G4String & argFileName);
virtual G4bool LoadNonLogData(const G4String & argFileName);
virtual G4bool SaveData(const G4String & argFileName) const;
virtual G4double RandomSelect(G4int /*componentId */) const { return -1.; };
// void CleanUpComponents();
G4double FindValue(G4double e, G4int componentId=0) const override;
G4double FindShellValue(G4double argEnergy, G4int shell) const;
void PrintData(void) const override;
const G4VEMDataSet* GetComponent(G4int componentId) const override
{ return components[componentId]; }
void AddComponent(G4VEMDataSet* dataSet) override
{ components.push_back(dataSet); }
size_t NumberOfComponents(void) const override
{ return components.size(); }
const G4DataVector& GetEnergies(G4int componentId) const override
{ return GetComponent(componentId)->GetEnergies(0); }
const G4DataVector& GetData(G4int componentId) const override
{ return GetComponent(componentId)->GetData(0); }
const G4DataVector& GetLogEnergies(G4int componentId) const override
{ return GetComponent(componentId)->GetLogEnergies(0); }
const G4DataVector& GetLogData(G4int componentId) const override
{ return GetComponent(componentId)->GetLogData(0); }
void SetEnergiesData(G4DataVector* x, G4DataVector* values, G4int componentId) override;
void SetLogEnergiesData(G4DataVector* x,
G4DataVector* values,
G4DataVector* log_x,
G4DataVector* log_values,
G4int componentId) override;
G4bool LoadData(const G4String & argFileName) override;
G4bool LoadNonLogData(const G4String & argFileName) override;
G4bool SaveData(const G4String & argFileName) const override;
G4double RandomSelect(G4int /*componentId */) const override
{ return -1.; };
private:
G4MicroElecCrossSectionDataSet_new();
G4MicroElecCrossSectionDataSet_new(const G4MicroElecCrossSectionDataSet_new & copy);
G4MicroElecCrossSectionDataSet_new& operator=(const G4MicroElecCrossSectionDataSet_new & right);
G4String FullFileName(const G4String & argFileName) const;
// Hide copy constructor and assignment operator
G4MuElecCrossSectionDataSet();
G4MuElecCrossSectionDataSet(const G4MuElecCrossSectionDataSet & copy);
G4MuElecCrossSectionDataSet& operator=(const G4MuElecCrossSectionDataSet & right);
std::vector<G4VEMDataSet*> components; // Owned pointers
G4int z;
G4VDataSetAlgorithm* algorithm; // Owned pointer
G4double unitEnergies;
G4double unitData;
G4double GetUnitEnergies() const { return unitEnergies; }
G4double GetUnitData() const { return unitData; }
const G4VDataSetAlgorithm* GetAlgorithm() const { return algorithm; }
void CleanUpComponents(void);
std::vector<G4VEMDataSet*> components; // Owned pointers
G4int z;
G4VDataSetAlgorithm* algorithm; // Owned pointer
G4double unitEnergies;
G4double unitData;
};
#endif /* G4MuElecCrossSectionDataSet_HH */
#endif
@@ -0,0 +1,190 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecElasticModel_new.hh, 2011/08/29 A.Valentin, M. Raine are with CEA [a]
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
// - A.Valentin, M. Raine,
// Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with the Geant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// https://doi.org/10.1109/NSSMIC.2010.5873720
//
// - A.Valentin, M. Raine, M.Gaillardin, P.Paillet
// Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Silicon,
// https://doi.org/10.1016/j.nimb.2012.06.007
// NIM B, vol. 288, pp. 66-73, 2012, part A
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012, part B
// https://doi.org/10.1016/j.nimb.2012.07.028
//
// - M. Raine, M. Gaillardin, P. Paillet
// Geant4 physics processes for silicon microdosimetry simulation:
// Improvements and extension of the energy-range validity up to 10 GeV/nucleon
// NIM B, vol. 325, pp. 97-100, 2014
// https://doi.org/10.1016/j.nimb.2014.01.014
//
// - J. Pierron, C. Inguimbert, M. Belhaj, T. Gineste, J. Puech, M. Raine
// Electron emission yield for low energy electrons:
// Monte Carlo simulation and experimental comparison for Al, Ag, and Si
// Journal of Applied Physics 121 (2017) 215107.
// https://doi.org/10.1063/1.4984761
//
// - P. Caron,
// Study of Electron-Induced Single-Event Upset in Integrated Memory Devices
// PHD, 16th October 2019
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MICROELECELASTICMODEL_HH
#define G4MICROELECELASTICMODEL_HH 1
#include <map>
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4MicroElecMaterialStructure.hh"
#include "G4MicroElecCrossSectionDataSet_new.hh"
#include "G4VEmModel.hh"
#include "G4Electron.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4LogLogInterpolation.hh"
#include "G4ProductionCutsTable.hh"
#include "G4NistManager.hh"
class G4MicroElecElasticModel_new : public G4VEmModel
{
public:
G4MicroElecElasticModel_new(const G4ParticleDefinition* p = 0,
const G4String& nam = "MicroElecElasticModel");
~G4MicroElecElasticModel_new() override;
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
G4double CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double emin,
G4double emax) override;
G4double AcousticCrossSectionPerVolume(G4double ekin, G4double kbz, G4double rho,
G4double cs, G4double Aac, G4double Eac,
G4double prefactor);
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
void SetKillBelowThreshold (G4double threshold);
G4double GetKillBelowThreshold () { return killBelowEnergy; }
G4double DamageEnergy(G4double T,G4double A, G4double Z);
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma;
private:
G4MicroElecElasticModel_new & operator=(const G4MicroElecElasticModel_new &right);
G4MicroElecElasticModel_new(const G4MicroElecElasticModel_new&);
// Final state
G4double Theta(G4ParticleDefinition * aParticleDefinition, G4double k, G4double integrDiff);
G4double LinLinInterpolate(G4double e1, G4double e2, G4double e, G4double xs1, G4double xs2);
G4double LogLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1, G4double xs2);
G4double LinLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1, G4double xs2);
G4double QuadInterpolator(G4double e11, G4double e12, G4double e21, G4double e22,
G4double x11, G4double x12, G4double x21, G4double x22,
G4double t1, G4double t2, G4double t, G4double e);
G4double RandomizeCosTheta(G4double k);
G4Material* nistSi = nullptr;
G4double killBelowEnergy;
G4double lowEnergyLimit;
G4double lowEnergyLimitOfModel;
G4double highEnergyLimit;
G4bool isInitialised;
G4int verboseLevel;
// Cross section
typedef std::map<G4String,G4String,std::less<G4String> > MapFile;
MapFile tableFile;
typedef std::map<G4String,G4MicroElecCrossSectionDataSet_new*,std::less<G4String> > MapData;
//MapData tableData;
typedef std::map<G4String, MapData*, std::less<G4String> > TCSMap;
TCSMap tableTCS;
//Maps for multilayers
typedef std::map<double, std::map<double, double> > TriDimensionMap;
typedef std::map<G4String, TriDimensionMap* > ThetaMap;
ThetaMap thetaDataStorage; //Storage of angles (cumulated)
typedef std::map<G4String, std::vector<double>* > energyMap;
energyMap eIncidentEnergyStorage;
typedef std::map<double, std::vector<double> > VecMap;
typedef std::map<G4String, VecMap* > ProbaMap;
ProbaMap eProbaStorage; //Storage of probabilities for cumulated sections
typedef std::map<G4String, G4MicroElecMaterialStructure*, std::less<G4String> > MapStructure;
MapStructure tableMaterialsStructures; //Structures of all materials simulated
G4MicroElecMaterialStructure* currentMaterialStructure = nullptr;
typedef std::map<G4String, G4double, std::less<G4String> > MapEnergy;
MapEnergy lowEnergyLimitTable;
MapEnergy highEnergyLimitTable;
MapEnergy workFunctionTable;
G4bool killElectron, acousticModelEnabled;
G4String currentMaterialName;
G4bool isOkToBeInitialised;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -0,0 +1,194 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecInelasticModel_new.hh, 2011/08/29 A.Valentin, M. Raine are with CEA [a]
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
// - A.Valentin, M. Raine,
// Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with the Geant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// https://doi.org/10.1109/NSSMIC.2010.5873720
//
// - A.Valentin, M. Raine, M.Gaillardin, P.Paillet
// Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Silicon,
// https://doi.org/10.1016/j.nimb.2012.06.007
// NIM B, vol. 288, pp. 66-73, 2012, part A
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012, part B
// https://doi.org/10.1016/j.nimb.2012.07.028
//
// - M. Raine, M. Gaillardin, P. Paillet
// Geant4 physics processes for silicon microdosimetry simulation:
// Improvements and extension of the energy-range validity up to 10 GeV/nucleon
// NIM B, vol. 325, pp. 97-100, 2014
// https://doi.org/10.1016/j.nimb.2014.01.014
//
// - J. Pierron, C. Inguimbert, M. Belhaj, T. Gineste, J. Puech, M. Raine
// Electron emission yield for low energy electrons:
// Monte Carlo simulation and experimental comparison for Al, Ag, and Si
// Journal of Applied Physics 121 (2017) 215107.
// https://doi.org/10.1063/1.4984761
//
// - P. Caron,
// Study of Electron-Induced Single-Event Upset in Integrated Memory Devices
// PHD, 16th October 2019
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MICROELECINELASTICMODEL_NEW_HH
#define G4MICROELECINELASTICMODEL_NEW_HH 1
#include "globals.hh"
#include "G4VEmModel.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4ProductionCutsTable.hh"
#include "G4MicroElecMaterialStructure.hh"
#include "G4MicroElecCrossSectionDataSet_new.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
#include "G4GenericIon.hh"
#include "G4ParticleDefinition.hh"
#include "G4LogLogInterpolation.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4NistManager.hh"
class G4MicroElecInelasticModel_new : public G4VEmModel
{
public:
G4MicroElecInelasticModel_new(const G4ParticleDefinition* p = 0,
const G4String& nam = "MicroElecInelasticModel");
~G4MicroElecInelasticModel_new() override;
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
G4double CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double emin,
G4double emax) override;
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
G4double DifferentialCrossSection(const G4ParticleDefinition * aParticleDefinition,
G4double k, G4double energyTransfer, G4int shell);
G4double ComputeRelativistVelocity(G4double E, G4double mass);
G4double ComputeElasticQmax(G4double T1i, G4double T2i, G4double m1, G4double m2);
G4double BKZ(G4double Ep, G4double mp, G4int Zp, G4double EF);
// compute the effective charge according Brandt et Kitagawa theory
G4double stepFunc(G4double x);
G4double vrkreussler(G4double v, G4double vF);
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
private:
//
// private methods
//
G4MicroElecInelasticModel_new & operator=(const G4MicroElecInelasticModel_new &right);
G4MicroElecInelasticModel_new(const G4MicroElecInelasticModel_new&);
G4int RandomSelect(G4double energy,const G4String& particle, G4double originalMass, G4int originalZ );
G4double RandomizeCreatedElectronEnergy(G4double secondaryKinetic);
G4double RandomizeEjectedElectronEnergy(const G4ParticleDefinition * aParticleDefinition,
G4double incomingParticleEnergy, G4int shell,
G4double originalMass, G4int originalZ) ;
G4double RandomizeEjectedElectronEnergyFromCumulatedDcs(const G4ParticleDefinition*,
G4double k, G4int shell);
G4double TransferedEnergy(const G4ParticleDefinition*, G4double k,
G4int ionizationLevelIndex, G4double random);
G4double Interpolate(G4double e1, G4double e2, G4double e, G4double xs1, G4double xs2);
G4double QuadInterpolator( G4double e11, G4double e12, G4double e21, G4double e22,
G4double x11, G4double x12, G4double x21, G4double x22,
G4double t1, G4double t2, G4double t, G4double e);
//
// private elements
//
G4String currentMaterial = "";
G4bool fasterCode = false;
//deexcitation manager to produce fluo photns and e-
G4VAtomDeexcitation* fAtomDeexcitation = nullptr;
G4Material* nistSi = nullptr;
std::map<G4String,G4double,std::less<G4String> > lowEnergyLimit;
std::map<G4String,G4double,std::less<G4String> > highEnergyLimit;
G4bool isInitialised = false;
G4int verboseLevel = 0;
typedef std::map<G4String,G4String,std::less<G4String> > MapFile;
typedef std::map<G4String,G4MicroElecCrossSectionDataSet_new*,std::less<G4String> > MapData;
typedef std::map<G4double, std::map<G4double, G4double> > TriDimensionMap;
typedef std::map<G4double, std::vector<G4double> > VecMap;
//Tables for multilayers
typedef std::map<G4String, MapData*, std::less<G4String> > TCSMap;
TCSMap tableTCS; //TCS tables by particle
typedef std::map<G4String, std::vector<TriDimensionMap>* > dataDiffCSMap;
dataDiffCSMap eDiffDatatable, pDiffDatatable; //Transfer probabilities (for slower code)
dataDiffCSMap eNrjTransStorage, pNrjTransStorage; //Transfered energies and corresponding probability (faster code)
typedef std::map<G4String, std::vector<VecMap>* > dataProbaShellMap;
dataProbaShellMap eProbaShellStorage, pProbaShellStorage; //Cumulated Transfer probabilities (faster code)
typedef std::map<G4String, std::vector<G4double>* > incidentEnergyMap;
incidentEnergyMap eIncidentEnergyStorage, pIncidentEnergyStorage; //Incident energies for interpolation (faster code)
typedef std::map<G4String, VecMap* > TranfEnergyMap;
TranfEnergyMap eVecmStorage, pVecmStorage; //Transfered energy for interpolation (slower code)
typedef std::map<G4String, G4MicroElecMaterialStructure*, std::less<G4String> > MapStructure;
MapStructure tableMaterialsStructures; //Structures of all materials simulated
G4MicroElecMaterialStructure* currentMaterialStructure = nullptr;
};
#endif
@@ -0,0 +1,105 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecInelastic_new.hh, 2011/08/29 A.Valentin, M. Raine are with CEA [a]
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
// - A.Valentin, M. Raine,
// Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with the Geant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// https://doi.org/10.1109/NSSMIC.2010.5873720
//
// - A.Valentin, M. Raine, M.Gaillardin, P.Paillet
// Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Silicon,
// https://doi.org/10.1016/j.nimb.2012.06.007
// NIM B, vol. 288, pp. 66-73, 2012, part A
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012, part B
// https://doi.org/10.1016/j.nimb.2012.07.028
//
// - M. Raine, M. Gaillardin, P. Paillet
// Geant4 physics processes for silicon microdosimetry simulation:
// Improvements and extension of the energy-range validity up to 10 GeV/nucleon
// NIM B, vol. 325, pp. 97-100, 2014
// https://doi.org/10.1016/j.nimb.2014.01.014
//
// - J. Pierron, C. Inguimbert, M. Belhaj, T. Gineste, J. Puech, M. Raine
// Electron emission yield for low energy electrons:
// Monte Carlo simulation and experimental comparison for Al, Ag, and Si
// Journal of Applied Physics 121 (2017) 215107.
// https://doi.org/10.1063/1.4984761
//
// - P. Caron,
// Study of Electron-Induced Single-Event Upset in Integrated Memory Devices
// PHD, 16th October 2019
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MICROELEINELASTIC_HH
#define G4MICROELEINELASTIC_HH 1
#include "G4VEmProcess.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
#include "G4GenericIon.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4MicroElecInelastic_new : public G4VEmProcess
{
public:
G4MicroElecInelastic_new(const G4String& processName ="MicroElecIonisation",
G4ProcessType type = fElectromagnetic);
~G4MicroElecInelastic_new() override;
G4bool IsApplicable(const G4ParticleDefinition&) override;
void PrintInfo() override;
protected:
void InitialiseProcess(const G4ParticleDefinition*) override;
private:
G4bool isInitialised = false;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,94 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecLOPhononModel.hh,
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MICROELECLOPHONONMODEL_HH
#define G4MICROELECLOPHONONMODEL_HH 1
#include "G4Step.hh"
#include "G4VDiscreteProcess.hh"
#include "G4DynamicParticle.hh"
#include "G4Material.hh"
#include "G4VEmModel.hh"
#include "G4Electron.hh"
#include "G4TransportationManager.hh"
#include "G4ParticleChangeForGamma.hh"
class G4MicroElecLOPhononModel : public G4VEmModel
{
public:
G4MicroElecLOPhononModel(const G4ParticleDefinition*p = 0,
const G4String& nam = "G4MicroElecLOPhononModel");
~G4MicroElecLOPhononModel() override;
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
G4double CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double emin,
G4double emax) override;
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma;
private:
G4bool Interband;
G4MicroElecLOPhononModel & operator=(const G4MicroElecLOPhononModel &right);
G4MicroElecLOPhononModel(const G4MicroElecLOPhononModel&);
G4bool isOkToBeInitialised;
G4bool isInitialised;
G4bool abs = false;
G4double Eprim = 0, signe = -1,phononEnergy=0;
};
#endif
@@ -24,58 +24,53 @@
// ********************************************************************
//
//
// G4MuElecInelastic.hh, 2011/08/29 A.Valentin, M. Raine
// G4MicroElecLOPhononModel.hh,
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
//
// - Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66-73, 2012.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for protons and
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012.
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MuElecInelastic_h
#define G4MuElecInelastic_h 1
#ifndef G4MICROELECLOPHONONSCATTERING_HH
#define G4MICROELECLOPHONONSCATTERING_HH 1
#include "G4VEmProcess.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
#include "G4GenericIon.hh"
// Available models
#include "G4MuElecInelasticModel.hh"
#include "G4MicroElecLOPhononModel.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4MuElecInelastic : public G4VEmProcess
class G4MicroElecLOPhononScattering : public G4VEmProcess
{
public:
G4MuElecInelastic(const G4String& processName ="MuElecIonisation",
G4ProcessType type = fElectromagnetic);
virtual ~G4MuElecInelastic();
virtual G4bool IsApplicable(const G4ParticleDefinition&);
public:
G4MicroElecLOPhononScattering(const G4String& processName = "LOPhononScattering",
G4ProcessType type = fElectromagnetic);
~G4MicroElecLOPhononScattering() override;
G4bool IsApplicable(const G4ParticleDefinition&) override;
void PrintInfo() override;
virtual void PrintInfo();
protected:
virtual void InitialiseProcess(const G4ParticleDefinition*);
void InitialiseProcess(const G4ParticleDefinition*) override;
private:
G4bool isInitialised;
G4bool isInitialised;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
#endif
@@ -1,73 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4MicroElecSiStructure.hh, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
//
// - Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66-73, 2012.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for protons and
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MICROELECSISTRUCTURE_HH
#define G4MICROELECSISTRUCTURE_HH 1
#include "globals.hh"
#include <vector>
class G4MicroElecSiStructure
{
public:
G4MicroElecSiStructure();
virtual ~G4MicroElecSiStructure();
G4double Energy(G4int level);
G4int NumberOfLevels() { return nLevels; }
private:
// Number of levels of silicon
G4int nLevels;
std::vector<G4double> energyConstant;
};
#endif
@@ -0,0 +1,143 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecSurface.hh,
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// D. Lambert is with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MicroElecSurface_h
#define G4MicroElecSurface_h 1
/////////////
// Includes
/////////////
#include "globals.hh"
#include "templates.hh"
#include "geomdefs.hh"
#include "Randomize.hh"
#include "G4ProductionCutsTable.hh"
#include "G4RandomTools.hh"
#include "G4RandomDirection.hh"
#include "G4MicroElecMaterialStructure.hh"
#include "G4Step.hh"
#include "G4VDiscreteProcess.hh"
#include "G4DynamicParticle.hh"
#include "G4Material.hh"
#include "G4LogicalBorderSurface.hh"
#include "G4LogicalSkinSurface.hh"
#include "G4TransportationManager.hh"
// Class Description:
// Discrete Process -- reflection/refraction at interfaces for electrons.
// Class inherits publicly from G4VDiscreteProcess.
// Class Description - End:
/////////////////////
// Class Definition
/////////////////////
enum G4MicroElecSurfaceStatus { UndefinedSurf,
NotAtBoundarySurf,
SameMaterialSurf,
StepTooSmallSurf };
class G4MicroElecSurface : public G4VDiscreteProcess
{
public:
G4MicroElecSurface(const G4String& processName = "MicroElecSurface",
G4ProcessType type = fElectromagnetic);
~G4MicroElecSurface() override;
G4bool IsApplicable(const G4ParticleDefinition& aParticleType) override;
// Returns true -> 'is applicable' only for an electron.
void SetFlagFranchissement();
G4double GetMeanFreePath(const G4Track& ,
G4double ,
G4ForceCondition* condition) override;
// Returns infinity; i. e. the process does not limit the step,
// but sets the 'Forced' condition for the DoIt to be invoked at
// every step. However, only at a boundary will any action be
// taken.
G4VParticleChange* PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep) override;
// This is the method implementing boundary processes.
void BuildPhysicsTable(const G4ParticleDefinition&) override;
// Initialisation
G4MicroElecSurfaceStatus GetStatus() const;
// Returns the current status.
G4MicroElecSurface(const G4MicroElecSurface &right) = delete;
G4MicroElecSurface& operator=(const G4MicroElecSurface &right) = delete;
private:
G4double GetIncidentAngle();
G4ThreeVector Reflexion(const G4StepPoint* PostStepPoint);
// private elements
typedef std::map<G4String, G4double, std::less<G4String> > WorkFunctionTable;
WorkFunctionTable tableWF; //Table of all materials simulated
G4double theParticleMomentum;
G4ThreeVector oldMomentum, previousMomentum;
G4ThreeVector theGlobalNormal;
G4ThreeVector theFacetNormal;
G4Material* material1;
G4Material* material2;
G4MicroElecSurfaceStatus theStatus;
G4double kCarTolerance;
G4double ekint, thetat, thetaft, energyThreshold, crossingProbability;
G4bool flag_franchissement_surface, flag_reflexion,flag_normal, teleportToDo, teleportDone, isInitialised;
};
#endif
@@ -1,153 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4MuElecElasticModel.hh, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66 - 73, 2012.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MuElecElasticModel_h
#define G4MuElecElasticModel_h 1
#include <map>
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4MuElecCrossSectionDataSet.hh"
#include "G4VEmModel.hh"
#include "G4Electron.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4LogLogInterpolation.hh"
#include "G4ProductionCutsTable.hh"
#include "G4NistManager.hh"
class G4MuElecElasticModel : public G4VEmModel
{
public:
G4MuElecElasticModel(const G4ParticleDefinition* p = 0,
const G4String& nam = "MuElecElasticModel");
virtual ~G4MuElecElasticModel();
virtual void Initialise(const G4ParticleDefinition*, const G4DataVector&);
virtual G4double CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double emin,
G4double emax);
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy);
inline void SetKillBelowThreshold (G4double threshold);
G4double GetKillBelowThreshold () { return killBelowEnergy; }
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma;
private:
G4Material* nistSi;
G4double killBelowEnergy;
G4double lowEnergyLimit;
G4double lowEnergyLimitOfModel;
G4double highEnergyLimit;
G4bool isInitialised;
G4int verboseLevel;
// Cross section
typedef std::map<G4String,G4String,std::less<G4String> > MapFile;
MapFile tableFile;
typedef std::map<G4String,G4MuElecCrossSectionDataSet*,std::less<G4String> > MapData;
MapData tableData;
// Final state
G4double Theta(G4ParticleDefinition * aParticleDefinition, G4double k, G4double integrDiff);
G4double LogLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1, G4double xs2);
G4double LinLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1, G4double xs2);
G4double QuadInterpolator(G4double e11,
G4double e12,
G4double e21,
G4double e22,
G4double x11,
G4double x12,
G4double x21,
G4double x22,
G4double t1,
G4double t2,
G4double t,
G4double e);
typedef std::map<double, std::map<double, double> > TriDimensionMap;
TriDimensionMap eDiffCrossSectionData;
std::vector<double> eTdummyVec;
typedef std::map<double, std::vector<double> > VecMap;
VecMap eVecm;
G4double RandomizeCosTheta(G4double k);
//
G4MuElecElasticModel & operator=(const G4MuElecElasticModel &right);
G4MuElecElasticModel(const G4MuElecElasticModel&);
};
inline void G4MuElecElasticModel::SetKillBelowThreshold (G4double threshold)
{
killBelowEnergy = threshold;
if (threshold < 5*CLHEP::eV)
{
G4Exception ("*** WARNING : the G4MuElecElasticModel class is not validated below 5 eV !","",JustWarning,"") ;
threshold = 0.025*CLHEP::eV;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -1,162 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4MuElecInelasticModel.hh, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
//
// - Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66-73, 2012.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for protons and
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4MuElecInelasticModel_h
#define G4MuElecInelasticModel_h 1
#include "globals.hh"
#include "G4VEmModel.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4ProductionCutsTable.hh"
#include "G4MuElecCrossSectionDataSet.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
#include "G4GenericIon.hh"
#include "G4ParticleDefinition.hh"
#include "G4LogLogInterpolation.hh"
#include "G4MuElecSiStructure.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4NistManager.hh"
class G4MuElecInelasticModel : public G4VEmModel
{
public:
G4MuElecInelasticModel(const G4ParticleDefinition* p = 0,
const G4String& nam = "MuElecInelasticModel");
virtual ~G4MuElecInelasticModel();
virtual void Initialise(const G4ParticleDefinition*, const G4DataVector&);
virtual G4double CrossSectionPerVolume( const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double emin,
G4double emax);
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy);
double DifferentialCrossSection(G4ParticleDefinition * aParticleDefinition, G4double k, G4double energyTransfer, G4int shell);
protected:
G4ParticleChangeForGamma* fParticleChangeForGamma;
private:
//deexcitation manager to produce fluo photns and e-
G4VAtomDeexcitation* fAtomDeexcitation;
G4Material* nistSi;
std::map<G4String,G4double,std::less<G4String> > lowEnergyLimit;
std::map<G4String,G4double,std::less<G4String> > highEnergyLimit;
G4bool isInitialised;
G4int verboseLevel;
// Cross section
typedef std::map<G4String,G4String,std::less<G4String> > MapFile;
MapFile tableFile;
typedef std::map<G4String,G4MuElecCrossSectionDataSet*,std::less<G4String> > MapData;
MapData tableData;
// Final state
G4MuElecSiStructure SiStructure;
G4double RandomizeEjectedElectronEnergy(G4ParticleDefinition * aParticleDefinition, G4double incomingParticleEnergy, G4int shell) ;
void RandomizeEjectedElectronDirection(G4ParticleDefinition * aParticleDefinition, G4double incomingParticleEnergy, G4double
outgoingParticleEnergy, G4double & cosTheta, G4double & phi );
G4double LogLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1, G4double xs2);
G4double QuadInterpolator( G4double e11,
G4double e12,
G4double e21,
G4double e22,
G4double x11,
G4double x12,
G4double x21,
G4double x22,
G4double t1,
G4double t2,
G4double t,
G4double e);
typedef std::map<double, std::map<double, double> > TriDimensionMap;
TriDimensionMap eDiffCrossSectionData[7];
TriDimensionMap pDiffCrossSectionData[7];
std::vector<double> eTdummyVec;
std::vector<double> pTdummyVec;
typedef std::map<double, std::vector<double> > VecMap;
VecMap eVecm;
VecMap pVecm;
// Partial cross section
G4int RandomSelect(G4double energy,const G4String& particle );
//
G4MuElecInelasticModel & operator=(const G4MuElecInelasticModel &right);
G4MuElecInelasticModel(const G4MuElecInelasticModel&);
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -0,0 +1,168 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// $Id: G4PenelopeRayleighModelMI.hh 75573 2013-11-04 11:48:15Z gcosmo $
//
// Author: Luciano Pandola and Gianfranco Paternò
//
// -------------------------------------------------------------------
// History:
// 03 Dec 2009 L. Pandola 1st implementation
// 25 May 2011 L. Pandola Renamed (make v2008 as default Penelope)
// 27 Sep 2013 L. Pandola Migration to MT paradigm
// 20 Aug 2017 G. Paternò Molecular Interference implementation
// 24 Mar 2019 G. Paternò Improved Molecular Interference implementation
// 20 Jun 2020 G. Paternò Read qext separately and leave original atomic form factors
// 27 Aug 2020 G. Paternò Further improvement of MI implementation
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics, Rayleigh Scattering
// with the model from Penelope, version 2008
// extended for Molecular Interference Effects
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#ifndef G4PenelopeRayleighModelMI_HH
#define G4PenelopeRayleighModelMI_HH 1
#include "globals.hh"
#include "G4VEmModel.hh"
#include "G4DataVector.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4ExtendedMaterial.hh"
#include "G4MIData.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class G4ParticleDefinition;
class G4DynamicParticle;
class G4MaterialCutsCouple;
class G4Material;
class G4PhysicsFreeVector;
class G4PenelopeSamplingData;
class G4PenelopeRayleighModelMI : public G4VEmModel
{
public:
G4PenelopeRayleighModelMI(const G4ParticleDefinition* p = nullptr,
const G4String& processName = "PenRayleighMI");
virtual ~G4PenelopeRayleighModelMI();
virtual void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
virtual void InitialiseLocal(const G4ParticleDefinition*,
G4VEmModel *masterModel) override;
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
G4double kinEnergy,
G4double Z,
G4double A = 0,
G4double cut = 0,
G4double emax = DBL_MAX) override;
//Overriding of parent's (G4VEmModel) method
virtual G4double CrossSectionPerVolume(const G4Material*,
const G4ParticleDefinition*,
G4double kineticEnergy,
G4double cutEnergy = 0.,
G4double maxEnergy = DBL_MAX) override;
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
void SetVerbosityLevel(G4int lev) {verboseLevel = lev;};
G4int GetVerbosityLevel() {return verboseLevel;};
//Testing purposes
void DumpFormFactorTable(const G4Material*);
//Settings
void SetMIActive(G4bool val){fIsMIActive = val;};
G4bool IsMIActive(){return fIsMIActive;};
private:
G4PenelopeRayleighModelMI& operator=(const G4PenelopeRayleighModelMI &right);
G4PenelopeRayleighModelMI(const G4PenelopeRayleighModelMI&);
void SetParticle(const G4ParticleDefinition*);
//Helper methods
void ReadDataFile(G4int);
void ClearTables();
void BuildFormFactorTable(const G4Material*);
void GetPMaxTable(const G4Material*);
G4double GetFSquared(const G4Material*,const G4double);
void InitializeSamplingAlgorithm(const G4Material*);
void ReadMolInterferenceData(const G4String&,const G4String& filename="NULL");
G4MIData* GetMIData(const G4Material*);
void CalculateThetaAndAngFun();
G4double CalculateQSquared(G4double angle, G4double energy);
G4double IntegrateFun(G4double y[], G4int n, G4double dTheta);
void LoadKnownMIFFMaterials();
/// Data members
G4ParticleChangeForGamma* fParticleChange;
const G4ParticleDefinition* fParticle;
//Intrinsic energy limits of the model: cannot be extended by the parent process
G4double fIntrinsicLowEnergyLimit;
G4double fIntrinsicHighEnergyLimit;
G4int verboseLevel;
G4bool isInitialised;
//Internal tables and manager methods
std::map<G4int,G4PhysicsFreeVector*> *logAtomicCrossSection;
std::map<G4int,G4PhysicsFreeVector*> *atomicFormFactor;
std::map<G4String,G4PhysicsFreeVector*> *MolInterferenceData; //G. Paternò
G4DataVector logQSquareGrid; //log(Q^2) grid for interpolation
std::map<const G4Material*,G4PhysicsFreeVector*> *logFormFactorTable; //log(Q^2) vs. log(F^2)
G4DataVector logEnergyGridPMax; //energy grid for PMax (and originally for the x-section)
std::map<const G4Material*,G4PhysicsFreeVector*> *pMaxTable; //E vs. Pmax
std::map<const G4Material*,G4PenelopeSamplingData*> *samplingTable;
//Used only for G4EmCalculator and Unit Tests
G4bool fLocalTable;
static const G4int Ntheta = 31415;
G4double fDTheta = {0.0001};
G4bool fIsMIActive;
G4PhysicsFreeVector* angularFunction;
std::map<G4String,G4String> *fKnownMaterials;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -98,7 +98,7 @@ private:
G4double zParticle) const;
// returns the energy loss via the quantal harmonic oscillator model
// get number of shell, energy and oscillator strenghts for material
// get number of shell, energy and oscillator strengths for material
G4int GetNumberOfShell(const G4Material* material) const;
G4double GetShellEnergy(const G4Material* material,G4int nbOfTheShell) const;
@@ -117,7 +117,7 @@ private:
// Z of element at now avaliable for the model
static const G4int materialAvailable[6];
// number, energy and oscillator strenghts
// number, energy and oscillator strengths
// for an harmonic oscillator model of material
static const G4int nbofShellForMaterial[6];
static const G4double alShellEnergy[3];
View File
View File
@@ -4,7 +4,7 @@
# Package: Geant4.src.G4processes.G4electromagnetic.G4emlowenergy
#
# Sources description for a library.
# Lists the sources and headers of the code explicitely.
# Lists the sources and headers of the code explicitly.
# Lists include paths needed.
# Lists the internal granular and global dependencies of the library.
# Source specific properties should be added at the end.
@@ -14,35 +14,9 @@
#
#------------------------------------------------------------------------------
# List external includes needed.
include_directories(${CLHEP_INCLUDE_DIRS})
# List internal includes needed.
include_directories(${CMAKE_SOURCE_DIR}/source/geometry/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/geometry/navigation/include)
include_directories(${CMAKE_SOURCE_DIR}/source/geometry/volumes/include)
include_directories(${CMAKE_SOURCE_DIR}/source/global/HEPGeometry/include)
include_directories(${CMAKE_SOURCE_DIR}/source/global/HEPNumerics/include)
include_directories(${CMAKE_SOURCE_DIR}/source/global/HEPRandom/include)
include_directories(${CMAKE_SOURCE_DIR}/source/global/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/intercoms/include)
include_directories(${CMAKE_SOURCE_DIR}/source/materials/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/bosons/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/barions/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/ions/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/mesons/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/leptons/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/cuts/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/electromagnetic/standard/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/electromagnetic/utils/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/track/include)
#
# Define the Geant4 Module.
#
include(Geant4MacroDefineModule)
GEANT4_DEFINE_MODULE(NAME G4emlowenergy
HEADERS
G4AtomicDeexcitation.hh
@@ -97,7 +71,7 @@ GEANT4_DEFINE_MODULE(NAME G4emlowenergy
G4LivermoreBremsstrahlungModel.hh
G4LivermoreComptonModel.hh
G4LivermoreComptonModifiedModel.hh
G4LivermoreGammaConversion5DModel.hh
G4LivermoreGammaConversion5DModel.hh
G4LivermoreGammaConversionModel.hh
G4LivermoreGammaConversionModelRC.hh
G4LivermoreIonisationCrossSection.hh
@@ -115,18 +89,19 @@ GEANT4_DEFINE_MODULE(NAME G4emlowenergy
G4LowEPComptonModel.hh
G4LowEPPolarizedComptonModel.hh
G4LowEWentzelVIModel.hh
G4MIData.hh
G4MicroElecCrossSectionDataSet.hh
G4MicroElecElastic.hh
G4MicroElecElasticModel.hh
G4MicroElecInelastic.hh
G4MicroElecInelasticModel.hh
G4MicroElecSiStructure.hh
G4MuElecCrossSectionDataSet.hh
G4MuElecElastic.hh
G4MuElecElasticModel.hh
G4MuElecInelastic.hh
G4MuElecInelasticModel.hh
G4MuElecSiStructure.hh
G4MicroElecCrossSectionDataSet_new.hh
G4MicroElecElasticModel_new.hh
G4MicroElecInelastic_new.hh
G4MicroElecInelasticModel_new.hh
G4MicroElecLOPhononModel.hh
G4MicroElecLOPhononScattering.hh
G4MicroElecSurface.hh
G4OrlicLiXsModel.hh
G4PaulKxsModel.hh
G4PenelopeAnnihilationModel.hh
@@ -138,11 +113,12 @@ GEANT4_DEFINE_MODULE(NAME G4emlowenergy
G4PenelopeGammaConversionModel.hh
G4PenelopeIonisationCrossSection.hh
G4PenelopeIonisationModel.hh
G4PenelopeIonisationXSHandler.hh
G4PenelopeIonisationXSHandler.hh
G4PenelopeOscillator.hh
G4PenelopeOscillatorManager.hh
G4PenelopePhotoElectricModel.hh
G4PenelopeRayleighModel.hh
G4PenelopeRayleighModelMI.hh
G4PenelopeSamplingData.hh
G4PhotoElectricAngularGeneratorPolarized.hh
G4PhotoElectricAngularGeneratorSauterGavrila.hh
@@ -220,7 +196,7 @@ GEANT4_DEFINE_MODULE(NAME G4emlowenergy
G4LivermoreBremsstrahlungModel.cc
G4LivermoreComptonModel.cc
G4LivermoreComptonModifiedModel.cc
G4LivermoreGammaConversion5DModel.cc
G4LivermoreGammaConversion5DModel.cc
G4LivermoreGammaConversionModel.cc
G4LivermoreGammaConversionModelRC.cc
G4LivermoreIonisationCrossSection.cc
@@ -238,20 +214,21 @@ GEANT4_DEFINE_MODULE(NAME G4emlowenergy
G4LowEPComptonModel.cc
G4LowEPPolarizedComptonModel.cc
G4LowEWentzelVIModel.cc
G4MIData.cc
G4MicroElecCrossSectionDataSet.cc
G4MicroElecElastic.cc
G4MicroElecElasticModel.cc
G4MicroElecInelastic.cc
G4MicroElecInelasticModel.cc
G4MicroElecSiStructure.cc
G4MuElecCrossSectionDataSet.cc
G4MuElecElastic.cc
G4MuElecElasticModel.cc
G4MuElecInelastic.cc
G4MuElecInelasticModel.cc
G4MuElecSiStructure.cc
G4MicroElecCrossSectionDataSet_new.cc
G4MicroElecElasticModel_new.cc
G4MicroElecInelastic_new.cc
G4MicroElecInelasticModel_new.cc
G4MicroElecLOPhononModel.cc
G4MicroElecLOPhononScattering.cc
G4MicroElecSurface.cc
G4OrlicLiXsModel.cc
G4PaulKxsModel.cc
G4PaulKxsModel.cc
G4PenelopeAnnihilationModel.cc
G4PenelopeBremsstrahlungAngular.cc
G4PenelopeBremsstrahlungFS.cc
@@ -266,6 +243,7 @@ GEANT4_DEFINE_MODULE(NAME G4emlowenergy
G4PenelopeOscillatorManager.cc
G4PenelopePhotoElectricModel.cc
G4PenelopeRayleighModel.cc
G4PenelopeRayleighModelMI.cc
G4PenelopeSamplingData.cc
G4PhotoElectricAngularGeneratorPolarized.cc
G4PhotoElectricAngularGeneratorSauterGavrila.cc
@@ -330,7 +330,7 @@ void G4FluoData::PrintData()
{
G4int id = StartShellId(k,i);
// let's start from 1 because the first (index = 0) element of the vector
// is the id of the intial vacancy
// is the id of the initial vacancy
G4double e = StartShellEnergy(k,i) /MeV;
G4double p = StartShellProb(k,i);
G4cout << k <<") Shell id: " << id <<G4endl;
@@ -74,7 +74,7 @@ G4bool G4JAEAElasticScattering::IsApplicable(const G4ParticleDefinition& p)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//intialize the process
//initialize the process
void G4JAEAElasticScattering::InitialiseProcess(const G4ParticleDefinition*)
{
if(!isInitialised) {
@@ -203,7 +203,7 @@ if( !ES_Data_Buffer.is_open() )
}
dataCS[Z] = new G4LPhysicsFreeVector(300,0.01,3.);
for (G4int i=0;i<300;++i)
dataCS[Z]->PutValue(i,10.*i*1e-3,Polarized_ES_Data[Z]->at(i)*1e-22);
@@ -326,7 +326,7 @@ G4int energyindex=round(100*photonEnergy0)-1;
//G4double theta =45.*CLHEP::pi/180.;
//Theta is in degree to call scattering amplitudes
G4int theta_in_degree =round(theta*180./CLHEP::pi);
//theta_in_degree=45;
G4double am1=0,am2=0,am3=0,am4=0,aparaSquare=0,aperpSquare=0,apara_aper_Asterisk=0,img_apara_aper_Asterisk=0;
@@ -347,7 +347,7 @@ G4int energyindex=round(100*photonEnergy0)-1;
G4ThreeVector Polarization_Linear1(0.,0.,0.);
G4ThreeVector Polarization_Linear2(0.,0.,0.);
G4ThreeVector Polarization_Circular(0.,0.,0.);
//Stokes parameters for the incoming and outgoing photon
G4double Xi1=0, Xi2=0, Xi3=0, Xi1_Prime=0,Xi2_Prime=0,Xi3_Prime=0;
@@ -358,13 +358,14 @@ Xi1=gammaPolarization0.x();
Xi2=gammaPolarization0.y();
Xi3=gammaPolarization0.z();
//Polarization vector must be unit vector
G4double polarization_magnitude=Xi1*Xi1+Xi2*Xi2+Xi3*Xi3;
if ((polarization_magnitude)>1 || (Xi1*Xi1>1) || (Xi2*Xi2>1) || (Xi3*Xi3>1))
{
G4cout<<"WARNING: G4JAEAPolarizedElasticScatteringModel is only compatible with a unit polarization vector."<<G4endl;
G4cout<<"The event is ignored."<<G4endl;
return;
//Polarization vector must be unit vector (5% tolerance)
if ((gammaPolarization0.mag())>1.05 || (Xi1*Xi1>1.05) || (Xi2*Xi2>1.05) || (Xi3*Xi3>1.05))
{
G4Exception("G4JAEAPolarizedElasticScatteringModel::SampleSecondaries()","em1006",
JustWarning,
"WARNING: G4JAEAPolarizedElasticScatteringModel is only compatible with a unit polarization vector.");
return;
}
//Unpolarized gamma rays
if (Xi1==0 && Xi2==0 && Xi3==0)
@@ -509,10 +510,12 @@ G4double prob2=dsigmaL2/totalSigma;
G4double probc=1-(prob1+prob2);
//Check the Probability of polarization mixing
if (abs(probc - dsigmaC)>=0.0001)
{
G4cout<<"WARNING: Polarization mixing might be incorrect."<<G4endl;
}
if (abs(probc - dsigmaC/totalSigma)>=0.0001)
{
G4Exception("G4JAEAPolarizedElasticScatteringModel::SampleSecondaries()","em1007",
JustWarning,
"WARNING: Polarization mixing might be incorrect.");
}
// Generate outgoing photon direction
G4ThreeVector finaldirection(0.0,0.0,0.0);
@@ -206,7 +206,7 @@ void G4LivermoreComptonModifiedModel::SampleSecondaries(std::vector<G4DynamicPar
G4double epsilon0Local = 1. / (1. + 2. * e0m);
G4double epsilon0Sq = epsilon0Local * epsilon0Local;
G4double alpha1 = -std::log(epsilon0Local);
G4double alpha1 = -G4Log(epsilon0Local);
G4double alpha2 = 0.5 * (1. - epsilon0Sq);
G4double wlPhoton = h_Planck*c_light/photonEnergy0;
@@ -353,7 +353,7 @@ void G4LivermorePolarizedComptonModel::SampleSecondaries(std::vector<G4DynamicPa
G4double epsilon0Local = 1./(1. + 2*E0_m);
G4double epsilon0Sq = epsilon0Local*epsilon0Local;
G4double alpha1 = - std::log(epsilon0Local);
G4double alpha1 = - G4Log(epsilon0Local);
G4double alpha2 = 0.5*(1.- epsilon0Sq);
G4double wlGamma = h_Planck*c_light/gammaEnergy0;
@@ -23,51 +23,26 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// gpaterno, March 2019
//
// G4MuElecSiStructure.hh, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
//
// - Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66-73, 2012.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for protons and
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4MIData.hh"
#ifndef G4MUELECSISTRUCTURE_HH
#define G4MUELECSISTRUCTURE_HH 1
#include "globals.hh"
#include <vector>
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
class G4MuElecSiStructure
{
public:
G4MuElecSiStructure();
virtual ~G4MuElecSiStructure();
G4double Energy(G4int level);
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int NumberOfLevels() { return nLevels; }
private:
// Number of levels of silicon
G4int nLevels;
G4MIData::G4MIData(const G4String& name):
G4VMaterialExtension(name),
fFilenameFF(""),
fFilenameCS(""),
fMolWeight(0.)
{;}
std::vector<G4double> energyConstant;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
G4MIData::~G4MIData() {;}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -27,14 +27,17 @@
// Based on G4DNACrossSectionDataSet
//
#include "G4MuElecCrossSectionDataSet.hh"
#include "G4MicroElecCrossSectionDataSet_new.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4EMDataSet.hh"
#include <vector>
#include <fstream>
#include <sstream>
G4MuElecCrossSectionDataSet::G4MuElecCrossSectionDataSet(G4VDataSetAlgorithm* argAlgorithm,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MicroElecCrossSectionDataSet_new::G4MicroElecCrossSectionDataSet_new(G4VDataSetAlgorithm* argAlgorithm,
G4double argUnitEnergies,
G4double argUnitData)
:
@@ -43,7 +46,9 @@ G4MuElecCrossSectionDataSet::G4MuElecCrossSectionDataSet(G4VDataSetAlgorithm* ar
z = 0;
}
G4MuElecCrossSectionDataSet::~G4MuElecCrossSectionDataSet()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MicroElecCrossSectionDataSet_new::~G4MicroElecCrossSectionDataSet_new()
{
CleanUpComponents();
@@ -51,38 +56,41 @@ G4MuElecCrossSectionDataSet::~G4MuElecCrossSectionDataSet()
delete algorithm;
}
G4bool G4MuElecCrossSectionDataSet::LoadData(const G4String & argFileName)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4MicroElecCrossSectionDataSet_new::LoadData(const G4String & argFileName)
{
CleanUpComponents();
G4cout << "loaddata : " << argFileName << G4endl;
G4String fullFileName(FullFileName(argFileName));
std::ifstream in(fullFileName, std::ifstream::binary|std::ifstream::in);
if (!in.is_open())
{
G4String message("Data file \"");
message+=fullFileName;
message+="\" not found";
G4Exception("G4MuElecCrossSectionDataSet::LoadData","em0003",
FatalException,message);
G4Exception("G4MicroElecCrossSectionDataSet_new::LoadData","em0003",
FatalException,message);
return false;
}
std::vector<G4DataVector *> columns;
std::vector<G4DataVector *> log_columns;
std::stringstream *stream(new std::stringstream);
char c;
G4bool comment(false);
G4bool space(true);
G4bool first(true);
try
{
while (!in.eof())
{
in.get(c);
switch (c)
{
case '\r':
@@ -91,62 +99,74 @@ G4bool G4MuElecCrossSectionDataSet::LoadData(const G4String & argFileName)
{
unsigned long i(0);
G4double value;
while (!stream->eof())
{
(*stream) >> value;
while (i>=columns.size())
{
columns.push_back(new G4DataVector);
log_columns.push_back(new G4DataVector);
columns.push_back(new G4DataVector);
log_columns.push_back(new G4DataVector);
}
columns[i]->push_back(value);
// N. A. Karakatsanis
// A condition is applied to check if negative or zero values are present in the dataset.
// If yes, then a near-zero value is applied to allow the computation of the logarithmic value
// If a value is zero, this simplification is acceptable
// If a value is negative, then it is not acceptable and the data of the particular column of
// logarithmic values should not be used by interpolation methods.
//
// Therefore, G4LogLogInterpolation and G4LinLogLogInterpolation should not be used if negative values are present.
// Instead, G4LinInterpolation is safe in every case
// SemiLogInterpolation is safe only if the energy columns are non-negative
// G4LinLogInterpolation is safe only if the cross section data columns are non-negative
// N. A. Karakatsanis
// A condition is applied to check if negative or zero values are present in the dataset.
// If yes, then a near-zero value is applied to allow the computation of the logarithmic value
// If a value is zero, this simplification is acceptable
// If a value is negative, then it is not acceptable and the data of the particular column of
// logarithmic values should not be used by interpolation methods.
//
// Therefore, G4LogLogInterpolation and G4LinLogLogInterpolation should not be used if negative values are present.
// Instead, G4LinInterpolation is safe in every case
// SemiLogInterpolation is safe only if the energy columns are non-negative
// G4LinLogInterpolation is safe only if the cross section data columns are non-negative
if (value <=0.) value = 1e-300;
log_columns[i]->push_back(std::log10(value));
i++;
}
delete stream;
stream=new std::stringstream;
}
first=true;
comment=false;
space=true;
break;
case '#':
comment=true;
break;
case '\t':
case ' ':
space = true;
break;
c=' ';
break;
//case ' ':
// if (space)
// break;
default:
if (comment) { break; }
if (space && (!first)) { (*stream) << ' '; }
first=false;
(*stream) << c;
space=false;
if ((c==' ') && space)
break;
if (comment)
break;
if (c==' ')
space=true;
else
{
if (space && (!first))
(*stream) << ' ';
first=false;
(*stream) << c;
space=false;
}
}
}
}
@@ -155,43 +175,43 @@ G4bool G4MuElecCrossSectionDataSet::LoadData(const G4String & argFileName)
// some implementations of STL could throw a "failture" exception
// when read wants read characters after end of file
}
delete stream;
std::vector<G4DataVector *>::size_type maxI(columns.size());
if (maxI<2)
{
G4String message("Data file \"");
message+=fullFileName;
message+="\" should have at least two columns";
G4Exception("G4MuElecCrossSectionDataSet::LoadData","em0005",
FatalException,message);
G4Exception("G4MicroElecCrossSectionDataSet_new::LoadData","em0005",
FatalException,message);
return false;
}
std::vector<G4DataVector*>::size_type i(1);
while (i<maxI)
{
G4DataVector::size_type maxJ(columns[i]->size());
if (maxJ!=columns[0]->size())
{
G4String message("Data file \"");
message+=fullFileName;
message+="\" has lines with a different number of columns";
G4Exception("G4MuElecCrossSectionDataSet::LoadData","em0005",
G4Exception("G4MicroElecCrossSectionDataSet_new::LoadData","em0005",
FatalException,message);
return false;
}
G4DataVector::size_type j(0);
G4DataVector *argEnergies=new G4DataVector;
G4DataVector *argData=new G4DataVector;
G4DataVector *argLogEnergies=new G4DataVector;
G4DataVector *argLogData=new G4DataVector;
while(j<maxJ)
{
argEnergies->push_back(columns[0]->operator[] (j)*GetUnitEnergies());
@@ -200,12 +220,12 @@ G4bool G4MuElecCrossSectionDataSet::LoadData(const G4String & argFileName)
argLogData->push_back(log_columns[i]->operator[] (j) + std::log10(GetUnitData()));
j++;
}
AddComponent(new G4EMDataSet(i-1, argEnergies, argData, argLogEnergies, argLogData, GetAlgorithm()->Clone(), GetUnitEnergies(), GetUnitData()));
i++;
}
i=maxI;
while (i>0)
{
@@ -217,8 +237,11 @@ G4bool G4MuElecCrossSectionDataSet::LoadData(const G4String & argFileName)
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4MuElecCrossSectionDataSet::LoadNonLogData(const G4String & argFileName)
G4bool G4MicroElecCrossSectionDataSet_new::LoadNonLogData(const G4String & argFileName)
{
CleanUpComponents();
@@ -230,7 +253,7 @@ G4bool G4MuElecCrossSectionDataSet::LoadNonLogData(const G4String & argFileName)
G4String message("Data file \"");
message+=fullFileName;
message+="\" not found";
G4Exception("G4MuElecCrossSectionDataSet::LoadData","em0003",
G4Exception("G4MicroElecCrossSectionDataSet_new::LoadData","em0003",
FatalException,message);
return false;
}
@@ -284,19 +307,27 @@ G4bool G4MuElecCrossSectionDataSet::LoadNonLogData(const G4String & argFileName)
case '#':
comment=true;
break;
case '\t':
case ' ':
space = true;
break;
default:
if (comment) { break; }
if (space && (!first)) { (*stream) << ' '; }
if( c=='\t')
c=' ';
if( c==' ' && space)
break;
first=false;
(*stream) << c;
space=false;
if (comment)
break;
if (c==' ')
space=true;
else
{
if (space && (!first))
(*stream) << ' ';
first=false;
(*stream) << c;
space=false;
}
}
}
}
@@ -315,7 +346,7 @@ G4bool G4MuElecCrossSectionDataSet::LoadNonLogData(const G4String & argFileName)
G4String message("Data file \"");
message+=fullFileName;
message+="\" should have at least two columns";
G4Exception("G4MuElecCrossSectionDataSet::LoadData","em0005",
G4Exception("G4MicroElecCrossSectionDataSet_new::LoadData","em0005",
FatalException,message);
return false;
}
@@ -325,12 +356,13 @@ G4bool G4MuElecCrossSectionDataSet::LoadNonLogData(const G4String & argFileName)
{
G4DataVector::size_type maxJ(columns[i]->size());
if (maxJ!=columns[0]->size())
{
G4String message("Data file \"");
message+=fullFileName;
message+="\" has lines with a different number of columns.";
G4Exception("G4MuElecCrossSectionDataSet::LoadData","em0005",
G4Exception("G4MicroElecCrossSectionDataSet_new::LoadData","em0005",
FatalException,message);
return false;
}
@@ -362,14 +394,16 @@ G4bool G4MuElecCrossSectionDataSet::LoadNonLogData(const G4String & argFileName)
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4MuElecCrossSectionDataSet::SaveData(const G4String & argFileName) const
G4bool G4MicroElecCrossSectionDataSet_new::SaveData(const G4String & argFileName) const
{
const size_t n(NumberOfComponents());
if (n==0)
{
G4Exception("G4MuElecCrossSectionDataSet::SaveData","em0005",
G4Exception("G4MicroElecCrossSectionDataSet_new::SaveData","em0005",
FatalException,"Expected at least one component");
return false;
@@ -383,7 +417,7 @@ G4bool G4MuElecCrossSectionDataSet::SaveData(const G4String & argFileName) const
G4String message("Cannot open \"");
message+=fullFileName;
message+="\"";
G4Exception("G4MuElecCrossSectionDataSet::SaveData","em0005",
G4Exception("G4MicroElecCrossSectionDataSet_new::SaveData","em0005",
FatalException,message);
return false;
}
@@ -431,27 +465,29 @@ G4bool G4MuElecCrossSectionDataSet::SaveData(const G4String & argFileName) const
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4String G4MuElecCrossSectionDataSet::FullFileName(const G4String& argFileName) const
G4String G4MicroElecCrossSectionDataSet_new::FullFileName(const G4String& argFileName) const
{
char* path = std::getenv("G4LEDATA");
char *path = std::getenv("G4LEDATA");
if (!path)
{
G4Exception("G4MuElecCrossSectionDataSet::FullFileName","em0006",
FatalException,"G4LEDATA environment variable not set.");
return "";
}
{
G4Exception("G4MicroElecCrossSectionDataSet_new::Initialise","em0006",FatalException,"G4LEDATA environment variable not set.");
return "";
}
//Reading DCS file
std::ostringstream fullFileName;
fullFileName << path << "/" << argFileName << ".dat";
fullFileName << path << "/microelec/" << argFileName << ".dat";
return G4String(fullFileName.str().c_str());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuElecCrossSectionDataSet::FindValue(G4double argEnergy, G4int /* argComponentId */) const
G4double G4MicroElecCrossSectionDataSet_new::FindValue(G4double argEnergy, G4int /* argComponentId */) const
{
// Returns the sum over the shells corresponding to e
G4double value = 0.;
@@ -468,8 +504,17 @@ G4double G4MuElecCrossSectionDataSet::FindValue(G4double argEnergy, G4int /* arg
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecCrossSectionDataSet::PrintData(void) const
G4double G4MicroElecCrossSectionDataSet_new::FindShellValue(G4double argEnergy, G4int shell) const
{
return components.at(shell)->FindValue(argEnergy);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MicroElecCrossSectionDataSet_new::PrintData(void) const
{
const size_t n(NumberOfComponents());
@@ -486,8 +531,10 @@ void G4MuElecCrossSectionDataSet::PrintData(void) const
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecCrossSectionDataSet::SetEnergiesData(G4DataVector* argEnergies,
void G4MicroElecCrossSectionDataSet_new::SetEnergiesData(G4DataVector* argEnergies,
G4DataVector* argData,
G4int argComponentId)
{
@@ -502,13 +549,14 @@ void G4MuElecCrossSectionDataSet::SetEnergiesData(G4DataVector* argEnergies,
std::ostringstream message;
message << "Component " << argComponentId << " not found";
G4Exception("G4MuElecCrossSectionDataSet::SetEnergiesData","em0005",
G4Exception("G4MicroElecCrossSectionDataSet_new::SetEnergiesData","em0005",
FatalException,message.str().c_str());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecCrossSectionDataSet::SetLogEnergiesData(G4DataVector* argEnergies,
void G4MicroElecCrossSectionDataSet_new::SetLogEnergiesData(G4DataVector* argEnergies,
G4DataVector* argData,
G4DataVector* argLogEnergies,
G4DataVector* argLogData,
@@ -525,13 +573,14 @@ void G4MuElecCrossSectionDataSet::SetLogEnergiesData(G4DataVector* argEnergies,
std::ostringstream message;
message << "Component " << argComponentId << " not found";
G4Exception("G4MuElecCrossSectionDataSet::SetLogEnergiesData","em0005",
G4Exception("G4MicroElecCrossSectionDataSet_new::SetLogEnergiesData","em0005",
FatalException,message.str().c_str());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecCrossSectionDataSet::CleanUpComponents()
void G4MicroElecCrossSectionDataSet_new::CleanUpComponents()
{
while (!components.empty())
{
@@ -540,4 +589,5 @@ void G4MuElecCrossSectionDataSet::CleanUpComponents()
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -0,0 +1,692 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecElasticModel_new.cc, 2011/08/29 A.Valentin, M. Raine are with CEA [a]
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
// - A.Valentin, M. Raine,
// Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with the Geant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// https://doi.org/10.1109/NSSMIC.2010.5873720
//
// - A.Valentin, M. Raine, M.Gaillardin, P.Paillet
// Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Silicon,
// https://doi.org/10.1016/j.nimb.2012.06.007
// NIM B, vol. 288, pp. 66-73, 2012, part A
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012, part B
// https://doi.org/10.1016/j.nimb.2012.07.028
//
// - M. Raine, M. Gaillardin, P. Paillet
// Geant4 physics processes for silicon microdosimetry simulation:
// Improvements and extension of the energy-range validity up to 10 GeV/nucleon
// NIM B, vol. 325, pp. 97-100, 2014
// https://doi.org/10.1016/j.nimb.2014.01.014
//
// - J. Pierron, C. Inguimbert, M. Belhaj, T. Gineste, J. Puech, M. Raine
// Electron emission yield for low energy electrons:
// Monte Carlo simulation and experimental comparison for Al, Ag, and Si
// Journal of Applied Physics 121 (2017) 215107.
// https://doi.org/10.1063/1.4984761
//
// - P. Caron,
// Study of Electron-Induced Single-Event Upset in Integrated Memory Devices
// PHD, 16th October 2019
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MicroElecElasticModel_new.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4Exp.hh"
#include "G4Material.hh"
#include "G4String.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
using namespace std;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MicroElecElasticModel_new::G4MicroElecElasticModel_new(const G4ParticleDefinition*,
const G4String& nam)
:G4VEmModel(nam), isInitialised(false)
{
killBelowEnergy = 0.1*eV; // Minimum e- energy for energy loss by excitation
lowEnergyLimit = 0.1 * eV;
lowEnergyLimitOfModel = 10 * eV; // The model lower energy is 10 eV
highEnergyLimit = 500. * keV;
SetLowEnergyLimit(lowEnergyLimit);
SetHighEnergyLimit(highEnergyLimit);
verboseLevel= 0;
// Verbosity scale:
// 0 = nothing
// 1 = warning for energy non-conservation
// 2 = details of energy budget
// 3 = calculation of cross sections, file openings, sampling of atoms
// 4 = entering in methods
if( verboseLevel>0 )
{
G4cout << "MicroElec Elastic model is constructed " << G4endl
<< "Energy range: "
<< lowEnergyLimit / eV << " eV - "
<< highEnergyLimit / MeV << " MeV"
<< G4endl;
}
fParticleChangeForGamma = 0;
killElectron = false;
acousticModelEnabled = false;
currentMaterialName = "";
isOkToBeInitialised = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MicroElecElasticModel_new::~G4MicroElecElasticModel_new()
{
// For total cross section
TCSMap::iterator pos2;
for (pos2 = tableTCS.begin(); pos2 != tableTCS.end(); ++pos2) {
MapData* tableData = pos2->second;
std::map< G4String, G4MicroElecCrossSectionDataSet_new*, std::less<G4String> >::iterator pos;
for (pos = tableData->begin(); pos != tableData->end(); ++pos)
{
G4MicroElecCrossSectionDataSet_new* table = pos->second;
delete table;
}
delete tableData;
}
//Clearing DCS maps
ThetaMap::iterator iterator_angle;
for (iterator_angle = thetaDataStorage.begin(); iterator_angle != thetaDataStorage.end(); ++iterator_angle) {
TriDimensionMap* eDiffCrossSectionData = iterator_angle->second;
eDiffCrossSectionData->clear();
delete eDiffCrossSectionData;
}
energyMap::iterator iterator_energy;
for (iterator_energy = eIncidentEnergyStorage.begin(); iterator_energy != eIncidentEnergyStorage.end(); ++iterator_energy) {
std::vector<double>* eTdummyVec = iterator_energy->second;
eTdummyVec->clear();
delete eTdummyVec;
}
ProbaMap::iterator iterator_proba;
for (iterator_proba = eProbaStorage.begin(); iterator_proba != eProbaStorage.end(); ++iterator_proba) {
VecMap* eVecm = iterator_proba->second;
eVecm->clear();
delete eVecm;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MicroElecElasticModel_new::Initialise(const G4ParticleDefinition* /*particle*/,
const G4DataVector& /*cuts*/)
{
if (isOkToBeInitialised == true && isInitialised == false) {
if (verboseLevel > -1)
G4cout << "Calling G4MicroElecElasticModel_new::Initialise()" << G4endl;
// Energy limits
// Reading of data files
G4double scaleFactor = 1e-18 * cm * cm;
G4ProductionCutsTable* theCoupleTable =
G4ProductionCutsTable::GetProductionCutsTable();
G4int numOfCouples = theCoupleTable->GetTableSize();
for (G4int i = 0; i < numOfCouples; ++i) {
const G4Material* material =
theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
//theCoupleTable->GetMaterialCutsCouple(i)->;
G4cout << "MicroElasticModel, Material " << i + 1 << " / " << numOfCouples << " : " << material->GetName() << G4endl;
if (material->GetName() == "Vacuum") continue;
G4String matName = material->GetName().substr(3, material->GetName().size());
G4cout<< matName<< G4endl;
currentMaterialStructure = new G4MicroElecMaterialStructure(matName);
lowEnergyLimitTable[matName]=currentMaterialStructure->GetElasticModelLowLimit();
highEnergyLimitTable[matName]=currentMaterialStructure->GetElasticModelHighLimit();
workFunctionTable[matName] = currentMaterialStructure->GetWorkFunction();
delete currentMaterialStructure;
G4cout << "Reading TCS file" << G4endl;
G4String fileElectron = "Elastic/elsepa_elastic_cross_e_" + matName;
G4cout << "Elastic Total Cross file : " << fileElectron << G4endl;
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
G4String electron = electronDef->GetParticleName();
// For total cross section
MapData* tableData = new MapData();
G4MicroElecCrossSectionDataSet_new* tableE = new G4MicroElecCrossSectionDataSet_new(new G4LogLogInterpolation, eV, scaleFactor);
tableE->LoadData(fileElectron);
tableData->insert(make_pair(electron, tableE));
tableTCS[matName] = tableData; //Storage of TCS
// For final state
char *path = std::getenv("G4LEDATA");
if (!path)
{
G4Exception("G4MicroElecElasticModel_new::Initialise","em0006",FatalException,"G4LEDATA environment variable not set.");
return;
}
//Reading DCS file
std::ostringstream eFullFileName;
eFullFileName << path << "/microelec/Elastic/elsepa_elastic_cumulated_diffcross_e_" + matName + ".dat";
G4cout << "Elastic Cumulated Diff Cross : " << eFullFileName.str().c_str() << G4endl;
std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
if (!eDiffCrossSection)
G4Exception("G4MicroElecElasticModel_new::Initialise", "em0003", FatalException, "Missing data file: /microelec/sigmadiff_cumulated_elastic_e_Si.dat");
// October 21th, 2014 - Melanie Raine
// Added clear for MT
// Diff Cross Sections in cumulated mode
TriDimensionMap* eDiffCrossSectionData = new TriDimensionMap(); //Angles
std::vector<double>* eTdummyVec = new std::vector<double>; //Incident energy vector
VecMap* eProbVec = new VecMap; //Probabilities
eTdummyVec->push_back(0.);
while (!eDiffCrossSection.eof())
{
double tDummy; //incident energy
double eProb; //Proba
eDiffCrossSection >> tDummy >> eProb;
// SI : mandatory eVecm initialization
if (tDummy != eTdummyVec->back())
{
eTdummyVec->push_back(tDummy); //adding values for incident energy points
(*eProbVec)[tDummy].push_back(0.); //adding probability for the first angle, equal to 0
}
eDiffCrossSection >> (*eDiffCrossSectionData)[tDummy][eProb]; //adding Angle Value to map
if (eProb != (*eProbVec)[tDummy].back()) {
(*eProbVec)[tDummy].push_back(eProb); //Adding cumulated proba to map
}
}
//Filling maps for the material
thetaDataStorage[matName] = eDiffCrossSectionData;
eIncidentEnergyStorage[matName] = eTdummyVec;
eProbaStorage[matName] = eProbVec;
}
// End final state
if (verboseLevel > 2)
G4cout << "Loaded cross section files for MicroElec Elastic model" << G4endl;
if (verboseLevel > 0)
{
G4cout << "MicroElec Elastic model is initialized " << G4endl
<< "Energy range: "
<< LowEnergyLimit() / eV << " eV - "
<< HighEnergyLimit() / MeV << " MeV"
<< G4endl; // system("pause"); linux doesn't like
}
if (isInitialised) { return; }
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double,
G4double)
{
if (verboseLevel > 3)
G4cout << "Calling CrossSectionPerVolume() of G4MicroElecElasticModel" << G4endl;
isOkToBeInitialised = true;
currentMaterialName = material->GetName().substr(3, material->GetName().size());
const G4DataVector cuts;
Initialise(p, cuts);
// Calculate total cross section for model
MapEnergy::iterator lowEPos;
lowEPos = lowEnergyLimitTable.find(currentMaterialName);
MapEnergy::iterator highEPos;
highEPos = highEnergyLimitTable.find(currentMaterialName);
MapEnergy::iterator killEPos;
killEPos = workFunctionTable.find(currentMaterialName);
if (lowEPos == lowEnergyLimitTable.end() || highEPos == highEnergyLimitTable.end() || killEPos == workFunctionTable.end())
{
G4String str = "Material ";
str += currentMaterialName + " not found!";
G4Exception("G4MicroElecElasticModel_new::EnergyLimits", "em0002", FatalException, str);
return 0;
}
else {
// G4cout << "normal elastic " << G4endl;
lowEnergyLimit = lowEPos->second;
highEnergyLimit = highEPos->second;
killBelowEnergy = killEPos->second;
}
if (ekin < killBelowEnergy) {
return DBL_MAX; }
G4double sigma=0;
//Phonon for SiO2
if (currentMaterialName == "SILICON_DIOXIDE" && ekin < 100 * eV) {
acousticModelEnabled = true;
//Values for SiO2
G4double kbz = 11.54e9,
rho = 2.2 * 1000, // [g/cm3] * 1000
cs = 3560, //Sound speed
Ebz = 5.1 * 1.6e-19,
Aac = 17 * Ebz, //A screening parameter
Eac = 3.5 * 1.6e-19, //C deformation potential
prefactor = 2.2;// Facteur pour modifier les MFP
return AcousticCrossSectionPerVolume(ekin, kbz, rho, cs, Aac, Eac, prefactor);
}
//Elastic
else {
acousticModelEnabled = false;
G4double density = material->GetTotNbOfAtomsPerVolume();
const G4String& particleName = p->GetParticleName();
TCSMap::iterator tablepos;
tablepos = tableTCS.find(currentMaterialName);
if (tablepos != tableTCS.end())
{
MapData* tableData = tablepos->second;
if (ekin >= lowEnergyLimit && ekin < highEnergyLimit)
{
std::map< G4String, G4MicroElecCrossSectionDataSet_new*, std::less<G4String> >::iterator pos;
pos = tableData->find(particleName);
if (pos != tableData->end())
{
G4MicroElecCrossSectionDataSet_new* table = pos->second;
if (table != 0)
{
sigma = table->FindValue(ekin);
}
}
else
{
G4Exception("G4MicroElecElasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, "Model not applicable to particle type.");
}
}
else return 1 / DBL_MAX;
}
else
{
G4String str = "Material ";
str += currentMaterialName + " TCS table not found!";
G4Exception("G4MicroElecElasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, str);
}
if (verboseLevel > 3)
{
G4cout << "---> Kinetic energy(eV)=" << ekin / eV << G4endl;
G4cout << " - Cross section per Si atom (cm^2)=" << sigma / cm / cm << G4endl;
G4cout << " - Cross section per Si atom (cm^-1)=" << sigma*density / (1. / cm) << G4endl;
}
return sigma*density;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::AcousticCrossSectionPerVolume(G4double ekin,
G4double kbz,
G4double rho,
G4double cs,
G4double Aac,
G4double Eac,
G4double prefactor)
{
G4double e = 1.6e-19,
m0 = 9.10938356e-31,
h = 1.0546e-34,
kb = 1.38e-23;
G4double E = (ekin / eV) * e;
G4double D = (2 / (std::sqrt(2) * std::pow(pi, 2) * std::pow(h, 3))) * (1 + 2 * E) * std::pow(m0, 1.5) * std::sqrt(E);
// Parametres SiO2
G4double T = 300,
Ebz = (std::pow(h, 2) * std::pow(kbz, 2)) / (2 * m0),
hwbz = cs * kbz * h,
nbz = 1.0 / (exp(hwbz / (kb * T)) - 1),
Pac;
if (E < Ebz / 4.0)
{
Pac = ((pi * kb * T) / (h * std::pow(cs, 2) * rho)) * (std::pow(Eac, 2) * D) / (1 + (E / Aac));
}
else if (E > Ebz) //Screened relationship
{
Pac = ((2 * pi * m0 * (2 * nbz + 1)) / (h * rho * hwbz)) * std::pow(Eac, 2) * D * E * 2 * std::pow((Aac / E), 2) * (((-E / Aac) / (1 + (E / Aac))) + log(1 + (E / Aac)));
}
else //Linear interpolation
{
G4double fEbz = ((2 * pi * m0 * (2 * nbz + 1)) / (h * rho * hwbz)) * std::pow(Eac, 2) * D * Ebz * 2 * std::pow((Aac / Ebz), 2) * (((-Ebz / Aac) / (1 + (Ebz / Aac))) + log(1 + (Ebz / Aac)));
G4double fEbz4 = ((pi * kb * T) / (h * std::pow(cs, 2) * rho)) * (std::pow(Eac, 2) * D) / (1 + ((Ebz / 4) / Aac));
G4double alpha = ((fEbz - fEbz4) / (Ebz - (Ebz / 4)));
Pac = alpha * E + (fEbz - alpha * Ebz);
}
G4double MFP = (std::sqrt(2 * E / m0) / (prefactor * Pac)) * m;
return 1 / MFP;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MicroElecElasticModel_new::SampleSecondaries(std::vector<G4DynamicParticle*>* /*fvect*/,
const G4MaterialCutsCouple* /*couple*/,
const G4DynamicParticle* aDynamicElectron,
G4double,
G4double)
{
if (verboseLevel > 3)
G4cout << "Calling SampleSecondaries() of G4MicroElecElasticModel" << G4endl;
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
if (electronEnergy0 < killBelowEnergy)
{
fParticleChangeForGamma->SetProposedKineticEnergy(0.);
fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
fParticleChangeForGamma->ProposeLocalEnergyDeposit(electronEnergy0);
return;
}
if (electronEnergy0 < highEnergyLimit)
{
G4double cosTheta = 0;
if (acousticModelEnabled)
{
cosTheta = 1 - 2 * G4UniformRand(); //Isotrope
}
else if (electronEnergy0 >= lowEnergyLimit)
{
cosTheta = RandomizeCosTheta(electronEnergy0);
}
G4double phi = 2. * pi * G4UniformRand();
G4ThreeVector zVers = aDynamicElectron->GetMomentumDirection();
G4ThreeVector xVers = zVers.orthogonal();
G4ThreeVector yVers = zVers.cross(xVers);
G4double xDir = std::sqrt(1. - cosTheta*cosTheta);
G4double yDir = xDir;
xDir *= std::cos(phi);
yDir *= std::sin(phi);
G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::DamageEnergy(G4double T,G4double A, G4double Z)
{
//.................. T in eV!!!!!!!!!!!!!
G4double Z2= Z;
G4double M2= A;
G4double k_d;
G4double epsilon_d;
G4double g_epsilon_d;
G4double E_nu;
k_d=0.1334*std::pow(Z2,(2./3.))*std::pow(M2,(-1./2.));
epsilon_d=0.01014*std::pow(Z2,(-7./3.))*(T/eV);
g_epsilon_d= epsilon_d+0.40244*std::pow(epsilon_d,(3./4.))+3.4008*std::pow(epsilon_d,(1./6.));
E_nu=1./(1.+ k_d*g_epsilon_d);
return E_nu;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::Theta
(G4ParticleDefinition * particleDefinition, G4double k, G4double integrDiff)
{
G4double theta = 0.;
G4double valueT1 = 0;
G4double valueT2 = 0;
G4double valueE21 = 0;
G4double valueE22 = 0;
G4double valueE12 = 0;
G4double valueE11 = 0;
G4double xs11 = 0;
G4double xs12 = 0;
G4double xs21 = 0;
G4double xs22 = 0;
if (particleDefinition == G4Electron::ElectronDefinition())
{
ThetaMap::iterator iterator_angle;
iterator_angle = thetaDataStorage.find(currentMaterialName);
energyMap::iterator iterator_energy;
iterator_energy = eIncidentEnergyStorage.find(currentMaterialName);
ProbaMap::iterator iterator_proba;
iterator_proba = eProbaStorage.find(currentMaterialName);
if (iterator_angle != thetaDataStorage.end() && iterator_energy != eIncidentEnergyStorage.end() && iterator_proba != eProbaStorage.end())
{
TriDimensionMap* eDiffCrossSectionData = iterator_angle->second; //Theta points
std::vector<double>* eTdummyVec = iterator_energy->second;
VecMap* eVecm = iterator_proba->second;
std::vector<double>::iterator t2 = std::upper_bound(eTdummyVec->begin(), eTdummyVec->end(), k);
std::vector<double>::iterator t1 = t2 - 1;
std::vector<double>::iterator e12 = std::upper_bound((*eVecm)[(*t1)].begin(), (*eVecm)[(*t1)].end(), integrDiff);
std::vector<double>::iterator e11 = e12 - 1;
std::vector<double>::iterator e22 = std::upper_bound((*eVecm)[(*t2)].begin(), (*eVecm)[(*t2)].end(), integrDiff);
std::vector<double>::iterator e21 = e22 - 1;
valueT1 = *t1;
valueT2 = *t2;
valueE21 = *e21;
valueE22 = *e22;
valueE12 = *e12;
valueE11 = *e11;
xs11 = (*eDiffCrossSectionData)[valueT1][valueE11];
xs12 = (*eDiffCrossSectionData)[valueT1][valueE12];
xs21 = (*eDiffCrossSectionData)[valueT2][valueE21];
xs22 = (*eDiffCrossSectionData)[valueT2][valueE22];
}
else
{
G4String str = "Material ";
str += currentMaterialName + " not found!";
G4Exception("G4MicroElecElasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, str);
}
}
if (xs11==0 || xs12==0 ||xs21==0 ||xs22==0) return (0.);
theta = QuadInterpolator( valueE11, valueE12,
valueE21, valueE22,
xs11, xs12,
xs21, xs22,
valueT1, valueT2,
k, integrDiff );
return theta;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::LinLogInterpolate(G4double e1,
G4double e2,
G4double e,
G4double xs1,
G4double xs2)
{
G4double d1 = std::log(xs1);
G4double d2 = std::log(xs2);
G4double value = G4Exp(d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::LinLinInterpolate(G4double e1,
G4double e2,
G4double e,
G4double xs1,
G4double xs2)
{
G4double d1 = xs1;
G4double d2 = xs2;
G4double value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::LogLogInterpolate(G4double e1,
G4double e2,
G4double e,
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));
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::QuadInterpolator(G4double e11, G4double e12,
G4double e21, G4double e22,
G4double xs11, G4double xs12,
G4double xs21, G4double xs22,
G4double t1, G4double t2,
G4double t, G4double e)
{
// Lin-Lin
G4double interpolatedvalue1 = LinLinInterpolate(e11, e12, e, xs11, xs12);
G4double interpolatedvalue2 = LinLinInterpolate(e21, e22, e, xs21, xs22);
G4double value = LinLinInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecElasticModel_new::RandomizeCosTheta(G4double k)
{
G4double integrdiff=0;
G4double uniformRand=G4UniformRand();
integrdiff = uniformRand;
G4double theta=0.;
G4double cosTheta=0.;
theta = Theta(G4Electron::ElectronDefinition(),k/eV,integrdiff);
cosTheta= std::cos(theta*pi/180.);
return cosTheta;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MicroElecElasticModel_new::SetKillBelowThreshold (G4double threshold)
{
killBelowEnergy = threshold;
if (threshold < 5*CLHEP::eV)
{
G4Exception ("*** WARNING : the G4MicroElecElasticModel class is not validated below 5 eV !","",JustWarning,"") ;
threshold = 5*CLHEP::eV;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1075,7 +1075,7 @@ G4double G4MicroElecInelasticModel::TransferedEnergy(G4ParticleDefinition* parti
nrjTransf21,
nrjTransf22);
// zeros are explicitely set
// zeros are explicitly set
G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
@@ -1197,7 +1197,7 @@ G4double G4MicroElecInelasticModel::TransferedEnergy(G4ParticleDefinition* parti
nrjTransf21,
nrjTransf22);
// zeros are explicitely set
// zeros are explicitly set
G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,134 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecInelastic_new.cc, 2011/08/29 A.Valentin, M. Raine are with CEA [a]
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
// - A.Valentin, M. Raine,
// Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with the Geant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85
// https://doi.org/10.1109/NSSMIC.2010.5873720
//
// - A.Valentin, M. Raine, M.Gaillardin, P.Paillet
// Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Silicon,
// https://doi.org/10.1016/j.nimb.2012.06.007
// NIM B, vol. 288, pp. 66-73, 2012, part A
// heavy ions in Si, NIM B, vol. 287, pp. 124-129, 2012, part B
// https://doi.org/10.1016/j.nimb.2012.07.028
//
// - M. Raine, M. Gaillardin, P. Paillet
// Geant4 physics processes for silicon microdosimetry simulation:
// Improvements and extension of the energy-range validity up to 10 GeV/nucleon
// NIM B, vol. 325, pp. 97-100, 2014
// https://doi.org/10.1016/j.nimb.2014.01.014
//
// - J. Pierron, C. Inguimbert, M. Belhaj, T. Gineste, J. Puech, M. Raine
// Electron emission yield for low energy electrons:
// Monte Carlo simulation and experimental comparison for Al, Ag, and Si
// Journal of Applied Physics 121 (2017) 215107.
// https://doi.org/10.1063/1.4984761
//
// - P. Caron,
// Study of Electron-Induced Single-Event Upset in Integrated Memory Devices
// PHD, 16th October 2019
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MicroElecInelastic_new.hh"
#include "G4DummyModel.hh"
#include "G4SystemOfUnits.hh"
#include "G4Alpha.hh"
#include "G4GenericIon.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
using namespace std;
G4MicroElecInelastic_new::G4MicroElecInelastic_new(const G4String& processName,
G4ProcessType type)
: G4VEmProcess (processName, type)
{
SetProcessSubType(53);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4MicroElecInelastic_new::~G4MicroElecInelastic_new()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4MicroElecInelastic_new::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Electron::Electron() ||
&p == G4Proton::Proton() ||
&p == G4Alpha::Alpha() ||
&p == G4GenericIon::GenericIonDefinition());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MicroElecInelastic_new::InitialiseProcess(const G4ParticleDefinition* p)
{
if(!isInitialised)
{
isInitialised = true;
SetBuildTableFlag(false);
G4String name = p->GetParticleName();
if(!EmModel(0)) SetEmModel(new G4DummyModel());
AddEmModel(2, EmModel(0));
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MicroElecInelastic_new::PrintInfo()
{
// V.I. printout of models is performed by model manager
// if this extra printout is needed it should be
// protected by verbosity level
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,181 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecLOPhononModel.cc,
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
//
// - J. Pierron, C. Inguimbert, M. Belhaj, T. Gineste, J. Puech, M. Raine
// Electron emission yield for low energy electrons:
// Monte Carlo simulation and experimental comparison for Al, Ag, and Si
// Journal of Applied Physics 121 (2017) 215107.
// https://doi.org/10.1063/1.4984761
//
// - P. Caron,
// Study of Electron-Induced Single-Event Upset in Integrated Memory Devices
// PHD, 16th October 2019
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MicroElecLOPhononModel.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
G4MicroElecLOPhononModel::G4MicroElecLOPhononModel(const G4ParticleDefinition*,
const G4String& nam)
: G4VEmModel(nam),isInitialised(false)
{
abs = false;
fParticleChangeForGamma = GetParticleChangeForGamma();
G4cout << "SiO2 Phonon model is constructed " << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4MicroElecLOPhononModel::~G4MicroElecLOPhononModel()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MicroElecLOPhononModel::Initialise(const G4ParticleDefinition* /*particle*/,
const G4DataVector& /*cuts*/)
{
if (isOkToBeInitialised == true && isInitialised == false) {
G4cout << "Calling G4MicroElecLOPhononModel" << "::Initialise()" << G4endl;
if (isInitialised) { return; }
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MicroElecLOPhononModel::CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double, G4double)
{
G4double e = CLHEP::eplus / coulomb,
m0 = CLHEP::electron_mass_c2 / c_squared / kg,
h = CLHEP::hbar_Planck / (m2*kg / s),
eps0 = CLHEP::epsilon0 / (farad / m),
kb = CLHEP::k_Boltzmann / (joule / kelvin);
G4double eps = 9,
einf = 3,
T = 300;
isOkToBeInitialised = true;
const G4DataVector cuts;
Initialise(p, cuts);
if (material->GetName()!="G4_SILICON_DIOXIDE") return 1/DBL_MAX;
G4double E =(ekin/eV)*e;
// Parameters SiO2
eps = 3.84;
einf = 2.25;
phononEnergy = (0.75*0.153+0.25*0.063 )* eV;
G4double hw = (phononEnergy / eV) * e;
G4double n = 1.0 / (std::exp(hw / (kb*T)) - 1); //Phonon distribution
if (abs) { //Absorption
Eprim = E + hw;
signe = -1;
}
else { //Emission
Eprim = E - hw;
signe = +1;
}
G4double racine = std::sqrt(1. + ((-signe*hw) / E));
G4double P = (std::pow(e, 2) / (4 * pi*eps0*h*h)) * (n + 0.5 + signe*0.5) * ((1 / einf) - (1 / eps)) * std::sqrt(m0 / (2 * E)) *hw* std::log((1 + racine) / (signe * 1 + ((-signe)*racine)));
G4double MFP = (std::sqrt(2. * E / m0) / P)*m;
return 2 / MFP;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MicroElecLOPhononModel::SampleSecondaries(
std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle* aDynamicElectron,
G4double, G4double)
{
G4double E = aDynamicElectron->GetKineticEnergy();
if (abs) {
Eprim = E + phononEnergy;
}
else {
Eprim = E - phononEnergy;
}
G4double rand = G4UniformRand();
G4double B = (E + Eprim + 2 * std::sqrt(E*Eprim)) / (E + Eprim - 2 * std::sqrt(E*Eprim));
G4double cosTheta = ((E + Eprim) / (2 * std::sqrt(E*Eprim)))*(1 - std::pow(B, rand)) + std::pow(B, rand);
if(Interband){
cosTheta = 1 - 2 * G4UniformRand(); //Isotrope
}
G4double phi = 2. * pi * G4UniformRand();
G4ThreeVector zVers = aDynamicElectron->GetMomentumDirection();
G4ThreeVector xVers = zVers.orthogonal();
G4ThreeVector yVers = zVers.cross(xVers);
G4double xDir = std::sqrt(1. - cosTheta*cosTheta);
G4double yDir = xDir;
xDir *= std::cos(phi);
yDir *= std::sin(phi);
G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
fParticleChangeForGamma->SetProposedKineticEnergy(Eprim);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -24,79 +24,84 @@
// ********************************************************************
//
//
// G4MuElecElastic.cc, 2011/08/29 A.Valentin, M. Raine
// G4MicroElecLOPhononScattering.cc,
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66 - 73, 2012.
//
// - J. Pierron, C. Inguimbert, M. Belhaj, T. Gineste, J. Puech, M. Raine
// Electron emission yield for low energy electrons:
// Monte Carlo simulation and experimental comparison for Al, Ag, and Si
// Journal of Applied Physics 121 (2017) 215107.
// https://doi.org/10.1063/1.4984761
//
// - P. Caron,
// Study of Electron-Induced Single-Event Upset in Integrated Memory Devices
// PHD, 16th October 2019
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MuElecElastic.hh"
#include "G4MicroElecLOPhononScattering.hh"
#include "G4DummyModel.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
using namespace std;
G4MuElecElastic::G4MuElecElastic(const G4String& processName,
G4ProcessType type):G4VEmProcess (processName, type),
isInitialised(false)
G4MicroElecLOPhononScattering::G4MicroElecLOPhononScattering(
const G4String& processName, G4ProcessType type)
:G4VEmProcess(processName, type),
isInitialised(false)
{
SetProcessSubType(51);
G4cout << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << " The name of the class G4MuElecElastic is changed to G4MicroElecElastic. " << G4endl;
G4cout << " The obsolete class will be REMOVED with the next release of Geant4. " << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4MuElecElastic::~G4MuElecElastic()
G4MicroElecLOPhononScattering::~G4MicroElecLOPhononScattering()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4MuElecElastic::IsApplicable(const G4ParticleDefinition& p)
G4bool G4MicroElecLOPhononScattering::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Electron::Electron());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecElastic::InitialiseProcess(const G4ParticleDefinition*)
void G4MicroElecLOPhononScattering::InitialiseProcess(const G4ParticleDefinition*)
{
if(!isInitialised)
{
isInitialised = true;
SetBuildTableFlag(false);
if(!EmModel()) SetEmModel(new G4MuElecElasticModel);
EmModel()->SetLowEnergyLimit(5*eV);
EmModel()->SetHighEnergyLimit(100*MeV);
AddEmModel(1, EmModel());
}
if (!isInitialised)
{
isInitialised = true;
SetBuildTableFlag(false);
if (!EmModel(0)) SetEmModel(new G4DummyModel());
AddEmModel(2, EmModel(0));
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MuElecElastic::PrintInfo()
void G4MicroElecLOPhononScattering::PrintInfo()
{
// V.I. printout of models is perfored by model manager
// if this extra printout is needed it should be
// protected by verbosity level
/*
G4cout
<< " Total cross sections computed from " << EmModel()->GetName() << " model"
<< G4endl;
*/
}
// V.I. printout of models is performed by model manager
// if this extra printout is needed it should be
// protected by verbosity level
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -1,70 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4MicroElecSiStructure.cc, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
//
// - Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66 - 73, 2012.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for protons and
// heavy ions in Si, NIM B, vol. 287, pp. 124 - 129, 2012.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MicroElecSiStructure.hh"
#include "G4SystemOfUnits.hh"
G4MicroElecSiStructure::G4MicroElecSiStructure(): nLevels(6)
{
energyConstant.push_back(16.65*eV);
energyConstant.push_back(6.52*eV);
energyConstant.push_back(13.63*eV);
energyConstant.push_back(107.98*eV);
energyConstant.push_back(151.55*eV);
energyConstant.push_back(1828.5*eV);
nLevels = energyConstant.size();
}
G4MicroElecSiStructure::~G4MicroElecSiStructure()
{ }
G4double G4MicroElecSiStructure::Energy(G4int level)
{
G4double energ = 0.;
if (level >=0 && level < nLevels) energ = energyConstant[level];
return energ;
}
@@ -0,0 +1,493 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// G4MicroElecSurface.cc,
// 2020/05/20 P. Caron, C. Inguimbert are with ONERA [b]
// Q. Gibaru is with CEA [a], ONERA [b] and CNES [c]
// M. Raine and D. Lambert are with CEA [a]
//
// A part of this work has been funded by the French space agency(CNES[c])
// [a] CEA, DAM, DIF - 91297 ARPAJON, France
// [b] ONERA - DPHY, 2 avenue E.Belin, 31055 Toulouse, France
// [c] CNES, 18 av.E.Belin, 31401 Toulouse CEDEX, France
//
// Based on the following publications
//
// - Q.Gibaru, C.Inguimbert, P.Caron, M.Raine, D.Lambert, J.Puech,
// Geant4 physics processes for microdosimetry and secondary electron emission simulation :
// Extension of MicroElec to very low energies and new materials
// NIM B, 2020, in review.
//
//
// - Modèle de transport d'électrons à basse énergie (10 eV- 2 keV) pour
// applications spatiales (OSMOSEE, GEANT4), PhD dissertation, 2017.
//
//
////////////////////////////////////////////////////////////////////////
#include "G4MicroElecSurface.hh"
#include "G4ios.hh"
#include "G4PhysicalConstants.hh"
#include "G4EmProcessSubType.hh"
#include "G4GeometryTolerance.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MicroElecSurface::G4MicroElecSurface(const G4String& processName,G4ProcessType type)
: G4VDiscreteProcess(processName, type),
oldMomentum(0.,0.,0.), previousMomentum(0.,0.,0.),
theGlobalNormal(0.,0.,0.), theFacetNormal(0.,0.,0.)
{
if ( verboseLevel > 0)
{
G4cout << GetProcessName() << " is created " << G4endl;
}
isInitialised=false;
SetProcessSubType(25);
theStatus = UndefinedSurf;
material1 = nullptr;
material2 = nullptr;
kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
theParticleMomentum = 0.;
flag_franchissement_surface = false;
flag_normal = false;
flag_reflexion = false;
teleportToDo = teleportDone = false;
ekint = thetat = thetaft = energyThreshold = crossingProbability = 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MicroElecSurface::~G4MicroElecSurface()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool
G4MicroElecSurface::IsApplicable(const G4ParticleDefinition& aParticleType)
{
return ( aParticleType.GetPDGEncoding() == 11 );
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MicroElecSurface::BuildPhysicsTable(const G4ParticleDefinition&)
{
if (isInitialised) { return; }
G4ProductionCutsTable* theCoupleTable =
G4ProductionCutsTable::GetProductionCutsTable();
G4int numOfCouples = theCoupleTable->GetTableSize();
G4cout << "G4MicroElecSurface::Initialise: Ncouples= "
<< numOfCouples << G4endl;
for (G4int i = 0; i < numOfCouples; ++i) {
const G4Material* material =
theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
G4cout << "G4Surface, Material " << i + 1 << " / " << numOfCouples << " : " << material->GetName() << G4endl;
if (material->GetName() == "Vacuum") { tableWF[material->GetName()] = 0; continue; }
G4String mat = material->GetName();
G4MicroElecMaterialStructure str = G4MicroElecMaterialStructure(mat);
tableWF[mat] = str.GetWorkFunction();
}
isInitialised = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange* G4MicroElecSurface::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep)
{
theStatus = UndefinedSurf;
//Definition of the parameters for the particle
aParticleChange.Initialize(aTrack);
aParticleChange.ProposeVelocity(aTrack.GetVelocity());
G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
material1 = pPreStepPoint -> GetMaterial();
material2 = pPostStepPoint -> GetMaterial();
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
theParticleMomentum = aParticle->GetTotalMomentum();
previousMomentum = oldMomentum;
oldMomentum = aParticle->GetMomentumDirection();
//First case: not a boundary
if (pPostStepPoint->GetStepStatus() != fGeomBoundary ||
pPostStepPoint->GetPhysicalVolume() == pPreStepPoint->GetPhysicalVolume())
{
theStatus = NotAtBoundarySurf;
flag_franchissement_surface = false;
flag_reflexion = false;
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
}
theStatus = UndefinedSurf;
//Third case: same material
if (material1 == material2)
{
theStatus = SameMaterialSurf;
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
}
if (verboseLevel > 0)
{
G4cout << G4endl << " Electron at Boundary! " << G4endl;
G4VPhysicalVolume* thePrePV = pPreStepPoint->GetPhysicalVolume();
G4VPhysicalVolume* thePostPV = pPostStepPoint->GetPhysicalVolume();
if (thePrePV) G4cout << " thePrePV: " << thePrePV->GetName() << G4endl;
if (thePostPV) G4cout << " thePostPV: " << thePostPV->GetName() << G4endl;
G4cout << " Old Momentum Direction: " << oldMomentum << G4endl;
}
//Definition of the parameters for the surface
G4ThreeVector theGlobalPoint = pPostStepPoint->GetPosition();
G4Navigator* theNavigator =
G4TransportationManager::GetTransportationManager()->
GetNavigatorForTracking();
G4bool valid;
theGlobalNormal = theNavigator->GetGlobalExitNormal(theGlobalPoint, &valid);
// G4cout << "Global exit normal = " << theGlobalNormal << " valid = " << valid << G4endl;
if (valid)
{
theGlobalNormal = -theGlobalNormal;
}
else
{
G4ExceptionDescription ed;
ed << " G4MicroElecSurface/PostStepDoIt(): "
<< " The Navigator reports that it returned an invalid normal.\n"
<< "PV: " << pPreStepPoint->GetPhysicalVolume()->GetName()
<< " TrackID= " << aTrack.GetTrackID()
<< " Ekin(MeV)= " << aTrack.GetKineticEnergy()
<< " position: " << theGlobalPoint
<< " direction: " << oldMomentum
<< G4endl;
G4Exception("G4MuElecSurf::PostStepDoIt", "OpBoun01",
FatalException, ed,
"Invalid Surface Normal - Geometry must return valid surface normal");
return 0;
}
//Exception: the particle is not in the right direction
if (oldMomentum * theGlobalNormal > 0.0)
{
theGlobalNormal = -theGlobalNormal;
}
//Second case: step too small
//Corrections bug rotation + réflexion
if (aTrack.GetStepLength()<=kCarTolerance)
{
theStatus = StepTooSmallSurf;
if (pPostStepPoint) {
WorkFunctionTable::iterator postStepWF;
postStepWF = tableWF.find(pPostStepPoint->GetMaterial()->GetName());
WorkFunctionTable::iterator preStepWF;
preStepWF = tableWF.find(pPreStepPoint->GetMaterial()->GetName());
if (postStepWF == tableWF.end()) {
G4String str = "Material ";
str += pPostStepPoint->GetMaterial()->GetName() + " not found!";
G4Exception("G4Surface::G4Surface", "em0002", FatalException, str);
return 0;
}
else if (preStepWF == tableWF.end()) {
G4String str = "Material ";
str += pPreStepPoint->GetMaterial()->GetName() + " not found!";
G4Exception("G4Surface::G4Surface", "em0002", FatalException, str);
return 0;
}
if (pPreStepPoint->GetMaterial() != pPostStepPoint->GetMaterial()) {
flag_franchissement_surface = false;
if (flag_reflexion == true && flag_normal == true) {
aParticleChange.ProposeMomentumDirection(-Reflexion(aStep.GetPostStepPoint()));
flag_reflexion = false;
flag_normal = false;
}
}
}
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
}
flag_normal = (theGlobalNormal.x() == 0.0 && theGlobalNormal.y() == 0.0);
G4LogicalSurface* Surface = nullptr;
Surface = G4LogicalBorderSurface::GetSurface
(pPreStepPoint ->GetPhysicalVolume(),
pPostStepPoint->GetPhysicalVolume());
if (Surface == nullptr)
{
G4bool enteredDaughter=(pPostStepPoint->GetPhysicalVolume()
->GetMotherLogical() ==
pPreStepPoint->GetPhysicalVolume()
->GetLogicalVolume());
if(enteredDaughter)
{
Surface = G4LogicalSkinSurface::GetSurface
(pPostStepPoint->GetPhysicalVolume()->
GetLogicalVolume());
if(Surface == nullptr)
Surface = G4LogicalSkinSurface::GetSurface
(pPreStepPoint->GetPhysicalVolume()->
GetLogicalVolume());
}
else
{
Surface = G4LogicalSkinSurface::GetSurface
(pPreStepPoint->GetPhysicalVolume()->
GetLogicalVolume());
if(Surface == nullptr)
Surface = G4LogicalSkinSurface::GetSurface
(pPostStepPoint->GetPhysicalVolume()->
GetLogicalVolume());
}
}
G4VPhysicalVolume* thePrePV = pPreStepPoint->GetPhysicalVolume();
G4VPhysicalVolume* thePostPV = pPostStepPoint->GetPhysicalVolume();
if (thePostPV)
{
WorkFunctionTable::iterator postStepWF;
postStepWF = tableWF.find(thePostPV->GetLogicalVolume()->GetMaterial()->GetName());
WorkFunctionTable::iterator preStepWF;
preStepWF = tableWF.find(thePrePV->GetLogicalVolume()->GetMaterial()->GetName());
if (postStepWF == tableWF.end()) {
G4String str = "Material ";
str += thePostPV->GetLogicalVolume()->GetMaterial()->GetName() + " not found!";
G4Exception("G4Surface::G4Surface", "em0002", FatalException, str);
return 0;
}
else if (preStepWF == tableWF.end()) {
G4String str = "Material ";
str += thePrePV->GetLogicalVolume()->GetMaterial()->GetName() + " not found!";
G4Exception("G4Surface::G4Surface", "em0002", FatalException, str);
return 0;
}
else
{
G4double thresholdNew = postStepWF->second;
G4double thresholdOld = preStepWF->second;
energyThreshold = thresholdNew - thresholdOld;
}
}
ekint = pPreStepPoint->GetKineticEnergy();
thetat= GetIncidentAngle(); //angle d'incidence
G4double ekinNormalt=ekint*std::cos(thetat)*std::cos(thetat);
G4double atet = std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat);
thetaft = (atet > 1.0) ? pi*0.5 : std::asin(atet);//Angle de réfraction
G4double aleat=G4UniformRand();
const G4double waveVectort=std::sqrt(2*9.1093826E-31*1.602176487E-19)/(6.6260755E-34/(2.0*pi));
//Parameter for an exponential barrier of potential (Thèse P68)
const G4double at=0.5E-10;
//G4double modif already declared in .hh
crossingProbability=0;
G4double kft=waveVectort*std::sqrt(ekint+energyThreshold)*std::cos(thetaft);
G4double kit=waveVectort*std::sqrt(ekinNormalt);
G4double yy = std::sinh(pi*at*(kit-kft))/std::sinh(pi*at*(kit+kft));
crossingProbability = 1 - yy*yy;
//First case: the electron crosses the surface
if((aleat<=crossingProbability)&&(ekint>std::abs(energyThreshold)))
{
if (pPreStepPoint->GetMaterial() != pPostStepPoint->GetMaterial()) {
flag_franchissement_surface = true;
}
thetaft=std::abs(thetaft-thetat);
G4ThreeVector zVerst = aStep.GetPostStepPoint()->GetMomentumDirection();
G4ThreeVector xVerst = zVerst.orthogonal();
G4ThreeVector yVerst = zVerst.cross(xVerst);
G4double cost = std::cos(thetaft);
G4double xDirt = std::sqrt(1. - cost*cost);
G4double yDirt = xDirt;
G4ThreeVector zPrimeVerst = xDirt*xVerst + yDirt*yVerst + cost*zVerst;
aParticleChange.ProposeMomentumDirection(zPrimeVerst.unit());
}
else if ((aleat > crossingProbability) && (ekint>std::abs(energyThreshold)))
{
flag_reflexion = true;
if (flag_normal) { aParticleChange.ProposeMomentumDirection(-oldMomentum.unit()); }
else { aParticleChange.ProposeMomentumDirection(Reflexion(aStep.GetPostStepPoint())); }
}
else {
if (flag_normal) { aParticleChange.ProposeMomentumDirection(-oldMomentum.unit()); }
else { aParticleChange.ProposeMomentumDirection(Reflexion(aStep.GetPostStepPoint())); }
flag_reflexion = true;
}
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecSurface::GetMeanFreePath(const G4Track&, G4double,
G4ForceCondition* condition)
{
*condition = Forced;
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MicroElecSurface::GetIncidentAngle()
{
theFacetNormal=theGlobalNormal;
G4double PdotN = oldMomentum * theFacetNormal;
G4double magP= oldMomentum.mag();
G4double magN= theFacetNormal.mag();
G4double incidentangle = pi - std::acos(PdotN/(magP*magN));
return incidentangle;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ThreeVector G4MicroElecSurface::Reflexion(const G4StepPoint* PostStepPoint)
{
//Normale
G4double Nx = theGlobalNormal.x();
G4double Ny = theGlobalNormal.y();
G4double Nz = theGlobalNormal.z();
//PostStepPoint
G4double PSx = PostStepPoint->GetPosition().x();
G4double PSy = PostStepPoint->GetPosition().y();
G4double PSz = PostStepPoint->GetPosition().z();
//P(alpha,beta,gamma) - PostStep avec translation momentum
G4double alpha = PSx + oldMomentum.x();
G4double beta = PSy + oldMomentum.y();
G4double gamma = PSz + oldMomentum.z();
G4double r = theGlobalNormal.mag();
G4double x, y, z, d, A, B, PM2x, PM2y, PM2z;
d = -(Nx*PSx + Ny*PSy + Nz*PSz);
if (Ny == 0 && Nx == 0) {
gamma = -gamma;
}
else {
if (Ny == 0) {
A = (Nz*Nz*alpha) + (Nx*Nx*PSx) + (Nx*Nz*(PSz - gamma));
B = r*r;
//M(x,y,z) - Projection de P sur la surface
x = A / B;
y = beta;
z = (x - alpha)*(Nz / Nx) + gamma;
}
else {
A = (r*r) / Ny;
B = (beta / Ny)*(Nx*Nx + Nz*Nz) - (Nx*alpha + Nz*gamma + d);
//M(x,y,z) - Projection de P sur la surface
y = B / A;
x = (y - beta)*(Nx / Ny) + alpha;
z = (y - beta)*(Nz / Ny) + gamma;
}
//Vecteur 2*PM
PM2x = 2 * (x - alpha); PM2y = 2 * (y - beta); PM2z = 2 * (z - gamma);
//Nouveau point P
alpha += PM2x; beta += PM2y; gamma += PM2z;
}
G4ThreeVector newMomentum = G4ThreeVector(alpha-PSx,beta-PSy,gamma-PSz);
return newMomentum.unit();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MicroElecSurfaceStatus G4MicroElecSurface::GetStatus() const
{
return theStatus;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MicroElecSurface::SetFlagFranchissement()
{
flag_franchissement_surface = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1,433 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4MuElecElasticModel.cc, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66 - 73, 2012.
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MuElecElasticModel.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4Exp.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
using namespace std;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MuElecElasticModel::G4MuElecElasticModel(const G4ParticleDefinition*,
const G4String& nam)
:G4VEmModel(nam),isInitialised(false)
{
G4cout << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << " The name of the class G4MuElecElasticModel is changed to G4MicroElecElasticModel. " << G4endl;
G4cout << " The obsolete class will be REMOVED with the next release of Geant4. " << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << G4endl;
nistSi = G4NistManager::Instance()->FindOrBuildMaterial("G4_Si");
killBelowEnergy = 16.7 * eV; // Minimum e- energy for energy loss by excitation
lowEnergyLimit = 0 * eV;
lowEnergyLimitOfModel = 5 * eV; // The model lower energy is 5 eV
highEnergyLimit = 100. * MeV;
SetLowEnergyLimit(lowEnergyLimit);
SetHighEnergyLimit(highEnergyLimit);
verboseLevel= 0;
// Verbosity scale:
// 0 = nothing
// 1 = warning for energy non-conservation
// 2 = details of energy budget
// 3 = calculation of cross sections, file openings, sampling of atoms
// 4 = entering in methods
if( verboseLevel>0 )
{
G4cout << "MuElec Elastic model is constructed " << G4endl
<< "Energy range: "
<< lowEnergyLimit / eV << " eV - "
<< highEnergyLimit / keV << " keV"
<< G4endl;
}
fParticleChangeForGamma = 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MuElecElasticModel::~G4MuElecElasticModel()
{
// For total cross section
std::map< G4String,G4MuElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
for (pos = tableData.begin(); pos != tableData.end(); ++pos)
{
G4MuElecCrossSectionDataSet* table = pos->second;
delete table;
}
// For final state
eVecm.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecElasticModel::Initialise(const G4ParticleDefinition* /*particle*/,
const G4DataVector& /*cuts*/)
{
if (verboseLevel > 3)
G4cout << "Calling G4MuElecElasticModel::Initialise()" << G4endl;
// Energy limits
if (LowEnergyLimit() < lowEnergyLimit)
{
G4cout << "G4MuElecElasticModel: low energy limit increased from " <<
LowEnergyLimit()/eV << " eV to " << lowEnergyLimit/eV << " eV" << G4endl;
SetLowEnergyLimit(lowEnergyLimit);
}
if (HighEnergyLimit() > highEnergyLimit)
{
G4cout << "G4MuElecElasticModel: high energy limit decreased from " <<
HighEnergyLimit()/MeV << " MeV to " << highEnergyLimit/MeV << " MeV" << G4endl;
SetHighEnergyLimit(highEnergyLimit);
}
// Reading of data files
G4double scaleFactor = 1e-18 * cm * cm;
G4String fileElectron("microelec/sigma_elastic_e_Si");
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
G4String electron;
// For total cross section
electron = electronDef->GetParticleName();
tableFile[electron] = fileElectron;
G4MuElecCrossSectionDataSet* tableE = new G4MuElecCrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
tableE->LoadData(fileElectron);
tableData[electron] = tableE;
// For final state
char *path = std::getenv("G4LEDATA");
if (!path)
{
G4Exception("G4MuElecElasticModel::Initialise","em0006",FatalException,"G4LEDATA environment variable not set.");
return;
}
std::ostringstream eFullFileName;
eFullFileName << path << "/microelec/sigmadiff_elastic_e_Si.dat";
std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
if (!eDiffCrossSection)
G4Exception("G4MuElecElasticModel::Initialise","em0003",FatalException,"Missing data file: /microelec/sigmadiff_elastic_e_Si.dat");
eTdummyVec.push_back(0.);
while(!eDiffCrossSection.eof())
{
double tDummy;
double eDummy;
eDiffCrossSection>>tDummy>>eDummy;
// SI : mandatory eVecm initialization
if (tDummy != eTdummyVec.back())
{
eTdummyVec.push_back(tDummy);
eVecm[tDummy].push_back(0.);
}
eDiffCrossSection>>eDiffCrossSectionData[tDummy][eDummy];
// SI : only if not end of file reached !
if (!eDiffCrossSection.eof()) eDiffCrossSectionData[tDummy][eDummy]*=scaleFactor;
if (eDummy != eVecm[tDummy].back()) eVecm[tDummy].push_back(eDummy);
}
// End final state
if (verboseLevel > 2)
G4cout << "Loaded cross section files for MuElec Elastic model" << G4endl;
if( verboseLevel>0 )
{
G4cout << "MuElec Elastic model is initialized " << G4endl
<< "Energy range: "
<< LowEnergyLimit() / eV << " eV - "
<< HighEnergyLimit() / keV << " keV"
<< G4endl;
}
if (isInitialised) { return; }
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
// InitialiseElementSelectors(particle,cuts);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuElecElasticModel::CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double,
G4double)
{
if (verboseLevel > 3)
G4cout << "Calling CrossSectionPerVolume() of G4MuElecElasticModel" << G4endl;
// Calculate total cross section for model
G4double sigma=0;
G4double density = material->GetTotNbOfAtomsPerVolume();
if (material == nistSi || material->GetBaseMaterial() == nistSi)
{
const G4String& particleName = p->GetParticleName();
if (ekin < highEnergyLimit)
{
//SI : XS must not be zero otherwise sampling of secondaries method ignored
if (ekin < lowEnergyLimitOfModel) ekin = lowEnergyLimitOfModel;
//
std::map< G4String,G4MuElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
pos = tableData.find(particleName);
if (pos != tableData.end())
{
G4MuElecCrossSectionDataSet* table = pos->second;
if (table != 0)
{
sigma = table->FindValue(ekin);
}
}
else
{
G4Exception("G4MuElecElasticModel::ComputeCrossSectionPerVolume","em0002",FatalException,"Model not applicable to particle type.");
}
}
if (verboseLevel > 3)
{
G4cout << "---> Kinetic energy(eV)=" << ekin/eV << G4endl;
G4cout << " - Cross section per Si atom (cm^2)=" << sigma/cm/cm << G4endl;
G4cout << " - Cross section per Si atom (cm^-1)=" << sigma*density/(1./cm) << G4endl;
}
}
return sigma*density;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecElasticModel::SampleSecondaries(std::vector<G4DynamicParticle*>* /*fvect*/,
const G4MaterialCutsCouple* /*couple*/,
const G4DynamicParticle* aDynamicElectron,
G4double,
G4double)
{
if (verboseLevel > 3)
G4cout << "Calling SampleSecondaries() of G4MuElecElasticModel" << G4endl;
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
if (electronEnergy0 < killBelowEnergy)
{
fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
fParticleChangeForGamma->ProposeLocalEnergyDeposit(electronEnergy0);
return ;
}
if (electronEnergy0>= killBelowEnergy && electronEnergy0 < highEnergyLimit)
{
G4double cosTheta = RandomizeCosTheta(electronEnergy0);
G4double phi = 2. * pi * G4UniformRand();
G4ThreeVector zVers = aDynamicElectron->GetMomentumDirection();
G4ThreeVector xVers = zVers.orthogonal();
G4ThreeVector yVers = zVers.cross(xVers);
G4double xDir = std::sqrt(1. - cosTheta*cosTheta);
G4double yDir = xDir;
xDir *= std::cos(phi);
yDir *= std::sin(phi);
G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit()) ;
fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuElecElasticModel::Theta
(G4ParticleDefinition * particleDefinition, G4double k, G4double integrDiff)
{
G4double theta = 0.;
G4double valueT1 = 0;
G4double valueT2 = 0;
G4double valueE21 = 0;
G4double valueE22 = 0;
G4double valueE12 = 0;
G4double valueE11 = 0;
G4double xs11 = 0;
G4double xs12 = 0;
G4double xs21 = 0;
G4double xs22 = 0;
if (particleDefinition == G4Electron::ElectronDefinition())
{
std::vector<double>::iterator t2 = std::upper_bound(eTdummyVec.begin(),eTdummyVec.end(), k);
std::vector<double>::iterator t1 = t2-1;
std::vector<double>::iterator e12 = std::upper_bound(eVecm[(*t1)].begin(),eVecm[(*t1)].end(), integrDiff);
std::vector<double>::iterator e11 = e12-1;
std::vector<double>::iterator e22 = std::upper_bound(eVecm[(*t2)].begin(),eVecm[(*t2)].end(), integrDiff);
std::vector<double>::iterator e21 = e22-1;
valueT1 =*t1;
valueT2 =*t2;
valueE21 =*e21;
valueE22 =*e22;
valueE12 =*e12;
valueE11 =*e11;
xs11 = eDiffCrossSectionData[valueT1][valueE11];
xs12 = eDiffCrossSectionData[valueT1][valueE12];
xs21 = eDiffCrossSectionData[valueT2][valueE21];
xs22 = eDiffCrossSectionData[valueT2][valueE22];
}
if (xs11==0 || xs12==0 ||xs21==0 ||xs22==0) return (0.);
theta = QuadInterpolator( valueE11, valueE12,
valueE21, valueE22,
xs11, xs12,
xs21, xs22,
valueT1, valueT2,
k, integrDiff );
return theta;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuElecElasticModel::LinLogInterpolate(G4double e1,
G4double e2,
G4double e,
G4double xs1,
G4double xs2)
{
G4double d1 = std::log(xs1);
G4double d2 = std::log(xs2);
G4double value = G4Exp(d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuElecElasticModel::LogLogInterpolate(G4double e1,
G4double e2,
G4double e,
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));
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuElecElasticModel::QuadInterpolator(G4double e11, G4double e12,
G4double e21, G4double e22,
G4double xs11, G4double xs12,
G4double xs21, G4double xs22,
G4double t1, G4double t2,
G4double t, G4double e)
{
// Lin-Log
G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuElecElasticModel::RandomizeCosTheta(G4double k)
{
G4double integrdiff=0;
G4double uniformRand=G4UniformRand();
integrdiff = uniformRand;
G4double theta=0.;
G4double cosTheta=0.;
theta = Theta(G4Electron::ElectronDefinition(),k/eV,integrdiff);
cosTheta= std::cos(theta*pi/180);
return cosTheta;
}
@@ -1,148 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4MuElecInelastic.cc, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
//
// - Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66 - 73, 2012.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for protons and
// heavy ions in Si, NIM B, vol. 287, pp. 124 - 129, 2012.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MuElecInelastic.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
using namespace std;
G4MuElecInelastic::G4MuElecInelastic(const G4String& processName,
G4ProcessType type):G4VEmProcess (processName, type),
isInitialised(false)
{
SetProcessSubType(53);
G4cout << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << " The name of the class G4MuElecInelastic is changed to G4MicroElecInelastic. " << G4endl;
G4cout << " The obsolete class will be REMOVED with the next release of Geant4. " << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4MuElecInelastic::~G4MuElecInelastic()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4MuElecInelastic::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Electron::Electron() ||
&p == G4Proton::Proton() ||
(p.GetPDGCharge() != 0.0 && !p.IsShortLived() && p.GetParticleType() == "nucleus"));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecInelastic::InitialiseProcess(const G4ParticleDefinition* p)
{
if(!isInitialised)
{
isInitialised = true;
SetBuildTableFlag(false);
G4String name = p->GetParticleName();
if(name == "e-")
{
if(!EmModel()) SetEmModel(new G4MuElecInelasticModel);
EmModel()->SetLowEnergyLimit(16.7*eV);
EmModel()->SetHighEnergyLimit(100*MeV);
AddEmModel(1, EmModel());
}
else if(name == "proton")
{
if(!EmModel()) SetEmModel(new G4MuElecInelasticModel);
EmModel()->SetLowEnergyLimit(50.*keV);
EmModel()->SetHighEnergyLimit(10*GeV);
AddEmModel(1, EmModel());
}
else if(name == "GenericIon")
{
if(!EmModel()) SetEmModel(new G4MuElecInelasticModel);
EmModel()->SetLowEnergyLimit(50.*keV);
EmModel()->SetHighEnergyLimit(10000.*GeV);
AddEmModel(1, EmModel());
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MuElecInelastic::PrintInfo()
{
// V.I. printout of models is perfored by model manager
// if this extra printout is needed it should be
// protected by verbosity level
/*
if (EmModel(2))
{
G4cout
<< " Total cross sections computed from "
<< EmModel(1)->GetName()
<< " and "
<< EmModel(2)->GetName()
<< " models"
<< G4endl;
}
else
{
G4cout
<< " Total cross sections computed from "
<< EmModel()->GetName()
<< G4endl;
}
*/
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -1,799 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4MuElecInelasticModel.cc, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
//
// - Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66 - 73, 2012.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for protons and
// heavy ions in Si, NIM B, vol. 287, pp. 124 - 129, 2012.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MuElecInelasticModel.hh"
#include "globals.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4ios.hh"
#include "G4UnitsTable.hh"
#include "G4UAtomicDeexcitation.hh"
#include "G4LossTableManager.hh"
#include "G4ionEffectiveCharge.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
using namespace std;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MuElecInelasticModel::G4MuElecInelasticModel(const G4ParticleDefinition*,
const G4String& nam)
:G4VEmModel(nam),fAtomDeexcitation(0),isInitialised(false)
{
G4cout << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << " The name of the class G4MuElecInelasticModel is changed to G4MicroElecInelasticModel. " << G4endl;
G4cout << " The obsolete class will be REMOVED with the next release of Geant4. " << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << "*******************************************************************************" << G4endl;
G4cout << G4endl;
nistSi = G4NistManager::Instance()->FindOrBuildMaterial("G4_Si");
verboseLevel= 0;
// Verbosity scale:
// 0 = nothing
// 1 = warning for energy non-conservation
// 2 = details of energy budget
// 3 = calculation of cross sections, file openings, sampling of atoms
// 4 = entering in methods
if( verboseLevel>0 )
{
G4cout << "MuElec inelastic model is constructed " << G4endl;
}
//Mark this model as "applicable" for atomic deexcitation
SetDeexcitationFlag(true);
fParticleChangeForGamma = 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4MuElecInelasticModel::~G4MuElecInelasticModel()
{
// Cross section
std::map< G4String,G4MuElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
for (pos = tableData.begin(); pos != tableData.end(); ++pos)
{
G4MuElecCrossSectionDataSet* table = pos->second;
delete table;
}
// Final state
eVecm.clear();
pVecm.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecInelasticModel::Initialise(const G4ParticleDefinition* particle,
const G4DataVector& /*cuts*/)
{
if (verboseLevel > 3)
G4cout << "Calling G4MuElecInelasticModel::Initialise()" << G4endl;
// Energy limits
G4String fileElectron("microelec/sigma_inelastic_e_Si");
G4String fileProton("microelec/sigma_inelastic_p_Si");
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
G4String electron;
G4String proton;
G4double scaleFactor = 1e-18 * cm *cm;
char *path = std::getenv("G4LEDATA");
// *** ELECTRON
electron = electronDef->GetParticleName();
tableFile[electron] = fileElectron;
lowEnergyLimit[electron] = 16.7 * eV;
highEnergyLimit[electron] = 100.0 * MeV;
// Cross section
G4MuElecCrossSectionDataSet* tableE = new G4MuElecCrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
tableE->LoadData(fileElectron);
tableData[electron] = tableE;
// Final state
std::ostringstream eFullFileName;
eFullFileName << path << "/microelec/sigmadiff_inelastic_e_Si.dat";
std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
if (!eDiffCrossSection)
{
G4Exception("G4MuElecInelasticModel::Initialise","em0003",FatalException,"Missing data file:/microelec/sigmadiff_inelastic_e_Si.dat");
}
eTdummyVec.push_back(0.);
while(!eDiffCrossSection.eof())
{
double tDummy;
double eDummy;
eDiffCrossSection>>tDummy>>eDummy;
if (tDummy != eTdummyVec.back()) eTdummyVec.push_back(tDummy);
for (int j=0; j<6; j++)
{
eDiffCrossSection>>eDiffCrossSectionData[j][tDummy][eDummy];
// SI - only if eof is not reached !
if (!eDiffCrossSection.eof()) eDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
eVecm[tDummy].push_back(eDummy);
}
}
//
// *** PROTON
proton = protonDef->GetParticleName();
tableFile[proton] = fileProton;
lowEnergyLimit[proton] = 50. * keV;
highEnergyLimit[proton] = 10. * GeV;
// Cross section
G4MuElecCrossSectionDataSet* tableP = new G4MuElecCrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
tableP->LoadData(fileProton);
tableData[proton] = tableP;
// Final state
std::ostringstream pFullFileName;
pFullFileName << path << "/microelec/sigmadiff_inelastic_p_Si.dat";
std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
if (!pDiffCrossSection)
{
G4Exception("G4MuElecInelasticModel::Initialise","em0003",FatalException,"Missing data file:/microelec/sigmadiff_inelastic_p_Si.dat");
}
pTdummyVec.push_back(0.);
while(!pDiffCrossSection.eof())
{
double tDummy;
double eDummy;
pDiffCrossSection>>tDummy>>eDummy;
if (tDummy != pTdummyVec.back()) pTdummyVec.push_back(tDummy);
for (int j=0; j<6; j++)
{
pDiffCrossSection>>pDiffCrossSectionData[j][tDummy][eDummy];
// SI - only if eof is not reached !
if (!pDiffCrossSection.eof()) pDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
pVecm[tDummy].push_back(eDummy);
}
}
if (particle==electronDef)
{
SetLowEnergyLimit(lowEnergyLimit[electron]);
SetHighEnergyLimit(highEnergyLimit[electron]);
}
if (particle==protonDef)
{
SetLowEnergyLimit(lowEnergyLimit[proton]);
SetHighEnergyLimit(highEnergyLimit[proton]);
}
if( verboseLevel>0 )
{
G4cout << "MuElec Inelastic model is initialized " << G4endl
<< "Energy range: "
<< LowEnergyLimit() / eV << " eV - "
<< HighEnergyLimit() / keV << " keV for "
<< particle->GetParticleName()
<< " with mass (amu) " << particle->GetPDGMass()/proton_mass_c2
<< " and charge " << particle->GetPDGCharge()
<< G4endl << G4endl ;
}
//
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
if (isInitialised) { return; }
fParticleChangeForGamma = GetParticleChangeForGamma();
isInitialised = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuElecInelasticModel::CrossSectionPerVolume(const G4Material* material,
const G4ParticleDefinition* particleDefinition,
G4double ekin,
G4double,
G4double)
{
if (verboseLevel > 3)
G4cout << "Calling CrossSectionPerVolume() of G4MuElecInelasticModel" << G4endl;
G4double density = material->GetTotNbOfAtomsPerVolume();
/* if (
particleDefinition != G4Proton::ProtonDefinition()
&&
particleDefinition != G4Electron::ElectronDefinition()
&&
particleDefinition != G4GenericIon::GenericIonDefinition()
)
return 0;*/
// Calculate total cross section for model
G4double lowLim = 0;
G4double highLim = 0;
G4double sigma=0;
const G4String& particleName = particleDefinition->GetParticleName();
G4String nameLocal = particleName ;
G4double Zeff2 = 1.0;
G4double Mion_c2 = particleDefinition->GetPDGMass();
if (Mion_c2 > proton_mass_c2)
{
G4ionEffectiveCharge EffCharge ;
G4double Zeff = EffCharge.EffectiveCharge(particleDefinition, material,ekin);
Zeff2 = Zeff*Zeff;
if (verboseLevel > 3)
G4cout << "Before scaling : " << G4endl
<< "Particle : " << nameLocal << ", mass : " << Mion_c2/proton_mass_c2 << "*mp, charge " << Zeff
<< ", Ekin (eV) = " << ekin/eV << G4endl ;
ekin *= proton_mass_c2/Mion_c2 ;
nameLocal = "proton" ;
if (verboseLevel > 3)
G4cout << "After scaling : " << G4endl
<< "Particle : " << nameLocal << ", Ekin (eV) = " << ekin/eV << G4endl ;
}
if (material == nistSi || material->GetBaseMaterial() == nistSi)
{
std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
pos1 = lowEnergyLimit.find(nameLocal);
if (pos1 != lowEnergyLimit.end())
{
lowLim = pos1->second;
}
std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
pos2 = highEnergyLimit.find(nameLocal);
if (pos2 != highEnergyLimit.end())
{
highLim = pos2->second;
}
if (ekin >= lowLim && ekin < highLim)
{
std::map< G4String,G4MuElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
pos = tableData.find(nameLocal);
if (pos != tableData.end())
{
G4MuElecCrossSectionDataSet* table = pos->second;
if (table != 0)
{
sigma = table->FindValue(ekin);
}
}
else
{
G4Exception("G4MuElecInelasticModel::CrossSectionPerVolume","em0002",FatalException,"Model not applicable to particle type.");
}
}
else
{
if (nameLocal!="e-")
{
// G4cout << "Particle : " << nameLocal << ", Ekin (eV) = " << ekin/eV << G4endl;
// G4cout << "### Warning: particle energy out of bounds! ###" << G4endl;
}
}
if (verboseLevel > 3)
{
G4cout << "---> Kinetic energy (eV)=" << ekin/eV << G4endl;
G4cout << " - Cross section per Si atom (cm^2)=" << sigma*Zeff2/cm2 << G4endl;
G4cout << " - Cross section per Si atom (cm^-1)=" << sigma*density*Zeff2/(1./cm) << G4endl;
}
} // if (SiMaterial)
return sigma*density*Zeff2;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuElecInelasticModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
const G4MaterialCutsCouple* /*couple*/,
const G4DynamicParticle* particle,
G4double,
G4double)
{
if (verboseLevel > 3)
G4cout << "Calling SampleSecondaries() of G4MuElecInelasticModel" << G4endl;
G4double lowLim = 0;
G4double highLim = 0;
G4double ekin = particle->GetKineticEnergy();
G4double k = ekin ;
G4ParticleDefinition* PartDef = particle->GetDefinition();
const G4String& particleName = PartDef->GetParticleName();
G4String nameLocal2 = particleName ;
G4double particleMass = particle->GetDefinition()->GetPDGMass();
if (particleMass > proton_mass_c2)
{
k *= proton_mass_c2/particleMass ;
PartDef = G4Proton::ProtonDefinition();
nameLocal2 = "proton" ;
}
std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
pos1 = lowEnergyLimit.find(nameLocal2);
if (pos1 != lowEnergyLimit.end())
{
lowLim = pos1->second;
}
std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
pos2 = highEnergyLimit.find(nameLocal2);
if (pos2 != highEnergyLimit.end())
{
highLim = pos2->second;
}
if (k >= lowLim && k < highLim)
{
G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
G4double totalEnergy = ekin + particleMass;
G4double pSquare = ekin * (totalEnergy + particleMass);
G4double totalMomentum = std::sqrt(pSquare);
G4int Shell = RandomSelect(k,nameLocal2);
G4double bindingEnergy = SiStructure.Energy(Shell);
if (verboseLevel > 3)
{
G4cout << "---> Kinetic energy (eV)=" << k/eV << G4endl ;
G4cout << "Shell: " << Shell << ", energy: " << bindingEnergy/eV << G4endl;
}
// sample deexcitation
G4int secNumberInit = 0; // need to know at a certain point the energy of secondaries
G4int secNumberFinal = 0; // So I'll make the difference and then sum the energies
if(fAtomDeexcitation && Shell > 2) {
G4int Z = 14;
G4AtomicShellEnumerator as = fKShell;
if (Shell == 4)
{
as = G4AtomicShellEnumerator(1);
}
else if (Shell == 3)
{
as = G4AtomicShellEnumerator(3);
}
const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
secNumberInit = fvect->size();
fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
secNumberFinal = fvect->size();
}
G4double secondaryKinetic = RandomizeEjectedElectronEnergy(PartDef,k,Shell);
if (verboseLevel > 3)
{
G4cout << "Ionisation process" << G4endl;
G4cout << "Shell: " << Shell << " Kin. energy (eV)=" << k/eV
<< " Sec. energy (eV)=" << secondaryKinetic/eV << G4endl;
}
G4double cosTheta = 0.;
G4double phi = 0.;
RandomizeEjectedElectronDirection(PartDef, k, secondaryKinetic, cosTheta, phi);
G4double sinTheta = std::sqrt(1.-cosTheta*cosTheta);
G4double dirX = sinTheta*std::cos(phi);
G4double dirY = sinTheta*std::sin(phi);
G4double dirZ = cosTheta;
G4ThreeVector deltaDirection(dirX,dirY,dirZ);
deltaDirection.rotateUz(primaryDirection);
//if (particle->GetDefinition() == G4Electron::ElectronDefinition())
//{
G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
finalPx /= finalMomentum;
finalPy /= finalMomentum;
finalPz /= finalMomentum;
G4ThreeVector direction;
direction.set(finalPx,finalPy,finalPz);
fParticleChangeForGamma->ProposeMomentumDirection(direction.unit()) ;
//}
//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-bindingEnergy-secondaryKinetic);
fParticleChangeForGamma->ProposeLocalEnergyDeposit(bindingEnergy-deexSecEnergy);
G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic) ;
fvect->push_back(dp);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuElecInelasticModel::RandomizeEjectedElectronEnergy(G4ParticleDefinition* particleDefinition,
G4double k, G4int shell)
{
if (particleDefinition == G4Electron::ElectronDefinition())
{
G4double maximumEnergyTransfer=0.;
if ((k+SiStructure.Energy(shell))/2. > k) maximumEnergyTransfer=k;
else maximumEnergyTransfer = (k+SiStructure.Energy(shell))/2.;
G4double crossSectionMaximum = 0.;
G4double minEnergy = SiStructure.Energy(shell);
G4double maxEnergy = maximumEnergyTransfer;
G4int nEnergySteps = 100;
G4double value(minEnergy);
G4double stpEnergy(std::pow(maxEnergy/value, 1./static_cast<G4double>(nEnergySteps-1)));
G4int step(nEnergySteps);
while (step>0)
{
step--;
G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
value*=stpEnergy;
}
G4double secondaryElectronKineticEnergy=0.;
do
{
secondaryElectronKineticEnergy = G4UniformRand() * (maximumEnergyTransfer-SiStructure.Energy(shell));
} while(G4UniformRand()*crossSectionMaximum >
DifferentialCrossSection(particleDefinition, k/eV,(secondaryElectronKineticEnergy+SiStructure.Energy(shell))/eV,shell));
return secondaryElectronKineticEnergy;
}
if (particleDefinition == G4Proton::ProtonDefinition())
{
G4double maximumEnergyTransfer = 4.* (electron_mass_c2 / proton_mass_c2) * k;
G4double crossSectionMaximum = 0.;
G4double minEnergy = SiStructure.Energy(shell);
G4double maxEnergy = maximumEnergyTransfer;
G4int nEnergySteps = 100;
G4double value(minEnergy);
G4double stpEnergy(std::pow(maxEnergy/value, 1./static_cast<G4double>(nEnergySteps-1)));
G4int step(nEnergySteps);
while (step>0)
{
step--;
G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
value*=stpEnergy;
}
G4double secondaryElectronKineticEnergy = 0.;
do
{
secondaryElectronKineticEnergy = G4UniformRand() * (maximumEnergyTransfer-SiStructure.Energy(shell));
} while(G4UniformRand()*crossSectionMaximum >=
DifferentialCrossSection(particleDefinition, k/eV,(secondaryElectronKineticEnergy+SiStructure.Energy(shell))/eV,shell));
return secondaryElectronKineticEnergy;
}
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4MuElecInelasticModel::RandomizeEjectedElectronDirection(G4ParticleDefinition* particleDefinition,
G4double k,
G4double secKinetic,
G4double & cosTheta,
G4double & phi )
{
if (particleDefinition == G4Electron::ElectronDefinition())
{
phi = twopi * G4UniformRand();
G4double sin2O = (1.-secKinetic/k) / (1.+secKinetic/(2.*electron_mass_c2));
cosTheta = std::sqrt(1.-sin2O);
}
if (particleDefinition == G4Proton::ProtonDefinition())
{
G4double maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
phi = twopi * G4UniformRand();
cosTheta = std::sqrt(secKinetic / maxSecKinetic);
}
else
{
G4double maxSecKinetic = 4.* (electron_mass_c2 / particleDefinition->GetPDGMass()) * k;
phi = twopi * G4UniformRand();
cosTheta = std::sqrt(secKinetic / maxSecKinetic);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
double G4MuElecInelasticModel::DifferentialCrossSection(G4ParticleDefinition * particleDefinition,
G4double k,
G4double energyTransfer,
G4int LevelIndex)
{
G4double sigma = 0.;
if (energyTransfer >= SiStructure.Energy(LevelIndex))
{
G4double valueT1 = 0;
G4double valueT2 = 0;
G4double valueE21 = 0;
G4double valueE22 = 0;
G4double valueE12 = 0;
G4double valueE11 = 0;
G4double xs11 = 0;
G4double xs12 = 0;
G4double xs21 = 0;
G4double xs22 = 0;
if (particleDefinition == G4Electron::ElectronDefinition())
{
// k should be in eV and energy transfer eV also
std::vector<double>::iterator t2 = std::upper_bound(eTdummyVec.begin(),eTdummyVec.end(), k);
std::vector<double>::iterator t1 = t2-1;
// SI : the following condition avoids situations where energyTransfer >last vector element
if (energyTransfer <= eVecm[(*t1)].back() && energyTransfer <= eVecm[(*t2)].back() )
{
std::vector<double>::iterator e12 = std::upper_bound(eVecm[(*t1)].begin(),eVecm[(*t1)].end(), energyTransfer);
std::vector<double>::iterator e11 = e12-1;
std::vector<double>::iterator e22 = std::upper_bound(eVecm[(*t2)].begin(),eVecm[(*t2)].end(), energyTransfer);
std::vector<double>::iterator e21 = e22-1;
valueT1 =*t1;
valueT2 =*t2;
valueE21 =*e21;
valueE22 =*e22;
valueE12 =*e12;
valueE11 =*e11;
xs11 = eDiffCrossSectionData[LevelIndex][valueT1][valueE11];
xs12 = eDiffCrossSectionData[LevelIndex][valueT1][valueE12];
xs21 = eDiffCrossSectionData[LevelIndex][valueT2][valueE21];
xs22 = eDiffCrossSectionData[LevelIndex][valueT2][valueE22];
}
}
if (particleDefinition == G4Proton::ProtonDefinition())
{
// k should be in eV and energy transfer eV also
std::vector<double>::iterator t2 = std::upper_bound(pTdummyVec.begin(),pTdummyVec.end(), k);
std::vector<double>::iterator t1 = t2-1;
if (energyTransfer <= pVecm[(*t1)].back() && energyTransfer <= pVecm[(*t2)].back() )
{
std::vector<double>::iterator e12 = std::upper_bound(pVecm[(*t1)].begin(),pVecm[(*t1)].end(), energyTransfer);
std::vector<double>::iterator e11 = e12-1;
std::vector<double>::iterator e22 = std::upper_bound(pVecm[(*t2)].begin(),pVecm[(*t2)].end(), energyTransfer);
std::vector<double>::iterator e21 = e22-1;
valueT1 =*t1;
valueT2 =*t2;
valueE21 =*e21;
valueE22 =*e22;
valueE12 =*e12;
valueE11 =*e11;
xs11 = pDiffCrossSectionData[LevelIndex][valueT1][valueE11];
xs12 = pDiffCrossSectionData[LevelIndex][valueT1][valueE12];
xs21 = pDiffCrossSectionData[LevelIndex][valueT2][valueE21];
xs22 = pDiffCrossSectionData[LevelIndex][valueT2][valueE22];
}
}
G4double xsProduct = xs11 * xs12 * xs21 * xs22;
if (xsProduct != 0.)
{
sigma = QuadInterpolator( valueE11, valueE12,
valueE21, valueE22,
xs11, xs12,
xs21, xs22,
valueT1, valueT2,
k, energyTransfer);
}
}
return sigma;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuElecInelasticModel::LogLogInterpolate(G4double e1,
G4double e2,
G4double e,
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));
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4MuElecInelasticModel::QuadInterpolator(G4double e11, G4double e12,
G4double e21, G4double e22,
G4double xs11, G4double xs12,
G4double xs21, G4double xs22,
G4double t1, G4double t2,
G4double t, G4double e)
{
G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
return value;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int G4MuElecInelasticModel::RandomSelect(G4double k, const G4String& particle )
{
G4int level = 0;
std::map< G4String,G4MuElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
pos = tableData.find(particle);
if (pos != tableData.end())
{
G4MuElecCrossSectionDataSet* table = pos->second;
if (table != 0)
{
G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
const size_t n(table->NumberOfComponents());
size_t i(n);
G4double value = 0.;
while (i>0)
{
i--;
valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
value += valuesBuffer[i];
}
value *= G4UniformRand();
i = n;
while (i > 0)
{
i--;
if (valuesBuffer[i] > value)
{
delete[] valuesBuffer;
return i;
}
value -= valuesBuffer[i];
}
if (valuesBuffer) delete[] valuesBuffer;
}
}
else
{
G4Exception("G4MuElecInelasticModel::RandomSelect","em0002",FatalException,"Model not applicable to particle type.");
}
return level;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -1,70 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4MuElecSiStructure.cc, 2011/08/29 A.Valentin, M. Raine
//
// Based on the following publications
//
// - Inelastic cross-sections of low energy electrons in silicon
// for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
// NSS Conf. Record 2010, pp. 80-85.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for electrons in Si,
// NIM B, vol. 288, pp. 66 - 73, 2012.
// - Geant4 physics processes for microdosimetry simulation:
// very low energy electromagnetic models for protons and
// heavy ions in Si, NIM B, vol. 287, pp. 124 - 129, 2012.
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4MuElecSiStructure.hh"
#include "G4SystemOfUnits.hh"
G4MuElecSiStructure::G4MuElecSiStructure(): nLevels(6)
{
energyConstant.push_back(16.65*eV);
energyConstant.push_back(6.52*eV);
energyConstant.push_back(13.63*eV);
energyConstant.push_back(107.98*eV);
energyConstant.push_back(151.55*eV);
energyConstant.push_back(1828.5*eV);
nLevels = energyConstant.size();
}
G4MuElecSiStructure::~G4MuElecSiStructure()
{ }
G4double G4MuElecSiStructure::Energy(G4int level)
{
G4double energ = 0.;
if (level >=0 && level < nLevels) energ = energyConstant[level];
return energ;
}
@@ -289,7 +289,7 @@ G4double G4PenelopeAnnihilationModel:: ComputeCrossSectionPerElectron(G4double e
G4double gamma2 = gamma*gamma;
G4double f2 = gamma2-1.0;
G4double f1 = std::sqrt(f2);
G4double crossSection = fPielr2*((gamma2+4.0*gamma+1.0)*std::log(gamma+f1)/f2
G4double crossSection = fPielr2*((gamma2+4.0*gamma+1.0)*G4Log(gamma+f1)/f2
- (gamma+3.0)/f1)/(gamma+1.0);
return crossSection;
}
@@ -219,7 +219,7 @@ void G4PenelopeBremsstrahlungAngular::PrepareTables(const G4Material* material,G
//fill vectors
for (k=0;k<NumberofZPoints;k++)
{
QQ1vector->PutValue(k,pZ[k],std::log(QQ1[k][i][j]));
QQ1vector->PutValue(k,pZ[k],G4Log(QQ1[k][i][j]));
QQ2vector->PutValue(k,pZ[k],QQ2[k][i][j]);
}
@@ -259,7 +259,7 @@ void G4PenelopeBremsstrahlungAngular::PrepareTables(const G4Material* material,G
for (j=0;j<NumberofKPoints;j++)
{
Q1vector->PutValue(j,pK[j],std::log(Q1[i][j])); //logarithmic
Q1vector->PutValue(j,pK[j],G4Log(Q1[i][j])); //logarithmic
Q2vector->PutValue(j,pK[j],Q2[i][j]);
}
@@ -338,16 +338,16 @@ void G4PenelopeBremsstrahlungFS::BuildScaledXSTable(const G4Material* material,
(G4PhysicsFreeVector*) ((*thePhysicsTable)[ix]);
for (size_t ie=0;ie<nBinsE;ie++)
{
G4double logene = std::log(theEGrid[ie]);
G4double logene = G4Log(theEGrid[ie]);
G4double aValue = (*tempMatrix)[ie*nBinsX+ix];
if (aValue < 1e-20*millibarn) //protection against log(0)
aValue = 1e-20*millibarn;
theVec->PutValue(ie+1,logene,std::log(aValue));
theVec->PutValue(ie+1,logene,G4Log(aValue));
}
//Add fake point at 1 eV using an extrapolation with the derivative
//at the first valid point (Penelope approach)
G4double derivative = ((*theVec)[2]-(*theVec)[1])/(theVec->Energy(2) - theVec->Energy(1));
G4double log1eV = std::log(1*eV);
G4double log1eV = G4Log(1*eV);
G4double val1eV = (*theVec)[1]+derivative*(log1eV-theVec->Energy(1));
//fake point at very low energy
theVec->PutValue(0,log1eV,val1eV);
@@ -495,7 +495,7 @@ G4double G4PenelopeBremsstrahlungFS::GetMomentumIntegral(G4double* y,
G4double b=dy/dx;
G4double a=y1-b*x1;
if (momOrder == -1)
ds = a*std::log(xtc/x1)+b*(xtc-x1);
ds = a*G4Log(xtc/x1)+b*(xtc-x1);
else if (momOrder == 0) //speed it up, not using pow()
ds = a*(xtc-x1) + 0.5*b*(xtc*xtc-x1*x1);
else
@@ -578,7 +578,7 @@ void G4PenelopeBremsstrahlungFS::InitializeEnergySampling(const G4Material* mate
G4double y2=G4Exp((*v2)[ie+1]);
G4double B = (y2-y1)/(x2-x1);
G4double A = y1-B*x1;
G4double dS = A*std::log(x2/x1)+B*(x2-x1);
G4double dS = A*G4Log(x2/x1)+B*(x2-x1);
value += dS;
theVec->PutValue(ix,theXGrid[ix],value);
}
@@ -537,7 +537,7 @@ void G4PenelopeBremsstrahlungModel::BuildXSTable(const G4Material* mat,G4double
//the 32-point x grid. Interpolation is log-log
size_t nBinsX = fPenelopeFSHelper->GetNBinsX();
G4double* tempData = new G4double[nBinsX];
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
for (size_t ix=0;ix<nBinsX;ix++)
{
//find dSigma/dx for the given E. X belongs to the 32-point grid.
@@ -713,7 +713,7 @@ G4double G4PenelopeBremsstrahlungModel::GetPositronXSCorrection(const G4Material
//by Kim et al. (1986) (cf. Berger and Seltzer, 1982). Here, it is used an
//analytical approximation which reproduces the tabulated values with 0.5%
//accuracy
G4double t=std::log(1.0+1e6*energy/
G4double t=G4Log(1.0+1e6*energy/
(electron_mass_c2*fPenelopeFSHelper->GetEffectiveZSquared(mat)));
G4double corr = 1.0-G4Exp(-t*(1.2359e-1-t*(6.1274e-2-t*
(3.1516e-2-t*(7.7446e-3-t*(1.0595e-3-t*
@@ -326,7 +326,7 @@ void G4PenelopeComptonModel::SampleSecondaries(std::vector<G4DynamicParticle*>*
G4double ek1 = eks-ek2-1.0;
G4double taumin = 1.0/ek2;
G4double a1 = std::log(ek2);
G4double a1 = G4Log(ek2);
G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
G4double TST = 0;
@@ -452,10 +452,10 @@ void G4PenelopeComptonModel::SampleSecondaries(std::vector<G4DynamicParticle*>*
hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor();
oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
if (A < 0.5)
pzomc = (std::sqrt(0.5)-std::sqrt(0.5-std::log(2.0*A)))/
pzomc = (std::sqrt(0.5)-std::sqrt(0.5-G4Log(2.0*A)))/
(std::sqrt(2.0)*hartreeFunc);
else
pzomc = (std::sqrt(0.5-std::log(2.0-2.0*A))-std::sqrt(0.5))/
pzomc = (std::sqrt(0.5-G4Log(2.0-2.0*A))-std::sqrt(0.5))/
(std::sqrt(2.0)*hartreeFunc);
} while (pzomc < -1);
@@ -657,7 +657,7 @@ void G4PenelopeComptonModel::SampleSecondaries(std::vector<G4DynamicParticle*>*
*/
//Always produce explicitely the electron
//Always produce explicitly the electron
G4DynamicParticle* electron = 0;
G4double xEl = sinThetaE * std::cos(phi+pi);
@@ -925,7 +925,7 @@ G4double G4PenelopeComptonModel::KleinNishinaCrossSection(G4double energy,
G4double ek1 = eks-ek2-1.0;
G4double t0 = 1.0/ek2;
G4double csl = 0.5*eks*t0*t0+ek2*t0+ek1*std::log(t0)-(1.0/t0);
G4double csl = 0.5*eks*t0*t0+ek2*t0+ek1*G4Log(t0)-(1.0/t0);
G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material);
@@ -936,7 +936,7 @@ G4double G4PenelopeComptonModel::KleinNishinaCrossSection(G4double energy,
G4double tau=(energy-ionEnergy)/energy;
if (tau > t0)
{
G4double csu = 0.5*eks*tau*tau+ek2*tau+ek1*std::log(tau)-(1.0/tau);
G4double csu = 0.5*eks*tau*tau+ek2*tau+ek1*G4Log(tau)-(1.0/tau);
G4double stre = theOsc->GetOscillatorStrength();
cs += stre*(csu-csl);
@@ -144,35 +144,35 @@ void G4PenelopeCrossSection::AddCrossSectionPoint(size_t binNumber,G4double ener
G4cout << "Trying to register more points than originally declared" << G4endl;
return;
}
G4double logEne = std::log(energy);
G4double logEne = G4Log(energy);
//XS0
G4double val = std::log(std::max(XS0,1e-42*cm2)); //avoid log(0)
G4double val = G4Log(std::max(XS0,1e-42*cm2)); //avoid log(0)
theVector->PutValue(binNumber,logEne,val);
//XS1
theVector = (G4PhysicsFreeVector*) (*softCrossSections)[1];
val = std::log(std::max(XS1,1e-42*eV*cm2)); //avoid log(0)
val = G4Log(std::max(XS1,1e-42*eV*cm2)); //avoid log(0)
theVector->PutValue(binNumber,logEne,val);
//XS2
theVector = (G4PhysicsFreeVector*) (*softCrossSections)[2];
val = std::log(std::max(XS2,1e-42*eV*eV*cm2)); //avoid log(0)
val = G4Log(std::max(XS2,1e-42*eV*eV*cm2)); //avoid log(0)
theVector->PutValue(binNumber,logEne,val);
//XH0
theVector = (G4PhysicsFreeVector*) (*hardCrossSections)[0];
val = std::log(std::max(XH0,1e-42*cm2)); //avoid log(0)
val = G4Log(std::max(XH0,1e-42*cm2)); //avoid log(0)
theVector->PutValue(binNumber,logEne,val);
//XH1
theVector = (G4PhysicsFreeVector*) (*hardCrossSections)[1];
val = std::log(std::max(XH1,1e-42*eV*cm2)); //avoid log(0)
val = G4Log(std::max(XH1,1e-42*eV*cm2)); //avoid log(0)
theVector->PutValue(binNumber,logEne,val);
//XH2
theVector = (G4PhysicsFreeVector*) (*hardCrossSections)[2];
val = std::log(std::max(XH2,1e-42*eV*eV*cm2)); //avoid log(0)
val = G4Log(std::max(XH2,1e-42*eV*eV*cm2)); //avoid log(0)
theVector->PutValue(binNumber,logEne,val);
return;
@@ -212,8 +212,8 @@ void G4PenelopeCrossSection::AddShellCrossSectionPoint(size_t binNumber,
G4cout << "Trying to register more points than originally declared" << G4endl;
return;
}
G4double logEne = std::log(energy);
G4double val = std::log(std::max(xs,1e-42*cm2)); //avoid log(0)
G4double logEne = G4Log(energy);
G4double val = G4Log(std::max(xs,1e-42*cm2)); //avoid log(0)
theVector->PutValue(binNumber,logEne,val);
return;
@@ -242,7 +242,7 @@ G4double G4PenelopeCrossSection::GetTotalCrossSection(G4double energy) const
G4cout << "Soft cross section table looks not filled" << G4endl;
return result;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4double logXS = theVector->Value(logene);
G4double softXS = G4Exp(logXS);
@@ -285,7 +285,7 @@ G4double G4PenelopeCrossSection::GetHardCrossSection(G4double energy) const
G4cout << "Hard cross section table looks not filled" << G4endl;
return result;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4double logXS = theVector->Value(logene);
result = G4Exp(logXS);
@@ -315,7 +315,7 @@ G4double G4PenelopeCrossSection::GetSoftStoppingPower(G4double energy) const
G4cout << "Soft cross section table looks not filled" << G4endl;
return result;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4double logXS = theVector->Value(logene);
result = G4Exp(logXS);
@@ -352,7 +352,7 @@ G4double G4PenelopeCrossSection::GetShellCrossSection(size_t shellID,G4double en
G4cout << "Shell cross section table looks not filled" << G4endl;
return result;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4double logXS = theVector->Value(logene);
result = G4Exp(logXS);
@@ -397,7 +397,7 @@ G4double G4PenelopeCrossSection::GetNormalizedShellCrossSection(size_t shellID,G
G4cout << "Shell cross section table looks not filled" << G4endl;
return result;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4double logXS = theVector->Value(logene);
result = G4Exp(logXS);
@@ -439,7 +439,7 @@ void G4PenelopeCrossSection::NormalizeShellCrossSections()
normFactor += G4Exp((*theVec)[i]);
}
G4double logNormFactor = std::log(normFactor);
G4double logNormFactor = G4Log(normFactor);
//Normalize
for (size_t shellID=0;shellID<numberOfShells;shellID++)
{
@@ -153,7 +153,7 @@ void G4PenelopeGammaConversionModel::Initialise(const G4ParticleDefinition* part
for (size_t j=0;j<material->GetNumberOfElements();j++)
{
G4int iZ = (G4int) theElementVector->at(j)->GetZ();
G4int iZ = theElementVector->at(j)->GetZasInt();
//read data files only in the master
if (!logAtomicCrossSection->count(iZ))
ReadDataFile(iZ);
@@ -263,7 +263,7 @@ G4double G4PenelopeGammaConversionModel::ComputeCrossSectionPerAtom(
}
G4double cs = 0;
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4PhysicsFreeVector* theVec = logAtomicCrossSection->find(iZ)->second;
@@ -480,7 +480,7 @@ G4PenelopeGammaConversionModel::SampleSecondaries(std::vector<G4DynamicParticle*
G4cout << "Incoming photon energy: " << photonEnergy/keV << " keV" << G4endl;
G4cout << "-----------------------------------------------------------" << G4endl;
if (electronKineEnergy)
G4cout << "Electron (explicitely produced) " << electronKineEnergy/keV << " keV"
G4cout << "Electron (explicitly produced) " << electronKineEnergy/keV << " keV"
<< G4endl;
if (positronKineEnergy)
G4cout << "Positron (not at rest) " << positronKineEnergy/keV << " keV" << G4endl;
@@ -583,7 +583,7 @@ void G4PenelopeGammaConversionModel::ReadDataFile(const G4int Z)
xs *= barn;
if (xs < 1e-40*cm2) //protection against log(0)
xs = 1e-40*cm2;
theVec->PutValue(i,std::log(ene),std::log(xs));
theVec->PutValue(i,G4Log(ene),G4Log(xs));
}
file.close();
@@ -699,7 +699,7 @@ void G4PenelopeGammaConversionModel::InitializeScreeningFunctions(const G4Materi
fMaterialInvScreeningRadius->insert(std::make_pair(material,matRadius));
std::pair<G4double,G4double> myPair(0,0);
G4double f0a = 4.0*std::log(fAtomicScreeningRadius[intZ-1]);
G4double f0a = 4.0*G4Log(fAtomicScreeningRadius[intZ-1]);
G4double f0b = f0a - 4.0*fc;
myPair.first = f0a;
myPair.second = f0b;
@@ -732,7 +732,7 @@ G4PenelopeGammaConversionModel::GetScreeningFunctions(G4double B)
//
std::pair<G4double,G4double> result(0.,0.);
G4double BSquared = B*B;
G4double f1 = 2.0-2.0*std::log(1.0+BSquared);
G4double f1 = 2.0-2.0*G4Log(1.0+BSquared);
G4double f2 = f1 - 6.66666666e-1; // (-2/3)
if (B < 1.0e-10)
f1 = f1-twopi*B;
@@ -740,7 +740,7 @@ G4PenelopeGammaConversionModel::GetScreeningFunctions(G4double B)
{
G4double a0 = 4.0*B*std::atan(1./B);
f1 = f1 - a0;
f2 += 2.0*BSquared*(4.0-a0-3.0*std::log((1.0+BSquared)/BSquared));
f2 += 2.0*BSquared*(4.0-a0-3.0*G4Log((1.0+BSquared)/BSquared));
}
G4double g1 = 0.5*(3.0*f1-f2);
G4double g2 = 0.25*(3.0*f1+f2);
@@ -788,7 +788,7 @@ void G4PenelopeIonisationModel::SampleFinalStateElectron(const G4Material* mat,
{
cps = kineticEnergy*rb;
cp = std::sqrt(cps);
G4double XHDT0 = std::max(std::log(gam2)-beta2-delta,0.);
G4double XHDT0 = std::max(G4Log(gam2)-beta2-delta,0.);
if (resEne > 1.0e-6*kineticEnergy)
{
G4double cpp = std::sqrt((kineticEnergy-resEne)*(kineticEnergy-resEne+2.0*electron_mass_c2));
@@ -801,7 +801,7 @@ void G4PenelopeIonisationModel::SampleFinalStateElectron(const G4Material* mat,
}
if (QM < cutoffEne)
{
XHDL = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)))
XHDL = G4Log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)))
*invResEne;
XHDT = XHDT0*invResEne;
}
@@ -832,7 +832,7 @@ void G4PenelopeIonisationModel::SampleFinalStateElectron(const G4Material* mat,
G4double rl1 = 1.0-rcl;
G4double rrl1 = 1.0/rl1;
XHC = (amol*(0.5-rcl)+1.0/rcl-rrl1+
(1.0-amol)*std::log(rcl*rrl1))/EE;
(1.0-amol)*G4Log(rcl*rrl1))/EE;
}
//Total cross section per molecule for the active shell, in cm2
@@ -1002,7 +1002,7 @@ void G4PenelopeIonisationModel::SampleFinalStatePositron(const G4Material* mat,
{
cps = kineticEnergy*rb;
cp = std::sqrt(cps);
G4double XHDT0 = std::max(std::log(gam2)-beta2-delta,0.);
G4double XHDT0 = std::max(G4Log(gam2)-beta2-delta,0.);
if (resEne > 1.0e-6*kineticEnergy)
{
G4double cpp = std::sqrt((kineticEnergy-resEne)*(kineticEnergy-resEne+2.0*electron_mass_c2));
@@ -1015,7 +1015,7 @@ void G4PenelopeIonisationModel::SampleFinalStatePositron(const G4Material* mat,
}
if (QM < cutoffEne)
{
XHDL = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)))
XHDL = G4Log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)))
*invResEne;
XHDT = XHDT0*invResEne;
}
@@ -1042,7 +1042,7 @@ void G4PenelopeIonisationModel::SampleFinalStatePositron(const G4Material* mat,
if (wcl < wmaxc)
{
G4double rl1 = 1.0-rcl;
XHC = ((1.0/rcl-1.0)+bha1*std::log(rcl)+bha2*rl1
XHC = ((1.0/rcl-1.0)+bha1*G4Log(rcl)+bha2*rl1
+ (bha3/2.0)*(rcl*rcl-1.0)
+ (bha4/3.0)*(1.0-rcl*rcl*rcl))/kineticEnergy;
}
@@ -299,7 +299,7 @@ G4double G4PenelopeIonisationXSHandler::GetDensityCorrection(const G4Material* m
G4cout << "Invalid energy " << energy/eV << " eV " << G4endl;
return 0;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
if (theDeltaTable->count(mat))
{
@@ -410,12 +410,12 @@ void G4PenelopeIonisationXSHandler::BuildDeltaTable(const G4Material* mat)
G4PenelopeOscillator* theOscLocal3 = (*theTable)[i];
G4double wri = theOscLocal3->GetResonanceEnergy();
delta += theOscLocal3->GetOscillatorStrength()*
std::log(1.0+(wl2/(wri*wri)));
G4Log(1.0+(wl2/(wri*wri)));
}
delta = (delta/totalZ)-wl2/(gamSq*plasmaSq);
}
energy = std::max(1e-9*eV,energy); //prevents log(0)
theVector->PutValue(bin,std::log(energy),delta);
theVector->PutValue(bin,G4Log(energy),delta);
}
theDeltaTable->insert(std::make_pair(mat,theVector));
return;
@@ -453,7 +453,7 @@ G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsElectron(G
G4double beta = (gammaSq-1.0)/gammaSq;
G4double pielr2 = pi*classic_electr_radius*classic_electr_radius; //pi*re^2
G4double constant = pielr2*2.0*electron_mass_c2/beta;
G4double XHDT0 = std::log(gammaSq)-beta;
G4double XHDT0 = G4Log(gammaSq)-beta;
G4double cpSq = energy*(energy+2.0*electron_mass_c2);
G4double cp = std::sqrt(cpSq);
@@ -480,7 +480,7 @@ G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsElectron(G
}
G4double SDL1 = 0;
if (QM < cutoffEne)
SDL1 = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
SDL1 = G4Log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
//Distant transverse interactions
if (SDL1)
@@ -510,14 +510,14 @@ G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsElectron(G
if (wl < wu-(1e-5*eV))
{
H0 += (1.0/(ee-wu)) - (1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) +
(1.0-amol)*std::log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
(1.0-amol)*G4Log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
amol*(wu-wl)/(ee*ee);
H1 += std::log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
(2.0-amol)*std::log((ee-wu)/(ee-wl)) +
H1 += G4Log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
(2.0-amol)*G4Log((ee-wu)/(ee-wl)) +
amol*(wu*wu-wl*wl)/(2.0*ee*ee);
H2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) -
(wl*(2.0*ee-wl)/(ee-wl)) +
(3.0-amol)*ee*std::log((ee-wu)/(ee-wl)) +
(3.0-amol)*ee*G4Log((ee-wu)/(ee-wl)) +
amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
wu = wl;
}
@@ -535,14 +535,14 @@ G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsElectron(G
}
S0 += (1.0/(ee-wu))-(1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) +
(1.0-amol)*std::log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
(1.0-amol)*G4Log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
amol*(wu-wl)/(ee*ee);
S1 += std::log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
(2.0-amol)*std::log((ee-wu)/(ee-wl)) +
S1 += G4Log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
(2.0-amol)*G4Log((ee-wu)/(ee-wl)) +
amol*(wu*wu-wl*wl)/(2.0*ee*ee);
S2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) -
(wl*(2.0*ee-wl)/(ee-wl)) +
(3.0-amol)*ee*std::log((ee-wu)/(ee-wl)) +
(3.0-amol)*ee*G4Log((ee-wu)/(ee-wl)) +
amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
(*result)[0] = constant*H0;
@@ -585,7 +585,7 @@ G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsPositron(G
G4double beta = (gammaSq-1.0)/gammaSq;
G4double pielr2 = pi*classic_electr_radius*classic_electr_radius; //pi*re^2
G4double constant = pielr2*2.0*electron_mass_c2/beta;
G4double XHDT0 = std::log(gammaSq)-beta;
G4double XHDT0 = G4Log(gammaSq)-beta;
G4double cpSq = energy*(energy+2.0*electron_mass_c2);
G4double cp = std::sqrt(cpSq);
@@ -618,7 +618,7 @@ G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsPositron(G
}
G4double SDL1 = 0;
if (QM < cutoffEne)
SDL1 = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
SDL1 = G4Log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
//Distant transverse interactions
if (SDL1)
@@ -650,11 +650,11 @@ G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsPositron(G
{
G4double wlSq = wl*wl;
G4double wuSq = wu*wu;
H0 += (1.0/wl) - (1.0/wu)- bha1*std::log(wu/wl)/energy
H0 += (1.0/wl) - (1.0/wu)- bha1*G4Log(wu/wl)/energy
+ bha2*(wu-wl)/energySq
- bha3*(wuSq-wlSq)/(2.0*energySq*energy)
+ bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
H1 += std::log(wu/wl) - bha1*(wu-wl)/energy
H1 += G4Log(wu/wl) - bha1*(wu-wl)/energy
+ bha2*(wuSq-wlSq)/(2.0*energySq)
- bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
+ bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
@@ -680,12 +680,12 @@ G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsPositron(G
G4double wlSq = wl*wl;
G4double wuSq = wu*wu;
S0 += (1.0/wl) - (1.0/wu) - bha1*std::log(wu/wl)/energy
S0 += (1.0/wl) - (1.0/wu) - bha1*G4Log(wu/wl)/energy
+ bha2*(wu-wl)/energySq
- bha3*(wuSq-wlSq)/(2.0*energySq*energy)
+ bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
S1 += std::log(wu/wl) - bha1*(wu-wl)/energy
S1 += G4Log(wu/wl) - bha1*(wu-wl)/energy
+ bha2*(wuSq-wlSq)/(2.0*energySq)
- bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
+ bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
@@ -486,7 +486,7 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
for (size_t i=0;i<StechiometricFactors->size();i++)
{
G4cout << "Element " << (*elementVector)[i]->GetSymbol() << " (Z = " <<
(*elementVector)[i]->GetZ() << ") --> " <<
(*elementVector)[i]->GetZasInt() << ") --> " <<
(*StechiometricFactors)[i] << " atoms/molecule " << G4endl;
}
}
@@ -494,10 +494,10 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
for (G4int i=0;i<nElements;i++)
{
G4int iZ = (G4int) (*elementVector)[i]->GetZ();
G4int iZ = (*elementVector)[i]->GetZasInt();
totalZ += iZ * (*StechiometricFactors)[i];
totalMolecularWeight += (*elementVector)[i]->GetAtomicMassAmu() * (*StechiometricFactors)[i];
meanExcitationEnergy += iZ*std::log(meanAtomExcitationEnergy[iZ-1])*(*StechiometricFactors)[i];
meanExcitationEnergy += iZ*G4Log(meanAtomExcitationEnergy[iZ-1])*(*StechiometricFactors)[i];
/*
G4cout << iZ << " " << (*StechiometricFactors)[i] << " " << totalZ << " " <<
totalMolecularWeight/(g/mole) << " " << meanExcitationEnergy << " " <<
@@ -606,7 +606,7 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
if (verbosityLevel > 1)
{
G4cout << "Estimated oscillator strenght and energy of plasmon: " <<
G4cout << "Estimated oscillator strength and energy of plasmon: " <<
conductionStrength << " and " << plasmaEnergy/eV << " eV" << G4endl;
}
@@ -622,7 +622,7 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
if (verbosityLevel >1 )
G4cout << material->GetName() << " is a conductor " << G4endl;
isAConductor = true;
//copy the conduction strenght.. The number is going to change.
//copy the conduction strength.. The number is going to change.
G4double conductionStrengthCopy = conductionStrength;
G4bool quit = false;
for (size_t i = 1; i<helper->size() && !quit ;i++)
@@ -699,7 +699,7 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
G4double adjustmentFactor = 0;
if (helper->size() > 1)
{
G4double TST = totalZ*std::log(meanExcitationEnergy/eV);
G4double TST = totalZ*G4Log(meanExcitationEnergy/eV);
G4double AALow = 0.1;
G4double AAHigh = 10.;
do
@@ -711,7 +711,7 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
if (i == 0 && isAConductor)
{
G4double resEne = (*helper)[i].GetResonanceEnergy();
sumLocal += (*helper)[i].GetOscillatorStrength()*std::log(resEne/eV);
sumLocal += (*helper)[i].GetOscillatorStrength()*G4Log(resEne/eV);
}
else
{
@@ -721,7 +721,7 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
2./3.*(oscStre/totalZ)*Omega*Omega;
G4double resEne = std::sqrt(WI2);
(*helper)[i].SetResonanceEnergy(resEne);
sumLocal += (*helper)[i].GetOscillatorStrength()*std::log(resEne/eV);
sumLocal += (*helper)[i].GetOscillatorStrength()*G4Log(resEne/eV);
}
}
if (sumLocal < TST)
@@ -746,11 +746,11 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
}
//Check again for data consistency
G4double xcheck = (*helper)[0].GetOscillatorStrength()*std::log((*helper)[0].GetResonanceEnergy());
G4double xcheck = (*helper)[0].GetOscillatorStrength()*G4Log((*helper)[0].GetResonanceEnergy());
G4double TST = (*helper)[0].GetOscillatorStrength();
for (size_t i=1;i<helper->size();i++)
{
xcheck += (*helper)[i].GetOscillatorStrength()*std::log((*helper)[i].GetResonanceEnergy());
xcheck += (*helper)[i].GetOscillatorStrength()*G4Log((*helper)[i].GetResonanceEnergy());
TST += (*helper)[i].GetOscillatorStrength();
}
if (std::fabs(TST-totalZ)>1e-8*totalZ)
@@ -813,7 +813,7 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
//COPY THE HELPER (vector of object) to theTable (vector of Pointers).
for (size_t i=0;i<helper->size();i++)
{
//copy content --> one may need it later (e.g. to fill an other table, with variations)
//copy content --> one may need it later (e.g. to fill another table, with variations)
G4PenelopeOscillator* theOsc = new G4PenelopeOscillator((*helper)[i]);
theTable->push_back(theOsc);
}
@@ -852,8 +852,8 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
skipLoop = true;
if (!skipLoop)
{
G4double newRes = G4Exp((oscStre*std::log(resEne)+
oscStrePlus1*std::log(resEnePlus1))
G4double newRes = G4Exp((oscStre*G4Log(resEne)+
oscStrePlus1*G4Log(resEnePlus1))
/(oscStre+oscStrePlus1));
(*theTable)[i]->SetResonanceEnergy(newRes);
G4double newIon = (oscStre*ionEne+
@@ -942,7 +942,7 @@ void G4PenelopeOscillatorManager::BuildOscillatorTable(const G4Material* materia
//COPY THE HELPER (vector of object) to theTable (vector of Pointers).
for (size_t i=0;i<helper->size();i++)
{
//copy content --> one may need it later (e.g. to fill an other table, with variations)
//copy content --> one may need it later (e.g. to fill another table, with variations)
G4PenelopeOscillator* theOsc = new G4PenelopeOscillator((*helper)[i]);
theTableC->push_back(theOsc);
}
@@ -149,7 +149,7 @@ void G4PenelopePhotoElectricModel::Initialise(const G4ParticleDefinition* partic
for (size_t j=0;j<material->GetNumberOfElements();j++)
{
G4int iZ = (G4int) theElementVector->at(j)->GetZ();
G4int iZ = theElementVector->at(j)->GetZasInt();
//read data files only in the master
if (!logAtomicShellXS->count(iZ))
ReadDataFile(iZ);
@@ -260,7 +260,7 @@ G4double G4PenelopePhotoElectricModel::ComputeCrossSectionPerAtom(
"Unable to retrieve the total cross section table");
return 0;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4double logXS = totalXSLog->Value(logene);
cross = G4Exp(logXS);
@@ -316,7 +316,7 @@ void G4PenelopePhotoElectricModel::SampleSecondaries(std::vector<G4DynamicPartic
// atom can be selected efficiently if element selectors are initialised
const G4Element* anElement =
SelectRandomAtom(couple,G4Gamma::GammaDefinition(),photonEnergy);
G4int Z = (G4int) anElement->GetZ();
G4int Z = anElement->GetZasInt();
if (verboseLevel > 2)
G4cout << "Selected " << anElement->GetName() << G4endl;
@@ -611,7 +611,7 @@ void G4PenelopePhotoElectricModel::ReadDataFile(G4int Z)
G4double aValue = 0;
file >> energy ;
energy *= eV;
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
//loop on the columns
for (size_t i=0;i<nShells+1;i++)
{
@@ -620,7 +620,7 @@ void G4PenelopePhotoElectricModel::ReadDataFile(G4int Z)
G4PhysicsFreeVector* theVec = (G4PhysicsFreeVector*) ((*thePhysicsTable)[i]);
if (aValue < 1e-40*cm2) //protection against log(0)
aValue = 1e-40*cm2;
theVec->PutValue(k,logene,std::log(aValue));
theVec->PutValue(k,logene,G4Log(aValue));
}
}
@@ -686,7 +686,7 @@ G4double G4PenelopePhotoElectricModel::GetShellCrossSection(G4int Z,size_t shell
"Unable to retrieve the total cross section table");
return 0;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4double logXS = totalXSLog->Value(logene);
G4double cross = G4Exp(logXS);
if (cross < 2e-40*cm2) cross = 0;
@@ -733,7 +733,7 @@ void G4PenelopePhotoElectricModel::SetParticle(const G4ParticleDefinition* p)
size_t G4PenelopePhotoElectricModel::SelectRandomShell(G4int Z,G4double energy)
{
G4double logEnergy = std::log(energy);
G4double logEnergy = G4Log(energy);
//Check if data have been read (it should be!)
if (!logAtomicShellXS->count(Z))
@@ -74,11 +74,11 @@ G4PenelopeRayleighModel::G4PenelopeRayleighModel(const G4ParticleDefinition* par
// 4 = entering in methods
//build the energy grid. It is the same for all materials
G4double logenergy = std::log(fIntrinsicLowEnergyLimit/2.);
G4double logmaxenergy = std::log(1.5*fIntrinsicHighEnergyLimit);
G4double logenergy = G4Log(fIntrinsicLowEnergyLimit/2.);
G4double logmaxenergy = G4Log(1.5*fIntrinsicHighEnergyLimit);
//finer grid below 160 keV
G4double logtransitionenergy = std::log(160*keV);
G4double logfactor1 = std::log(10.)/250.;
G4double logtransitionenergy = G4Log(160*keV);
G4double logfactor1 = G4Log(10.)/250.;
G4double logfactor2 = logfactor1*10;
logEnergyGridPMax.push_back(logenergy);
do{
@@ -129,7 +129,7 @@ void G4PenelopeRayleighModel::ClearTables()
for (auto& item : (*logFormFactorTable))
if (item.second) delete item.second;
delete logFormFactorTable;
logFormFactorTable = nullptr; //zero explicitely
logFormFactorTable = nullptr; //zero explicitly
}
if (pMaxTable)
@@ -137,7 +137,7 @@ void G4PenelopeRayleighModel::ClearTables()
for (auto& item : (*pMaxTable))
if (item.second) delete item.second;
delete pMaxTable;
pMaxTable = nullptr; //zero explicitely
pMaxTable = nullptr; //zero explicitly
}
if (samplingTable)
@@ -145,7 +145,7 @@ void G4PenelopeRayleighModel::ClearTables()
for (auto& item : (*samplingTable))
if (item.second) delete item.second;
delete samplingTable;
samplingTable = nullptr; //zero explicitely
samplingTable = nullptr; //zero explicitly
}
return;
@@ -198,7 +198,7 @@ void G4PenelopeRayleighModel::Initialise(const G4ParticleDefinition* part,
for (size_t j=0;j<material->GetNumberOfElements();j++)
{
G4int iZ = (G4int) theElementVector->at(j)->GetZ();
G4int iZ = theElementVector->at(j)->GetZasInt();
//read data files only in the master
if (!logAtomicCrossSection->count(iZ))
ReadDataFile(iZ);
@@ -326,7 +326,7 @@ G4double G4PenelopeRayleighModel::ComputeCrossSectionPerAtom(const G4ParticleDef
"em2041",FatalException,ed);
return 0;
}
G4double logene = std::log(energy);
G4double logene = G4Log(energy);
G4double logXS = atom->Value(logene);
cross = G4Exp(logXS);
@@ -394,13 +394,13 @@ void G4PenelopeRayleighModel::BuildFormFactorTable(const G4Material* material)
G4double ff2 = 0; //squared form factor
for (G4int i=0;i<nElements;i++)
{
G4int iZ = (G4int) (*elementVector)[i]->GetZ();
G4int iZ = (*elementVector)[i]->GetZasInt();
G4PhysicsFreeVector* theAtomVec = atomicFormFactor->find(iZ)->second;
G4double f = (*theAtomVec)[k]; //the q-grid is always the same
ff2 += f*f*(*StechiometricFactors)[i];
}
if (ff2)
theFFVec->PutValue(k,logQSquareGrid[k],std::log(ff2)); //NOTICE: THIS IS log(Q^2) vs. log(F^2)
theFFVec->PutValue(k,logQSquareGrid[k],G4Log(ff2)); //NOTICE: THIS IS log(Q^2) vs. log(F^2)
}
logFormFactorTable->insert(std::make_pair(material,theFFVec));
@@ -489,7 +489,7 @@ void G4PenelopeRayleighModel::SampleSecondaries(std::vector<G4DynamicParticle*>*
G4AutoLock lock(&PenelopeRayleighModelMutex);
for (size_t j=0;j<theMat->GetNumberOfElements();j++)
{
G4int iZ = (G4int) theElementVector->at(j)->GetZ();
G4int iZ = theElementVector->at(j)->GetZasInt();
if (!logAtomicCrossSection->count(iZ))
{
lock.lock();
@@ -636,7 +636,7 @@ void G4PenelopeRayleighModel::ReadDataFile(const G4int Z)
//dimensional quantities
ene *= eV;
xs *= cm2;
theVec->PutValue(i,std::log(ene),std::log(xs));
theVec->PutValue(i,G4Log(ene),G4Log(xs));
if (file.eof() && i != (nPoints-1)) //file ended too early
{
G4ExceptionDescription ed ;
@@ -694,7 +694,7 @@ void G4PenelopeRayleighModel::ReadDataFile(const G4int Z)
theFFVec->PutValue(i,q,ff);
if (fillQGrid)
{
logQSquareGrid.push_back(2.0*std::log(q));
logQSquareGrid.push_back(2.0*G4Log(q));
}
if (file.eof() && i != (nPoints-1)) //file ended too early
{
@@ -726,7 +726,7 @@ G4double G4PenelopeRayleighModel::GetFSquared(const G4Material* mat, const G4dou
//Input value QSquared could be zero: protect the log() below against
//the FPE exception
//If Q<1e-10, set Q to 1e-10
G4double logQSquared = (QSquared>1e-10) ? std::log(QSquared) : -23.;
G4double logQSquared = (QSquared>1e-10) ? G4Log(QSquared) : -23.;
//last value of the table
G4double maxlogQ2 = logQSquareGrid[logQSquareGrid.size()-1];
File diff suppressed because it is too large Load Diff
View File
View File