Import Geant4 11.1.0.beta source tree
This commit is contained in:
@@ -19,6 +19,7 @@ CPPFLAGS += -I$(G4BASE)/global/management/include \
|
||||
-I$(G4BASE)/track/include \
|
||||
-I$(G4BASE)/processes/management/include \
|
||||
-I$(G4BASE)/processes/cuts/include \
|
||||
-I$(G4BASE)/processes/transportation/include \
|
||||
-I$(G4BASE)/particles/management/include \
|
||||
-I$(G4BASE)/particles/bosons/include \
|
||||
-I$(G4BASE)/particles/leptons/include \
|
||||
|
||||
@@ -1,49 +1,153 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category emutils History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2022-06-19 V.Ivanchenko (emutils-V11-00-30)
|
||||
- G4EmExtraParametersMessenger - fixed typo (problem #2492)
|
||||
|
||||
07 April 2022 V.Ivanchenko (emutils-V10-07-40)
|
||||
## 2022-06-17 V.Ivanchenko (emutils-V11-00-29)
|
||||
- G4VEnergyLossProcess - fixed trivial Coverity warnings
|
||||
|
||||
## 2022-06-07 V.Ivanchenko (emutils-V11-00-28)
|
||||
- G4VEnergyLossProcess, G4EmDataHandler - improve StorePhysicsTable(..)
|
||||
method and debug pritouts
|
||||
|
||||
## 2022-06-07 V.Ivanchenko (emutils-V11-00-27)
|
||||
- G4VEnergyLossProcess - moved out common computations to G4EmTableUtil,
|
||||
use G4EmDataHandler, removed unused headers and methods
|
||||
|
||||
## 2022-05-31 V.Ivanchenko (emutils-V11-00-26)
|
||||
- G4VEmModel - fixed Coverity warning
|
||||
|
||||
## 2022-05-28 V.Ivanchenko (emutils-V11-00-25)
|
||||
- G4EmParametersMessenger - added extra UI command to define model of
|
||||
fluctuations
|
||||
|
||||
## 2022-05-23 V.Ivanchenko (emutils-V11-00-24)
|
||||
- G4EmTableUtil - added extra methods
|
||||
- G4VEmModel, G4VEmProcess, G4VEnergyLossProcess,
|
||||
G4VMultipleScattering, G4LossTableManager - use new utiity methods,
|
||||
updated sampling of random element in compounds and random
|
||||
isotopes, code cleanup
|
||||
- G4EmParameters - added extra parameter: type for of fluctuation model
|
||||
|
||||
## 2022-05-20 Z.Li (emutils-V11-00-23)
|
||||
- G4EmLowEParameters, change default photon database to EPICS2017
|
||||
|
||||
## 2022-05-13 V.Ivanchenko (emutils-V11-00-22)
|
||||
- G4EmUtility - added methods to sample isotopes or element
|
||||
- G4VEmModel, G4EmCalculator, G4EmConfigurator - use G4EmUtility
|
||||
|
||||
## 2022-05-12 V.Ivanchenko (emutils-V11-00-21)
|
||||
- G4EmUtility - removed precision lost in energy value at
|
||||
initialisation of integral method
|
||||
- G4VEmProcess, G4VEnergyLossProcess - for integral method
|
||||
use master thread cross section type and pointers directly
|
||||
simplifing initialisation
|
||||
|
||||
## 2022-05-11 J.Hahnfeld (emutils-V11-00-20)
|
||||
- Remove dependency on `G4magneticfield`
|
||||
|
||||
## 2022-05-02 J.Hahnfeld (emutils-V11-00-19)
|
||||
- `G4TransportationWithMsc`: Add possibility of internal stepping
|
||||
- `G4EmParameters`: Update flag to tristate for enabling it
|
||||
|
||||
## 2022-04-29 V.Ivanchenko (emutils-V11-00-18)
|
||||
- G4EmTableUtil - new utility to perform common computations at
|
||||
initialisation
|
||||
- G4VMultipleScattering - use G4EmTableUtil and fix Coverity warnings
|
||||
- G4EmConfigurator, G4VEnergyLossProcess - fixed Coverity warnings
|
||||
|
||||
## 2022-04-27 D.Sawkey (emutils-V11-00-17)
|
||||
- many files: run clang-tidy. Use default ctors; keywords nullptr, auto, using
|
||||
|
||||
## 2022-04-23 V.Ivanchenko (emutils-V11-00-16)
|
||||
- G4EmConfigurator - implement model per region for G4TransportationWithMsc
|
||||
- GNUmakefile, source.cmake - updated accordingly
|
||||
|
||||
## 2022-04-19 J.Hahnfeld (emutil-V11-00-15)
|
||||
- Create `G4TransportationWithMsc` process, add flag to `G4EmParameters`
|
||||
|
||||
## 2022-04-13 V.Ivanchenko (emutils-V11-00-14)
|
||||
- G4VEnergyLossProcess, G4VEmProcess - use G4EmUtility to compute cross
|
||||
section shape parameters
|
||||
- G4VMultipleScattering - updated arguments for AddEmModel, SetEmModel,
|
||||
and EmModel methods from G4VEmModel* to G4VMscModel*
|
||||
- G4EmConfigurator - updated interfaces
|
||||
|
||||
## 2022-04-10 V.Ivanchenko (emutils-V11-00-13)
|
||||
- G4EmUtility - added new static methods to prepare data structures for
|
||||
integral method using EM tables or using GetCrossSection(..) method
|
||||
from G4VDiscreteProcess based class, this will allow using it for hadronics
|
||||
- G4VEnergyLossProcess, G4VEmProcess, G4VMultipleScattering - minor clean-up
|
||||
|
||||
## 2022-04-07 V.Ivanchenko (emutils-V11-00-12)
|
||||
- G4VMultipleScattering - fix #2480 responsible for energy deposition shift of
|
||||
custom CMS Physics List FTFP_BERT_EMM
|
||||
|
||||
01 April 2022 J.Hahnfeld
|
||||
## 2022-04-01 J.Hahnfeld (emutils-V11-00-11)
|
||||
- Fix typo in Bremsstrahlung.
|
||||
|
||||
24 March 2022: V.Ivanchenko
|
||||
## 2022-03-29 H.Tran (emutils-V11-00-10)
|
||||
- G4LowEnergyEmProcessSubType - add fLowEnergyScavenger (66) for DNAScavenger process
|
||||
|
||||
## 2022-03-24 V.Ivanchenko (emutils-V11-00-09)
|
||||
- G4VEnergyLossProcess - fix fluctuation model pointer if an extra
|
||||
model is added on top of the default list of models
|
||||
|
||||
22 January 22: V.Ivanchenko (emutils-V10-07-39)
|
||||
## 2022-03-17 V.Ivanchenko (emutils-V11-00-08)
|
||||
- G4EmParametersMessenger - restored UI command "/process/em/integral"
|
||||
- G4VEmProcess - updated methods to access cross section in run time,
|
||||
implement new virtual method GetCrossSection, removed unused
|
||||
methods
|
||||
- G4EmCalculator - use updated method from G4VEmProcess
|
||||
- G4EmUtility - a new utility class
|
||||
|
||||
## 2022-03-09 V.Ivanchenko (emutils-V11-00-07)
|
||||
- G4EmCalculator - fixed variable shadowing
|
||||
|
||||
## 2022-03-07 V.Ivanchenko (emutils-V11-00-06)
|
||||
- G4EmModelManager - updated interface to Initialise(.. ) method,
|
||||
removed obsolete method Update(..)
|
||||
- G4VEmProcess, G4VEnergyLossProcess, G4VMultipleScattering - use updated
|
||||
method of G4EmModelManager
|
||||
|
||||
## 2022-02-17 V.Ivanchenko (emutils-V11-00-05)
|
||||
- G4EmParametersMessenger - instantion order of UI directories improved,
|
||||
directories are created only in the master thread
|
||||
|
||||
## 2022-01-22 V.Ivanchenko (emutils-V11-00-04)
|
||||
- G4EmParametersMessenger - added forgotten UI command to enable polarisation
|
||||
|
||||
08 January 22: V.Ivanchenko
|
||||
## 2022-01-08 V.Ivanchenko (emutils-V11-00-03)
|
||||
- G4VEmProcess - fixed methods, which implementation based on assumption that
|
||||
the lambda table defined for full energy range: LambdaPhysicsVector(..),
|
||||
CrossSEctionPerVolume(...), FindLambdaMax(...). No change is expected for
|
||||
the default physics configuration, fix mainly affect positron annihilation
|
||||
processes at high energies.
|
||||
|
||||
05 January 22: V.Ivanchenko
|
||||
## 2022-01-05 V.Ivanchenko (emutils-V11-00-02)
|
||||
- Complete internal redesign started in 2021, results are identical
|
||||
- G4EmTableType - added 3d peak energy in the data structure needed for bremsstrahlung
|
||||
- G4VEnergyLossProcess - fill data structure for bremsstrahlung type of x-section
|
||||
only in the master thread - do not repeat in each thread; removed ineffective
|
||||
cache from run time computation of cross section.
|
||||
- G4VMscModel, G4VEmProcess - move few methods and header files from header to
|
||||
source in order to reduce dependencies between packages.
|
||||
|
||||
17 December 21: I.Hrivnacova
|
||||
## 2021-12-17 Ivana Hrivnacova (emutils-V11-00-01)
|
||||
- Added info in setMaxBetaChange command description.
|
||||
|
||||
## 2021-12-10 Ben Morgan (emutils-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
19 November 21: V.Ivanchenko (emutils-V10-07-38)
|
||||
- G4EmCalculator - fixed computation of dedx for He3 and alpha
|
||||
(complete fix of #2440)
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
const G4Region* r = nullptr);
|
||||
inline G4double GetDEDX(G4double kinEnergy, const G4String& part,
|
||||
const G4String& mat,
|
||||
const G4String& s = "world");
|
||||
const G4String& regname = "world");
|
||||
|
||||
G4double GetRangeFromRestricteDEDX(G4double kinEnergy,
|
||||
const G4ParticleDefinition*,
|
||||
@@ -104,28 +104,28 @@ public:
|
||||
inline G4double GetRangeFromRestricteDEDX(G4double kinEnergy,
|
||||
const G4String& part,
|
||||
const G4String& mat,
|
||||
const G4String& s = "world");
|
||||
const G4String& regname = "world");
|
||||
|
||||
G4double GetCSDARange(G4double kinEnergy, const G4ParticleDefinition*,
|
||||
const G4Material*,
|
||||
const G4Region* r = nullptr);
|
||||
inline G4double GetCSDARange(G4double kinEnergy, const G4String& part,
|
||||
const G4String& mat,
|
||||
const G4String& s = "world");
|
||||
const G4String& regname = "world");
|
||||
|
||||
G4double GetRange(G4double kinEnergy, const G4ParticleDefinition*,
|
||||
const G4Material*,
|
||||
const G4Region* r = nullptr);
|
||||
inline G4double GetRange(G4double kinEnergy, const G4String& part,
|
||||
const G4String& mat,
|
||||
const G4String& s = "world");
|
||||
const G4String& regname = "world");
|
||||
|
||||
G4double GetKinEnergy(G4double range, const G4ParticleDefinition*,
|
||||
const G4Material*,
|
||||
const G4Region* r = nullptr);
|
||||
inline G4double GetKinEnergy(G4double range, const G4String& part,
|
||||
const G4String& mat,
|
||||
const G4String& s = "world");
|
||||
const G4String& regname = "world");
|
||||
|
||||
G4double GetCrossSectionPerVolume(
|
||||
G4double kinEnergy, const G4ParticleDefinition*,
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
const G4Region* r = nullptr);
|
||||
inline G4double GetCrossSectionPerVolume(
|
||||
G4double kinEnergy, const G4String& part, const G4String& proc,
|
||||
const G4String& mat, const G4String& s = "world");
|
||||
const G4String& mat, const G4String& regname = "world");
|
||||
|
||||
G4double GetShellIonisationCrossSectionPerAtom(
|
||||
const G4String& part, G4int Z,
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
const G4Region* r = nullptr);
|
||||
inline G4double GetMeanFreePath(G4double kinEnergy, const G4String& part,
|
||||
const G4String& proc, const G4String& mat,
|
||||
const G4String& s = "world");
|
||||
const G4String& regname = "world");
|
||||
|
||||
void PrintDEDXTable(const G4ParticleDefinition*);
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
class G4VEnergyLossProcess;
|
||||
class G4VEmProcess;
|
||||
class G4VMultipleScattering;
|
||||
class G4TransportationWithMsc;
|
||||
|
||||
class G4EmConfigurator
|
||||
{
|
||||
@@ -93,7 +94,8 @@ public:
|
||||
G4VEmProcess* p);
|
||||
|
||||
void PrepareModels(const G4ParticleDefinition* aParticle,
|
||||
G4VMultipleScattering* p);
|
||||
G4VMultipleScattering* p,
|
||||
G4TransportationWithMsc* trans = nullptr);
|
||||
|
||||
void Clear();
|
||||
|
||||
@@ -105,8 +107,6 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
const G4Region* FindRegion(const G4String&);
|
||||
|
||||
void SetModelForRegion(G4VEmModel* model,
|
||||
G4VEmFluctuationModel* fm,
|
||||
const G4Region* reg,
|
||||
|
||||
@@ -67,10 +67,19 @@ public:
|
||||
|
||||
~G4EmDataHandler();
|
||||
|
||||
// add table
|
||||
size_t SetTable(G4PhysicsTable*);
|
||||
|
||||
// update existing table
|
||||
void UpdateTable(G4PhysicsTable*, size_t idx);
|
||||
|
||||
// assuming that the table is already defined
|
||||
G4PhysicsTable* MakeTable(size_t idx);
|
||||
|
||||
// existing table may be substituted
|
||||
G4PhysicsTable* MakeTable(G4PhysicsTable*, size_t idx);
|
||||
|
||||
// clean existing table
|
||||
void CleanTable(size_t idx);
|
||||
|
||||
G4bool StorePhysicsTable(size_t idx,
|
||||
@@ -82,7 +91,7 @@ public:
|
||||
const G4ParticleDefinition* part,
|
||||
const G4String& fname,
|
||||
G4bool ascii, G4bool spline);
|
||||
|
||||
|
||||
void SetMasterProcess(const G4VEmProcess*);
|
||||
|
||||
const G4VEmProcess* GetMasterProcess(size_t idx) const;
|
||||
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
|
||||
const G4DataVector* Initialise(const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition* secPart,
|
||||
G4double, G4int verb);
|
||||
G4int verb);
|
||||
|
||||
void FillDEDXVector(G4PhysicsVector*, const G4MaterialCutsCouple*,
|
||||
G4EmTableType t = fRestricted);
|
||||
@@ -163,10 +163,8 @@ public:
|
||||
void AddEmModel(G4int, G4VEmModel*, G4VEmFluctuationModel* fm,
|
||||
const G4Region* r);
|
||||
|
||||
void UpdateEmModel(const G4String& model_name, G4double emin, G4double emax);
|
||||
|
||||
// Get model pointer from the model list
|
||||
G4VEmModel* GetModel(G4int idx, G4bool ver = false);
|
||||
G4VEmModel* GetModel(G4int idx, G4bool ver = false) const;
|
||||
|
||||
// Get model pointer from the model list for a given material cuts couple
|
||||
// no check on material cuts couple index
|
||||
|
||||
@@ -59,15 +59,28 @@
|
||||
#include "G4DNAModelSubType.hh"
|
||||
#include "G4EmSaturation.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include <vector>
|
||||
|
||||
enum G4eSingleScatteringType
|
||||
{
|
||||
fWVI = 0,
|
||||
fMott,
|
||||
fDPWA
|
||||
};
|
||||
{
|
||||
fWVI = 0,
|
||||
fMott,
|
||||
fDPWA
|
||||
};
|
||||
|
||||
enum class G4TransportationWithMscType
|
||||
{
|
||||
fDisabled = 0,
|
||||
fEnabled,
|
||||
fMultipleSteps,
|
||||
};
|
||||
|
||||
enum G4EmFluctuationType
|
||||
{
|
||||
fDummyFluctuation = 0,
|
||||
fUniversalFluctuation,
|
||||
fUrbanFluctuation
|
||||
};
|
||||
|
||||
class G4EmParametersMessenger;
|
||||
class G4EmExtraParameters;
|
||||
@@ -152,6 +165,9 @@ public:
|
||||
void SetUseICRU90Data(G4bool val);
|
||||
G4bool UseICRU90Data() const;
|
||||
|
||||
void SetFluctuationType(G4EmFluctuationType val);
|
||||
G4EmFluctuationType FluctuationType() const;
|
||||
|
||||
void SetDNAFast(G4bool val);
|
||||
G4bool DNAFast() const;
|
||||
|
||||
@@ -279,6 +295,9 @@ public:
|
||||
void SetWorkerVerbose(G4int val);
|
||||
G4int WorkerVerbose() const;
|
||||
|
||||
void SetTransportationWithMsc(G4TransportationWithMscType val);
|
||||
G4TransportationWithMscType TransportationWithMsc() const;
|
||||
|
||||
void SetMscStepLimitType(G4MscStepLimitType val);
|
||||
G4MscStepLimitType MscStepLimitType() const;
|
||||
|
||||
@@ -425,14 +444,12 @@ private:
|
||||
G4int workerVerbose;
|
||||
G4int tripletConv; // 5d model triplet generation type
|
||||
|
||||
G4TransportationWithMscType fTransportationWithMsc;
|
||||
G4MscStepLimitType mscStepLimit;
|
||||
G4MscStepLimitType mscStepLimitMuHad;
|
||||
G4NuclearFormfactorType nucFormfactor;
|
||||
G4eSingleScatteringType fSStype;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
static G4Mutex emParametersMutex;
|
||||
#endif
|
||||
G4EmFluctuationType fFluct;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -86,6 +86,7 @@ private:
|
||||
G4UIdirectory* dnaDirectory;
|
||||
|
||||
G4UIcmdWithABool* flucCmd;
|
||||
G4UIcmdWithABool* intCmd;
|
||||
G4UIcmdWithABool* rangeCmd;
|
||||
G4UIcmdWithABool* lpmCmd;
|
||||
G4UIcmdWithABool* rsCmd;
|
||||
@@ -132,10 +133,12 @@ private:
|
||||
G4UIcmdWithAnInteger* ver2Cmd;
|
||||
G4UIcmdWithAnInteger* tripletCmd;
|
||||
|
||||
G4UIcmdWithAString* transWithMscCmd;
|
||||
G4UIcmdWithAString* mscCmd;
|
||||
G4UIcmdWithAString* msc1Cmd;
|
||||
G4UIcmdWithAString* nffCmd;
|
||||
G4UIcmdWithAString* ssCmd;
|
||||
G4UIcmdWithAString* fluc1Cmd;
|
||||
|
||||
G4UIcommand* dumpCmd;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ enum G4EmSecondaryParticleType
|
||||
_TripletElectron = 10014,
|
||||
|
||||
_Bremsstrahlung = 10020,
|
||||
// Legacy name for compatibility with Geant4 11.0 and patch01.
|
||||
// Legacy name for compatibility with Geant4 11.0 and patch01.
|
||||
_Bremsstruhlung = 10020,
|
||||
_SplitBremsstrahlung = 10021,
|
||||
_ComptonGamma = 10022,
|
||||
|
||||
@@ -65,6 +65,7 @@ struct G4TwoPeaksXS {
|
||||
G4double e1deep;
|
||||
G4double e2peak;
|
||||
G4double e2deep;
|
||||
G4double e3peak;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Geant4 header G4EmTableUtil
|
||||
//
|
||||
// Author V.Ivanchenko 14.03.2022
|
||||
//
|
||||
// Utilities used at initialisation of EM physics
|
||||
//
|
||||
|
||||
#ifndef G4EmTableUtil_h
|
||||
#define G4EmTableUtil_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4VMultipleScattering.hh"
|
||||
#include "G4VEmProcess.hh"
|
||||
#include "G4VEnergyLossProcess.hh"
|
||||
#include "G4EmModelManager.hh"
|
||||
#include "G4LossTableBuilder.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MscStepLimitType.hh"
|
||||
#include "G4DataVector.hh"
|
||||
|
||||
class G4EmTableUtil
|
||||
{
|
||||
public:
|
||||
|
||||
static const G4DataVector*
|
||||
PrepareEmProcess(G4VEmProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition* secPart,
|
||||
G4EmModelManager* modelManager,
|
||||
const G4double& maxKinEnergy,
|
||||
G4int& secID, G4int& tripletID,
|
||||
G4int& mainSec, const G4int& verb,
|
||||
const G4bool& master);
|
||||
|
||||
static void BuildEmProcess(G4VEmProcess* proc,
|
||||
const G4VEmProcess* masterProc,
|
||||
const G4ParticleDefinition* firstPart,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4int nModels, const G4int verb,
|
||||
const G4bool master, const G4bool isLocked,
|
||||
const G4bool toBuild, G4bool& baseMat);
|
||||
|
||||
static void BuildLambdaTable(G4VEmProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
G4EmModelManager* modelManager,
|
||||
G4LossTableBuilder* bld,
|
||||
G4PhysicsTable* theLambdaTable,
|
||||
G4PhysicsTable* theLambdaTablePrim,
|
||||
const G4double minKinEnergy,
|
||||
const G4double minKinEnergyPrim,
|
||||
const G4double maxKinEnergy,
|
||||
const G4double scale,
|
||||
const G4int verbose,
|
||||
const G4bool startFromNull,
|
||||
const G4bool splineFlag);
|
||||
|
||||
static void BuildLambdaTable(G4VEnergyLossProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
G4EmModelManager* modelManager,
|
||||
G4LossTableBuilder* bld,
|
||||
G4PhysicsTable* theLambdaTable,
|
||||
const G4DataVector* theCuts,
|
||||
const G4double minKinEnergy,
|
||||
const G4double maxKinEnergy,
|
||||
const G4double scale,
|
||||
const G4int verbose,
|
||||
const G4bool splineFlag);
|
||||
|
||||
static const G4ParticleDefinition* CheckIon(
|
||||
G4VEnergyLossProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition* particle,
|
||||
const G4int verboseLevel, G4bool& isIon);
|
||||
|
||||
static void UpdateModels(G4VEnergyLossProcess* proc,
|
||||
G4EmModelManager* modelManager,
|
||||
const G4double maxKinEnergy,
|
||||
const G4int nModels,
|
||||
G4int& secID, G4int& biasID,
|
||||
G4int& mainSecondaries, const G4bool baseMat,
|
||||
const G4bool isMaster, const G4bool useAGen);
|
||||
|
||||
static void BuildLocalElossProcess(G4VEnergyLossProcess* proc,
|
||||
const G4VEnergyLossProcess* masterProc,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4int nModels);
|
||||
|
||||
static void BuildDEDXTable(G4VEnergyLossProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
G4EmModelManager* modelManager,
|
||||
G4LossTableBuilder* bld,
|
||||
G4PhysicsTable* table,
|
||||
const G4double minKinEnergy,
|
||||
const G4double maxKinEnergy,
|
||||
const G4int nbins,
|
||||
const G4int verbose,
|
||||
const G4EmTableType tType,
|
||||
const G4bool splineFlag);
|
||||
|
||||
static void PrepareMscProcess(G4VMultipleScattering* proc,
|
||||
const G4ParticleDefinition& part,
|
||||
G4EmModelManager* modelManager,
|
||||
G4MscStepLimitType& stepLimit,
|
||||
G4double& facrange,
|
||||
G4bool& latDisplacement, G4bool& master,
|
||||
G4bool& isIon, G4bool& baseMat);
|
||||
|
||||
static void BuildMscProcess(G4VMultipleScattering* proc,
|
||||
const G4VMultipleScattering* masterProc,
|
||||
const G4ParticleDefinition& part,
|
||||
const G4ParticleDefinition* firstPart,
|
||||
G4int nModels, G4bool master);
|
||||
|
||||
static G4bool StoreMscTable(G4VMultipleScattering* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4String& directory,
|
||||
const G4int nModels, const G4int verb,
|
||||
const G4bool ascii);
|
||||
|
||||
static G4bool StoreTable(G4VProcess*, const G4ParticleDefinition*,
|
||||
G4PhysicsTable*, const G4String& dir,
|
||||
const G4String& tname, G4int verb,
|
||||
G4bool ascii);
|
||||
|
||||
static G4bool RetrieveTable(G4VProcess* ptr,
|
||||
const G4ParticleDefinition* part,
|
||||
G4PhysicsTable* aTable,
|
||||
const G4String& dir, const G4String& tname,
|
||||
const G4int verb, const G4bool ascii,
|
||||
const G4bool spline);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Geant4 header G4EmUtility
|
||||
//
|
||||
// Author V.Ivanchenko 14.03.2022
|
||||
//
|
||||
// Utilities used at initialisation of EM physics
|
||||
//
|
||||
|
||||
#ifndef G4EmUtility_h
|
||||
#define G4EmUtility_h 1
|
||||
|
||||
#include <vector>
|
||||
#include "globals.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4EmTableType.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VDiscreteProcess.hh"
|
||||
#include "G4LossTableBuilder.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4Isotope.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
|
||||
class G4EmUtility
|
||||
{
|
||||
public:
|
||||
|
||||
// find G4Region pointer by name, by default no verbosity
|
||||
static const G4Region* FindRegion(const G4String& regionName,
|
||||
const G4int verbose = 0);
|
||||
|
||||
// sample random G4Element for the case if cross section is
|
||||
// proportional to the number of electrons in an atom
|
||||
static const G4Element* SampleRandomElement(const G4Material*);
|
||||
|
||||
// sample random G4Isotope
|
||||
static const G4Isotope* SampleRandomIsotope(const G4Element*);
|
||||
|
||||
// find energy of cross section maximum for all couples
|
||||
static std::vector<G4double>* FindCrossSectionMax(G4PhysicsTable*);
|
||||
static std::vector<G4double>*
|
||||
FindCrossSectionMax(G4VDiscreteProcess*, const G4ParticleDefinition*);
|
||||
|
||||
// fill structure describing more than one peak in cross sections
|
||||
static std::vector<G4TwoPeaksXS*>*
|
||||
FillPeaksStructure(G4PhysicsTable*, G4LossTableBuilder*);
|
||||
|
||||
// model initialisation
|
||||
static void InitialiseElementSelectors(G4VEmModel*,
|
||||
const G4ParticleDefinition*,
|
||||
const G4DataVector& cuts,
|
||||
const G4double emin,
|
||||
const G4double emax);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ private:
|
||||
static G4ThreadLocal G4int let_max_num_warnings;
|
||||
static G4ThreadLocal G4bool first_loss;
|
||||
*/
|
||||
typedef std::map<K,G4EnergyLossTablesHelper,std::less<K> > helper_map;
|
||||
using helper_map = std::map<K, G4EnergyLossTablesHelper, std::less<K> >;
|
||||
static helper_map *dict;
|
||||
|
||||
static G4EnergyLossTablesHelper GetTables(const G4ParticleDefinition* p);
|
||||
|
||||
@@ -56,7 +56,8 @@ enum G4LowEnergyEmProcessSubType
|
||||
fLowEnergyDoubleIonisation = 62,
|
||||
fLowEnergyDoubleCap = 63,
|
||||
fLowEnergyIoniTransfer = 64,
|
||||
fLowEnergyStaticMol = 65
|
||||
fLowEnergyStaticMol = 65,
|
||||
fLowEnergyScavenger = 66
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
|
||||
explicit G4NIELCalculator(G4VEmModel*, G4int verb);
|
||||
|
||||
~G4NIELCalculator();
|
||||
~G4NIELCalculator() = default;
|
||||
|
||||
// initialisation before start of run
|
||||
void Initialise();
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4TransportationWithMsc
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// It is a generic process of transportation with multiple scattering included
|
||||
// in the step limitation and propagation.
|
||||
//
|
||||
// Original author: Jonas Hahnfeld, 2022
|
||||
|
||||
#ifndef G4TrasportationWithMsc_h
|
||||
#define G4TrasportationWithMsc_h 1
|
||||
|
||||
#include "G4Transportation.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class G4EmModelManager;
|
||||
class G4LossTableManager;
|
||||
class G4ParticleDefinition;
|
||||
class G4Region;
|
||||
class G4VMscModel;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
class G4TransportationWithMsc : public G4Transportation
|
||||
{
|
||||
public:
|
||||
enum class ScatteringType
|
||||
{
|
||||
MultipleScattering,
|
||||
};
|
||||
|
||||
explicit G4TransportationWithMsc(ScatteringType type, G4int verbosity = 0);
|
||||
|
||||
~G4TransportationWithMsc() override;
|
||||
|
||||
inline void SetMultipleSteps(G4bool val);
|
||||
inline G4bool MultipleSteps() const;
|
||||
|
||||
void AddMscModel(G4VMscModel* mscModel, G4int order = 0,
|
||||
const G4Region* region = nullptr);
|
||||
|
||||
public:
|
||||
void PreparePhysicsTable(const G4ParticleDefinition& part) override;
|
||||
void BuildPhysicsTable(const G4ParticleDefinition& part) override;
|
||||
|
||||
void StartTracking(G4Track* track) override;
|
||||
|
||||
G4double AlongStepGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4double previousStepSize,
|
||||
G4double currentMinimumStep, G4double& proposedSafety,
|
||||
G4GPILSelection* selection) override;
|
||||
|
||||
private:
|
||||
const ScatteringType fType;
|
||||
G4bool fMultipleSteps = false;
|
||||
|
||||
G4LossTableManager* fEmManager;
|
||||
G4EmModelManager* fModelManager;
|
||||
const G4ParticleDefinition* fFirstParticle = nullptr;
|
||||
|
||||
G4DynamicParticle* fSubStepDynamicParticle;
|
||||
G4Track* fSubStepTrack;
|
||||
G4Step* fSubStep;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline void G4TransportationWithMsc::SetMultipleSteps(G4bool val)
|
||||
{
|
||||
fMultipleSteps = val;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4bool G4TransportationWithMsc::MultipleSteps() const
|
||||
{
|
||||
return fMultipleSteps;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#endif
|
||||
@@ -294,7 +294,6 @@ public:
|
||||
G4double cutEnergy = 0.0,
|
||||
G4double maxEnergy = DBL_MAX);
|
||||
|
||||
|
||||
// to select atom cross section per volume is recomputed for each element
|
||||
const G4Element* SelectRandomAtom(const G4Material*,
|
||||
const G4ParticleDefinition*,
|
||||
@@ -303,10 +302,12 @@ public:
|
||||
G4double maxEnergy = DBL_MAX);
|
||||
|
||||
// to select atom if cross section is proportional number of electrons
|
||||
G4int SelectRandomAtomNumber(const G4Material*);
|
||||
const G4Element* GetCurrentElement(const G4Material* mat = nullptr) const;
|
||||
G4int SelectRandomAtomNumber(const G4Material*) const;
|
||||
|
||||
// select isotope in order to have precise mass of the nucleus
|
||||
G4int SelectIsotopeNumber(const G4Element*);
|
||||
const G4Isotope* GetCurrentIsotope(const G4Element* elm = nullptr) const;
|
||||
G4int SelectIsotopeNumber(const G4Element*) const;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Get/Set methods
|
||||
@@ -388,10 +389,6 @@ public:
|
||||
|
||||
inline void SetCurrentCouple(const G4MaterialCutsCouple*);
|
||||
|
||||
inline const G4Element* GetCurrentElement() const;
|
||||
|
||||
inline const G4Isotope* GetCurrentIsotope() const;
|
||||
|
||||
inline G4bool IsLocked() const;
|
||||
|
||||
inline void SetLocked(G4bool);
|
||||
@@ -415,7 +412,6 @@ private:
|
||||
G4VEmModel* fTripletModel = nullptr;
|
||||
const G4MaterialCutsCouple* fCurrentCouple = nullptr;
|
||||
const G4Element* fCurrentElement = nullptr;
|
||||
const G4Isotope* fCurrentIsotope = nullptr;
|
||||
std::vector<G4EmElementSelector*>* elmSelectors = nullptr;
|
||||
G4LossTableManager* fEmManager;
|
||||
|
||||
@@ -497,21 +493,6 @@ inline const G4MaterialCutsCouple* G4VEmModel::CurrentCouple() const
|
||||
inline void G4VEmModel::SetCurrentElement(const G4Element* elm)
|
||||
{
|
||||
fCurrentElement = elm;
|
||||
fCurrentIsotope = nullptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline const G4Element* G4VEmModel::GetCurrentElement() const
|
||||
{
|
||||
return fCurrentElement;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline const G4Isotope* G4VEmModel::GetCurrentIsotope() const
|
||||
{
|
||||
return fCurrentIsotope;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -569,7 +550,7 @@ G4VEmModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition* part,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
SetCurrentElement(elm);
|
||||
fCurrentElement = elm;
|
||||
return ComputeCrossSectionPerAtom(part,kinEnergy,elm->GetZ(),elm->GetN(),
|
||||
cutEnergy,maxEnergy);
|
||||
}
|
||||
@@ -587,7 +568,6 @@ G4VEmModel::SelectRandomAtom(const G4MaterialCutsCouple* couple,
|
||||
fCurrentElement = (nSelectors > 0) ?
|
||||
((*elmSelectors)[couple->GetIndex()])->SelectRandomAtom(kinEnergy) :
|
||||
SelectRandomAtom(pBaseMaterial,part,kinEnergy,cutEnergy,maxEnergy);
|
||||
fCurrentIsotope = nullptr;
|
||||
return fCurrentElement;
|
||||
}
|
||||
|
||||
@@ -605,7 +585,6 @@ G4VEmModel::SelectTargetAtom(const G4MaterialCutsCouple* couple,
|
||||
fCurrentElement = (nSelectors > 0)
|
||||
? ((*elmSelectors)[couple->GetIndex()])->SelectRandomAtom(kinEnergy,logKinE)
|
||||
: SelectRandomAtom(pBaseMaterial,part,kinEnergy,cutEnergy,maxEnergy);
|
||||
fCurrentIsotope = nullptr;
|
||||
return fCurrentElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,13 +95,6 @@ protected:
|
||||
|
||||
virtual void InitialiseProcess(const G4ParticleDefinition*) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Method with standard implementation; may be overwritten if needed
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
virtual G4double MinPrimaryEnergy(const G4ParticleDefinition*,
|
||||
const G4Material*);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Implementation of virtual methods common to all Discrete processes
|
||||
//------------------------------------------------------------------------
|
||||
@@ -148,25 +141,21 @@ public:
|
||||
// Specific methods for Discrete EM post step simulation
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// It returns the cross section per volume for energy/ material
|
||||
G4double CrossSectionPerVolume(G4double kineticEnergy,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4double logKinEnergy = DBL_MAX);
|
||||
// The main method to access cross section per volume
|
||||
inline G4double GetLambda(G4double kinEnergy,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4double logKinEnergy);
|
||||
|
||||
// It returns the cross section per volume for energy/material
|
||||
G4double GetCrossSection(const G4double kinEnergy,
|
||||
const G4MaterialCutsCouple* couple) override;
|
||||
|
||||
// It returns the cross section of the process per atom
|
||||
G4double ComputeCrossSectionPerAtom(G4double kineticEnergy,
|
||||
G4double Z, G4double A=0.,
|
||||
G4double cut=0.0);
|
||||
|
||||
G4double MeanFreePath(const G4Track& track);
|
||||
|
||||
// Obsolete method to access cross section per volume
|
||||
G4double GetLambda(G4double kinEnergy, const G4MaterialCutsCouple* couple);
|
||||
|
||||
// The main method to access cross section per volume
|
||||
inline G4double GetLambda(G4double kinEnergy,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4double logKinEnergy);
|
||||
inline G4double MeanFreePath(const G4Track& track);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Specific methods to build and access Physics Tables
|
||||
@@ -184,13 +173,18 @@ public:
|
||||
// Max kinetic energy for tables
|
||||
void SetMaxKinEnergy(G4double e);
|
||||
|
||||
// for cross section with one peak
|
||||
void SetEnergyOfCrossSectionMax(std::vector<G4double>*);
|
||||
|
||||
// Cross section table pointers
|
||||
inline G4PhysicsTable* LambdaTable() const;
|
||||
inline G4PhysicsTable* LambdaTablePrim() const;
|
||||
inline void SetLambdaTable(G4PhysicsTable*);
|
||||
inline void SetLambdaTablePrim(G4PhysicsTable*);
|
||||
|
||||
// Integral method type and peak positions
|
||||
inline std::vector<G4double>* EnergyOfCrossSectionMax() const;
|
||||
inline void SetEnergyOfCrossSectionMax(std::vector<G4double>*);
|
||||
inline G4CrossSectionType CrossSectionType() const;
|
||||
inline void SetCrossSectionType(G4CrossSectionType val);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Define and access particle type
|
||||
//------------------------------------------------------------------------
|
||||
@@ -198,12 +192,12 @@ public:
|
||||
inline const G4ParticleDefinition* Particle() const;
|
||||
inline const G4ParticleDefinition* SecondaryParticle() const;
|
||||
|
||||
protected:
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Specific methods to set, access, modify models and basic parameters
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
protected:
|
||||
|
||||
// Select model in run time
|
||||
inline G4VEmModel* SelectModel(G4double kinEnergy, size_t);
|
||||
|
||||
@@ -230,7 +224,7 @@ public:
|
||||
inline const G4VEmModel* GetCurrentModel() const;
|
||||
|
||||
// Access to models
|
||||
G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
|
||||
inline G4VEmModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
|
||||
|
||||
// Access to the current G4Element
|
||||
const G4Element* GetCurrentElement() const;
|
||||
@@ -247,11 +241,7 @@ public:
|
||||
void ActivateSecondaryBiasing(const G4String& region, G4double factor,
|
||||
G4double energyLimit);
|
||||
|
||||
std::vector<G4double>* FindLambdaMax();
|
||||
|
||||
inline void SetEmMasterProcess(const G4VEmProcess*);
|
||||
|
||||
inline void SetCrossSectionType(G4CrossSectionType val);
|
||||
|
||||
inline void SetBuildTableFlag(G4bool val);
|
||||
|
||||
@@ -259,6 +249,11 @@ public:
|
||||
|
||||
inline G4bool UseBaseMaterial() const;
|
||||
|
||||
void BuildLambdaTable();
|
||||
|
||||
void StreamInfo(std::ostream& outFile, const G4ParticleDefinition&,
|
||||
G4bool rst=false) const;
|
||||
|
||||
// hide copy constructor and assignment operator
|
||||
G4VEmProcess(G4VEmProcess &) = delete;
|
||||
G4VEmProcess & operator=(const G4VEmProcess &right) = delete;
|
||||
@@ -286,11 +281,6 @@ protected:
|
||||
// Single scattering parameters
|
||||
inline G4double PolarAngleLimit() const;
|
||||
|
||||
inline G4CrossSectionType CrossSectionType() const;
|
||||
|
||||
inline G4double RecalculateLambda(G4double kinEnergy,
|
||||
const G4MaterialCutsCouple* couple);
|
||||
|
||||
inline G4ParticleChangeForGamma* GetParticleChange();
|
||||
|
||||
inline void SetParticle(const G4ParticleDefinition* p);
|
||||
@@ -311,9 +301,9 @@ protected:
|
||||
|
||||
inline void SetSplineFlag(G4bool val);
|
||||
|
||||
inline const G4Element* GetTargetElement() const;
|
||||
const G4Element* GetTargetElement() const;
|
||||
|
||||
inline const G4Isotope* GetTargetIsotope() const;
|
||||
const G4Isotope* GetTargetIsotope() const;
|
||||
|
||||
// these two methods assume that vectors are initilized
|
||||
// and idx is within vector length
|
||||
@@ -322,13 +312,6 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
void Clear();
|
||||
|
||||
void BuildLambdaTable();
|
||||
|
||||
void StreamInfo(std::ostream& outFile, const G4ParticleDefinition&,
|
||||
G4bool rst=false) const;
|
||||
|
||||
void PrintWarning(G4String tit, G4double val);
|
||||
|
||||
void ComputeIntegralLambda(G4double kinEnergy, G4double logKinEnergy);
|
||||
@@ -391,7 +374,7 @@ private:
|
||||
G4double maxKinEnergy;
|
||||
G4double minKinEnergyPrim = DBL_MAX;
|
||||
G4double lambdaFactor = 0.8;
|
||||
G4double logLambdaFactor;
|
||||
G4double invLambdaFactor;
|
||||
G4double biasFactor = 1.0;
|
||||
G4double massRatio = 1.0;
|
||||
G4double fFactor = 1.0;
|
||||
@@ -456,11 +439,6 @@ private:
|
||||
|
||||
// ======== Run time inline methods ================
|
||||
|
||||
inline G4bool G4VEmProcess::ApplyCuts() const
|
||||
{
|
||||
return applyCuts;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline size_t G4VEmProcess::CurrentMaterialCutsCoupleIndex() const
|
||||
@@ -615,15 +593,22 @@ G4VEmProcess::GetLambda(G4double kinEnergy, const G4MaterialCutsCouple* couple,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4double
|
||||
G4VEmProcess::RecalculateLambda(G4double e, const G4MaterialCutsCouple* couple)
|
||||
G4double G4VEmProcess::MeanFreePath(const G4Track& track)
|
||||
{
|
||||
CurrentSetup(couple, e);
|
||||
return fFactor*ComputeCurrentLambda(e);
|
||||
const G4double kinEnergy = track.GetKineticEnergy();
|
||||
CurrentSetup(track.GetMaterialCutsCouple(), kinEnergy);
|
||||
const G4double xs = GetCurrentLambda(kinEnergy,
|
||||
track.GetDynamicParticle()->GetLogKineticEnergy());
|
||||
return (0.0 < xs) ? 1.0/xs : DBL_MAX;
|
||||
}
|
||||
|
||||
// ======== Get/Set inline methods used at initialisation ================
|
||||
|
||||
inline G4bool G4VEmProcess::ApplyCuts() const
|
||||
{
|
||||
return applyCuts;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4int G4VEmProcess::LambdaBinning() const
|
||||
@@ -668,6 +653,20 @@ inline G4PhysicsTable* G4VEmProcess::LambdaTablePrim() const
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline void G4VEmProcess::SetLambdaTable(G4PhysicsTable* ptr)
|
||||
{
|
||||
theLambdaTable = ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline void G4VEmProcess::SetLambdaTablePrim(G4PhysicsTable* ptr)
|
||||
{
|
||||
theLambdaTablePrim = ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline std::vector<G4double>* G4VEmProcess::EnergyOfCrossSectionMax() const
|
||||
{
|
||||
return theEnergyOfCrossSectionMax;
|
||||
@@ -675,6 +674,14 @@ inline std::vector<G4double>* G4VEmProcess::EnergyOfCrossSectionMax() const
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline void
|
||||
G4VEmProcess::SetEnergyOfCrossSectionMax(std::vector<G4double>* ptr)
|
||||
{
|
||||
theEnergyOfCrossSectionMax = ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline const G4ParticleDefinition* G4VEmProcess::Particle() const
|
||||
{
|
||||
return particle;
|
||||
@@ -746,20 +753,6 @@ inline void G4VEmProcess::SetSplineFlag(G4bool val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline const G4Element* G4VEmProcess::GetTargetElement() const
|
||||
{
|
||||
return currentModel->GetCurrentElement();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline const G4Isotope* G4VEmProcess::GetTargetIsotope() const
|
||||
{
|
||||
return currentModel->GetCurrentIsotope();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4int G4VEmProcess::DensityIndex(G4int idx) const
|
||||
{
|
||||
return (*theDensityIdx)[idx];
|
||||
@@ -809,4 +802,11 @@ inline G4VEmModel* G4VEmProcess::EmModel(size_t index) const
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver) const
|
||||
{
|
||||
return modelManager->GetModel(idx, ver);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#endif
|
||||
|
||||
@@ -75,6 +75,7 @@ class G4VAtomDeexcitation;
|
||||
class G4VSubCutProducer;
|
||||
class G4EmBiasingManager;
|
||||
class G4LossTableManager;
|
||||
class G4EmDataHandler;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -99,20 +100,12 @@ protected:
|
||||
virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition*,
|
||||
const G4ParticleDefinition*) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Methods with standard implementation; may be overwritten if needed
|
||||
//------------------------------------------------------------------------
|
||||
public:
|
||||
|
||||
// used as low energy limit LambdaTable
|
||||
virtual G4double MinPrimaryEnergy(const G4ParticleDefinition*,
|
||||
const G4Material*, G4double cut);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Virtual methods implementation common to all EM ContinuousDiscrete
|
||||
// processes. Further inheritance is not assumed
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
// print documentation in html format
|
||||
void ProcessDescription(std::ostream& outFile) const override;
|
||||
|
||||
@@ -170,19 +163,6 @@ private:
|
||||
void StreamInfo(std::ostream& out, const G4ParticleDefinition& part,
|
||||
G4bool rst=false) const;
|
||||
|
||||
// store a table
|
||||
G4bool StoreTable(const G4ParticleDefinition* p,
|
||||
G4PhysicsTable*, G4bool ascii,
|
||||
const G4String& directory,
|
||||
const G4String& tname);
|
||||
|
||||
// retrieve a table
|
||||
G4bool RetrieveTable(const G4ParticleDefinition* p,
|
||||
G4PhysicsTable*, G4bool ascii,
|
||||
const G4String& directory,
|
||||
const G4String& tname,
|
||||
G4bool mandatory);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Public interface to cross section, mfp and sampling of fluctuations
|
||||
// These methods are not used in run time
|
||||
@@ -328,16 +308,17 @@ public:
|
||||
void SetDEDXTable(G4PhysicsTable* p, G4EmTableType tType);
|
||||
void SetCSDARangeTable(G4PhysicsTable* pRange);
|
||||
void SetRangeTableForLoss(G4PhysicsTable* p);
|
||||
void SetSecondaryRangeTable(G4PhysicsTable* p);
|
||||
void SetInverseRangeTable(G4PhysicsTable* p);
|
||||
void SetLambdaTable(G4PhysicsTable* p);
|
||||
void SetTwoPeaksXS(std::vector<G4TwoPeaksXS*>* p);
|
||||
|
||||
void SetTwoPeaksXS(std::vector<G4TwoPeaksXS*>*);
|
||||
void SetEnergyOfCrossSectionMax(std::vector<G4double>*);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Specific methods to define custom Physics Tables to the process
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Binning for dEdx, range, inverse range and labda tables
|
||||
// Binning for dEdx, range, inverse range and lambda tables
|
||||
void SetDEDXBinning(G4int nbins);
|
||||
|
||||
// Min kinetic energy for tables
|
||||
@@ -375,11 +356,11 @@ public:
|
||||
inline G4PhysicsTable* DEDXunRestrictedTable() const;
|
||||
inline G4PhysicsTable* IonisationTable() const;
|
||||
inline G4PhysicsTable* CSDARangeTable() const;
|
||||
inline G4PhysicsTable* SecondaryRangeTable() const;
|
||||
inline G4PhysicsTable* RangeTableForLoss() const;
|
||||
inline G4PhysicsTable* InverseRangeTable() const;
|
||||
inline G4PhysicsTable* LambdaTable() const;
|
||||
inline std::vector<G4TwoPeaksXS*>* TwoPeaksXS() const;
|
||||
inline std::vector<G4double>* EnergyOfCrossSectionMax() const;
|
||||
|
||||
inline G4bool UseBaseMaterial() const;
|
||||
|
||||
@@ -448,18 +429,13 @@ private:
|
||||
const G4ParticleDefinition* particle = nullptr;
|
||||
const G4ParticleDefinition* baseParticle = nullptr;
|
||||
const G4ParticleDefinition* secondaryParticle = nullptr;
|
||||
const G4ParticleDefinition* theElectron;
|
||||
const G4ParticleDefinition* thePositron;
|
||||
const G4ParticleDefinition* theGamma;
|
||||
const G4ParticleDefinition* theGenericIon = nullptr;
|
||||
G4EmDataHandler* theData = nullptr;
|
||||
|
||||
G4PhysicsTable* theDEDXTable = nullptr;
|
||||
G4PhysicsTable* theDEDXunRestrictedTable = nullptr;
|
||||
G4PhysicsTable* theIonisationTable = nullptr;
|
||||
G4PhysicsTable* theIonisationSubTable = nullptr;
|
||||
G4PhysicsTable* theRangeTableForLoss = nullptr;
|
||||
G4PhysicsTable* theCSDARangeTable = nullptr;
|
||||
G4PhysicsTable* theSecondaryRangeTable = nullptr;
|
||||
G4PhysicsTable* theInverseRangeTable = nullptr;
|
||||
G4PhysicsTable* theLambdaTable = nullptr;
|
||||
|
||||
@@ -469,6 +445,7 @@ private:
|
||||
const std::vector<G4double>* theDensityFactor = nullptr;
|
||||
const G4DataVector* theCuts = nullptr;
|
||||
|
||||
std::vector<G4double>* theEnergyOfCrossSectionMax = nullptr;
|
||||
std::vector<G4TwoPeaksXS*>* fXSpeaks = nullptr;
|
||||
|
||||
G4double lowestKinEnergy;
|
||||
@@ -479,8 +456,8 @@ private:
|
||||
G4double linLossLimit = 0.01;
|
||||
G4double dRoverRange = 0.2;
|
||||
G4double finalRange;
|
||||
G4double lambdaFactor = 1.0;
|
||||
G4double logLambdafactor = 0.0;
|
||||
G4double lambdaFactor = 0.8;
|
||||
G4double invLambdaFactor;
|
||||
G4double biasFactor = 1.0;
|
||||
|
||||
G4double massRatio = 1.0;
|
||||
@@ -488,8 +465,6 @@ private:
|
||||
G4double fFactor = 1.0;
|
||||
G4double reduceFactor = 1.0;
|
||||
G4double chargeSqRatio = 1.0;
|
||||
G4double fLambda = 0.0;
|
||||
G4double fLambdaEnergy = 0.0;
|
||||
G4double fRange = 0.0;
|
||||
G4double fRangeEnergy = 0.0;
|
||||
|
||||
@@ -517,7 +492,6 @@ private:
|
||||
|
||||
size_t basedCoupleIndex = 0;
|
||||
size_t coupleIdxRange = 0;
|
||||
size_t coupleIdxLambda = 0;
|
||||
size_t idxDEDX = 0;
|
||||
size_t idxDEDXunRestricted = 0;
|
||||
size_t idxIonisation = 0;
|
||||
@@ -528,7 +502,7 @@ private:
|
||||
size_t idxLambda = 0;
|
||||
|
||||
G4GPILSelection aGPILSelection;
|
||||
G4CrossSectionType fXSType = fEmIncreasing;
|
||||
G4CrossSectionType fXSType = fEmOnePeak;
|
||||
|
||||
G4bool lossFluctuationFlag = true;
|
||||
G4bool rndmStepFlag = false;
|
||||
@@ -548,8 +522,7 @@ private:
|
||||
G4bool actMaxKinEnergy = false;
|
||||
|
||||
std::vector<G4DynamicParticle*> secParticles;
|
||||
std::vector<G4Track*> scTracks;
|
||||
|
||||
std::vector<G4Track*> scTracks;
|
||||
};
|
||||
|
||||
// ======== Run time inline methods ================
|
||||
@@ -581,7 +554,7 @@ inline void
|
||||
G4VEnergyLossProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
if(couple != currentCouple) {
|
||||
currentCouple = couple;
|
||||
currentCouple = couple;
|
||||
currentMaterial = couple->GetMaterial();
|
||||
basedCoupleIndex = currentCoupleIndex = couple->GetIndex();
|
||||
fFactor = chargeSqRatio*biasFactor;
|
||||
@@ -712,12 +685,7 @@ inline G4double G4VEnergyLossProcess::ScaledKinEnergyForLoss(G4double r)
|
||||
|
||||
inline G4double G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e)
|
||||
{
|
||||
if(currentCoupleIndex != coupleIdxLambda || fLambdaEnergy != e) {
|
||||
coupleIdxLambda = currentCoupleIndex;
|
||||
fLambdaEnergy = e;
|
||||
fLambda = fFactor*((*theLambdaTable)[basedCoupleIndex])->Value(e, idxLambda);
|
||||
}
|
||||
return fLambda;
|
||||
return fFactor*((*theLambdaTable)[basedCoupleIndex])->Value(e, idxLambda);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -725,13 +693,7 @@ inline G4double G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e)
|
||||
inline G4double
|
||||
G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e, G4double loge)
|
||||
{
|
||||
if(currentCoupleIndex != coupleIdxLambda || fLambdaEnergy != e) {
|
||||
coupleIdxLambda = currentCoupleIndex;
|
||||
fLambdaEnergy = e;
|
||||
fLambda = fFactor*
|
||||
((*theLambdaTable)[basedCoupleIndex])->LogVectorValue(e, loge);
|
||||
}
|
||||
return fLambda;
|
||||
return fFactor*((*theLambdaTable)[basedCoupleIndex])->LogVectorValue(e, loge);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -981,13 +943,6 @@ inline G4PhysicsTable* G4VEnergyLossProcess::CSDARangeTable() const
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4PhysicsTable* G4VEnergyLossProcess::SecondaryRangeTable() const
|
||||
{
|
||||
return theSecondaryRangeTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4PhysicsTable* G4VEnergyLossProcess::RangeTableForLoss() const
|
||||
{
|
||||
return theRangeTableForLoss;
|
||||
@@ -1016,6 +971,14 @@ inline G4bool G4VEnergyLossProcess::UseBaseMaterial() const
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline std::vector<G4double>*
|
||||
G4VEnergyLossProcess::EnergyOfCrossSectionMax() const
|
||||
{
|
||||
return theEnergyOfCrossSectionMax;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline std::vector<G4TwoPeaksXS*>* G4VEnergyLossProcess::TwoPeaksXS() const
|
||||
{
|
||||
return fXSpeaks;
|
||||
@@ -1032,8 +995,7 @@ inline size_t G4VEnergyLossProcess::NumberOfModels() const
|
||||
|
||||
inline G4VEmModel* G4VEnergyLossProcess::EmModel(size_t index) const
|
||||
{
|
||||
return (nullptr != emModels && index < emModels->size())
|
||||
? (*emModels)[index] : nullptr;
|
||||
return (index < emModels->size()) ? (*emModels)[index] : nullptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -328,6 +328,8 @@ G4VMscModel::GetTransportMeanFreePath(const G4ParticleDefinition* part,
|
||||
return (x > 0.0) ? 1.0/x : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline G4double
|
||||
G4VMscModel::GetTransportMeanFreePath(const G4ParticleDefinition* part,
|
||||
G4double ekin, G4double logekin)
|
||||
|
||||
@@ -98,10 +98,14 @@ public:
|
||||
|
||||
void ProcessDescription(std::ostream& outFile) const override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void InitialiseProcess(const G4ParticleDefinition*) = 0;
|
||||
|
||||
// Print out of generic class parameters
|
||||
void StreamInfo(std::ostream& outFile, const G4ParticleDefinition&,
|
||||
G4bool rst = false) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void StreamProcessInfo(std::ostream&) const {};
|
||||
|
||||
public:
|
||||
@@ -178,7 +182,7 @@ public:
|
||||
|
||||
// Add model for region, smaller value of order defines which
|
||||
// model will be selected for a given energy interval
|
||||
void AddEmModel(G4int order, G4VEmModel*, const G4Region* region = nullptr);
|
||||
void AddEmModel(G4int order, G4VMscModel*, const G4Region* region = nullptr);
|
||||
|
||||
// Assign a model to a process local list, to enable the list in run time
|
||||
// the derived process should execute AddEmModel(..) for all such models
|
||||
@@ -190,14 +194,12 @@ public:
|
||||
// Access to run time models
|
||||
inline G4int NumberOfModels() const;
|
||||
|
||||
inline G4VMscModel* GetModelByIndex(G4int idx = 0, G4bool ver = false) const;
|
||||
inline G4VMscModel* GetModelByIndex(G4int idx, G4bool ver = false) const;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Get/Set parameters for simulation of multiple scattering
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
void SetIonisation(G4VEnergyLossProcess*);
|
||||
|
||||
inline G4bool LateralDisplasmentFlag() const;
|
||||
|
||||
inline G4double Skin() const;
|
||||
@@ -237,10 +239,6 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
// Print out of generic class parameters
|
||||
void StreamInfo(std::ostream& outFile, const G4ParticleDefinition&,
|
||||
G4bool rst = false) const;
|
||||
|
||||
// ======== Parameters of the class fixed at construction =========
|
||||
|
||||
G4EmModelManager* modelManager;
|
||||
@@ -337,7 +335,7 @@ inline G4double G4VMultipleScattering::PolarAngleLimit() const
|
||||
|
||||
inline G4MscStepLimitType G4VMultipleScattering::StepLimitType() const
|
||||
{
|
||||
return theParameters->MscStepLimitType();
|
||||
return stepLimit;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -387,6 +385,7 @@ inline G4int G4VMultipleScattering::NumberOfModels() const
|
||||
inline G4VMscModel*
|
||||
G4VMultipleScattering::GetModelByIndex(G4int idx, G4bool ver) const
|
||||
{
|
||||
// static cast is possible inside this class
|
||||
return static_cast<G4VMscModel*>(modelManager->GetModel(idx, ver));
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
explicit G4VSubCutProducer(const G4String& name) : fName(name) {};
|
||||
|
||||
virtual ~G4VSubCutProducer() {};
|
||||
virtual ~G4VSubCutProducer() = default;
|
||||
|
||||
// Sample direction in global coordinate system,
|
||||
// this means for zero scattering angle this direction is the same
|
||||
|
||||
@@ -27,6 +27,8 @@ geant4_add_module(G4emutils
|
||||
G4EmSaturation.hh
|
||||
G4EmSecondaryParticleType.hh
|
||||
G4EmTableType.hh
|
||||
G4EmTableUtil.hh
|
||||
G4EmUtility.hh
|
||||
G4EnergyLossTables.hh
|
||||
G4LossTableBuilder.hh
|
||||
G4LossTableManager.hh
|
||||
@@ -36,6 +38,7 @@ geant4_add_module(G4emutils
|
||||
G4NuclearFormfactorType.hh
|
||||
G4OpticalParameters.hh
|
||||
G4OpticalParametersMessenger.hh
|
||||
G4TransportationWithMsc.hh
|
||||
G4VAtomDeexcitation.hh
|
||||
G4VEmAngularDistribution.hh
|
||||
G4VEmFluctuationModel.hh
|
||||
@@ -65,12 +68,15 @@ geant4_add_module(G4emutils
|
||||
G4EmParameters.cc
|
||||
G4EmParametersMessenger.cc
|
||||
G4EmSaturation.cc
|
||||
G4EmTableUtil.cc
|
||||
G4EmUtility.cc
|
||||
G4EnergyLossTables.cc
|
||||
G4LossTableBuilder.cc
|
||||
G4LossTableManager.cc
|
||||
G4NIELCalculator.cc
|
||||
G4OpticalParameters.cc
|
||||
G4OpticalParametersMessenger.cc
|
||||
G4TransportationWithMsc.cc
|
||||
G4VAtomDeexcitation.cc
|
||||
G4VEmAngularDistribution.cc
|
||||
G4VEmFluctuationModel.cc
|
||||
@@ -93,6 +99,7 @@ geant4_module_link_libraries(G4emutils
|
||||
G4partman
|
||||
G4procman
|
||||
G4track
|
||||
G4transportation
|
||||
PRIVATE
|
||||
G4baryons
|
||||
G4bosons
|
||||
|
||||
@@ -45,8 +45,7 @@
|
||||
G4AngleDirect::G4AngleDirect() : G4VEmAngularDistribution("AngleDirect")
|
||||
{}
|
||||
|
||||
G4AngleDirect::~G4AngleDirect()
|
||||
{}
|
||||
G4AngleDirect::~G4AngleDirect() = default;
|
||||
|
||||
G4ThreeVector& G4AngleDirect::SampleDirection(const G4DynamicParticle* dp,
|
||||
G4double, G4int,
|
||||
|
||||
@@ -57,8 +57,7 @@ G4DummyModel::G4DummyModel(const G4String& nam)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DummyModel::~G4DummyModel()
|
||||
{}
|
||||
G4DummyModel::~G4DummyModel() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -66,8 +66,7 @@ G4ElectronIonPair::G4ElectronIonPair(G4int verb)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4ElectronIonPair::~G4ElectronIonPair()
|
||||
{}
|
||||
G4ElectronIonPair::~G4ElectronIonPair() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -106,7 +105,7 @@ G4double G4ElectronIonPair::MeanNumberOfIonsAlongStep(
|
||||
std::vector<G4ThreeVector>*
|
||||
G4ElectronIonPair::SampleIonsAlongStep(const G4Step* step)
|
||||
{
|
||||
std::vector<G4ThreeVector>* v = 0;
|
||||
std::vector<G4ThreeVector>* v = nullptr;
|
||||
|
||||
G4int nion = SampleNumberOfIonsAlongStep(step);
|
||||
|
||||
|
||||
@@ -74,8 +74,7 @@ G4EmBiasingManager::G4EmBiasingManager()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmBiasingManager::~G4EmBiasingManager()
|
||||
{}
|
||||
G4EmBiasingManager::~G4EmBiasingManager() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -415,7 +414,7 @@ G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4Track*>& track,
|
||||
if(G4UniformRand()*weight > 1.0) {
|
||||
const G4Track* t = track[k];
|
||||
delete t;
|
||||
track[k] = 0;
|
||||
track[k] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -444,7 +443,7 @@ G4EmBiasingManager::ApplyRangeCut(std::vector<G4DynamicParticle*>& vd,
|
||||
if(eIonisation->GetRange(e, track.GetMaterialCutsCouple()) < safety) {
|
||||
eloss += e;
|
||||
delete dp;
|
||||
vd[k] = 0;
|
||||
vd[k] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -589,9 +588,9 @@ G4EmBiasingManager::ApplyDirectionalSplitting(
|
||||
foundPrimaryParticle = true;
|
||||
primaryWeight = weight;
|
||||
} else {
|
||||
G4DynamicParticle* dp = new G4DynamicParticle(theGamma,
|
||||
partChange->GetProposedMomentumDirection(),
|
||||
partChange->GetProposedKineticEnergy());
|
||||
auto dp = new G4DynamicParticle(theGamma,
|
||||
partChange->GetProposedMomentumDirection(),
|
||||
partChange->GetProposedKineticEnergy());
|
||||
vd.push_back(dp);
|
||||
fDirectionalSplittingWeights.push_back(1.);
|
||||
}
|
||||
@@ -602,9 +601,9 @@ G4EmBiasingManager::ApplyDirectionalSplitting(
|
||||
primaryMomdir = momdir;
|
||||
primaryWeight = 1.;
|
||||
} else {
|
||||
G4DynamicParticle* dp = new G4DynamicParticle(theGamma,
|
||||
partChange->GetProposedMomentumDirection(),
|
||||
partChange->GetProposedKineticEnergy());
|
||||
auto dp = new G4DynamicParticle(theGamma,
|
||||
partChange->GetProposedMomentumDirection(),
|
||||
partChange->GetProposedKineticEnergy());
|
||||
vd.push_back(dp);
|
||||
fDirectionalSplittingWeights.push_back(1./weight);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4EmUtility.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -247,11 +248,11 @@ G4double G4EmCalculator::GetCrossSectionPerVolume(G4double kinEnergy,
|
||||
|
||||
G4VEmProcess* emproc = FindDiscreteProcess(p, processName);
|
||||
if(emproc) {
|
||||
res = emproc->CrossSectionPerVolume(kinEnergy, couple);
|
||||
res = emproc->GetCrossSection(kinEnergy, couple);
|
||||
} else if(currentLambda) {
|
||||
// special tables are built for Msc models (procType is set in FindLambdaTable
|
||||
if(procType==2) {
|
||||
G4VMscModel* mscM = static_cast<G4VMscModel*>(currentModel);
|
||||
auto mscM = static_cast<G4VMscModel*>(currentModel);
|
||||
mscM->SetCurrentCouple(couple);
|
||||
G4double tr1Mfp = mscM->GetTransportMeanFreePath(p, kinEnergy);
|
||||
if (tr1Mfp<DBL_MAX) {
|
||||
@@ -367,7 +368,8 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
|
||||
|
||||
// Special case of ICRU'73 model
|
||||
const G4String& mname = currentModel->GetName();
|
||||
if(mname == "ParamICRU73" || mname == "LinhardSorensen" || mname == "Atima") {
|
||||
if(mname == "ParamICRU73" || mname == "LinhardSorensen" ||
|
||||
mname == "Atima") {
|
||||
res = currentModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cut);
|
||||
if(verbose > 1) {
|
||||
G4cout << mname << " ion E(MeV)= " << kinEnergy << " ";
|
||||
@@ -388,7 +390,9 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
|
||||
}
|
||||
} else {
|
||||
res = currentModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cut);
|
||||
if(verbose > 1) { G4cout << " no basePart E(MeV)= " << kinEnergy << " "; }
|
||||
if(verbose > 1) {
|
||||
G4cout << " no basePart E(MeV)= " << kinEnergy << " ";
|
||||
}
|
||||
}
|
||||
if(verbose > 1) {
|
||||
G4cout << currentModel->GetName() << ": DEDX(MeV/mm)= " << res*mm/MeV
|
||||
@@ -404,10 +408,10 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
|
||||
G4double res0 = 0.0;
|
||||
G4double res1 = 0.0;
|
||||
if(baseParticle) {
|
||||
res1 = currentModel->ComputeDEDXPerVolume(mat, baseParticle, eth, cut)
|
||||
* chargeSquare;
|
||||
res0 = loweModel->ComputeDEDXPerVolume(mat, baseParticle, eth, cut)
|
||||
* chargeSquare;
|
||||
res1 = chargeSquare*
|
||||
currentModel->ComputeDEDXPerVolume(mat, baseParticle, eth, cut);
|
||||
res0 = chargeSquare*
|
||||
loweModel->ComputeDEDXPerVolume(mat, baseParticle, eth, cut);
|
||||
} else {
|
||||
res1 = currentModel->ComputeDEDXPerVolume(mat, p, eth, cut);
|
||||
res0 = loweModel->ComputeDEDXPerVolume(mat, p, eth, cut);
|
||||
@@ -430,7 +434,7 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
|
||||
// low energy correction for ions
|
||||
if(isIon) {
|
||||
G4double length = CLHEP::nm;
|
||||
const G4Region* r = 0;
|
||||
const G4Region* r = nullptr;
|
||||
const G4MaterialCutsCouple* couple = FindCouple(mat, r);
|
||||
G4double eloss = res*length;
|
||||
dynParticle->SetKineticEnergy(kinEnergy);
|
||||
@@ -440,8 +444,8 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV
|
||||
<< " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
|
||||
<< G4endl;
|
||||
<< " DEDX(MeV*cm^2/g)= "
|
||||
<< res*gram/(MeV*cm2*mat->GetDensity()) << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -482,10 +486,10 @@ G4double G4EmCalculator::ComputeElectronicDEDX(G4double kinEnergy,
|
||||
|
||||
for(G4int i=0; i<n; ++i) {
|
||||
if(vel[i]) {
|
||||
G4VProcess* p = reinterpret_cast<G4VProcess*>(vel[i]);
|
||||
auto p = reinterpret_cast<G4VProcess*>(vel[i]);
|
||||
if(ActiveForParticle(part, p)) {
|
||||
//G4cout << "idx= " << i << " " << (vel[i])->GetProcessName()
|
||||
// << " " << (vel[i])->Particle()->GetParticleName() << G4endl;
|
||||
// << " " << (vel[i])->Particle()->GetParticleName() << G4endl;
|
||||
dedx += ComputeDEDX(kinEnergy,part,(vel[i])->GetProcessName(),mat,cut);
|
||||
}
|
||||
}
|
||||
@@ -496,10 +500,11 @@ G4double G4EmCalculator::ComputeElectronicDEDX(G4double kinEnergy,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCalculator::ComputeDEDXForCutInRange(G4double kinEnergy,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4Material* mat,
|
||||
G4double rangecut)
|
||||
G4double
|
||||
G4EmCalculator::ComputeDEDXForCutInRange(G4double kinEnergy,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4Material* mat,
|
||||
G4double rangecut)
|
||||
{
|
||||
SetupMaterial(mat);
|
||||
G4double dedx = 0.0;
|
||||
@@ -512,9 +517,12 @@ G4double G4EmCalculator::ComputeDEDXForCutInRange(G4double kinEnergy,
|
||||
|
||||
if(mat != cutMaterial) {
|
||||
cutMaterial = mat;
|
||||
cutenergy[0] = ComputeEnergyCutFromRangeCut(rangecut, G4Gamma::Gamma(), mat);
|
||||
cutenergy[1] = ComputeEnergyCutFromRangeCut(rangecut, G4Electron::Electron(), mat);
|
||||
cutenergy[2] = ComputeEnergyCutFromRangeCut(rangecut, G4Positron::Positron(), mat);
|
||||
cutenergy[0] =
|
||||
ComputeEnergyCutFromRangeCut(rangecut, G4Gamma::Gamma(), mat);
|
||||
cutenergy[1] =
|
||||
ComputeEnergyCutFromRangeCut(rangecut, G4Electron::Electron(), mat);
|
||||
cutenergy[2] =
|
||||
ComputeEnergyCutFromRangeCut(rangecut, G4Positron::Positron(), mat);
|
||||
}
|
||||
|
||||
//G4cout << "ComputeElectronicDEDX for " << part->GetParticleName()
|
||||
@@ -522,10 +530,10 @@ G4double G4EmCalculator::ComputeDEDXForCutInRange(G4double kinEnergy,
|
||||
|
||||
for(G4int i=0; i<n; ++i) {
|
||||
if(vel[i]) {
|
||||
G4VProcess* p = reinterpret_cast<G4VProcess*>(vel[i]);
|
||||
auto p = reinterpret_cast<G4VProcess*>(vel[i]);
|
||||
if(ActiveForParticle(part, p)) {
|
||||
//G4cout << "idx= " << i << " " << (vel[i])->GetProcessName()
|
||||
// << " " << (vel[i])->Particle()->GetParticleName() << G4endl;
|
||||
// << " " << (vel[i])->Particle()->GetParticleName() << G4endl;
|
||||
const G4ParticleDefinition* sec = (vel[i])->SecondaryParticle();
|
||||
G4int idx = 0;
|
||||
if(sec == G4Electron::Electron()) { idx = 1; }
|
||||
@@ -601,7 +609,8 @@ G4double G4EmCalculator::ComputeCrossSectionPerVolume(
|
||||
res = currentModel->CrossSectionPerVolume(mat, p, e, aCut, e);
|
||||
}
|
||||
if(verbose>0) {
|
||||
G4cout << "G4EmCalculator::ComputeXSPerVolume: E(MeV)= " << kinEnergy/MeV
|
||||
G4cout << "G4EmCalculator::ComputeXSPerVolume: E(MeV)= "
|
||||
<< kinEnergy/MeV
|
||||
<< " cross(cm-1)= " << res*cm
|
||||
<< " cut(keV)= " << aCut/keV
|
||||
<< " " << p->GetParticleName()
|
||||
@@ -615,12 +624,12 @@ G4double G4EmCalculator::ComputeCrossSectionPerVolume(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCalculator::ComputeCrossSectionPerAtom(
|
||||
G4double kinEnergy,
|
||||
const G4ParticleDefinition* p,
|
||||
const G4String& processName,
|
||||
G4double Z, G4double A,
|
||||
G4double cut)
|
||||
G4double
|
||||
G4EmCalculator::ComputeCrossSectionPerAtom(G4double kinEnergy,
|
||||
const G4ParticleDefinition* p,
|
||||
const G4String& processName,
|
||||
G4double Z, G4double A,
|
||||
G4double cut)
|
||||
{
|
||||
G4double res = 0.0;
|
||||
if(UpdateParticle(p, kinEnergy)) {
|
||||
@@ -653,11 +662,12 @@ G4double G4EmCalculator::ComputeCrossSectionPerAtom(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4EmCalculator::ComputeCrossSectionPerShell(G4double kinEnergy,
|
||||
const G4ParticleDefinition* p,
|
||||
const G4String& processName,
|
||||
G4int Z, G4int shellIdx,
|
||||
G4double cut)
|
||||
G4double
|
||||
G4EmCalculator::ComputeCrossSectionPerShell(G4double kinEnergy,
|
||||
const G4ParticleDefinition* p,
|
||||
const G4String& processName,
|
||||
G4int Z, G4int shellIdx,
|
||||
G4double cut)
|
||||
{
|
||||
G4double res = 0.0;
|
||||
if(UpdateParticle(p, kinEnergy)) {
|
||||
@@ -668,8 +678,9 @@ G4double G4EmCalculator::ComputeCrossSectionPerShell(G4double kinEnergy,
|
||||
if(baseParticle) {
|
||||
e *= kinEnergy*massRatio;
|
||||
currentModel->InitialiseForElement(baseParticle, Z);
|
||||
res = currentModel->ComputeCrossSectionPerShell(baseParticle, Z, shellIdx,
|
||||
e, aCut) * chargeSquare;
|
||||
res =
|
||||
currentModel->ComputeCrossSectionPerShell(baseParticle, Z, shellIdx,
|
||||
e, aCut) * chargeSquare;
|
||||
} else {
|
||||
currentModel->InitialiseForElement(p, Z);
|
||||
res = currentModel->ComputeCrossSectionPerAtom(p, Z, shellIdx, e, aCut);
|
||||
@@ -728,10 +739,11 @@ G4double G4EmCalculator::ComputeMeanFreePath(G4double kinEnergy,
|
||||
const G4ParticleDefinition* p,
|
||||
const G4String& processName,
|
||||
const G4Material* mat,
|
||||
G4double cut)
|
||||
G4double cut)
|
||||
{
|
||||
G4double mfp = DBL_MAX;
|
||||
G4double x = ComputeCrossSectionPerVolume(kinEnergy, p, processName, mat, cut);
|
||||
G4double x =
|
||||
ComputeCrossSectionPerVolume(kinEnergy, p, processName, mat, cut);
|
||||
if(x > 0.0) { mfp = 1.0/x; }
|
||||
if(verbose>1) {
|
||||
G4cout << "E(MeV)= " << kinEnergy/MeV
|
||||
@@ -765,7 +777,7 @@ G4bool G4EmCalculator::UpdateParticle(const G4ParticleDefinition* p,
|
||||
currentParticle = p;
|
||||
dynParticle->SetDefinition(const_cast<G4ParticleDefinition*>(p));
|
||||
dynParticle->SetKineticEnergy(kinEnergy);
|
||||
baseParticle = 0;
|
||||
baseParticle = nullptr;
|
||||
currentParticleName = p->GetParticleName();
|
||||
massRatio = 1.0;
|
||||
mass = p->GetPDGMass();
|
||||
@@ -825,7 +837,7 @@ G4bool G4EmCalculator::UpdateParticle(const G4ParticleDefinition* p,
|
||||
|
||||
const G4ParticleDefinition* G4EmCalculator::FindParticle(const G4String& name)
|
||||
{
|
||||
const G4ParticleDefinition* p = 0;
|
||||
const G4ParticleDefinition* p = nullptr;
|
||||
if(name != currentParticleName) {
|
||||
p = G4ParticleTable::GetParticleTable()->FindParticle(name);
|
||||
if(!p) {
|
||||
@@ -864,13 +876,7 @@ const G4Material* G4EmCalculator::FindMaterial(const G4String& name)
|
||||
|
||||
const G4Region* G4EmCalculator::FindRegion(const G4String& reg)
|
||||
{
|
||||
const G4Region* r = 0;
|
||||
if(reg != "" && reg != "world") {
|
||||
r = G4RegionStore::GetInstance()->GetRegion(reg);
|
||||
} else {
|
||||
r = G4RegionStore::GetInstance()->GetRegion("DefaultRegionForTheWorld");
|
||||
}
|
||||
return r;
|
||||
return G4EmUtility::FindRegion(reg);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -1136,13 +1142,13 @@ G4VEnergyLossProcess*
|
||||
G4EmCalculator::FindEnLossProcess(const G4ParticleDefinition* part,
|
||||
const G4String& processName)
|
||||
{
|
||||
G4VEnergyLossProcess* proc = 0;
|
||||
G4VEnergyLossProcess* proc = nullptr;
|
||||
const std::vector<G4VEnergyLossProcess*> v =
|
||||
manager->GetEnergyLossProcessVector();
|
||||
G4int n = v.size();
|
||||
for(G4int i=0; i<n; ++i) {
|
||||
if((v[i])->GetProcessName() == processName) {
|
||||
G4VProcess* p = reinterpret_cast<G4VProcess*>(v[i]);
|
||||
auto p = reinterpret_cast<G4VProcess*>(v[i]);
|
||||
if(ActiveForParticle(part, p)) {
|
||||
proc = v[i];
|
||||
break;
|
||||
@@ -1167,7 +1173,7 @@ G4EmCalculator::FindDiscreteProcess(const G4ParticleDefinition* part,
|
||||
proc = v[i]->GetEmProcess(processName);
|
||||
break;
|
||||
} else if(pName == processName) {
|
||||
G4VProcess* p = reinterpret_cast<G4VProcess*>(v[i]);
|
||||
auto p = reinterpret_cast<G4VProcess*>(v[i]);
|
||||
if(ActiveForParticle(part, p)) {
|
||||
proc = v[i];
|
||||
break;
|
||||
@@ -1183,13 +1189,13 @@ G4VMultipleScattering*
|
||||
G4EmCalculator::FindMscProcess(const G4ParticleDefinition* part,
|
||||
const G4String& processName)
|
||||
{
|
||||
G4VMultipleScattering* proc = 0;
|
||||
G4VMultipleScattering* proc = nullptr;
|
||||
const std::vector<G4VMultipleScattering*> v =
|
||||
manager->GetMultipleScatteringVector();
|
||||
G4int n = v.size();
|
||||
for(G4int i=0; i<n; ++i) {
|
||||
if((v[i])->GetProcessName() == processName) {
|
||||
G4VProcess* p = reinterpret_cast<G4VProcess*>(v[i]);
|
||||
auto p = reinterpret_cast<G4VProcess*>(v[i]);
|
||||
if(ActiveForParticle(part, p)) {
|
||||
proc = v[i];
|
||||
break;
|
||||
@@ -1204,7 +1210,7 @@ G4EmCalculator::FindMscProcess(const G4ParticleDefinition* part,
|
||||
G4VProcess* G4EmCalculator::FindProcess(const G4ParticleDefinition* part,
|
||||
const G4String& processName)
|
||||
{
|
||||
G4VProcess* proc = 0;
|
||||
G4VProcess* proc = nullptr;
|
||||
const G4ProcessManager* procman = part->GetProcessManager();
|
||||
G4ProcessVector* pv = procman->GetProcessList();
|
||||
G4int nproc = pv->size();
|
||||
@@ -1243,7 +1249,7 @@ void G4EmCalculator::SetupMaterial(const G4Material* mat)
|
||||
currentMaterial = mat;
|
||||
currentMaterialName = mat->GetName();
|
||||
} else {
|
||||
currentMaterial = 0;
|
||||
currentMaterial = nullptr;
|
||||
currentMaterialName = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
//
|
||||
|
||||
#include "G4EmConfigurator.hh"
|
||||
#include "G4EmUtility.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
@@ -58,6 +59,7 @@
|
||||
#include "G4VEnergyLossProcess.hh"
|
||||
#include "G4VEmProcess.hh"
|
||||
#include "G4VMultipleScattering.hh"
|
||||
#include "G4TransportationWithMsc.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -68,8 +70,7 @@ G4EmConfigurator::G4EmConfigurator(G4int val):verbose(val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmConfigurator::~G4EmConfigurator()
|
||||
{}
|
||||
G4EmConfigurator::~G4EmConfigurator() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -110,13 +111,13 @@ void G4EmConfigurator::SetExtraEmModel(const G4String& particleName,
|
||||
void G4EmConfigurator::AddModels()
|
||||
{
|
||||
size_t n = models.size();
|
||||
if(0 < verbose) {
|
||||
if(1 < verbose) {
|
||||
G4cout << "### G4EmConfigurator::AddModels n= " << n << G4endl;
|
||||
}
|
||||
if(n > 0) {
|
||||
for(size_t i=0; i<n; ++i) {
|
||||
if(nullptr != models[i]) {
|
||||
const G4Region* reg = FindRegion(regions[i]);
|
||||
const G4Region* reg = G4EmUtility::FindRegion(regions[i]);
|
||||
if(nullptr != reg) {
|
||||
--index;
|
||||
SetModelForRegion(models[i],flucModels[i],reg,
|
||||
@@ -178,36 +179,67 @@ void G4EmConfigurator::SetModelForRegion(G4VEmModel* mod,
|
||||
break;
|
||||
}
|
||||
}
|
||||
G4bool isCombinedMscTrans = false;
|
||||
G4TransportationWithMsc* trans = nullptr;
|
||||
if(nullptr == proc) {
|
||||
G4cout << "### G4EmConfigurator WARNING: fails to find a process <"
|
||||
<< processName << "> for " << particleName << G4endl;
|
||||
return;
|
||||
}
|
||||
if(processName == "msc") {
|
||||
for(G4int i=0; i<np; ++i) {
|
||||
trans = dynamic_cast<G4TransportationWithMsc*>((*plist)[i]);
|
||||
if(nullptr != trans) {
|
||||
G4cout << "G4TransportationWithMsc is found out!" << G4endl;
|
||||
isCombinedMscTrans = true;
|
||||
proc = trans;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(nullptr == proc) {
|
||||
if(0 < verbose) {
|
||||
G4cout << "### G4EmConfigurator WARNING: fails to find a process <"
|
||||
<< processName << "> for " << particleName << G4endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(!UpdateModelEnergyRange(mod, emin, emax)) { return; }
|
||||
// classify process
|
||||
G4int ii = proc->GetProcessSubType();
|
||||
if(10 == ii) {
|
||||
G4VMultipleScattering* p = static_cast<G4VMultipleScattering*>(proc);
|
||||
p->AddEmModel(index,mod,reg);
|
||||
auto msc = dynamic_cast<G4VMscModel*>(mod);
|
||||
if(isCombinedMscTrans && nullptr != msc) {
|
||||
trans->AddMscModel(msc, index, reg);
|
||||
if(1 < verbose) {
|
||||
G4cout << "### Added msc model order= " << index << " for "
|
||||
<< particleName << " and " << processName << G4endl;
|
||||
<< particleName << " and " << proc->GetProcessName()
|
||||
<< G4endl;
|
||||
}
|
||||
} else if(10 == ii && nullptr != msc) {
|
||||
auto p = dynamic_cast<G4VMultipleScattering*>(proc);
|
||||
if(nullptr != p) {
|
||||
p->AddEmModel(index, msc, reg);
|
||||
if(1 < verbose) {
|
||||
G4cout << "### Added msc model order= " << index << " for "
|
||||
<< particleName << " and " << processName << G4endl;
|
||||
}
|
||||
}
|
||||
} else if(2 <= ii && 4 >= ii) {
|
||||
G4VEnergyLossProcess* p = static_cast<G4VEnergyLossProcess*>(proc);
|
||||
p->AddEmModel(index,mod,fm,reg);
|
||||
if(1 < verbose) {
|
||||
G4cout << "### Added eloss model order= " << index << " for "
|
||||
<< particleName << " and " << processName << G4endl;
|
||||
}
|
||||
auto p = dynamic_cast<G4VEnergyLossProcess*>(proc);
|
||||
if(nullptr != p) {
|
||||
p->AddEmModel(index,mod,fm,reg);
|
||||
if(1 < verbose) {
|
||||
G4cout << "### Added eloss model order= " << index << " for "
|
||||
<< particleName << " and " << processName << G4endl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
G4VEmProcess* p = static_cast<G4VEmProcess*>(proc);
|
||||
p->AddEmModel(index,mod,reg);
|
||||
if(1 < verbose) {
|
||||
G4cout << "### Added em model order= " << index << " for "
|
||||
<< particleName << " and " << processName << G4endl;
|
||||
}
|
||||
auto p = dynamic_cast<G4VEmProcess*>(proc);
|
||||
if(nullptr != p) {
|
||||
p->AddEmModel(index,mod,reg);
|
||||
if(1 < verbose) {
|
||||
G4cout << "### Added em model order= " << index << " for "
|
||||
<< particleName << " and " << processName << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -235,7 +267,7 @@ G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
|
||||
if((particleName == particles[i]) ||
|
||||
(particles[i] == "all") ||
|
||||
(particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
|
||||
const G4Region* reg = FindRegion(regions[i]);
|
||||
const G4Region* reg = G4EmUtility::FindRegion(regions[i]);
|
||||
//G4cout << "Region " << reg << G4endl;
|
||||
if(nullptr != reg) {
|
||||
--index;
|
||||
@@ -280,7 +312,7 @@ G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
|
||||
if((particleName == particles[i]) ||
|
||||
(particles[i] == "all") ||
|
||||
(particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
|
||||
const G4Region* reg = FindRegion(regions[i]);
|
||||
const G4Region* reg = G4EmUtility::FindRegion(regions[i]);
|
||||
//G4cout << "Region " << reg << G4endl;
|
||||
if(nullptr != reg) {
|
||||
--index;
|
||||
@@ -305,7 +337,8 @@ G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
|
||||
|
||||
void
|
||||
G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
|
||||
G4VMultipleScattering* p)
|
||||
G4VMultipleScattering* p,
|
||||
G4TransportationWithMsc* trans)
|
||||
{
|
||||
size_t n = particles.size();
|
||||
if(1 < verbose) {
|
||||
@@ -314,22 +347,26 @@ G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
|
||||
}
|
||||
|
||||
if(n > 0) {
|
||||
G4String particleName = aParticle->GetParticleName();
|
||||
G4String processName = p->GetProcessName();
|
||||
G4String particleName = aParticle->GetParticleName();
|
||||
G4String processName = (nullptr == p) ? "msc" : p->GetProcessName();
|
||||
for(size_t i=0; i<n; ++i) {
|
||||
if(processName == processes[i]) {
|
||||
if((particleName == particles[i]) ||
|
||||
(particles[i] == "all") ||
|
||||
(particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
|
||||
const G4Region* reg = FindRegion(regions[i]);
|
||||
if(nullptr != reg) {
|
||||
--index;
|
||||
G4VEmModel* mod = models[i];
|
||||
if((particleName == particles[i]) ||
|
||||
(particles[i] == "all") ||
|
||||
(particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
|
||||
const G4Region* reg = G4EmUtility::FindRegion(regions[i]);
|
||||
if(nullptr != reg) {
|
||||
--index;
|
||||
auto mod = dynamic_cast<G4VMscModel*>(models[i]);
|
||||
if(nullptr != mod) {
|
||||
if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
|
||||
p->AddEmModel(index,mod,reg);
|
||||
if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
|
||||
if(nullptr != p) {
|
||||
p->AddEmModel(index,mod,reg);
|
||||
} else {
|
||||
trans->AddMscModel(mod,index,reg);
|
||||
}
|
||||
//G4cout << "### Added msc model order= " << index << " for "
|
||||
// << particleName << " and " << processName << G4endl;
|
||||
// << particleName << " and " << processName << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,28 +391,6 @@ void G4EmConfigurator::Clear()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
const G4Region* G4EmConfigurator::FindRegion(const G4String& regionName)
|
||||
{
|
||||
// search for region
|
||||
const G4Region* reg = nullptr;
|
||||
G4RegionStore* regStore = G4RegionStore::GetInstance();
|
||||
G4String r = regionName;
|
||||
if(r == "" || r == "world" || r == "World") {
|
||||
r = "DefaultRegionForTheWorld";
|
||||
}
|
||||
reg = regStore->GetRegion(r, true);
|
||||
if(nullptr == reg) {
|
||||
G4cout << "### G4EmConfigurator WARNING: fails to find a region <"
|
||||
<< r << G4endl;
|
||||
} else if(verbose > 1) {
|
||||
G4cout << "### G4EmConfigurator finds out G4Region <" << r << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4EmConfigurator::UpdateModelEnergyRange(G4VEmModel* mod,
|
||||
G4double emin, G4double emax)
|
||||
{
|
||||
|
||||
@@ -852,8 +852,7 @@ void G4EmCorrections::BuildCorrectionVector()
|
||||
<< ion->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
G4PhysicsLogVector* vv =
|
||||
new G4PhysicsLogVector(eCorrMin,eCorrMax,nbinCorr,false);
|
||||
auto vv = new G4PhysicsLogVector(eCorrMin,eCorrMax,nbinCorr,false);
|
||||
const G4double eth0 = v->Energy(0);
|
||||
const G4double escal = eth/massFactor;
|
||||
G4double qe =
|
||||
@@ -904,8 +903,7 @@ void G4EmCorrections::InitialiseForNewRun()
|
||||
ncouples = tb->GetTableSize();
|
||||
if(currmat.size() != ncouples) {
|
||||
currmat.resize(ncouples);
|
||||
for(std::map< G4int, std::vector<G4double> >::iterator it =
|
||||
thcorr.begin(); it != thcorr.end(); ++it){
|
||||
for(auto it = thcorr.begin(); it != thcorr.end(); ++it){
|
||||
(it->second).clear();
|
||||
}
|
||||
thcorr.clear();
|
||||
|
||||
@@ -58,9 +58,12 @@ G4EmDataHandler::G4EmDataHandler(size_t n) : tLength(n)
|
||||
|
||||
G4EmDataHandler::~G4EmDataHandler()
|
||||
{
|
||||
//std::cout << "G4EmDataHandler::~G4EmDataHandler "
|
||||
// << tLength << " " << this << std::endl;
|
||||
for(size_t i=0; i<tLength; ++i) { CleanTable(i); }
|
||||
for(size_t i=0; i<tLength; ++i) {
|
||||
for(size_t j = i+1; j<tLength; ++j) {
|
||||
if(data[j] == data[i]) { data[j] = nullptr; }
|
||||
}
|
||||
CleanTable(i);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -74,27 +77,56 @@ size_t G4EmDataHandler::SetTable(G4PhysicsTable* ptr)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmDataHandler::UpdateTable(G4PhysicsTable* ptr, size_t idx)
|
||||
{
|
||||
// update table pointer but not delete previous
|
||||
if(idx < tLength) {
|
||||
if(ptr != data[idx]) { data[idx] = ptr; }
|
||||
} else {
|
||||
G4cout << "### G4EmDataHandler::UpdateTable fail for idx=" << idx
|
||||
<< " length=" << tLength << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4PhysicsTable* G4EmDataHandler::MakeTable(size_t i)
|
||||
{
|
||||
G4PhysicsTable* table = nullptr;
|
||||
size_t idx = i;
|
||||
if(idx >= tLength) {
|
||||
data.push_back(nullptr);
|
||||
idx = tLength;
|
||||
++tLength;
|
||||
}
|
||||
data[idx] = G4PhysicsTableHelper::PreparePhysicsTable(data[idx]);
|
||||
return data[idx];
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4PhysicsTable* G4EmDataHandler::MakeTable(G4PhysicsTable* ptr, size_t i)
|
||||
{
|
||||
size_t idx = i;
|
||||
// create new table only if index corresponds to the
|
||||
// position in the vector
|
||||
if(i <= tLength) {
|
||||
if(i < tLength) { table = data[i]; }
|
||||
table = G4PhysicsTableHelper::PreparePhysicsTable(table);
|
||||
if(i == tLength) {
|
||||
data.push_back(table);
|
||||
++tLength;
|
||||
} else { data[i] = table; }
|
||||
if(idx < tLength) {
|
||||
if(ptr != data[idx]) {
|
||||
CleanTable(idx);
|
||||
data[idx] = ptr;
|
||||
}
|
||||
} else {
|
||||
data.push_back(ptr);
|
||||
idx = tLength;
|
||||
++tLength;
|
||||
}
|
||||
return table;
|
||||
data[idx] = G4PhysicsTableHelper::PreparePhysicsTable(ptr);
|
||||
return data[idx];
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmDataHandler::CleanTable(size_t i)
|
||||
{
|
||||
//std::cout << i << " " << data[i] << std::endl;
|
||||
if(i < tLength && nullptr != data[i]) {
|
||||
data[i]->clearAndDestroy();
|
||||
delete data[i];
|
||||
@@ -114,11 +146,11 @@ G4bool G4EmDataHandler::StorePhysicsTable(size_t idx,
|
||||
yes = data[idx]->StorePhysicsTable(fname, ascii);
|
||||
|
||||
if ( yes ) {
|
||||
G4cout << "Physics table is stored for "
|
||||
G4cout << "### Physics table is stored for "
|
||||
<< part->GetParticleName()
|
||||
<< " <" << fname << "> " << G4endl;
|
||||
} else {
|
||||
G4cout << "Fail to store Physics Table for "
|
||||
G4cout << "### Fail to store Physics Table for "
|
||||
<< part->GetParticleName()
|
||||
<< " <" << fname << "> " << G4endl;
|
||||
}
|
||||
@@ -131,20 +163,20 @@ G4bool G4EmDataHandler::StorePhysicsTable(size_t idx,
|
||||
G4bool G4EmDataHandler::RetrievePhysicsTable(size_t idx,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4String& fname,
|
||||
G4bool ascii, G4bool spline)
|
||||
G4bool ascii, G4bool spline)
|
||||
{
|
||||
G4PhysicsTable* table = Table(idx);
|
||||
G4bool yes = G4PhysicsTableHelper::RetrievePhysicsTable(table, fname, ascii, spline);
|
||||
G4EmParameters* param = G4EmParameters::Instance();
|
||||
if ( yes ) {
|
||||
if (0 < param->Verbose()) {
|
||||
G4cout << "Physics table " << idx << " for "
|
||||
G4cout << "### Physics table " << idx << " for "
|
||||
<< part->GetParticleName()
|
||||
<< " is retrieved from <" << fname << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
} else if (1 < param->Verbose()) {
|
||||
G4cout << "Fail to retrieve physics table " << idx << " for "
|
||||
G4cout << "### Fail to retrieve physics table " << idx << " for "
|
||||
<< part->GetParticleName() << " from <"
|
||||
<< fname << ">" << G4endl;
|
||||
}
|
||||
|
||||
@@ -65,10 +65,10 @@ G4EmElementSelector::G4EmElementSelector(G4VEmModel* mod,
|
||||
theElementVector = material->GetElementVector();
|
||||
if(nElmMinusOne > 0) {
|
||||
xSections.reserve(n);
|
||||
G4PhysicsLogVector* v0 = new G4PhysicsLogVector(lowEnergy,highEnergy,nbins,false);
|
||||
auto v0 = new G4PhysicsLogVector(lowEnergy,highEnergy,nbins,false);
|
||||
xSections.push_back(v0);
|
||||
for(G4int i=1; i<n; ++i) {
|
||||
G4PhysicsLogVector* v = new G4PhysicsLogVector(*v0);
|
||||
auto v = new G4PhysicsLogVector(*v0);
|
||||
xSections.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,13 +66,13 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
paiCmd->AvailableForStates(G4State_PreInit);
|
||||
paiCmd->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* part = new G4UIparameter("partName",'s',false);
|
||||
auto part = new G4UIparameter("partName",'s',false);
|
||||
paiCmd->SetParameter(part);
|
||||
|
||||
G4UIparameter* pregName = new G4UIparameter("regName",'s',false);
|
||||
auto pregName = new G4UIparameter("regName",'s',false);
|
||||
paiCmd->SetParameter(pregName);
|
||||
|
||||
G4UIparameter* ptype = new G4UIparameter("type",'s',false);
|
||||
auto ptype = new G4UIparameter("type",'s',false);
|
||||
paiCmd->SetParameter(ptype);
|
||||
ptype->SetParameterCandidates("pai PAI PAIphoton");
|
||||
|
||||
@@ -82,10 +82,10 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
mscoCmd->SetGuidance(" emType : G4EmStandard, G4EmStandard_opt1, ...");
|
||||
mscoCmd->AvailableForStates(G4State_PreInit);
|
||||
|
||||
G4UIparameter* mregName = new G4UIparameter("regName",'s',false);
|
||||
auto mregName = new G4UIparameter("regName",'s',false);
|
||||
mscoCmd->SetParameter(mregName);
|
||||
|
||||
G4UIparameter* mtype = new G4UIparameter("mscType",'s',false);
|
||||
auto mtype = new G4UIparameter("mscType",'s',false);
|
||||
mscoCmd->SetParameter(mtype);
|
||||
mtype->SetParameterCandidates("G4EmStandard G4EmStandard_opt1 G4EmStandard_opt2 G4EmStandard_opt3 G4EmStandard_opt4 G4EmStandardGS G4EmStandardSS G4EmLivermore G4EmPenelope G4RadioactiveDecay");
|
||||
|
||||
@@ -103,15 +103,15 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
StepFuncCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
StepFuncCmd->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* dRoverRPrm = new G4UIparameter("dRoverR",'d',false);
|
||||
auto dRoverRPrm = new G4UIparameter("dRoverR",'d',false);
|
||||
dRoverRPrm->SetParameterRange("dRoverR>0. && dRoverR<=1.");
|
||||
StepFuncCmd->SetParameter(dRoverRPrm);
|
||||
|
||||
G4UIparameter* finalRangePrm = new G4UIparameter("finalRange",'d',false);
|
||||
auto finalRangePrm = new G4UIparameter("finalRange",'d',false);
|
||||
finalRangePrm->SetParameterRange("finalRange>0.");
|
||||
StepFuncCmd->SetParameter(finalRangePrm);
|
||||
|
||||
G4UIparameter* unitPrm = new G4UIparameter("unit",'s',true);
|
||||
auto unitPrm = new G4UIparameter("unit",'s',true);
|
||||
unitPrm->SetDefaultUnit("mm");
|
||||
StepFuncCmd->SetParameter(unitPrm);
|
||||
|
||||
@@ -122,15 +122,15 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
StepFuncCmd1->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
StepFuncCmd1->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* dRoverRPrm1 = new G4UIparameter("dRoverRMuHad",'d',false);
|
||||
auto dRoverRPrm1 = new G4UIparameter("dRoverRMuHad",'d',false);
|
||||
dRoverRPrm1->SetParameterRange("dRoverRMuHad>0. && dRoverRMuHad<=1.");
|
||||
StepFuncCmd1->SetParameter(dRoverRPrm1);
|
||||
|
||||
G4UIparameter* finalRangePrm1 = new G4UIparameter("finalRangeMuHad",'d',false);
|
||||
auto finalRangePrm1 = new G4UIparameter("finalRangeMuHad",'d',false);
|
||||
finalRangePrm1->SetParameterRange("finalRangeMuHad>0.");
|
||||
StepFuncCmd1->SetParameter(finalRangePrm1);
|
||||
|
||||
G4UIparameter* unitPrm1 = new G4UIparameter("unit",'s',true);
|
||||
auto unitPrm1 = new G4UIparameter("unit",'s',true);
|
||||
unitPrm1->SetDefaultValue("mm");
|
||||
StepFuncCmd1->SetParameter(unitPrm1);
|
||||
|
||||
@@ -141,15 +141,15 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
StepFuncCmd2->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
StepFuncCmd2->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* dRoverRPrm2 = new G4UIparameter("dRoverRLIons",'d',false);
|
||||
auto dRoverRPrm2 = new G4UIparameter("dRoverRLIons",'d',false);
|
||||
dRoverRPrm2->SetParameterRange("dRoverRLIons>0. && dRoverRLIons<=1.");
|
||||
StepFuncCmd2->SetParameter(dRoverRPrm2);
|
||||
|
||||
G4UIparameter* finalRangePrm2 = new G4UIparameter("finalRangeLIons",'d',false);
|
||||
auto finalRangePrm2 = new G4UIparameter("finalRangeLIons",'d',false);
|
||||
finalRangePrm2->SetParameterRange("finalRangeLIons>0.");
|
||||
StepFuncCmd2->SetParameter(finalRangePrm2);
|
||||
|
||||
G4UIparameter* unitPrm2 = new G4UIparameter("unit",'s',true);
|
||||
auto unitPrm2 = new G4UIparameter("unit",'s',true);
|
||||
unitPrm2->SetDefaultValue("mm");
|
||||
StepFuncCmd2->SetParameter(unitPrm2);
|
||||
|
||||
@@ -160,15 +160,15 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
StepFuncCmd3->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
StepFuncCmd3->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* dRoverRPrm3 = new G4UIparameter("dRoverRMuHad",'d',false);
|
||||
auto dRoverRPrm3 = new G4UIparameter("dRoverRIons",'d',false);
|
||||
dRoverRPrm3->SetParameterRange("dRoverRIons>0. && dRoverRIons<=1.");
|
||||
StepFuncCmd3->SetParameter(dRoverRPrm3);
|
||||
|
||||
G4UIparameter* finalRangePrm3 = new G4UIparameter("finalRangeIons",'d',false);
|
||||
auto finalRangePrm3 = new G4UIparameter("finalRangeIons",'d',false);
|
||||
finalRangePrm3->SetParameterRange("finalRangeIons>0.");
|
||||
StepFuncCmd3->SetParameter(finalRangePrm3);
|
||||
|
||||
G4UIparameter* unitPrm3 = new G4UIparameter("unit",'s',true);
|
||||
auto unitPrm3 = new G4UIparameter("unit",'s',true);
|
||||
unitPrm3->SetDefaultValue("mm");
|
||||
StepFuncCmd3->SetParameter(unitPrm3);
|
||||
|
||||
@@ -180,13 +180,13 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
bfCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
bfCmd->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* procName = new G4UIparameter("procName",'s',false);
|
||||
auto procName = new G4UIparameter("procName",'s',false);
|
||||
bfCmd->SetParameter(procName);
|
||||
|
||||
G4UIparameter* procFact = new G4UIparameter("procFact",'d',false);
|
||||
auto procFact = new G4UIparameter("procFact",'d',false);
|
||||
bfCmd->SetParameter(procFact);
|
||||
|
||||
G4UIparameter* flagFact = new G4UIparameter("flagFact",'s',false);
|
||||
auto flagFact = new G4UIparameter("flagFact",'s',false);
|
||||
bfCmd->SetParameter(flagFact);
|
||||
|
||||
fiCmd = new G4UIcommand("/process/em/setForcedInteraction",this);
|
||||
@@ -199,21 +199,21 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
fiCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
fiCmd->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* procNam = new G4UIparameter("procNam",'s',false);
|
||||
auto procNam = new G4UIparameter("procNam",'s',false);
|
||||
fiCmd->SetParameter(procNam);
|
||||
|
||||
G4UIparameter* regNam = new G4UIparameter("regNam",'s',false);
|
||||
auto regNam = new G4UIparameter("regNam",'s',false);
|
||||
fiCmd->SetParameter(regNam);
|
||||
|
||||
G4UIparameter* tlength = new G4UIparameter("tlength",'d',false);
|
||||
auto tlength = new G4UIparameter("tlength",'d',false);
|
||||
tlength->SetParameterRange("tlength>0");
|
||||
fiCmd->SetParameter(tlength);
|
||||
|
||||
G4UIparameter* unitT = new G4UIparameter("unitT",'s',true);
|
||||
auto unitT = new G4UIparameter("unitT",'s',true);
|
||||
unitT->SetDefaultUnit("mm");
|
||||
fiCmd->SetParameter(unitT);
|
||||
|
||||
G4UIparameter* flagT = new G4UIparameter("tflag",'b',true);
|
||||
auto flagT = new G4UIparameter("tflag",'b',true);
|
||||
flagT->SetDefaultValue(true);
|
||||
fiCmd->SetParameter(flagT);
|
||||
|
||||
@@ -227,19 +227,19 @@ G4EmExtraParametersMessenger::G4EmExtraParametersMessenger(G4EmExtraParameters*
|
||||
bsCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
bsCmd->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* bProcNam = new G4UIparameter("bProcNam",'s',false);
|
||||
auto bProcNam = new G4UIparameter("bProcNam",'s',false);
|
||||
bsCmd->SetParameter(bProcNam);
|
||||
|
||||
G4UIparameter* bRegNam = new G4UIparameter("bRegNam",'s',false);
|
||||
auto bRegNam = new G4UIparameter("bRegNam",'s',false);
|
||||
bsCmd->SetParameter(bRegNam);
|
||||
|
||||
G4UIparameter* bFactor = new G4UIparameter("bFactor",'d',false);
|
||||
auto bFactor = new G4UIparameter("bFactor",'d',false);
|
||||
bsCmd->SetParameter(bFactor);
|
||||
|
||||
G4UIparameter* bEnergy = new G4UIparameter("bEnergy",'d',false);
|
||||
auto bEnergy = new G4UIparameter("bEnergy",'d',false);
|
||||
bsCmd->SetParameter(bEnergy);
|
||||
|
||||
G4UIparameter* bUnit = new G4UIparameter("bUnit",'s',true);
|
||||
auto bUnit = new G4UIparameter("bUnit",'s',true);
|
||||
bUnit->SetDefaultUnit("MeV");
|
||||
bsCmd->SetParameter(bUnit);
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ void G4EmLowEParameters::Initialise()
|
||||
|
||||
namePIXE = "Empirical";
|
||||
nameElectronPIXE = "Livermore";
|
||||
livDataDir = "livermore";
|
||||
livDataDir = "epics_2017";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
@@ -169,10 +169,10 @@ G4EmLowEParametersMessenger::G4EmLowEParametersMessenger(G4EmLowEParameters* ptr
|
||||
dnaCmd->AvailableForStates(G4State_PreInit);
|
||||
dnaCmd->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* regName = new G4UIparameter("regName",'s',false);
|
||||
auto regName = new G4UIparameter("regName",'s',false);
|
||||
dnaCmd->SetParameter(regName);
|
||||
|
||||
G4UIparameter* type = new G4UIparameter("dnaType",'s',false);
|
||||
auto type = new G4UIparameter("dnaType",'s',false);
|
||||
dnaCmd->SetParameter(type);
|
||||
type->SetParameterCandidates("DNA_Opt0 DNA_Opt2 DNA_Opt4 DNA_Opt4a DNA_Opt6 DNA_Opt6a DNA_Opt7");
|
||||
|
||||
@@ -185,16 +185,16 @@ G4EmLowEParametersMessenger::G4EmLowEParametersMessenger(G4EmLowEParameters* ptr
|
||||
deexCmd->AvailableForStates(G4State_PreInit,G4State_Init,G4State_Idle);
|
||||
deexCmd->SetToBeBroadcasted(false);
|
||||
|
||||
G4UIparameter* regNameD = new G4UIparameter("regName",'s',false);
|
||||
auto regNameD = new G4UIparameter("regName",'s',false);
|
||||
deexCmd->SetParameter(regNameD);
|
||||
|
||||
G4UIparameter* flagFluo = new G4UIparameter("flagFluo",'s',false);
|
||||
auto flagFluo = new G4UIparameter("flagFluo",'s',false);
|
||||
deexCmd->SetParameter(flagFluo);
|
||||
|
||||
G4UIparameter* flagAuger = new G4UIparameter("flagAuger",'s',false);
|
||||
auto flagAuger = new G4UIparameter("flagAuger",'s',false);
|
||||
deexCmd->SetParameter(flagAuger);
|
||||
|
||||
G4UIparameter* flagPIXE = new G4UIparameter("flagPIXE",'s',false);
|
||||
auto flagPIXE = new G4UIparameter("flagPIXE",'s',false);
|
||||
deexCmd->SetParameter(flagPIXE);
|
||||
|
||||
}
|
||||
|
||||
@@ -147,32 +147,13 @@ void G4EmModelManager::AddEmModel(G4int num, G4VEmModel* p,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::UpdateEmModel(const G4String& nam,
|
||||
G4double emin, G4double emax)
|
||||
{
|
||||
if (nEmModels > 0) {
|
||||
for(G4int i=0; i<nEmModels; ++i) {
|
||||
if(nam == models[i]->GetName()) {
|
||||
models[i]->SetLowEnergyLimit(emin);
|
||||
models[i]->SetHighEnergyLimit(emax);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
G4cout << "G4EmModelManager::UpdateEmModel WARNING: no model <"
|
||||
<< nam << "> is found out"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VEmModel* G4EmModelManager::GetModel(G4int i, G4bool ver)
|
||||
G4VEmModel* G4EmModelManager::GetModel(G4int idx, G4bool ver) const
|
||||
{
|
||||
G4VEmModel* model = nullptr;
|
||||
if(i < nEmModels) { model = models[i]; }
|
||||
if(idx >= 0 && idx < nEmModels) { model = models[idx]; }
|
||||
else if(verboseLevel > 0 && ver) {
|
||||
G4cout << "G4EmModelManager::GetModel WARNING: "
|
||||
<< "index " << i << " is wrong Nmodels= "
|
||||
<< "index " << idx << " is wrong Nmodels= "
|
||||
<< nEmModels;
|
||||
if(nullptr != particle) {
|
||||
G4cout << " for " << particle->GetParticleName();
|
||||
@@ -203,7 +184,7 @@ G4int G4EmModelManager::NumberOfRegionModels(size_t idx) const
|
||||
const G4DataVector*
|
||||
G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
const G4ParticleDefinition* secondaryParticle,
|
||||
G4double, G4int verb)
|
||||
G4int verb)
|
||||
{
|
||||
verboseLevel = verb;
|
||||
if(1 < verboseLevel) {
|
||||
@@ -267,10 +248,10 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
// or only one region
|
||||
if(nRegions > 1 && nEmModels > 1) {
|
||||
idxOfRegionModels.resize(numOfCouples,0);
|
||||
setOfRegionModels.resize((size_t)nRegions,0);
|
||||
setOfRegionModels.resize((size_t)nRegions,nullptr);
|
||||
} else {
|
||||
idxOfRegionModels.resize(1,0);
|
||||
setOfRegionModels.resize(1,0);
|
||||
setOfRegionModels.resize(1,nullptr);
|
||||
}
|
||||
|
||||
std::vector<G4int> modelAtRegion(nEmModels);
|
||||
@@ -469,7 +450,7 @@ G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
for(G4int iii=0; iii<=n; ++iii) {G4cout << eLow[iii]/MeV << " ";}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow, region);
|
||||
auto rm = new G4RegionModels(n, modelAtRegion, eLow, region);
|
||||
setOfRegionModels[reg] = rm;
|
||||
// shortcut
|
||||
if(1 == nEmModels) { break; }
|
||||
@@ -758,7 +739,7 @@ void G4EmModelManager::DumpModelList(std::ostream& out, G4int verb)
|
||||
out << " Fluo";
|
||||
}
|
||||
out << G4endl;
|
||||
G4VMscModel* msc = dynamic_cast<G4VMscModel*>(model);
|
||||
auto msc = dynamic_cast<G4VMscModel*>(model);
|
||||
if(msc != nullptr) msc->DumpParameters(out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,8 +59,7 @@ G4EmMultiModel::G4EmMultiModel(const G4String& nam)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmMultiModel::~G4EmMultiModel()
|
||||
{}
|
||||
G4EmMultiModel::~G4EmMultiModel() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -55,28 +55,27 @@
|
||||
#include "G4Region.hh"
|
||||
#include "G4ApplicationState.hh"
|
||||
#include "G4StateManager.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
G4EmParameters* G4EmParameters::theInstance = nullptr;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4Mutex G4EmParameters::emParametersMutex = G4MUTEX_INITIALIZER;
|
||||
#endif
|
||||
namespace
|
||||
{
|
||||
G4Mutex emParametersMutex = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4EmParameters* G4EmParameters::Instance()
|
||||
{
|
||||
if(nullptr == theInstance) {
|
||||
#ifdef G4MULTITHREADED
|
||||
G4MUTEXLOCK(&emParametersMutex);
|
||||
G4AutoLock l(&emParametersMutex);
|
||||
if(nullptr == theInstance) {
|
||||
#endif
|
||||
static G4EmParameters manager;
|
||||
theInstance = &manager;
|
||||
#ifdef G4MULTITHREADED
|
||||
}
|
||||
G4MUTEXUNLOCK(&emParametersMutex);
|
||||
#endif
|
||||
l.unlock();
|
||||
}
|
||||
return theInstance;
|
||||
}
|
||||
@@ -165,10 +164,12 @@ void G4EmParameters::Initialise()
|
||||
workerVerbose = 0;
|
||||
tripletConv = 0;
|
||||
|
||||
fTransportationWithMsc = G4TransportationWithMscType::fDisabled;
|
||||
mscStepLimit = fUseSafety;
|
||||
mscStepLimitMuHad = fMinimal;
|
||||
nucFormfactor = fExponentialNF;
|
||||
fSStype = fWVI;
|
||||
fFluct = fUniversalFluctuation;
|
||||
}
|
||||
|
||||
void G4EmParameters::SetLossFluctuations(G4bool val)
|
||||
@@ -952,6 +953,28 @@ G4int G4EmParameters::WorkerVerbose() const
|
||||
return workerVerbose;
|
||||
}
|
||||
|
||||
void G4EmParameters::SetTransportationWithMsc(G4TransportationWithMscType val)
|
||||
{
|
||||
if(IsLocked()) { return; }
|
||||
fTransportationWithMsc = val;
|
||||
}
|
||||
|
||||
G4TransportationWithMscType G4EmParameters::TransportationWithMsc() const
|
||||
{
|
||||
return fTransportationWithMsc;
|
||||
}
|
||||
|
||||
void G4EmParameters::SetFluctuationType(G4EmFluctuationType val)
|
||||
{
|
||||
if(IsLocked()) { return; }
|
||||
fFluct = val;
|
||||
}
|
||||
|
||||
G4EmFluctuationType G4EmParameters::FluctuationType() const
|
||||
{
|
||||
return fFluct;
|
||||
}
|
||||
|
||||
void G4EmParameters::SetMscStepLimitType(G4MscStepLimitType val)
|
||||
{
|
||||
if(IsLocked()) { return; }
|
||||
@@ -1234,6 +1257,13 @@ void G4EmParameters::StreamInfo(std::ostream& os) const
|
||||
os << "LPM effect enabled " <<flagLPM << "\n";
|
||||
os << "Enable creation and use of sampling tables " <<fSamplingTable << "\n";
|
||||
os << "Apply cuts on all EM processes " <<applyCuts << "\n";
|
||||
const char* transportationWithMsc = "Disabled";
|
||||
if(fTransportationWithMsc == G4TransportationWithMscType::fEnabled) {
|
||||
transportationWithMsc = "Enabled";
|
||||
} else if (fTransportationWithMsc == G4TransportationWithMscType::fMultipleSteps) {
|
||||
transportationWithMsc = "MultipleSteps";
|
||||
}
|
||||
os << "Use combined TransportationWithMsc " <<transportationWithMsc << "\n";
|
||||
os << "Use general process " <<gener << "\n";
|
||||
os << "Enable linear polarisation for gamma " <<fPolarisation << "\n";
|
||||
os << "Enable sampling of quantum entanglement "
|
||||
@@ -1283,8 +1313,9 @@ void G4EmParameters::StreamInfo(std::ostream& os) const
|
||||
<<G4BestUnit(lowestElectronEnergy,"Energy") << "\n";
|
||||
os << "Lowest muon/hadron kinetic energy "
|
||||
<<G4BestUnit(lowestMuHadEnergy,"Energy") << "\n";
|
||||
os << "Fluctuations of dE/dx are enabled " <<lossFluctuation << "\n";
|
||||
os << "Use ICRU90 data " << fICRU90 << "\n";
|
||||
os << "Fluctuations of dE/dx are enabled " <<lossFluctuation << "\n";
|
||||
os << "Type of fluctuation model " << fFluct << "\n";
|
||||
os << "Use built-in Birks satuaration " << birks << "\n";
|
||||
os << "Build CSDA range enabled " <<buildCSDARange << "\n";
|
||||
os << "Use cut as a final range enabled " <<cutAsFinalRange << "\n";
|
||||
|
||||
@@ -61,15 +61,15 @@
|
||||
G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
|
||||
: theParameters(ptr)
|
||||
{
|
||||
gconvDirectory = new G4UIdirectory("/process/gconv/");
|
||||
gconvDirectory->SetGuidance("Commands for EM gamma conversion BH5D model.");
|
||||
eLossDirectory = new G4UIdirectory("/process/eLoss/");
|
||||
eLossDirectory->SetGuidance("Commands for EM processes.");
|
||||
mscDirectory = new G4UIdirectory("/process/msc/");
|
||||
mscDirectory->SetGuidance("Commands for EM scattering processes.");
|
||||
emDirectory = new G4UIdirectory("/process/em/");
|
||||
emDirectory = new G4UIdirectory("/process/em/", false);
|
||||
emDirectory->SetGuidance("General commands for EM processes.");
|
||||
dnaDirectory = new G4UIdirectory("/process/dna/");
|
||||
eLossDirectory = new G4UIdirectory("/process/eLoss/", false);
|
||||
eLossDirectory->SetGuidance("Commands for energy loss processes.");
|
||||
mscDirectory = new G4UIdirectory("/process/msc/", false);
|
||||
mscDirectory->SetGuidance("Commands for EM scattering processes.");
|
||||
gconvDirectory = new G4UIdirectory("/process/gconv/", false);
|
||||
gconvDirectory->SetGuidance("Commands for EM gamma conversion BH5D model.");
|
||||
dnaDirectory = new G4UIdirectory("/process/dna/", false);
|
||||
dnaDirectory->SetGuidance("Commands for DNA processes.");
|
||||
|
||||
flucCmd = new G4UIcmdWithABool("/process/eLoss/fluct",this);
|
||||
@@ -107,6 +107,13 @@ G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
|
||||
aplCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
aplCmd->SetToBeBroadcasted(false);
|
||||
|
||||
intCmd = new G4UIcmdWithABool("/process/em/integral",this);
|
||||
intCmd->SetGuidance("Enable/disable integral method.");
|
||||
intCmd->SetParameterName("choice",true);
|
||||
intCmd->SetDefaultValue(true);
|
||||
intCmd->AvailableForStates(G4State_PreInit);
|
||||
intCmd->SetToBeBroadcasted(false);
|
||||
|
||||
latCmd = new G4UIcmdWithABool("/process/msc/LateralDisplacement",this);
|
||||
latCmd->SetGuidance("Enable/disable sampling of lateral displacement");
|
||||
latCmd->SetParameterName("lat",true);
|
||||
@@ -142,7 +149,7 @@ G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
|
||||
mottCmd->AvailableForStates(G4State_PreInit);
|
||||
mottCmd->SetToBeBroadcasted(false);
|
||||
|
||||
birksCmd = new G4UIcmdWithABool("/process/msc/UseG4EmSaturation",this);
|
||||
birksCmd = new G4UIcmdWithABool("/process/em/UseG4EmSaturation",this);
|
||||
birksCmd->SetGuidance("Enable usage of built-in Birks saturation");
|
||||
birksCmd->SetParameterName("birks",true);
|
||||
birksCmd->SetDefaultValue(false);
|
||||
@@ -363,6 +370,13 @@ G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
|
||||
ver2Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
ver2Cmd->SetToBeBroadcasted(false);
|
||||
|
||||
transWithMscCmd = new G4UIcmdWithAString("/process/em/transportationWithMsc",this);
|
||||
transWithMscCmd->SetGuidance("Enable/disable the G4TransportationWithMsc process");
|
||||
transWithMscCmd->SetParameterName("trans",true);
|
||||
transWithMscCmd->SetCandidates("Disabled Enabled MultipleSteps");
|
||||
transWithMscCmd->AvailableForStates(G4State_PreInit);
|
||||
transWithMscCmd->SetToBeBroadcasted(false);
|
||||
|
||||
mscCmd = new G4UIcmdWithAString("/process/msc/StepLimit",this);
|
||||
mscCmd->SetGuidance("Set msc step limitation type");
|
||||
mscCmd->SetParameterName("StepLim",true);
|
||||
@@ -396,6 +410,13 @@ G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
|
||||
ssCmd->AvailableForStates(G4State_PreInit);
|
||||
ssCmd->SetToBeBroadcasted(false);
|
||||
|
||||
fluc1Cmd = new G4UIcmdWithAString("/process/eloss/setFluctModel",this);
|
||||
fluc1Cmd->SetGuidance("Define type of energy loss fluctuation model");
|
||||
fluc1Cmd->SetParameterName("Fluc1",true);
|
||||
fluc1Cmd->SetCandidates("Dummy Universal Urban");
|
||||
fluc1Cmd->AvailableForStates(G4State_PreInit);
|
||||
fluc1Cmd->SetToBeBroadcasted(false);
|
||||
|
||||
tripletCmd = new G4UIcmdWithAnInteger("/process/gconv/conversionType",this);
|
||||
tripletCmd->SetGuidance("gamma conversion triplet/nuclear generation type:");
|
||||
tripletCmd->SetGuidance("0 - (default) both triplet and nuclear");
|
||||
@@ -432,6 +453,7 @@ G4EmParametersMessenger::~G4EmParametersMessenger()
|
||||
delete lpmCmd;
|
||||
delete rsCmd;
|
||||
delete aplCmd;
|
||||
delete intCmd;
|
||||
delete latCmd;
|
||||
delete lat96Cmd;
|
||||
delete mulatCmd;
|
||||
@@ -472,12 +494,14 @@ G4EmParametersMessenger::~G4EmParametersMessenger()
|
||||
delete verCmd;
|
||||
delete ver1Cmd;
|
||||
delete ver2Cmd;
|
||||
delete transWithMscCmd;
|
||||
delete tripletCmd;
|
||||
|
||||
delete mscCmd;
|
||||
delete msc1Cmd;
|
||||
delete nffCmd;
|
||||
delete ssCmd;
|
||||
delete fluc1Cmd;
|
||||
|
||||
delete dumpCmd;
|
||||
}
|
||||
@@ -502,6 +526,8 @@ void G4EmParametersMessenger::SetNewValue(G4UIcommand* command,
|
||||
} else if (command == aplCmd) {
|
||||
theParameters->SetApplyCuts(aplCmd->GetNewBoolValue(newValue));
|
||||
physicsModified = true;
|
||||
} else if (command == intCmd) {
|
||||
theParameters->SetIntegral(intCmd->GetNewBoolValue(newValue));
|
||||
} else if (command == latCmd) {
|
||||
theParameters->SetLateralDisplacement(latCmd->GetNewBoolValue(newValue));
|
||||
physicsModified = true;
|
||||
@@ -593,6 +619,20 @@ void G4EmParametersMessenger::SetNewValue(G4UIcommand* command,
|
||||
} else if (command == dumpCmd) {
|
||||
theParameters->SetIsPrintedFlag(false);
|
||||
theParameters->Dump();
|
||||
} else if (command == transWithMscCmd) {
|
||||
G4TransportationWithMscType type = G4TransportationWithMscType::fDisabled;
|
||||
if(newValue == "Disabled") {
|
||||
type = G4TransportationWithMscType::fDisabled;
|
||||
} else if(newValue == "Enabled") {
|
||||
type = G4TransportationWithMscType::fEnabled;
|
||||
} else if(newValue == "MultipleSteps") {
|
||||
type = G4TransportationWithMscType::fMultipleSteps;
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << " TransportationWithMsc type <" << newValue << "> unknown!";
|
||||
G4Exception("G4EmParametersMessenger", "em0044", JustWarning, ed);
|
||||
}
|
||||
theParameters->SetTransportationWithMsc(type);
|
||||
} else if (command == mscCmd || command == msc1Cmd) {
|
||||
G4MscStepLimitType msctype = fUseSafety;
|
||||
if(newValue == "Minimal") {
|
||||
@@ -638,6 +678,11 @@ void G4EmParametersMessenger::SetNewValue(G4UIcommand* command,
|
||||
return;
|
||||
}
|
||||
theParameters->SetSingleScatteringType(x);
|
||||
} else if (command == fluc1Cmd) {
|
||||
G4EmFluctuationType x = fUniversalFluctuation;
|
||||
if(newValue == "Dummy") { x = fDummyFluctuation; }
|
||||
else if(newValue == "Urban") { x = fUrbanFluctuation; }
|
||||
theParameters->SetFluctuationType(x);
|
||||
} else if ( command==tripletCmd ) {
|
||||
theParameters->SetConversionType(tripletCmd->GetNewIntValue(newValue));
|
||||
} else if ( command==onIsolatedCmd ) {
|
||||
|
||||
@@ -72,8 +72,7 @@ G4EmSaturation::G4EmSaturation(G4int verb)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmSaturation::~G4EmSaturation()
|
||||
{}
|
||||
G4EmSaturation::~G4EmSaturation() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -0,0 +1,695 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Geant4 class G4EmTableUtil
|
||||
//
|
||||
// Author V.Ivanchenko 14.03.2022
|
||||
//
|
||||
|
||||
#include "G4EmTableUtil.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4EmUtility.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4EmTableType.hh"
|
||||
#include "G4PhysicsModelCatalog.hh"
|
||||
#include "G4LowEnergyEmProcessSubType.hh"
|
||||
#include "G4PhysicsTableHelper.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include <iostream>
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
const G4DataVector*
|
||||
G4EmTableUtil::PrepareEmProcess(G4VEmProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition* secPart,
|
||||
G4EmModelManager* modelManager,
|
||||
const G4double& maxKinEnergy,
|
||||
G4int& secID, G4int& tripletID,
|
||||
G4int& mainSec, const G4int& verb,
|
||||
const G4bool& master)
|
||||
{
|
||||
G4EmParameters* param = G4EmParameters::Instance();
|
||||
|
||||
// initialisation of models
|
||||
G4double plimit = param->MscThetaLimit();
|
||||
G4int nModels = modelManager->NumberOfModels();
|
||||
for(G4int i=0; i<nModels; ++i) {
|
||||
G4VEmModel* mod = modelManager->GetModel(i);
|
||||
if(nullptr == mod) { continue; }
|
||||
mod->SetPolarAngleLimit(plimit);
|
||||
mod->SetMasterThread(master);
|
||||
if(mod->HighEnergyLimit() > maxKinEnergy) {
|
||||
mod->SetHighEnergyLimit(maxKinEnergy);
|
||||
}
|
||||
proc->SetEmModel(mod);
|
||||
}
|
||||
|
||||
// defined ID of secondary particles and verbosity
|
||||
G4int stype = proc->GetProcessSubType();
|
||||
if(stype == fAnnihilation) {
|
||||
secID = _Annihilation;
|
||||
tripletID = _TripletGamma;
|
||||
} else if(stype == fGammaConversion) {
|
||||
secID = _PairProduction;
|
||||
mainSec = 2;
|
||||
} else if(stype == fPhotoElectricEffect) {
|
||||
secID = _PhotoElectron;
|
||||
} else if(stype == fComptonScattering) {
|
||||
secID = _ComptonElectron;
|
||||
} else if(stype >= fLowEnergyElastic) {
|
||||
secID = fDNAUnknownModel;
|
||||
}
|
||||
if(master) {
|
||||
proc->SetVerboseLevel(param->Verbose());
|
||||
} else {
|
||||
proc->SetVerboseLevel(param->WorkerVerbose());
|
||||
}
|
||||
|
||||
// model initialisation
|
||||
const G4DataVector* cuts = modelManager->Initialise(part, secPart, verb);
|
||||
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VEmProcess::PreparePhysicsTable() done for "
|
||||
<< proc->GetProcessName()
|
||||
<< " and particle " << part->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
return cuts;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4EmTableUtil::BuildEmProcess(G4VEmProcess* proc,
|
||||
const G4VEmProcess* masterProc,
|
||||
const G4ParticleDefinition* firstPart,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4int nModels, const G4int verb,
|
||||
const G4bool master, const G4bool isLocked,
|
||||
const G4bool toBuild, G4bool& baseMat)
|
||||
{
|
||||
G4String num = part->GetParticleName();
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VEmProcess::BuildPhysicsTable() for "
|
||||
<< proc->GetProcessName() << " and particle " << num
|
||||
<< " buildLambdaTable=" << toBuild << " master= " << master
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(firstPart == part) {
|
||||
|
||||
// worker initialisation
|
||||
if(!master) {
|
||||
proc->SetLambdaTable(masterProc->LambdaTable());
|
||||
proc->SetLambdaTablePrim(masterProc->LambdaTablePrim());
|
||||
proc->SetCrossSectionType(masterProc->CrossSectionType());
|
||||
proc->SetEnergyOfCrossSectionMax(masterProc->EnergyOfCrossSectionMax());
|
||||
|
||||
// local initialisation of models
|
||||
baseMat = masterProc->UseBaseMaterial();
|
||||
G4bool printing = true;
|
||||
for(G4int i=0; i<nModels; ++i) {
|
||||
G4VEmModel* mod = proc->GetModelByIndex(i, printing);
|
||||
G4VEmModel* mod0= masterProc->GetModelByIndex(i, printing);
|
||||
mod->SetUseBaseMaterials(baseMat);
|
||||
mod->InitialiseLocal(part, mod0);
|
||||
}
|
||||
// master thread
|
||||
} else {
|
||||
if(toBuild) { proc->BuildLambdaTable(); }
|
||||
auto fXSType = proc->CrossSectionType();
|
||||
auto v = proc->EnergyOfCrossSectionMax();
|
||||
delete v;
|
||||
v = nullptr;
|
||||
if(fXSType == fEmOnePeak) {
|
||||
auto table = proc->LambdaTable();
|
||||
if(nullptr == table) {
|
||||
v = G4EmUtility::FindCrossSectionMax(proc, part);
|
||||
} else {
|
||||
v = G4EmUtility::FindCrossSectionMax(table);
|
||||
}
|
||||
if(nullptr == v) { proc->SetCrossSectionType(fEmIncreasing); }
|
||||
}
|
||||
proc->SetEnergyOfCrossSectionMax(v);
|
||||
}
|
||||
}
|
||||
// protection against double printout
|
||||
if(isLocked) { return; }
|
||||
|
||||
// explicitly defined printout by particle name
|
||||
if(1 < verb || (0 < verb && (num == "gamma" || num == "e-" ||
|
||||
num == "e+" || num == "mu+" ||
|
||||
num == "mu-" || num == "proton"||
|
||||
num == "pi+" || num == "pi-" ||
|
||||
num == "kaon+" || num == "kaon-" ||
|
||||
num == "alpha" || num == "anti_proton" ||
|
||||
num == "GenericIon" ||
|
||||
num == "alpha+" || num == "helium" ||
|
||||
num == "hydrogen"))) {
|
||||
proc->StreamInfo(G4cout, *part);
|
||||
}
|
||||
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VEmProcess::BuildPhysicsTable() done for "
|
||||
<< proc->GetProcessName() << " and particle " << num
|
||||
<< " baseMat=" << baseMat << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4EmTableUtil::BuildLambdaTable(G4VEmProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
G4EmModelManager* modelManager,
|
||||
G4LossTableBuilder* bld,
|
||||
G4PhysicsTable* theLambdaTable,
|
||||
G4PhysicsTable* theLambdaTablePrim,
|
||||
const G4double minKinEnergy,
|
||||
const G4double minKinEnergyPrim,
|
||||
const G4double maxKinEnergy,
|
||||
const G4double scale,
|
||||
const G4int verboseLevel,
|
||||
const G4bool startFromNull,
|
||||
const G4bool splineFlag)
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmProcess::BuildLambdaTable() for process "
|
||||
<< proc->GetProcessName() << " and particle "
|
||||
<< part->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
// Access to materials
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
G4PhysicsLogVector* aVector = nullptr;
|
||||
G4PhysicsLogVector* aVectorPrim = nullptr;
|
||||
G4PhysicsLogVector* bVectorPrim = nullptr;
|
||||
|
||||
G4double emax1 = std::min(maxKinEnergy, minKinEnergyPrim);
|
||||
|
||||
for(size_t i=0; i<numOfCouples; ++i) {
|
||||
|
||||
if (bld->GetFlag(i)) {
|
||||
// create physics vector and fill it
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
|
||||
// build main table
|
||||
if(nullptr != theLambdaTable) {
|
||||
delete (*theLambdaTable)[i];
|
||||
|
||||
// if start from zero then change the scale
|
||||
G4double emin = minKinEnergy;
|
||||
G4bool startNull = false;
|
||||
if(startFromNull) {
|
||||
G4double e = proc->MinPrimaryEnergy(part, couple->GetMaterial());
|
||||
if(e >= emin) {
|
||||
emin = e;
|
||||
startNull = true;
|
||||
}
|
||||
}
|
||||
G4double emax = emax1;
|
||||
if(emax <= emin) { emax = 2*emin; }
|
||||
G4int bin = G4lrint(scale*G4Log(emax/emin));
|
||||
bin = std::max(bin, 5);
|
||||
aVector = new G4PhysicsLogVector(emin, emax, bin, splineFlag);
|
||||
modelManager->FillLambdaVector(aVector, couple, startNull);
|
||||
if(splineFlag) { aVector->FillSecondDerivatives(); }
|
||||
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
|
||||
}
|
||||
// build high energy table
|
||||
if(nullptr != theLambdaTablePrim) {
|
||||
delete (*theLambdaTablePrim)[i];
|
||||
|
||||
// start not from zero and always use spline
|
||||
if(nullptr == bVectorPrim) {
|
||||
G4int bin = G4lrint(scale*G4Log(maxKinEnergy/minKinEnergyPrim));
|
||||
bin = std::max(bin, 5);
|
||||
aVectorPrim =
|
||||
new G4PhysicsLogVector(minKinEnergyPrim, maxKinEnergy, bin, true);
|
||||
bVectorPrim = aVectorPrim;
|
||||
} else {
|
||||
aVectorPrim = new G4PhysicsLogVector(*bVectorPrim);
|
||||
}
|
||||
modelManager->FillLambdaVector(aVectorPrim, couple, false,
|
||||
fIsCrossSectionPrim);
|
||||
aVectorPrim->FillSecondDerivatives();
|
||||
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTablePrim, i,
|
||||
aVectorPrim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Lambda table is built for " << part->GetParticleName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4EmTableUtil::BuildLambdaTable(G4VEnergyLossProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
G4EmModelManager* modelManager,
|
||||
G4LossTableBuilder* bld,
|
||||
G4PhysicsTable* theLambdaTable,
|
||||
const G4DataVector* theCuts,
|
||||
const G4double minKinEnergy,
|
||||
const G4double maxKinEnergy,
|
||||
const G4double scale,
|
||||
const G4int verboseLevel,
|
||||
const G4bool splineFlag)
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EnergyLossProcess::BuildLambdaTable() for process "
|
||||
<< proc->GetProcessName() << " and particle "
|
||||
<< part->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
G4PhysicsLogVector* aVector = nullptr;
|
||||
for(size_t i=0; i<numOfCouples; ++i) {
|
||||
if (bld->GetFlag(i)) {
|
||||
// create physics vector and fill it
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
|
||||
delete (*theLambdaTable)[i];
|
||||
G4bool startNull = true;
|
||||
G4double emin =
|
||||
proc->MinPrimaryEnergy(part, couple->GetMaterial(), (*theCuts)[i]);
|
||||
if(minKinEnergy > emin) {
|
||||
emin = minKinEnergy;
|
||||
startNull = false;
|
||||
}
|
||||
|
||||
G4double emax = maxKinEnergy;
|
||||
if(emax <= emin) { emax = 2*emin; }
|
||||
G4int bin = G4lrint(scale*G4Log(emax/emin));
|
||||
bin = std::max(bin, 5);
|
||||
aVector = new G4PhysicsLogVector(emin, emax, bin, splineFlag);
|
||||
modelManager->FillLambdaVector(aVector, couple, startNull, fRestricted);
|
||||
if(splineFlag) { aVector->FillSecondDerivatives(); }
|
||||
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
|
||||
}
|
||||
}
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Lambda table is built for " << part->GetParticleName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
const G4ParticleDefinition*
|
||||
G4EmTableUtil::CheckIon(G4VEnergyLossProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition* partLocal,
|
||||
const G4int verb, G4bool& isIon)
|
||||
{
|
||||
if(1 < verb) {
|
||||
G4cout << "G4VEnergyLossProcess::PreparePhysicsTable for "
|
||||
<< proc->GetProcessName() << " for " << part->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
const G4ParticleDefinition* particle = partLocal;
|
||||
|
||||
// Are particle defined?
|
||||
if(nullptr == particle) { particle = part; }
|
||||
if(part->GetParticleType() == "nucleus") {
|
||||
G4String pname = part->GetParticleName();
|
||||
if(pname != "deuteron" && pname != "triton" &&
|
||||
pname != "alpha+" && pname != "alpha") {
|
||||
|
||||
const G4ParticleDefinition* theGIon = G4GenericIon::GenericIon();
|
||||
isIon = true;
|
||||
|
||||
if(particle != theGIon) {
|
||||
G4ProcessManager* pm = theGIon->GetProcessManager();
|
||||
G4ProcessVector* v = pm->GetAlongStepProcessVector();
|
||||
size_t n = v->size();
|
||||
for(size_t j=0; j<n; ++j) {
|
||||
if((*v)[j] == proc) {
|
||||
particle = theGIon;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return particle;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4EmTableUtil::UpdateModels(G4VEnergyLossProcess* proc,
|
||||
G4EmModelManager* modelManager,
|
||||
const G4double maxKinEnergy,
|
||||
const G4int nModels,
|
||||
G4int& secID, G4int& biasID,
|
||||
G4int& mainSec, const G4bool baseMat,
|
||||
const G4bool isMaster, const G4bool useAGen)
|
||||
{
|
||||
// defined ID of secondary particles
|
||||
G4int stype = proc->GetProcessSubType();
|
||||
if(stype == fBremsstrahlung) {
|
||||
secID = _Bremsstrahlung;
|
||||
biasID = _SplitBremsstrahlung;
|
||||
} else if(stype == fPairProdByCharged) {
|
||||
secID = _PairProduction;
|
||||
mainSec = 2;
|
||||
}
|
||||
|
||||
// initialisation of models
|
||||
for(G4int i=0; i<nModels; ++i) {
|
||||
G4VEmModel* mod = modelManager->GetModel(i);
|
||||
mod->SetMasterThread(isMaster);
|
||||
mod->SetAngularGeneratorFlag(useAGen);
|
||||
if(mod->HighEnergyLimit() > maxKinEnergy) {
|
||||
mod->SetHighEnergyLimit(maxKinEnergy);
|
||||
}
|
||||
mod->SetUseBaseMaterials(baseMat);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void
|
||||
G4EmTableUtil::BuildLocalElossProcess(G4VEnergyLossProcess* proc,
|
||||
const G4VEnergyLossProcess* masterProc,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4int nModels)
|
||||
{
|
||||
// copy table pointers from master thread
|
||||
proc->SetDEDXTable(masterProc->DEDXTable(),fRestricted);
|
||||
proc->SetDEDXTable(masterProc->DEDXunRestrictedTable(),fTotal);
|
||||
proc->SetDEDXTable(masterProc->IonisationTable(),fIsIonisation);
|
||||
proc->SetRangeTableForLoss(masterProc->RangeTableForLoss());
|
||||
proc->SetCSDARangeTable(masterProc->CSDARangeTable());
|
||||
proc->SetInverseRangeTable(masterProc->InverseRangeTable());
|
||||
proc->SetLambdaTable(masterProc->LambdaTable());
|
||||
proc->SetCrossSectionType(masterProc->CrossSectionType());
|
||||
proc->SetEnergyOfCrossSectionMax(masterProc->EnergyOfCrossSectionMax());
|
||||
proc->SetTwoPeaksXS(masterProc->TwoPeaksXS());
|
||||
proc->SetIonisation(masterProc->IsIonisationProcess());
|
||||
G4bool baseMat = masterProc->UseBaseMaterial();
|
||||
|
||||
// local initialisation of models
|
||||
G4bool printing = true;
|
||||
for(G4int i=0; i<nModels; ++i) {
|
||||
G4VEmModel* mod = proc->GetModelByIndex(i, printing);
|
||||
G4VEmModel* mod0= masterProc->GetModelByIndex(i, printing);
|
||||
mod->SetUseBaseMaterials(baseMat);
|
||||
mod->InitialiseLocal(part, mod0);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4EmTableUtil::BuildDEDXTable(G4VEnergyLossProcess* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
G4EmModelManager* modelManager,
|
||||
G4LossTableBuilder* bld,
|
||||
G4PhysicsTable* table,
|
||||
const G4double emin,
|
||||
const G4double emax,
|
||||
const G4int nbins,
|
||||
const G4int verbose,
|
||||
const G4EmTableType tType,
|
||||
const G4bool spline)
|
||||
{
|
||||
// Access to materials
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << numOfCouples << " couples" << " minKinEnergy(MeV)= " << emin
|
||||
<< " maxKinEnergy(MeV)= " << emax << " nbins= " << nbins << G4endl;
|
||||
}
|
||||
G4PhysicsLogVector* aVector = nullptr;
|
||||
G4PhysicsLogVector* bVector = nullptr;
|
||||
|
||||
for(size_t i=0; i<numOfCouples; ++i) {
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4VEnergyLossProcess::BuildDEDXVector idx= " << i
|
||||
<< " flagTable=" << table->GetFlag(i)
|
||||
<< " flagBuilder=" << bld->GetFlag(i) << G4endl;
|
||||
}
|
||||
if(bld->GetFlag(i)) {
|
||||
|
||||
// create physics vector and fill it
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
delete (*table)[i];
|
||||
if(nullptr != bVector) {
|
||||
aVector = new G4PhysicsLogVector(*bVector);
|
||||
} else {
|
||||
bVector = new G4PhysicsLogVector(emin, emax, nbins, spline);
|
||||
aVector = bVector;
|
||||
}
|
||||
|
||||
modelManager->FillDEDXVector(aVector, couple, tType);
|
||||
if(spline) { aVector->FillSecondDerivatives(); }
|
||||
|
||||
// Insert vector for this material into the table
|
||||
G4PhysicsTableHelper::SetPhysicsVector(table, i, aVector);
|
||||
}
|
||||
}
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4VEnergyLossProcess::BuildDEDXTable(): table is built for "
|
||||
<< part->GetParticleName()
|
||||
<< " and process " << proc->GetProcessName()
|
||||
<< G4endl;
|
||||
if(2 < verbose) G4cout << (*table) << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4EmTableUtil::PrepareMscProcess(G4VMultipleScattering* proc,
|
||||
const G4ParticleDefinition& part,
|
||||
G4EmModelManager* modelManager,
|
||||
G4MscStepLimitType& stepLimit,
|
||||
G4double& facrange,
|
||||
G4bool& latDisplacement, G4bool& master,
|
||||
G4bool& isIon, G4bool& baseMat)
|
||||
{
|
||||
auto param = G4EmParameters::Instance();
|
||||
G4int verb = (master) ? param->Verbose() : param->WorkerVerbose();
|
||||
proc->SetVerboseLevel(verb);
|
||||
|
||||
if(part.GetPDGMass() > CLHEP::GeV ||
|
||||
part.GetParticleName() == "GenericIon") { isIon = true; }
|
||||
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
|
||||
<< proc->GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< " isIon: " << isIon << " isMaster: " << master
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// initialise process
|
||||
proc->InitialiseProcess(&part);
|
||||
|
||||
// heavy particles
|
||||
if(part.GetPDGMass() > CLHEP::MeV) {
|
||||
stepLimit = param->MscMuHadStepLimitType();
|
||||
facrange = param->MscMuHadRangeFactor();
|
||||
latDisplacement = param->MuHadLateralDisplacement();
|
||||
} else {
|
||||
stepLimit = param->MscStepLimitType();
|
||||
facrange = param->MscRangeFactor();
|
||||
latDisplacement = param->LateralDisplacement();
|
||||
}
|
||||
|
||||
// initialisation of models
|
||||
auto numberOfModels = modelManager->NumberOfModels();
|
||||
for(G4int i=0; i<numberOfModels; ++i) {
|
||||
G4VMscModel* msc = proc->GetModelByIndex(i);
|
||||
msc->SetIonisation(nullptr, &part);
|
||||
msc->SetMasterThread(master);
|
||||
msc->SetPolarAngleLimit(param->MscThetaLimit());
|
||||
G4double emax = std::min(msc->HighEnergyLimit(),param->MaxKinEnergy());
|
||||
msc->SetHighEnergyLimit(emax);
|
||||
msc->SetUseBaseMaterials(baseMat);
|
||||
}
|
||||
modelManager->Initialise(&part, nullptr, verb);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4EmTableUtil::BuildMscProcess(G4VMultipleScattering* proc,
|
||||
const G4VMultipleScattering* masterProc,
|
||||
const G4ParticleDefinition& part,
|
||||
const G4ParticleDefinition* firstPart,
|
||||
G4int nModels, G4bool master)
|
||||
{
|
||||
auto param = G4EmParameters::Instance();
|
||||
G4int verb = param->Verbose();
|
||||
|
||||
if(!master && firstPart == &part) {
|
||||
// initialisation of models
|
||||
G4bool baseMat = masterProc->UseBaseMaterial();
|
||||
for(G4int i=0; i<nModels; ++i) {
|
||||
G4VMscModel* msc = proc->GetModelByIndex(i);
|
||||
G4VMscModel* msc0 = masterProc->GetModelByIndex(i);
|
||||
msc->SetUseBaseMaterials(baseMat);
|
||||
msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false);
|
||||
msc->InitialiseLocal(&part, msc0);
|
||||
}
|
||||
}
|
||||
if(!param->IsPrintLocked()) {
|
||||
const G4String& num = part.GetParticleName();
|
||||
|
||||
// explicitly defined printout by particle name
|
||||
if(1 < verb || (0 < verb && (num == "e-" ||
|
||||
num == "e+" || num == "mu+" ||
|
||||
num == "mu-" || num == "proton"||
|
||||
num == "pi+" || num == "pi-" ||
|
||||
num == "kaon+" || num == "kaon-" ||
|
||||
num == "alpha" || num == "anti_proton" ||
|
||||
num == "GenericIon" || num == "alpha+" ||
|
||||
num == "alpha" ))) {
|
||||
proc->StreamInfo(G4cout, part);
|
||||
}
|
||||
}
|
||||
if(1 < verb) {
|
||||
G4cout << "### G4VMultipleScattering::BuildPhysicsTable() done for "
|
||||
<< proc->GetProcessName()
|
||||
<< " and particle " << part.GetParticleName() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4EmTableUtil::StoreMscTable(G4VMultipleScattering* proc,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4String& dir,
|
||||
const G4int nModels, const G4int verb,
|
||||
const G4bool ascii)
|
||||
{
|
||||
G4bool ok = true;
|
||||
for(G4int i=0; i<nModels; ++i) {
|
||||
G4VMscModel* msc = proc->GetModelByIndex(i);
|
||||
G4PhysicsTable* table = msc->GetCrossSectionTable();
|
||||
if (nullptr != table) {
|
||||
G4String ss = G4UIcommand::ConvertToString(i);
|
||||
G4String name =
|
||||
proc->GetPhysicsTableFileName(part, dir, "LambdaMod"+ss, ascii);
|
||||
G4bool yes = table->StorePhysicsTable(name,ascii);
|
||||
|
||||
if ( yes ) {
|
||||
if ( verb > 0 ) {
|
||||
G4cout << "Physics table are stored for "
|
||||
<< part->GetParticleName()
|
||||
<< " and process " << proc->GetProcessName()
|
||||
<< " with a name <" << name << "> " << G4endl;
|
||||
}
|
||||
} else {
|
||||
G4cout << "Fail to store Physics Table for "
|
||||
<< part->GetParticleName()
|
||||
<< " and process " << proc->GetProcessName()
|
||||
<< " in the directory <" << dir
|
||||
<< "> " << G4endl;
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4EmTableUtil::StoreTable(G4VProcess* ptr,
|
||||
const G4ParticleDefinition* part,
|
||||
G4PhysicsTable* aTable,
|
||||
const G4String& dir,
|
||||
const G4String& tname,
|
||||
const G4int verb, const G4bool ascii)
|
||||
{
|
||||
G4bool res = true;
|
||||
if (nullptr != aTable) {
|
||||
const G4String& name =
|
||||
ptr->GetPhysicsTableFileName(part, dir, tname, ascii);
|
||||
if ( aTable->StorePhysicsTable(name, ascii) ) {
|
||||
if (1 < verb) G4cout << "Stored: " << name << G4endl;
|
||||
} else {
|
||||
res = false;
|
||||
G4cout << "Fail to store: " << name << G4endl;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4EmTableUtil::RetrieveTable(G4VProcess* ptr,
|
||||
const G4ParticleDefinition* part,
|
||||
G4PhysicsTable* aTable,
|
||||
const G4String& dir, const G4String& tname,
|
||||
const G4int verb, const G4bool ascii,
|
||||
const G4bool spline)
|
||||
{
|
||||
G4bool res = true;
|
||||
if (nullptr == aTable) { return res; }
|
||||
G4cout << tname << " table for " << part->GetParticleName()
|
||||
<< " will be retrieved " << G4endl;
|
||||
const G4String& name =
|
||||
ptr->GetPhysicsTableFileName(part, dir, tname, ascii);
|
||||
if(G4PhysicsTableHelper::RetrievePhysicsTable(aTable, name, ascii, spline)) {
|
||||
if(spline) {
|
||||
for(auto & v : *aTable) {
|
||||
if(nullptr != v) { v->FillSecondDerivatives(); }
|
||||
}
|
||||
}
|
||||
if (0 < verb) {
|
||||
G4cout << tname << " table for " << part->GetParticleName()
|
||||
<< " is Retrieved from <" << name << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
} else {
|
||||
res = false;
|
||||
G4cout << "Fail to retrieve: " << tname << " from " << name << " for "
|
||||
<< part->GetParticleName() << G4endl;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,395 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Geant4 class G4EmUtility
|
||||
//
|
||||
// Author V.Ivanchenko 14.03.2022
|
||||
//
|
||||
|
||||
#include "G4EmUtility.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4VEmProcess.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Exp.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
static const G4double g4log10 = G4Log(10.);
|
||||
|
||||
const G4Region*
|
||||
G4EmUtility::FindRegion(const G4String& regionName, const G4int verbose)
|
||||
{
|
||||
const G4Region* reg = nullptr;
|
||||
G4RegionStore* regStore = G4RegionStore::GetInstance();
|
||||
G4String r = regionName;
|
||||
if(r == "") { r = "DefaultRegionForTheWorld"; }
|
||||
reg = regStore->GetRegion(r, true);
|
||||
if(nullptr == reg && verbose > 0) {
|
||||
G4cout << "### G4EmUtility WARNING: fails to find a region <"
|
||||
<< r << G4endl;
|
||||
} else if(verbose > 1) {
|
||||
G4cout << "### G4EmUtility finds out G4Region <" << r << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
const G4Element* G4EmUtility::SampleRandomElement(const G4Material* mat)
|
||||
{
|
||||
const G4Element* elm = mat->GetElement(0);
|
||||
size_t nElements = mat->GetNumberOfElements();
|
||||
if(1 < nElements) {
|
||||
G4double x = mat->GetTotNbOfElectPerVolume()*G4UniformRand();
|
||||
const G4double* y = mat->GetVecNbOfAtomsPerVolume();
|
||||
for(size_t i=0; i<nElements; ++i) {
|
||||
elm = mat->GetElement(i);
|
||||
x -= y[i]*elm->GetZ();
|
||||
if(x <= 0.0) { break; }
|
||||
}
|
||||
}
|
||||
return elm;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
const G4Isotope* G4EmUtility::SampleRandomIsotope(const G4Element* elm)
|
||||
{
|
||||
const size_t ni = elm->GetNumberOfIsotopes();
|
||||
const G4Isotope* iso = elm->GetIsotope(0);
|
||||
if(ni > 1) {
|
||||
const G4double* ab = elm->GetRelativeAbundanceVector();
|
||||
G4double x = G4UniformRand();
|
||||
for(size_t idx=0; idx<ni; ++idx) {
|
||||
x -= ab[idx];
|
||||
if (x <= 0.0) {
|
||||
iso = elm->GetIsotope(idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return iso;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
std::vector<G4double>* G4EmUtility::FindCrossSectionMax(G4PhysicsTable* p)
|
||||
{
|
||||
std::vector<G4double>* ptr = nullptr;
|
||||
if(nullptr == p) { return ptr; }
|
||||
|
||||
const G4int n = p->length();
|
||||
ptr = new std::vector<G4double>;
|
||||
ptr->resize(n, DBL_MAX);
|
||||
|
||||
G4bool isPeak = false;
|
||||
G4double e, ss, ee, xs;
|
||||
|
||||
// first loop on existing vectors
|
||||
for (G4int i=0; i<n; ++i) {
|
||||
const G4PhysicsVector* pv = (*p)[i];
|
||||
xs = ee = 0.0;
|
||||
if(nullptr != pv) {
|
||||
G4int nb = pv->GetVectorLength();
|
||||
for (G4int j=0; j<nb; ++j) {
|
||||
e = pv->Energy(j);
|
||||
ss = (*pv)(j);
|
||||
if(ss >= xs) {
|
||||
xs = ss;
|
||||
ee = e;
|
||||
continue;
|
||||
} else {
|
||||
isPeak = true;
|
||||
(*ptr)[i] = ee;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// there is no peak for any material
|
||||
if(!isPeak) {
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
std::vector<G4double>*
|
||||
G4EmUtility::FindCrossSectionMax(G4VDiscreteProcess* p,
|
||||
const G4ParticleDefinition* part)
|
||||
{
|
||||
std::vector<G4double>* ptr = nullptr;
|
||||
if(nullptr == p || nullptr == part) { return ptr; }
|
||||
/*
|
||||
G4cout << "G4EmUtility::FindCrossSectionMax for "
|
||||
<< p->GetProcessName() << " and " << part->GetParticleName() << G4endl;
|
||||
*/
|
||||
G4EmParameters* theParameters = G4EmParameters::Instance();
|
||||
G4double tmin = theParameters->MinKinEnergy();
|
||||
G4double tmax = theParameters->MaxKinEnergy();
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t n = theCoupleTable->GetTableSize();
|
||||
ptr = new std::vector<G4double>;
|
||||
ptr->resize(n, DBL_MAX);
|
||||
|
||||
G4bool isPeak = false;
|
||||
G4double scale = theParameters->NumberOfBinsPerDecade()/g4log10;
|
||||
|
||||
G4double e, sig, ee, x, sm, em, emin, emax;
|
||||
|
||||
// first loop on existing vectors
|
||||
for (size_t i=0; i<n; ++i) {
|
||||
auto couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
emin = std::max(p->MinPrimaryEnergy(part, couple->GetMaterial()), tmin);
|
||||
emax = std::max(tmax, 2*emin);
|
||||
ee = G4Log(emax/emin);
|
||||
|
||||
G4int nbin = G4lrint(ee*scale);
|
||||
if(nbin < 4) { nbin = 4; }
|
||||
x = G4Exp(ee/nbin);
|
||||
sm = 0.0;
|
||||
em = 0.0;
|
||||
e = emin;
|
||||
for(G4int j=0; j<=nbin; ++j) {
|
||||
sig = p->GetCrossSection(e, couple);
|
||||
if(sig >= sm) {
|
||||
em = e;
|
||||
sm = sig;
|
||||
e = (j+1 < nbin) ? e*x : emax;
|
||||
} else {
|
||||
isPeak = true;
|
||||
(*ptr)[i] = em;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//G4cout << i << ". em=" << em << " sm=" << sm << G4endl;
|
||||
}
|
||||
// there is no peak for any couple
|
||||
if(!isPeak) {
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
std::vector<G4TwoPeaksXS*>*
|
||||
G4EmUtility::FillPeaksStructure(G4PhysicsTable* p, G4LossTableBuilder* bld)
|
||||
{
|
||||
std::vector<G4TwoPeaksXS*>* ptr = nullptr;
|
||||
if(nullptr == p) { return ptr; }
|
||||
|
||||
const G4int n = p->length();
|
||||
ptr = new std::vector<G4TwoPeaksXS*>;
|
||||
ptr->resize(n, nullptr);
|
||||
|
||||
G4double e, ss, xs, ee;
|
||||
G4double e1peak, e1deep, e2peak, e2deep, e3peak;
|
||||
G4bool isDeep = false;
|
||||
|
||||
// first loop on existing vectors
|
||||
for (G4int i=0; i<n; ++i) {
|
||||
const G4PhysicsVector* pv = (*p)[i];
|
||||
ee = xs = 0.0;
|
||||
e1peak = e1deep = e2peak = e2deep = e3peak = DBL_MAX;
|
||||
if(nullptr != pv) {
|
||||
G4int nb = pv->GetVectorLength();
|
||||
for (G4int j=0; j<nb; ++j) {
|
||||
e = pv->Energy(j);
|
||||
ss = (*pv)(j);
|
||||
// find out 1st peak
|
||||
if(e1peak == DBL_MAX) {
|
||||
if(ss >= xs) {
|
||||
xs = ss;
|
||||
ee = e;
|
||||
continue;
|
||||
} else {
|
||||
e1peak = ee;
|
||||
}
|
||||
}
|
||||
// find out the deep
|
||||
if(e1deep == DBL_MAX) {
|
||||
if(ss <= xs) {
|
||||
xs = ss;
|
||||
ee = e;
|
||||
continue;
|
||||
} else {
|
||||
e1deep = ee;
|
||||
isDeep = true;
|
||||
}
|
||||
}
|
||||
// find out 2nd peak
|
||||
if(e2peak == DBL_MAX) {
|
||||
if(ss >= xs) {
|
||||
xs = ss;
|
||||
ee = e;
|
||||
continue;
|
||||
} else {
|
||||
e2peak = ee;
|
||||
}
|
||||
}
|
||||
if(e2deep == DBL_MAX) {
|
||||
if(ss <= xs) {
|
||||
xs = ss;
|
||||
ee = e;
|
||||
continue;
|
||||
} else {
|
||||
e2deep = ee;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// find out 3d peak
|
||||
if(e3peak == DBL_MAX) {
|
||||
if(ss >= xs) {
|
||||
xs = ss;
|
||||
ee = e;
|
||||
continue;
|
||||
} else {
|
||||
e3peak = ee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
G4TwoPeaksXS* x = (*ptr)[i];
|
||||
if(nullptr == x) {
|
||||
x = new G4TwoPeaksXS();
|
||||
(*ptr)[i] = x;
|
||||
}
|
||||
x->e1peak = e1peak;
|
||||
x->e1deep = e1deep;
|
||||
x->e2peak = e2peak;
|
||||
x->e2deep = e2deep;
|
||||
x->e3peak = e3peak;
|
||||
}
|
||||
// case of no 1st peak in all vectors
|
||||
if(!isDeep) {
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
// check base particles
|
||||
if(!bld->GetBaseMaterialFlag()) { return ptr; }
|
||||
|
||||
auto theDensityIdx = bld->GetCoupleIndexes();
|
||||
// second loop using base materials
|
||||
for (G4int i=0; i<n; ++i) {
|
||||
const G4PhysicsVector* pv = (*p)[i];
|
||||
if (nullptr == pv) {
|
||||
G4int j = (*theDensityIdx)[i];
|
||||
if(j == i) { continue; }
|
||||
G4TwoPeaksXS* x = (*ptr)[i];
|
||||
G4TwoPeaksXS* y = (*ptr)[j];
|
||||
if(nullptr == x) {
|
||||
x = new G4TwoPeaksXS();
|
||||
(*ptr)[i] = x;
|
||||
}
|
||||
x->e1peak = y->e1peak;
|
||||
x->e1deep = y->e1deep;
|
||||
x->e2peak = y->e2peak;
|
||||
x->e2deep = y->e2deep;
|
||||
x->e3peak = y->e3peak;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4EmUtility::InitialiseElementSelectors(G4VEmModel* mod,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4DataVector& cuts,
|
||||
const G4double elow,
|
||||
const G4double ehigh)
|
||||
{
|
||||
// using spline for element selectors should be investigated in details
|
||||
// because small number of points may provide biased results
|
||||
// large number of points requires significant increase of memory
|
||||
G4bool spline = false;
|
||||
|
||||
G4int nbinsPerDec = G4EmParameters::Instance()->NumberOfBinsPerDecade();
|
||||
|
||||
G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
// prepare vector
|
||||
auto elmSelectors = mod->GetElementSelectors();
|
||||
if(nullptr == elmSelectors) {
|
||||
elmSelectors = new std::vector<G4EmElementSelector*>;
|
||||
}
|
||||
G4int nSelectors = elmSelectors->size();
|
||||
if(numOfCouples > nSelectors) {
|
||||
for(G4int i=nSelectors; i<numOfCouples; ++i) {
|
||||
elmSelectors->push_back(nullptr);
|
||||
}
|
||||
nSelectors = numOfCouples;
|
||||
}
|
||||
|
||||
// initialise vector
|
||||
for(G4int i=0; i<numOfCouples; ++i) {
|
||||
|
||||
// no need in element selectors for infinite cuts
|
||||
if(cuts[i] == DBL_MAX) { continue; }
|
||||
|
||||
auto couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
auto mat = couple->GetMaterial();
|
||||
mod->SetCurrentCouple(couple);
|
||||
|
||||
// selector already exist then delete
|
||||
delete (*elmSelectors)[i];
|
||||
|
||||
G4double emin = std::max(elow, mod->MinPrimaryEnergy(mat, part, cuts[i]));
|
||||
G4double emax = std::max(ehigh, 10*emin);
|
||||
static const G4double invlog106 = 1.0/(6*G4Log(10.));
|
||||
G4int nbins = G4lrint(nbinsPerDec*G4Log(emax/emin)*invlog106);
|
||||
nbins = std::max(nbins, 3);
|
||||
|
||||
(*elmSelectors)[i] = new G4EmElementSelector(mod,mat,nbins,
|
||||
emin,emax,spline);
|
||||
((*elmSelectors)[i])->Initialise(part, cuts[i]);
|
||||
/*
|
||||
G4cout << "G4VEmModel::InitialiseElmSelectors i= " << i
|
||||
<< " " << part->GetParticleName()
|
||||
<< " for " << mod->GetName() << " cut= " << cuts[i]
|
||||
<< " " << (*elmSelectors)[i] << G4endl;
|
||||
((*elmSelectors)[i])->Dump(part);
|
||||
*/
|
||||
}
|
||||
mod->SetElementSelectors(elmSelectors);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -49,9 +49,9 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EnergyLossTablesHelper *G4EnergyLossTables::t = 0;
|
||||
G4EnergyLossTablesHelper *G4EnergyLossTables::null_loss = 0;
|
||||
G4ParticleDefinition* G4EnergyLossTables::lastParticle = 0;
|
||||
G4EnergyLossTablesHelper *G4EnergyLossTables::t = nullptr;
|
||||
G4EnergyLossTablesHelper *G4EnergyLossTables::null_loss = nullptr;
|
||||
G4ParticleDefinition* G4EnergyLossTables::lastParticle = nullptr;
|
||||
G4double G4EnergyLossTables::QQPositron = 1.0; // e_squared
|
||||
G4double G4EnergyLossTables::Chargesquare ;
|
||||
G4int G4EnergyLossTables::oldIndex = -1 ;
|
||||
@@ -62,7 +62,7 @@ G4int G4EnergyLossTables::let_counter = 0;
|
||||
G4int G4EnergyLossTables::let_max_num_warnings = 100;
|
||||
G4bool G4EnergyLossTables::first_loss = true;
|
||||
|
||||
G4EnergyLossTables::helper_map *G4EnergyLossTables::dict = 0;
|
||||
G4EnergyLossTables::helper_map *G4EnergyLossTables::dict = nullptr;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -126,7 +126,8 @@ void G4EnergyLossTables::Register(
|
||||
Chargesquare = (p->GetPDGCharge())*(p->GetPDGCharge())/
|
||||
QQPositron ;
|
||||
if (first_loss ) {
|
||||
*null_loss = G4EnergyLossTablesHelper(0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0);
|
||||
*null_loss = G4EnergyLossTablesHelper(
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, 0.0, 0.0, 0.0, 0);
|
||||
first_loss = false;
|
||||
}
|
||||
}
|
||||
@@ -138,7 +139,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetDEDXTable(
|
||||
{
|
||||
if (!dict) dict = new G4EnergyLossTables::helper_map;
|
||||
helper_map::iterator it;
|
||||
if((it=dict->find(p))==dict->end()) return 0;
|
||||
if((it=dict->find(p))==dict->end()) return nullptr;
|
||||
return (*it).second.theDEDXTable;
|
||||
}
|
||||
|
||||
@@ -149,7 +150,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetRangeTable(
|
||||
{
|
||||
if (!dict) dict = new G4EnergyLossTables::helper_map;
|
||||
helper_map::iterator it;
|
||||
if((it=dict->find(p))==dict->end()) return 0;
|
||||
if((it=dict->find(p))==dict->end()) return nullptr;
|
||||
return (*it).second.theRangeTable;
|
||||
}
|
||||
|
||||
@@ -160,7 +161,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetInverseRangeTable(
|
||||
{
|
||||
if (!dict) dict = new G4EnergyLossTables::helper_map;
|
||||
helper_map::iterator it;
|
||||
if((it=dict->find(p))==dict->end()) return 0;
|
||||
if((it=dict->find(p))==dict->end()) return nullptr;
|
||||
return (*it).second.theInverseRangeTable;
|
||||
}
|
||||
|
||||
@@ -171,7 +172,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetLabTimeTable(
|
||||
{
|
||||
if (!dict) dict = new G4EnergyLossTables::helper_map;
|
||||
helper_map::iterator it;
|
||||
if((it=dict->find(p))==dict->end()) return 0;
|
||||
if((it=dict->find(p))==dict->end()) return nullptr;
|
||||
return (*it).second.theLabTimeTable;
|
||||
}
|
||||
|
||||
@@ -182,7 +183,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetProperTimeTable(
|
||||
{
|
||||
if (!dict) dict = new G4EnergyLossTables::helper_map;
|
||||
helper_map::iterator it;
|
||||
if((it=dict->find(p))==dict->end()) return 0;
|
||||
if((it=dict->find(p))==dict->end()) return nullptr;
|
||||
return (*it).second.theProperTimeTable;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,10 +159,10 @@ G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
|
||||
if(0 >= nCouples) { return; }
|
||||
|
||||
for (size_t i=0; i<nCouples; ++i) {
|
||||
G4PhysicsLogVector* pv0 = static_cast<G4PhysicsLogVector*>((*(list[0]))[i]);
|
||||
auto pv0 = static_cast<G4PhysicsLogVector*>((*(list[0]))[i]);
|
||||
if(pv0 == nullptr) { continue; }
|
||||
size_t npoints = pv0->GetVectorLength();
|
||||
G4PhysicsLogVector* pv = new G4PhysicsLogVector(*pv0);
|
||||
auto pv = new G4PhysicsLogVector(*pv0);
|
||||
for (size_t j=0; j<npoints; ++j) {
|
||||
G4double dedx = 0.0;
|
||||
for (size_t k=0; k<n_processes; ++k) {
|
||||
@@ -193,7 +193,7 @@ void G4LossTableBuilder::BuildRangeTable(const G4PhysicsTable* dedxTable,
|
||||
const G4double del = 1.0/(G4double)n;
|
||||
|
||||
for (std::size_t i=0; i<nCouples; ++i) {
|
||||
G4PhysicsLogVector* pv = static_cast<G4PhysicsLogVector*>((*dedxTable)[i]);
|
||||
auto pv = static_cast<G4PhysicsLogVector*>((*dedxTable)[i]);
|
||||
if((pv == nullptr) || (isBaseMatActive && !(*theFlag)[i])) { continue; }
|
||||
std::size_t npoints = pv->GetVectorLength();
|
||||
std::size_t bin0 = 0;
|
||||
@@ -273,7 +273,7 @@ G4LossTableBuilder::BuildInverseRangeTable(const G4PhysicsTable* rangeTable,
|
||||
std::size_t npoints = pv->GetVectorLength();
|
||||
|
||||
delete (*invRangeTable)[i];
|
||||
G4PhysicsFreeVector* v = new G4PhysicsFreeVector(npoints,splineFlag);
|
||||
auto v = new G4PhysicsFreeVector(npoints,splineFlag);
|
||||
|
||||
for (std::size_t j=0; j<npoints; ++j) {
|
||||
G4double e = pv->Energy(j);
|
||||
|
||||
@@ -772,10 +772,6 @@ void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (theElectron == part && theElectron == proc->SecondaryParticle() ) {
|
||||
proc->SetSecondaryRangeTable(base_proc->RangeTableForLoss());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,7 +805,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
|
||||
// possible case of process sharing between particle/anti-particle
|
||||
if(!yes) {
|
||||
G4VProcess* ptr = static_cast<G4VProcess*>(p);
|
||||
auto ptr = static_cast<G4VProcess*>(p);
|
||||
for(G4int j=0; j<nvec; ++j) {
|
||||
//G4cout << "j= " << j << " " << (*pvec)[j] << " " << ptr << G4endl;
|
||||
if(ptr == (*pvec)[j]) {
|
||||
@@ -847,7 +843,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
if (0 == n_dedx || !em) {
|
||||
G4cout << "G4LossTableManager WARNING: no DEDX processes for "
|
||||
<< aParticle->GetParticleName() << G4endl;
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
G4int nSubRegions = em->NumberOfSubCutoffRegions();
|
||||
|
||||
@@ -870,7 +866,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
em->SetDEDXTable(dedx, fIsIonisation);
|
||||
|
||||
if (1 < n_dedx) {
|
||||
dedx = 0;
|
||||
dedx = nullptr;
|
||||
dedx = G4PhysicsTableHelper::PreparePhysicsTable(dedx);
|
||||
tableBuilder->BuildDEDXTable(dedx, t_list);
|
||||
em->SetDEDXTable(dedx, fRestricted);
|
||||
|
||||
@@ -69,11 +69,6 @@ G4NIELCalculator::G4NIELCalculator(G4VEmModel* mod, G4int verb)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4NIELCalculator::~G4NIELCalculator()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4NIELCalculator::AddEmModel(G4VEmModel* mod)
|
||||
{
|
||||
if(mod && mod != fModel) {
|
||||
|
||||
@@ -86,7 +86,7 @@ G4OpticalParametersMessenger::G4OpticalParametersMessenger(
|
||||
new G4UIcommand("/process/optical/processActivation", this);
|
||||
fActivateProcessCmd->SetGuidance(
|
||||
"Activate/deactivate the specified optical process");
|
||||
G4UIparameter* par = new G4UIparameter("proc_name", 's', false);
|
||||
auto par = new G4UIparameter("proc_name", 's', false);
|
||||
G4String candidates;
|
||||
for(G4int i = 0; i < kNoProcess; ++i)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,461 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4TransportationWithMsc
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// It is a generic process of transportation with multiple scattering included
|
||||
// in the step limitation and propagation.
|
||||
//
|
||||
// Original author: Jonas Hahnfeld, 2022
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4TransportationWithMsc.hh"
|
||||
|
||||
#include "G4LossTableBuilder.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4EmConfigurator.hh"
|
||||
#include "G4VMscModel.hh"
|
||||
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4StepPoint.hh"
|
||||
#include "G4StepStatus.hh"
|
||||
#include "G4Track.hh"
|
||||
|
||||
#include "G4Electron.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
static constexpr G4double kLowestKinEnergy = 10 * CLHEP::eV;
|
||||
static constexpr G4double kGeomMin = 0.05 * CLHEP::nm;
|
||||
static constexpr G4double kMinDisplacement2 = kGeomMin * kGeomMin;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4TransportationWithMsc::G4TransportationWithMsc(ScatteringType type,
|
||||
G4int verbosity)
|
||||
: G4Transportation(verbosity, "TransportationWithMsc")
|
||||
, fType(type)
|
||||
{
|
||||
SetVerboseLevel(1);
|
||||
|
||||
fEmManager = G4LossTableManager::Instance();
|
||||
fModelManager = new G4EmModelManager;
|
||||
|
||||
G4ThreeVector zero;
|
||||
fSubStepDynamicParticle =
|
||||
new G4DynamicParticle(G4Electron::Definition(), zero);
|
||||
fSubStepTrack = new G4Track(fSubStepDynamicParticle, 0, zero);
|
||||
fSubStep = new G4Step;
|
||||
fSubStepTrack->SetStep(fSubStep);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4TransportationWithMsc::~G4TransportationWithMsc()
|
||||
{
|
||||
delete fModelManager;
|
||||
// fSubStepDynamicParticle is owned and also deleted by fSubStepTrack!
|
||||
delete fSubStepTrack;
|
||||
delete fSubStep;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4TransportationWithMsc::AddMscModel(G4VMscModel* mscModel, G4int order,
|
||||
const G4Region* region)
|
||||
{
|
||||
if(fType != ScatteringType::MultipleScattering)
|
||||
{
|
||||
G4Exception("G4TransportationWithMsc::AddMscModel", "em0051",
|
||||
FatalException,
|
||||
"not allowed unless type == MultipleScattering");
|
||||
}
|
||||
|
||||
fModelManager->AddEmModel(order, mscModel, nullptr, region);
|
||||
mscModel->SetParticleChange(&fParticleChange);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4TransportationWithMsc::PreparePhysicsTable(
|
||||
const G4ParticleDefinition& part)
|
||||
{
|
||||
if(nullptr == fFirstParticle)
|
||||
{
|
||||
fFirstParticle = ∂
|
||||
G4VMultipleScattering* ptr = nullptr;
|
||||
auto emConfigurator = fEmManager->EmConfigurator();
|
||||
emConfigurator->PrepareModels(&part, ptr, this);
|
||||
}
|
||||
|
||||
if(fFirstParticle == &part)
|
||||
{
|
||||
G4bool master = fEmManager->IsMaster();
|
||||
G4LossTableBuilder* bld = fEmManager->GetTableBuilder();
|
||||
G4bool baseMat = bld->GetBaseMaterialFlag();
|
||||
const auto* theParameters = G4EmParameters::Instance();
|
||||
|
||||
if(master)
|
||||
{
|
||||
SetVerboseLevel(theParameters->Verbose());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVerboseLevel(theParameters->WorkerVerbose());
|
||||
}
|
||||
|
||||
const G4int numberOfModels = fModelManager->NumberOfModels();
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
msc->SetMasterThread(master);
|
||||
msc->SetPolarAngleLimit(theParameters->MscThetaLimit());
|
||||
G4double emax =
|
||||
std::min(msc->HighEnergyLimit(), theParameters->MaxKinEnergy());
|
||||
msc->SetHighEnergyLimit(emax);
|
||||
msc->SetUseBaseMaterials(baseMat);
|
||||
}
|
||||
|
||||
fModelManager->Initialise(fFirstParticle, G4Electron::Electron(),
|
||||
verboseLevel);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4TransportationWithMsc::BuildPhysicsTable(
|
||||
const G4ParticleDefinition& part)
|
||||
{
|
||||
if(fFirstParticle == &part)
|
||||
{
|
||||
fEmManager->BuildPhysicsTable(fFirstParticle);
|
||||
|
||||
if(!fEmManager->IsMaster())
|
||||
{
|
||||
const auto masterProcess =
|
||||
static_cast<const G4TransportationWithMsc*>(GetMasterProcess());
|
||||
|
||||
// Initialisation of models.
|
||||
const G4int numberOfModels = fModelManager->NumberOfModels();
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
auto msc0 =
|
||||
static_cast<G4VMscModel*>(masterProcess->fModelManager->GetModel(i));
|
||||
msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false);
|
||||
msc->InitialiseLocal(fFirstParticle, msc0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!G4EmParameters::Instance()->IsPrintLocked() && verboseLevel > 0)
|
||||
{
|
||||
G4cout << G4endl;
|
||||
G4cout << GetProcessName() << ": for " << part.GetParticleName();
|
||||
if(fMultipleSteps)
|
||||
{
|
||||
G4cout << " (multipleSteps: 1)";
|
||||
}
|
||||
G4cout << G4endl;
|
||||
fModelManager->DumpModelList(G4cout, verboseLevel);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4TransportationWithMsc::StartTracking(G4Track* track)
|
||||
{
|
||||
auto* currParticle = track->GetParticleDefinition();
|
||||
auto* ionisation = fEmManager->GetEnergyLossProcess(currParticle);
|
||||
|
||||
fSubStepDynamicParticle->SetDefinition(currParticle);
|
||||
|
||||
const G4int numberOfModels = fModelManager->NumberOfModels();
|
||||
for(G4int i = 0; i < numberOfModels; ++i)
|
||||
{
|
||||
auto msc = static_cast<G4VMscModel*>(fModelManager->GetModel(i));
|
||||
msc->StartTracking(track);
|
||||
msc->SetIonisation(ionisation, currParticle);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4TransportationWithMsc::AlongStepGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4double previousStepSize, G4double currentMinimumStep,
|
||||
G4double& proposedSafety, G4GPILSelection* selection)
|
||||
{
|
||||
*selection = NotCandidateForSelection;
|
||||
|
||||
const G4double physStepLimit = currentMinimumStep;
|
||||
|
||||
switch(fType)
|
||||
{
|
||||
case ScatteringType::MultipleScattering: {
|
||||
// Select the MSC model for the current kinetic energy.
|
||||
G4VMscModel* mscModel = nullptr;
|
||||
const G4double ekin = track.GetKineticEnergy();
|
||||
const auto* couple = track.GetMaterialCutsCouple();
|
||||
const auto* particleDefinition = track.GetParticleDefinition();
|
||||
if(physStepLimit > kGeomMin)
|
||||
{
|
||||
G4double ekinForSelection = ekin;
|
||||
G4double pdgMass = particleDefinition->GetPDGMass();
|
||||
if(pdgMass > CLHEP::GeV)
|
||||
{
|
||||
ekinForSelection *= proton_mass_c2 / pdgMass;
|
||||
}
|
||||
|
||||
if(ekinForSelection >= kLowestKinEnergy)
|
||||
{
|
||||
mscModel = static_cast<G4VMscModel*>(
|
||||
fModelManager->SelectModel(ekinForSelection, couple->GetIndex()));
|
||||
if(mscModel == nullptr)
|
||||
{
|
||||
G4Exception("G4TransportationWithMsc::AlongStepGPIL", "em0052",
|
||||
FatalException, "no MSC model found");
|
||||
}
|
||||
if(!mscModel->IsActive(ekinForSelection))
|
||||
{
|
||||
mscModel = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the MSC model to potentially limit the step and convert to
|
||||
// geometric path length.
|
||||
if(mscModel != nullptr)
|
||||
{
|
||||
mscModel->SetCurrentCouple(couple);
|
||||
|
||||
// Use the provided track for the first step.
|
||||
const G4Track* currentTrackPtr = &track;
|
||||
|
||||
G4double currentSafety = proposedSafety;
|
||||
G4double currentEnergy = ekin;
|
||||
|
||||
G4double stepLimitLeft = physStepLimit;
|
||||
G4double totalGeometryStepLength = 0, totalTruePathLength = 0;
|
||||
G4bool firstStep = true, continueStepping = fMultipleSteps;
|
||||
|
||||
do
|
||||
{
|
||||
G4double gPathLength = stepLimitLeft;
|
||||
G4double tPathLength =
|
||||
mscModel->ComputeTruePathLengthLimit(*currentTrackPtr, gPathLength);
|
||||
G4bool mscLimitsStep = (tPathLength < stepLimitLeft);
|
||||
if(!fMultipleSteps && mscLimitsStep)
|
||||
{
|
||||
// MSC limits the step.
|
||||
*selection = CandidateForSelection;
|
||||
}
|
||||
|
||||
if(!firstStep)
|
||||
{
|
||||
// Move the navigator to where the previous step ended.
|
||||
fLinearNavigator->LocateGlobalPointWithinVolume(
|
||||
fTransportEndPosition);
|
||||
}
|
||||
|
||||
G4GPILSelection transportSelection;
|
||||
G4double geometryStepLength =
|
||||
G4Transportation::AlongStepGetPhysicalInteractionLength(
|
||||
*currentTrackPtr, previousStepSize, gPathLength, currentSafety,
|
||||
&transportSelection);
|
||||
if(geometryStepLength < gPathLength)
|
||||
{
|
||||
// Transportation limits the step, ie the track hit a boundary.
|
||||
*selection = CandidateForSelection;
|
||||
continueStepping = false;
|
||||
}
|
||||
if(fTransportEndKineticEnergy != currentEnergy)
|
||||
{
|
||||
// Field propagation changed the energy, it's not possible to
|
||||
// estimate the continuous energy loss and continue stepping.
|
||||
continueStepping = false;
|
||||
}
|
||||
|
||||
if(firstStep)
|
||||
{
|
||||
proposedSafety = currentSafety;
|
||||
}
|
||||
totalGeometryStepLength += geometryStepLength;
|
||||
|
||||
// Sample MSC direction change and displacement.
|
||||
const G4double range =
|
||||
mscModel->GetRange(particleDefinition, currentEnergy, couple);
|
||||
|
||||
tPathLength = mscModel->ComputeTrueStepLength(geometryStepLength);
|
||||
|
||||
// Protect against wrong t->g->t conversion.
|
||||
tPathLength = std::min(tPathLength, stepLimitLeft);
|
||||
|
||||
totalTruePathLength += tPathLength;
|
||||
if(*selection != CandidateForSelection && !mscLimitsStep)
|
||||
{
|
||||
// If neither MSC nor transportation limits the step, we got the
|
||||
// distance we want - make sure we exit the loop.
|
||||
continueStepping = false;
|
||||
}
|
||||
else if(tPathLength >= range)
|
||||
{
|
||||
// The particle will stop, exit the loop.
|
||||
continueStepping = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
stepLimitLeft -= tPathLength;
|
||||
}
|
||||
|
||||
// Do not sample scattering at the last or at a small step.
|
||||
if(tPathLength < range && tPathLength > kGeomMin)
|
||||
{
|
||||
static constexpr G4double minSafety = 1.20 * CLHEP::nm;
|
||||
static constexpr G4double sFact = 0.99;
|
||||
|
||||
// The call to SampleScattering() *may* directly fill in the changed
|
||||
// direction into fParticleChange, so we have to:
|
||||
// 1) Make sure the momentum direction is initialized.
|
||||
fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir);
|
||||
// 2) Call SampleScattering(), which *may* change it.
|
||||
const G4ThreeVector displacement =
|
||||
mscModel->SampleScattering(fTransportEndMomentumDir, minSafety);
|
||||
// 3) Get the changed direction and inform G4Transportation.
|
||||
fMomentumChanged = true;
|
||||
fTransportEndMomentumDir = *fParticleChange.GetMomentumDirection();
|
||||
|
||||
const G4double r2 = displacement.mag2();
|
||||
if(r2 > kMinDisplacement2)
|
||||
{
|
||||
G4bool positionChanged = true;
|
||||
G4double dispR = std::sqrt(r2);
|
||||
G4double postSafety = sFact * fpSafetyHelper->ComputeSafety(
|
||||
fTransportEndPosition, dispR);
|
||||
|
||||
// Far away from geometry boundary
|
||||
if(postSafety > 0.0 && dispR <= postSafety)
|
||||
{
|
||||
fTransportEndPosition += displacement;
|
||||
|
||||
// Near the boundary
|
||||
}
|
||||
else
|
||||
{
|
||||
// displaced point is definitely within the volume
|
||||
if(dispR < postSafety)
|
||||
{
|
||||
fTransportEndPosition += displacement;
|
||||
|
||||
// reduced displacement
|
||||
}
|
||||
else if(postSafety > kGeomMin)
|
||||
{
|
||||
fTransportEndPosition += displacement * (postSafety / dispR);
|
||||
|
||||
// very small postSafety
|
||||
}
|
||||
else
|
||||
{
|
||||
positionChanged = false;
|
||||
}
|
||||
}
|
||||
if(positionChanged)
|
||||
{
|
||||
fpSafetyHelper->ReLocateWithinVolume(fTransportEndPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(continueStepping)
|
||||
{
|
||||
// Update safety according to the geometry distance.
|
||||
if(currentSafety < fEndPointDistance)
|
||||
{
|
||||
currentSafety = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSafety -= fEndPointDistance;
|
||||
}
|
||||
|
||||
// Update the kinetic energy according to the continuous loss.
|
||||
currentEnergy = mscModel->GetEnergy(particleDefinition,
|
||||
range - tPathLength, couple);
|
||||
|
||||
// From now on, use the track that we can update below.
|
||||
currentTrackPtr = fSubStepTrack;
|
||||
|
||||
fSubStepDynamicParticle->SetKineticEnergy(currentEnergy);
|
||||
fSubStepDynamicParticle->SetMomentumDirection(
|
||||
fTransportEndMomentumDir);
|
||||
fSubStepTrack->SetPosition(fTransportEndPosition);
|
||||
|
||||
G4StepPoint& subPreStepPoint = *fSubStep->GetPreStepPoint();
|
||||
subPreStepPoint.SetMaterialCutsCouple(couple);
|
||||
subPreStepPoint.SetPosition(fTransportEndPosition);
|
||||
subPreStepPoint.SetSafety(currentSafety);
|
||||
subPreStepPoint.SetStepStatus(fAlongStepDoItProc);
|
||||
}
|
||||
firstStep = false;
|
||||
} while(continueStepping);
|
||||
|
||||
// Note: currentEnergy is only updated if continueStepping is true.
|
||||
// In case field propagation changed the energy, this flag is
|
||||
// immediately set to false and currentEnergy is still equal to the
|
||||
// initial kinetic energy stored in ekin.
|
||||
if(currentEnergy != ekin)
|
||||
{
|
||||
// If field propagation didn't change the energy and we potentially
|
||||
// did multiple steps, reset the energy that G4Transportation will
|
||||
// propose to not subtract the energy loss twice.
|
||||
fTransportEndKineticEnergy = ekin;
|
||||
// Also ask for the range again with the initial energy so it is
|
||||
// correctly cached in the G4VEnergyLossProcess.
|
||||
// FIXME: Asking for a range should never change the cached values!
|
||||
(void) mscModel->GetRange(particleDefinition, ekin, couple);
|
||||
}
|
||||
|
||||
fParticleChange.ProposeTrueStepLength(totalTruePathLength);
|
||||
|
||||
return totalGeometryStepLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, no scattering has happened.
|
||||
return G4Transportation::AlongStepGetPhysicalInteractionLength(
|
||||
track, previousStepSize, currentMinimumStep, proposedSafety, selection);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -79,8 +79,7 @@ G4VAtomDeexcitation::G4VAtomDeexcitation(const G4String& modname)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VAtomDeexcitation::~G4VAtomDeexcitation()
|
||||
{}
|
||||
G4VAtomDeexcitation::~G4VAtomDeexcitation() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -306,7 +305,7 @@ G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
|
||||
G4double rho = truelength*theAtomNumDensityVector[i];
|
||||
//G4cout<<" Z "<< Z <<" is active x(mm)= " << truelength/mm << G4endl;
|
||||
for(G4int ii=0; ii<nshells; ++ii) {
|
||||
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(ii);
|
||||
auto as = (G4AtomicShellEnumerator)(ii);
|
||||
const G4AtomicShell* shell = GetAtomicShell(Z, as);
|
||||
const G4double bindingEnergy = shell->BindingEnergy();
|
||||
|
||||
|
||||
@@ -61,8 +61,7 @@ G4VEmAngularDistribution::G4VEmAngularDistribution(const G4String& name)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VEmAngularDistribution::~G4VEmAngularDistribution()
|
||||
{}
|
||||
G4VEmAngularDistribution::~G4VEmAngularDistribution() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4EmUtility.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "Randomize.hh"
|
||||
#include <iostream>
|
||||
@@ -138,65 +139,8 @@ G4ParticleChangeForGamma* G4VEmModel::GetParticleChangeForGamma()
|
||||
void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* part,
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
// using spline for element selectors should be investigated in details
|
||||
// because small number of points may provide biased results
|
||||
// large number of points requires significant increase of memory
|
||||
G4bool spline = false;
|
||||
|
||||
//G4cout << "IES: for " << GetName() << " Emin(MeV)= " << lowLimit/MeV
|
||||
// << " Emax(MeV)= " << highLimit/MeV << G4endl;
|
||||
|
||||
// two times less bins because probability functon is normalized
|
||||
// so correspondingly is more smooth
|
||||
if(highLimit <= lowLimit) { return; }
|
||||
|
||||
G4int nbinsPerDec = G4EmParameters::Instance()->NumberOfBinsPerDecade();
|
||||
|
||||
G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
// prepare vector
|
||||
if(!elmSelectors) {
|
||||
elmSelectors = new std::vector<G4EmElementSelector*>;
|
||||
}
|
||||
if(numOfCouples > nSelectors) {
|
||||
for(G4int i=nSelectors; i<numOfCouples; ++i) {
|
||||
elmSelectors->push_back(nullptr);
|
||||
}
|
||||
nSelectors = numOfCouples;
|
||||
}
|
||||
|
||||
// initialise vector
|
||||
for(G4int i=0; i<numOfCouples; ++i) {
|
||||
|
||||
// no need in element selectors for infinite cuts
|
||||
if(cuts[i] == DBL_MAX) { continue; }
|
||||
|
||||
auto couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
auto material = couple->GetMaterial();
|
||||
SetCurrentCouple(couple);
|
||||
|
||||
// selector already exist then delete
|
||||
delete (*elmSelectors)[i];
|
||||
|
||||
G4double emin = std::max(lowLimit, MinPrimaryEnergy(material, part, cuts[i]));
|
||||
G4double emax = std::max(highLimit, 10*emin);
|
||||
static const G4double invlog106 = 1.0/(6*G4Log(10.));
|
||||
G4int nbins = (G4int)(nbinsPerDec*G4Log(emax/emin)*invlog106);
|
||||
nbins = std::max(nbins, 3);
|
||||
|
||||
(*elmSelectors)[i] = new G4EmElementSelector(this,material,nbins,
|
||||
emin,emax,spline);
|
||||
((*elmSelectors)[i])->Initialise(part, cuts[i]);
|
||||
/*
|
||||
G4cout << "G4VEmModel::InitialiseElmSelectors i= " << i
|
||||
<< " " << part->GetParticleName()
|
||||
<< " for " << GetName() << " cut= " << cuts[i]
|
||||
<< " " << (*elmSelectors)[i] << G4endl;
|
||||
((*elmSelectors)[i])->Dump(part);
|
||||
*/
|
||||
}
|
||||
G4EmUtility::InitialiseElementSelectors(this,part,cuts,lowLimit,highLimit);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -292,48 +236,47 @@ const G4Element* G4VEmModel::SelectRandomAtom(const G4Material* mat,
|
||||
}
|
||||
return fCurrentElement;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4VEmModel::SelectRandomAtomNumber(const G4Material* mat)
|
||||
const G4Element* G4VEmModel::GetCurrentElement(const G4Material* mat) const
|
||||
{
|
||||
// this algorith assumes that cross section is proportional to
|
||||
// number electrons multiplied by number of atoms
|
||||
const size_t nn = mat->GetNumberOfElements();
|
||||
fCurrentElement = mat->GetElement(0);
|
||||
if(1 < nn) {
|
||||
const G4double* at = mat->GetVecNbOfAtomsPerVolume();
|
||||
G4double tot = mat->GetTotNbOfAtomsPerVolume()*G4UniformRand();
|
||||
for(size_t i=0; i<nn; ++i) {
|
||||
tot -= at[i];
|
||||
if(tot <= 0.0) {
|
||||
fCurrentElement = mat->GetElement(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
const G4Element* elm = fCurrentElement;
|
||||
if(nullptr == elm && nullptr != mat) {
|
||||
elm = G4EmUtility::SampleRandomElement(mat);
|
||||
}
|
||||
return fCurrentElement->GetZasInt();
|
||||
return elm;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4VEmModel::SelectIsotopeNumber(const G4Element* elm)
|
||||
G4int G4VEmModel::SelectRandomAtomNumber(const G4Material* mat) const
|
||||
{
|
||||
SetCurrentElement(elm);
|
||||
const size_t ni = elm->GetNumberOfIsotopes();
|
||||
fCurrentIsotope = elm->GetIsotope(0);
|
||||
size_t idx = 0;
|
||||
if(ni > 1) {
|
||||
const G4double* ab = elm->GetRelativeAbundanceVector();
|
||||
G4double x = G4UniformRand();
|
||||
for(; idx<ni; ++idx) {
|
||||
x -= ab[idx];
|
||||
if (x <= 0.0) {
|
||||
fCurrentIsotope = elm->GetIsotope(idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
const G4Element* elm = GetCurrentElement(mat);
|
||||
return (nullptr == elm) ? 0 : elm->GetZasInt();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4Isotope* G4VEmModel::GetCurrentIsotope(const G4Element* elm) const
|
||||
{
|
||||
const G4Isotope* iso = nullptr;
|
||||
const G4Element* el = elm;
|
||||
if(nullptr == el && nullptr != fCurrentCouple) {
|
||||
el = GetCurrentElement(fCurrentCouple->GetMaterial());
|
||||
}
|
||||
return fCurrentIsotope->GetN();
|
||||
if(nullptr != el) {
|
||||
iso = G4EmUtility::SampleRandomIsotope(el);
|
||||
}
|
||||
return iso;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4VEmModel::SelectIsotopeNumber(const G4Element* elm) const
|
||||
{
|
||||
auto iso = GetCurrentIsotope(elm);
|
||||
return (nullptr != iso) ? iso->GetN() : 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
#include "G4EmDataHandler.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4PhysicsModelCatalog.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4Gamma.hh"
|
||||
@@ -68,7 +67,8 @@
|
||||
#include "G4EmBiasingManager.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4EmProcessSubType.hh"
|
||||
#include "G4LowEnergyEmProcessSubType.hh"
|
||||
#include "G4EmTableUtil.hh"
|
||||
#include "G4EmUtility.hh"
|
||||
#include "G4DNAModelSubType.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4Log.hh"
|
||||
@@ -87,12 +87,12 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
|
||||
maxKinEnergy = 100.0*CLHEP::TeV;
|
||||
|
||||
// default lambda factor
|
||||
logLambdaFactor = G4Log(lambdaFactor);
|
||||
invLambdaFactor = 1.0/lambdaFactor;
|
||||
|
||||
// particle types
|
||||
theGamma = G4Gamma::Gamma();
|
||||
theElectron = G4Electron::Electron();
|
||||
thePositron = G4Positron::Positron();
|
||||
theGamma = G4Gamma::Gamma();
|
||||
theElectron = G4Electron::Electron();
|
||||
thePositron = G4Positron::Positron();
|
||||
|
||||
pParticleChange = &fParticleChange;
|
||||
fParticleChange.SetSecondaryWeightByProcess(true);
|
||||
@@ -101,6 +101,7 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
|
||||
modelManager = new G4EmModelManager();
|
||||
lManager = G4LossTableManager::Instance();
|
||||
lManager->Register(this);
|
||||
isTheMaster = lManager->IsMaster();
|
||||
G4LossTableBuilder* bld = lManager->GetTableBuilder();
|
||||
theDensityFactor = bld->GetDensityFactors();
|
||||
theDensityIdx = bld->GetCoupleIndexes();
|
||||
@@ -110,12 +111,6 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
|
||||
|
||||
G4VEmProcess::~G4VEmProcess()
|
||||
{
|
||||
/*
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4VEmProcess destruct " << GetProcessName()
|
||||
<< " " << this << " " << theLambdaTable <<G4endl;
|
||||
}
|
||||
*/
|
||||
if(isTheMaster) {
|
||||
delete theData;
|
||||
delete theEnergyOfCrossSectionMax;
|
||||
@@ -127,22 +122,6 @@ G4VEmProcess::~G4VEmProcess()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VEmProcess::Clear()
|
||||
{
|
||||
currentCouple = nullptr;
|
||||
preStepLambda = 0.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VEmProcess::MinPrimaryEnergy(const G4ParticleDefinition*,
|
||||
const G4Material*)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VEmProcess::AddEmModel(G4int order, G4VEmModel* ptr,
|
||||
const G4Region* region)
|
||||
{
|
||||
@@ -165,16 +144,8 @@ void G4VEmProcess::SetEmModel(G4VEmModel* ptr, G4int)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver) const
|
||||
{
|
||||
return modelManager->GetModel(idx, ver);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
|
||||
{
|
||||
isTheMaster = lManager->IsMaster();
|
||||
if(nullptr == particle) { SetParticle(&part); }
|
||||
|
||||
if(part.GetParticleType() == "nucleus" &&
|
||||
@@ -182,124 +153,75 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
|
||||
|
||||
G4String pname = part.GetParticleName();
|
||||
if(pname != "deuteron" && pname != "triton" &&
|
||||
pname != "alpha" && pname != "He3" &&
|
||||
pname != "alpha+" && pname != "helium" &&
|
||||
pname != "hydrogen") {
|
||||
pname != "alpha" && pname != "alpha+" &&
|
||||
pname != "helium" && pname != "hydrogen") {
|
||||
|
||||
particle = G4GenericIon::GenericIon();
|
||||
isIon = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4VEmProcess::PreparePhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< " local particle " << particle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(particle != &part) { return; }
|
||||
|
||||
lManager->PreparePhysicsTable(&part, this, isTheMaster);
|
||||
|
||||
Clear();
|
||||
// for new run
|
||||
currentCouple = nullptr;
|
||||
preStepLambda = 0.0;
|
||||
fLambdaEnergy = 0.0;
|
||||
|
||||
InitialiseProcess(particle);
|
||||
|
||||
G4LossTableBuilder* bld = lManager->GetTableBuilder();
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
theCutsGamma = theCoupleTable->GetEnergyCutsVector(idxG4GammaCut);
|
||||
theCutsElectron = theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut);
|
||||
theCutsPositron = theCoupleTable->GetEnergyCutsVector(idxG4PositronCut);
|
||||
|
||||
// initialisation of the process
|
||||
if(!actMinKinEnergy) { minKinEnergy = theParameters->MinKinEnergy(); }
|
||||
if(!actMaxKinEnergy) { maxKinEnergy = theParameters->MaxKinEnergy(); }
|
||||
|
||||
if(isTheMaster) {
|
||||
SetVerboseLevel(theParameters->Verbose());
|
||||
if(nullptr == theData) { theData = new G4EmDataHandler(2); }
|
||||
if(fEmOnePeak == fXSType) {
|
||||
if(nullptr == theEnergyOfCrossSectionMax) {
|
||||
theEnergyOfCrossSectionMax = new std::vector<G4double>;
|
||||
}
|
||||
size_t n = theCoupleTable->GetTableSize();
|
||||
theEnergyOfCrossSectionMax->resize(n, DBL_MAX);
|
||||
}
|
||||
} else {
|
||||
SetVerboseLevel(theParameters->WorkerVerbose());
|
||||
}
|
||||
applyCuts = theParameters->ApplyCuts();
|
||||
lambdaFactor = theParameters->LambdaFactor();
|
||||
logLambdaFactor = G4Log(lambdaFactor);
|
||||
invLambdaFactor = 1.0/lambdaFactor;
|
||||
theParameters->DefineRegParamForEM(this);
|
||||
|
||||
// integral option may be disabled
|
||||
if(!theParameters->Integral()) { fXSType = fEmNoIntegral; }
|
||||
|
||||
// prepare tables
|
||||
if(buildLambdaTable && isTheMaster){
|
||||
theLambdaTable = theData->MakeTable(0);
|
||||
bld->InitialiseBaseMaterials(theLambdaTable);
|
||||
}
|
||||
// high energy table
|
||||
if(isTheMaster && minKinEnergyPrim < maxKinEnergy){
|
||||
theLambdaTablePrim = theData->MakeTable(1);
|
||||
bld->InitialiseBaseMaterials(theLambdaTablePrim);
|
||||
}
|
||||
baseMat = bld->GetBaseMaterialFlag();
|
||||
if(isTheMaster) {
|
||||
if(nullptr == theData) { theData = new G4EmDataHandler(2); }
|
||||
|
||||
// initialisation of models
|
||||
numberOfModels = modelManager->NumberOfModels();
|
||||
for(G4int i=0; i<numberOfModels; ++i) {
|
||||
G4VEmModel* mod = modelManager->GetModel(i);
|
||||
if(nullptr == mod) { continue; }
|
||||
if(nullptr == currentModel) { currentModel = mod; }
|
||||
mod->SetPolarAngleLimit(theParameters->MscThetaLimit());
|
||||
mod->SetMasterThread(isTheMaster);
|
||||
if(mod->HighEnergyLimit() > maxKinEnergy) {
|
||||
mod->SetHighEnergyLimit(maxKinEnergy);
|
||||
if(buildLambdaTable) {
|
||||
theLambdaTable = theData->MakeTable(0);
|
||||
bld->InitialiseBaseMaterials(theLambdaTable);
|
||||
}
|
||||
// high energy table
|
||||
if(minKinEnergyPrim < maxKinEnergy) {
|
||||
theLambdaTablePrim = theData->MakeTable(1);
|
||||
bld->InitialiseBaseMaterials(theLambdaTablePrim);
|
||||
}
|
||||
SetEmModel(mod);
|
||||
mod->SetUseBaseMaterials(baseMat);
|
||||
}
|
||||
|
||||
// models
|
||||
baseMat = bld->GetBaseMaterialFlag();
|
||||
numberOfModels = modelManager->NumberOfModels();
|
||||
currentModel = modelManager->GetModel(0);
|
||||
if(nullptr != lManager->AtomDeexcitation()) {
|
||||
modelManager->SetFluoFlag(true);
|
||||
}
|
||||
fLambdaEnergy = 0.0;
|
||||
|
||||
theCuts =
|
||||
modelManager->Initialise(particle,secondaryParticle,1.0,verboseLevel);
|
||||
theCutsGamma = theCoupleTable->GetEnergyCutsVector(idxG4GammaCut);
|
||||
theCutsElectron = theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut);
|
||||
theCutsPositron = theCoupleTable->GetEnergyCutsVector(idxG4PositronCut);
|
||||
|
||||
// forced biasing
|
||||
if(biasManager) {
|
||||
biasManager->Initialise(part,GetProcessName(),verboseLevel);
|
||||
if(nullptr != biasManager) {
|
||||
biasManager->Initialise(part, GetProcessName(), verboseLevel);
|
||||
biasFlag = false;
|
||||
}
|
||||
|
||||
// defined ID of secondary particles
|
||||
G4int stype = GetProcessSubType();
|
||||
if(stype == fAnnihilation) {
|
||||
secID = _Annihilation;
|
||||
tripletID = _TripletGamma;
|
||||
} else if(stype == fGammaConversion) {
|
||||
secID = _PairProduction;
|
||||
mainSecondaries = 2;
|
||||
} else if(stype == fPhotoElectricEffect) {
|
||||
secID = _PhotoElectron;
|
||||
} else if(stype == fComptonScattering) {
|
||||
secID = _ComptonElectron;
|
||||
} else if(stype >= fLowEnergyElastic) {
|
||||
secID = fDNAUnknownModel;
|
||||
}
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### G4VEmProcess::PreparePhysicsTable() done for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< " baseMat=" << baseMat << G4endl;
|
||||
}
|
||||
theCuts =
|
||||
G4EmTableUtil::PrepareEmProcess(this, particle, secondaryParticle,
|
||||
modelManager, maxKinEnergy,
|
||||
secID, tripletID, mainSecondaries,
|
||||
verboseLevel, isTheMaster);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -310,166 +232,31 @@ void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
if(isTheMaster) { masterProc = this; }
|
||||
else { masterProc = static_cast<const G4VEmProcess*>(GetMasterProcess());}
|
||||
}
|
||||
G4int nModels = modelManager->NumberOfModels();
|
||||
G4bool isLocked = theParameters->IsPrintLocked();
|
||||
G4bool toBuild = (buildLambdaTable || minKinEnergyPrim < maxKinEnergy);
|
||||
|
||||
G4String num = part.GetParticleName();
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### G4VEmProcess::BuildPhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << num
|
||||
<< " buildLambdaTable= " << buildLambdaTable
|
||||
<< " isTheMaster= " << isTheMaster
|
||||
<< " " << masterProc
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(particle == &part) {
|
||||
|
||||
// worker initialisation
|
||||
if(!isTheMaster) {
|
||||
theLambdaTable = masterProc->LambdaTable();
|
||||
theLambdaTablePrim = masterProc->LambdaTablePrim();
|
||||
if(fXSType == fEmOnePeak) {
|
||||
SetEnergyOfCrossSectionMax(masterProc->EnergyOfCrossSectionMax());
|
||||
}
|
||||
baseMat = masterProc->UseBaseMaterial();
|
||||
|
||||
// local initialisation of models
|
||||
G4bool printing = true;
|
||||
for(G4int i=0; i<numberOfModels; ++i) {
|
||||
G4VEmModel* mod = GetModelByIndex(i, printing);
|
||||
G4VEmModel* mod0= masterProc->GetModelByIndex(i, printing);
|
||||
//G4cout << i << ". " << mod << " " << mod0 << " "
|
||||
// << particle->GetParticleName() << G4endl;
|
||||
mod->SetUseBaseMaterials(baseMat);
|
||||
mod->InitialiseLocal(particle, mod0);
|
||||
}
|
||||
// master thread
|
||||
} else {
|
||||
if(buildLambdaTable || minKinEnergyPrim < maxKinEnergy) {
|
||||
BuildLambdaTable();
|
||||
}
|
||||
if(fXSType == fEmOnePeak) {
|
||||
delete theEnergyOfCrossSectionMax;
|
||||
theEnergyOfCrossSectionMax = nullptr;
|
||||
SetEnergyOfCrossSectionMax(FindLambdaMax());
|
||||
}
|
||||
}
|
||||
}
|
||||
// protection against double printout
|
||||
if(theParameters->IsPrintLocked()) { return; }
|
||||
|
||||
// explicitly defined printout by particle name
|
||||
if(1 < verboseLevel ||
|
||||
(0 < verboseLevel && (num == "gamma" || num == "e-" ||
|
||||
num == "e+" || num == "mu+" ||
|
||||
num == "mu-" || num == "proton"||
|
||||
num == "pi+" || num == "pi-" ||
|
||||
num == "kaon+" || num == "kaon-" ||
|
||||
num == "alpha" || num == "anti_proton" ||
|
||||
num == "GenericIon"|| num == "alpha++" ||
|
||||
num == "alpha+" || num == "helium" ||
|
||||
num == "hydrogen")))
|
||||
{
|
||||
StreamInfo(G4cout, part);
|
||||
}
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### G4VEmProcess::BuildPhysicsTable() done for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << num
|
||||
<< " baseMat=" << baseMat
|
||||
<< G4endl;
|
||||
}
|
||||
G4EmTableUtil::BuildEmProcess(this, masterProc, particle, &part,
|
||||
nModels, verboseLevel, isTheMaster,
|
||||
isLocked, toBuild, baseMat);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VEmProcess::BuildLambdaTable()
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmProcess::BuildLambdaTable() for process "
|
||||
<< GetProcessName() << " and particle "
|
||||
<< particle->GetParticleName() << " " << this
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Access to materials
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
G4LossTableBuilder* bld = lManager->GetTableBuilder();
|
||||
|
||||
G4PhysicsLogVector* aVector = nullptr;
|
||||
G4PhysicsLogVector* aVectorPrim = nullptr;
|
||||
G4PhysicsLogVector* bVectorPrim = nullptr;
|
||||
|
||||
G4double scale = theParameters->MaxKinEnergy()/theParameters->MinKinEnergy();
|
||||
G4int nbin =
|
||||
theParameters->NumberOfBinsPerDecade()*G4lrint(std::log10(scale));
|
||||
scale = G4Log(scale);
|
||||
if(actBinning) { nbin = std::max(nbin, nLambdaBins); }
|
||||
G4double emax1 = std::min(maxKinEnergy, minKinEnergyPrim);
|
||||
|
||||
for(size_t i=0; i<numOfCouples; ++i) {
|
||||
|
||||
if (bld->GetFlag(i)) {
|
||||
|
||||
// create physics vector and fill it
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
|
||||
// build main table
|
||||
if(buildLambdaTable) {
|
||||
delete (*theLambdaTable)[i];
|
||||
|
||||
// if start from zero then change the scale
|
||||
G4double emin = minKinEnergy;
|
||||
G4bool startNull = false;
|
||||
if(startFromNull) {
|
||||
G4double e = MinPrimaryEnergy(particle,couple->GetMaterial());
|
||||
if(e >= emin) {
|
||||
emin = e;
|
||||
startNull = true;
|
||||
}
|
||||
}
|
||||
G4double emax = emax1;
|
||||
if(emax <= emin) { emax = 2*emin; }
|
||||
G4int bin = G4lrint(nbin*G4Log(emax/emin)/scale);
|
||||
if(bin < 3) { bin = 3; }
|
||||
aVector = new G4PhysicsLogVector(emin, emax, bin, splineFlag);
|
||||
modelManager->FillLambdaVector(aVector, couple, startNull);
|
||||
if(splineFlag) { aVector->FillSecondDerivatives(); }
|
||||
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
|
||||
}
|
||||
// build high energy table
|
||||
if(minKinEnergyPrim < maxKinEnergy) {
|
||||
delete (*theLambdaTablePrim)[i];
|
||||
|
||||
// start not from zero and always use spline
|
||||
if(!bVectorPrim) {
|
||||
G4int bin = G4lrint(nbin*G4Log(maxKinEnergy/minKinEnergyPrim)/scale);
|
||||
if(bin < 3) { bin = 3; }
|
||||
aVectorPrim =
|
||||
new G4PhysicsLogVector(minKinEnergyPrim, maxKinEnergy, bin, true);
|
||||
bVectorPrim = aVectorPrim;
|
||||
} else {
|
||||
aVectorPrim = new G4PhysicsLogVector(*bVectorPrim);
|
||||
}
|
||||
modelManager->FillLambdaVector(aVectorPrim, couple, false,
|
||||
fIsCrossSectionPrim);
|
||||
aVectorPrim->FillSecondDerivatives();
|
||||
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTablePrim, i,
|
||||
aVectorPrim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Lambda table is built for "
|
||||
<< particle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
scale = nbin/G4Log(scale);
|
||||
|
||||
G4LossTableBuilder* bld = lManager->GetTableBuilder();
|
||||
G4EmTableUtil::BuildLambdaTable(this, particle, modelManager,
|
||||
bld, theLambdaTable, theLambdaTablePrim,
|
||||
minKinEnergy, minKinEnergyPrim,
|
||||
maxKinEnergy, scale, verboseLevel,
|
||||
startFromNull, splineFlag);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -490,10 +277,8 @@ void G4VEmProcess::StreamInfo(std::ostream& out,
|
||||
out << " BuildTable=" << buildLambdaTable << G4endl;
|
||||
if(buildLambdaTable) {
|
||||
if(particle == &part) {
|
||||
size_t length = theLambdaTable->length();
|
||||
for(size_t i=0; i<length; ++i) {
|
||||
G4PhysicsVector* v = (*theLambdaTable)[i];
|
||||
if(v) {
|
||||
for(auto & v : *theLambdaTable) {
|
||||
if(nullptr != v) {
|
||||
out << " Lambda table from ";
|
||||
G4double emin = v->Energy(0);
|
||||
G4double emax = v->GetMaxEnergy();
|
||||
@@ -514,11 +299,9 @@ void G4VEmProcess::StreamInfo(std::ostream& out,
|
||||
}
|
||||
}
|
||||
if(minKinEnergyPrim < maxKinEnergy) {
|
||||
if(particle == &part) {
|
||||
size_t length = theLambdaTablePrim->length();
|
||||
for(size_t i=0; i<length; ++i) {
|
||||
G4PhysicsVector* v = (*theLambdaTablePrim)[i];
|
||||
if(v) {
|
||||
if(particle == &part) {
|
||||
for(auto & v : *theLambdaTablePrim) {
|
||||
if(nullptr != v) {
|
||||
out << " LambdaPrime table from "
|
||||
<< G4BestUnit(v->Energy(0),"Energy")
|
||||
<< " to "
|
||||
@@ -617,7 +400,7 @@ G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
|
||||
theNumberOfInteractionLengthLeft = -G4Log( G4UniformRand() );
|
||||
theInitialNumberOfInteractionLength = theNumberOfInteractionLengthLeft;
|
||||
|
||||
} else if(currentInteractionLength < DBL_MAX) {
|
||||
} else {
|
||||
|
||||
theNumberOfInteractionLengthLeft -=
|
||||
previousStepSize/currentInteractionLength;
|
||||
@@ -640,7 +423,7 @@ void G4VEmProcess::ComputeIntegralLambda(G4double e, G4double loge)
|
||||
preStepLambda = GetCurrentLambda(e, loge);
|
||||
|
||||
} else if(fXSType == fEmIncreasing) {
|
||||
if(e/lambdaFactor < mfpKinEnergy) {
|
||||
if(e*invLambdaFactor < mfpKinEnergy) {
|
||||
mfpKinEnergy = e;
|
||||
preStepLambda = GetCurrentLambda(e, loge);
|
||||
}
|
||||
@@ -655,7 +438,7 @@ void G4VEmProcess::ComputeIntegralLambda(G4double e, G4double loge)
|
||||
} else if(fXSType == fEmOnePeak) {
|
||||
const G4double epeak = (*theEnergyOfCrossSectionMax)[currentCoupleIndex];
|
||||
if(e <= epeak) {
|
||||
if(e/lambdaFactor < mfpKinEnergy) {
|
||||
if(e*invLambdaFactor < mfpKinEnergy) {
|
||||
mfpKinEnergy = e;
|
||||
preStepLambda = GetCurrentLambda(e, loge);
|
||||
}
|
||||
@@ -675,7 +458,7 @@ void G4VEmProcess::ComputeIntegralLambda(G4double e, G4double loge)
|
||||
G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
// In all cases clear number of interaction lengths
|
||||
// clear number of interaction lengths in any case
|
||||
theNumberOfInteractionLengthLeft = -1.0;
|
||||
mfpKinEnergy = DBL_MAX;
|
||||
|
||||
@@ -685,7 +468,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
|
||||
// should be performed by the AtRestDoIt!
|
||||
if (track.GetTrackStatus() == fStopButAlive) { return &fParticleChange; }
|
||||
|
||||
const G4double finalT = track.GetKineticEnergy();
|
||||
const G4double finalT = track.GetKineticEnergy();
|
||||
|
||||
// forced process - should happen only once per track
|
||||
if(biasFlag) {
|
||||
@@ -701,23 +484,20 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
|
||||
|
||||
// Integral approach
|
||||
if (fXSType != fEmNoIntegral) {
|
||||
const G4double logFinalT = track.GetDynamicParticle()->GetLogKineticEnergy();
|
||||
const G4double logFinalT =
|
||||
track.GetDynamicParticle()->GetLogKineticEnergy();
|
||||
const G4double lx = std::max(GetCurrentLambda(finalT, logFinalT), 0.0);
|
||||
const G4double lg = preStepLambda;
|
||||
if(finalT < mfpKinEnergy) {
|
||||
mfpKinEnergy = finalT;
|
||||
preStepLambda = lx;
|
||||
}
|
||||
#ifdef G4VERBOSE
|
||||
if(lg < lx && 1 < verboseLevel) {
|
||||
if(preStepLambda < lx && 1 < verboseLevel) {
|
||||
G4cout << "WARNING: for " << currentParticle->GetParticleName()
|
||||
<< " and " << GetProcessName()
|
||||
<< " E(MeV)= " << finalT/MeV
|
||||
<< " preLambda= " << lg << " < " << lx << " (postLambda) "
|
||||
<< G4endl;
|
||||
<< " and " << GetProcessName() << " E(MeV)= " << finalT/MeV
|
||||
<< " preLambda= " << preStepLambda
|
||||
<< " < " << lx << " (postLambda) " << G4endl;
|
||||
}
|
||||
#endif
|
||||
if(lg*G4UniformRand() >= lx) {
|
||||
// if false interaction then use new cross section value
|
||||
// if both values are zero - no interaction
|
||||
if(preStepLambda*G4UniformRand() >= lx) {
|
||||
return &fParticleChange;
|
||||
}
|
||||
}
|
||||
@@ -860,127 +640,46 @@ G4bool G4VEmProcess::StorePhysicsTable(const G4ParticleDefinition* part,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4bool yes = true;
|
||||
if(!isTheMaster) { return yes; }
|
||||
|
||||
if ( theLambdaTable && part == particle) {
|
||||
const G4String& nam =
|
||||
GetPhysicsTableFileName(part,directory,"Lambda",ascii);
|
||||
yes = theLambdaTable->StorePhysicsTable(nam,ascii);
|
||||
|
||||
if ( yes ) {
|
||||
if(0 < verboseLevel) G4cout << "Stored: " << nam << G4endl;
|
||||
} else {
|
||||
G4cout << "Fail to store Physics Table for "
|
||||
<< particle->GetParticleName()
|
||||
<< " and process " << GetProcessName()
|
||||
<< " in the directory <" << directory
|
||||
<< "> " << G4endl;
|
||||
}
|
||||
if(!isTheMaster || part != particle) { return true; }
|
||||
if(G4EmTableUtil::StoreTable(this, part, theLambdaTable,
|
||||
directory, "Lambda",
|
||||
verboseLevel, ascii) &&
|
||||
G4EmTableUtil::StoreTable(this, part, theLambdaTablePrim,
|
||||
directory, "LambdaPrim",
|
||||
verboseLevel, ascii)) {
|
||||
return true;
|
||||
}
|
||||
if ( theLambdaTablePrim && part == particle) {
|
||||
const G4String& name =
|
||||
GetPhysicsTableFileName(part,directory,"LambdaPrim",ascii);
|
||||
yes = theLambdaTablePrim->StorePhysicsTable(name,ascii);
|
||||
|
||||
if ( yes ) {
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "Physics table prim is stored for "
|
||||
<< particle->GetParticleName()
|
||||
<< " and process " << GetProcessName()
|
||||
<< " in the directory <" << directory
|
||||
<< "> " << G4endl;
|
||||
}
|
||||
} else {
|
||||
G4cout << "Fail to store Physics Table Prim for "
|
||||
<< particle->GetParticleName()
|
||||
<< " and process " << GetProcessName()
|
||||
<< " in the directory <" << directory
|
||||
<< "> " << G4endl;
|
||||
}
|
||||
}
|
||||
return yes;
|
||||
return false;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4bool G4VEmProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
|
||||
const G4String& directory,
|
||||
const G4String& dir,
|
||||
G4bool ascii)
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4VEmProcess::RetrievePhysicsTable() for "
|
||||
<< part->GetParticleName() << " and process "
|
||||
<< GetProcessName() << G4endl;
|
||||
}
|
||||
if(!isTheMaster || part != particle) { return true; }
|
||||
G4bool yes = true;
|
||||
|
||||
if((!buildLambdaTable && minKinEnergyPrim > maxKinEnergy)
|
||||
|| particle != part) { return yes; }
|
||||
|
||||
const G4String particleName = part->GetParticleName();
|
||||
|
||||
if(buildLambdaTable) {
|
||||
const G4String& filename =
|
||||
GetPhysicsTableFileName(part,directory,"Lambda",ascii);
|
||||
yes = G4PhysicsTableHelper::RetrievePhysicsTable(theLambdaTable,
|
||||
filename,ascii,
|
||||
splineFlag);
|
||||
if ( yes ) {
|
||||
if (0 < verboseLevel) {
|
||||
G4cout << "Lambda table for " << particleName
|
||||
<< " is Retrieved from <"
|
||||
<< filename << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
if(splineFlag) {
|
||||
for(auto & v : *theLambdaTable) {
|
||||
if(nullptr != v) { v->FillSecondDerivatives(); }
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (1 < verboseLevel) {
|
||||
G4cout << "Lambda table for " << particleName << " in file <"
|
||||
<< filename << "> is not exist"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
yes = G4EmTableUtil::RetrieveTable(this, part, theLambdaTable, dir,
|
||||
"Lambda", verboseLevel,
|
||||
ascii, splineFlag);
|
||||
}
|
||||
if(minKinEnergyPrim < maxKinEnergy) {
|
||||
const G4String& filename =
|
||||
GetPhysicsTableFileName(part,directory,"LambdaPrim",ascii);
|
||||
yes = G4PhysicsTableHelper::RetrievePhysicsTable(theLambdaTablePrim,
|
||||
filename,ascii,true);
|
||||
if ( yes ) {
|
||||
if (0 < verboseLevel) {
|
||||
G4cout << "Lambda table prim for " << particleName
|
||||
<< " is Retrieved from <"
|
||||
<< filename << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
for(auto & v : *theLambdaTablePrim) {
|
||||
if(nullptr != v) { v->FillSecondDerivatives(); }
|
||||
}
|
||||
} else {
|
||||
if (1 < verboseLevel) {
|
||||
G4cout << "Lambda table prim for " << particleName << " in file <"
|
||||
<< filename << "> is not exist"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
if(yes && minKinEnergyPrim < maxKinEnergy) {
|
||||
yes = G4EmTableUtil::RetrieveTable(this, part, theLambdaTablePrim, dir,
|
||||
"LambdaPrim", verboseLevel,
|
||||
ascii, splineFlag);
|
||||
}
|
||||
return yes;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VEmProcess::CrossSectionPerVolume(G4double kinEnergy,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4double)
|
||||
G4double G4VEmProcess::GetCrossSection(G4double kinEnergy,
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
G4double cross = RecalculateLambda(kinEnergy, couple);
|
||||
return std::max(cross, 0.0);
|
||||
CurrentSetup(couple, kinEnergy);
|
||||
return GetCurrentLambda(kinEnergy, G4Log(kinEnergy));
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -995,17 +694,6 @@ G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VEmProcess::MeanFreePath(const G4Track& track)
|
||||
{
|
||||
const G4double kinEnergy = track.GetKineticEnergy();
|
||||
CurrentSetup(track.GetMaterialCutsCouple(), kinEnergy);
|
||||
const G4double xs = GetCurrentLambda(kinEnergy,
|
||||
track.GetDynamicParticle()->GetLogKineticEnergy());
|
||||
return (0.0 < xs) ? 1.0/xs : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4VEmProcess::ComputeCrossSectionPerAtom(G4double kinEnergy,
|
||||
G4double Z, G4double A, G4double cut)
|
||||
@@ -1018,78 +706,6 @@ G4VEmProcess::ComputeCrossSectionPerAtom(G4double kinEnergy,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
std::vector<G4double>* G4VEmProcess::FindLambdaMax()
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### G4VEmProcess::FindLambdaMax: "
|
||||
<< particle->GetParticleName()
|
||||
<< " and process " << GetProcessName() << " " << G4endl;
|
||||
}
|
||||
std::vector<G4double>* ptr = nullptr;
|
||||
if(fXSType != fEmOnePeak) { return ptr; }
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t n = theCoupleTable->GetTableSize();
|
||||
ptr = new std::vector<G4double>;
|
||||
ptr->resize(n, DBL_MAX);
|
||||
|
||||
G4bool isPeak = false;
|
||||
const G4double g4log10 = G4Log(10.);
|
||||
const G4double scale = theParameters->NumberOfBinsPerDecade()/g4log10;
|
||||
|
||||
for(size_t i=0; i<n; ++i) {
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
G4double emin = std::max(minKinEnergy, MinPrimaryEnergy(particle, couple->GetMaterial()));
|
||||
G4double emax = std::max(maxKinEnergy, emin + emin);
|
||||
G4double ee = G4Log(emax/emin);
|
||||
G4int nbin = G4lrint(ee*scale);
|
||||
if(nbin < 4) { nbin = 4; }
|
||||
G4double x = G4Exp(ee/nbin);
|
||||
G4double sm = 0.0;
|
||||
G4double em = emin;
|
||||
G4double e = emin;
|
||||
for(G4int j=0; j<=nbin; ++j) {
|
||||
G4double sig = RecalculateLambda(e, couple);
|
||||
//G4cout << j << " E=" << e << " Lambda=" << sig << G4endl;
|
||||
if(sig >= sm) {
|
||||
em = e;
|
||||
sm = sig;
|
||||
e *= x;
|
||||
} else {
|
||||
isPeak = true;
|
||||
(*ptr)[i] = em;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << " " << i << ". Epeak(GeV)=" << em/GeV
|
||||
<< " SigmaMax(1/mm)=" << sm
|
||||
<< " Emin(GeV)=" << emin/GeV << " Emax(GeV)=" << emax/GeV
|
||||
<< " " << couple->GetMaterial()->GetName() << G4endl;
|
||||
}
|
||||
}
|
||||
// there is no peak for any material
|
||||
if(!isPeak) {
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VEmProcess::SetEnergyOfCrossSectionMax(std::vector<G4double>* ptr)
|
||||
{
|
||||
if(nullptr == ptr) {
|
||||
fXSType = fEmIncreasing;
|
||||
} else {
|
||||
theEnergyOfCrossSectionMax = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4PhysicsVector*
|
||||
G4VEmProcess::LambdaPhysicsVector(const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
@@ -1103,7 +719,24 @@ G4VEmProcess::LambdaPhysicsVector(const G4MaterialCutsCouple* couple)
|
||||
|
||||
const G4Element* G4VEmProcess::GetCurrentElement() const
|
||||
{
|
||||
return (nullptr != currentModel) ? currentModel->GetCurrentElement() : nullptr;
|
||||
return (nullptr != currentModel) ?
|
||||
currentModel->GetCurrentElement(currentMaterial) : nullptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4Element* G4VEmProcess::GetTargetElement() const
|
||||
{
|
||||
return (nullptr != currentModel) ?
|
||||
currentModel->GetCurrentElement(currentMaterial) : nullptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4Isotope* G4VEmProcess::GetTargetIsotope() const
|
||||
{
|
||||
return (nullptr != currentModel) ?
|
||||
currentModel->GetCurrentIsotope(GetCurrentElement()) : nullptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -1224,15 +857,6 @@ G4VEmProcess* G4VEmProcess::GetEmProcess(const G4String& nam)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4VEmProcess::GetLambda(G4double kinEnergy, const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
CurrentSetup(couple, kinEnergy);
|
||||
return GetCurrentLambda(kinEnergy, G4Log(kinEnergy));
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VEmProcess::PolarAngleLimit() const
|
||||
{
|
||||
return theParameters->MscThetaLimit();
|
||||
@@ -1256,7 +880,7 @@ void G4VEmProcess::PrintWarning(G4String tit, G4double val)
|
||||
|
||||
void G4VEmProcess::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
if(particle) {
|
||||
if(nullptr != particle) {
|
||||
StreamInfo(out, *particle, true);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -69,8 +69,7 @@ G4VMscModel::G4VMscModel(const G4String& nam):
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VMscModel::~G4VMscModel()
|
||||
{}
|
||||
G4VMscModel::~G4VMscModel() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
#include "G4ProcessVector.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4LossTableBuilder.hh"
|
||||
#include "G4EmTableUtil.hh"
|
||||
#include <iostream>
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -93,7 +94,7 @@ G4VMultipleScattering::G4VMultipleScattering(const G4String&, G4ProcessType)
|
||||
|
||||
lowestKinEnergy = 10*CLHEP::eV;
|
||||
|
||||
geomMin = 0.05*CLHEP::nm;
|
||||
geomMin = 0.05*CLHEP::nm;
|
||||
minDisplacement2 = geomMin*geomMin;
|
||||
|
||||
pParticleChange = &fParticleChange;
|
||||
@@ -114,7 +115,7 @@ G4VMultipleScattering::~G4VMultipleScattering()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VMultipleScattering::AddEmModel(G4int order, G4VEmModel* ptr,
|
||||
void G4VMultipleScattering::AddEmModel(G4int order, G4VMscModel* ptr,
|
||||
const G4Region* region)
|
||||
{
|
||||
if(nullptr == ptr) { return; }
|
||||
@@ -139,76 +140,22 @@ void G4VMultipleScattering::SetEmModel(G4VMscModel* ptr, G4int)
|
||||
void
|
||||
G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part)
|
||||
{
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
G4bool master = emManager->IsMaster();
|
||||
|
||||
if(nullptr == firstParticle) { firstParticle = ∂ }
|
||||
if(part.GetPDGMass() > CLHEP::GeV) {
|
||||
// flag declears that mass scaling is applied
|
||||
isIon = true;
|
||||
}
|
||||
|
||||
emManager->PreparePhysicsTable(&part, this, master);
|
||||
currParticle = nullptr;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< " local particle " << firstParticle->GetParticleName()
|
||||
<< " isIon: " << isIon << " isMaster: " << master
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(firstParticle == &part) {
|
||||
baseMat = emManager->GetTableBuilder()->GetBaseMaterialFlag();
|
||||
|
||||
// initialise process
|
||||
InitialiseProcess(firstParticle);
|
||||
G4EmTableUtil::PrepareMscProcess(this, part, modelManager,
|
||||
stepLimit, facrange,
|
||||
latDisplacement, master,
|
||||
isIon, baseMat);
|
||||
|
||||
// heavy particles
|
||||
if(part.GetPDGMass() > CLHEP::MeV) {
|
||||
stepLimit = theParameters->MscMuHadStepLimitType();
|
||||
facrange = theParameters->MscMuHadRangeFactor();
|
||||
latDisplacement = theParameters->MuHadLateralDisplacement();
|
||||
} else {
|
||||
stepLimit = theParameters->MscStepLimitType();
|
||||
facrange = theParameters->MscRangeFactor();
|
||||
latDisplacement = theParameters->LateralDisplacement();
|
||||
}
|
||||
if(master) { SetVerboseLevel(theParameters->Verbose()); }
|
||||
else { SetVerboseLevel(theParameters->WorkerVerbose()); }
|
||||
|
||||
// initialisation of models
|
||||
numberOfModels = modelManager->NumberOfModels();
|
||||
/*
|
||||
std::cout << "### G4VMultipleScattering::PreparePhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< " Nmodels= " << mscModels.size() << " " << this << std::endl;
|
||||
*/
|
||||
G4LossTableBuilder* bld = emManager->GetTableBuilder();
|
||||
baseMat = bld->GetBaseMaterialFlag();
|
||||
|
||||
for(G4int i=0; i<numberOfModels; ++i) {
|
||||
G4VMscModel* msc = GetModelByIndex(i);
|
||||
if(nullptr == msc) { continue; }
|
||||
if(nullptr == currentModel) { currentModel = msc; }
|
||||
msc->SetIonisation(nullptr, firstParticle);
|
||||
msc->SetMasterThread(master);
|
||||
msc->SetPolarAngleLimit(theParameters->MscThetaLimit());
|
||||
G4double emax =
|
||||
std::min(msc->HighEnergyLimit(),theParameters->MaxKinEnergy());
|
||||
msc->SetHighEnergyLimit(emax);
|
||||
msc->SetUseBaseMaterials(baseMat);
|
||||
}
|
||||
|
||||
modelManager->Initialise(firstParticle, G4Electron::Electron(),
|
||||
1.0, verboseLevel);
|
||||
currentModel = GetModelByIndex(0);
|
||||
|
||||
if(nullptr == safetyHelper) {
|
||||
safetyHelper = G4TransportationManager::GetTransportationManager()
|
||||
@@ -222,66 +169,18 @@ G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part)
|
||||
|
||||
void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
{
|
||||
const G4String& num = part.GetParticleName();
|
||||
G4bool master = emManager->IsMaster();
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << num << " isIon: " << isIon
|
||||
<< " IsMaster: " << master << G4endl;
|
||||
}
|
||||
const G4VMultipleScattering* masterProcess =
|
||||
static_cast<const G4VMultipleScattering*>(GetMasterProcess());
|
||||
|
||||
if(firstParticle == &part) {
|
||||
/*
|
||||
std::cout << "### G4VMultipleScattering::BuildPhysicsTable() for "
|
||||
<< GetProcessName() << " and particle " << num
|
||||
<< " IsMaster= " << G4LossTableManager::Instance()->IsMaster()
|
||||
<< " " << this << std::endl;
|
||||
*/
|
||||
emManager->BuildPhysicsTable(firstParticle);
|
||||
|
||||
if(!master) {
|
||||
// initialisation of models
|
||||
/*
|
||||
std::cout << "### G4VMultipleScattering::BuildPhysicsTable() for "
|
||||
<< GetProcessName() << " and particle " << num
|
||||
<< " Nmod= " << mscModels.size() << " NOT master" << std::endl;
|
||||
*/
|
||||
baseMat = masterProcess->UseBaseMaterial();
|
||||
for(G4int i=0; i<numberOfModels; ++i) {
|
||||
G4VMscModel* msc = GetModelByIndex(i);
|
||||
if(nullptr == msc) { continue; }
|
||||
G4VMscModel* msc0 = masterProcess->GetModelByIndex(i);
|
||||
msc->SetUseBaseMaterials(baseMat);
|
||||
msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false);
|
||||
msc->InitialiseLocal(firstParticle, msc0);
|
||||
}
|
||||
}
|
||||
}
|
||||
// protection against double printout
|
||||
if(theParameters->IsPrintLocked()) { return; }
|
||||
|
||||
// explicitly defined printout by particle name
|
||||
if(1 < verboseLevel ||
|
||||
(0 < verboseLevel && (num == "e-" ||
|
||||
num == "e+" || num == "mu+" ||
|
||||
num == "mu-" || num == "proton"||
|
||||
num == "pi+" || num == "pi-" ||
|
||||
num == "kaon+" || num == "kaon-" ||
|
||||
num == "alpha" || num == "anti_proton" ||
|
||||
num == "GenericIon" || num == "alpha+" ||
|
||||
num == "alpha++" )))
|
||||
{
|
||||
StreamInfo(G4cout, part);
|
||||
}
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### G4VMultipleScattering::BuildPhysicsTable() done for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << num << G4endl;
|
||||
const G4VMultipleScattering* ptr = this;
|
||||
if(!master) {
|
||||
ptr = static_cast<const G4VMultipleScattering*>(GetMasterProcess());
|
||||
}
|
||||
|
||||
G4EmTableUtil::BuildMscProcess(this, ptr, part, firstParticle,
|
||||
numberOfModels, master);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -306,22 +205,8 @@ void G4VMultipleScattering::StartTracking(G4Track* track)
|
||||
fIonisation = emManager->GetEnergyLossProcess(currParticle);
|
||||
eloss = fIonisation;
|
||||
}
|
||||
/*
|
||||
G4cout << "G4VMultipleScattering::StartTracking Nmod= " << numberOfModels
|
||||
<< " " << currParticle->GetParticleName()
|
||||
<< " E(MeV)= " << track->GetKineticEnergy()
|
||||
<< " Ion= " << fIonisation << " IsMaster= "
|
||||
<< G4LossTableManager::Instance()->IsMaster()
|
||||
<< G4endl;
|
||||
*/
|
||||
for(G4int i=0; i<numberOfModels; ++i) {
|
||||
G4VMscModel* msc = GetModelByIndex(i);
|
||||
/*
|
||||
G4cout << "Next model " << msc
|
||||
<< " Emin= " << msc->LowEnergyLimit()
|
||||
<< " Emax= " << msc->HighEnergyLimit()
|
||||
<< " Eact= " << msc->LowEnergyActivationLimit() << G4endl;
|
||||
*/
|
||||
msc->StartTracking(track);
|
||||
if(nullptr != eloss) {
|
||||
msc->SetIonisation(eloss, currParticle);
|
||||
@@ -355,9 +240,10 @@ G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
|
||||
}
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
|
||||
// select new model
|
||||
// select new model, static cast is possible in this class
|
||||
if(1 < numberOfModels) {
|
||||
currentModel = static_cast<G4VMscModel*>(SelectModel(ekin,couple->GetIndex()));
|
||||
currentModel =
|
||||
static_cast<G4VMscModel*>(SelectModel(ekin,couple->GetIndex()));
|
||||
}
|
||||
currentModel->SetCurrentCouple(couple);
|
||||
// msc is active is model is active, energy above the limit,
|
||||
@@ -371,7 +257,10 @@ G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
|
||||
if (tPathLength < physStepLimit) {
|
||||
*selection = CandidateForSelection;
|
||||
}
|
||||
} else { isActive = false; }
|
||||
} else {
|
||||
isActive = false;
|
||||
gPathLength = DBL_MAX;
|
||||
}
|
||||
|
||||
//if(currParticle->GetPDGMass() > GeV)
|
||||
/*
|
||||
@@ -537,41 +426,11 @@ G4VMultipleScattering::StorePhysicsTable(const G4ParticleDefinition* part,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4bool yes = true;
|
||||
if(part != firstParticle) { return yes; }
|
||||
const G4VMultipleScattering* masterProcess =
|
||||
static_cast<const G4VMultipleScattering*>(GetMasterProcess());
|
||||
if(nullptr != masterProcess && masterProcess != this) { return yes; }
|
||||
if(part != firstParticle || !emManager->IsMaster()) { return yes; }
|
||||
|
||||
G4int nmod = modelManager->NumberOfModels();
|
||||
static const G4String ss[4] = {"1","2","3","4"};
|
||||
for(G4int i=0; i<nmod; ++i) {
|
||||
G4VEmModel* msc = modelManager->GetModel(i);
|
||||
if(nullptr == msc) { continue; }
|
||||
yes = true;
|
||||
G4PhysicsTable* table = msc->GetCrossSectionTable();
|
||||
if (nullptr != table) {
|
||||
G4int j = std::min(i,3);
|
||||
G4String name =
|
||||
GetPhysicsTableFileName(part,directory,"LambdaMod"+ss[j],ascii);
|
||||
yes = table->StorePhysicsTable(name,ascii);
|
||||
|
||||
if ( yes ) {
|
||||
if ( verboseLevel>0 ) {
|
||||
G4cout << "Physics table are stored for "
|
||||
<< part->GetParticleName()
|
||||
<< " and process " << GetProcessName()
|
||||
<< " with a name <" << name << "> " << G4endl;
|
||||
}
|
||||
} else {
|
||||
G4cout << "Fail to store Physics Table for "
|
||||
<< part->GetParticleName()
|
||||
<< " and process " << GetProcessName()
|
||||
<< " in the directory <" << directory
|
||||
<< "> " << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return yes;
|
||||
return G4EmTableUtil::StoreMscTable(this, part, directory,
|
||||
numberOfModels, verboseLevel,
|
||||
ascii);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -586,18 +445,9 @@ G4VMultipleScattering::RetrievePhysicsTable(const G4ParticleDefinition*,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VMultipleScattering::SetIonisation(G4VEnergyLossProcess* p)
|
||||
{
|
||||
for(auto & msc : mscModels) {
|
||||
if(nullptr != msc) { msc->SetIonisation(p, firstParticle); }
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VMultipleScattering::ProcessDescription(std::ostream& outFile) const
|
||||
{
|
||||
if(firstParticle) {
|
||||
if(nullptr != firstParticle) {
|
||||
StreamInfo(outFile, *firstParticle, true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user