Import Geant4 11.3.0.beta source tree
This commit is contained in:
@@ -6,15 +6,82 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-05-11 Gabriele Cosmo (emdna-V11-01-26)
|
||||
## 2024-05-23 Hoang Tran (emdna-V11-02-12)
|
||||
- Delete enum unused due to te use of EmParameters
|
||||
to control chemistry models in G4EmDNAChemistry_option3.
|
||||
|
||||
## 2024-05-11 Gabriele Cosmo (emdna-V11-02-11)
|
||||
- Fixed compilation error on macOS/clang with C++23 enabled, for the use
|
||||
of std::function in G4OctreeFinder.
|
||||
|
||||
## 2024-04-19 Gabriele Cosmo
|
||||
## 2024-05-06 Gabriele Cosmo (emdna-V11-02-10)
|
||||
- Fixed compilation warning on macOS/XCode for implicit type conversion
|
||||
in G4DNADoubleIonisationModel and G4DNAMultipleIonisationManager.
|
||||
|
||||
## 2024-04-25 Hoang Tran (emdna-V11-02-09)
|
||||
- Delete DelayLists at the end of chemistry stage
|
||||
- clean the G4Scheduler
|
||||
|
||||
## 2024-04-24 W.G.Shin (emdna-V11-02-08)
|
||||
- G4DNAELSEPAElasticModel
|
||||
- Modified to be compatible with density scaling
|
||||
|
||||
## 2024-04-19 Gabriele Cosmo (emdna-V11-02-07)
|
||||
- Fixed compilation error on Windows VC++ with C++20 Standard enabled.
|
||||
Added missing declarations for TG4MoleculeShoot specialisations on G4Track.
|
||||
Based on [GitHub PR#69](https://github.com/Geant4/geant4/pull/69).
|
||||
|
||||
## 2024-04-18 Hoang Tran (emdna-V11-02-06)
|
||||
- debug invalid KDTree node.
|
||||
|
||||
## 2024-04-15 Vladimir Ivanchenko (emdna-V11-02-05)
|
||||
- G4GeneralIonIonisationModel, G4DNAIonChargeIncreaseModel,
|
||||
G4DNAIonChargeDecreaseModel - new classes implementing general models for
|
||||
ions heavier than Helium
|
||||
- G4DNAChargeDecrease, G4DNAChargeIncrease - removed obsolete definition of
|
||||
min/max model energy inside processes class, code clean-up
|
||||
- G4DNARuddIonisationExtendedModel - updated initialisation to allow be called
|
||||
from the general model
|
||||
- source.cmake in models sub-directory become using alphabetical order for
|
||||
both .hh and .cc files
|
||||
|
||||
## 2024-04-10 Shogo Okada (emdna-V11-02-04)
|
||||
- G4DNAElectronHoleRecombination
|
||||
- Changed the branch condition in FindReactant() to select only H2O+ ions
|
||||
involved in electron-hole recombination
|
||||
- G4DNAWaterDissociationDisplacer
|
||||
- Added dissociative decay channels for multiple-ionized water ions
|
||||
- G4DNAMultipleIonisationManager
|
||||
- New class focusing on generation of multiple-ionized water ions and
|
||||
calculation of scale parameter to compute cross-section of each
|
||||
multiple-ionization process
|
||||
- G4DNADoubleIonisation
|
||||
- G4DNATripleIonisation
|
||||
- G4DNAQuadrupleIonisation
|
||||
- New process classes for multiple-ionization
|
||||
- G4DNADoubleIonisationModel
|
||||
- G4DNATripleIonisationModel
|
||||
- G4DNAQuadrupleIonisationModel
|
||||
- New model classes related to multiple-ionization
|
||||
|
||||
## 2024-04-05 Vladimir Ivanchenko (emdna-V11-02-03)
|
||||
- G4DNARuddIonisationExtendedModel - updated model: do not use autolock but
|
||||
uppload data in the class constructor once in all threads, use
|
||||
effective charge approach for all ions with Z > 2 (in order to have more
|
||||
correct computation of stopping power and ranges), precompute internal
|
||||
variables before sampling, optimized algorithm of sampling (at 10 MeV it
|
||||
becomes ~10 times faster), removed unused parameters.
|
||||
|
||||
## 2024-02-29 Hoang Tran (emdna-V11-02-02)
|
||||
- correct verbose conditions for warning in IRT-syn model
|
||||
|
||||
## 2024-02-24 Hoang Tran (emdna-V11-02-01)
|
||||
- Optimize IRT-syn at 1 ps for high LET applications
|
||||
|
||||
## 2023-12-15 Vladimir Ivanchenko (emdna-V11-02-00)
|
||||
- G4DNABornAngle - fixed numerical problem: added protection for cosTheta;
|
||||
use relativistic formula for max energy transfer to delta-electron
|
||||
|
||||
## 2023-11-14 Ben Morgan (emdna-V11-01-25)
|
||||
- Use G4FindDataDir to access data libraries in place of raw `getenv`.
|
||||
|
||||
@@ -115,10 +182,10 @@ G4DNAPTBExcitationStructure) - PTB models
|
||||
|
||||
## 2022-11-24 Vladimir Ivanchenko (emdna-V11-00-39)
|
||||
- G4DNARuddIonisationExtendedModel - fixed common work between DNA physics and
|
||||
radioactive decay module - before this update test2.in macro crash, because
|
||||
radioactive decay module - before this update test2.in macro crash, because
|
||||
only 5 ions have data needed for this model; with this modification of the
|
||||
model scaling relation to the carbon ion is used for any ion, which has
|
||||
no data; low-energy limit is used now more correctly - all ions are stopped
|
||||
no data; low-energy limit is used now more correctly - all ions are stopped
|
||||
but not killed, because they may have radioactive decay at rest; all commented
|
||||
lines are removed from the class
|
||||
|
||||
@@ -132,7 +199,7 @@ G4DNAPTBExcitationStructure) - PTB models
|
||||
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
|
||||
|
||||
## 2022-11-08 Vladimir Ivanchenko (emdna-V11-00-35)
|
||||
- G4DNAUeharaScreenedRutherfordElasticModel - code cleanup; introduced
|
||||
- G4DNAUeharaScreenedRutherfordElasticModel - code cleanup; introduced
|
||||
low and high energy limit for the model; removed missleading G4Exception
|
||||
|
||||
## 2022-11-01 Hoang Tran (emdna-V11-00-34)
|
||||
@@ -180,9 +247,9 @@ G4DNARPWBAExcitationModel
|
||||
errors on NVHPC compiler.
|
||||
|
||||
## 2022-08-30 Vladimir Ivanchenko (emdna-V11-00-24)
|
||||
- G4DNAExcitation, G4DNAVibExcitation, G4DNARotExcitation - class
|
||||
- G4DNAExcitation, G4DNAVibExcitation, G4DNARotExcitation - class
|
||||
cleanup according to the recent G4VEmProcess base class; model
|
||||
headers are moved to source; C++11 keywards are introduced.
|
||||
headers are moved to source; C++11 keywards are introduced.
|
||||
|
||||
## 2022-06-21 Igor Semeniouk (emdna-V11-00-23)
|
||||
- G4DNABornIonisationModel1.cc, G4DNACPA100ElasticModel.cc,
|
||||
@@ -225,7 +292,7 @@ G4DNARPWBAExcitationModel
|
||||
- add fResetScavenger in G4SchedulerMessenger
|
||||
|
||||
## 2022-04-14 Paolo Dondero (emdna-V11-00-13)
|
||||
- save local instances for recurrent access to particle definition in
|
||||
- save local instances for recurrent access to particle definition in
|
||||
G4DNAMillerGreenExcitationModel, G4DNARuddIonisationExtendedModel and
|
||||
G4DNARuddIonisationModel
|
||||
- use G4Pow and G4Log instead of std::pow and std::log
|
||||
@@ -238,7 +305,7 @@ G4DNARPWBAExcitationModel
|
||||
- Delete G4ITFinder.cc
|
||||
|
||||
## 2022-04-04 Paolo Dondero (emdna-V11-00-11)
|
||||
- save local instances for recurrent access to particle definition in
|
||||
- save local instances for recurrent access to particle definition in
|
||||
G4DNADingfelderChargeDecreaseModel and G4DNADingfelderChargeIncreaseModel
|
||||
- use G4Pow and G4Log instead of std::pow and std::log
|
||||
|
||||
@@ -309,18 +376,18 @@ warning in G4DNAMolecularDissociation::DecayIt()
|
||||
|
||||
23-09-2021, A. Ribon, emdna-V10-07-12
|
||||
- G4ITTransportation, G4DNAElastic, G4DNAExcitation, G4DNAIonisation,
|
||||
G4DNAVibExcitation, G4DNAAttachment, G4DNAChargeDecrease,
|
||||
G4DNAVibExcitation, G4DNAAttachment, G4DNAChargeDecrease,
|
||||
G4DNAChargeIncrease, G4DNAElectronSolvation, G4DNAMolecularDissociation,
|
||||
G4DNASecondOrderReaction, G4DNAElectronHoleRecombination,
|
||||
G4DNABrownianTransportation : replaced hardwired process-sub-types
|
||||
with enum values introduced in the new class G4LowEnergyEmProcessSubType
|
||||
|
||||
18-07-2021, V. Ivanchenko, emdna-V10-07-11
|
||||
- G4DNABohrExcitationModel2, G4DNABohrIonisationModel2,
|
||||
- G4DNABohrExcitationModel2, G4DNABohrIonisationModel2,
|
||||
G4VLEPSModel - updated interfaces to G4PhysicsVector
|
||||
|
||||
16-07-2021, D. Sakata, emdna-V10-07-10
|
||||
- Fixed initialization error in G4DNAELSEPAElasticModel
|
||||
- Fixed initialization error in G4DNAELSEPAElasticModel
|
||||
|
||||
28-06-2021, G. Cosmo, emdna-V10-07-09
|
||||
- Fixed compilation error in G4ITMultiNavigator when compiling with c++20
|
||||
|
||||
@@ -76,7 +76,7 @@ template<typename Position>
|
||||
G4KDNode_Base* aParent = nullptr;
|
||||
G4KDNode_Base* next = this;
|
||||
G4int split = -1;
|
||||
while(next)
|
||||
while(next != nullptr && next->IsValid())
|
||||
{
|
||||
split = (G4int)next->fAxis;
|
||||
aParent = next;
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
// We would be very happy hearing from you, send us your feedback! :)
|
||||
//
|
||||
// In order for Geant4-DNA to be maintained and still open-source,
|
||||
// article citations are crucial.
|
||||
// If you use Geant4-DNA chemistry and you publish papers about your software,
|
||||
// article citations are crucial.
|
||||
// If you use Geant4-DNA chemistry and you publish papers about your software,
|
||||
// in addition to the general paper on Geant4-DNA:
|
||||
//
|
||||
// Int. J. Model. Simul. Sci. Comput. 1 (2010) 157–178
|
||||
@@ -41,26 +41,24 @@
|
||||
// reference papers on chemistry:
|
||||
//
|
||||
// J. Comput. Phys. 274 (2014) 841-882
|
||||
// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
|
||||
|
||||
|
||||
// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
|
||||
|
||||
#ifndef G4Scheduler_h
|
||||
#define G4Scheduler_h
|
||||
|
||||
#include <G4VScheduler.hh>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
#include "G4ITModelHandler.hh"
|
||||
#include "G4ITReaction.hh"
|
||||
#include "G4ITStepStatus.hh"
|
||||
#include "G4ITTrackHolder.hh"
|
||||
#include "G4VStateDependent.hh"
|
||||
#include "G4ITReaction.hh"
|
||||
#include "G4VScavengerMaterial.hh"
|
||||
#include "G4VStateDependent.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include <G4VScheduler.hh>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class G4ITTrackingManager;
|
||||
class G4ITModelProcessor;
|
||||
@@ -72,226 +70,211 @@ class G4ITTrackingInteractivity;
|
||||
class G4ITGun;
|
||||
|
||||
#ifndef compTrackPerID__
|
||||
#define compTrackPerID__
|
||||
struct compTrackPerID
|
||||
{
|
||||
# define compTrackPerID__
|
||||
struct compTrackPerID
|
||||
{
|
||||
G4bool operator()(G4Track* rhs, G4Track* lhs) const
|
||||
{
|
||||
return rhs->GetTrackID() < lhs->GetTrackID();
|
||||
}
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* G4Scheduler synchronizes (in time) track stepping
|
||||
*/
|
||||
class G4Scheduler :
|
||||
public G4VScheduler,
|
||||
public G4VStateDependent
|
||||
class G4Scheduler : public G4VScheduler, public G4VStateDependent
|
||||
{
|
||||
protected:
|
||||
~G4Scheduler() override;
|
||||
protected:
|
||||
~G4Scheduler() override;
|
||||
|
||||
public:
|
||||
G4Scheduler(const G4Scheduler&) = delete;
|
||||
G4Scheduler& operator=(const G4Scheduler&) = delete;
|
||||
public:
|
||||
G4Scheduler(const G4Scheduler&) = delete;
|
||||
G4Scheduler& operator=(const G4Scheduler&) = delete;
|
||||
|
||||
static G4Scheduler* Instance();
|
||||
/** DeleteInstance should be used instead
|
||||
* of the destructor
|
||||
*/
|
||||
static void DeleteInstance();
|
||||
G4bool Notify(G4ApplicationState requestedState) override;
|
||||
static G4Scheduler* Instance();
|
||||
/** DeleteInstance should be used instead
|
||||
* of the destructor
|
||||
*/
|
||||
static void DeleteInstance();
|
||||
G4bool Notify(G4ApplicationState requestedState) override;
|
||||
|
||||
void RegisterModel(G4VITStepModel*, G4double) override;
|
||||
void RegisterModel(G4VITStepModel*, G4double) override;
|
||||
|
||||
void Initialize() override;
|
||||
void ForceReinitialization();
|
||||
inline G4bool IsInitialized();
|
||||
inline G4bool IsRunning() override{return fRunning;}
|
||||
void Reset() override;
|
||||
void Process() override;
|
||||
void ClearList();
|
||||
void Initialize() override;
|
||||
void ForceReinitialization();
|
||||
inline G4bool IsInitialized();
|
||||
inline G4bool IsRunning() override { return fRunning; }
|
||||
void Reset() override;
|
||||
void Process() override;
|
||||
void ClearList();
|
||||
|
||||
inline void SetGun(G4ITGun*) override;
|
||||
inline G4ITGun* GetGun();
|
||||
inline void SetGun(G4ITGun*) override;
|
||||
inline G4ITGun* GetGun();
|
||||
|
||||
inline void Stop();
|
||||
void Clear();
|
||||
inline void Stop();
|
||||
void Clear();
|
||||
|
||||
// To be called only in UserReactionAction::EndProcessing()
|
||||
// after fRunning flag has been turned off.
|
||||
// This is not done automatically before UserReactionAction::EndProcessing()
|
||||
// is called in case one would like to access some track information
|
||||
void EndTracking();
|
||||
// To be called only in UserReactionAction::EndProcessing()
|
||||
// after fRunning flag has been turned off.
|
||||
// This is not done automatically before UserReactionAction::EndProcessing()
|
||||
// is called in case one would like to access some track information
|
||||
void EndTracking();
|
||||
|
||||
void SetEndTime(const G4double) override;
|
||||
void SetEndTime(const G4double) override;
|
||||
|
||||
/* Two tracks below the time tolerance are supposed to be
|
||||
* in the same time slice
|
||||
*/
|
||||
inline void SetTimeTolerance(G4double) override;
|
||||
inline G4double GetTimeTolerance() const override;
|
||||
/* Two tracks below the time tolerance are supposed to be
|
||||
* in the same time slice
|
||||
*/
|
||||
inline void SetTimeTolerance(G4double) override;
|
||||
inline G4double GetTimeTolerance() const override;
|
||||
|
||||
inline void SetMaxZeroTimeAllowed(G4int) override;
|
||||
inline G4int GetMaxZeroTimeAllowed() const override;
|
||||
inline void SetMaxZeroTimeAllowed(G4int) override;
|
||||
inline G4int GetMaxZeroTimeAllowed() const override;
|
||||
|
||||
inline G4ITModelHandler* GetModelHandler() override;
|
||||
inline G4ITModelHandler* GetModelHandler() override;
|
||||
|
||||
inline void SetTimeSteps(std::map<G4double, G4double>*) override;
|
||||
inline void AddTimeStep(G4double, G4double) override;
|
||||
inline void SetDefaultTimeStep(G4double) override;
|
||||
G4double GetLimitingTimeStep() const override;
|
||||
inline G4int GetNbSteps() const override;
|
||||
inline void SetMaxNbSteps(G4int) override;
|
||||
inline G4int GetMaxNbSteps() const override;
|
||||
inline G4double GetStartTime() const override;
|
||||
inline G4double GetEndTime() const override;
|
||||
inline G4double GetTimeStep() const override;
|
||||
inline G4double GetPreviousTimeStep() const override;
|
||||
inline G4double GetGlobalTime() const override;
|
||||
inline void SetUserAction(G4UserTimeStepAction*) override;
|
||||
inline G4UserTimeStepAction* GetUserTimeStepAction() const override;
|
||||
inline void SetTimeSteps(std::map<G4double, G4double>*) override;
|
||||
inline void AddTimeStep(G4double, G4double) override;
|
||||
inline void SetDefaultTimeStep(G4double) override;
|
||||
G4double GetLimitingTimeStep() const override;
|
||||
inline G4int GetNbSteps() const override;
|
||||
inline void SetMaxNbSteps(G4int) override;
|
||||
inline G4int GetMaxNbSteps() const override;
|
||||
inline G4double GetStartTime() const override;
|
||||
inline G4double GetEndTime() const override;
|
||||
inline G4double GetTimeStep() const override;
|
||||
inline G4double GetPreviousTimeStep() const override;
|
||||
inline G4double GetGlobalTime() const override;
|
||||
inline void SetUserAction(G4UserTimeStepAction*) override;
|
||||
inline G4UserTimeStepAction* GetUserTimeStepAction() const override;
|
||||
|
||||
// To use with transportation only, no reactions
|
||||
inline void UseDefaultTimeSteps(G4bool);
|
||||
inline G4bool AreDefaultTimeStepsUsed();
|
||||
// To use with transportation only, no reactions
|
||||
inline void UseDefaultTimeSteps(G4bool);
|
||||
inline G4bool AreDefaultTimeStepsUsed();
|
||||
|
||||
inline G4ITStepStatus GetStatus() const;
|
||||
inline G4ITStepStatus GetStatus() const;
|
||||
|
||||
/* 1 : Reaction information
|
||||
* 2 : (1) + time step information
|
||||
* 3 : (2) + step info for individual tracks
|
||||
* 4 : (2) + trackList processing info + pushed and killed track info
|
||||
*/
|
||||
inline void SetVerbose(G4int) override;
|
||||
|
||||
inline G4int GetVerbose() const;
|
||||
/* 1 : Reaction information
|
||||
* 2 : (1) + time step information
|
||||
* 3 : (2) + step info for individual tracks
|
||||
* 4 : (2) + trackList processing info + pushed and killed track info
|
||||
*/
|
||||
inline void SetVerbose(G4int) override;
|
||||
|
||||
inline void WhyDoYouStop();
|
||||
inline G4int GetVerbose() const;
|
||||
|
||||
void SetInteractivity(G4ITTrackingInteractivity*) override;
|
||||
inline G4ITTrackingInteractivity* GetInteractivity() override;
|
||||
inline void WhyDoYouStop();
|
||||
|
||||
virtual size_t GetNTracks();
|
||||
void SetInteractivity(G4ITTrackingInteractivity*) override;
|
||||
inline G4ITTrackingInteractivity* GetInteractivity() override;
|
||||
|
||||
void GetCollisionType(G4String& interactionType);
|
||||
virtual size_t GetNTracks();
|
||||
|
||||
void AddWatchedTime(G4double time)
|
||||
{
|
||||
fWatchedTimes.insert(time);
|
||||
}
|
||||
void GetCollisionType(G4String& interactionType);
|
||||
|
||||
G4double GetNextWatchedTime() const;
|
||||
void AddWatchedTime(G4double time) { fWatchedTimes.insert(time); }
|
||||
|
||||
inline void SetMaxTimeStep(G4double maxTimeStep)
|
||||
{
|
||||
fMaxTimeStep = maxTimeStep;
|
||||
}
|
||||
G4double GetNextWatchedTime() const;
|
||||
|
||||
inline G4double GetMaxTimeStep() const
|
||||
{
|
||||
return fMaxTimeStep;
|
||||
}
|
||||
inline void SetMaxTimeStep(G4double maxTimeStep) { fMaxTimeStep = maxTimeStep; }
|
||||
|
||||
inline G4VScavengerMaterial* GetScavengerMaterial() const
|
||||
{
|
||||
return fpUserScavenger.get();
|
||||
}
|
||||
inline void SetScavengerMaterial(std::unique_ptr<G4VScavengerMaterial> scavengerMaterial)
|
||||
{
|
||||
inline G4double GetMaxTimeStep() const { return fMaxTimeStep; }
|
||||
|
||||
inline G4VScavengerMaterial* GetScavengerMaterial() const { return fpUserScavenger.get(); }
|
||||
inline void SetScavengerMaterial(std::unique_ptr<G4VScavengerMaterial> scavengerMaterial)
|
||||
{
|
||||
fpUserScavenger = std::move(scavengerMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void DoProcess();
|
||||
void SynchronizeTracks();
|
||||
void Stepping();
|
||||
|
||||
void DoProcess();
|
||||
void SynchronizeTracks();
|
||||
void Stepping();
|
||||
void FindUserPreDefinedTimeStep();
|
||||
|
||||
void FindUserPreDefinedTimeStep();
|
||||
G4bool CanICarryOn();
|
||||
|
||||
G4bool CanICarryOn();
|
||||
void PrintWhyDoYouStop();
|
||||
|
||||
void PrintWhyDoYouStop();
|
||||
private:
|
||||
G4Scheduler();
|
||||
void Create();
|
||||
|
||||
private:
|
||||
G4Scheduler();
|
||||
void Create();
|
||||
G4SchedulerMessenger* fpMessenger = nullptr;
|
||||
|
||||
G4SchedulerMessenger* fpMessenger;
|
||||
static G4ThreadLocal G4Scheduler* fgScheduler;
|
||||
G4int fVerbose;
|
||||
G4bool fWhyDoYouStop;
|
||||
G4bool fInitialized;
|
||||
G4bool fRunning;
|
||||
G4bool fContinue;
|
||||
|
||||
static G4ThreadLocal G4Scheduler* fgScheduler;
|
||||
G4int fVerbose;
|
||||
G4bool fWhyDoYouStop;
|
||||
G4bool fInitialized;
|
||||
G4bool fRunning;
|
||||
G4bool fContinue;
|
||||
G4int fNbSteps;
|
||||
G4int fMaxSteps;
|
||||
|
||||
G4int fNbSteps;
|
||||
G4int fMaxSteps;
|
||||
G4ITStepStatus fITStepStatus;
|
||||
|
||||
G4ITStepStatus fITStepStatus;
|
||||
// Time members
|
||||
G4bool fUseDefaultTimeSteps;
|
||||
G4double fTimeTolerance;
|
||||
G4double fGlobalTime;
|
||||
G4double fStartTime;
|
||||
G4double fStopTime;
|
||||
G4double fEndTime;
|
||||
G4double fPreviousTimeStep;
|
||||
G4int fZeroTimeCount;
|
||||
G4int fMaxNZeroTimeStepsAllowed;
|
||||
|
||||
// Time members
|
||||
G4bool fUseDefaultTimeSteps;
|
||||
G4double fTimeTolerance;
|
||||
G4double fGlobalTime;
|
||||
G4double fTmpGlobalTime;
|
||||
G4double fStartTime;
|
||||
G4double fStopTime;
|
||||
G4double fEndTime;
|
||||
G4double fPreviousTimeStep;
|
||||
G4int fZeroTimeCount;
|
||||
G4int fMaxNZeroTimeStepsAllowed;
|
||||
G4double fTimeStep; // The selected minimum time step
|
||||
G4double fMaxTimeStep;
|
||||
|
||||
G4double fTimeStep; // The selected minimum time step
|
||||
G4double fMaxTimeStep;
|
||||
// User steps
|
||||
G4bool fUsePreDefinedTimeSteps;
|
||||
G4double fDefaultMinTimeStep;
|
||||
std::map<G4double, G4double>* fpUserTimeSteps = nullptr;
|
||||
// One can give time steps in respect to the global time
|
||||
mutable G4double fUserUpperTimeLimit;
|
||||
G4double fDefinedMinTimeStep;
|
||||
// selected user time step in respect to the global time
|
||||
G4bool fReachedUserTimeLimit; // if fMinTimeStep == the user time step
|
||||
|
||||
// User steps
|
||||
G4bool fUsePreDefinedTimeSteps;
|
||||
G4double fDefaultMinTimeStep;
|
||||
std::map<G4double, G4double>* fpUserTimeSteps;
|
||||
// One can give time steps in respect to the global time
|
||||
mutable G4double fUserUpperTimeLimit;
|
||||
G4double fDefinedMinTimeStep;
|
||||
// selected user time step in respect to the global time
|
||||
G4bool fReachedUserTimeLimit; // if fMinTimeStep == the user time step
|
||||
std::set<G4double> fWatchedTimes;
|
||||
|
||||
std::set<G4double> fWatchedTimes;
|
||||
G4UserTimeStepAction* fpUserTimeStepAction;
|
||||
|
||||
G4UserTimeStepAction* fpUserTimeStepAction;
|
||||
std::unique_ptr<G4VScavengerMaterial> fpUserScavenger;
|
||||
|
||||
std::unique_ptr<G4VScavengerMaterial> fpUserScavenger;
|
||||
// ==========================================
|
||||
// TO BE REMOVED
|
||||
G4ITStepProcessor* fpStepProcessor = nullptr;
|
||||
G4ITModelProcessor* fpModelProcessor = nullptr;
|
||||
G4ITTrackingManager* fpTrackingManager = nullptr;
|
||||
G4ITTrackingInteractivity* fpTrackingInteractivity = nullptr;
|
||||
G4ITReactionSet* fReactionSet = nullptr;
|
||||
G4ITTrackHolder& fTrackContainer;
|
||||
G4ITModelHandler* fpModelHandler = nullptr;
|
||||
// ==========================================
|
||||
|
||||
// ==========================================
|
||||
// TO BE REMOVED
|
||||
G4ITStepProcessor* fpStepProcessor;
|
||||
G4ITModelProcessor* fpModelProcessor;
|
||||
G4ITTrackingManager* fpTrackingManager;
|
||||
G4ITTrackingInteractivity* fpTrackingInteractivity;
|
||||
G4ITReactionSet* fReactionSet;
|
||||
G4ITTrackHolder& fTrackContainer;
|
||||
G4ITModelHandler* fpModelHandler;
|
||||
// ==========================================
|
||||
G4double fTSTimeStep;
|
||||
// Time calculated by the time stepper in CalculateMinTimeStep()
|
||||
G4double fILTimeStep;
|
||||
// Time calculated by the interaction length methods
|
||||
// in ComputeInteractionLength()
|
||||
|
||||
G4double fTSTimeStep;
|
||||
// Time calculated by the time stepper in CalculateMinTimeStep()
|
||||
G4double fILTimeStep;
|
||||
// Time calculated by the interaction length methods
|
||||
// in ComputeInteractionLength()
|
||||
G4bool fInteractionStep;
|
||||
// Flag : if the step is driven by the interaction with the matter and
|
||||
// NOT by the reaction between tracks
|
||||
|
||||
G4bool fInteractionStep;
|
||||
// Flag : if the step is driven by the interaction with the matter and
|
||||
// NOT by the reaction between tracks
|
||||
G4ITGun* fpGun;
|
||||
|
||||
G4ITGun* fpGun;
|
||||
// ==========================================
|
||||
// Hoang
|
||||
G4bool fResetScavenger;
|
||||
|
||||
// ==========================================
|
||||
//Hoang
|
||||
bool fResetScavenger;
|
||||
public:
|
||||
void ResetScavenger(bool);
|
||||
public:
|
||||
void ResetScavenger(bool);
|
||||
};
|
||||
|
||||
inline G4bool G4Scheduler::IsInitialized()
|
||||
@@ -309,8 +292,7 @@ inline void G4Scheduler::SetEndTime(const G4double __endtime)
|
||||
fEndTime = __endtime;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4Scheduler::SetTimeSteps(std::map<G4double, G4double>* steps)
|
||||
inline void G4Scheduler::SetTimeSteps(std::map<G4double, G4double>* steps)
|
||||
{
|
||||
fUsePreDefinedTimeSteps = true;
|
||||
fpUserTimeSteps = steps;
|
||||
@@ -318,8 +300,7 @@ void G4Scheduler::SetTimeSteps(std::map<G4double, G4double>* steps)
|
||||
|
||||
inline void G4Scheduler::AddTimeStep(G4double startingTime, G4double timeStep)
|
||||
{
|
||||
if (fpUserTimeSteps == nullptr)
|
||||
{
|
||||
if (fpUserTimeSteps == nullptr) {
|
||||
fpUserTimeSteps = new std::map<G4double, G4double>();
|
||||
fUsePreDefinedTimeSteps = true;
|
||||
}
|
||||
@@ -367,8 +348,7 @@ inline G4double G4Scheduler::GetGlobalTime() const
|
||||
return fGlobalTime;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4Scheduler::SetUserAction(G4UserTimeStepAction* userITAction)
|
||||
inline void G4Scheduler::SetUserAction(G4UserTimeStepAction* userITAction)
|
||||
{
|
||||
fpUserTimeStepAction = userITAction;
|
||||
}
|
||||
@@ -388,8 +368,7 @@ inline G4int G4Scheduler::GetVerbose() const
|
||||
return fVerbose;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4Scheduler::SetMaxZeroTimeAllowed(G4int maxTimeStepAllowed)
|
||||
inline void G4Scheduler::SetMaxZeroTimeAllowed(G4int maxTimeStepAllowed)
|
||||
{
|
||||
fMaxNZeroTimeStepsAllowed = maxTimeStepAllowed;
|
||||
}
|
||||
@@ -456,7 +435,7 @@ inline G4bool G4Scheduler::AreDefaultTimeStepsUsed()
|
||||
|
||||
inline void G4Scheduler::ResetScavenger(bool value)
|
||||
{
|
||||
fResetScavenger = value;
|
||||
fResetScavenger = value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,165 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNADoubleIonisationModel.hh
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
// Reference: J.Meesungnoen et. al, DOI: 10.1021/jp058037z
|
||||
//
|
||||
|
||||
#ifndef G4DNA_DOUBLE_IONISATION_MODEL_HH_
|
||||
#define G4DNA_DOUBLE_IONISATION_MODEL_HH_
|
||||
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
#include "G4DNAGenericIonsManager.hh"
|
||||
#include "G4DNACrossSectionDataSet.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
|
||||
#include "G4DNAWaterIonisationStructure.hh"
|
||||
#include "G4VAtomDeexcitation.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4DNAMultipleIonisationManager.hh"
|
||||
|
||||
using EnergyLimitTable = std::map<G4String, G4double, std::less<G4String>>;
|
||||
|
||||
using CrossSectionDataTable = std::map<G4String, G4DNACrossSectionDataSet*,
|
||||
std::less<G4String>>;
|
||||
|
||||
//==============================================================================
|
||||
|
||||
class G4DNADoubleIonisationModel : public G4VEmModel {
|
||||
public:
|
||||
|
||||
// constructor
|
||||
G4DNADoubleIonisationModel(
|
||||
const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& model_name = "G4DNADoubleIonisationModel");
|
||||
|
||||
// destructor
|
||||
~G4DNADoubleIonisationModel() override;
|
||||
|
||||
G4DNADoubleIonisationModel& operator=(
|
||||
const G4DNADoubleIonisationModel&) = delete;
|
||||
G4DNADoubleIonisationModel(const G4DNADoubleIonisationModel&) = delete;
|
||||
|
||||
void Initialise(
|
||||
const G4ParticleDefinition* particle, const G4DataVector&) override;
|
||||
|
||||
G4double CrossSectionPerVolume(
|
||||
const G4Material* material, const G4ParticleDefinition* pdef,
|
||||
G4double ekin, G4double, G4double) override;
|
||||
|
||||
void SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vsec, const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle, G4double, G4double) override;
|
||||
|
||||
void SelectStationary(G4bool in);
|
||||
|
||||
void SelectVerboseLevel(G4int in);
|
||||
|
||||
void UseChampionAlphaParameter(G4bool in);
|
||||
|
||||
void SetMultipleIonisationEnergy(G4double in);
|
||||
|
||||
protected:
|
||||
|
||||
G4double RandomizeEjectedElectronEnergy(
|
||||
G4ParticleDefinition* pdef, G4double ekin, G4int shell);
|
||||
|
||||
G4ParticleChangeForGamma* particle_change_ = nullptr;
|
||||
|
||||
G4int RandomSelect(G4double energy, G4double scale_param,
|
||||
const G4String& pname);
|
||||
|
||||
G4double GenerateSecondaries(std::vector<G4DynamicParticle*>* vsec,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle,
|
||||
G4int ioni_shell,
|
||||
G4double& theta, G4double& phi,
|
||||
G4double& shell_energy);
|
||||
|
||||
G4double GetLowEnergyLimit(const G4String& pname);
|
||||
|
||||
G4double GetUppEnergyLimit(const G4String& pname);
|
||||
|
||||
G4bool stat_code_;
|
||||
|
||||
G4VAtomDeexcitation* atom_deex_;
|
||||
|
||||
EnergyLimitTable elow_tab_;
|
||||
EnergyLimitTable eupp_tab_;
|
||||
|
||||
CrossSectionDataTable xs_tab_;
|
||||
|
||||
G4ParticleDefinition* proton_def_;
|
||||
G4ParticleDefinition* alpha_def_;
|
||||
G4ParticleDefinition* carbon_def_;
|
||||
|
||||
const std::vector<G4double>* water_density_;
|
||||
|
||||
G4bool is_initialized_;
|
||||
G4int verbose_level_;
|
||||
|
||||
std::map<G4double, G4double> model_elow_tab_;
|
||||
|
||||
G4DNAMultipleIonisationManager* mioni_manager_;
|
||||
|
||||
G4bool use_champion_param_;
|
||||
|
||||
G4double energy_threshold_;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
inline void G4DNADoubleIonisationModel::SelectStationary(G4bool in)
|
||||
{
|
||||
stat_code_ = in;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void G4DNADoubleIonisationModel::SelectVerboseLevel(G4int in)
|
||||
{
|
||||
verbose_level_ = in;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void G4DNADoubleIonisationModel::UseChampionAlphaParameter(G4bool in)
|
||||
{
|
||||
use_champion_param_ = in;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline void G4DNADoubleIonisationModel::SetMultipleIonisationEnergy(G4double in)
|
||||
{
|
||||
energy_threshold_ = in;
|
||||
}
|
||||
|
||||
#endif // G4DNA_DOUBLE_IONISATION_MODEL_HH_
|
||||
@@ -159,6 +159,8 @@ private:
|
||||
std::vector<G4double> eEdummyVec_Au;
|
||||
std::vector<G4double> eEdummyVec_H2O;
|
||||
|
||||
G4Material* fpBaseWater;
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author V.Ivanchenko 15.04.2024
|
||||
//
|
||||
// General ion ionisation model applicable for G4GenericIons.
|
||||
// Concrete model of ion ionisation is selected on fly.
|
||||
// Lowest energy limit - tracking cut and stationary mode are taken
|
||||
// from EM parameters.
|
||||
//
|
||||
|
||||
#ifndef G4DNAGeneralIonIonisationModel_h
|
||||
#define G4DNAGeneralIonIonisationModel_h 1
|
||||
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
|
||||
class G4DNAGeneralIonIonisationModel : public G4VEmModel
|
||||
{
|
||||
public:
|
||||
|
||||
G4DNAGeneralIonIonisationModel(const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& nam = "DNAIonIonisationModel");
|
||||
|
||||
~G4DNAGeneralIonIonisationModel() override = default;
|
||||
|
||||
G4DNAGeneralIonIonisationModel & operator=
|
||||
(const G4DNAGeneralIonIonisationModel &right) = delete;
|
||||
G4DNAGeneralIonIonisationModel(const G4DNAGeneralIonIonisationModel&) = delete;
|
||||
|
||||
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
|
||||
|
||||
G4double CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin, G4double emin,
|
||||
G4double emax) override;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double, G4double) override;
|
||||
|
||||
void StartTracking(G4Track*) override;
|
||||
|
||||
protected:
|
||||
|
||||
G4ParticleChangeForGamma* fParticleChangeForGamma{nullptr};
|
||||
|
||||
private:
|
||||
|
||||
G4double fLowestEnergy{0.0};
|
||||
const G4DynamicParticle* fDynParticle{nullptr};
|
||||
G4VEmModel* fCurrentModel{nullptr};
|
||||
|
||||
// list of concrete ion ionisation models, put extra here
|
||||
G4VEmModel* fRuddIonisation;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author V.Ivanchenko 15.04.2024
|
||||
//
|
||||
// General ion model for simulation of charge decrease.
|
||||
// Concrete model of ion ionisation is selected on fly.
|
||||
//
|
||||
|
||||
#ifndef G4DNAIonChargeDecreaseModel_h
|
||||
#define G4DNAIonChargeDecreaseModel_h 1
|
||||
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
|
||||
class G4DNAIonChargeDecreaseModel : public G4VEmModel
|
||||
{
|
||||
public:
|
||||
|
||||
G4DNAIonChargeDecreaseModel(const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& nam = "DNAIonChargeDecrease");
|
||||
|
||||
~G4DNAIonChargeDecreaseModel() override = default;
|
||||
|
||||
G4DNAIonChargeDecreaseModel & operator=
|
||||
(const G4DNAIonChargeDecreaseModel &right) = delete;
|
||||
G4DNAIonChargeDecreaseModel(const G4DNAIonChargeDecreaseModel&) = delete;
|
||||
|
||||
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
|
||||
|
||||
G4double CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin, G4double,
|
||||
G4double) override;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double, G4double) override;
|
||||
|
||||
void StartTracking(G4Track*) override;
|
||||
|
||||
protected:
|
||||
|
||||
G4ParticleChangeForGamma* fParticleChangeForGamma{nullptr};
|
||||
|
||||
private:
|
||||
|
||||
const G4DynamicParticle* fDynParticle{nullptr};
|
||||
G4VEmModel* fCurrentModel{nullptr};
|
||||
|
||||
// list of concrete ion ionisation models, put extra here
|
||||
G4VEmModel* fDummy;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author V.Ivanchenko 15.04.2024
|
||||
//
|
||||
// General ion model for simulation of charge increase.
|
||||
// Concrete model of ion ionisation is selected on fly.
|
||||
//
|
||||
|
||||
#ifndef G4DNAIonChargeIncreaseModel_h
|
||||
#define G4DNAIonChargeIncreaseModel_h 1
|
||||
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
|
||||
class G4DNAIonChargeIncreaseModel : public G4VEmModel
|
||||
{
|
||||
public:
|
||||
|
||||
G4DNAIonChargeIncreaseModel(const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& nam = "DNAIonChargeIncrease");
|
||||
|
||||
~G4DNAIonChargeIncreaseModel() override = default;
|
||||
|
||||
G4DNAIonChargeIncreaseModel & operator=
|
||||
(const G4DNAIonChargeIncreaseModel &right) = delete;
|
||||
G4DNAIonChargeIncreaseModel(const G4DNAIonChargeIncreaseModel&) = delete;
|
||||
|
||||
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
|
||||
|
||||
G4double CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin, G4double,
|
||||
G4double) override;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double, G4double) override;
|
||||
|
||||
void StartTracking(G4Track*) override;
|
||||
|
||||
protected:
|
||||
|
||||
G4ParticleChangeForGamma* fParticleChangeForGamma{nullptr};
|
||||
|
||||
private:
|
||||
|
||||
const G4DynamicParticle* fDynParticle{nullptr};
|
||||
G4VEmModel* fCurrentModel{nullptr};
|
||||
|
||||
// list of concrete ion ionisation models, put extra here
|
||||
G4VEmModel* fDummy;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNAMultipleIonisationManager.hh
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
|
||||
#ifndef G4DNA_MULTIPLE_IONISATION_MANAGER_HH_
|
||||
#define G4DNA_MULTIPLE_IONISATION_MANAGER_HH_
|
||||
|
||||
#include "globals.hh"
|
||||
#include <vector>
|
||||
|
||||
class G4Track;
|
||||
|
||||
enum MultipleIonisedModification {
|
||||
eDoubleIonisedMolecule = 3,
|
||||
eTripleIonisedMolecule = 4,
|
||||
eQuadrupleIonisedMolecule = 5
|
||||
};
|
||||
|
||||
class G4DNAMultipleIonisationManager {
|
||||
public:
|
||||
G4DNAMultipleIonisationManager() = default;
|
||||
|
||||
~G4DNAMultipleIonisationManager() = default;
|
||||
|
||||
void CreateMultipleIonisedWaterMolecule(
|
||||
MultipleIonisedModification mod, G4int* shell_level,
|
||||
const G4Track* incoming_track);
|
||||
|
||||
G4bool CheckShellEnergy(
|
||||
MultipleIonisedModification mod, G4double* shell_energy);
|
||||
|
||||
void LoadAlphaParam(const G4String& filepath, G4double Z, G4double A);
|
||||
|
||||
G4double GetAlphaParam(G4double energy);
|
||||
|
||||
private:
|
||||
G4int num_node_;
|
||||
std::vector<G4double> Eion_;
|
||||
std::vector<G4double> alpha_;
|
||||
|
||||
};
|
||||
|
||||
#endif // G4DNA_MULTIPLE_IONISATION_MANAGER_HH_
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNAQuadrupleIonisationModel.hh
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
// Reference: J.Meesungnoen et. al, DOI: 10.1021/jp058037z
|
||||
//
|
||||
|
||||
#ifndef G4DNA_QUADRUPLE_IONISATION_MODEL_HH_
|
||||
#define G4DNA_QUADRUPLE_IONISATION_MODEL_HH_
|
||||
|
||||
#include "G4DNADoubleIonisationModel.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
|
||||
class G4DNAQuadrupleIonisationModel : public G4DNADoubleIonisationModel {
|
||||
public:
|
||||
// constructor
|
||||
G4DNAQuadrupleIonisationModel(
|
||||
const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& model_name = "G4DNAQuadrupleIonisationModel");
|
||||
|
||||
// destructor
|
||||
~G4DNAQuadrupleIonisationModel() override = default;
|
||||
|
||||
void Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector&) override;
|
||||
|
||||
G4double CrossSectionPerVolume(
|
||||
const G4Material* material, const G4ParticleDefinition* pdef,
|
||||
G4double ekin, G4double, G4double) override;
|
||||
|
||||
void SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vsec, const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle, G4double, G4double) override;
|
||||
};
|
||||
|
||||
#endif // G4DNA_QUADRUPLE_IONISATION_MODEL_HH_
|
||||
+15
-4
@@ -83,14 +83,17 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void LoadData();
|
||||
|
||||
void SetParticle(const G4ParticleDefinition*);
|
||||
|
||||
G4int SelectShell(G4double energy);
|
||||
|
||||
G4double SampleElectronEnergy(G4double kine, G4double bindingEnergy, G4int shell);
|
||||
G4double MaxEnergy(G4double kine, G4int shell);
|
||||
|
||||
G4double ProbabilityFunction(G4double kine, G4double deltae,
|
||||
G4double bindingEnergy, G4int shell);
|
||||
G4double SampleElectronEnergy(G4double kine, G4int shell);
|
||||
|
||||
G4double ProbabilityFunction(G4double kine, G4double deltae, G4int shell);
|
||||
|
||||
G4double S_1s(G4double t,
|
||||
G4double energyTransferred,
|
||||
@@ -148,10 +151,17 @@ private:
|
||||
G4double fLimitEnergy;
|
||||
|
||||
G4double fMass{0.0};
|
||||
G4double fAmass{0.0};
|
||||
G4double fMassRate{1.0};
|
||||
G4double fElow{0.0};
|
||||
|
||||
G4double F1{0.0};
|
||||
G4double F2{0.0};
|
||||
G4double alphaConst{0.0};
|
||||
G4double bEnergy{0.0};
|
||||
G4double u{0.0};
|
||||
G4double v{0.0};
|
||||
G4double wc{0.0};
|
||||
|
||||
G4double slaterEffectiveCharge[3] = {0.0};
|
||||
G4double sCoefficient[3] = {0.0};
|
||||
G4double fTemp[5] = {0.0};
|
||||
@@ -159,6 +169,7 @@ private:
|
||||
G4int idx{-1};
|
||||
G4int verbose{0};
|
||||
|
||||
G4bool isInitialised{false};
|
||||
G4bool isIon{false};
|
||||
G4bool isFirst{false};
|
||||
G4bool isHelium{false};
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNATripleIonisationModel.hh
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
// Reference: J.Meesungnoen et. al, DOI: 10.1021/jp058037z
|
||||
//
|
||||
|
||||
#ifndef G4DNA_TRIPLE_IONISATION_MODEL_HH_
|
||||
#define G4DNA_TRIPLE_IONISATION_MODEL_HH_
|
||||
|
||||
#include "G4DNADoubleIonisationModel.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
|
||||
class G4DNATripleIonisationModel : public G4DNADoubleIonisationModel {
|
||||
public:
|
||||
// constructor
|
||||
G4DNATripleIonisationModel(
|
||||
const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& model_name = "G4DNATripleIonisationModel");
|
||||
|
||||
// destructor
|
||||
~G4DNATripleIonisationModel() override = default;
|
||||
|
||||
void Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector&) override;
|
||||
|
||||
G4double CrossSectionPerVolume(
|
||||
const G4Material* material, const G4ParticleDefinition* pdef,
|
||||
G4double ekin, G4double, G4double) override;
|
||||
|
||||
void SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vsec, const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle, G4double, G4double) override;
|
||||
};
|
||||
|
||||
#endif // G4DNA_TRIPLE_IONISATION_MODEL_HH_
|
||||
@@ -3,6 +3,7 @@
|
||||
# Define the Geant4 Module.
|
||||
geant4_add_module(G4emdna-models
|
||||
PUBLIC_HEADERS
|
||||
G4ChemEquilibrium.hh
|
||||
G4DNABornAngle.hh
|
||||
G4DNABornExcitationModel.hh
|
||||
G4DNABornExcitationModel1.hh
|
||||
@@ -10,40 +11,60 @@ geant4_add_module(G4emdna-models
|
||||
G4DNABornIonisationModel.hh
|
||||
G4DNABornIonisationModel1.hh
|
||||
G4DNABornIonisationModel2.hh
|
||||
G4DNAChampionElasticModel.hh
|
||||
G4DNACPA100ElasticModel.hh
|
||||
G4DNACPA100ExcitationModel.hh
|
||||
G4DNACPA100IonisationModel.hh
|
||||
G4DNASmoluchowskiDiffusion.hh
|
||||
G4DNASmoluchowskiReactionModel.hh
|
||||
G4DNAChampionElasticModel.hh
|
||||
G4DNADingfelderChargeDecreaseModel.hh
|
||||
G4DNADingfelderChargeIncreaseModel.hh
|
||||
G4DNADiracRMatrixExcitationModel.hh
|
||||
G4DNADoubleIonisationModel.hh
|
||||
G4DNAELSEPAElasticModel.hh
|
||||
G4DNAEmfietzoglouExcitationModel.hh
|
||||
G4DNAEmfietzoglouIonisationModel.hh
|
||||
G4DNAELSEPAElasticModel.hh
|
||||
G4DNAIonElasticModel.hh
|
||||
G4DNAEventScheduler.hh
|
||||
G4DNAGeneralIonIonisationModel.hh
|
||||
G4DNAGillespieDirectMethod.hh
|
||||
G4DNAIRT.hh
|
||||
G4DNAIndependentReactionTimeModel.hh
|
||||
G4DNAIndependentReactionTimeStepper.hh
|
||||
G4DNAIonChargeDecreaseModel.hh
|
||||
G4DNAIonChargeIncreaseModel.hh
|
||||
G4DNAIonElasticModel.hh
|
||||
G4DNAIRTMoleculeEncounterStepper.hh
|
||||
G4DNAMakeReaction.hh
|
||||
G4DNAMeltonAttachmentModel.hh
|
||||
G4DNAMillerGreenExcitationModel.hh
|
||||
G4DNAModelInterface.hh
|
||||
G4DNAMolecularIRTModel.hh
|
||||
G4DNAMolecularReaction.hh
|
||||
G4DNAMolecularStepByStepModel.hh
|
||||
G4DNAMoleculeEncounterStepper.hh
|
||||
G4DNAMultipleIonisationManager.hh
|
||||
G4DNAOneStepThermalizationModel.hh
|
||||
G4DNAOneStepThermalizationModel.hpp
|
||||
G4DNAPTBAugerModel.hh
|
||||
G4DNAPTBElasticModel.hh
|
||||
G4DNAPTBExcitationModel.hh
|
||||
G4DNAPTBIonisationModel.hh
|
||||
G4DNAQuadrupleIonisationModel.hh
|
||||
G4DNAQuinnPlasmonExcitationModel.hh
|
||||
G4DNARPWBAExcitationModel.hh
|
||||
G4DNARPWBAIonisationModel.hh
|
||||
G4DNARelativisticIonisationModel.hh
|
||||
G4DNARuddAngle.hh
|
||||
G4DNARuddIonisationExtendedModel.hh
|
||||
G4DNARuddIonisationModel.hh
|
||||
G4DNASancheExcitationModel.hh
|
||||
G4DNAOneStepThermalizationModel.hh
|
||||
G4DNAOneStepThermalizationModel.hpp
|
||||
G4DNAPTBIonisationModel.hh
|
||||
G4DNAPTBElasticModel.hh
|
||||
G4DNAPTBExcitationModel.hh
|
||||
G4DNAPTBAugerModel.hh
|
||||
G4DNAScreenedRutherfordElasticModel.hh
|
||||
G4DNASmoluchowskiDiffusion.hh
|
||||
G4DNASmoluchowskiReactionModel.hh
|
||||
G4DNATransformElectronModel.hh
|
||||
G4DNATripleIonisationModel.hh
|
||||
G4DNAUeharaScreenedRutherfordElasticModel.hh
|
||||
G4DNAUpdateSystemModel.hh
|
||||
G4DNAVacuumModel.hh
|
||||
G4DiffusionControlledReactionModel.hh
|
||||
G4LEPTSAttachmentModel.hh
|
||||
G4LEPTSDissociationModel.hh
|
||||
G4LEPTSElasticModel.hh
|
||||
@@ -51,97 +72,88 @@ geant4_add_module(G4emdna-models
|
||||
G4LEPTSPositroniumModel.hh
|
||||
G4LEPTSRotExcitationModel.hh
|
||||
G4LEPTSVibExcitationModel.hh
|
||||
G4VLEPTSModel.hh
|
||||
G4LEPTSDiffXS.hh
|
||||
G4LEPTSDistribution.hh
|
||||
G4LEPTSElossDistr.hh
|
||||
G4LEPTSExcitationModel.hh
|
||||
G4VDNAModel.hh
|
||||
G4DNAModelInterface.hh
|
||||
G4DNADiracRMatrixExcitationModel.hh
|
||||
G4DNAQuinnPlasmonExcitationModel.hh
|
||||
G4DNARelativisticIonisationModel.hh
|
||||
G4DiffusionControlledReactionModel.hh
|
||||
G4DNAIndependentReactionTimeModel.hh
|
||||
G4DNAIndependentReactionTimeStepper.hh
|
||||
G4DNAMakeReaction.hh
|
||||
G4DNAUpdateSystemModel.hh
|
||||
G4DNAGillespieDirectMethod.hh
|
||||
G4VUpdateSystemModel.hh
|
||||
G4DNAUpdateSystemModel.hh
|
||||
G4DNAEventScheduler.hh
|
||||
G4DNARPWBAExcitationModel.hh
|
||||
G4DNARPWBAIonisationModel.hh
|
||||
G4VDNAHitModel.hh
|
||||
G4ChemEquilibrium.hh
|
||||
G4VLEPTSModel.hh
|
||||
G4VUpdateSystemModel.hh
|
||||
SOURCES
|
||||
G4ChemEquilibrium.cc
|
||||
G4DNABornAngle.cc
|
||||
G4DNABornExcitationModel1.cc
|
||||
G4DNABornExcitationModel2.cc
|
||||
G4DNABornIonisationModel1.cc
|
||||
G4DNABornIonisationModel2.cc
|
||||
G4DNAChampionElasticModel.cc
|
||||
G4DNACPA100ElasticModel.cc
|
||||
G4DNACPA100ExcitationModel.cc
|
||||
G4DNACPA100IonisationModel.cc
|
||||
G4DNASmoluchowskiDiffusion.cc
|
||||
G4DNASmoluchowskiReactionModel.cc
|
||||
G4DNAChampionElasticModel.cc
|
||||
G4DNADingfelderChargeDecreaseModel.cc
|
||||
G4DNADingfelderChargeIncreaseModel.cc
|
||||
G4DNADiracRMatrixExcitationModel.cc
|
||||
G4DNADoubleIonisationModel.cc
|
||||
G4DNAELSEPAElasticModel.cc
|
||||
G4DNAEmfietzoglouExcitationModel.cc
|
||||
G4DNAEmfietzoglouIonisationModel.cc
|
||||
G4DNAIonElasticModel.cc
|
||||
G4DNAEventScheduler.cc
|
||||
G4DNAGeneralIonIonisationModel.cc
|
||||
G4DNAGillespieDirectMethod.cc
|
||||
G4DNAIRT.cc
|
||||
G4DNAIndependentReactionTimeModel.cc
|
||||
G4DNAIndependentReactionTimeStepper.cc
|
||||
G4DNAIonChargeDecreaseModel.cc
|
||||
G4DNAIonChargeIncreaseModel.cc
|
||||
G4DNAIonElasticModel.cc
|
||||
G4DNAIRTMoleculeEncounterStepper.cc
|
||||
G4DNAMakeReaction.cc
|
||||
G4DNAMeltonAttachmentModel.cc
|
||||
G4DNAMillerGreenExcitationModel.cc
|
||||
G4DNAModelInterface.cc
|
||||
G4DNAMolecularIRTModel.cc
|
||||
G4DNAMolecularReaction.cc
|
||||
G4DNAMolecularStepByStepModel.cc
|
||||
G4DNAMoleculeEncounterStepper.cc
|
||||
G4DNAMultipleIonisationManager.cc
|
||||
G4DNAOneStepThermalizationModel.cc
|
||||
G4DNAPTBAugerModel.cc
|
||||
G4DNAPTBElasticModel.cc
|
||||
G4DNAPTBExcitationModel.cc
|
||||
G4DNAPTBIonisationModel.cc
|
||||
G4DNAQuadrupleIonisationModel.cc
|
||||
G4DNAQuinnPlasmonExcitationModel.cc
|
||||
G4DNARPWBAExcitationModel.cc
|
||||
G4DNARPWBAIonisationModel.cc
|
||||
G4DNARelativisticIonisationModel.cc
|
||||
G4DNARuddAngle.cc
|
||||
G4DNARuddIonisationExtendedModel.cc
|
||||
G4DNARuddIonisationModel.cc
|
||||
G4DNASancheExcitationModel.cc
|
||||
G4DNAOneStepThermalizationModel.cc
|
||||
G4DNAPTBIonisationModel.cc
|
||||
G4DNAPTBElasticModel.cc
|
||||
G4DNAPTBExcitationModel.cc
|
||||
G4DNAPTBAugerModel.cc
|
||||
G4DNAScreenedRutherfordElasticModel.cc
|
||||
G4DNASmoluchowskiDiffusion.cc
|
||||
G4DNASmoluchowskiReactionModel.cc
|
||||
G4DNATransformElectronModel.cc
|
||||
G4DNATripleIonisationModel.cc
|
||||
G4DNAUeharaScreenedRutherfordElasticModel.cc
|
||||
G4DNAUpdateSystemModel.cc
|
||||
G4DNAVacuumModel.cc
|
||||
G4LEPTSElossDistr.cc
|
||||
G4DiffusionControlledReactionModel.cc
|
||||
G4LEPTSAttachmentModel.cc
|
||||
G4LEPTSDissociationModel.cc
|
||||
G4LEPTSElasticModel.cc
|
||||
G4LEPTSDistribution.cc
|
||||
G4LEPTSIonisationModel.cc
|
||||
G4LEPTSPositroniumModel.cc
|
||||
G4LEPTSRotExcitationModel.cc
|
||||
G4LEPTSVibExcitationModel.cc
|
||||
G4VLEPTSModel.cc
|
||||
G4LEPTSExcitationModel.cc
|
||||
G4LEPTSDiffXS.cc
|
||||
G4LEPTSDistribution.cc
|
||||
G4LEPTSElossDistr.cc
|
||||
G4LEPTSExcitationModel.cc
|
||||
G4VDNAModel.cc
|
||||
G4DNAModelInterface.cc
|
||||
G4DNADiracRMatrixExcitationModel.cc
|
||||
G4DNAQuinnPlasmonExcitationModel.cc
|
||||
G4DNARelativisticIonisationModel.cc
|
||||
G4DiffusionControlledReactionModel.cc
|
||||
G4DNAIndependentReactionTimeModel.cc
|
||||
G4DNAIndependentReactionTimeStepper.cc
|
||||
G4DNAMakeReaction.cc
|
||||
G4DNAUpdateSystemModel.cc
|
||||
G4DNAGillespieDirectMethod.cc
|
||||
G4DNAUpdateSystemModel.cc
|
||||
G4DNAEventScheduler.cc
|
||||
G4DNARPWBAExcitationModel.cc
|
||||
G4DNARPWBAIonisationModel.cc
|
||||
G4VDNAHitModel.cc
|
||||
G4ChemEquilibrium.cc)
|
||||
G4VLEPTSModel.cc)
|
||||
|
||||
geant4_module_link_libraries(G4emdna-models
|
||||
PUBLIC
|
||||
|
||||
@@ -72,6 +72,7 @@ G4DNABornAngle::SampleDirectionForShell(const G4DynamicParticle* dp,
|
||||
{
|
||||
G4double k = dp->GetKineticEnergy();
|
||||
G4double cosTheta = 1.0;
|
||||
|
||||
if (dp->GetDefinition() == fElectron)
|
||||
{
|
||||
if (secKinetic < 50.*eV) cosTheta = (2.*G4UniformRand())-1.;
|
||||
@@ -89,14 +90,12 @@ G4DNABornAngle::SampleDirectionForShell(const G4DynamicParticle* dp,
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double mass = dp->GetDefinition()->GetPDGMass();
|
||||
G4double maxSecKinetic = 4.* (electron_mass_c2 / mass) * k;
|
||||
|
||||
// cosTheta = std::sqrt(secKinetic / maxSecKinetic);
|
||||
G4double tau = k/dp->GetDefinition()->GetPDGMass();
|
||||
G4double maxSecKinetic = 2.* electron_mass_c2*tau*(tau + 2.0);
|
||||
|
||||
// Restriction below 100 eV from Emfietzoglou (2000)
|
||||
|
||||
if (secKinetic>100*eV) cosTheta = std::sqrt(secKinetic / maxSecKinetic);
|
||||
if (secKinetic>100*eV) cosTheta = std::min(std::sqrt(secKinetic / maxSecKinetic), 1.0);
|
||||
else cosTheta = (2.*G4UniformRand())-1.;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,736 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNADoubleIonisationModel.cc
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
// Reference: J.Meesungnoen et. al, DOI: 10.1021/jp058037z
|
||||
//
|
||||
|
||||
#include "G4DNADoubleIonisationModel.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UAtomicDeexcitation.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
|
||||
#include "G4IonTable.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4DNARuddAngle.hh"
|
||||
#include "G4DeltaAngle.hh"
|
||||
#include "G4Exp.hh"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
|
||||
G4DNAWaterIonisationStructure water_structure;
|
||||
|
||||
// parameters for rejection function
|
||||
struct FuncParams {
|
||||
G4double Bj_energy;
|
||||
G4double alpha_const;
|
||||
G4double beta_squared;
|
||||
G4double velocity;
|
||||
G4double correction_factor;
|
||||
G4double wc;
|
||||
G4double F1;
|
||||
G4double F2;
|
||||
G4double c;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void setup_rejection_function(G4ParticleDefinition* pdef, const G4double ekin,
|
||||
const G4int shell, FuncParams& par)
|
||||
{
|
||||
|
||||
// Following values provided by M. Dingfelder (priv. comm)
|
||||
const G4double Bj[5]
|
||||
= { 12.60 * eV, 14.70 * eV, 18.40 * eV, 32.20 * eV, 540.0 * eV };
|
||||
|
||||
// Data For Liquid Water from Dingfelder (Protons in Water)
|
||||
G4double A1{1.02}, B1{82.0}, C1{0.45}, D1{-0.80}, E1{0.38}, A2{1.07},
|
||||
B2{11.6}, // Value provided by M. Dingfelder (priv. comm)
|
||||
C2{0.60}, D2{0.04}, alpha_const{0.64};
|
||||
|
||||
auto Bj_energy = Bj[shell];
|
||||
|
||||
if (shell == 4) {
|
||||
alpha_const = 0.66;
|
||||
//Data For Liquid Water K SHELL from Dingfelder (Protons in Water)
|
||||
A1 = 1.25; B1 = 0.5; C1 = 1.00; D1 = 1.00; E1 = 3.00;
|
||||
A2 = 1.10; B2 = 1.30; C2 = 1.00; D2 = 0.00;
|
||||
// The following cases are provided by M. Dingfelder (priv. comm)
|
||||
Bj_energy = water_structure.IonisationEnergy(shell);
|
||||
}
|
||||
|
||||
const auto mass = pdef->GetPDGMass();
|
||||
const auto tau = ekin * electron_mass_c2 / mass;
|
||||
const auto A_ion = pdef->GetAtomicMass();
|
||||
|
||||
G4double v2;
|
||||
G4double beta2;
|
||||
|
||||
constexpr G4double Ry = 13.6 * eV;
|
||||
constexpr G4double xxx = 5.447761194E-02 * MeV;
|
||||
|
||||
if (tau < xxx) {
|
||||
v2 = tau / Bj_energy;
|
||||
beta2 = 2.0 * tau / electron_mass_c2;
|
||||
} else {
|
||||
// Relativistic
|
||||
v2 = (0.5 * electron_mass_c2 / Bj_energy)
|
||||
* (1.0 - (1.0 / std::pow((1.0 + (tau / electron_mass_c2)), 2.0)));
|
||||
beta2 = 1.0 - 1.0 / std::pow((1.0 + (tau / electron_mass_c2 / A_ion)), 2.0);
|
||||
}
|
||||
|
||||
const auto v = std::sqrt(v2);
|
||||
const auto wc = 4.0 * v2 - 2.0 * v - (Ry / (4.0 * Bj_energy));
|
||||
|
||||
const auto L1 = (C1 * std::pow(v, D1)) / (1.0 + E1 * std::pow(v, (D1 + 4.0)));
|
||||
const auto L2 = C2 * std::pow(v, D2);
|
||||
const auto H1 = (A1 * G4Log(1.0 + v2)) / (v2 + (B1 / v2));
|
||||
const auto H2 = (A2 / v2) + (B2 /(v2 * v2));
|
||||
const auto F1 = L1 + H1;
|
||||
const auto F2 = (L2 * H2) / (L2 + H2);
|
||||
|
||||
// ZF. generalized & relativistic version
|
||||
G4double max_energy;
|
||||
|
||||
if (ekin <= 0.1 * mass) {
|
||||
// maximum kinetic energy , non relativistic
|
||||
max_energy = 4.0 * (electron_mass_c2 / mass) * ekin;
|
||||
} else {
|
||||
// relativistic
|
||||
auto gamma = 1.0 / std::sqrt(1.0 - beta2);
|
||||
max_energy = 2.0 * electron_mass_c2 * (gamma * gamma - 1.0)
|
||||
/ (1.0 + 2.0 * gamma * (electron_mass_c2 / mass)
|
||||
+ std::pow(electron_mass_c2 / mass, 2.0));
|
||||
}
|
||||
|
||||
const auto wmax = max_energy / Bj_energy;
|
||||
auto c = wmax * (F2 * wmax+ F1 * (2.0 + wmax))
|
||||
/ (2.0 * (1.0 + wmax) * (1.0 + wmax));
|
||||
c = 1.0 / c; // manual calculus leads to c = 1 / c
|
||||
|
||||
par.Bj_energy = Bj_energy;
|
||||
par.alpha_const = alpha_const;
|
||||
par.beta_squared = beta2;
|
||||
par.velocity = v;
|
||||
par.correction_factor = 1.0;
|
||||
par.wc = wc;
|
||||
par.F1 = F1;
|
||||
par.F2 = F2;
|
||||
par.c = c;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double rejection_function(G4ParticleDefinition* pdef, const G4int shell,
|
||||
const FuncParams& par, G4double proposed_ws)
|
||||
{
|
||||
|
||||
const G4double Gj[5] = { 0.99, 1.11, 1.11, 0.52, 1.0 };
|
||||
|
||||
proposed_ws /= par.Bj_energy;
|
||||
|
||||
auto rejection_term = 1.0 + G4Exp(par.alpha_const * (proposed_ws - par.wc)
|
||||
/ par.velocity);
|
||||
rejection_term = (1.0 / rejection_term) * par.correction_factor * Gj[shell];
|
||||
|
||||
if (pdef == G4Proton::ProtonDefinition()) {
|
||||
|
||||
// for protons
|
||||
return rejection_term;
|
||||
|
||||
} else if (pdef->GetAtomicMass() > 4) {
|
||||
|
||||
// for carbon ions
|
||||
auto Z = pdef->GetAtomicNumber();
|
||||
auto x = 100.0 * std::sqrt(par.beta_squared) / std::pow(Z, 0.6666667);
|
||||
auto zeff = Z * (1.0 - G4Exp(x * (-1.316 + x * (0.112 - 0.0650 * x))));
|
||||
|
||||
rejection_term *= (zeff * zeff);
|
||||
|
||||
return rejection_term;
|
||||
|
||||
}
|
||||
|
||||
// for alpha particles
|
||||
auto zeff = pdef->GetPDGCharge() / eplus + pdef->GetLeptonNumber();
|
||||
rejection_term *= (zeff * zeff);
|
||||
|
||||
return rejection_term;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double proposed_sampled_energy(const FuncParams& par)
|
||||
{
|
||||
const auto rval = G4UniformRand();
|
||||
|
||||
auto proposed_ws = par.c * (par.F1 * par.F1 * par.c
|
||||
+ 2.0 * rval * (par.F2 - par.F1));
|
||||
|
||||
proposed_ws = -par.F1 * par.c + 2.0 * rval + std::sqrt(proposed_ws);
|
||||
|
||||
proposed_ws /= (par.c * (par.F1 + par.F2) - 2.0 * rval);
|
||||
|
||||
proposed_ws *= par.Bj_energy;
|
||||
|
||||
return proposed_ws;
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
//==============================================================================
|
||||
|
||||
// constructor
|
||||
G4DNADoubleIonisationModel::G4DNADoubleIonisationModel(
|
||||
const G4ParticleDefinition*, const G4String& model_name)
|
||||
: G4VEmModel(model_name),
|
||||
is_initialized_(false)
|
||||
{
|
||||
water_density_ = nullptr;
|
||||
|
||||
model_elow_tab_[1] = 100 * eV;
|
||||
model_elow_tab_[4] = 1.0 * keV;
|
||||
model_elow_tab_[5] = 0.5 * MeV; // For A = 3 or above, limit is MeV/uma
|
||||
|
||||
verbose_level_ = 0;
|
||||
|
||||
// Define default angular generator
|
||||
SetAngularDistribution(new G4DNARuddAngle());
|
||||
|
||||
// Mark this model as "applicable" for atomic deexcitation
|
||||
SetDeexcitationFlag(true);
|
||||
atom_deex_ = nullptr;
|
||||
particle_change_ = nullptr;
|
||||
|
||||
// Selection of stationary mode
|
||||
stat_code_ = false;
|
||||
|
||||
// True if use champion alpha parameter
|
||||
use_champion_param_ = false;
|
||||
|
||||
// Double-ionization energy
|
||||
energy_threshold_ = 40.0 * eV;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4DNADoubleIonisationModel::~G4DNADoubleIonisationModel()
|
||||
{
|
||||
for (auto x : xs_tab_) {
|
||||
G4DNACrossSectionDataSet* table = x.second;
|
||||
if (table) { delete table; }
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNADoubleIonisationModel::Initialise(
|
||||
const G4ParticleDefinition* particle, const G4DataVector&)
|
||||
{
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling G4DNADoubleIonisationModel::Initialise()" << G4endl;
|
||||
}
|
||||
|
||||
proton_def_ = G4Proton::ProtonDefinition();
|
||||
alpha_def_ = G4DNAGenericIonsManager::Instance()->GetIon("alpha++");
|
||||
carbon_def_ = G4IonTable::GetIonTable()->GetIon(6, 12);
|
||||
|
||||
constexpr G4double kScaleFactor = 1.0 * m * m;
|
||||
|
||||
mioni_manager_ = new G4DNAMultipleIonisationManager();
|
||||
|
||||
G4double Z{0.0}, A{0.0};
|
||||
G4String alpha_param_file{"dna/multipleionisation_alphaparam_champion.dat"};
|
||||
|
||||
if (particle == proton_def_) {
|
||||
|
||||
// *************************************************************************
|
||||
// for protons
|
||||
auto proton = proton_def_->GetParticleName();
|
||||
elow_tab_[proton] = model_elow_tab_[1];
|
||||
eupp_tab_[proton] = 3.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_proton = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_proton->LoadData("dna/sigma_ionisation_p_rudd");
|
||||
xs_tab_[proton] = xs_proton;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[proton]);
|
||||
SetHighEnergyLimit(eupp_tab_[proton]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_p.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(proton_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(proton_def_->GetAtomicMass());
|
||||
|
||||
} else if (particle == alpha_def_) {
|
||||
|
||||
//**************************************************************************
|
||||
// for alpha particles
|
||||
auto alpha = alpha_def_->GetParticleName();
|
||||
elow_tab_[alpha] = model_elow_tab_[4];
|
||||
eupp_tab_[alpha] = 23.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_alpha = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_alpha->LoadData("dna/sigma_ionisation_alphaplusplus_rudd");
|
||||
xs_tab_[alpha] = xs_alpha;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[alpha]);
|
||||
SetHighEnergyLimit(eupp_tab_[alpha]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_alphaplusplus.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(alpha_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(alpha_def_->GetAtomicMass());
|
||||
|
||||
} else if (particle == G4GenericIon::GenericIonDefinition()) {
|
||||
|
||||
// *************************************************************************
|
||||
// for carbon ions
|
||||
auto carbon = carbon_def_->GetParticleName();
|
||||
elow_tab_[carbon] = model_elow_tab_[5] * carbon_def_->GetAtomicMass();
|
||||
eupp_tab_[carbon] = 120.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_carbon = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_carbon->LoadData("dna/sigma_ionisation_c_rudd");
|
||||
xs_tab_[carbon] = xs_carbon;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[carbon]);
|
||||
SetHighEnergyLimit(eupp_tab_[carbon]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_c.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(carbon_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(carbon_def_->GetAtomicMass());
|
||||
|
||||
}
|
||||
|
||||
// load alpha parameter
|
||||
mioni_manager_->LoadAlphaParam(alpha_param_file, Z, A);
|
||||
|
||||
if (verbose_level_ > 0) {
|
||||
G4cout << "G4DNADoubleIonisationModel is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / keV << " keV for "
|
||||
<< particle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
water_density_ = G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(
|
||||
G4Material::GetMaterial("G4_WATER"));
|
||||
|
||||
atom_deex_ = G4LossTableManager::Instance()->AtomDeexcitation();
|
||||
|
||||
if (is_initialized_) { return; }
|
||||
|
||||
particle_change_ = GetParticleChangeForGamma();
|
||||
is_initialized_ = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double G4DNADoubleIonisationModel::GetLowEnergyLimit(const G4String& pname)
|
||||
{
|
||||
G4double elim{0.0};
|
||||
|
||||
EnergyLimitTable::iterator itr = elow_tab_.find(pname);
|
||||
if (itr != elow_tab_.end()) { elim = itr->second; }
|
||||
|
||||
return elim;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double G4DNADoubleIonisationModel::GetUppEnergyLimit(const G4String& pname)
|
||||
{
|
||||
G4double elim{0.0};
|
||||
|
||||
EnergyLimitTable::iterator itr = eupp_tab_.find(pname);
|
||||
if (itr != eupp_tab_.end()) { elim = itr->second; }
|
||||
|
||||
return elim;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double G4DNADoubleIonisationModel::CrossSectionPerVolume(
|
||||
const G4Material* material, const G4ParticleDefinition* pdef,
|
||||
G4double ekin, G4double, G4double)
|
||||
{
|
||||
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling G4DNADoubleIonisationModel::CrossSectionPerVolume()"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
if (pdef != proton_def_ && pdef != alpha_def_ && pdef != carbon_def_) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static G4double water_dens = (*water_density_)[material->GetIndex()];
|
||||
|
||||
const auto& pname = pdef->GetParticleName();
|
||||
|
||||
const auto low_energy_lim = GetLowEnergyLimit(pname);
|
||||
const auto upp_energy_lim = GetUppEnergyLimit(pname);
|
||||
|
||||
G4double sigma{0.0};
|
||||
if (ekin <= upp_energy_lim) {
|
||||
|
||||
if (ekin < low_energy_lim) { ekin = low_energy_lim; }
|
||||
|
||||
CrossSectionDataTable::iterator pos = xs_tab_.find(pname);
|
||||
if (pos == xs_tab_.end()) {
|
||||
G4Exception("G4DNADoubleIonisationModel::CrossSectionPerVolume",
|
||||
"em0002", FatalException,
|
||||
"Model not applicable to particle type.");
|
||||
}
|
||||
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
if (table != nullptr) {
|
||||
const auto a = mioni_manager_->GetAlphaParam(ekin);
|
||||
sigma = table->FindValue(ekin) * a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (verbose_level_ > 2) {
|
||||
|
||||
std::stringstream msg;
|
||||
|
||||
msg << "----------------------------------------------------------------\n";
|
||||
msg << " G4DNADoubleIonisationModel - XS INFO START\n";
|
||||
msg << " - Kinetic energy(eV): " << ekin/eV << ", Particle : "
|
||||
<< pdef->GetParticleName() << "\n";
|
||||
msg << " - Cross section per water molecule (cm^2): "
|
||||
<< sigma / cm / cm << "\n";
|
||||
msg << " - Cross section per water molecule (cm^-1): "
|
||||
<< sigma * water_dens / (1.0 / cm) << "\n";
|
||||
msg << " G4DNADoubleIonisationModel - XS INFO END\n";
|
||||
msg << "----------------------------------------------------------------\n";
|
||||
|
||||
G4cout << msg.str() << G4endl;
|
||||
|
||||
}
|
||||
|
||||
return (sigma * water_dens);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double G4DNADoubleIonisationModel::GenerateSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vsec, const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle, G4int ioni_shell,
|
||||
G4double& theta, G4double& phi, G4double& shell_energy)
|
||||
{
|
||||
auto pdef = particle->GetDefinition();
|
||||
|
||||
// get kinetic energy for a parent particle
|
||||
auto ekin1 = particle->GetKineticEnergy();
|
||||
|
||||
// sample kinetic energy for a secondary electron
|
||||
auto ekin2 = RandomizeEjectedElectronEnergy(pdef, ekin1, ioni_shell);
|
||||
|
||||
// sample momentum direction for a secondary electron
|
||||
auto sample_electron_direction = [this](
|
||||
const G4DynamicParticle* dp, G4double _ekin2, G4int _Z, G4int _ioni_shell,
|
||||
const G4MaterialCutsCouple* mcc, G4double& _theta, G4double& _phi) {
|
||||
|
||||
G4ThreeVector locdir;
|
||||
|
||||
if (_theta > 0.0) {
|
||||
|
||||
auto costh = std::cos(_theta);
|
||||
auto sinth = std::sqrt((1.0 - costh) * (1.0 + costh));
|
||||
locdir.set(sinth * std::cos(_phi), sinth * std::sin(_phi), costh);
|
||||
locdir.rotateUz(dp->GetMomentumDirection());
|
||||
|
||||
} else {
|
||||
|
||||
locdir = GetAngularDistribution()->SampleDirectionForShell(
|
||||
dp, _ekin2, _Z, _ioni_shell, mcc->GetMaterial());
|
||||
_theta = locdir.theta();
|
||||
_phi = locdir.phi();
|
||||
|
||||
}
|
||||
|
||||
return locdir;
|
||||
};
|
||||
|
||||
constexpr G4int Z = 8;
|
||||
auto delta_dir = sample_electron_direction(
|
||||
particle, ekin2, Z, ioni_shell, couple, theta, phi);
|
||||
|
||||
// generate a secondary electron and put it into the stack
|
||||
auto dp = new G4DynamicParticle(G4Electron::Electron(), delta_dir, ekin2);
|
||||
vsec->push_back(dp);
|
||||
|
||||
if (!atom_deex_ || ioni_shell != 4) { return ekin2; }
|
||||
|
||||
// ***************************************************************************
|
||||
// Only atomic deexcitation from K shell is considered
|
||||
|
||||
constexpr auto k_shell = G4AtomicShellEnumerator(0);
|
||||
const auto shell = atom_deex_->GetAtomicShell(Z, k_shell);
|
||||
|
||||
// get number of secondary electrons in the stack
|
||||
// before processing atomic deescitation
|
||||
const auto num_sec_init = vsec->size();
|
||||
|
||||
// perform atomic deexcitation process
|
||||
atom_deex_->GenerateParticles(vsec, shell, Z, 0, 0);
|
||||
|
||||
// get number of secondary electrons in the stack
|
||||
// after processing atomic deescitation
|
||||
const auto num_sec_final = vsec->size();
|
||||
|
||||
if (num_sec_final == num_sec_init) { return ekin2; }
|
||||
|
||||
for (auto i = num_sec_init; i < num_sec_final; i++) {
|
||||
|
||||
auto e = ((*vsec)[i])->GetKineticEnergy();
|
||||
|
||||
// Check if there is enough residual energy
|
||||
if (shell_energy < e) {
|
||||
|
||||
// Invalid secondary: not enough energy to create it!
|
||||
// Keep its energy in the local deposit
|
||||
delete (*vsec)[i];
|
||||
(*vsec)[i] = 0;
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// Ok, this is a valid secondary: keep it
|
||||
shell_energy -= e;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
return ekin2;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNADoubleIonisationModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vsec, const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle, G4double, G4double)
|
||||
{
|
||||
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling SampleSecondaries() of G4DNADoubleIonisationModel"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// get the definition for this parent particle
|
||||
auto pdef = particle->GetDefinition();
|
||||
|
||||
// get kinetic energy
|
||||
auto ekin = particle->GetKineticEnergy();
|
||||
|
||||
// get particle name
|
||||
const auto& pname = pdef->GetParticleName();
|
||||
|
||||
// get energy limits
|
||||
const auto low_energy_lim = GetLowEnergyLimit(pname);
|
||||
|
||||
// ***************************************************************************
|
||||
// stop the transportation process of this parent particle
|
||||
// if its kinetic energy is below the lower limit
|
||||
if (ekin < low_energy_lim) {
|
||||
particle_change_->SetProposedKineticEnergy(0.0);
|
||||
particle_change_->ProposeTrackStatus(fStopAndKill);
|
||||
particle_change_->ProposeLocalEnergyDeposit(ekin);
|
||||
return;
|
||||
}
|
||||
// ***************************************************************************
|
||||
|
||||
constexpr G4int kNumSecondaries = 2;
|
||||
constexpr G4double kDeltaTheta = pi;
|
||||
|
||||
G4int ioni_shell[kNumSecondaries];
|
||||
G4double shell_energy[kNumSecondaries];
|
||||
|
||||
const auto scale_param = mioni_manager_->GetAlphaParam(ekin);
|
||||
G4double tot_ioni_energy{0.0};
|
||||
for (G4int i = 0; i < kNumSecondaries; i++) {
|
||||
ioni_shell[i] = RandomSelect(ekin, scale_param, pname);
|
||||
shell_energy[i] = ::water_structure.IonisationEnergy(ioni_shell[i]);
|
||||
tot_ioni_energy += shell_energy[i];
|
||||
}
|
||||
|
||||
if (ekin < tot_ioni_energy || tot_ioni_energy < energy_threshold_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// generate secondary electrons
|
||||
G4double theta{0.0}, phi{0.0}, tot_ekin2{0.0};
|
||||
for (G4int i = 0; i < kNumSecondaries; i++) {
|
||||
tot_ekin2 += GenerateSecondaries(vsec, couple, particle, ioni_shell[i],
|
||||
theta, phi, shell_energy[i]);
|
||||
theta += kDeltaTheta;
|
||||
}
|
||||
|
||||
// This should never happen
|
||||
if (mioni_manager_->CheckShellEnergy(eDoubleIonisedMolecule, shell_energy)) {
|
||||
G4Exception("G4DNADoubleIonisatioModel::SampleSecondaries()",
|
||||
"em2050", FatalException, "Negative local energy deposit");
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// update kinematics for this parent particle
|
||||
const auto primary_dir = particle->GetMomentumDirection();
|
||||
particle_change_->ProposeMomentumDirection(primary_dir);
|
||||
|
||||
const auto scattered_energy = ekin - tot_ioni_energy - tot_ekin2;
|
||||
|
||||
// update total amount of shell energy
|
||||
tot_ioni_energy = shell_energy[0] + shell_energy[1];
|
||||
|
||||
if (stat_code_) {
|
||||
particle_change_->SetProposedKineticEnergy(ekin);
|
||||
particle_change_->ProposeLocalEnergyDeposit(ekin - scattered_energy);
|
||||
} else {
|
||||
particle_change_->SetProposedKineticEnergy(scattered_energy);
|
||||
particle_change_->ProposeLocalEnergyDeposit(tot_ioni_energy);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// generate double-ionized water molecules (H2O^2+)
|
||||
const auto the_track = particle_change_->GetCurrentTrack();
|
||||
mioni_manager_->CreateMultipleIonisedWaterMolecule(
|
||||
eDoubleIonisedMolecule, ioni_shell, the_track);
|
||||
// ***************************************************************************
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double G4DNADoubleIonisationModel::RandomizeEjectedElectronEnergy(
|
||||
G4ParticleDefinition* pdef, G4double ekin, G4int shell)
|
||||
{
|
||||
|
||||
//
|
||||
// based on RandomizeEjectedElectronEnergy()
|
||||
// of G4DNARuddIonisationExtendedModel
|
||||
//
|
||||
|
||||
::FuncParams par;
|
||||
::setup_rejection_function(pdef, ekin, shell, par);
|
||||
|
||||
// calculate maximum value
|
||||
G4double emax{0.0}, val;
|
||||
for (G4double en = 0.0; en < 20.0; en += 1.0) {
|
||||
val = ::rejection_function(pdef, shell, par, en);
|
||||
if (val <= emax) { continue; }
|
||||
emax = val;
|
||||
}
|
||||
|
||||
G4double proposed_energy, rand;
|
||||
do {
|
||||
// Proposed energy by inverse function sampling
|
||||
proposed_energy = ::proposed_sampled_energy(par);
|
||||
rand = G4UniformRand() * emax;
|
||||
val = ::rejection_function(pdef, shell, par, proposed_energy);
|
||||
} while (rand > val);
|
||||
|
||||
return proposed_energy;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4int G4DNADoubleIonisationModel::RandomSelect(
|
||||
G4double ekin, G4double scale_param, const G4String& pname)
|
||||
{
|
||||
|
||||
//
|
||||
// based on RandomSelect() of G4DNARuddIonisationExtendedModel
|
||||
//
|
||||
|
||||
// Retrieve data table corresponding to the current particle type
|
||||
CrossSectionDataTable::iterator pos = xs_tab_.find(pname);
|
||||
|
||||
if (pos == xs_tab_.end()) {
|
||||
G4Exception("G4DNADoubleIonisationModel::RandomSelect", "em0002",
|
||||
FatalException, "Model not applicable to particle type.");
|
||||
}
|
||||
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
|
||||
if (table != nullptr) {
|
||||
|
||||
// get total number of energy level
|
||||
const auto num_component = table->NumberOfComponents();
|
||||
|
||||
auto* valuesBuffer = new G4double[num_component];
|
||||
|
||||
auto shell = num_component;
|
||||
G4double value = 0.0;
|
||||
|
||||
while (shell > 0) {
|
||||
shell--;
|
||||
valuesBuffer[shell] = table->GetComponent((G4int)shell)->FindValue(ekin)
|
||||
* scale_param;
|
||||
value += valuesBuffer[shell];
|
||||
}
|
||||
|
||||
value *= G4UniformRand();
|
||||
|
||||
shell = num_component;
|
||||
|
||||
while (shell > 0) {
|
||||
shell--;
|
||||
if (valuesBuffer[shell] > value) {
|
||||
if (valuesBuffer) { delete [] valuesBuffer; }
|
||||
return (G4int)shell;
|
||||
}
|
||||
value -= valuesBuffer[shell];
|
||||
}
|
||||
|
||||
if (valuesBuffer) { delete [] valuesBuffer; }
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -54,18 +55,23 @@ G4VEmModel(nam)
|
||||
G4ProductionCutsTable* theCoupleTable =
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
auto numOfCouples = (G4int)theCoupleTable->GetTableSize();
|
||||
|
||||
fpBaseWater = G4Material::GetMaterial("G4_WATER");
|
||||
|
||||
for(G4int i=0; i<numOfCouples; ++i)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
|
||||
if(!material) material = couple->GetMaterial();
|
||||
|
||||
auto nelm = (G4int)material->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
|
||||
if(nelm==1)
|
||||
{// Protection: only for single element
|
||||
G4int Z = 79;
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
Z = G4lrint((*theElementVector)[0]->GetZ());
|
||||
// Protection: only for GOLD
|
||||
if (Z==79){
|
||||
@@ -78,8 +84,8 @@ G4VEmModel(nam)
|
||||
//continue;
|
||||
}
|
||||
}else{// Protection: H2O only is available
|
||||
if(material->GetName()=="G4_WATER"){
|
||||
flowEnergyLimit = 10. * eV;
|
||||
if(material==fpBaseWater){
|
||||
flowEnergyLimit = 10. * eV;
|
||||
fhighEnergyLimit = 1 * MeV;
|
||||
SetLowEnergyLimit (flowEnergyLimit);
|
||||
SetHighEnergyLimit(fhighEnergyLimit);
|
||||
@@ -99,7 +105,6 @@ G4VEmModel(nam)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fParticleChangeForGamma = nullptr;
|
||||
fpMolDensity = nullptr;
|
||||
|
||||
@@ -111,31 +116,9 @@ G4VEmModel(nam)
|
||||
|
||||
G4DNAELSEPAElasticModel::~G4DNAELSEPAElasticModel()
|
||||
{
|
||||
//std::map<G4int,G4DNACrossSectionDataSet*,
|
||||
// std::less<G4String>>::iterator posZ;
|
||||
//for (posZ = tableZData.begin(); posZ != tableZData.end(); ++posZ)
|
||||
//{
|
||||
// G4DNACrossSectionDataSet* table = posZ->second;
|
||||
// delete table;
|
||||
//}
|
||||
//for (posZ = tableZData_Au.begin(); posZ != tableZData_Au.end(); ++posZ)
|
||||
//{
|
||||
// G4DNACrossSectionDataSet* table = posZ->second;
|
||||
// delete table;
|
||||
//}
|
||||
//for (posZ = tableZData_H2O.begin(); posZ != tableZData_H2O.end(); ++posZ)
|
||||
//{
|
||||
// G4DNACrossSectionDataSet* table = posZ->second;
|
||||
// delete table;
|
||||
//}
|
||||
|
||||
delete fpData_Au;
|
||||
delete fpData_H2O;
|
||||
|
||||
//eEdummyVecZ.clear();
|
||||
//eCumZ.clear();
|
||||
//fAngleDataZ.clear();
|
||||
|
||||
eEdummyVec_Au.clear();
|
||||
eEdummyVec_H2O.clear();
|
||||
eCum_Au.clear();
|
||||
@@ -168,22 +151,20 @@ const G4DataVector& )
|
||||
// UNIT OF TCS
|
||||
G4double scaleFactor = 1.*cm*cm;
|
||||
|
||||
//tableZData.clear();
|
||||
//tableZData_Au.clear();
|
||||
//tableZData_H2O.clear();
|
||||
|
||||
fpData_Au=nullptr;
|
||||
fpData_H2O=nullptr;
|
||||
fpBaseWater = G4Material::GetMaterial("G4_WATER");
|
||||
|
||||
for(G4int i=0; i<numOfCouples; ++i)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
|
||||
if(!material) material = couple->GetMaterial();
|
||||
|
||||
auto nelm = (G4int)material->GetNumberOfElements();
|
||||
if (nelm==1){// Protection: only for single element
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
G4int Z = G4lrint((*theElementVector)[0]->GetZ());
|
||||
if (Z!=79)// Protection: only for GOLD
|
||||
{
|
||||
@@ -198,13 +179,6 @@ const G4DataVector& )
|
||||
oss.clear(stringstream::goodbit);
|
||||
oss << Z;
|
||||
fileZElectron += oss.str()+"_muffintin";
|
||||
|
||||
//G4DNACrossSectionDataSet* tableZE =
|
||||
// new G4DNACrossSectionDataSet
|
||||
// (new G4LogLogInterpolation, eV,scaleFactor );
|
||||
//tableZE->LoadData(fileZElectron);
|
||||
////tableZData_Au[0] = tableZE;
|
||||
//tableZData[Z] = tableZE;
|
||||
|
||||
fpData_Au = new G4DNACrossSectionDataSet(new G4LogLogInterpolation,
|
||||
eV,
|
||||
@@ -212,7 +186,8 @@ const G4DataVector& )
|
||||
fpData_Au->LoadData(fileZElectron);
|
||||
|
||||
std::ostringstream eFullFileNameZ;
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
const char *path = G4EmParameters::Instance()->GetDirLEDATA();
|
||||
|
||||
if (path == nullptr)
|
||||
{
|
||||
G4Exception("G4DNAELSEPAElasticModel::Initialise","em0002",
|
||||
@@ -236,44 +211,32 @@ const G4DataVector& )
|
||||
FatalException,"Missing data file for cumulated DCS");
|
||||
return;
|
||||
}
|
||||
|
||||
//eEdummyVecZ.clear();
|
||||
//eCumZ.clear();
|
||||
//fAngleDataZ.clear();
|
||||
|
||||
eEdummyVec_Au.clear();
|
||||
eCum_Au.clear();
|
||||
fAngleData_Au.clear();
|
||||
|
||||
//eEdummyVecZ[Z].push_back(0.);
|
||||
eEdummyVec_Au.push_back(0.);
|
||||
do
|
||||
{
|
||||
G4double eDummy;
|
||||
G4double cumDummy;
|
||||
eDiffCrossSectionZ>>eDummy>>cumDummy;
|
||||
//if (eDummy != eEdummyVecZ[Z].back())
|
||||
if (eDummy != eEdummyVec_Au.back())
|
||||
{
|
||||
|
||||
//eEdummyVecZ[Z].push_back(eDummy);
|
||||
eEdummyVec_Au.push_back(eDummy);
|
||||
//eCumZ[Z][eDummy].push_back(0.);
|
||||
eCum_Au[eDummy].push_back(0.);
|
||||
}
|
||||
//eDiffCrossSectionZ>>fAngleDataZ[Z][eDummy][cumDummy];
|
||||
eDiffCrossSectionZ>>fAngleData_Au[eDummy][cumDummy];
|
||||
//if (cumDummy != eCumZ[Z][eDummy].back())
|
||||
if (cumDummy != eCum_Au[eDummy].back())
|
||||
{
|
||||
//eCumZ[Z][eDummy].push_back(cumDummy);
|
||||
eCum_Au[eDummy].push_back(cumDummy);
|
||||
}
|
||||
}while(!eDiffCrossSectionZ.eof());
|
||||
}
|
||||
|
||||
}else{// Protection: H2O only is available
|
||||
if(material->GetName()=="G4_WATER"){
|
||||
if(material == fpBaseWater && !fpData_H2O){
|
||||
if (LowEnergyLimit() < 10*eV)
|
||||
{
|
||||
G4cout<<"G4DNAELSEPAElasticModel: low energy limit increased from "
|
||||
@@ -292,13 +255,6 @@ const G4DataVector& )
|
||||
|
||||
G4String fileZElectron("dna/sigma_elastic_e_elsepa_muffin");
|
||||
|
||||
//G4DNACrossSectionDataSet* tableZE =
|
||||
// new G4DNACrossSectionDataSet(
|
||||
// new G4LogLogInterpolation, eV,scaleFactor );
|
||||
//tableZE->LoadData(fileZElectron);
|
||||
////tableZData_H2O[0] = tableZE;
|
||||
//tableZData[0] = tableZE;
|
||||
|
||||
fpData_H2O = new G4DNACrossSectionDataSet(new G4LogLogInterpolation,
|
||||
eV,
|
||||
scaleFactor );
|
||||
@@ -306,7 +262,7 @@ const G4DataVector& )
|
||||
|
||||
std::ostringstream eFullFileNameZ;
|
||||
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
const char *path = G4EmParameters::Instance()->GetDirLEDATA();
|
||||
if (path == nullptr)
|
||||
{
|
||||
G4Exception("G4DNAELSEPAElasticModel::Initialise","em0004",
|
||||
@@ -328,15 +284,10 @@ const G4DataVector& )
|
||||
FatalException,
|
||||
"Missing data file for cumulated DCS");
|
||||
|
||||
//eEdummyVecZ.clear();
|
||||
//eCumZ.clear();
|
||||
//fAngleDataZ.clear();
|
||||
|
||||
eEdummyVec_H2O.clear();
|
||||
eCum_H2O.clear();
|
||||
fAngleData_H2O.clear();
|
||||
|
||||
//eEdummyVecZ[0].push_back(0.);
|
||||
eEdummyVec_H2O.push_back(0.);
|
||||
|
||||
do
|
||||
@@ -344,19 +295,13 @@ const G4DataVector& )
|
||||
G4double eDummy;
|
||||
G4double cumDummy;
|
||||
eDiffCrossSectionZ>>eDummy>>cumDummy;
|
||||
//if (eDummy != eEdummyVecZ[0].back())
|
||||
if (eDummy != eEdummyVec_H2O.back())
|
||||
{
|
||||
//eEdummyVecZ[0].push_back(eDummy);
|
||||
eEdummyVec_H2O.push_back(eDummy);
|
||||
//eCumZ[0][eDummy].push_back(0.);
|
||||
eCum_H2O[eDummy].push_back(0.);
|
||||
}
|
||||
//eDiffCrossSectionZ>>fAngleDataZ[0][eDummy][cumDummy];
|
||||
eDiffCrossSectionZ>>fAngleData_H2O[eDummy][cumDummy];
|
||||
//if (cumDummy != eCumZ[0][eDummy].back()){
|
||||
if (cumDummy != eCum_H2O[eDummy].back()){
|
||||
//eCumZ[0][eDummy].push_back(cumDummy);
|
||||
eCum_H2O[eDummy].push_back(cumDummy);
|
||||
}
|
||||
}while(!eDiffCrossSectionZ.eof());
|
||||
@@ -378,7 +323,10 @@ const G4DataVector& )
|
||||
|
||||
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
fpMolDensity = nullptr;
|
||||
|
||||
fpMolDensity =
|
||||
G4DNAMolecularMaterial::Instance()->
|
||||
GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER"));
|
||||
|
||||
isInitialised = true;
|
||||
}
|
||||
@@ -403,13 +351,13 @@ G4double G4DNAELSEPAElasticModel::CrossSectionPerVolume
|
||||
G4double atomicNDensity=0.0;
|
||||
G4double sigma=0;
|
||||
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
std::size_t nelm = material->GetNumberOfElements();
|
||||
if (nelm==1) // Protection: only for single element
|
||||
{
|
||||
// Protection: only for GOLD
|
||||
if (material->GetZ()!=79) return 0.0;
|
||||
|
||||
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
G4int Z = G4lrint((*theElementVector)[0]->GetZ());
|
||||
|
||||
const G4String& particleName = particle->GetParticleName();
|
||||
@@ -420,28 +368,6 @@ G4double G4DNAELSEPAElasticModel::CrossSectionPerVolume
|
||||
{
|
||||
if (ekin < fkillBelowEnergy_Au) return DBL_MAX;
|
||||
|
||||
//std::map< G4int,G4DNACrossSectionDataSet*,
|
||||
// std::less<G4String> >::iterator pos;
|
||||
////pos = tableZData_Au.find(0);
|
||||
//pos = tableZData.find(Z);
|
||||
//
|
||||
////if (pos != tableZData_Au.end())
|
||||
//if (pos != tableZData.end())
|
||||
//{
|
||||
// G4DNACrossSectionDataSet* table = pos->second;
|
||||
// if (table != 0)
|
||||
// {
|
||||
// // XS takes its 10 eV value below 10 eV for GOLD
|
||||
// if (ekin < 10*eV) sigma = table->FindValue(10*eV);
|
||||
// else sigma = table->FindValue(ekin);
|
||||
// }
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// G4Exception("G4DNAELSEPAElasticModel::ComputeCrossSectionPerVolume",
|
||||
// "em0006",FatalException,"Model not applicable to particle type.");
|
||||
//}
|
||||
|
||||
if (ekin < 10*eV) sigma = fpData_Au->FindValue(10*eV);
|
||||
else sigma = fpData_Au->FindValue(ekin);
|
||||
}
|
||||
@@ -462,30 +388,11 @@ G4double G4DNAELSEPAElasticModel::CrossSectionPerVolume
|
||||
}
|
||||
else
|
||||
{
|
||||
fpMolDensity =
|
||||
G4DNAMolecularMaterial::Instance()->
|
||||
GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER"));
|
||||
atomicNDensity = (*fpMolDensity)[material->GetIndex()];
|
||||
if(atomicNDensity!= 0.0)
|
||||
{
|
||||
if (ekin < HighEnergyLimit() && ekin >= LowEnergyLimit())
|
||||
{
|
||||
//std::map< G4int,G4DNACrossSectionDataSet*,
|
||||
//std::less<G4String> >::iterator pos;
|
||||
////pos = tableZData_H2O.find(0); // the data is stored as Z=0
|
||||
//pos = tableZData.find(0); // the data is stored as Z=0
|
||||
////SI : XS must not be zero
|
||||
//// otherwise sampling of secondaries method ignored
|
||||
////if (pos != tableZData_H2O.end())
|
||||
//if (pos != tableZData.end())
|
||||
//{
|
||||
// G4DNACrossSectionDataSet* table = pos->second;
|
||||
// if (table != 0)
|
||||
// {
|
||||
// sigma = table->FindValue(ekin);
|
||||
// }
|
||||
//}
|
||||
|
||||
sigma = fpData_H2O->FindValue(ekin);
|
||||
}
|
||||
}
|
||||
@@ -524,11 +431,13 @@ void G4DNAELSEPAElasticModel::SampleSecondaries(
|
||||
|
||||
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
|
||||
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
|
||||
if(!material) material = couple->GetMaterial();
|
||||
|
||||
std::size_t nelm = material->GetNumberOfElements();
|
||||
if (nelm==1) // Protection: only for single element
|
||||
{
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
G4int Z = G4lrint((*theElementVector)[0]->GetZ());
|
||||
if (Z!=79) return;
|
||||
if (electronEnergy0 < fkillBelowEnergy_Au)
|
||||
@@ -571,7 +480,7 @@ void G4DNAELSEPAElasticModel::SampleSecondaries(
|
||||
}
|
||||
else
|
||||
{
|
||||
if(material->GetName()=="G4_WATER")
|
||||
if(material == fpBaseWater)
|
||||
{
|
||||
//The data for water is stored as Z=0
|
||||
G4double cosTheta = RandomizeCosTheta(0,electronEnergy0);
|
||||
@@ -616,9 +525,7 @@ G4double G4DNAELSEPAElasticModel::Theta(G4int Z,
|
||||
|
||||
if (particleDefinition == G4Electron::ElectronDefinition())
|
||||
{
|
||||
//std::vector<G4double>::iterator e2
|
||||
// = std::upper_bound(eEdummyVecZ[Z].begin(),
|
||||
// eEdummyVecZ[Z].end(), k);
|
||||
|
||||
std::vector<G4double>::iterator e2;
|
||||
if(Z==0){
|
||||
e2 = std::upper_bound(eEdummyVec_H2O.begin(),
|
||||
@@ -630,9 +537,6 @@ G4double G4DNAELSEPAElasticModel::Theta(G4int Z,
|
||||
|
||||
auto e1 = e2 - 1;
|
||||
|
||||
//std::vector<G4double>::iterator cum12
|
||||
// = std::upper_bound(eCumZ[Z][(*e1)].begin(),
|
||||
// eCumZ[Z][(*e1)].end(),integrDiff);
|
||||
std::vector<G4double>::iterator cum12;
|
||||
if(Z==0){
|
||||
cum12 = std::upper_bound(eCum_H2O[(*e1)].begin(),
|
||||
@@ -665,11 +569,6 @@ G4double G4DNAELSEPAElasticModel::Theta(G4int Z,
|
||||
valuecum21 = *cum21;
|
||||
valuecum22 = *cum22;
|
||||
|
||||
|
||||
//a11 = fAngleDataZ[Z][valueE1][valuecum11];
|
||||
//a12 = fAngleDataZ[Z][valueE1][valuecum12];
|
||||
//a21 = fAngleDataZ[Z][valueE2][valuecum21];
|
||||
//a22 = fAngleDataZ[Z][valueE2][valuecum22];
|
||||
if(Z==0){
|
||||
a11 = fAngleData_H2O[valueE1][valuecum11];
|
||||
a12 = fAngleData_H2O[valueE1][valuecum12];
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4DNAGeneralIonIonisationModel.hh"
|
||||
#include "G4DNARuddIonisationExtendedModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNAGeneralIonIonisationModel::G4DNAGeneralIonIonisationModel(
|
||||
const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VEmModel(nam)
|
||||
{
|
||||
fRuddIonisation = new G4DNARuddIonisationExtendedModel();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAGeneralIonIonisationModel::Initialise(const G4ParticleDefinition* part,
|
||||
const G4DataVector& v)
|
||||
{
|
||||
if (part != G4GenericIon::GenericIon()) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Wrong particle type <" << part->GetParticleName()
|
||||
<< "> - only G4GenericIon is allowed";
|
||||
G4Exception("G4DNAGeneralIonIonisationModel::Initialise(...)",
|
||||
"em2001", FatalException, ed);
|
||||
}
|
||||
|
||||
// stationary model and tracking cut may be defined between runs
|
||||
auto param = G4EmParameters::Instance();
|
||||
fLowestEnergy = param->LowestMuHadEnergy();
|
||||
|
||||
// this pointer should be defined once before initialisation of
|
||||
// concrete models
|
||||
if (nullptr == fParticleChangeForGamma) {
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
|
||||
// should be set once for each model
|
||||
fRuddIonisation->SetParticleChange(fParticleChangeForGamma);
|
||||
}
|
||||
|
||||
// initialisation of concrete models - put extra model here
|
||||
fRuddIonisation->Initialise(part, v);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAGeneralIonIonisationModel::StartTracking(G4Track* track)
|
||||
{
|
||||
fDynParticle = track->GetDynamicParticle();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAGeneralIonIonisationModel::CrossSectionPerVolume(const G4Material* mat,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double, G4double)
|
||||
{
|
||||
// apply tracking cut
|
||||
if (ekin <= fLowestEnergy) { return DBL_MAX; }
|
||||
|
||||
// select model
|
||||
fCurrentModel = fRuddIonisation;
|
||||
|
||||
// G4int Z = GetAtomicNumber();
|
||||
// G4int Q = G4lrint(fDynParticle->GetCharge()/CLHEP::eplus);
|
||||
|
||||
// compute concrete cross section
|
||||
return fCurrentModel->CrossSectionPerVolume(mat, p, ekin);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAGeneralIonIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double, G4double)
|
||||
{
|
||||
G4double ekin = dp->GetKineticEnergy();
|
||||
|
||||
// tracking cut
|
||||
if (ekin <= fLowestEnergy) {
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(0.);
|
||||
fParticleChangeForGamma->ProposeTrackStatus(fStopButAlive);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(ekin);
|
||||
return;
|
||||
}
|
||||
|
||||
// sample secondaries by the selected model
|
||||
fCurrentModel->SampleSecondaries(fvect, couple, dp);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
+142
-212
@@ -25,27 +25,27 @@
|
||||
// 20/2/2019
|
||||
// Author: HoangTRAN
|
||||
|
||||
#include <memory>
|
||||
#include "G4DNAIndependentReactionTimeStepper.hh"
|
||||
#include "G4VDNAReactionModel.hh"
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4Molecule.hh"
|
||||
|
||||
#include "G4ChemicalMoleculeFinder.hh"
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAMakeReaction.hh"
|
||||
#include "G4ITReactionChange.hh"
|
||||
#include "G4Scheduler.hh"
|
||||
#include "G4IRTUtils.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
#include "G4DiffusionControlledReactionModel.hh"
|
||||
#include "G4IRTUtils.hh"
|
||||
#include "G4ITReactionChange.hh"
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4Scheduler.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4VDNAReactionModel.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include <memory>
|
||||
using namespace std;
|
||||
using namespace CLHEP;
|
||||
|
||||
G4DNAIndependentReactionTimeStepper::Utils::Utils(const G4Track& trackA,
|
||||
const G4Track& trackB)
|
||||
: fTrackA(trackA)
|
||||
, fTrackB(trackB)
|
||||
G4DNAIndependentReactionTimeStepper::Utils::Utils(const G4Track& trackA, const G4Track& trackB)
|
||||
: fTrackA(trackA), fTrackB(trackB)
|
||||
{
|
||||
fpMoleculeA = GetMolecule(trackA);
|
||||
fpMoleculeB = GetMolecule(trackA);
|
||||
@@ -65,16 +65,15 @@ void G4DNAIndependentReactionTimeStepper::Prepare()
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::InitializeForNewTrack()
|
||||
{
|
||||
if(fReactants != nullptr)
|
||||
{
|
||||
if (fReactants != nullptr) {
|
||||
fReactants.reset();
|
||||
}
|
||||
fSampledMinTimeStep = DBL_MAX;
|
||||
fSampledMinTimeStep = DBL_MAX;
|
||||
fHasAlreadyReachedNullTime = false;
|
||||
}
|
||||
|
||||
G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
|
||||
const G4Track& trackA, const G4double& userMinTimeStep)
|
||||
G4double G4DNAIndependentReactionTimeStepper::CalculateStep(const G4Track& trackA,
|
||||
const G4double& userMinTimeStep)
|
||||
{
|
||||
auto pMoleculeA = GetMolecule(trackA);
|
||||
InitializeForNewTrack();
|
||||
@@ -82,14 +81,13 @@ G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
|
||||
fCheckedTracks.insert(trackA.GetTrackID());
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if(fVerbose != 0)
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "________________________________________________________________"
|
||||
"_______"
|
||||
<< G4endl;
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep" << G4endl;
|
||||
G4cout << "Check done for molecule : " << pMoleculeA->GetName() << " ("
|
||||
<< trackA.GetTrackID() << ") " << G4endl;
|
||||
G4cout << "Check done for molecule : " << pMoleculeA->GetName() << " (" << trackA.GetTrackID()
|
||||
<< ") " << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -97,54 +95,41 @@ G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
|
||||
|
||||
const auto pReactantList = fMolecularReactionTable->CanReactWith(pMolConfA);
|
||||
|
||||
if(pReactantList == nullptr)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
|
||||
G4cout << "!!! WARNING" << G4endl;
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will "
|
||||
"return infinity "
|
||||
"for the reaction because the molecule "
|
||||
<< pMoleculeA->GetName()
|
||||
<< " does not have any reactants given in the reaction table."
|
||||
<< G4endl;
|
||||
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
|
||||
if (pReactantList == nullptr) {
|
||||
if(fVerbose > 1) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "G4DNAIndependentReactionTimeStepper::CalculateStep will return infinity "
|
||||
"for the reaction because the molecule "
|
||||
<< pMoleculeA->GetName() << " does not have any reactants given in the reaction table."
|
||||
<< G4endl;
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::CalculateStep",
|
||||
"G4DNAIndependentReactionTimeStepper03", JustWarning, msg);
|
||||
}
|
||||
#endif
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
auto nbReactives = (G4int)pReactantList->size();
|
||||
auto nbReactives = (G4int)pReactantList->size();
|
||||
|
||||
if(nbReactives == 0)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
// DEBUG
|
||||
if(fVerbose != 0)
|
||||
{
|
||||
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
|
||||
G4cout << "!!! WARNING" << G4endl;
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will "
|
||||
"return infinity "
|
||||
"for the reaction because the molecule "
|
||||
<< pMoleculeA->GetName()
|
||||
<< " does not have any reactants given in the reaction table."
|
||||
<< "This message can also result from a wrong implementation of "
|
||||
"the reaction table."
|
||||
<< G4endl;
|
||||
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
|
||||
if (nbReactives == 0) {
|
||||
if(fVerbose != 0){
|
||||
G4ExceptionDescription msg;
|
||||
msg << "G4DNAIndependentReactionTimeStepper::CalculateStep will "
|
||||
"return infinity "
|
||||
"for the reaction because the molecule "
|
||||
<< pMoleculeA->GetName() << " does not have any reactants given in the reaction table."
|
||||
<< "This message can also result from a wrong implementation of "
|
||||
"the reaction table."
|
||||
<< G4endl;
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::CalculateStep",
|
||||
"G4DNAIndependentReactionTimeStepper04", JustWarning, msg);
|
||||
}
|
||||
#endif
|
||||
return DBL_MAX;
|
||||
}
|
||||
fReactants = std::make_shared<vector<G4Track*>>();
|
||||
fReactionModel->Initialise(pMolConfA, trackA);
|
||||
for(G4int i = 0; i < nbReactives; ++i)
|
||||
{
|
||||
for (G4int i = 0; i < nbReactives; ++i) {
|
||||
auto pMoleculeB = (*pReactantList)[i];
|
||||
G4int key = pMoleculeB->GetMoleculeID();
|
||||
G4int key = pMoleculeB->GetMoleculeID();
|
||||
|
||||
// fRCutOff = G4IRTUtils::GetRCutOff(1 * ps);
|
||||
fRCutOff = G4IRTUtils::GetRCutOff();
|
||||
@@ -153,51 +138,40 @@ G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
|
||||
const G4double Reff = fReactionModel->GetReactionRadius(i);
|
||||
std::vector<std::pair<G4TrackList::iterator, G4double>> resultIndices;
|
||||
resultIndices.clear();
|
||||
G4ChemicalMoleculeFinder::Instance()->FindNearestInRange(
|
||||
trackA, key, fRCutOff, resultIndices);
|
||||
G4ChemicalMoleculeFinder::Instance()->FindNearestInRange(trackA, key, fRCutOff, resultIndices);
|
||||
|
||||
if(resultIndices.empty())
|
||||
{
|
||||
if (resultIndices.empty()) {
|
||||
continue;
|
||||
}
|
||||
for(auto& it : resultIndices)
|
||||
{
|
||||
for (auto& it : resultIndices) {
|
||||
G4Track* pTrackB = *(std::get<0>(it));
|
||||
|
||||
if(pTrackB == &trackA)
|
||||
{
|
||||
if (pTrackB == &trackA) {
|
||||
continue;
|
||||
}
|
||||
if(pTrackB == nullptr)
|
||||
{
|
||||
if (pTrackB == nullptr) {
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No trackB no valid";
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper"
|
||||
"::CalculateStep()",
|
||||
"G4DNAIndependentReactionTimeStepper007", FatalException,
|
||||
exceptionDescription);
|
||||
}else
|
||||
{
|
||||
if(fCheckedTracks.find(pTrackB->GetTrackID()) != fCheckedTracks.end())
|
||||
{
|
||||
G4Exception(
|
||||
"G4DNAIndependentReactionTimeStepper"
|
||||
"::CalculateStep()",
|
||||
"G4DNAIndependentReactionTimeStepper007", FatalException, exceptionDescription);
|
||||
}
|
||||
else {
|
||||
if (fCheckedTracks.find(pTrackB->GetTrackID()) != fCheckedTracks.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Utils utils(trackA, *pTrackB);
|
||||
|
||||
auto pMolB = GetMolecule(pTrackB);
|
||||
auto pMolConfB = pMolB->GetMolecularConfiguration();
|
||||
auto pMolB = GetMolecule(pTrackB);
|
||||
auto pMolConfB = pMolB->GetMolecularConfiguration();
|
||||
G4double distance = (trackA.GetPosition() - pTrackB->GetPosition()).mag();
|
||||
if(distance * distance < Reff * Reff)
|
||||
{
|
||||
auto reactionData =
|
||||
fMolecularReactionTable->GetReactionData(pMolConfA, pMolConfB);
|
||||
if(G4Scheduler::Instance()->GetGlobalTime() == G4Scheduler::Instance()->GetStartTime())
|
||||
{
|
||||
if(reactionData->GetProbability() > G4UniformRand())
|
||||
{
|
||||
if(!fHasAlreadyReachedNullTime)
|
||||
{
|
||||
if (distance * distance < Reff * Reff) {
|
||||
auto reactionData = fMolecularReactionTable->GetReactionData(pMolConfA, pMolConfB);
|
||||
if (G4Scheduler::Instance()->GetGlobalTime() == G4Scheduler::Instance()->GetStartTime()) {
|
||||
if (reactionData->GetProbability() > G4UniformRand()) {
|
||||
if (!fHasAlreadyReachedNullTime) {
|
||||
fReactants->clear();
|
||||
fHasAlreadyReachedNullTime = true;
|
||||
}
|
||||
@@ -206,15 +180,12 @@ G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
G4double tempMinET = GetTimeToEncounter(trackA, *pTrackB);
|
||||
if(tempMinET < 0 || tempMinET > G4Scheduler::Instance()->GetEndTime())
|
||||
{
|
||||
if (tempMinET < 0 || tempMinET > G4Scheduler::Instance()->GetEndTime()) {
|
||||
continue;
|
||||
}
|
||||
if(tempMinET >= fSampledMinTimeStep)
|
||||
{
|
||||
if (tempMinET >= fSampledMinTimeStep) {
|
||||
continue;
|
||||
}
|
||||
fSampledMinTimeStep = tempMinET;
|
||||
@@ -226,23 +197,19 @@ G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if(fVerbose != 0)
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will finally "
|
||||
"return :"
|
||||
<< G4BestUnit(fSampledMinTimeStep, "Time") << G4endl;
|
||||
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
G4cout << "Selected reactants for trackA: " << pMoleculeA->GetName()
|
||||
<< " (" << trackA.GetTrackID() << ") are: ";
|
||||
if (fVerbose > 1) {
|
||||
G4cout << "Selected reactants for trackA: " << pMoleculeA->GetName() << " ("
|
||||
<< trackA.GetTrackID() << ") are: ";
|
||||
|
||||
vector<G4Track*>::iterator it;
|
||||
for(it = fReactants->begin(); it != fReactants->end(); it++)
|
||||
{
|
||||
for (it = fReactants->begin(); it != fReactants->end(); it++) {
|
||||
G4Track* trackB = *it;
|
||||
G4cout << GetMolecule(trackB)->GetName() << " (" << trackB->GetTrackID()
|
||||
<< ") \t ";
|
||||
G4cout << GetMolecule(trackB)->GetName() << " (" << trackB->GetTrackID() << ") \t ";
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
@@ -251,126 +218,107 @@ G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
|
||||
return fSampledMinTimeStep;
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::CheckAndRecordResults(
|
||||
const Utils& utils)
|
||||
void G4DNAIndependentReactionTimeStepper::CheckAndRecordResults(const Utils& utils)
|
||||
{
|
||||
if(utils.fTrackB.GetTrackStatus() != fAlive)
|
||||
{
|
||||
if (utils.fTrackB.GetTrackStatus() != fAlive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(&utils.fTrackB == &utils.fTrackA)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "A track is reacting with itself"
|
||||
if (&utils.fTrackB == &utils.fTrackA) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "A track is reacting with itself"
|
||||
" (which is impossible) ie fpTrackA == trackB"
|
||||
<< G4endl;
|
||||
exceptionDescription << "Molecule A is of type : "
|
||||
<< utils.fpMoleculeA->GetName()
|
||||
msg << "Molecule A is of type : " << utils.fpMoleculeA->GetName()
|
||||
<< " with trackID : " << utils.fTrackA.GetTrackID()
|
||||
<< " and B : " << utils.fpMoleculeB->GetName()
|
||||
<< " with trackID : " << utils.fTrackB.GetTrackID()
|
||||
<< G4endl;
|
||||
<< " with trackID : " << utils.fTrackB.GetTrackID() << G4endl;
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
|
||||
"G4DNAIndependentReactionTimeStepper003", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
msg);
|
||||
}
|
||||
|
||||
if(fabs(utils.fTrackB.GetGlobalTime() - utils.fTrackA.GetGlobalTime()) >
|
||||
utils.fTrackA.GetGlobalTime() * (1. - 1. / 100))
|
||||
if (fabs(utils.fTrackB.GetGlobalTime() - utils.fTrackA.GetGlobalTime())
|
||||
> utils.fTrackA.GetGlobalTime() * (1. - 1. / 100))
|
||||
{
|
||||
// DEBUG
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription
|
||||
<< "The interacting tracks are not synchronized in time" << G4endl;
|
||||
exceptionDescription
|
||||
<< "trackB->GetGlobalTime() != fpTrackA.GetGlobalTime()" << G4endl;
|
||||
G4ExceptionDescription msg;
|
||||
msg << "The interacting tracks are not synchronized in time" << G4endl;
|
||||
msg << "trackB->GetGlobalTime() != fpTrackA.GetGlobalTime()" << G4endl;
|
||||
|
||||
exceptionDescription << "fpTrackA : trackID : "
|
||||
<< utils.fTrackA.GetTrackID()
|
||||
msg << "fpTrackA : trackID : " << utils.fTrackA.GetTrackID()
|
||||
<< "\t Name :" << utils.fpMoleculeA->GetName()
|
||||
<< "\t fpTrackA->GetGlobalTime() = "
|
||||
<< G4BestUnit(utils.fTrackA.GetGlobalTime(), "Time")
|
||||
<< G4endl;
|
||||
<< G4BestUnit(utils.fTrackA.GetGlobalTime(), "Time") << G4endl;
|
||||
|
||||
exceptionDescription << "trackB : trackID : " << utils.fTrackB.GetTrackID()
|
||||
msg << "trackB : trackID : " << utils.fTrackB.GetTrackID()
|
||||
<< "\t Name :" << utils.fpMoleculeB->GetName()
|
||||
<< "\t trackB->GetGlobalTime() = "
|
||||
<< G4BestUnit(utils.fTrackB.GetGlobalTime(), "Time")
|
||||
<< G4endl;
|
||||
<< G4BestUnit(utils.fTrackB.GetGlobalTime(), "Time") << G4endl;
|
||||
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
|
||||
"G4DNAIndependentReactionTimeStepper004", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
msg);
|
||||
}
|
||||
fReactants->push_back(const_cast<G4Track*>(&utils.fTrackB));
|
||||
}
|
||||
|
||||
std::unique_ptr<G4ITReactionChange>
|
||||
G4DNAIndependentReactionTimeStepper::FindReaction(
|
||||
std::unique_ptr<G4ITReactionChange> G4DNAIndependentReactionTimeStepper::FindReaction(
|
||||
G4ITReactionSet* pReactionSet, const G4double& currentStepTime,
|
||||
const G4double& /*previousStepTime*/,
|
||||
const G4bool& /*reachedUserStepTimeLimit*/)
|
||||
const G4double& /*previousStepTime*/, const G4bool& /*reachedUserStepTimeLimit*/)
|
||||
{
|
||||
if(pReactionSet == nullptr)
|
||||
{
|
||||
if (pReactionSet == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
G4ITReactionPerTime& reactionPerTime = pReactionSet->GetReactionsPerTime();
|
||||
if(reactionPerTime.empty())
|
||||
{
|
||||
if (reactionPerTime.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for(auto reaction_i = reactionPerTime.begin();
|
||||
reaction_i != reactionPerTime.end(); reaction_i = reactionPerTime.begin())
|
||||
for (auto reaction_i = reactionPerTime.begin(); reaction_i != reactionPerTime.end();
|
||||
reaction_i = reactionPerTime.begin())
|
||||
{
|
||||
if ((*reaction_i)->GetTime() > currentStepTime) {
|
||||
fReactionSet->CleanAllReaction();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
G4Track* pTrackA = (*reaction_i)->GetReactants().first;
|
||||
if(pTrackA->GetTrackStatus() == fStopAndKill)
|
||||
{
|
||||
if (pTrackA->GetTrackStatus() == fStopAndKill) {
|
||||
continue;
|
||||
}
|
||||
G4Track* pTrackB = (*reaction_i)->GetReactant(pTrackA);
|
||||
if(pTrackB->GetTrackStatus() == fStopAndKill)
|
||||
{
|
||||
if (pTrackB->GetTrackStatus() == fStopAndKill) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(pTrackB == pTrackA)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "The IT reaction process sent back a reaction "
|
||||
if (pTrackB == pTrackA) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "The IT reaction process sent back a reaction "
|
||||
"between trackA and trackB. ";
|
||||
exceptionDescription << "The problem is trackA == trackB";
|
||||
msg << "The problem is trackA == trackB";
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::FindReaction",
|
||||
"G4DNAIndependentReactionTimeStepper02", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
msg);
|
||||
}
|
||||
pReactionSet->SelectThisReaction(*reaction_i);
|
||||
if(fpReactionProcess != nullptr &&
|
||||
fpReactionProcess->TestReactibility(*pTrackA, *pTrackB, currentStepTime,
|
||||
false))
|
||||
if (fpReactionProcess != nullptr
|
||||
&& fpReactionProcess->TestReactibility(*pTrackA, *pTrackB, currentStepTime, false))
|
||||
{
|
||||
if((fSampledPositions.find(pTrackA->GetTrackID()) ==
|
||||
fSampledPositions.end() &&
|
||||
(fSampledPositions.find(pTrackB->GetTrackID()) ==
|
||||
fSampledPositions.end())))
|
||||
if ((fSampledPositions.find(pTrackA->GetTrackID()) == fSampledPositions.end()
|
||||
&& (fSampledPositions.find(pTrackB->GetTrackID()) == fSampledPositions.end())))
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription
|
||||
<< "The positions of trackA and trackB have no counted ";
|
||||
G4ExceptionDescription msg;
|
||||
msg << "The positions of trackA and trackB have no counted ";
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::FindReaction",
|
||||
"G4DNAIndependentReactionTimeStepper0001",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
"G4DNAIndependentReactionTimeStepper0001", FatalErrorInArgument,
|
||||
msg);
|
||||
}
|
||||
|
||||
pTrackA->SetPosition(fSampledPositions[pTrackA->GetTrackID()]);
|
||||
pTrackB->SetPosition(fSampledPositions[pTrackB->GetTrackID()]);
|
||||
auto pReactionChange =
|
||||
fpReactionProcess->MakeReaction(*pTrackA, *pTrackB);
|
||||
if(pReactionChange == nullptr)
|
||||
{
|
||||
auto pReactionChange = fpReactionProcess->MakeReaction(*pTrackA, *pTrackB);
|
||||
if (pReactionChange == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return pReactionChange;
|
||||
@@ -379,8 +327,7 @@ G4DNAIndependentReactionTimeStepper::FindReaction(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionModel(
|
||||
G4VDNAReactionModel* pReactionModel)
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionModel(G4VDNAReactionModel* pReactionModel)
|
||||
{
|
||||
fReactionModel = pReactionModel;
|
||||
}
|
||||
@@ -395,85 +342,68 @@ void G4DNAIndependentReactionTimeStepper::SetVerbose(G4int flag)
|
||||
fVerbose = flag;
|
||||
}
|
||||
|
||||
G4double G4DNAIndependentReactionTimeStepper::GetTimeToEncounter(
|
||||
const G4Track& trackA, const G4Track& trackB)
|
||||
G4double G4DNAIndependentReactionTimeStepper::GetTimeToEncounter(const G4Track& trackA,
|
||||
const G4Track& trackB)
|
||||
{
|
||||
G4double timeToReaction =
|
||||
dynamic_cast<G4DiffusionControlledReactionModel*>(fReactionModel)
|
||||
->GetTimeToEncounter(trackA, trackB);
|
||||
G4double timeToReaction = dynamic_cast<G4DiffusionControlledReactionModel*>(fReactionModel)
|
||||
->GetTimeToEncounter(trackA, trackB);
|
||||
return timeToReaction;
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionProcess(
|
||||
G4VITReactionProcess* pReactionProcess)
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionProcess(G4VITReactionProcess* pReactionProcess)
|
||||
{
|
||||
fpReactionProcess = pReactionProcess;
|
||||
}
|
||||
G4double G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep(
|
||||
G4double /*currentGlobalTime*/, G4double definedMinTimeStep)
|
||||
G4double G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep(G4double /*currentGlobalTime*/,
|
||||
G4double definedMinTimeStep)
|
||||
{
|
||||
G4double fTSTimeStep = DBL_MAX;
|
||||
fCheckedTracks.clear();
|
||||
|
||||
for(auto pTrack : *fpTrackContainer->GetMainList())
|
||||
{
|
||||
if(pTrack == nullptr)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No track found.";
|
||||
for (auto pTrack : *fpTrackContainer->GetMainList()) {
|
||||
if (pTrack == nullptr) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "No track found.";
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep",
|
||||
"G4DNAIndependentReactionTimeStepper006",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
"G4DNAIndependentReactionTimeStepper006", FatalErrorInArgument,
|
||||
msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
G4TrackStatus trackStatus = pTrack->GetTrackStatus();
|
||||
if(trackStatus == fStopAndKill || trackStatus == fStopButAlive)
|
||||
{
|
||||
if (trackStatus == fStopAndKill || trackStatus == fStopButAlive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
G4double sampledMinTimeStep = CalculateStep(*pTrack, definedMinTimeStep);
|
||||
G4double sampledMinTimeStep = CalculateStep(*pTrack, definedMinTimeStep);
|
||||
G4TrackVectorHandle reactants = GetReactants();
|
||||
|
||||
if(sampledMinTimeStep < fTSTimeStep)
|
||||
{
|
||||
if (sampledMinTimeStep < fTSTimeStep) {
|
||||
fTSTimeStep = sampledMinTimeStep;
|
||||
fReactionSet->CleanAllReaction();
|
||||
if(reactants)
|
||||
{
|
||||
fReactionSet->AddReactions(fTSTimeStep, const_cast<G4Track*>(pTrack),
|
||||
reactants);
|
||||
if (reactants) {
|
||||
fReactionSet->AddReactions(fTSTimeStep, const_cast<G4Track*>(pTrack), reactants);
|
||||
|
||||
fSampledPositions[pTrack->GetTrackID()] = pTrack->GetPosition();
|
||||
for(const auto& it : *fReactants)
|
||||
{
|
||||
for (const auto& it : *fReactants) {
|
||||
auto pTrackB = it;
|
||||
// G4cout<<"position : "<<pTrackB->GetTrackID()<<G4endl;
|
||||
fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
|
||||
}
|
||||
ResetReactants();
|
||||
}
|
||||
}
|
||||
else if(fTSTimeStep == sampledMinTimeStep && G4bool(reactants))
|
||||
{
|
||||
fReactionSet->AddReactions(fTSTimeStep, const_cast<G4Track*>(pTrack),
|
||||
reactants);
|
||||
else if (fTSTimeStep == sampledMinTimeStep && G4bool(reactants)) {
|
||||
fReactionSet->AddReactions(fTSTimeStep, const_cast<G4Track*>(pTrack), reactants);
|
||||
|
||||
fSampledPositions[pTrack->GetTrackID()] = pTrack->GetPosition();
|
||||
for(const auto& it : *fReactants)
|
||||
{
|
||||
for (const auto& it : *fReactants) {
|
||||
auto pTrackB = it;
|
||||
// G4cout<<"position : "<<pTrackB->GetTrackID()<<G4endl;
|
||||
fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
|
||||
}
|
||||
ResetReactants();
|
||||
}
|
||||
else if(reactants)
|
||||
{
|
||||
else if (reactants) {
|
||||
ResetReactants();
|
||||
}
|
||||
}
|
||||
|
||||
return fTSTimeStep;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4DNAIonChargeDecreaseModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4DummyModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNAIonChargeDecreaseModel::G4DNAIonChargeDecreaseModel(
|
||||
const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VEmModel(nam)
|
||||
{
|
||||
// dummy for the time being
|
||||
fDummy = new G4DummyModel();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAIonChargeDecreaseModel::Initialise(const G4ParticleDefinition* part,
|
||||
const G4DataVector& v)
|
||||
{
|
||||
if (part != G4GenericIon::GenericIon()) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Wrong particle type <" << part->GetParticleName()
|
||||
<< "> - only G4GenericIon is allowed";
|
||||
G4Exception("G4DNAIonChargeDecreaseModel::Initialise(...)",
|
||||
"em2001", FatalException, ed);
|
||||
}
|
||||
|
||||
// this pointer should defined once before initialisation of
|
||||
// concrete models
|
||||
if (nullptr == fParticleChangeForGamma) {
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
|
||||
// should be set once for each model
|
||||
fDummy->SetParticleChange(fParticleChangeForGamma);
|
||||
}
|
||||
|
||||
// initialisation of concrete models - put extra model here
|
||||
fDummy->Initialise(part, v);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAIonChargeDecreaseModel::StartTracking(G4Track* track)
|
||||
{
|
||||
fDynParticle = track->GetDynamicParticle();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAIonChargeDecreaseModel::CrossSectionPerVolume(const G4Material* mat,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double, G4double)
|
||||
{
|
||||
G4int Q = G4lrint(fDynParticle->GetCharge()/CLHEP::eplus);
|
||||
|
||||
if (Q <= 0) { return 0.0; }
|
||||
|
||||
// select model
|
||||
fCurrentModel = fDummy;
|
||||
|
||||
// compute concrete cross section
|
||||
return fCurrentModel->CrossSectionPerVolume(mat, p, ekin);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAIonChargeDecreaseModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double, G4double)
|
||||
{
|
||||
// sample secondaries by the selected model
|
||||
fCurrentModel->SampleSecondaries(fvect, couple, dp);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4DNAIonChargeIncreaseModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4DummyModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNAIonChargeIncreaseModel::G4DNAIonChargeIncreaseModel(
|
||||
const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VEmModel(nam)
|
||||
{
|
||||
// dummy for the time being
|
||||
fDummy = new G4DummyModel();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAIonChargeIncreaseModel::Initialise(const G4ParticleDefinition* part,
|
||||
const G4DataVector& v)
|
||||
{
|
||||
if (part != G4GenericIon::GenericIon()) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Wrong particle type <" << part->GetParticleName()
|
||||
<< "> - only G4GenericIon is allowed";
|
||||
G4Exception("G4DNAIonChargeIncreaseModel::Initialise(...)",
|
||||
"em2001", FatalException, ed);
|
||||
}
|
||||
|
||||
// this pointer should defined once before initialisation of
|
||||
// concrete models
|
||||
if (nullptr == fParticleChangeForGamma) {
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
|
||||
// should be set once for each model
|
||||
fDummy->SetParticleChange(fParticleChangeForGamma);
|
||||
}
|
||||
|
||||
// initialisation of concrete models - put extra model here
|
||||
fDummy->Initialise(part, v);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAIonChargeIncreaseModel::StartTracking(G4Track* track)
|
||||
{
|
||||
fDynParticle = track->GetDynamicParticle();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAIonChargeIncreaseModel::CrossSectionPerVolume(const G4Material* mat,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double, G4double)
|
||||
{
|
||||
G4int Z = p->GetAtomicNumber();
|
||||
G4int Q = G4lrint(fDynParticle->GetCharge()/CLHEP::eplus);
|
||||
|
||||
if (Q >= Z) { return 0.0; }
|
||||
|
||||
// select model
|
||||
fCurrentModel = fDummy;
|
||||
|
||||
// compute concrete cross section
|
||||
return fCurrentModel->CrossSectionPerVolume(mat, p, ekin);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAIonChargeIncreaseModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double, G4double)
|
||||
{
|
||||
// sample secondaries by the selected model
|
||||
fCurrentModel->SampleSecondaries(fvect, couple, dp);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -190,13 +190,18 @@ G4DNAMakeReaction::FindReaction(G4ITReactionSet* pReactionSet,
|
||||
std::vector<std::unique_ptr<G4ITReactionChange>> ReactionInfo;
|
||||
ReactionInfo.clear();
|
||||
auto stepper = dynamic_cast<G4DNAIndependentReactionTimeStepper*>(fpTimeStepper);
|
||||
if(stepper != nullptr){
|
||||
auto pReactionChange = stepper->
|
||||
FindReaction(pReactionSet,currentStepTime);
|
||||
if (pReactionChange != nullptr)
|
||||
{
|
||||
ReactionInfo.push_back(std::move(pReactionChange));
|
||||
}
|
||||
if(stepper == nullptr){
|
||||
return ReactionInfo;
|
||||
}else
|
||||
{
|
||||
do{
|
||||
auto pReactionChange = stepper->
|
||||
FindReaction(pReactionSet,currentStepTime);
|
||||
if (pReactionChange != nullptr)
|
||||
{
|
||||
ReactionInfo.push_back(std::move(pReactionChange));
|
||||
}
|
||||
}while (!pReactionSet->GetReactionsPerTime().empty());
|
||||
}
|
||||
return ReactionInfo;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNAMultipleIonisationManager.cc
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
|
||||
#include "G4DNAMultipleIonisationManager.hh"
|
||||
#include "G4FindDataDir.hh"
|
||||
#include "G4Scheduler.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4VITTrackHolder.hh"
|
||||
#include "G4H2O.hh"
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNAMultipleIonisationManager::CreateMultipleIonisedWaterMolecule(
|
||||
MultipleIonisedModification mod, G4int* shell_level,
|
||||
const G4Track* incoming_track)
|
||||
{
|
||||
if (!G4DNAChemistryManager::IsActivated()) { return; }
|
||||
|
||||
G4int num_shells{0};
|
||||
switch (mod) {
|
||||
case eDoubleIonisedMolecule:
|
||||
num_shells = 2;
|
||||
break;
|
||||
case eTripleIonisedMolecule:
|
||||
num_shells = 3;
|
||||
break;
|
||||
case eQuadrupleIonisedMolecule:
|
||||
num_shells = 4;
|
||||
break;
|
||||
default: // never happen
|
||||
return;
|
||||
}
|
||||
|
||||
auto* H2O = new G4Molecule(G4H2O::Definition());
|
||||
for (G4int i = 0; i < num_shells; i++) {
|
||||
H2O->IonizeMolecule(4 - shell_level[i]);
|
||||
}
|
||||
|
||||
constexpr G4double kT0 = 1.0 * picosecond;
|
||||
auto* H2O_track = H2O->BuildTrack(kT0, incoming_track->GetPosition());
|
||||
H2O_track->SetParentID(incoming_track->GetTrackID());
|
||||
H2O_track->SetTrackStatus(fStopButAlive);
|
||||
H2O_track->SetKineticEnergy(0.0);
|
||||
|
||||
G4VITTrackHolder::Instance()->Push(H2O_track);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4bool G4DNAMultipleIonisationManager::CheckShellEnergy(
|
||||
MultipleIonisedModification mod, G4double* shell_energy)
|
||||
{
|
||||
G4int num_shells{0};
|
||||
switch (mod) {
|
||||
case eDoubleIonisedMolecule:
|
||||
num_shells = 2;
|
||||
break;
|
||||
case eTripleIonisedMolecule:
|
||||
num_shells = 3;
|
||||
break;
|
||||
case eQuadrupleIonisedMolecule:
|
||||
num_shells = 4;
|
||||
break;
|
||||
default: // never happen
|
||||
break;
|
||||
}
|
||||
|
||||
G4bool stop_process{false};
|
||||
for (int i = 0; i < num_shells; i++) {
|
||||
if (shell_energy[i] < 0.0) {
|
||||
stop_process = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stop_process;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNAMultipleIonisationManager::LoadAlphaParam(
|
||||
const G4String& filepath, G4double Z, G4double A)
|
||||
{
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
if (path == nullptr) {
|
||||
G4Exception("G4DNAMultipleIonisationManager::LoadAlphaParam","em0006",
|
||||
FatalException,"G4LEDATA environment variable not set.");
|
||||
}
|
||||
|
||||
std::stringstream fullpath;
|
||||
fullpath << path << "/" << filepath;
|
||||
|
||||
std::fstream fin(fullpath.str());
|
||||
|
||||
G4double e, a;
|
||||
std::string line = "";
|
||||
while (getline(fin, line)) {
|
||||
std::stringstream ss;
|
||||
ss << line;
|
||||
ss >> e >> a;
|
||||
Eion_.push_back(e * Z * A * MeV);
|
||||
alpha_.push_back(a);
|
||||
}
|
||||
|
||||
num_node_ = (G4int)Eion_.size();
|
||||
fin.close();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double G4DNAMultipleIonisationManager::GetAlphaParam(G4double energy)
|
||||
{
|
||||
auto find_lower_bound = [this](G4double e) {
|
||||
auto low = 0;
|
||||
auto upp = num_node_ - 1;
|
||||
if (e < Eion_[0]) { return low; }
|
||||
while (low <= upp) {
|
||||
const auto mid = static_cast<int>((low + upp) * 0.5);
|
||||
if (e < Eion_[mid]) { upp = mid - 1; }
|
||||
else { low = mid + 1; }
|
||||
if (upp < 0) { upp = 0; }
|
||||
}
|
||||
return upp;
|
||||
};
|
||||
|
||||
auto interp_log_log = [this](G4int bin1, G4double e) {
|
||||
if (e < Eion_[0]) { return alpha_[0]; }
|
||||
const auto num_bin = num_node_ - 1;
|
||||
const auto bin2 = bin1 + 1;
|
||||
G4double value{0.0};
|
||||
if (bin2 <= num_bin) {
|
||||
auto log10_e = std::log10(e);
|
||||
auto log10_e1 = Eion_[bin1];
|
||||
auto log10_e2 = Eion_[bin2];
|
||||
auto log10_a1 = alpha_[bin1];
|
||||
auto log10_a2 = alpha_[bin2];
|
||||
if (log10_a1 != 0.0 && log10_a2 != 0.0) {
|
||||
log10_e1 = std::log10(log10_e1);
|
||||
log10_e2 = std::log10(log10_e2);
|
||||
log10_a1 = std::log10(log10_a1);
|
||||
log10_a2 = std::log10(log10_a2);
|
||||
value = log10_a1 + (log10_a2 - log10_a1)
|
||||
* (log10_e - log10_e1) / (log10_e2 - log10_e1);
|
||||
value = std::pow(10.0, value);
|
||||
}
|
||||
} else {
|
||||
value = alpha_[num_bin];
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const auto bin1 = find_lower_bound(energy);
|
||||
return interp_log_log(bin1, energy);
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNAQuadrupleIonisationModel.cc
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
// Reference: J.Meesungnoen et. al, DOI: 10.1021/jp058037z
|
||||
//
|
||||
|
||||
#include "G4DNAQuadrupleIonisationModel.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UAtomicDeexcitation.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4DNARuddAngle.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
|
||||
G4DNAWaterIonisationStructure water_structure;
|
||||
G4Pow* g4pow = G4Pow::GetInstance();
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
//==============================================================================
|
||||
|
||||
// constructor
|
||||
G4DNAQuadrupleIonisationModel::G4DNAQuadrupleIonisationModel(
|
||||
const G4ParticleDefinition* p, const G4String& model_name)
|
||||
: G4DNADoubleIonisationModel(p, model_name)
|
||||
{
|
||||
// Quadruple-ionisation energy
|
||||
energy_threshold_ = 88.0 * eV;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNAQuadrupleIonisationModel::Initialise(
|
||||
const G4ParticleDefinition* particle, const G4DataVector&)
|
||||
{
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling G4DNAQuadrupleIonisationModel::Initialise()" << G4endl;
|
||||
}
|
||||
|
||||
proton_def_ = G4Proton::ProtonDefinition();
|
||||
alpha_def_ = G4DNAGenericIonsManager::Instance()->GetIon("alpha++");
|
||||
carbon_def_ = G4IonTable::GetIonTable()->GetIon(6, 12);
|
||||
|
||||
constexpr G4double kScaleFactor = 1.0 * m * m;
|
||||
|
||||
mioni_manager_ = new G4DNAMultipleIonisationManager();
|
||||
|
||||
G4double Z{0.0}, A{0.0};
|
||||
G4String alpha_param_file{"dna/multipleionisation_alphaparam_champion.dat"};
|
||||
|
||||
if (particle == proton_def_) {
|
||||
|
||||
// *************************************************************************
|
||||
// for protons
|
||||
auto proton = proton_def_->GetParticleName();
|
||||
elow_tab_[proton] = model_elow_tab_[1];
|
||||
eupp_tab_[proton] = 3.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_proton = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_proton->LoadData("dna/sigma_ionisation_p_rudd");
|
||||
xs_tab_[proton] = xs_proton;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[proton]);
|
||||
SetHighEnergyLimit(eupp_tab_[proton]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_p.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(proton_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(proton_def_->GetAtomicMass());
|
||||
|
||||
} else if (particle == alpha_def_) {
|
||||
|
||||
//**************************************************************************
|
||||
// for alpha particles
|
||||
auto alpha = alpha_def_->GetParticleName();
|
||||
elow_tab_[alpha] = model_elow_tab_[4];
|
||||
eupp_tab_[alpha] = 23.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_alpha = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_alpha->LoadData("dna/sigma_ionisation_alphaplusplus_rudd");
|
||||
xs_tab_[alpha] = xs_alpha;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[alpha]);
|
||||
SetHighEnergyLimit(eupp_tab_[alpha]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_alphaplusplus.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(alpha_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(alpha_def_->GetAtomicMass());
|
||||
|
||||
} else if (particle == G4GenericIon::GenericIonDefinition()) {
|
||||
|
||||
// *************************************************************************
|
||||
// for carbon ions
|
||||
auto carbon = carbon_def_->GetParticleName();
|
||||
elow_tab_[carbon] = model_elow_tab_[5] * carbon_def_->GetAtomicMass();
|
||||
eupp_tab_[carbon] = 120.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_carbon = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_carbon->LoadData("dna/sigma_ionisation_c_rudd");
|
||||
xs_tab_[carbon] = xs_carbon;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[carbon]);
|
||||
SetHighEnergyLimit(eupp_tab_[carbon]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_c.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(carbon_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(carbon_def_->GetAtomicMass());
|
||||
|
||||
}
|
||||
|
||||
// load alpha parameter
|
||||
mioni_manager_->LoadAlphaParam(alpha_param_file, Z, A);
|
||||
|
||||
if (verbose_level_ > 0) {
|
||||
G4cout << "G4DNAQuadrupleIonisationModel is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / keV << " keV for "
|
||||
<< particle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
water_density_ = G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(
|
||||
G4Material::GetMaterial("G4_WATER"));
|
||||
|
||||
atom_deex_ = G4LossTableManager::Instance()->AtomDeexcitation();
|
||||
|
||||
if (is_initialized_) { return; }
|
||||
|
||||
particle_change_ = GetParticleChangeForGamma();
|
||||
is_initialized_ = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double G4DNAQuadrupleIonisationModel::CrossSectionPerVolume(
|
||||
const G4Material* material, const G4ParticleDefinition* pdef,
|
||||
G4double ekin, G4double, G4double)
|
||||
{
|
||||
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling G4DNAQuadrupleIonisationModel::CrossSectionPerVolume()"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
if (pdef != proton_def_ && pdef != alpha_def_ && pdef != carbon_def_) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static G4double water_dens = (*water_density_)[material->GetIndex()];
|
||||
|
||||
const auto& pname = pdef->GetParticleName();
|
||||
|
||||
const auto low_energy_lim = GetLowEnergyLimit(pname);
|
||||
const auto upp_energy_lim = GetUppEnergyLimit(pname);
|
||||
|
||||
G4double sigma{0.0};
|
||||
if (ekin <= upp_energy_lim) {
|
||||
|
||||
if (ekin < low_energy_lim) { ekin = low_energy_lim; }
|
||||
|
||||
CrossSectionDataTable::iterator pos = xs_tab_.find(pname);
|
||||
if (pos == xs_tab_.end()) {
|
||||
G4Exception("G4DNAQuadrupleIonisationModel::CrossSectionPerVolume",
|
||||
"em0002", FatalException,
|
||||
"Model not applicable to particle type.");
|
||||
}
|
||||
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
if (table != nullptr) {
|
||||
auto scale_param = mioni_manager_->GetAlphaParam(ekin);
|
||||
scale_param = ::g4pow->powA(scale_param, 3.0);
|
||||
sigma = table->FindValue(ekin) * scale_param;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (verbose_level_ > 2) {
|
||||
|
||||
std::stringstream msg;
|
||||
|
||||
msg << "----------------------------------------------------------------\n";
|
||||
msg << " G4DNAQuadrupleIonisationModel - XS INFO START\n";
|
||||
msg << " - Kinetic energy(eV): " << ekin/eV << ", Particle : "
|
||||
<< pdef->GetParticleName() << "\n";
|
||||
msg << " - Cross section per water molecule (cm^2): "
|
||||
<< sigma / cm / cm << "\n";
|
||||
msg << " - Cross section per water molecule (cm^-1): "
|
||||
<< sigma * water_dens / (1.0 / cm) << "\n";
|
||||
msg << " G4DNAQuadrupleIonisationModel - XS INFO END\n";
|
||||
msg << "----------------------------------------------------------------\n";
|
||||
|
||||
G4cout << msg.str() << G4endl;
|
||||
|
||||
}
|
||||
|
||||
return (sigma * water_dens);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNAQuadrupleIonisationModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vsec, const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle, G4double, G4double)
|
||||
{
|
||||
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling SampleSecondaries() of G4DNAQuadrupleIonisationModel"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// get the definition for this parent particle
|
||||
auto pdef = particle->GetDefinition();
|
||||
|
||||
// get kinetic energy
|
||||
auto ekin = particle->GetKineticEnergy();
|
||||
|
||||
// get particle name
|
||||
const auto& pname = pdef->GetParticleName();
|
||||
|
||||
// get energy limits
|
||||
const auto low_energy_lim = GetLowEnergyLimit(pname);
|
||||
|
||||
// ***************************************************************************
|
||||
// stop the transportation process of this parent particle
|
||||
// if its kinetic energy is below the lower limit
|
||||
if (ekin < low_energy_lim) {
|
||||
particle_change_->SetProposedKineticEnergy(0.0);
|
||||
particle_change_->ProposeTrackStatus(fStopAndKill);
|
||||
particle_change_->ProposeLocalEnergyDeposit(ekin);
|
||||
return;
|
||||
}
|
||||
// ***************************************************************************
|
||||
|
||||
constexpr G4int kNumSecondaries = 4;
|
||||
constexpr G4double kDeltaTheta = pi * 0.5;
|
||||
|
||||
G4int ioni_shell[kNumSecondaries] = {0, 0, 0, 0};
|
||||
G4double shell_energy[kNumSecondaries];
|
||||
|
||||
auto scale_param = mioni_manager_->GetAlphaParam(ekin);
|
||||
scale_param = ::g4pow->powA(scale_param, 3.0);
|
||||
|
||||
G4bool is_continue{true};
|
||||
while (1) {
|
||||
ioni_shell[0] = RandomSelect(ekin, scale_param, pname);
|
||||
ioni_shell[1] = RandomSelect(ekin, scale_param, pname);
|
||||
ioni_shell[2] = RandomSelect(ekin, scale_param, pname);
|
||||
ioni_shell[3] = RandomSelect(ekin, scale_param, pname);
|
||||
is_continue =
|
||||
(ioni_shell[0] == ioni_shell[1] && ioni_shell[1] == ioni_shell[2]) ||
|
||||
(ioni_shell[1] == ioni_shell[2] && ioni_shell[2] == ioni_shell[3]) ||
|
||||
(ioni_shell[2] == ioni_shell[3] && ioni_shell[3] == ioni_shell[0]) ||
|
||||
(ioni_shell[3] == ioni_shell[0] && ioni_shell[0] == ioni_shell[1]) ||
|
||||
(ioni_shell[0] == ioni_shell[1] && ioni_shell[1] == ioni_shell[2] &&
|
||||
ioni_shell[2] == ioni_shell[3]);
|
||||
if (!is_continue) { break; }
|
||||
}
|
||||
|
||||
G4double tot_ioni_energy{0.0};
|
||||
for (int i = 0; i < kNumSecondaries; i++) {
|
||||
shell_energy[i] = ::water_structure.IonisationEnergy(ioni_shell[i]);
|
||||
tot_ioni_energy += shell_energy[i];
|
||||
}
|
||||
|
||||
if (ekin < tot_ioni_energy || tot_ioni_energy < energy_threshold_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// generate secondary electrons
|
||||
G4double theta{0.0}, phi{0.0}, tot_ekin2{0.0};
|
||||
for (int i = 0; i < kNumSecondaries; i++) {
|
||||
tot_ekin2 += GenerateSecondaries(vsec, couple, particle, ioni_shell[i],
|
||||
theta, phi, shell_energy[i]);
|
||||
theta += kDeltaTheta;
|
||||
}
|
||||
|
||||
// This should never happen
|
||||
if (mioni_manager_->CheckShellEnergy(eQuadrupleIonisedMolecule,
|
||||
shell_energy)) {
|
||||
G4Exception("G4DNAQuadrupleIonisatioModel::SampleSecondaries()",
|
||||
"em2050", FatalException, "Negative local energy deposit");
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// update kinematics for this parent particle
|
||||
const auto primary_dir = particle->GetMomentumDirection();
|
||||
particle_change_->ProposeMomentumDirection(primary_dir);
|
||||
|
||||
const auto scattered_energy = ekin - tot_ioni_energy - tot_ekin2;
|
||||
|
||||
// update total amount of shell energy
|
||||
tot_ioni_energy = shell_energy[0] + shell_energy[1] +
|
||||
shell_energy[2] + shell_energy[3];
|
||||
|
||||
if (stat_code_) {
|
||||
particle_change_->SetProposedKineticEnergy(ekin);
|
||||
particle_change_->ProposeLocalEnergyDeposit(
|
||||
ekin - scattered_energy);
|
||||
} else {
|
||||
particle_change_->SetProposedKineticEnergy(scattered_energy);
|
||||
particle_change_->ProposeLocalEnergyDeposit(tot_ioni_energy);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// generate triple-ionized water molecules (H2O^4+)
|
||||
const auto the_track = particle_change_->GetCurrentTrack();
|
||||
mioni_manager_->CreateMultipleIonisedWaterMolecule(
|
||||
eQuadrupleIonisedMolecule, ioni_shell, the_track);
|
||||
// ***************************************************************************
|
||||
|
||||
}
|
||||
+256
-243
@@ -48,7 +48,6 @@
|
||||
#include "G4Pow.hh"
|
||||
#include "G4Alpha.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -59,11 +58,9 @@ const std::vector<G4double>* G4DNARuddIonisationExtendedModel::fpWaterDensity =
|
||||
|
||||
namespace
|
||||
{
|
||||
G4Mutex ionDNAMutex = G4MUTEX_INITIALIZER;
|
||||
const G4double scaleFactor = CLHEP::m*CLHEP::m;
|
||||
const G4double tolerance = 1*CLHEP::eV;
|
||||
const G4double Ry = 13.6*CLHEP::eV;
|
||||
const G4double Gj[5] = {0.99, 1.11, 1.11, 0.52, 1.};
|
||||
|
||||
// Following values provided by M. Dingfelder (priv. comm)
|
||||
const G4double Bj[5] = {12.60*CLHEP::eV, 14.70*CLHEP::eV, 18.40*CLHEP::eV,
|
||||
@@ -86,6 +83,8 @@ G4DNARuddIonisationExtendedModel::G4DNARuddIonisationExtendedModel(const G4Parti
|
||||
|
||||
// Define default angular generator
|
||||
SetAngularDistribution(new G4DNARuddAngle());
|
||||
|
||||
if (nullptr == xshelium) { LoadData(); }
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -99,93 +98,98 @@ G4DNARuddIonisationExtendedModel::~G4DNARuddIonisationExtendedModel()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNARuddIonisationExtendedModel::LoadData()
|
||||
{
|
||||
// initialisation of static data once
|
||||
isFirst = true;
|
||||
G4String filename("dna/sigma_ionisation_h_rudd");
|
||||
xsdata[0] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[0]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_p_rudd";
|
||||
xsdata[1] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[1]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_alphaplusplus_rudd";
|
||||
xsdata[2] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[2]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_li_rudd";
|
||||
xsdata[3] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[3]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_be_rudd";
|
||||
xsdata[4] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[4]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_b_rudd";
|
||||
xsdata[5] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[5]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_c_rudd";
|
||||
xsdata[6] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[6]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_n_rudd";
|
||||
xsdata[7] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[7]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_o_rudd";
|
||||
xsdata[8] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[8]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_si_rudd";
|
||||
xsdata[14] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[14]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_fe_rudd";
|
||||
xsdata[26] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[26]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_alphaplus_rudd";
|
||||
xsalphaplus = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsalphaplus->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_he_rudd";
|
||||
xshelium = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xshelium->LoadData(filename);
|
||||
|
||||
// to avoid possible threading problem fill this vector only once
|
||||
auto water = G4NistManager::Instance()->FindMaterial("G4_WATER");
|
||||
fpWaterDensity =
|
||||
G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(water);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if(p != fParticle) { SetParticle(p); }
|
||||
if (p != fParticle) { SetParticle(p); }
|
||||
|
||||
// initialisation of static data once
|
||||
if(nullptr == xsdata[0]) {
|
||||
G4AutoLock l(&ionDNAMutex);
|
||||
if(nullptr == xsdata[0]) {
|
||||
isFirst = true;
|
||||
G4String filename("dna/sigma_ionisation_h_rudd");
|
||||
xsdata[0] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[0]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_p_rudd";
|
||||
xsdata[1] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[1]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_alphaplusplus_rudd";
|
||||
xsdata[2] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[2]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_li_rudd";
|
||||
xsdata[3] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[3]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_be_rudd";
|
||||
xsdata[4] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[4]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_b_rudd";
|
||||
xsdata[5] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[5]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_c_rudd";
|
||||
xsdata[6] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[6]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_n_rudd";
|
||||
xsdata[7] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[7]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_o_rudd";
|
||||
xsdata[8] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[8]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_si_rudd";
|
||||
xsdata[14] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[14]->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_fe_rudd";
|
||||
xsdata[26] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsdata[26]->LoadData(filename);
|
||||
filename = "dna/sigma_ionisation_alphaplus_rudd";
|
||||
xsalphaplus = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xsalphaplus->LoadData(filename);
|
||||
|
||||
filename = "dna/sigma_ionisation_he_rudd";
|
||||
xshelium = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
|
||||
xshelium->LoadData(filename);
|
||||
}
|
||||
// to avoid possible threading problem fill this vector only once
|
||||
auto water = G4NistManager::Instance()->FindMaterial("G4_WATER");
|
||||
fpWaterDensity =
|
||||
G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(water);
|
||||
|
||||
l.unlock();
|
||||
// particle change object may be externally set
|
||||
if (nullptr == fParticleChangeForGamma) {
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
}
|
||||
|
||||
// initialisation once in each thread
|
||||
if(nullptr == fParticleChangeForGamma) {
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
if (!isInitialised) {
|
||||
isInitialised = true;
|
||||
const G4String& pname = fParticle->GetParticleName();
|
||||
if(pname == "proton") {
|
||||
if (pname == "proton") {
|
||||
idx = 1;
|
||||
xscurrent = xsdata[1];
|
||||
fElow = fLowestEnergy;
|
||||
} else if(pname == "hydrogen") {
|
||||
} else if (pname == "hydrogen") {
|
||||
idx = 0;
|
||||
xscurrent = xsdata[0];
|
||||
fElow = fLowestEnergy;
|
||||
} else if(pname == "alpha") {
|
||||
} else if (pname == "alpha") {
|
||||
idx = 1;
|
||||
xscurrent = xsdata[2];
|
||||
isHelium = true;
|
||||
fElow = fLimitEnergy;
|
||||
} else if(pname == "alpha+") {
|
||||
} else if (pname == "alpha+") {
|
||||
idx = 1;
|
||||
isHelium = true;
|
||||
xscurrent = xsalphaplus;
|
||||
@@ -197,7 +201,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* p,
|
||||
sCoefficient[0]=0.7;
|
||||
sCoefficient[1]=0.15;
|
||||
sCoefficient[2]=0.15;
|
||||
} else if(pname == "helium") {
|
||||
} else if (pname == "helium") {
|
||||
idx = 0;
|
||||
isHelium = true;
|
||||
fElow = fLimitEnergy;
|
||||
@@ -210,6 +214,9 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* p,
|
||||
sCoefficient[2]=0.25;
|
||||
} else {
|
||||
isIon = true;
|
||||
idx = -1;
|
||||
xscurrent = xsdata[1];
|
||||
fElow = fLowestEnergy;
|
||||
}
|
||||
// defined stationary mode
|
||||
statCode = G4EmParameters::Instance()->DNAStationary();
|
||||
@@ -219,8 +226,8 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* p,
|
||||
|
||||
if (verbose > 0) {
|
||||
G4cout << "### G4DNARuddIonisationExtendedModel::Initialise(..) " << pname
|
||||
<< "/n idx=" << idx << " Amass=" << fAmass
|
||||
<< " isIon=" << isIon << " isHelium=" << isHelium << G4endl;
|
||||
<< "/n idx=" << idx << " isIon=" << isIon
|
||||
<< " isHelium=" << isHelium << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,17 +238,7 @@ void G4DNARuddIonisationExtendedModel::SetParticle(const G4ParticleDefinition* p
|
||||
{
|
||||
fParticle = p;
|
||||
fMass = p->GetPDGMass();
|
||||
fAmass = p->GetAtomicMass();
|
||||
|
||||
// for generic ions idx is dynamic, -1 means that data for the ion does not exist
|
||||
if(isIon) {
|
||||
G4int i = p->GetAtomicNumber();
|
||||
idx = -1;
|
||||
if (i < RUDDZMAX && nullptr != xsdata[i]) {
|
||||
idx = i;
|
||||
fElow = fAmass*fLowestEnergy;
|
||||
}
|
||||
}
|
||||
fMassRate = (isIon) ? CLHEP::proton_mass_c2/fMass : 1.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -260,33 +257,18 @@ G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Material* materi
|
||||
// ion may be different
|
||||
if (fParticle != part) { SetParticle(part); }
|
||||
|
||||
// initilise mass rate
|
||||
fMassRate = 1.0;
|
||||
|
||||
// ion shoud be stopped - check on kinetic energy and not scaled energy
|
||||
if (kinE < fLowestEnergy) { return DBL_MAX; }
|
||||
|
||||
G4double sigma = 0.;
|
||||
|
||||
// use ion table if available for given energy
|
||||
// for proton, hydrogen, alpha, alpha+, and helium no scaling to proton x-section
|
||||
if (idx == 0 || idx == 1) {
|
||||
sigma = (kinE > fElow) ? xscurrent->FindValue(kinE)
|
||||
: xscurrent->FindValue(fElow)*kinE/fElow;
|
||||
G4double e = kinE*fMassRate;
|
||||
|
||||
// for ions with data above limit energy
|
||||
} else if (idx > 1) {
|
||||
sigma = (kinE > fElow) ? xsdata[idx]->FindValue(kinE)
|
||||
: xsdata[idx]->FindValue(fElow)*kinE/fElow;
|
||||
G4double sigma = (e > fElow) ? xscurrent->FindValue(e)
|
||||
: xscurrent->FindValue(fElow) * e / fElow;
|
||||
|
||||
// scaling from proton
|
||||
} else {
|
||||
fMassRate = CLHEP::proton_mass_c2/fMass;
|
||||
G4double e = kinE*fMassRate;
|
||||
sigma = (e > fLowestEnergy) ? xsdata[1]->FindValue(e)
|
||||
: xsdata[1]->FindValue(fLowestEnergy)*e/fLowestEnergy;
|
||||
if (idx == -1) {
|
||||
sigma *= fEmCorrections->EffectiveChargeSquareRatio(part, material, kinE);
|
||||
}
|
||||
|
||||
sigma *= density;
|
||||
|
||||
if (verbose > 1) {
|
||||
@@ -318,14 +300,14 @@ G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicParticl
|
||||
return;
|
||||
}
|
||||
|
||||
G4int shell = SelectShell(kinE);
|
||||
G4int shell = SelectShell(kinE*fMassRate);
|
||||
G4double bindingEnergy = (useDNAWaterStructure)
|
||||
? waterStructure.IonisationEnergy(shell) : Bj[shell];
|
||||
|
||||
//Si: additional protection if tcs interpolation method is modified
|
||||
if (kinE < bindingEnergy) return;
|
||||
|
||||
G4double esec = SampleElectronEnergy(kinE, bindingEnergy, shell);
|
||||
if (kinE < bindingEnergy) { return; }
|
||||
|
||||
G4double esec = SampleElectronEnergy(kinE, shell);
|
||||
G4double esum = 0.0;
|
||||
|
||||
// sample deexcitation
|
||||
@@ -342,9 +324,8 @@ G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicParticl
|
||||
fAtomDeexcitation->GenerateParticles(fvect, ashell, Z, 0, 0);
|
||||
|
||||
// compute energy sum from de-excitation
|
||||
std::size_t nn = fvect->size();
|
||||
for (std::size_t i=0; i<nn; ++i) {
|
||||
esum += (*fvect)[i]->GetKineticEnergy();
|
||||
for (auto const & ptr : *fvect) {
|
||||
esum += ptr->GetKineticEnergy();
|
||||
}
|
||||
}
|
||||
// check energy balance
|
||||
@@ -386,131 +367,30 @@ G4int G4DNARuddIonisationExtendedModel::SelectShell(G4double e)
|
||||
{
|
||||
G4double sum = 0.0;
|
||||
G4double xs;
|
||||
for(G4int i=0; i<5; ++i) {
|
||||
if (idx == 0 || idx == 1) {
|
||||
auto ptr = xscurrent->GetComponent(i);
|
||||
xs = (e > fElow) ? ptr->FindValue(e) : ptr->FindValue(fElow)*e/fElow;
|
||||
|
||||
} else if (idx > 1) {
|
||||
auto ptr = xsdata[idx]->GetComponent(i);
|
||||
xs = (e > fElow) ? ptr->FindValue(e) : ptr->FindValue(fElow)*e/fElow;
|
||||
|
||||
} else {
|
||||
// use scaling from proton
|
||||
auto ptr = xsdata[1]->GetComponent(i);
|
||||
G4double x = e*fMassRate;
|
||||
xs = (x >= fLowestEnergy) ? ptr->FindValue(x)
|
||||
: ptr->FindValue(fLowestEnergy)*x/fLowestEnergy;
|
||||
}
|
||||
for (G4int i=0; i<5; ++i) {
|
||||
auto ptr = xscurrent->GetComponent(i);
|
||||
xs = (e > fElow) ? ptr->FindValue(e) : ptr->FindValue(fElow)*e/fElow;
|
||||
sum += xs;
|
||||
fTemp[i] = sum;
|
||||
}
|
||||
sum *= G4UniformRand();
|
||||
for(G4int i=0; i<5; ++i) {
|
||||
if(sum <= fTemp[i]) { return i; }
|
||||
for (G4int i=0; i<5; ++i) {
|
||||
if (sum <= fTemp[i]) { return i; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARuddIonisationExtendedModel::SampleElectronEnergy(G4double kine,
|
||||
G4double eexc,
|
||||
G4int shell)
|
||||
G4double G4DNARuddIonisationExtendedModel::MaxEnergy(G4double kine, G4int shell)
|
||||
{
|
||||
// kinematic limit
|
||||
G4double tau = kine/fMass;
|
||||
G4double gam = 1.0 + tau;
|
||||
G4double emax = 2.0*CLHEP::electron_mass_c2*tau*(tau + 2.0);
|
||||
// compute cumulative probability function
|
||||
G4double step = 1*CLHEP::eV;
|
||||
auto nn = (G4int)(emax/step);
|
||||
nn = std::max(nn, 10);
|
||||
step = emax/(G4double)nn;
|
||||
|
||||
// find max probability
|
||||
G4double pmax = ProbabilityFunction(kine, 0.0, eexc, shell);
|
||||
//G4cout << "E(keV)=" << kine/keV << " emax=" << emax/keV
|
||||
// << " pmax(0)=" << pmax << " shell=" << shell << " nn=" << nn << G4endl;
|
||||
|
||||
G4double e2 = 0.0; // backup energy
|
||||
G4double e0 = 0.0; // energy with max probability
|
||||
G4double e = 0.0;
|
||||
for (G4int i=0; i<nn; ++i) {
|
||||
e += step;
|
||||
G4double prob = ProbabilityFunction(kine, e, eexc, shell);
|
||||
if (prob < pmax) {
|
||||
e2 = 2*e;
|
||||
break;
|
||||
}
|
||||
pmax = prob;
|
||||
e0 = e;
|
||||
}
|
||||
//G4cout << " E0(keV)=" << e0/keV << " pmax=" << pmax << G4endl;
|
||||
pmax *= 1.05;
|
||||
// regression method with two regions
|
||||
G4double e1 = emax;
|
||||
G4double p1 = 0.0;
|
||||
if (2*e0 < emax) {
|
||||
e1 = e0 + 0.25*(emax - e0);
|
||||
p1 = ProbabilityFunction(kine, e1, eexc, shell);
|
||||
}
|
||||
G4double s2 = p1*(emax - e1);
|
||||
s2 /= (s2 + e1*pmax);
|
||||
G4double s1 = 1.0 - s2;
|
||||
|
||||
// sampling
|
||||
G4int count = 0;
|
||||
G4double ymax, y, deltae;
|
||||
for (G4int i = 0; i<100000; ++i) {
|
||||
G4double q = G4UniformRand();
|
||||
if (q <= s1) {
|
||||
ymax = pmax;
|
||||
deltae = e1 * q / s1;
|
||||
} else {
|
||||
ymax = p1;
|
||||
deltae = e1 + (emax - e1)* (q - s1) / s2;
|
||||
}
|
||||
y = ProbabilityFunction(kine, deltae, eexc, shell);
|
||||
//G4cout << " " << i << ". deltae=" << deltae/CLHEP::keV
|
||||
// << " y=" << y << " ymax=" << ymax << G4endl;
|
||||
if (y > ymax && count < 10) {
|
||||
++count;
|
||||
G4cout << "G4DNARuddIonisationExtendedModel::SampleElectronEnergy warning: "
|
||||
<< fParticle->GetParticleName() << " E(keV)=" << kine/CLHEP::keV
|
||||
<< " Edelta(keV)=" << deltae/CLHEP::keV
|
||||
<< " y=" << y << " ymax=" << ymax << " n=" << i << G4endl;
|
||||
}
|
||||
if (ymax * G4UniformRand() < y) {
|
||||
return deltae;
|
||||
}
|
||||
}
|
||||
deltae = e2;
|
||||
return deltae;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARuddIonisationExtendedModel::ProbabilityFunction(G4double kine,
|
||||
G4double deltae,
|
||||
G4double bindingEnergy,
|
||||
G4int shell)
|
||||
{
|
||||
// Shells ids are 0 1 2 3 4 (4 is k shell)
|
||||
// !!Attention, "energyTransfer" here is the energy transfered to the electron which means
|
||||
// that the secondary kinetic energy is w = energyTransfer - bindingEnergy
|
||||
//
|
||||
// ds S F1(nu) + w * F2(nu)
|
||||
// ---- = G(k) * ---- -------------------------------------------
|
||||
// dw Bj (1+w)^3 * [1 + exp{alpha * (w - wc) / nu}]
|
||||
//
|
||||
// w is the secondary electron kinetic Energy in eV
|
||||
//
|
||||
// All the other parameters can be found in Rudd's Papers
|
||||
//
|
||||
// M.Eugene Rudd, 1988, User-Friendly model for the energy distribution of
|
||||
// electrons from protons or electron collisions. Nucl. Tracks Rad. Meas.Vol 16 N0 2/3 pp 219-218
|
||||
//
|
||||
G4double A1, B1, C1, D1, E1, A2, B2, C2, D2, alphaConst;
|
||||
// Initialisation of sampling
|
||||
G4double A1, B1, C1, D1, E1, A2, B2, C2, D2;
|
||||
if (shell == 4) {
|
||||
//Data For Liquid Water K SHELL from Dingfelder (Protons in Water)
|
||||
A1 = 1.25;
|
||||
@@ -537,32 +417,166 @@ G4double G4DNARuddIonisationExtendedModel::ProbabilityFunction(G4double kine,
|
||||
D2 = 0.04;
|
||||
alphaConst = 0.64;
|
||||
}
|
||||
G4double bEnergy = Bj[shell];
|
||||
G4double w = deltae/bEnergy;
|
||||
G4double u = Ry/bEnergy;
|
||||
G4double tau = kine/fMass;
|
||||
G4double gam = 1.0 + tau;;
|
||||
|
||||
G4double v2 = 0.5*CLHEP::electron_mass_c2*tau*(tau + 2.0)/(bEnergy*gam*gam);
|
||||
G4double v = std::sqrt(v2);
|
||||
G4double wc = 4.*v2 - 2.*v - 0.25*u;
|
||||
|
||||
G4double x = alphaConst*(w - wc)/v;
|
||||
G4double y = (x > -15.) ? 1.0 + G4Exp(x) : 1.0;
|
||||
bEnergy = Bj[shell];
|
||||
G4double v2 = 0.25*emax/(bEnergy*gam*gam);
|
||||
v = std::sqrt(v2);
|
||||
u = Ry/bEnergy;
|
||||
wc = 4.*v2 - 2.*v - 0.25*u;
|
||||
|
||||
G4double L1 = (C1 * fGpow->powA(v, D1)) / (1. + E1 * fGpow->powA(v, (D1 + 4.)));
|
||||
G4double L2 = C2 * fGpow->powA(v, D2);
|
||||
G4double H1 = (A1 * G4Log(1. + v2)) / (v2 + (B1 / v2));
|
||||
G4double H2 = (A2 / v2) + (B2 / (v2 * v2));
|
||||
|
||||
G4double F1 = L1 + H1;
|
||||
G4double F2 = (L2 * H2) / (L2 + H2);
|
||||
F1 = L1 + H1;
|
||||
F2 = (L2 * H2) / (L2 + H2);
|
||||
return emax;
|
||||
}
|
||||
|
||||
G4double res = CorrectionFactor(kine, shell) * (F1 + w*F2) * Gj[shell] /
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARuddIonisationExtendedModel::SampleElectronEnergy(G4double kine,
|
||||
G4int shell)
|
||||
{
|
||||
G4double emax = MaxEnergy(kine, shell);
|
||||
// compute cumulative probability function
|
||||
G4double step = 1*CLHEP::eV;
|
||||
auto nn = (G4int)(emax/step);
|
||||
nn = std::min(std::max(nn, 10), 100);
|
||||
step = emax/(G4double)nn;
|
||||
|
||||
// find max probability
|
||||
G4double pmax = ProbabilityFunction(kine, 0.0, shell);
|
||||
//G4cout << "## E(keV)=" << kine/keV << " emax=" << emax/keV
|
||||
// << " pmax(0)=" << pmax << " shell=" << shell << " nn=" << nn << G4endl;
|
||||
|
||||
G4double e0 = 0.0; // energy with max probability
|
||||
// 2 areas after point with max probability
|
||||
G4double e1 = emax;
|
||||
G4double e2 = emax;
|
||||
G4double p1 = 0.0;
|
||||
G4double p2 = 0.0;
|
||||
const G4double f = 0.25;
|
||||
|
||||
// find max probability
|
||||
G4double e = 0.0;
|
||||
G4double p = 0.0;
|
||||
for (G4int i=0; i<nn; ++i) {
|
||||
e += step;
|
||||
p = ProbabilityFunction(kine, e, shell);
|
||||
if (p > pmax) {
|
||||
pmax = p;
|
||||
e0 = e;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// increase step to be more effective
|
||||
step *= 2.0;
|
||||
// 2-nd area
|
||||
for (G4int i=0; i<nn; ++i) {
|
||||
e += step;
|
||||
if (std::abs(e - emax) < step) {
|
||||
e1 = emax;
|
||||
break;
|
||||
}
|
||||
p = ProbabilityFunction(kine, e, shell);
|
||||
if (p < f*pmax) {
|
||||
p1 = p;
|
||||
e1 = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 3-d area
|
||||
if (e < emax) {
|
||||
for (G4int i=0; i<nn; ++i) {
|
||||
e += step;
|
||||
if (std::abs(e - emax) < step) {
|
||||
e2 = emax;
|
||||
break;
|
||||
}
|
||||
p = ProbabilityFunction(kine, e, shell);
|
||||
if (p < f*p1) {
|
||||
p2 = p;
|
||||
e2 = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pmax *= 1.05;
|
||||
// regression method with 3 regions
|
||||
G4double s0 = pmax*e1;
|
||||
G4double s1 = s0 + p1 * (e2 - e1);
|
||||
G4double s2 = s1 + p2 * (emax - e2);
|
||||
s0 = (s0 == s1) ? 1.0 : s0 / s2;
|
||||
s1 = (s1 == s2) ? 1.0 : s1 / s2;
|
||||
|
||||
//G4cout << "pmax=" << pmax << " e1(keV)=" << e1/keV << " p1=" << p1 << " e2(keV)=" << e2/keV
|
||||
// << " p2=" << p2 << " s0=" << s0 << " s1=" << s1 << " s2=" << s2 << G4endl;
|
||||
|
||||
// sampling
|
||||
G4int count = 0;
|
||||
G4double ymax, y, deltae;
|
||||
for (G4int i = 0; i<100000; ++i) {
|
||||
G4double q = G4UniformRand();
|
||||
if (q <= s0) {
|
||||
ymax = pmax;
|
||||
deltae = e1 * q / s0;
|
||||
} else if (q <= s1) {
|
||||
ymax = p1;
|
||||
deltae = e1 + (e2 - e1) * (q - s0) / (s1 - s0);
|
||||
} else {
|
||||
ymax = p2;
|
||||
deltae = e2 + (emax - e2) * (q - s1) / (1.0 - s1);
|
||||
}
|
||||
y = ProbabilityFunction(kine, deltae, shell);
|
||||
//G4cout << " " << i << ". deltae=" << deltae/CLHEP::keV
|
||||
// << " y=" << y << " ymax=" << ymax << G4endl;
|
||||
if (y > ymax && count < 10) {
|
||||
++count;
|
||||
G4cout << "G4DNARuddIonisationExtendedModel::SampleElectronEnergy warning: "
|
||||
<< fParticle->GetParticleName() << " E(keV)=" << kine/CLHEP::keV
|
||||
<< " Edelta(keV)=" << deltae/CLHEP::keV
|
||||
<< " y=" << y << " ymax=" << ymax << " n=" << i << G4endl;
|
||||
}
|
||||
if (ymax * G4UniformRand() <= y) {
|
||||
return deltae;
|
||||
}
|
||||
}
|
||||
deltae = std::min(e0 + step, 0.5*emax);
|
||||
return deltae;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARuddIonisationExtendedModel::ProbabilityFunction(G4double kine,
|
||||
G4double deltae,
|
||||
G4int shell)
|
||||
{
|
||||
// Shells ids are 0 1 2 3 4 (4 is k shell)
|
||||
// !!Attention, "energyTransfer" here is the energy transfered to the electron which means
|
||||
// that the secondary kinetic energy is w = energyTransfer - bindingEnergy
|
||||
//
|
||||
// ds S F1(nu) + w * F2(nu)
|
||||
// ---- = G(k) * ---- -------------------------------------------
|
||||
// dw Bj (1+w)^3 * [1 + exp{alpha * (w - wc) / nu}]
|
||||
//
|
||||
// w is the secondary electron kinetic Energy in eV
|
||||
//
|
||||
// All the other parameters can be found in Rudd's Papers
|
||||
//
|
||||
// M.Eugene Rudd, 1988, User-Friendly model for the energy distribution of
|
||||
// electrons from protons or electron collisions. Nucl. Tracks Rad. Meas.Vol 16 N0 2/3 pp 219-218
|
||||
//
|
||||
G4double w = deltae/bEnergy;
|
||||
G4double x = alphaConst*(w - wc)/v;
|
||||
G4double y = (x > -15.) ? 1.0 + G4Exp(x) : 1.0;
|
||||
|
||||
G4double res = CorrectionFactor(kine, shell) * (F1 + w*F2) /
|
||||
(fGpow->powN((1. + w)/u, 3) * y);
|
||||
|
||||
if(isHelium) {
|
||||
G4double energyTransfer = deltae + bindingEnergy;
|
||||
if (isHelium) {
|
||||
G4double energyTransfer = deltae + bEnergy;
|
||||
G4double Zeff = 2.0 -
|
||||
(sCoefficient[0] * S_1s(kine, energyTransfer, slaterEffectiveCharge[0], 1.) +
|
||||
sCoefficient[1] * S_2s(kine, energyTransfer, slaterEffectiveCharge[1], 2.) +
|
||||
@@ -579,9 +593,8 @@ G4double G4DNARuddIonisationExtendedModel::ComputeProbabilityFunction(
|
||||
const G4ParticleDefinition* p, G4double e, G4double deltae, G4int shell)
|
||||
{
|
||||
if (fParticle != p) { SetParticle(p); }
|
||||
G4double bEnergy = (useDNAWaterStructure)
|
||||
? waterStructure.IonisationEnergy(shell) : Bj[shell];
|
||||
return ProbabilityFunction(e, deltae, bEnergy, shell);
|
||||
MaxEnergy(e, shell);
|
||||
return ProbabilityFunction(e, deltae, shell);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNATripleIonisationModel.cc
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
// Reference: J.Meesungnoen et. al, DOI: 10.1021/jp058037z
|
||||
//
|
||||
|
||||
#include "G4DNATripleIonisationModel.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UAtomicDeexcitation.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4DNARuddAngle.hh"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
|
||||
G4DNAWaterIonisationStructure water_structure;
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
//==============================================================================
|
||||
|
||||
// constructor
|
||||
G4DNATripleIonisationModel::G4DNATripleIonisationModel(
|
||||
const G4ParticleDefinition* p, const G4String& model_name)
|
||||
: G4DNADoubleIonisationModel(p, model_name)
|
||||
{
|
||||
// Triple-ionisation energy
|
||||
energy_threshold_ = 65.0 * eV;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNATripleIonisationModel::Initialise(
|
||||
const G4ParticleDefinition* particle, const G4DataVector&)
|
||||
{
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling G4DNATripleIonisationModel::Initialise()" << G4endl;
|
||||
}
|
||||
|
||||
proton_def_ = G4Proton::ProtonDefinition();
|
||||
alpha_def_ = G4DNAGenericIonsManager::Instance()->GetIon("alpha++");
|
||||
carbon_def_ = G4IonTable::GetIonTable()->GetIon(6, 12);
|
||||
|
||||
constexpr G4double kScaleFactor = 1.0 * m * m;
|
||||
|
||||
mioni_manager_ = new G4DNAMultipleIonisationManager();
|
||||
|
||||
G4double Z{0.0}, A{0.0};
|
||||
G4String alpha_param_file{"dna/multipleionisation_alphaparam_champion.dat"};
|
||||
|
||||
if (particle == proton_def_) {
|
||||
|
||||
// *************************************************************************
|
||||
// for protons
|
||||
auto proton = proton_def_->GetParticleName();
|
||||
elow_tab_[proton] = model_elow_tab_[1];
|
||||
eupp_tab_[proton] = 3.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_proton = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_proton->LoadData("dna/sigma_ionisation_p_rudd");
|
||||
xs_tab_[proton] = xs_proton;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[proton]);
|
||||
SetHighEnergyLimit(eupp_tab_[proton]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_p.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(proton_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(proton_def_->GetAtomicMass());
|
||||
|
||||
} else if (particle == alpha_def_) {
|
||||
|
||||
//**************************************************************************
|
||||
// for alpha particles
|
||||
auto alpha = alpha_def_->GetParticleName();
|
||||
elow_tab_[alpha] = model_elow_tab_[4];
|
||||
eupp_tab_[alpha] = 23.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_alpha = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_alpha->LoadData("dna/sigma_ionisation_alphaplusplus_rudd");
|
||||
xs_tab_[alpha] = xs_alpha;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[alpha]);
|
||||
SetHighEnergyLimit(eupp_tab_[alpha]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_alphaplusplus.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(alpha_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(alpha_def_->GetAtomicMass());
|
||||
|
||||
} else if (particle == G4GenericIon::GenericIonDefinition()) {
|
||||
|
||||
// *************************************************************************
|
||||
// for carbon ions
|
||||
auto carbon = carbon_def_->GetParticleName();
|
||||
elow_tab_[carbon] = model_elow_tab_[5] * carbon_def_->GetAtomicMass();
|
||||
eupp_tab_[carbon] = 120.0 * MeV;
|
||||
|
||||
// load cross-section data for single ionization process
|
||||
auto xs_carbon = new G4DNACrossSectionDataSet(
|
||||
new G4LogLogInterpolation, eV, kScaleFactor);
|
||||
xs_carbon->LoadData("dna/sigma_ionisation_c_rudd");
|
||||
xs_tab_[carbon] = xs_carbon;
|
||||
|
||||
// set energy limits
|
||||
SetLowEnergyLimit(elow_tab_[carbon]);
|
||||
SetHighEnergyLimit(eupp_tab_[carbon]);
|
||||
|
||||
if (!use_champion_param_) {
|
||||
alpha_param_file = "dna/multipleionisation_alphaparam_c.dat";
|
||||
}
|
||||
|
||||
Z = static_cast<G4double>(carbon_def_->GetAtomicNumber());
|
||||
A = static_cast<G4double>(carbon_def_->GetAtomicMass());
|
||||
|
||||
}
|
||||
|
||||
// load alpha parameter
|
||||
mioni_manager_->LoadAlphaParam(alpha_param_file, Z, A);
|
||||
|
||||
if (verbose_level_ > 0) {
|
||||
G4cout << "G4DNATripleIonisationModel is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / keV << " keV for "
|
||||
<< particle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
water_density_ = G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(
|
||||
G4Material::GetMaterial("G4_WATER"));
|
||||
|
||||
atom_deex_ = G4LossTableManager::Instance()->AtomDeexcitation();
|
||||
|
||||
if (is_initialized_) { return; }
|
||||
|
||||
particle_change_ = GetParticleChangeForGamma();
|
||||
is_initialized_ = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4double G4DNATripleIonisationModel::CrossSectionPerVolume(
|
||||
const G4Material* material, const G4ParticleDefinition* pdef,
|
||||
G4double ekin, G4double, G4double)
|
||||
{
|
||||
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling G4DNATripleIonisationModel::CrossSectionPerVolume()"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
if (pdef != proton_def_ && pdef != alpha_def_ && pdef != carbon_def_) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static G4double water_dens = (*water_density_)[material->GetIndex()];
|
||||
|
||||
const auto& pname = pdef->GetParticleName();
|
||||
|
||||
const auto low_energy_lim = GetLowEnergyLimit(pname);
|
||||
const auto upp_energy_lim = GetUppEnergyLimit(pname);
|
||||
|
||||
G4double sigma{0.0};
|
||||
if (ekin <= upp_energy_lim) {
|
||||
|
||||
if (ekin < low_energy_lim) { ekin = low_energy_lim; }
|
||||
|
||||
CrossSectionDataTable::iterator pos = xs_tab_.find(pname);
|
||||
if (pos == xs_tab_.end()) {
|
||||
G4Exception("G4DNATripleIonisationModel::CrossSectionPerVolume",
|
||||
"em0002", FatalException,
|
||||
"Model not applicable to particle type.");
|
||||
}
|
||||
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
if (table != nullptr) {
|
||||
const auto a = mioni_manager_->GetAlphaParam(ekin);
|
||||
sigma = table->FindValue(ekin) * a * a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (verbose_level_ > 2) {
|
||||
|
||||
std::stringstream msg;
|
||||
|
||||
msg << "----------------------------------------------------------------\n";
|
||||
msg << " G4DNATripleIonisationModel - XS INFO START\n";
|
||||
msg << " - Kinetic energy(eV): " << ekin/eV << ", Particle : "
|
||||
<< pdef->GetParticleName() << "\n";
|
||||
msg << " - Cross section per water molecule (cm^2): "
|
||||
<< sigma / cm / cm << "\n";
|
||||
msg << " - Cross section per water molecule (cm^-1): "
|
||||
<< sigma * water_dens / (1.0 / cm) << "\n";
|
||||
msg << " G4DNATripleIonisationModel - XS INFO END\n";
|
||||
msg << "----------------------------------------------------------------\n";
|
||||
|
||||
G4cout << msg.str() << G4endl;
|
||||
|
||||
}
|
||||
|
||||
return (sigma * water_dens);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNATripleIonisationModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vsec, const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle, G4double, G4double)
|
||||
{
|
||||
|
||||
if (verbose_level_ > 3) {
|
||||
G4cout << "Calling SampleSecondaries() of G4DNATripleIonisationModel"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// get the definition for this parent particle
|
||||
auto pdef = particle->GetDefinition();
|
||||
|
||||
// get kinetic energy
|
||||
auto ekin = particle->GetKineticEnergy();
|
||||
|
||||
// get particle name
|
||||
const auto& pname = pdef->GetParticleName();
|
||||
|
||||
// get energy limits
|
||||
const auto low_energy_lim = GetLowEnergyLimit(pname);
|
||||
|
||||
// ***************************************************************************
|
||||
// stop the transportation process of this parent particle
|
||||
// if its kinetic energy is below the lower limit
|
||||
if (ekin < low_energy_lim) {
|
||||
particle_change_->SetProposedKineticEnergy(0.0);
|
||||
particle_change_->ProposeTrackStatus(fStopAndKill);
|
||||
particle_change_->ProposeLocalEnergyDeposit(ekin);
|
||||
return;
|
||||
}
|
||||
// ***************************************************************************
|
||||
|
||||
constexpr G4int kNumSecondaries = 3;
|
||||
constexpr G4double kDeltaTheta = pi * 0.666666667;
|
||||
|
||||
G4int ioni_shell[kNumSecondaries] = {0, 0, 0};
|
||||
G4double shell_energy[kNumSecondaries];
|
||||
|
||||
auto scale_param = mioni_manager_->GetAlphaParam(ekin);
|
||||
scale_param *= scale_param;
|
||||
|
||||
G4bool is_continue{true};
|
||||
while (1) {
|
||||
ioni_shell[0] = RandomSelect(ekin, scale_param, pname);
|
||||
ioni_shell[1] = RandomSelect(ekin, scale_param, pname);
|
||||
ioni_shell[2] = RandomSelect(ekin, scale_param, pname);
|
||||
is_continue = (ioni_shell[0] == ioni_shell[1] &&
|
||||
ioni_shell[1] == ioni_shell[2]);
|
||||
if (!is_continue) { break; }
|
||||
}
|
||||
|
||||
G4double tot_ioni_energy{0.0};
|
||||
for (int i = 0; i < kNumSecondaries; i++) {
|
||||
shell_energy[i] = ::water_structure.IonisationEnergy(ioni_shell[i]);
|
||||
tot_ioni_energy += shell_energy[i];
|
||||
}
|
||||
|
||||
if (ekin < tot_ioni_energy || tot_ioni_energy < energy_threshold_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// generate secondary electrons
|
||||
G4double theta{0.0}, phi{0.0}, tot_ekin2{0.0};
|
||||
for (int i = 0; i < kNumSecondaries; i++) {
|
||||
tot_ekin2 += GenerateSecondaries(vsec, couple, particle, ioni_shell[i],
|
||||
theta, phi, shell_energy[i]);
|
||||
theta += kDeltaTheta;
|
||||
}
|
||||
|
||||
// This should never happen
|
||||
if (mioni_manager_->CheckShellEnergy(eTripleIonisedMolecule, shell_energy)) {
|
||||
G4Exception("G4DNATripleIonisatioModel::SampleSecondaries()",
|
||||
"em2050", FatalException, "Negative local energy deposit");
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// update kinematics for this parent particle
|
||||
const auto primary_dir = particle->GetMomentumDirection();
|
||||
particle_change_->ProposeMomentumDirection(primary_dir);
|
||||
|
||||
const auto scattered_energy = ekin - tot_ioni_energy - tot_ekin2;
|
||||
|
||||
// update total amount of shell energy
|
||||
tot_ioni_energy = shell_energy[0] + shell_energy[1] + shell_energy[2];
|
||||
|
||||
if (stat_code_) {
|
||||
particle_change_->SetProposedKineticEnergy(ekin);
|
||||
particle_change_->ProposeLocalEnergyDeposit(
|
||||
ekin - scattered_energy);
|
||||
} else {
|
||||
particle_change_->SetProposedKineticEnergy(scattered_energy);
|
||||
particle_change_->ProposeLocalEnergyDeposit(tot_ioni_energy);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// generate triple-ionized water molecules (H2O^3+)
|
||||
const auto the_track = particle_change_->GetCurrentTrack();
|
||||
mioni_manager_->CreateMultipleIonisedWaterMolecule(
|
||||
eTripleIonisedMolecule, ioni_shell, the_track);
|
||||
// ***************************************************************************
|
||||
|
||||
}
|
||||
@@ -31,27 +31,20 @@
|
||||
|
||||
#include "G4VEmProcess.hh"
|
||||
|
||||
#include "G4DNAGenericIonsManager.hh"
|
||||
#include "G4Proton.hh"
|
||||
|
||||
// Available models
|
||||
#include "G4DNADingfelderChargeDecreaseModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class G4DNAChargeDecrease : public G4VEmProcess
|
||||
|
||||
{
|
||||
public:
|
||||
|
||||
G4DNAChargeDecrease(const G4String& processName ="DNAChargeDecrease",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
|
||||
~G4DNAChargeDecrease() override;
|
||||
~G4DNAChargeDecrease() override = default;
|
||||
|
||||
G4bool IsApplicable(const G4ParticleDefinition&) override;
|
||||
|
||||
virtual void PrintInfo();
|
||||
void ProcessDescription(std::ostream& outFile) const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -59,7 +52,7 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
G4bool isInitialised{false};
|
||||
G4bool isInitialised{false};
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -30,26 +30,21 @@
|
||||
#define G4DNAChargeIncrease_h 1
|
||||
|
||||
#include "G4VEmProcess.hh"
|
||||
#include "G4DNAGenericIonsManager.hh"
|
||||
|
||||
// Available models
|
||||
#include "G4DNADingfelderChargeIncreaseModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class G4DNAChargeIncrease : public G4VEmProcess
|
||||
|
||||
{
|
||||
public:
|
||||
|
||||
G4DNAChargeIncrease(const G4String& processName ="DNAChargeIncrease",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
|
||||
~G4DNAChargeIncrease() override;
|
||||
~G4DNAChargeIncrease() override = default;
|
||||
|
||||
G4bool IsApplicable(const G4ParticleDefinition&) override;
|
||||
|
||||
virtual void PrintInfo();
|
||||
void ProcessDescription(std::ostream& outFile) const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -57,7 +52,7 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
G4bool isInitialised{false};
|
||||
G4bool isInitialised{false};
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNADoubleIonisation.hh
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
|
||||
#ifndef G4DNA_DOUBLE_IONISATION_HH_
|
||||
#define G4DNA_DOUBLE_IONISATION_HH_
|
||||
|
||||
#include "G4VEmProcess.hh"
|
||||
#include "G4DNAGenericIonsManager.hh"
|
||||
|
||||
class G4DNADoubleIonisation : public G4VEmProcess {
|
||||
public:
|
||||
G4DNADoubleIonisation(const G4String& processName = "G4DNADoubleIonisation",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
|
||||
virtual ~G4DNADoubleIonisation() = default;
|
||||
|
||||
virtual G4bool IsApplicable(const G4ParticleDefinition&);
|
||||
|
||||
virtual void PrintInfo();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void InitialiseProcess(const G4ParticleDefinition*);
|
||||
|
||||
private:
|
||||
G4bool is_initialized_;
|
||||
|
||||
};
|
||||
|
||||
#endif // G4DNA_DOUBLE_IONISATION_HH_
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNAQuadrupleIonisation.hh
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
|
||||
#ifndef G4DNA_QUADRUPLE_IONISATION_HH_
|
||||
#define G4DNA_QUADRUPLE_IONISATION_HH_
|
||||
|
||||
#include "G4VEmProcess.hh"
|
||||
#include "G4DNAGenericIonsManager.hh"
|
||||
|
||||
class G4DNAQuadrupleIonisation : public G4VEmProcess {
|
||||
public:
|
||||
G4DNAQuadrupleIonisation(const G4String& pname ="DNAQuadrupleIonisation",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
|
||||
virtual ~G4DNAQuadrupleIonisation() = default;
|
||||
|
||||
virtual G4bool IsApplicable(const G4ParticleDefinition&);
|
||||
|
||||
virtual void PrintInfo();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void InitialiseProcess(const G4ParticleDefinition*);
|
||||
|
||||
private:
|
||||
G4bool is_initialized_;
|
||||
};
|
||||
|
||||
#endif // G4DNA_QUADRUPLE_IONISATION_HH_
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNATripleIonisation.hh
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
|
||||
#ifndef G4DNA_TRIPLE_IONISATION_HH_
|
||||
#define G4DNA_TRIPLE_IONISATION_HH_
|
||||
|
||||
#include "G4VEmProcess.hh"
|
||||
#include "G4DNAGenericIonsManager.hh"
|
||||
|
||||
class G4DNATripleIonisation : public G4VEmProcess {
|
||||
public:
|
||||
G4DNATripleIonisation(const G4String& pname ="DNATripleIonisation",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
|
||||
virtual ~G4DNATripleIonisation() = default;
|
||||
|
||||
virtual G4bool IsApplicable(const G4ParticleDefinition&);
|
||||
|
||||
virtual void PrintInfo();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void InitialiseProcess(const G4ParticleDefinition*);
|
||||
|
||||
private:
|
||||
G4bool is_initialized_;
|
||||
|
||||
};
|
||||
|
||||
#endif // G4DNA_TRIPLE_IONISATION_HH_
|
||||
+13
-8
@@ -31,8 +31,8 @@
|
||||
// We would be very happy hearing from you, send us your feedback! :)
|
||||
//
|
||||
// In order for Geant4-DNA to be maintained and still open-source,
|
||||
// article citations are crucial.
|
||||
// If you use Geant4-DNA chemistry and you publish papers about your software,
|
||||
// article citations are crucial.
|
||||
// If you use Geant4-DNA chemistry and you publish papers about your software,
|
||||
// in addition to the general paper on Geant4-DNA:
|
||||
//
|
||||
// Int. J. Model. Simul. Sci. Comput. 1 (2010) 157–178
|
||||
@@ -41,7 +41,7 @@
|
||||
// reference papers on chemistry:
|
||||
//
|
||||
// J. Comput. Phys. 274 (2014) 841-882
|
||||
// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
|
||||
// Prog. Nucl. Sci. Tec. 2 (2011) 503-508
|
||||
|
||||
|
||||
#ifndef G4DNAWaterDissociationDisplacer_h
|
||||
@@ -59,26 +59,31 @@ class G4DNAWaterDissociationDisplacer: public G4VMolecularDissociationDisplacer
|
||||
public:
|
||||
G4DNAWaterDissociationDisplacer();
|
||||
~G4DNAWaterDissociationDisplacer() override;
|
||||
|
||||
|
||||
std::vector<G4ThreeVector>
|
||||
GetProductsDisplacement(const G4MolecularDissociationChannel*) const
|
||||
override;
|
||||
|
||||
|
||||
G4ThreeVector
|
||||
GetMotherMoleculeDisplacement(const G4MolecularDissociationChannel*) const
|
||||
override;
|
||||
|
||||
|
||||
G4ThreeVector radialDistributionOfElectron() const;
|
||||
G4ThreeVector radialDistributionOfProducts(G4double r_rms) const;
|
||||
static G4double ElectronProbaDistribution(G4double r);
|
||||
|
||||
|
||||
G4CT_COUNT_DEF(Ionisation_DissociationDecay)
|
||||
G4CT_COUNT_DEF(A1B1_DissociationDecay)
|
||||
G4CT_COUNT_DEF(B1A1_DissociationDecay)
|
||||
G4CT_COUNT_DEF(B1A1_DissociationDecay2)
|
||||
G4CT_COUNT_DEF(AutoIonisation)
|
||||
G4CT_COUNT_DEF(DissociativeAttachment)
|
||||
|
||||
G4CT_COUNT_DEF(DoubleIonisation_DissociationDecay1)
|
||||
G4CT_COUNT_DEF(DoubleIonisation_DissociationDecay2)
|
||||
G4CT_COUNT_DEF(DoubleIonisation_DissociationDecay3)
|
||||
G4CT_COUNT_DEF(TripleIonisation_DissociationDecay)
|
||||
G4CT_COUNT_DEF(QuadrupleIonisation_DissociationDecay)
|
||||
|
||||
private:
|
||||
G4double ke;
|
||||
G4DNAModelSubType dnaSubType;
|
||||
|
||||
@@ -23,6 +23,9 @@ geant4_add_module(G4emdna-processes
|
||||
G4DNAVibExcitation.hh
|
||||
G4DNAScavengerProcess.hh
|
||||
G4DNAPolyNucleotideReactionProcess.hh
|
||||
G4DNADoubleIonisation.hh
|
||||
G4DNATripleIonisation.hh
|
||||
G4DNAQuadrupleIonisation.hh
|
||||
SOURCES
|
||||
G4DNAAttachment.cc
|
||||
G4DNABrownianTransportation.cc
|
||||
@@ -42,7 +45,10 @@ geant4_add_module(G4emdna-processes
|
||||
G4DNASecondOrderReaction.cc
|
||||
G4DNAVibExcitation.cc
|
||||
G4DNAScavengerProcess.cc
|
||||
G4DNAPolyNucleotideReactionProcess.cc)
|
||||
G4DNAPolyNucleotideReactionProcess.cc
|
||||
G4DNADoubleIonisation.cc
|
||||
G4DNATripleIonisation.cc
|
||||
G4DNAQuadrupleIonisation.cc)
|
||||
|
||||
geant4_module_link_libraries(G4emdna-processes
|
||||
PUBLIC
|
||||
|
||||
@@ -27,77 +27,59 @@
|
||||
#include "G4DNAChargeDecrease.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4LowEnergyEmProcessSubType.hh"
|
||||
#include "G4DNADingfelderChargeDecreaseModel.hh"
|
||||
#include "G4DNAIonChargeDecreaseModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4DNAChargeDecrease::G4DNAChargeDecrease(const G4String& processName,
|
||||
G4ProcessType type) :
|
||||
G4VEmProcess(processName, type)
|
||||
{
|
||||
SetBuildTableFlag(false);
|
||||
SetProcessSubType(fLowEnergyChargeDecrease);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4DNAChargeDecrease::~G4DNAChargeDecrease()
|
||||
= default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4DNAChargeDecrease::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
return (&p == G4Proton::ProtonDefinition()
|
||||
|| &p == instance->GetIon("alpha++") || &p == instance->GetIon("alpha+"));
|
||||
G4String name = p.GetParticleName();
|
||||
return (p.IsGeneralIon() ||
|
||||
name == "proton" || name == "alpha+" || name == "alpha");
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAChargeDecrease::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!isInitialised)
|
||||
{
|
||||
if (!isInitialised) {
|
||||
isInitialised = true;
|
||||
SetBuildTableFlag(false);
|
||||
|
||||
G4String name = p->GetParticleName();
|
||||
auto mod = EmModel();
|
||||
if (nullptr == mod) {
|
||||
|
||||
G4String name = p->GetParticleName();
|
||||
|
||||
if(name == "proton")
|
||||
{
|
||||
if(EmModel() == nullptr)
|
||||
{
|
||||
SetEmModel(new G4DNADingfelderChargeDecreaseModel);
|
||||
EmModel()->SetLowEnergyLimit(100 * eV);
|
||||
EmModel()->SetHighEnergyLimit(100 * MeV);
|
||||
if (name == "proton" || name == "alpha+" || name == "alpha") {
|
||||
SetEmModel(new G4DNADingfelderChargeDecreaseModel());
|
||||
} else {
|
||||
SetEmModel(new G4DNAIonChargeDecreaseModel());
|
||||
}
|
||||
AddEmModel(1, EmModel());
|
||||
}
|
||||
|
||||
if(name == "alpha" || name == "alpha+")
|
||||
{
|
||||
if(EmModel() == nullptr)
|
||||
{
|
||||
SetEmModel(new G4DNADingfelderChargeDecreaseModel);
|
||||
EmModel()->SetLowEnergyLimit(1 * keV);
|
||||
EmModel()->SetHighEnergyLimit(400 * MeV);
|
||||
}
|
||||
AddEmModel(1, EmModel());
|
||||
}
|
||||
|
||||
G4EmParameters* param = G4EmParameters::Instance();
|
||||
EmModel(0)->SetLowEnergyLimit(param->MinKinEnergy());
|
||||
EmModel(0)->SetHighEnergyLimit(param->MaxKinEnergy());
|
||||
AddEmModel(1, EmModel(0));
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4DNAChargeDecrease::PrintInfo()
|
||||
void G4DNAChargeDecrease::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
G4cout << " Total cross sections computed from " << EmModel()->GetName()
|
||||
<< " model" << G4endl;
|
||||
out << " Total cross sections computed from " << EmModel()->GetName()
|
||||
<< " model" << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -27,76 +27,59 @@
|
||||
#include "G4DNAChargeIncrease.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4LowEnergyEmProcessSubType.hh"
|
||||
#include "G4DNADingfelderChargeIncreaseModel.hh"
|
||||
#include "G4DNAIonChargeIncreaseModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4DNAChargeIncrease::G4DNAChargeIncrease(const G4String& processName,
|
||||
G4ProcessType type) :
|
||||
G4VEmProcess(processName, type)
|
||||
{
|
||||
SetBuildTableFlag(false);
|
||||
SetProcessSubType(fLowEnergyChargeIncrease);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4DNAChargeIncrease::~G4DNAChargeIncrease()
|
||||
= default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4DNAChargeIncrease::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
return (&p == instance->GetIon("hydrogen") || &p == instance->GetIon("alpha+")
|
||||
|| &p == instance->GetIon("helium"));
|
||||
G4String name = p.GetParticleName();
|
||||
return (p.IsGeneralIon() ||
|
||||
name == "hydrogen" || name == "alpha+" || name == "helium");
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAChargeIncrease::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!isInitialised)
|
||||
{
|
||||
if (!isInitialised) {
|
||||
isInitialised = true;
|
||||
SetBuildTableFlag(false);
|
||||
|
||||
G4String name = p->GetParticleName();
|
||||
auto mod = EmModel();
|
||||
if (nullptr == mod) {
|
||||
|
||||
G4String name = p->GetParticleName();
|
||||
|
||||
if(name == "hydrogen")
|
||||
{
|
||||
if(EmModel() == nullptr)
|
||||
{
|
||||
SetEmModel(new G4DNADingfelderChargeIncreaseModel);
|
||||
EmModel()->SetLowEnergyLimit(100 * eV);
|
||||
EmModel()->SetHighEnergyLimit(100 * MeV);
|
||||
if (name == "hydrogen" || name == "alpha+" || name == "helium") {
|
||||
SetEmModel(new G4DNADingfelderChargeIncreaseModel());
|
||||
} else {
|
||||
SetEmModel(new G4DNAIonChargeIncreaseModel());
|
||||
}
|
||||
AddEmModel(1, EmModel());
|
||||
}
|
||||
|
||||
if(name == "alpha+" || name == "helium")
|
||||
{
|
||||
if(EmModel() == nullptr)
|
||||
{
|
||||
SetEmModel(new G4DNADingfelderChargeIncreaseModel);
|
||||
EmModel()->SetLowEnergyLimit(1 * keV);
|
||||
EmModel()->SetHighEnergyLimit(400 * MeV);
|
||||
}
|
||||
AddEmModel(1, EmModel());
|
||||
}
|
||||
G4EmParameters* param = G4EmParameters::Instance();
|
||||
EmModel(0)->SetLowEnergyLimit(param->MinKinEnergy());
|
||||
EmModel(0)->SetHighEnergyLimit(param->MaxKinEnergy());
|
||||
AddEmModel(1, EmModel(0));
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4DNAChargeIncrease::PrintInfo()
|
||||
void G4DNAChargeIncrease::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
G4cout << " Total cross sections computed from " << EmModel()->GetName()
|
||||
<< " model" << G4endl;
|
||||
out << " Total cross sections computed from " << EmModel()->GetName()
|
||||
<< " model" << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNADoubleIonisation.cc
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
|
||||
#include "G4DNADoubleIonisation.hh"
|
||||
#include "G4DNADoubleIonisationModel.hh"
|
||||
#include "G4LowEnergyEmProcessSubType.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4Positron.hh"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4DNADoubleIonisation::G4DNADoubleIonisation(
|
||||
const G4String& pname, G4ProcessType type)
|
||||
: G4VEmProcess(pname, type),
|
||||
is_initialized_(false)
|
||||
{
|
||||
SetProcessSubType(fLowEnergyDoubleIonisation);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4bool G4DNADoubleIonisation::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
return (
|
||||
&p == G4Proton::Proton() ||
|
||||
&p == G4DNAGenericIonsManager::Instance()->GetIon("alpha++") ||
|
||||
&p == G4GenericIon::GenericIonDefinition()
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNADoubleIonisation::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
{
|
||||
if (is_initialized_) { return; }
|
||||
|
||||
is_initialized_ = true;
|
||||
SetBuildTableFlag(false);
|
||||
|
||||
const auto name = p->GetParticleName();
|
||||
|
||||
if (name == "proton") {
|
||||
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNADoubleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(3.0 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
|
||||
} else if (name == "alpha") {
|
||||
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNADoubleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(23.0 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
|
||||
} else if (name == "GenericIon") {
|
||||
|
||||
// for carbon ions (12C6+)
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNADoubleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(120 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNADoubleIonisation::PrintInfo()
|
||||
{
|
||||
if (EmModel(1)) {
|
||||
G4cout << " Total cross sections computed from " << EmModel(0)->GetName()
|
||||
<< " and " << EmModel(1)->GetName() << " models" << G4endl;
|
||||
} else {
|
||||
G4cout << " Total cross sections computed from " << EmModel()->GetName()
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -216,7 +216,9 @@ void G4DNAElectronHoleRecombination::MakeReaction(const G4Track& track)
|
||||
|
||||
G4bool G4DNAElectronHoleRecombination::FindReactant(const G4Track& track)
|
||||
{
|
||||
if (GetMolecule(track)->GetCharge() <= 0)
|
||||
// NOTE(Shogo OKADA, 2024-04-05 Fri.): Changed this branch condition to
|
||||
// select only H2O+ ions involved in electron-hole recombination
|
||||
if (GetMolecule(track)->GetCharge() != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNAQuadrupleIonisation.cc
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
|
||||
#include "G4DNAQuadrupleIonisation.hh"
|
||||
#include "G4DNAQuadrupleIonisationModel.hh"
|
||||
#include "G4LowEnergyEmProcessSubType.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4Positron.hh"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4DNAQuadrupleIonisation::G4DNAQuadrupleIonisation(
|
||||
const G4String& pname, G4ProcessType type)
|
||||
: G4VEmProcess(pname, type),
|
||||
is_initialized_(false)
|
||||
{
|
||||
SetProcessSubType(fLowEnergyQuadrupleIonisation);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4bool G4DNAQuadrupleIonisation::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
return (
|
||||
&p == G4Proton::Proton() ||
|
||||
&p == G4DNAGenericIonsManager::Instance()->GetIon("alpha++") ||
|
||||
&p == G4GenericIon::GenericIonDefinition()
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNAQuadrupleIonisation::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
{
|
||||
if (is_initialized_) { return; }
|
||||
|
||||
is_initialized_ = true;
|
||||
SetBuildTableFlag(false);
|
||||
|
||||
const auto name = p->GetParticleName();
|
||||
|
||||
if (name == "proton") {
|
||||
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNAQuadrupleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(3.0 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
|
||||
} else if (name == "alpha") {
|
||||
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNAQuadrupleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(23.0 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
|
||||
} else if (name == "GenericIon") {
|
||||
|
||||
// for carbon ions (12C6+)
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNAQuadrupleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(120.0 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNAQuadrupleIonisation::PrintInfo()
|
||||
{
|
||||
if (EmModel(1)) {
|
||||
G4cout << " Total cross sections computed from " << EmModel(0)->GetName()
|
||||
<< " and " << EmModel(1)->GetName() << " models" << G4endl;
|
||||
} else {
|
||||
G4cout << " Total cross sections computed from "
|
||||
<< EmModel()->GetName() << G4endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4DNATripleIonisation.cc
|
||||
//
|
||||
// Created at 2024/04/03 (Thu.)
|
||||
// Author: Shogo OKADA @KEK-CRC (shogo.okada@kek.jp)
|
||||
//
|
||||
|
||||
#include "G4DNATripleIonisation.hh"
|
||||
#include "G4DNATripleIonisationModel.hh"
|
||||
#include "G4LowEnergyEmProcessSubType.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4Positron.hh"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4DNATripleIonisation::G4DNATripleIonisation(
|
||||
const G4String& pname, G4ProcessType type)
|
||||
: G4VEmProcess(pname, type),
|
||||
is_initialized_(false)
|
||||
{
|
||||
SetProcessSubType(fLowEnergyTripleIonisation);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
G4bool G4DNATripleIonisation::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
return (
|
||||
&p == G4Proton::Proton() ||
|
||||
&p == G4DNAGenericIonsManager::Instance()->GetIon("alpha++") ||
|
||||
&p == G4GenericIon::GenericIonDefinition()
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNATripleIonisation::InitialiseProcess(const G4ParticleDefinition* p)
|
||||
{
|
||||
if (is_initialized_) { return; }
|
||||
|
||||
is_initialized_ = true;
|
||||
SetBuildTableFlag(false);
|
||||
|
||||
const auto name = p->GetParticleName();
|
||||
|
||||
if (name == "proton") {
|
||||
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNATripleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(3.0 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
|
||||
} else if (name == "alpha") {
|
||||
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNATripleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(23.0 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
|
||||
} else if (name == "GenericIon") {
|
||||
|
||||
// for carbon ions (12C6+)
|
||||
if (!EmModel()) {
|
||||
auto ptr = new G4DNATripleIonisationModel();
|
||||
SetEmModel(ptr);
|
||||
ptr->SetLowEnergyLimit(0.0 * keV);
|
||||
ptr->SetHighEnergyLimit(120.0 * MeV);
|
||||
}
|
||||
|
||||
AddEmModel(1, EmModel());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void G4DNATripleIonisation::PrintInfo()
|
||||
{
|
||||
if (EmModel(1)) {
|
||||
G4cout << " Total cross sections computed from " << EmModel(0)->GetName()
|
||||
<< " and " << EmModel(1)->GetName() << " models" << G4endl;
|
||||
} else {
|
||||
G4cout << " Total cross sections computed from "
|
||||
<< EmModel()->GetName() << G4endl;
|
||||
}
|
||||
}
|
||||
+499
-290
@@ -76,6 +76,22 @@ G4CT_COUNT_IMPL(G4DNAWaterDissociationDisplacer,
|
||||
|
||||
G4CT_COUNT_IMPL(G4DNAWaterDissociationDisplacer,
|
||||
DissociativeAttachment)
|
||||
|
||||
G4CT_COUNT_IMPL(G4DNAWaterDissociationDisplacer,
|
||||
DoubleIonisation_DissociationDecay1)
|
||||
|
||||
G4CT_COUNT_IMPL(G4DNAWaterDissociationDisplacer,
|
||||
DoubleIonisation_DissociationDecay2)
|
||||
|
||||
G4CT_COUNT_IMPL(G4DNAWaterDissociationDisplacer,
|
||||
DoubleIonisation_DissociationDecay3)
|
||||
|
||||
G4CT_COUNT_IMPL(G4DNAWaterDissociationDisplacer,
|
||||
TripleIonisation_DissociationDecay)
|
||||
|
||||
G4CT_COUNT_IMPL(G4DNAWaterDissociationDisplacer,
|
||||
QuadrupleIonisation_DissociationDecay)
|
||||
|
||||
/*
|
||||
//------------------------------------------------------------------------------
|
||||
#ifdef _WATER_DISPLACER_USE_KREIPL_
|
||||
@@ -124,7 +140,7 @@ G4double G4DNAWaterDissociationDisplacer::ElectronProbaDistribution(G4double r)
|
||||
*/
|
||||
G4DNAWaterDissociationDisplacer::G4DNAWaterDissociationDisplacer()
|
||||
:
|
||||
|
||||
|
||||
ke(1.7*eV)
|
||||
/*#ifdef _WATER_DISPLACER_USE_KREIPL_
|
||||
fFastElectronDistrib(0., 5., 0.001)
|
||||
@@ -151,7 +167,7 @@ G4DNAWaterDissociationDisplacer::G4DNAWaterDissociationDisplacer()
|
||||
proba += eps;
|
||||
// G4cout << G4BestUnit(r*nanometer, "Length") << G4endl;
|
||||
}*/
|
||||
dnaSubType = G4EmParameters::Instance()->DNAeSolvationSubType();
|
||||
dnaSubType = G4EmParameters::Instance()->DNAeSolvationSubType();
|
||||
// SetVerbose(1);
|
||||
}
|
||||
|
||||
@@ -159,317 +175,505 @@ G4DNAWaterDissociationDisplacer::G4DNAWaterDissociationDisplacer()
|
||||
|
||||
G4DNAWaterDissociationDisplacer::~G4DNAWaterDissociationDisplacer()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
G4ThreeVector
|
||||
G4DNAWaterDissociationDisplacer::
|
||||
GetMotherMoleculeDisplacement(const G4MolecularDissociationChannel*
|
||||
theDecayChannel) const
|
||||
G4ThreeVector G4DNAWaterDissociationDisplacer::GetMotherMoleculeDisplacement(
|
||||
const G4MolecularDissociationChannel* theDecayChannel) const
|
||||
{
|
||||
G4int decayType = theDecayChannel->GetDisplacementType();
|
||||
G4double RMSMotherMoleculeDisplacement(0.);
|
||||
G4int decayType = theDecayChannel->GetDisplacementType();
|
||||
G4double RMSMotherMoleculeDisplacement(0.0);
|
||||
|
||||
switch (decayType)
|
||||
{
|
||||
case Ionisation_DissociationDecay:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
case A1B1_DissociationDecay:
|
||||
RMSMotherMoleculeDisplacement = 0. * nanometer;
|
||||
break;
|
||||
case B1A1_DissociationDecay:
|
||||
RMSMotherMoleculeDisplacement = 0. * nanometer;
|
||||
break;
|
||||
case B1A1_DissociationDecay2:
|
||||
RMSMotherMoleculeDisplacement = 0. * nanometer;
|
||||
break;
|
||||
case AutoIonisation:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
case DissociativeAttachment:
|
||||
RMSMotherMoleculeDisplacement = 0. * nanometer;
|
||||
break;
|
||||
}
|
||||
switch (decayType) {
|
||||
case Ionisation_DissociationDecay:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
case A1B1_DissociationDecay:
|
||||
RMSMotherMoleculeDisplacement = 0.0 * nanometer;
|
||||
break;
|
||||
case B1A1_DissociationDecay:
|
||||
RMSMotherMoleculeDisplacement = 0.0 * nanometer;
|
||||
break;
|
||||
case B1A1_DissociationDecay2:
|
||||
RMSMotherMoleculeDisplacement = 0.0 * nanometer;
|
||||
break;
|
||||
case AutoIonisation:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
case DissociativeAttachment:
|
||||
RMSMotherMoleculeDisplacement = 0.0 * nanometer;
|
||||
break;
|
||||
case DoubleIonisation_DissociationDecay1:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
case DoubleIonisation_DissociationDecay2:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
case DoubleIonisation_DissociationDecay3:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
case TripleIonisation_DissociationDecay:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
case QuadrupleIonisation_DissociationDecay:
|
||||
RMSMotherMoleculeDisplacement = 2.0 * nanometer;
|
||||
break;
|
||||
}
|
||||
|
||||
if (RMSMotherMoleculeDisplacement == 0)
|
||||
{
|
||||
return G4ThreeVector(0, 0, 0);
|
||||
}
|
||||
auto RandDirection =
|
||||
radialDistributionOfProducts(RMSMotherMoleculeDisplacement);
|
||||
if (RMSMotherMoleculeDisplacement == 0) {
|
||||
return G4ThreeVector(0, 0, 0);
|
||||
}
|
||||
|
||||
return RandDirection;
|
||||
auto RandDirection =
|
||||
radialDistributionOfProducts(RMSMotherMoleculeDisplacement);
|
||||
|
||||
return RandDirection;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
vector<G4ThreeVector>
|
||||
G4DNAWaterDissociationDisplacer::
|
||||
GetProductsDisplacement(const G4MolecularDissociationChannel* pDecayChannel) const
|
||||
vector<G4ThreeVector> G4DNAWaterDissociationDisplacer::GetProductsDisplacement(
|
||||
const G4MolecularDissociationChannel* pDecayChannel) const
|
||||
{
|
||||
G4int nbProducts = pDecayChannel->GetNbProducts();
|
||||
vector<G4ThreeVector> theProductDisplacementVector(nbProducts);
|
||||
G4int nbProducts = pDecayChannel->GetNbProducts();
|
||||
vector<G4ThreeVector> theProductDisplacementVector(nbProducts);
|
||||
|
||||
typedef map<const G4MoleculeDefinition*, G4double> RMSmap;
|
||||
RMSmap theRMSmap;
|
||||
typedef map<const G4MoleculeDefinition*, G4double> RMSmap;
|
||||
RMSmap theRMSmap;
|
||||
|
||||
G4int decayType = pDecayChannel->GetDisplacementType();
|
||||
G4int decayType = pDecayChannel->GetDisplacementType();
|
||||
|
||||
switch (decayType)
|
||||
{
|
||||
case Ionisation_DissociationDecay:
|
||||
{
|
||||
if (fVerbose != 0)
|
||||
{
|
||||
G4cout << "Ionisation_DissociationDecay" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
G4double RdmValue = G4UniformRand();
|
||||
|
||||
if (RdmValue < 0.5)
|
||||
{
|
||||
// H3O
|
||||
theRMSmap[G4H3O::Definition()] = 0. * nanometer;
|
||||
// OH
|
||||
theRMSmap[G4OH::Definition()] = 0.8 * nanometer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// H3O
|
||||
theRMSmap[G4H3O::Definition()] = 0.8 * nanometer;
|
||||
// OH
|
||||
theRMSmap[G4OH::Definition()] = 0. * nanometer;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nbProducts; i++)
|
||||
{
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
G4double theRMSDisplacement = theRMSmap[pProduct->GetDefinition()];
|
||||
|
||||
if (theRMSDisplacement == 0.)
|
||||
{
|
||||
theProductDisplacementVector[i] = G4ThreeVector();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto RandDirection = radialDistributionOfProducts(theRMSDisplacement);
|
||||
theProductDisplacementVector[i] = RandDirection;
|
||||
}
|
||||
}
|
||||
break;
|
||||
switch (decayType) {
|
||||
case Ionisation_DissociationDecay:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "Ionisation_DissociationDecay" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
case A1B1_DissociationDecay:
|
||||
{
|
||||
if (fVerbose != 0)
|
||||
{
|
||||
G4cout << "A1B1_DissociationDecay" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
G4double theRMSDisplacement = 2.4 * nanometer;
|
||||
G4double RdmValue = G4UniformRand();
|
||||
|
||||
if (RdmValue < 0.5) {
|
||||
// H3O
|
||||
theRMSmap[G4H3O::Definition()] = 0.0 * nanometer;
|
||||
// OH
|
||||
theRMSmap[G4OH::Definition()] = 0.8 * nanometer;
|
||||
} else {
|
||||
// H3O
|
||||
theRMSmap[G4H3O::Definition()] = 0.8 * nanometer;
|
||||
// OH
|
||||
theRMSmap[G4OH::Definition()] = 0.0 * nanometer;
|
||||
}
|
||||
|
||||
for (G4int i = 0; i < nbProducts; i++) {
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
G4double theRMSDisplacement = theRMSmap[pProduct->GetDefinition()];
|
||||
|
||||
if (theRMSDisplacement == 0.0) {
|
||||
theProductDisplacementVector[i] = G4ThreeVector();
|
||||
} else {
|
||||
auto RandDirection =
|
||||
radialDistributionOfProducts(theRMSDisplacement);
|
||||
|
||||
for (G4int i = 0; i < nbProducts; i++)
|
||||
{
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
|
||||
if (pProduct->GetDefinition() == G4OH::Definition())
|
||||
{
|
||||
theProductDisplacementVector[i] = -1. / 18. * RandDirection;
|
||||
}
|
||||
else if (pProduct->GetDefinition() == G4Hydrogen::Definition())
|
||||
{
|
||||
theProductDisplacementVector[i] = +17. / 18. * RandDirection;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B1A1_DissociationDecay:
|
||||
{
|
||||
if (fVerbose != 0)
|
||||
{
|
||||
G4cout << "B1A1_DissociationDecay" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
G4double theRMSDisplacement = 0.8 * nanometer;
|
||||
auto RandDirection =
|
||||
radialDistributionOfProducts(theRMSDisplacement);
|
||||
|
||||
G4int NbOfOH = 0;
|
||||
for (G4int i = 0; i < nbProducts; ++i)
|
||||
{
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
if (pProduct->GetDefinition() == G4H2::Definition())
|
||||
{
|
||||
// In the paper of Kreipl (2009)
|
||||
// theProductDisplacementVector[i] = -2. / 18. * RandDirection;
|
||||
|
||||
// Based on momentum conservation
|
||||
theProductDisplacementVector[i] = -16. / 18. * RandDirection;
|
||||
}
|
||||
else if (pProduct->GetDefinition() == G4OH::Definition())
|
||||
{
|
||||
// In the paper of Kreipl (2009)
|
||||
// G4ThreeVector OxygenDisplacement = +16. / 18. * RandDirection;
|
||||
|
||||
// Based on momentum conservation
|
||||
G4ThreeVector OxygenDisplacement = +2. / 18. * RandDirection;
|
||||
G4double OHRMSDisplacement = 1.1 * nanometer;
|
||||
|
||||
auto OHDisplacement =
|
||||
radialDistributionOfProducts(OHRMSDisplacement);
|
||||
|
||||
if (NbOfOH == 0)
|
||||
{
|
||||
OHDisplacement = 0.5 * OHDisplacement;
|
||||
}
|
||||
else
|
||||
{
|
||||
OHDisplacement = -0.5 * OHDisplacement;
|
||||
}
|
||||
|
||||
theProductDisplacementVector[i] =
|
||||
OHDisplacement + OxygenDisplacement;
|
||||
|
||||
++NbOfOH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B1A1_DissociationDecay2:
|
||||
{
|
||||
if(fVerbose != 0){
|
||||
G4cout<<"B1A1_DissociationDecay2"<<G4endl;
|
||||
G4cout<<"Channel's name: "<<pDecayChannel->GetName()<<G4endl;
|
||||
radialDistributionOfProducts(theRMSDisplacement);
|
||||
theProductDisplacementVector[i] = RandDirection;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case A1B1_DissociationDecay:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "A1B1_DissociationDecay" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
G4int NbOfH = 0;
|
||||
for(G4int i =0; i < nbProducts; ++i)
|
||||
{
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
if(pProduct->GetDefinition() == G4Oxygen::Definition()){
|
||||
constexpr G4double theRMSDisplacement = 2.4 * nanometer;
|
||||
auto RandDirection = radialDistributionOfProducts(theRMSDisplacement);
|
||||
|
||||
for (G4int i = 0; i < nbProducts; i++) {
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
|
||||
if (pProduct->GetDefinition() == G4OH::Definition()) {
|
||||
theProductDisplacementVector[i] = -1.0 / 18.0 * RandDirection;
|
||||
} else if (pProduct->GetDefinition() == G4Hydrogen::Definition()) {
|
||||
theProductDisplacementVector[i] = +17.0 / 18.0 * RandDirection;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B1A1_DissociationDecay:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "B1A1_DissociationDecay" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
constexpr G4double theRMSDisplacement = 0.8 * nanometer;
|
||||
auto RandDirection = radialDistributionOfProducts(theRMSDisplacement);
|
||||
|
||||
G4int NbOfOH = 0;
|
||||
for (G4int i = 0; i < nbProducts; ++i) {
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
if (pProduct->GetDefinition() == G4H2::Definition()) {
|
||||
// In the paper of Kreipl (2009)
|
||||
// theProductDisplacementVector[i] = -2.0 / 18.0 * RandDirection;
|
||||
|
||||
// Based on momentum conservation
|
||||
theProductDisplacementVector[i] = -16.0 / 18.0 * RandDirection;
|
||||
} else if (pProduct->GetDefinition() == G4OH::Definition()) {
|
||||
// In the paper of Kreipl (2009)
|
||||
// G4ThreeVector OxygenDisplacement = +16.0 / 18.0 * RandDirection;
|
||||
|
||||
// Based on momentum conservation
|
||||
G4ThreeVector OxygenDisplacement = +2.0 / 18.0 * RandDirection;
|
||||
constexpr G4double OHRMSDisplacement = 1.1 * nanometer;
|
||||
|
||||
auto OHDisplacement =
|
||||
radialDistributionOfProducts(OHRMSDisplacement);
|
||||
|
||||
if (NbOfOH == 0) {
|
||||
OHDisplacement = 0.5 * OHDisplacement;
|
||||
} else {
|
||||
OHDisplacement = -0.5 * OHDisplacement;
|
||||
}
|
||||
|
||||
theProductDisplacementVector[i] =
|
||||
OHDisplacement + OxygenDisplacement;
|
||||
|
||||
++NbOfOH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B1A1_DissociationDecay2:
|
||||
{
|
||||
if (fVerbose != 0){
|
||||
G4cout << "B1A1_DissociationDecay2" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
G4int NbOfH = 0;
|
||||
for (G4int i = 0; i < nbProducts; ++i) {
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
if (pProduct->GetDefinition() == G4Oxygen::Definition()) {
|
||||
// O(3p)
|
||||
theProductDisplacementVector[i] = G4ThreeVector(0,0,0);
|
||||
}
|
||||
else if(pProduct->GetDefinition() == G4Hydrogen::Definition()){
|
||||
theProductDisplacementVector[i] = G4ThreeVector(0, 0, 0);
|
||||
} else if (pProduct->GetDefinition() == G4Hydrogen::Definition()) {
|
||||
// H
|
||||
G4double HRMSDisplacement = 1.6 * nanometer;
|
||||
constexpr G4double HRMSDisplacement = 1.6 * nanometer;
|
||||
|
||||
auto HDisplacement =
|
||||
radialDistributionOfProducts(HRMSDisplacement);
|
||||
radialDistributionOfProducts(HRMSDisplacement);
|
||||
|
||||
if(NbOfH==0) HDisplacement = 0.5*HDisplacement;
|
||||
else HDisplacement = -0.5*HDisplacement;
|
||||
if (NbOfH == 0) {
|
||||
HDisplacement = 0.5 * HDisplacement;
|
||||
} else {
|
||||
HDisplacement = -0.5 * HDisplacement;
|
||||
}
|
||||
theProductDisplacementVector[i] = HDisplacement;
|
||||
|
||||
++NbOfH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AutoIonisation:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "AutoIonisation" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
case AutoIonisation:
|
||||
{
|
||||
if (fVerbose != 0)
|
||||
{
|
||||
G4cout << "AutoIonisation" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
G4double RdmValue = G4UniformRand();
|
||||
G4double RdmValue = G4UniformRand();
|
||||
|
||||
if (RdmValue < 0.5)
|
||||
{
|
||||
// H3O
|
||||
theRMSmap[G4H3O::Definition()] = 0. * nanometer;
|
||||
// OH
|
||||
theRMSmap[G4OH::Definition()] = 0.8 * nanometer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// H3O
|
||||
theRMSmap[G4H3O::Definition()] = 0.8 * nanometer;
|
||||
// OH
|
||||
theRMSmap[G4OH::Definition()] = 0. * nanometer;
|
||||
}
|
||||
|
||||
for (G4int i = 0; i < nbProducts; i++)
|
||||
{
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
auto theRMSDisplacement = theRMSmap[pProduct->GetDefinition()];
|
||||
|
||||
if (theRMSDisplacement == 0)
|
||||
{
|
||||
theProductDisplacementVector[i] = G4ThreeVector();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto RandDirection =
|
||||
radialDistributionOfProducts(theRMSDisplacement);
|
||||
theProductDisplacementVector[i] = RandDirection;
|
||||
}
|
||||
if (pProduct->GetDefinition() == G4Electron_aq::Definition())
|
||||
{
|
||||
theProductDisplacementVector[i] = radialDistributionOfElectron();
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (RdmValue < 0.5) {
|
||||
// H3O
|
||||
theRMSmap[G4H3O::Definition()] = 0.0 * nanometer;
|
||||
// OH
|
||||
theRMSmap[G4OH::Definition()] = 0.8 * nanometer;
|
||||
} else {
|
||||
// H3O
|
||||
theRMSmap[G4H3O::Definition()] = 0.8 * nanometer;
|
||||
// OH
|
||||
theRMSmap[G4OH::Definition()] = 0.0 * nanometer;
|
||||
}
|
||||
case DissociativeAttachment:
|
||||
{
|
||||
if (fVerbose != 0)
|
||||
{
|
||||
G4cout << "DissociativeAttachment" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
G4double theRMSDisplacement = 0.8 * nanometer;
|
||||
|
||||
for (G4int i = 0; i < nbProducts; i++) {
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
auto theRMSDisplacement = theRMSmap[pProduct->GetDefinition()];
|
||||
|
||||
if (theRMSDisplacement == 0) {
|
||||
theProductDisplacementVector[i] = G4ThreeVector();
|
||||
} else {
|
||||
auto RandDirection =
|
||||
radialDistributionOfProducts(theRMSDisplacement);
|
||||
|
||||
G4int NbOfOH = 0;
|
||||
for (G4int i = 0; i < nbProducts; ++i)
|
||||
{
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
if (pProduct->GetDefinition() == G4H2::Definition())
|
||||
{
|
||||
// In the paper of Kreipl (2009)
|
||||
// theProductDisplacementVector[i] = -2. / 18. * RandDirection;
|
||||
|
||||
// Based on momentum conservation
|
||||
theProductDisplacementVector[i] = -16. / 18. * RandDirection;
|
||||
}
|
||||
else if (pProduct->GetDefinition() == G4OH::Definition())
|
||||
{
|
||||
// In the paper of Kreipl (2009)
|
||||
// G4ThreeVector OxygenDisplacement = +16. / 18. * RandDirection;
|
||||
|
||||
// Based on momentum conservation
|
||||
G4ThreeVector OxygenDisplacement = +2. / 18. * RandDirection;
|
||||
G4double OHRMSDisplacement = 1.1 * nanometer;
|
||||
|
||||
auto OHDisplacement =
|
||||
radialDistributionOfProducts(OHRMSDisplacement);
|
||||
|
||||
if (NbOfOH == 0)
|
||||
{
|
||||
OHDisplacement = 0.5 * OHDisplacement;
|
||||
}
|
||||
else
|
||||
{
|
||||
OHDisplacement = -0.5 * OHDisplacement;
|
||||
}
|
||||
theProductDisplacementVector[i] = OHDisplacement +
|
||||
OxygenDisplacement;
|
||||
++NbOfOH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
radialDistributionOfProducts(theRMSDisplacement);
|
||||
theProductDisplacementVector[i] = RandDirection;
|
||||
}
|
||||
if (pProduct->GetDefinition() == G4Electron_aq::Definition()) {
|
||||
theProductDisplacementVector[i] = radialDistributionOfElectron();
|
||||
}
|
||||
}
|
||||
}
|
||||
return theProductDisplacementVector;
|
||||
break;
|
||||
}
|
||||
case DissociativeAttachment:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "DissociativeAttachment" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
constexpr G4double theRMSDisplacement = 0.8 * nanometer;
|
||||
auto RandDirection = radialDistributionOfProducts(theRMSDisplacement);
|
||||
|
||||
G4int NbOfOH = 0;
|
||||
for (G4int i = 0; i < nbProducts; ++i) {
|
||||
auto pProduct = pDecayChannel->GetProduct(i);
|
||||
if (pProduct->GetDefinition() == G4H2::Definition()) {
|
||||
// In the paper of Kreipl (2009)
|
||||
// theProductDisplacementVector[i] = -2.0 / 18.0 * RandDirection;
|
||||
|
||||
// Based on momentum conservation
|
||||
theProductDisplacementVector[i] = -16.0 / 18.0 * RandDirection;
|
||||
} else if (pProduct->GetDefinition() == G4OH::Definition()) {
|
||||
// In the paper of Kreipl (2009)
|
||||
// G4ThreeVector OxygenDisplacement = +16.0 / 18.0 * RandDirection;
|
||||
|
||||
// Based on momentum conservation
|
||||
G4ThreeVector OxygenDisplacement = +2.0 / 18.0 * RandDirection;
|
||||
constexpr G4double OHRMSDisplacement = 1.1 * nanometer;
|
||||
|
||||
auto OHDisplacement =
|
||||
radialDistributionOfProducts(OHRMSDisplacement);
|
||||
|
||||
if (NbOfOH == 0) {
|
||||
OHDisplacement = 0.5 * OHDisplacement;
|
||||
} else {
|
||||
OHDisplacement = -0.5 * OHDisplacement;
|
||||
}
|
||||
theProductDisplacementVector[i] = OHDisplacement +
|
||||
OxygenDisplacement;
|
||||
++NbOfOH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DoubleIonisation_DissociationDecay1:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "DoubleIonisation_DissociationDecay1" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
// Ref.) B. Gervais, et al., DOI: 10.1016/j.radphyschem.2005.09.01
|
||||
// Decay Channel #1: H2O^2+ -> 2H+ + O(3P) -> 2H3O+ + O(3P)
|
||||
|
||||
theRMSmap[G4H3O::Definition()] = 1.2 * nanometer;
|
||||
theRMSmap[G4Oxygen::Definition()] = 0.0 * nanometer;
|
||||
|
||||
for (G4int i = 0, num_H3O = 0; i < nbProducts; i++) {
|
||||
|
||||
const auto prod_def = pDecayChannel->GetProduct(i)->GetDefinition();
|
||||
|
||||
if (prod_def == G4H3O::Definition()) {
|
||||
num_H3O++;
|
||||
if (num_H3O == 2) {
|
||||
constexpr G4double H3Op_rms = 0.3 * nanometer;
|
||||
theRMSmap[G4H3O::Definition()] = H3Op_rms;
|
||||
}
|
||||
}
|
||||
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(theRMSmap[prod_def]);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case DoubleIonisation_DissociationDecay2:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "DoubleIonisation_DissociationDecay2" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
// Ref.) B. Gervais, et al., DOI: 10.1016/j.radphyschem.2005.09.01
|
||||
// Decay Channel #2: H2O^2+ -> H+ + H* + O+ -> 2H3O+ + H* + *OH + O(3P)
|
||||
|
||||
theRMSmap[G4H3O::Definition()] = 1.2 * nanometer;
|
||||
theRMSmap[G4Oxygen::Definition()] = 0.0 * nanometer;
|
||||
theRMSmap[G4Hydrogen::Definition()] = 0.8 * nanometer;
|
||||
theRMSmap[G4OH::Definition()] = 0.3 * nanometer;
|
||||
|
||||
const auto OH_disp = radialDistributionOfProducts(
|
||||
theRMSmap[G4OH::Definition()]);
|
||||
|
||||
for (G4int i = 0, num_H3O = 0; i < nbProducts; i++) {
|
||||
|
||||
const auto prod_def = pDecayChannel->GetProduct(i)->GetDefinition();
|
||||
|
||||
if (prod_def == G4H3O::Definition()) {
|
||||
num_H3O++;
|
||||
if (num_H3O == 2) {
|
||||
constexpr G4double OH_rms = 0.3 * nanometer;
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(OH_rms);
|
||||
theProductDisplacementVector[i] += OH_disp;
|
||||
continue;
|
||||
}
|
||||
} else if (prod_def == G4OH::Definition()) {
|
||||
theProductDisplacementVector[i] = OH_disp;
|
||||
continue;
|
||||
}
|
||||
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(theRMSmap[prod_def]);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case DoubleIonisation_DissociationDecay3:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "DoubleIonisation_DissociationDecay3" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
// Ref.) B. Gervais, et al., DOI: 10.1016/j.radphyschem.2005.09.01
|
||||
// Decay Channel #3: H2O^2+ -> H+ + OH+ -> 2H3O+ + O(3P)
|
||||
|
||||
theRMSmap[G4H3O::Definition()] = 1.2 * nanometer;
|
||||
theRMSmap[G4Oxygen::Definition()] = 0.0 * nanometer;
|
||||
|
||||
for (G4int i = 0; i < nbProducts; i++) {
|
||||
|
||||
const auto prod_def = pDecayChannel->GetProduct(i)->GetDefinition();
|
||||
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(theRMSmap[prod_def]);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TripleIonisation_DissociationDecay:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "TripleIonisation_DissociationDecay" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
// Ref.) B. Gervais, et al., DOI: 10.1016/j.radphyschem.2005.09.01
|
||||
// Decay Channel: H2O^3+ -> 3H3O+ + *OH + O(3P)
|
||||
//
|
||||
// ** Detaied decay chain **
|
||||
// H2O^3+ -> O+ + H3O+ + H3O+
|
||||
// |
|
||||
// --> H2O+ + O(3P)
|
||||
// |
|
||||
// --> *OH + H3O+
|
||||
|
||||
theRMSmap[G4H3O::Definition()] = 1.2 * nanometer;
|
||||
theRMSmap[G4Oxygen::Definition()] = 0.0 * nanometer;
|
||||
theRMSmap[G4OH::Definition()] = 0.3 * nanometer;
|
||||
|
||||
const auto OH_disp = radialDistributionOfProducts(
|
||||
theRMSmap[G4OH::Definition()]);
|
||||
|
||||
for (G4int i = 0, num_H3O = 0; i < nbProducts; i++) {
|
||||
|
||||
const auto prod_def = pDecayChannel->GetProduct(i)->GetDefinition();
|
||||
|
||||
if (prod_def == G4H3O::Definition()) {
|
||||
num_H3O++;
|
||||
if (num_H3O == 3) {
|
||||
constexpr G4double H3Op_rms = 0.3 * nanometer;
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(H3Op_rms);
|
||||
theProductDisplacementVector[i] += OH_disp;
|
||||
continue;
|
||||
}
|
||||
} else if (prod_def == G4OH::Definition()) {
|
||||
theProductDisplacementVector[i] = OH_disp;
|
||||
continue;
|
||||
}
|
||||
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(theRMSmap[prod_def]);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case QuadrupleIonisation_DissociationDecay:
|
||||
{
|
||||
if (fVerbose != 0) {
|
||||
G4cout << "QuadrupleIonisation_DissociationDecay" << G4endl;
|
||||
G4cout << "Channel's name: " << pDecayChannel->GetName() << G4endl;
|
||||
}
|
||||
|
||||
// Ref.) B. Gervais, et al., DOI: 10.1016/j.radphyschem.2005.09.01
|
||||
// Decay Channel: H2O^4+ -> 4H3O+ + 2*OH + O(3P)
|
||||
//
|
||||
// ** Detaied decay chain **
|
||||
// H2O^4+ -> O^2+ + H3O+ + H3O+
|
||||
// |
|
||||
// --> H2O+ + H2O+ + O(3P)
|
||||
// | |
|
||||
// | --> *OH + H3O+
|
||||
// |
|
||||
// --> *OH + H3O+
|
||||
|
||||
theRMSmap[G4H3O::Definition()] = 1.2 * nanometer;
|
||||
theRMSmap[G4Oxygen::Definition()] = 0.0 * nanometer;
|
||||
theRMSmap[G4OH::Definition()] = 0.3 * nanometer;
|
||||
|
||||
const auto OH_disp1 = radialDistributionOfProducts(
|
||||
theRMSmap[G4OH::Definition()]);
|
||||
const auto OH_disp2 = radialDistributionOfProducts(
|
||||
theRMSmap[G4OH::Definition()]);
|
||||
|
||||
for (G4int i = 0, num_H3O = 0, num_OH = 0; i < nbProducts; i++) {
|
||||
|
||||
const auto prod_def = pDecayChannel->GetProduct(i)->GetDefinition();
|
||||
|
||||
if (prod_def == G4H3O::Definition()) {
|
||||
|
||||
num_H3O++;
|
||||
constexpr G4double H3Op_rms = 0.3 * nanometer;
|
||||
|
||||
if (num_H3O == 3) {
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(H3Op_rms);
|
||||
theProductDisplacementVector[i] += OH_disp1;
|
||||
continue;
|
||||
} else if (num_H3O == 4) {
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(H3Op_rms);
|
||||
theProductDisplacementVector[i] += OH_disp2;
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (prod_def == G4OH::Definition()) {
|
||||
|
||||
num_OH++;
|
||||
if (num_OH == 1) {
|
||||
theProductDisplacementVector[i] = OH_disp1;
|
||||
} else {
|
||||
theProductDisplacementVector[i] = OH_disp2;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
theProductDisplacementVector[i]
|
||||
= radialDistributionOfProducts(theRMSmap[prod_def]);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return theProductDisplacementVector;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -478,12 +682,12 @@ G4ThreeVector
|
||||
G4DNAWaterDissociationDisplacer::
|
||||
radialDistributionOfProducts(G4double Rrms) const
|
||||
{
|
||||
static const double inverse_sqrt_3 = 1. / sqrt(3.);
|
||||
double sigma = Rrms * inverse_sqrt_3;
|
||||
double x = G4RandGauss::shoot(0., sigma);
|
||||
double y = G4RandGauss::shoot(0., sigma);
|
||||
double z = G4RandGauss::shoot(0., sigma);
|
||||
return G4ThreeVector(x, y, z);
|
||||
static const double inverse_sqrt_3 = 1.0 / sqrt(3.0);
|
||||
double sigma = Rrms * inverse_sqrt_3;
|
||||
double x = G4RandGauss::shoot(0.0, sigma);
|
||||
double y = G4RandGauss::shoot(0.0, sigma);
|
||||
double z = G4RandGauss::shoot(0.0, sigma);
|
||||
return G4ThreeVector(x, y, z);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -500,13 +704,18 @@ G4DNAWaterDissociationDisplacer::radialDistributionOfElectron() const
|
||||
+ fElectronThermalization[bin_p1] * rand_value) *
|
||||
G4RandomDirection();*/
|
||||
|
||||
G4ThreeVector pdf = G4ThreeVector(0,0,0);
|
||||
G4ThreeVector pdf = G4ThreeVector(0, 0, 0);
|
||||
|
||||
if(dnaSubType == fRitchie1994eSolvation) DNA::Penetration::Ritchie1994::GetPenetration(ke,pdf);
|
||||
else if(dnaSubType == fTerrisol1990eSolvation) DNA::Penetration::Terrisol1990::GetPenetration(ke,pdf);
|
||||
else if(dnaSubType == fMeesungnoensolid2002eSolvation) DNA::Penetration::Meesungnoen2002_amorphous::GetPenetration(ke,pdf);
|
||||
else if(dnaSubType == fKreipl2009eSolvation) DNA::Penetration::Kreipl2009::GetPenetration(ke,pdf);
|
||||
else DNA::Penetration::Meesungnoen2002::GetPenetration(ke,pdf);
|
||||
|
||||
return pdf;
|
||||
if (dnaSubType == fRitchie1994eSolvation) {
|
||||
DNA::Penetration::Ritchie1994::GetPenetration(ke, pdf);
|
||||
} else if (dnaSubType == fTerrisol1990eSolvation) {
|
||||
DNA::Penetration::Terrisol1990::GetPenetration(ke, pdf);
|
||||
} else if (dnaSubType == fMeesungnoensolid2002eSolvation) {
|
||||
DNA::Penetration::Meesungnoen2002_amorphous::GetPenetration(ke, pdf);
|
||||
} else if (dnaSubType == fKreipl2009eSolvation) {
|
||||
DNA::Penetration::Kreipl2009::GetPenetration(ke, pdf);
|
||||
} else {
|
||||
DNA::Penetration::Meesungnoen2002::GetPenetration(ke, pdf);
|
||||
}
|
||||
return pdf;
|
||||
}
|
||||
|
||||
@@ -51,13 +51,6 @@ class G4DNAMolecularReactionTable;
|
||||
class G4VITStepModel;
|
||||
class G4MoleculeDefinition;
|
||||
|
||||
enum TimeStepModel
|
||||
{
|
||||
fSBS,
|
||||
fIRT,
|
||||
fIRT_syn
|
||||
};
|
||||
|
||||
class G4VUserChemistryList
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -6,9 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2023-12-11 V. Ivanchenko (emlowen-V11-01-12)
|
||||
## 2023-12-11 V. Ivanchenko (emlowen-V11-02-00)
|
||||
- G4MicroElecInelasticModel_new - fixed Coverity report on memory leak at exit,
|
||||
minimal code clean-up.
|
||||
likely partially; minimal code clean-up.
|
||||
- G4MicroElecLOPhononModel - minor clean-up
|
||||
|
||||
# 2023-11-06 Ben Morgan (emlowen-V11-01-11)
|
||||
|
||||
@@ -6,14 +6,46 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-06-06 V.Ivanchenko (emstand-V11-01-26)
|
||||
## 2024-06-06 I.Semeniouk & D.Bernard (emstand-V11-02-09)
|
||||
- new G4OrePowellAtRestModel - Orel & Powell orto positronium decay model AtRest
|
||||
- new G4SimpleoPsAtRestModel - simples orto para positronium chooser
|
||||
|
||||
## 2024-06-06 V.Ivanchenko (emstand-V11-02-08)
|
||||
- G4BetheHeitler5DModel - fixed computation of sinTheta
|
||||
|
||||
## 2024-05-28 V.Ivanchenko
|
||||
## 2024-06-04 Gabriele Cosmo (emstand-V11-02-07)
|
||||
- Fixed compilation warning on macOS/XCode for implicit type conversion
|
||||
on G4eplusAnnihilation.
|
||||
|
||||
## 2024-05-28 V.Ivanchenko (emstand-V11-02-06)
|
||||
- G4BetheHeitler5DModel - added checks on arguments of G4Exp in SampleSecondaries(..)
|
||||
method to avoid FPE problems in the case of -O3 optimisation
|
||||
- G4eplusAnnihilation - use more const class members, changed model ID definition
|
||||
for produced tracks
|
||||
|
||||
## 2024-01-23 V.Ivanchenko (emstand-V11-01-25)
|
||||
## 2024-05-23 V.Ivanchenko (emstand-V11-02-05)
|
||||
- G4UrbanMscModel - L.Urban optimized DistanceToBoundary step limitation
|
||||
algorithm currently used only in Opt3 EM physics
|
||||
|
||||
## 2024-05-14 V.Ivanchenko (emstand-V11-02-04)
|
||||
- G4SimplePositronAtRestModel, G4AllisonAtRestModel - new classes to sample
|
||||
positron annihilation
|
||||
- G4eeToTwoGammaModel - cosmetic change
|
||||
- G4eplusTo2GammaOKVIModel - removed sampling at rest
|
||||
- G4eplusAnnihilation - added selection of AtRest model, implement ApplyCuts
|
||||
for AtRest, implement choice of positron annihilation model at rest
|
||||
|
||||
## 2024-02-20 V.Ivanchenko (emstand-V11-02-03)
|
||||
- G4eeToTwoGammaModel - fixed precision lost in sampling of final state
|
||||
for the very high energy (ATLAS report)
|
||||
|
||||
## 2024-02-06 V.Ivanchenko (emstand-V11-02-02)
|
||||
- G4IonFluctuations - disable previous MR - return to 11.2 version
|
||||
|
||||
## 2024-01-27 V.Ivanchenko (emstand-V11-02-01)
|
||||
- G4IonFluctuations - fixed problem report #2580 - ion fluctuations at high energy
|
||||
|
||||
## 2024-01-23 V.Ivanchenko (emstand-V11-02-00)
|
||||
- G4IonICRU73Data - fixed bug #2586 for the case if target material has
|
||||
an element with Z>92, improve debug printouts. In the Lindhard-Sorensen
|
||||
model to compute dEdx the first try is to take it from ICRU73 or ICRU90
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
// File name: G4AllisonPositronAtRestModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 14 May 2024
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Allison AtRest positron 2-gamma annihilation model
|
||||
// Electron of media is assumed to have the Maxwell–Boltzmann
|
||||
// distribution defined by the temperature of the media.
|
||||
// Energy of mean ionisation should not be zero - some amount of free
|
||||
// electrons should be in the media.
|
||||
// Polarisation of gamma according to M.H.L.Pryce and J.C.Ward,
|
||||
// Nature 4065 (1947) 435.
|
||||
// Snyder et al, Physical Review 73 (1948) p.440.
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef G4AllisonPositronAtRestModel_h
|
||||
#define G4AllisonPositronAtRestModel_h 1
|
||||
|
||||
#include "G4VPositronAtRestModel.hh"
|
||||
|
||||
class G4AllisonPositronAtRestModel : public G4VPositronAtRestModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
G4AllisonPositronAtRestModel();
|
||||
|
||||
~G4AllisonPositronAtRestModel() override = default;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double&, const G4Material*) const override;
|
||||
|
||||
void PrintGeneratorInformation() const override;
|
||||
|
||||
G4AllisonPositronAtRestModel& operator=
|
||||
(const G4AllisonPositronAtRestModel& right) = delete;
|
||||
G4AllisonPositronAtRestModel(const G4AllisonPositronAtRestModel&) = delete;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
// File name: G4OrePowellAtRestModel
|
||||
//
|
||||
// Author: I.Semeniouk & D.Bernard
|
||||
//
|
||||
// Creation date: 4 Juin 2024
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Simple AtRest positron 3-gamma annihilation model.
|
||||
// Electron of media is assumed to have zero kinetic energy.
|
||||
// Ortho - Positronium three-photon annihilation by Ore and
|
||||
// Powell, Phys. Rev. 75 (1949).
|
||||
// Polarisation set randomly.
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef G4OrePowellAtRestModel_h
|
||||
#define G4OrePowellAtRestModel_h 1
|
||||
|
||||
#include "G4VPositronAtRestModel.hh"
|
||||
|
||||
class G4OrePowellAtRestModel : public G4VPositronAtRestModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
G4OrePowellAtRestModel();
|
||||
|
||||
~G4OrePowellAtRestModel() override = default;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double&, const G4Material*) const override;
|
||||
|
||||
void PrintGeneratorInformation() const override;
|
||||
|
||||
G4OrePowellAtRestModel& operator=
|
||||
(const G4OrePowellAtRestModel& right) = delete;
|
||||
G4OrePowellAtRestModel(const G4OrePowellAtRestModel&) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
// File name: G4SimplePositronAtRestModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 14 May 2024
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Simple AtRest positron 2-gamma annihilation model.
|
||||
// Electron of media is assumed to have zero kinetic energy.
|
||||
// Polarisation of gamma according to M.H.L.Pryce and J.C.Ward,
|
||||
// Nature 4065 (1947) 435.
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef G4SimplePositronAtRestModel_h
|
||||
#define G4SimplePositronAtRestModel_h 1
|
||||
|
||||
#include "G4VPositronAtRestModel.hh"
|
||||
|
||||
class G4SimplePositronAtRestModel : public G4VPositronAtRestModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
G4SimplePositronAtRestModel();
|
||||
|
||||
~G4SimplePositronAtRestModel() override = default;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double&, const G4Material*) const override;
|
||||
|
||||
void PrintGeneratorInformation() const override;
|
||||
|
||||
G4SimplePositronAtRestModel& operator=
|
||||
(const G4SimplePositronAtRestModel& right) = delete;
|
||||
G4SimplePositronAtRestModel(const G4SimplePositronAtRestModel&) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
// File name: G4SimplePsAtRestModel
|
||||
//
|
||||
// Author: I.Semeniouk & D.Bernard
|
||||
//
|
||||
// Creation date: 4 Juin 2024
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Simple switcher between positron 2-gamma annihilation at rest model and
|
||||
// positron 2-gamma annihilation at rest model.
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef G4SimplePsAtRestModel_h
|
||||
#define G4SimplePsAtRestModel_h 1
|
||||
|
||||
#include "G4VPositronAtRestModel.hh"
|
||||
|
||||
class G4SimplePositronAtRestModel;
|
||||
class G4OrePowellAtRestModel;
|
||||
|
||||
class G4SimplePsAtRestModel : public G4VPositronAtRestModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
G4SimplePsAtRestModel();
|
||||
|
||||
~G4SimplePsAtRestModel() override;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double&, const G4Material*) const override;
|
||||
|
||||
void PrintGeneratorInformation() const override;
|
||||
|
||||
G4SimplePsAtRestModel& operator=
|
||||
(const G4SimplePsAtRestModel& right) = delete;
|
||||
G4SimplePsAtRestModel(const G4SimplePsAtRestModel&) = delete;
|
||||
|
||||
private:
|
||||
|
||||
G4double f3gFranction;
|
||||
G4SimplePositronAtRestModel *model2g;
|
||||
G4OrePowellAtRestModel *model3g;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -44,8 +44,9 @@
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of e+ annihilation into 2 gamma
|
||||
|
||||
// Implementation of e+ annihilation into 2 gamma on fly
|
||||
// Annihilation at rest is sampled by G4VPositronAtRestModel
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -53,6 +54,7 @@
|
||||
#define G4eeToTwoGammaModel_h 1
|
||||
|
||||
#include "G4VEmModel.hh"
|
||||
#include <vector>
|
||||
|
||||
class G4ParticleChangeForGamma;
|
||||
|
||||
@@ -99,8 +101,6 @@ private:
|
||||
G4double pi_rcl2;
|
||||
const G4ParticleDefinition* theGamma;
|
||||
G4ParticleChangeForGamma* fParticleChange;
|
||||
|
||||
static G4bool fSampleAtomicPDF;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -48,9 +48,12 @@
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// This class manages the process of e+ annihilation into 2 gammas
|
||||
// This class manages the process of e+ annihilation at rest and on fly
|
||||
// It is possible to enable ApplyCuts and Entanglement options via
|
||||
// G4EmParameters class using UI commands or C++ interface.
|
||||
// EM splitting or Russian roulette are allowed is corresponding options
|
||||
// are enabled.
|
||||
//
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -60,6 +63,7 @@
|
||||
#include "G4VEmProcess.hh"
|
||||
|
||||
class G4ParticleDefinition;
|
||||
class G4VPositronAtRestModel;
|
||||
|
||||
class G4eplusAnnihilation : public G4VEmProcess
|
||||
{
|
||||
@@ -95,11 +99,12 @@ protected:
|
||||
void StreamProcessInfo(std::ostream& outFile) const override;
|
||||
|
||||
private:
|
||||
|
||||
G4bool isInitialised = false;
|
||||
const G4ParticleDefinition* theGamma;
|
||||
const G4ParticleDefinition* theElectron;
|
||||
|
||||
G4VPositronAtRestModel* fAtRestModel{nullptr};
|
||||
G4int fEntanglementModelID;
|
||||
G4bool isInitialised{false};
|
||||
G4bool fEntangled{false};
|
||||
G4bool fApplyCuts{false};
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -38,8 +38,18 @@
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of e+ annihilation into 2 gamma
|
||||
|
||||
// Implementation of e+ annihilation into 2 or 3 gamma on fly
|
||||
// Annihilation at rest is sampled by G4VPositronAtRestModel
|
||||
// Implementation of 3-gamma annihilation is performed by
|
||||
// G4eplusTo3GammaOKVIModel. Cross section of both models
|
||||
// depend on cut parameter fDelta, which defines relative low-energy
|
||||
// limit on 3d gamma energy. For computation of the cross section
|
||||
// next to leading order radiative corrections are taken into account,
|
||||
// atomic effects at low-energy are not considered.
|
||||
//
|
||||
// V.N.Baier, V.S. Fadin, V.A. Khose, E.A. Kuraev,
|
||||
// Physics Reports 78 (1981) 293-393.
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -58,8 +68,7 @@ class G4eplusTo2GammaOKVIModel : public G4VEmModel
|
||||
|
||||
public:
|
||||
|
||||
explicit G4eplusTo2GammaOKVIModel(const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& nam = "eplus2ggOKVI");
|
||||
G4eplusTo2GammaOKVIModel();
|
||||
|
||||
~G4eplusTo2GammaOKVIModel() override;
|
||||
|
||||
@@ -73,21 +82,21 @@ public:
|
||||
G4double Z,
|
||||
G4double A = 0.,
|
||||
G4double cutEnergy = 0.,
|
||||
G4double maxEnergy = DBL_MAX) final;
|
||||
G4double maxEnergy = DBL_MAX) override;
|
||||
|
||||
G4double CrossSectionPerVolume(const G4Material*,
|
||||
const G4ParticleDefinition*,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy = 0.0,
|
||||
G4double maxEnergy = DBL_MAX) final;
|
||||
G4double maxEnergy = DBL_MAX) override;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double tmin = 0.0,
|
||||
G4double maxEnergy = DBL_MAX) final;
|
||||
G4double maxEnergy = DBL_MAX) override;
|
||||
|
||||
inline void SetDelta(G4double val) { if(val > 0.0) { fDelta = val; } };
|
||||
void SetDelta(G4double val) { if(val > 0.0) { fDeltaMin = val; } };
|
||||
|
||||
// hide assignment operator
|
||||
G4eplusTo2GammaOKVIModel & operator=
|
||||
@@ -97,16 +106,14 @@ public:
|
||||
private:
|
||||
|
||||
const G4ParticleDefinition* theGamma;
|
||||
|
||||
G4ParticleChangeForGamma* fParticleChange;
|
||||
G4eplusTo3GammaOKVIModel* f3GModel;
|
||||
const G4DataVector* fCuts;
|
||||
|
||||
G4double fDelta;
|
||||
G4double fGammaTh;
|
||||
|
||||
G4double fDeltaMin; // fixed minimal relative limit
|
||||
G4double fDelta; // running limit - function of energy
|
||||
G4double fGammaTh; // 3-gamma annihilation low-energy limit
|
||||
|
||||
static G4PhysicsVector* fCrossSection;
|
||||
static G4PhysicsVector* fCrossSection3G;
|
||||
static G4PhysicsVector* f3GProbability;
|
||||
};
|
||||
|
||||
|
||||
@@ -38,8 +38,11 @@
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of e+ annihilation into 3 gamma
|
||||
|
||||
// Implementation of e+ annihilation into 3 gamma on fly
|
||||
//
|
||||
// V.N.Baier, V.S. Fadin, V.A. Khose, E.A. Kuraev,
|
||||
// Physics Reports 78 (1981) 293-393.
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -60,7 +63,7 @@ public:
|
||||
|
||||
~G4eplusTo3GammaOKVIModel() override;
|
||||
|
||||
void Initialise(const G4ParticleDefinition*, const G4DataVector&) final;
|
||||
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
|
||||
|
||||
G4double ComputeCrossSectionPerElectron(G4double kinEnergy);
|
||||
|
||||
@@ -100,8 +103,7 @@ public:
|
||||
private:
|
||||
|
||||
G4double fDelta;
|
||||
const G4ParticleDefinition* theGamma;
|
||||
G4ParticleChangeForGamma* fParticleChange;
|
||||
const G4ParticleDefinition* theGamma;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
geant4_add_module(G4emstandard
|
||||
PUBLIC_HEADERS
|
||||
G4ASTARStopping.hh
|
||||
G4AllisonPositronAtRestModel.hh
|
||||
G4AtimaEnergyLossModel.hh
|
||||
G4AtimaFluctuations.hh
|
||||
G4BetheBlochIonGasModel.hh
|
||||
@@ -55,6 +56,9 @@ geant4_add_module(G4emstandard
|
||||
G4SauterGavrilaAngularDistribution.hh
|
||||
G4ScreeningMottCrossSection.hh
|
||||
G4SeltzerBergerModel.hh
|
||||
G4SimplePositronAtRestModel.hh
|
||||
G4SimplePsAtRestModel.hh
|
||||
G4OrePowellAtRestModel.hh
|
||||
G4UniversalFluctuation.hh
|
||||
G4UrbanFluctuation.hh
|
||||
G4UrbanMscModel.hh
|
||||
@@ -83,6 +87,7 @@ geant4_add_module(G4emstandard
|
||||
G4ionIonisation.hh
|
||||
SOURCES
|
||||
G4ASTARStopping.cc
|
||||
G4AllisonPositronAtRestModel.cc
|
||||
G4AtimaEnergyLossModel.cc
|
||||
G4AtimaFluctuations.cc
|
||||
G4BetheBlochIonGasModel.cc
|
||||
@@ -133,6 +138,9 @@ geant4_add_module(G4emstandard
|
||||
G4SauterGavrilaAngularDistribution.cc
|
||||
G4ScreeningMottCrossSection.cc
|
||||
G4SeltzerBergerModel.cc
|
||||
G4SimplePositronAtRestModel.cc
|
||||
G4SimplePsAtRestModel.cc
|
||||
G4OrePowellAtRestModel.cc
|
||||
G4UniversalFluctuation.cc
|
||||
G4UrbanFluctuation.cc
|
||||
G4UrbanMscModel.cc
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4AllisonPositronAtRestModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 14 May 2024
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "G4AllisonPositronAtRestModel.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4AllisonPositronAtRestModel::G4AllisonPositronAtRestModel()
|
||||
: G4VPositronAtRestModel("Allison")
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4AllisonPositronAtRestModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double&, const G4Material* material) const
|
||||
{
|
||||
const G4double eGamma = CLHEP::electron_mass_c2;
|
||||
|
||||
// In rest frame of positronium gammas are back to back
|
||||
const G4ThreeVector& dir1 = G4RandomDirection();
|
||||
const G4ThreeVector& dir2 = -dir1;
|
||||
auto aGamma1 = new G4DynamicParticle(G4Gamma::Gamma(),dir1,eGamma);
|
||||
auto aGamma2 = new G4DynamicParticle(G4Gamma::Gamma(),dir2,eGamma);
|
||||
|
||||
// In rest frame the gammas are polarised perpendicular to each other - see
|
||||
// Pryce and Ward, Nature No 4065 (1947) p.435.
|
||||
// Snyder et al, Physical Review 73 (1948) p.440.
|
||||
G4ThreeVector pol1 = (G4RandomDirection().cross(dir1)).unit();
|
||||
G4ThreeVector pol2 = (pol1.cross(dir2)).unit();
|
||||
|
||||
// A positron in matter slows down and combines with an atomic electron to
|
||||
// make a neutral atom called positronium, about half the size of a normal
|
||||
// atom. I expect that when the energy of the positron is small enough,
|
||||
// less than the binding energy of positronium (6.8 eV), it is
|
||||
// energetically favourable for an electron from the outer orbitals of a
|
||||
// nearby atom or molecule to transfer and bind to the positron, as in an
|
||||
// ionic bond, leaving behind a mildly ionised nearby atom/molecule. I
|
||||
// would expect the positronium to come away with a kinetic energy of a
|
||||
// few eV on average. In its para (spin 0) state it annihilates into two
|
||||
// photons, which in the rest frame of the positronium are collinear
|
||||
// (back-to-back) due to momentum conservation. Because of the motion of the
|
||||
// positronium, photons will be not quite back-to-back in the laboratory.
|
||||
|
||||
// The positroniuim acquires an energy of order its binding energy and
|
||||
// doesn't have time to thermalise. Nevertheless, here we approximate its
|
||||
// energy distribution by a Maxwell-Boltzman with mean energy <KE>. In terms
|
||||
// of a more familiar concept of temperature, and the law of equipartition
|
||||
// of energy of translational motion, <KE>=3kT/2. Each component of velocity
|
||||
// has a distribution exp(-mv^2/2kT), which is a Gaussian of mean zero
|
||||
// and variance kT/m=2<KE>/3m, where m is the positronium mass.
|
||||
|
||||
const G4double meanEnergyPerIonPair = material->GetIonisation()->GetMeanEnergyPerIonPair();
|
||||
const G4double& meanKE = meanEnergyPerIonPair; // Just an alias
|
||||
|
||||
if (meanKE > 0.) { // Positronium has motion
|
||||
// Mass of positronium
|
||||
const G4double mass = 2.*CLHEP::electron_mass_c2;
|
||||
// Mean <KE>=3kT/2, as described above
|
||||
// const G4double T = 2.*meanKE/(3.*k_Boltzmann);
|
||||
// Component velocities: Gaussian, variance kT/m=2<KE>/3m.
|
||||
const G4double sigmav = std::sqrt(2.*meanKE/(3.*mass));
|
||||
// This is in units where c=1
|
||||
const G4double vx = G4RandGauss::shoot(0.,sigmav);
|
||||
const G4double vy = G4RandGauss::shoot(0.,sigmav);
|
||||
const G4double vz = G4RandGauss::shoot(0.,sigmav);
|
||||
const G4ThreeVector v(vx,vy,vz); // In unit where c=1
|
||||
const G4ThreeVector& beta = v; // so beta=v/c=v
|
||||
aGamma1->Set4Momentum(aGamma1->Get4Momentum().boost(beta));
|
||||
aGamma2->Set4Momentum(aGamma2->Get4Momentum().boost(beta));
|
||||
|
||||
// Rotate polarisation vectors
|
||||
const G4ThreeVector& newDir1 = aGamma1->GetMomentumDirection();
|
||||
const G4ThreeVector& newDir2 = aGamma2->GetMomentumDirection();
|
||||
const G4ThreeVector& axis1 = dir1.cross(newDir1); // No need to be unit
|
||||
const G4ThreeVector& axis2 = dir2.cross(newDir2); // No need to be unit
|
||||
const G4double& angle1 = std::acos(dir1*newDir1);
|
||||
const G4double& angle2 = std::acos(dir2*newDir2);
|
||||
pol1.rotate(axis1, angle1);
|
||||
pol2.rotate(axis2, angle2);
|
||||
}
|
||||
|
||||
// use constructors optimal for massless particle
|
||||
aGamma1->SetPolarization(pol1);
|
||||
aGamma2->SetPolarization(pol2);
|
||||
|
||||
secParticles.push_back(aGamma1);
|
||||
secParticles.push_back(aGamma2);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4AllisonPositronAtRestModel::PrintGeneratorInformation() const
|
||||
{
|
||||
G4cout << "\n" << G4endl;
|
||||
G4cout << "Allison AtRest positron 2-gamma annihilation model." << G4endl;
|
||||
G4cout << "Takes into account positronium motion in the media." << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -0,0 +1,153 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4OrePowellAtRestModel
|
||||
//
|
||||
// Author: I.Semeniouk & D.Bernard
|
||||
//
|
||||
// Creation date: 04 Juin 2024
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "G4OrePowellAtRestModel.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4OrePowellAtRestModel::G4OrePowellAtRestModel() : G4VPositronAtRestModel("OrePawell") {}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4OrePowellAtRestModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double&, const G4Material*) const
|
||||
{
|
||||
static const G4double PositronMass = CLHEP::electron_mass_c2;
|
||||
const G4double ymax = 8.1;
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
G4double cos12;
|
||||
G4double cos13;
|
||||
G4double r1;
|
||||
G4double r2;
|
||||
G4double r3;
|
||||
G4double theta12;
|
||||
G4double theta13;
|
||||
G4double sin12;
|
||||
G4double sin13;
|
||||
G4double pdf;
|
||||
|
||||
G4double rndmv2[2];
|
||||
G4double rndmv1;
|
||||
|
||||
do {
|
||||
rndmv1 = rndmEngine->flat();
|
||||
|
||||
do {
|
||||
rndmEngine->flatArray(2, rndmv2);
|
||||
// energies of photon1 and photon2 normalized to electron rest mass
|
||||
r1 = rndmv2[0];
|
||||
r2 = rndmv2[1];
|
||||
// energy conservation, with positronium assumed = 2 * electron rest mass
|
||||
r3 = 2.0 - (r1+r2);
|
||||
// cosine of angles between photons, from momentum conservation
|
||||
cos12=(r3*r3 - r1*r1 -r2*r2)/(2*r1*r2);
|
||||
cos13=(r2*r2 - r1*r1 -r3*r3)/(2*r1*r3);
|
||||
// request both cosines < 1.
|
||||
} while ( std::abs(cos12) > 1 || std::abs(cos13) > 1 );
|
||||
|
||||
theta12 = std::acos(cos12);
|
||||
theta13 = - std::acos(cos13);
|
||||
sin12 = std::sin(theta12);
|
||||
sin13 = std::sin(theta13);
|
||||
G4double cos23=cos12*cos13+sin12*sin13;
|
||||
|
||||
pdf = (1 - cos12)*(1 - cos12) + (1 - cos13)*(1 - cos13) + (1 - cos23)*(1 - cos23);
|
||||
} while ( pdf < ymax * rndmv1 );
|
||||
// END of Sampling
|
||||
|
||||
// photon directions in the decay plane, photon 1 along z, x perp to the plane.
|
||||
G4ThreeVector PhotonMomentum1(0., 0., 1.);
|
||||
G4ThreeVector PhotonMomentum2(0.,sin12,cos12);
|
||||
G4ThreeVector PhotonMomentum3(0.,sin13,cos13);
|
||||
|
||||
// First Gamma direction
|
||||
G4ThreeVector dir1 = G4RandomDirection();
|
||||
|
||||
PhotonMomentum1.rotateUz(dir1);
|
||||
PhotonMomentum2.rotateUz(dir1);
|
||||
PhotonMomentum3.rotateUz(dir1);
|
||||
|
||||
auto aGamma1 = new G4DynamicParticle(G4Gamma::Gamma(), PhotonMomentum1,
|
||||
r1 * PositronMass);
|
||||
|
||||
//Random polarization
|
||||
G4double phi1 = CLHEP::twopi * G4UniformRand();
|
||||
G4ThreeVector pol1(std::cos(phi1),std::sin(phi1),0.0);
|
||||
pol1.rotateUz(PhotonMomentum1);
|
||||
aGamma1->SetPolarization(pol1);
|
||||
secParticles.push_back(aGamma1);
|
||||
|
||||
auto aGamma2 = new G4DynamicParticle(G4Gamma::Gamma(), PhotonMomentum2,
|
||||
r2 * PositronMass);
|
||||
|
||||
G4double phi2 = CLHEP::twopi * G4UniformRand();
|
||||
G4ThreeVector pol2(std::cos(phi2),std::sin(phi2),0.0);
|
||||
pol2.rotateUz(PhotonMomentum2);
|
||||
aGamma2->SetPolarization(pol2);
|
||||
secParticles.push_back(aGamma2);
|
||||
|
||||
auto aGamma3 = new G4DynamicParticle(G4Gamma::Gamma(), PhotonMomentum3,
|
||||
r3 * PositronMass);
|
||||
|
||||
G4double phi3 = CLHEP::twopi * G4UniformRand();
|
||||
G4ThreeVector pol3(std::cos(phi3),std::sin(phi3),0.0);
|
||||
pol3.rotateUz(PhotonMomentum3);
|
||||
aGamma3->SetPolarization(pol3);
|
||||
secParticles.push_back(aGamma3);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4OrePowellAtRestModel::PrintGeneratorInformation() const
|
||||
{
|
||||
G4cout << "Orel Powell AtRest positron 3-gamma annihilation model" << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4SimplePositronAtRestModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 14 May 2024
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "G4SimplePositronAtRestModel.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4SimplePositronAtRestModel::G4SimplePositronAtRestModel()
|
||||
: G4VPositronAtRestModel("Simple")
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4SimplePositronAtRestModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double&, const G4Material*) const
|
||||
{
|
||||
G4ThreeVector dir1 = G4RandomDirection();
|
||||
auto aGamma1 = new G4DynamicParticle(G4Gamma::Gamma(), dir1,
|
||||
CLHEP::electron_mass_c2);
|
||||
G4double phi = CLHEP::twopi * G4UniformRand();
|
||||
G4double cosphi = std::cos(phi);
|
||||
G4double sinphi = std::sin(phi);
|
||||
G4ThreeVector pol1(cosphi, sinphi, 0.0);
|
||||
pol1.rotateUz(dir1);
|
||||
aGamma1->SetPolarization(pol1);
|
||||
secParticles.push_back(aGamma1);
|
||||
|
||||
G4ThreeVector dir2 = -dir1;
|
||||
auto aGamma2 = new G4DynamicParticle(G4Gamma::Gamma(), dir2,
|
||||
CLHEP::electron_mass_c2);
|
||||
G4ThreeVector pol2(-sinphi, cosphi, 0.0);
|
||||
pol2.rotateUz(dir1);
|
||||
aGamma2->SetPolarization(pol2);
|
||||
secParticles.push_back(aGamma2);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4SimplePositronAtRestModel::PrintGeneratorInformation() const
|
||||
{
|
||||
G4cout << "\n" << G4endl;
|
||||
G4cout << "Simple AtRest positron 2-gamma annihilation model" << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4SimplePsAtRestModel
|
||||
//
|
||||
// Author: I.Semeniouk & D.Bernard
|
||||
//
|
||||
// Creation date: 04 Juin 2024
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "G4SimplePsAtRestModel.hh"
|
||||
#include "G4SimplePositronAtRestModel.hh"
|
||||
#include "G4OrePowellAtRestModel.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4SimplePsAtRestModel::G4SimplePsAtRestModel()
|
||||
: G4VPositronAtRestModel("SimplePs")
|
||||
{
|
||||
f3gFranction = G4EmParameters::Instance()->OrtoPsFraction();
|
||||
model2g = new G4SimplePositronAtRestModel();
|
||||
model3g = new G4OrePowellAtRestModel();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4SimplePsAtRestModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double& localEnergyDeposit, const G4Material* mat) const
|
||||
{
|
||||
// G4cout << "SampleSecondaries model " << GetName() << G4endl;
|
||||
// G4cout << "3 gamma fraction " << f3gFranction << G4endl;
|
||||
if ( G4UniformRand() > f3gFranction ) {
|
||||
model2g->SampleSecondaries(secParticles,localEnergyDeposit,mat);
|
||||
} else {
|
||||
model3g->SampleSecondaries(secParticles,localEnergyDeposit,mat);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4SimplePsAtRestModel::PrintGeneratorInformation() const
|
||||
{
|
||||
G4cout << G4endl;
|
||||
model2g->PrintGeneratorInformation();
|
||||
model3g->PrintGeneratorInformation();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4SimplePsAtRestModel::~G4SimplePsAtRestModel()
|
||||
{
|
||||
delete model2g;
|
||||
delete model3g;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -124,7 +124,7 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
|
||||
G4UrbanMscModel::~G4UrbanMscModel()
|
||||
{
|
||||
if(isFirstInstance) {
|
||||
for(auto & ptr : msc) { delete ptr; }
|
||||
for(auto const & ptr : msc) { delete ptr; }
|
||||
msc.clear();
|
||||
}
|
||||
}
|
||||
@@ -504,8 +504,9 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
|
||||
|
||||
smallstep += 1.;
|
||||
insideskin = false;
|
||||
tgeom = geombig;
|
||||
|
||||
// initialisation at firs step and at the boundary
|
||||
// initialisation at first step and at the boundary
|
||||
if(firstStep || (stepStatus == fGeomBoundary))
|
||||
{
|
||||
rangeinit = currentRange;
|
||||
@@ -520,22 +521,17 @@ G4double G4UrbanMscModel::ComputeTruePathLengthLimit(
|
||||
<< " tlimitmin= " << tlimitmin << " geomlimit= "
|
||||
<< geomlimit <<G4endl;
|
||||
*/
|
||||
// constraint from the geometry
|
||||
|
||||
if((geomlimit < geombig) && (geomlimit > geommin))
|
||||
{
|
||||
// geomlimit is a geometrical step length
|
||||
// transform it to true path length (estimation)
|
||||
if(lambda0 > geomlimit) {
|
||||
geomlimit = -lambda0*G4Log(1.-geomlimit/lambda0)+tlimitmin;
|
||||
}
|
||||
tgeom = (stepStatus == fGeomBoundary)
|
||||
? geomlimit/facgeom : 2.*geomlimit/facgeom;
|
||||
}
|
||||
else
|
||||
{
|
||||
tgeom = geombig;
|
||||
}
|
||||
}
|
||||
// constraint from the geometry
|
||||
if((geomlimit < geombig) && (geomlimit > geommin))
|
||||
{
|
||||
// geomlimit is a geometrical step length
|
||||
// transform it to true path length (estimation)
|
||||
if(lambda0 > geomlimit) {
|
||||
geomlimit = -lambda0*G4Log(1.-geomlimit/lambda0)+tlimitmin;
|
||||
}
|
||||
tgeom = (stepStatus == fGeomBoundary) ? geomlimit/facgeom
|
||||
: facrange*rangeinit + stepmin;
|
||||
}
|
||||
|
||||
//step limit
|
||||
|
||||
@@ -83,14 +83,10 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4bool G4eeToTwoGammaModel::fSampleAtomicPDF = false;
|
||||
|
||||
G4eeToTwoGammaModel::G4eeToTwoGammaModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
pi_rcl2(pi*classic_electr_radius*classic_electr_radius)
|
||||
pi_rcl2(CLHEP::pi*CLHEP::classic_electr_radius*CLHEP::classic_electr_radius)
|
||||
{
|
||||
theGamma = G4Gamma::Gamma();
|
||||
fParticleChange = nullptr;
|
||||
@@ -105,27 +101,7 @@ G4eeToTwoGammaModel::~G4eeToTwoGammaModel() = default;
|
||||
void G4eeToTwoGammaModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if(IsMaster()) {
|
||||
G4int verbose = G4EmParameters::Instance()->Verbose();
|
||||
// redo initialisation for each new run
|
||||
fSampleAtomicPDF = false;
|
||||
const auto& materialTable = G4Material::GetMaterialTable();
|
||||
for (const auto& material: *materialTable) {
|
||||
const G4double meanEnergyPerIonPair = material->GetIonisation()->GetMeanEnergyPerIonPair();
|
||||
if (meanEnergyPerIonPair > 0.) {
|
||||
fSampleAtomicPDF = true;
|
||||
if(verbose > 0) {
|
||||
G4cout << "### G4eeToTwoGammaModel: for " << material->GetName() << " mean energy per ion pair is "
|
||||
<< meanEnergyPerIonPair/CLHEP::eV << " eV" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If no materials have meanEnergyPerIonPair set. This is probably the usual
|
||||
// case, since most applications are not senstive to the slight
|
||||
// non-collinearity of gammas in eeToTwoGamma. Do not issue any warning.
|
||||
|
||||
if(fParticleChange) { return; }
|
||||
if (nullptr != fParticleChange) { return; }
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
}
|
||||
|
||||
@@ -137,13 +113,13 @@ G4eeToTwoGammaModel::ComputeCrossSectionPerElectron(G4double kineticEnergy)
|
||||
// Calculates the cross section per electron of annihilation into two photons
|
||||
// from the Heilter formula.
|
||||
|
||||
G4double ekin = std::max(eV,kineticEnergy);
|
||||
G4double ekin = std::max(CLHEP::eV, kineticEnergy);
|
||||
|
||||
G4double tau = ekin/electron_mass_c2;
|
||||
G4double tau = ekin/CLHEP::electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gamma2= gam*gam;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double bg = sqrt(bg2);
|
||||
G4double bg = std::sqrt(bg2);
|
||||
|
||||
G4double cross = pi_rcl2*((gamma2+4*gam+1.)*G4Log(gam+bg) - (gam+3.)*bg)
|
||||
/ (bg2*(gam+1.));
|
||||
@@ -178,183 +154,46 @@ G4double G4eeToTwoGammaModel::CrossSectionPerVolume(
|
||||
// Polarisation of gamma according to M.H.L.Pryce and J.C.Ward,
|
||||
// Nature 4065 (1947) 435.
|
||||
|
||||
void G4eeToTwoGammaModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
|
||||
const G4MaterialCutsCouple* pCutsCouple,
|
||||
void G4eeToTwoGammaModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
G4double posiKinEnergy = dp->GetKineticEnergy();
|
||||
G4DynamicParticle *aGamma1, *aGamma2;
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
// Case at rest
|
||||
if(posiKinEnergy == 0.0) {
|
||||
|
||||
const G4double eGamma = electron_mass_c2;
|
||||
|
||||
// In rest frame of positronium gammas are back to back
|
||||
const G4ThreeVector& dir1 = G4RandomDirection();
|
||||
const G4ThreeVector& dir2 = -dir1;
|
||||
aGamma1 = new G4DynamicParticle(G4Gamma::Gamma(),dir1,eGamma);
|
||||
aGamma2 = new G4DynamicParticle(G4Gamma::Gamma(),dir2,eGamma);
|
||||
|
||||
// In rest frame the gammas are polarised perpendicular to each other - see
|
||||
// Pryce and Ward, Nature No 4065 (1947) p.435.
|
||||
// Snyder et al, Physical Review 73 (1948) p.440.
|
||||
G4ThreeVector pol1 = (G4RandomDirection().cross(dir1)).unit();
|
||||
G4ThreeVector pol2 = (pol1.cross(dir2)).unit();
|
||||
|
||||
// But the positronium is moving...
|
||||
// A positron in matter slows down and combines with an atomic electron to
|
||||
// make a neutral “atom” called positronium, about half the size of a normal
|
||||
// atom. I expect that when the energy of the positron is small enough,
|
||||
// less than the binding energy of positronium (6.8 eV), it is
|
||||
// energetically favourable for an electron from the outer orbitals of a
|
||||
// nearby atom or molecule to transfer and bind to the positron, as in an
|
||||
// ionic bond, leaving behind a mildly ionised nearby atom/molecule. I
|
||||
// would expect the positronium to come away with a kinetic energy of a
|
||||
// few eV on average. In its para (spin 0) state it annihilates into two
|
||||
// photons, which in the rest frame of the positronium are collinear
|
||||
// (back-to-back) due to momentum conservation. Because of the motion of the
|
||||
// positronium, photons will be not quite back-to-back in the laboratory.
|
||||
|
||||
// The positroniuim acquires an energy of order its binding energy and
|
||||
// doesn't have time to thermalise. Nevertheless, here we approximate its
|
||||
// energy distribution by a Maxwell-Boltzman with mean energy <KE>. In terms
|
||||
// of a more familiar concept of temperature, and the law of equipartition
|
||||
// of energy of translational motion, <KE>=3kT/2. Each component of velocity
|
||||
// has a distribution exp(-mv^2/2kT), which is a Gaussian of mean zero
|
||||
// and variance kT/m=2<KE>/3m, where m is the positronium mass.
|
||||
|
||||
// We take <KE> = material->GetIonisation()->GetMeanEnergyPerIonPair().
|
||||
|
||||
if(fSampleAtomicPDF) {
|
||||
const G4Material* material = pCutsCouple->GetMaterial();
|
||||
const G4double meanEnergyPerIonPair = material->GetIonisation()->GetMeanEnergyPerIonPair();
|
||||
const G4double& meanKE = meanEnergyPerIonPair; // Just an alias
|
||||
if (meanKE > 0.) { // Positronium haas motion
|
||||
// Mass of positronium
|
||||
const G4double mass = 2.*electron_mass_c2;
|
||||
// Mean <KE>=3kT/2, as described above
|
||||
// const G4double T = 2.*meanKE/(3.*k_Boltzmann);
|
||||
// Component velocities: Gaussian, variance kT/m=2<KE>/3m.
|
||||
const G4double sigmav = std::sqrt(2.*meanKE/(3.*mass));
|
||||
// This is in units where c=1
|
||||
const G4double vx = G4RandGauss::shoot(0.,sigmav);
|
||||
const G4double vy = G4RandGauss::shoot(0.,sigmav);
|
||||
const G4double vz = G4RandGauss::shoot(0.,sigmav);
|
||||
const G4ThreeVector v(vx,vy,vz); // In unit where c=1
|
||||
const G4ThreeVector& beta = v; // so beta=v/c=v
|
||||
|
||||
aGamma1->Set4Momentum(aGamma1->Get4Momentum().boost(beta));
|
||||
aGamma2->Set4Momentum(aGamma2->Get4Momentum().boost(beta));
|
||||
|
||||
// Rotate polarisation vectors
|
||||
const G4ThreeVector& newDir1 = aGamma1->GetMomentumDirection();
|
||||
const G4ThreeVector& newDir2 = aGamma2->GetMomentumDirection();
|
||||
const G4ThreeVector& axis1 = dir1.cross(newDir1); // No need to be unit
|
||||
const G4ThreeVector& axis2 = dir2.cross(newDir2); // No need to be unit
|
||||
const G4double& angle1 = std::acos(dir1*newDir1);
|
||||
const G4double& angle2 = std::acos(dir2*newDir2);
|
||||
if (axis1 != G4ThreeVector()) pol1.rotate(axis1,angle1);
|
||||
if (axis2 != G4ThreeVector()) pol2.rotate(axis2,angle2);
|
||||
}
|
||||
}
|
||||
aGamma1->SetPolarization(pol1.x(),pol1.y(),pol1.z());
|
||||
aGamma2->SetPolarization(pol2.x(),pol2.y(),pol2.z());
|
||||
|
||||
} else { // Positron interacts in flight
|
||||
|
||||
G4ThreeVector posiDirection = dp->GetMomentumDirection();
|
||||
|
||||
G4double tau = posiKinEnergy/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double tau2 = tau + 2.0;
|
||||
G4double sqgrate = sqrt(tau/tau2)*0.5;
|
||||
G4double sqg2m1 = sqrt(tau*tau2);
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double epsilmin = 0.5 - sqgrate;
|
||||
G4double epsilmax = 0.5 + sqgrate;
|
||||
G4double epsilqot = epsilmax/epsilmin;
|
||||
|
||||
//
|
||||
// sample the energy rate of the created gammas
|
||||
//
|
||||
G4double epsil, greject;
|
||||
|
||||
do {
|
||||
epsil = epsilmin*G4Exp(G4Log(epsilqot)*rndmEngine->flat());
|
||||
greject = 1. - epsil + (2.*gam*epsil-1.)/(epsil*tau2*tau2);
|
||||
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
|
||||
} while( greject < rndmEngine->flat());
|
||||
|
||||
//
|
||||
// scattered Gamma angles. ( Z - axis along the parent positron)
|
||||
//
|
||||
|
||||
G4double cost = (epsil*tau2-1.)/(epsil*sqg2m1);
|
||||
if(std::abs(cost) > 1.0) {
|
||||
G4cout << "### G4eeToTwoGammaModel WARNING cost= " << cost
|
||||
<< " positron Ekin(MeV)= " << posiKinEnergy
|
||||
<< " gamma epsil= " << epsil
|
||||
<< G4endl;
|
||||
if(cost > 1.0) cost = 1.0;
|
||||
else cost = -1.0;
|
||||
}
|
||||
G4double sint = sqrt((1.+cost)*(1.-cost));
|
||||
G4double phi = twopi * rndmEngine->flat();
|
||||
|
||||
//
|
||||
// kinematic of the created pair
|
||||
//
|
||||
|
||||
G4double totalEnergy = posiKinEnergy + 2.0*electron_mass_c2;
|
||||
G4double phot1Energy = epsil*totalEnergy;
|
||||
|
||||
G4ThreeVector phot1Direction(sint*cos(phi), sint*sin(phi), cost);
|
||||
phot1Direction.rotateUz(posiDirection);
|
||||
aGamma1 = new G4DynamicParticle (theGamma,phot1Direction, phot1Energy);
|
||||
phi = twopi * rndmEngine->flat();
|
||||
G4double cosphi = cos(phi);
|
||||
G4double sinphi = sin(phi);
|
||||
G4ThreeVector pol(cosphi, sinphi, 0.0);
|
||||
pol.rotateUz(phot1Direction);
|
||||
aGamma1->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
|
||||
G4double phot2Energy =(1.-epsil)*totalEnergy;
|
||||
G4double posiP= sqrt(posiKinEnergy*(posiKinEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector dir = posiDirection*posiP - phot1Direction*phot1Energy;
|
||||
G4ThreeVector phot2Direction = dir.unit();
|
||||
|
||||
// create G4DynamicParticle object for the particle2
|
||||
aGamma2 = new G4DynamicParticle (theGamma, phot2Direction, phot2Energy);
|
||||
|
||||
//!!! likely problematic direction to be checked
|
||||
pol.set(-sinphi, cosphi, 0.0);
|
||||
pol.rotateUz(phot1Direction);
|
||||
cost = pol*phot2Direction;
|
||||
pol -= cost*phot2Direction;
|
||||
pol = pol.unit();
|
||||
aGamma2->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
/*
|
||||
G4cout << "Annihilation on fly: e0= " << posiKinEnergy
|
||||
<< " m= " << electron_mass_c2
|
||||
<< " e1= " << phot1Energy
|
||||
<< " e2= " << phot2Energy << " dir= " << dir
|
||||
<< " -> " << phot1Direction << " "
|
||||
<< phot2Direction << G4endl;
|
||||
*/
|
||||
}
|
||||
|
||||
vdp->push_back(aGamma1);
|
||||
vdp->push_back(aGamma2);
|
||||
|
||||
// kill primary positron
|
||||
fParticleChange->SetProposedKineticEnergy(0.0);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
// Case at rest not considered anymore inside this model
|
||||
G4LorentzVector lv(dp->GetMomentum(),
|
||||
dp->GetKineticEnergy() + 2*CLHEP::electron_mass_c2);
|
||||
G4double eGammaCMS = 0.5 * lv.mag();
|
||||
|
||||
G4ThreeVector dir1 = G4RandomDirection();
|
||||
G4double phi = CLHEP::twopi * G4UniformRand();
|
||||
G4double cosphi = std::cos(phi);
|
||||
G4double sinphi = std::sin(phi);
|
||||
G4ThreeVector pol1(cosphi, sinphi, 0.0);
|
||||
pol1.rotateUz(dir1);
|
||||
G4LorentzVector lv1(eGammaCMS*dir1, eGammaCMS);
|
||||
|
||||
G4ThreeVector pol2(-sinphi, cosphi, 0.0);
|
||||
pol2.rotateUz(dir1);
|
||||
|
||||
// transformation to lab system
|
||||
lv1.boost(lv.boostVector());
|
||||
lv -= lv1;
|
||||
|
||||
//!!! boost of polarisation vector is not yet implemented
|
||||
|
||||
// use constructors optimal for massless particle
|
||||
auto aGamma1 = new G4DynamicParticle(G4Gamma::Gamma(), lv1.vect());
|
||||
aGamma1->SetPolarization(pol1);
|
||||
auto aGamma2 = new G4DynamicParticle(G4Gamma::Gamma(), lv.vect());
|
||||
aGamma2->SetPolarization(pol2);
|
||||
|
||||
vdp->push_back(aGamma1);
|
||||
vdp->push_back(aGamma2);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -54,12 +54,13 @@
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4eeToTwoGammaModel.hh"
|
||||
#include "G4EmBiasingManager.hh"
|
||||
#include "G4EntanglementAuxInfo.hh"
|
||||
#include "G4eplusAnnihilationEntanglementClipBoard.hh"
|
||||
#include "G4SimplePositronAtRestModel.hh"
|
||||
#include "G4AllisonPositronAtRestModel.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4PhysicsModelCatalog.hh"
|
||||
|
||||
@@ -68,12 +69,10 @@
|
||||
G4eplusAnnihilation::G4eplusAnnihilation(const G4String& name)
|
||||
: G4VEmProcess(name)
|
||||
{
|
||||
theGamma = G4Gamma::Gamma();
|
||||
theElectron = G4Electron::Electron();
|
||||
SetCrossSectionType(fEmDecreasing);
|
||||
SetBuildTableFlag(false);
|
||||
SetStartFromNullFlag(false);
|
||||
SetSecondaryParticle(theGamma);
|
||||
SetSecondaryParticle(G4Gamma::Gamma());
|
||||
SetProcessSubType(fAnnihilation);
|
||||
enableAtRestDoIt = true;
|
||||
mainSecondaries = 2;
|
||||
@@ -82,7 +81,10 @@ G4eplusAnnihilation::G4eplusAnnihilation(const G4String& name)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4eplusAnnihilation::~G4eplusAnnihilation() = default;
|
||||
G4eplusAnnihilation::~G4eplusAnnihilation()
|
||||
{
|
||||
delete fAtRestModel;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -104,13 +106,28 @@ G4double G4eplusAnnihilation::AtRestGetPhysicalInteractionLength(
|
||||
|
||||
void G4eplusAnnihilation::InitialiseProcess(const G4ParticleDefinition*)
|
||||
{
|
||||
if(!isInitialised) {
|
||||
if (!isInitialised) {
|
||||
isInitialised = true;
|
||||
if(nullptr == EmModel(0)) { SetEmModel(new G4eeToTwoGammaModel()); }
|
||||
EmModel(0)->SetLowEnergyLimit(MinKinEnergy());
|
||||
EmModel(0)->SetHighEnergyLimit(MaxKinEnergy());
|
||||
AddEmModel(1, EmModel(0));
|
||||
}
|
||||
auto param = G4EmParameters::Instance();
|
||||
|
||||
// AtRest model should be chosen only once
|
||||
if (nullptr == fAtRestModel) {
|
||||
auto type = param->PositronAtRestModelType();
|
||||
if (type == fAllisonPositronium) {
|
||||
fAtRestModel = new G4AllisonPositronAtRestModel();
|
||||
} else {
|
||||
fAtRestModel = new G4SimplePositronAtRestModel();
|
||||
}
|
||||
}
|
||||
// Check that entanglement is switched on
|
||||
// It may be set by the UI command "/process/em/QuantumEntanglement true".
|
||||
fEntangled = param->QuantumEntanglement();
|
||||
fApplyCuts = param->ApplyCuts();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -122,136 +139,96 @@ void G4eplusAnnihilation::StreamProcessInfo(std::ostream&) const
|
||||
|
||||
G4VParticleChange* G4eplusAnnihilation::AtRestDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
// Performs the e+ e- annihilation when both particles are assumed at rest.
|
||||
{
|
||||
// positron at rest should be killed
|
||||
fParticleChange.InitializeForPostStep(track);
|
||||
fParticleChange.SetProposedKineticEnergy(0.);
|
||||
fParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
DefineMaterial(track.GetMaterialCutsCouple());
|
||||
G4int idx = (G4int)CurrentMaterialCutsCoupleIndex();
|
||||
G4double ene(0.0);
|
||||
G4VEmModel* model = SelectModel(ene, idx);
|
||||
auto couple = step.GetPreStepPoint()->GetMaterialCutsCouple();
|
||||
DefineMaterial(couple);
|
||||
|
||||
G4double gammaCut = GetGammaEnergyCut();
|
||||
|
||||
// define new weight for primary and secondaries
|
||||
G4double weight = fParticleChange.GetParentWeight();
|
||||
// apply cuts
|
||||
if (fApplyCuts && gammaCut > CLHEP::electron_mass_c2) {
|
||||
fParticleChange.ProposeLocalEnergyDeposit(2*CLHEP::electron_mass_c2);
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
// sample secondaries
|
||||
secParticles.clear();
|
||||
G4double gammaCut = GetGammaEnergyCut();
|
||||
model->SampleSecondaries(&secParticles, MaterialCutsCouple(),
|
||||
track.GetDynamicParticle(), gammaCut);
|
||||
|
||||
G4int num0 = (G4int)secParticles.size();
|
||||
G4double edep = 0.0;
|
||||
fAtRestModel->SampleSecondaries(secParticles, edep, couple->GetMaterial());
|
||||
|
||||
// define new weight for primary and secondaries
|
||||
G4double weight = fParticleChange.GetParentWeight();
|
||||
std::size_t num0 = secParticles.size();
|
||||
|
||||
// splitting or Russian roulette
|
||||
if(biasManager) {
|
||||
if(biasManager->SecondaryBiasingRegion(idx)) {
|
||||
if (nullptr != biasManager) {
|
||||
G4int idx = couple->GetIndex();
|
||||
if (biasManager->SecondaryBiasingRegion(idx) &&
|
||||
!biasManager->GetDirectionalSplitting()) {
|
||||
G4VEmModel* mod = nullptr;
|
||||
G4double eloss = 0.0;
|
||||
weight *= biasManager->ApplySecondaryBiasing(
|
||||
secParticles, track, model, &fParticleChange, eloss,
|
||||
idx, gammaCut, step.GetPostStepPoint()->GetSafety());
|
||||
if(eloss > 0.0) {
|
||||
eloss += fParticleChange.GetLocalEnergyDeposit();
|
||||
fParticleChange.ProposeLocalEnergyDeposit(eloss);
|
||||
}
|
||||
weight *= biasManager->ApplySecondaryBiasing(secParticles, track, mod,
|
||||
&fParticleChange, eloss,
|
||||
idx, gammaCut);
|
||||
edep += eloss;
|
||||
}
|
||||
}
|
||||
|
||||
// save secondaries
|
||||
G4int num = (G4int)secParticles.size();
|
||||
std::size_t num = secParticles.size();
|
||||
|
||||
// Check that entanglement is switched on... (the following flag is
|
||||
// set by /process/em/QuantumEntanglement).
|
||||
G4bool entangled = G4EmParameters::Instance()->QuantumEntanglement();
|
||||
// ...and that we have two gammas with both gammas' energies above
|
||||
// gammaCut (entanglement is only programmed for e+ e- -> gamma gamma).
|
||||
G4bool entangledgammagamma = false;
|
||||
if (entangled) {
|
||||
if (num == 2) {
|
||||
entangledgammagamma = true;
|
||||
for (const auto* p: secParticles) {
|
||||
if (p->GetDefinition() != theGamma ||
|
||||
p->GetKineticEnergy() < gammaCut) {
|
||||
entangledgammagamma = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare a shared pointer for psossible use below. If it is used, the
|
||||
// Prepare a shared pointer only for two first gamma. If it is used, the
|
||||
// shared pointer is copied into the tracks through G4EntanglementAuxInfo.
|
||||
// This ensures the clip board lasts until both tracks are destroyed.
|
||||
// It is assumed that 2 first secondary particles are the most energetic gamma
|
||||
std::shared_ptr<G4eplusAnnihilationEntanglementClipBoard> clipBoard;
|
||||
if (entangledgammagamma) {
|
||||
if (fEntangled && num >= 2) {
|
||||
clipBoard = std::make_shared<G4eplusAnnihilationEntanglementClipBoard>();
|
||||
clipBoard->SetParentParticleDefinition(track.GetDefinition());
|
||||
}
|
||||
|
||||
if(num > 0) {
|
||||
if (num > 0) {
|
||||
const G4double time = track.GetGlobalTime();
|
||||
const G4ThreeVector& pos = track.GetPosition();
|
||||
auto touch = track.GetTouchableHandle();
|
||||
for (std::size_t i=0; i<num; ++i) {
|
||||
G4DynamicParticle* dp = secParticles[i];
|
||||
G4Track* t = new G4Track(dp, time, pos);
|
||||
t->SetTouchableHandle(touch);
|
||||
if (fEntangled && i < 2) {
|
||||
// entangledgammagamma is only true when there are only two gammas
|
||||
// (See code above where entangledgammagamma is calculated.)
|
||||
if (i == 0) { // First gamma
|
||||
clipBoard->SetTrackA(t);
|
||||
} else if (i == 1) { // Second gamma
|
||||
clipBoard->SetTrackB(t);
|
||||
}
|
||||
t->SetAuxiliaryTrackInformation
|
||||
(fEntanglementModelID, new G4EntanglementAuxInfo(clipBoard));
|
||||
}
|
||||
if (nullptr != biasManager) {
|
||||
t->SetWeight(weight * biasManager->GetWeight((G4int)i));
|
||||
} else {
|
||||
t->SetWeight(weight);
|
||||
}
|
||||
pParticleChange->AddSecondary(t);
|
||||
|
||||
fParticleChange.SetNumberOfSecondaries(num);
|
||||
G4double edep = fParticleChange.GetLocalEnergyDeposit();
|
||||
G4double time = track.GetGlobalTime();
|
||||
|
||||
for (G4int i=0; i<num; ++i) {
|
||||
if (secParticles[i]) {
|
||||
G4DynamicParticle* dp = secParticles[i];
|
||||
const G4ParticleDefinition* p = dp->GetParticleDefinition();
|
||||
G4double e = dp->GetKineticEnergy();
|
||||
G4bool good = true;
|
||||
if(ApplyCuts()) {
|
||||
if (p == theGamma) {
|
||||
if (e < gammaCut) { good = false; }
|
||||
} else if (p == theElectron) {
|
||||
if (e < GetElectronEnergyCut()) { good = false; }
|
||||
}
|
||||
// added secondary if it is good
|
||||
}
|
||||
if (good) {
|
||||
G4Track* t = new G4Track(dp, time, track.GetPosition());
|
||||
t->SetTouchableHandle(track.GetTouchableHandle());
|
||||
if (entangledgammagamma) {
|
||||
// entangledgammagamma is only true when there are only two gammas
|
||||
// (See code above where entangledgammagamma is calculated.)
|
||||
if (i == 0) { // First gamma
|
||||
clipBoard->SetTrackA(t);
|
||||
} else if (i == 1) { // Second gamma
|
||||
clipBoard->SetTrackB(t);
|
||||
}
|
||||
t->SetAuxiliaryTrackInformation
|
||||
(fEntanglementModelID,new G4EntanglementAuxInfo(clipBoard));
|
||||
}
|
||||
if (biasManager) {
|
||||
t->SetWeight(weight * biasManager->GetWeight(i));
|
||||
} else {
|
||||
t->SetWeight(weight);
|
||||
}
|
||||
pParticleChange->AddSecondary(t);
|
||||
|
||||
// define type of secondary
|
||||
if(i < mainSecondaries) { t->SetCreatorModelID(secID); }
|
||||
else if(i < num0) {
|
||||
if(p == theGamma) {
|
||||
t->SetCreatorModelID(fluoID);
|
||||
} else {
|
||||
t->SetCreatorModelID(augerID);
|
||||
}
|
||||
} else {
|
||||
t->SetCreatorModelID(biasID);
|
||||
}
|
||||
/*
|
||||
G4cout << "Secondary(post step) has weight " << t->GetWeight()
|
||||
<< ", Ekin= " << t->GetKineticEnergy()/MeV << " MeV "
|
||||
<< GetProcessName() << " fluoID= " << fluoID
|
||||
<< " augerID= " << augerID <<G4endl;
|
||||
*/
|
||||
} else {
|
||||
delete dp;
|
||||
edep += e;
|
||||
}
|
||||
}
|
||||
// define type of secondary
|
||||
if (i < num0) {
|
||||
t->SetCreatorModelID(secID);
|
||||
}
|
||||
else {
|
||||
t->SetCreatorModelID(biasID);
|
||||
}
|
||||
}
|
||||
fParticleChange.ProposeLocalEnergyDeposit(edep);
|
||||
}
|
||||
fParticleChange.ProposeLocalEnergyDeposit(edep);
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
//
|
||||
// Creation date: 29.03.2018
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -53,6 +54,7 @@
|
||||
#include "G4DataVector.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
#include "G4Log.hh"
|
||||
@@ -60,64 +62,70 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4PhysicsVector* G4eplusTo2GammaOKVIModel::fCrossSection = nullptr;
|
||||
G4PhysicsVector* G4eplusTo2GammaOKVIModel::fCrossSection3G = nullptr;
|
||||
G4PhysicsVector* G4eplusTo2GammaOKVIModel::f3GProbability = nullptr;
|
||||
|
||||
G4eplusTo2GammaOKVIModel::G4eplusTo2GammaOKVIModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
fDelta(0.001),
|
||||
fGammaTh(MeV)
|
||||
G4eplusTo2GammaOKVIModel::G4eplusTo2GammaOKVIModel()
|
||||
: G4VEmModel("eplus2ggOKVI"),
|
||||
fDeltaMin(0.001),
|
||||
fDelta(fDeltaMin),
|
||||
fGammaTh(CLHEP::MeV)
|
||||
{
|
||||
theGamma = G4Gamma::Gamma();
|
||||
fParticleChange = nullptr;
|
||||
fCuts = nullptr;
|
||||
f3GModel = new G4eplusTo3GammaOKVIModel();
|
||||
SetTripletModel(f3GModel);
|
||||
|
||||
// instantiate vectors once
|
||||
if (nullptr == fCrossSection) {
|
||||
G4double emin = 10*CLHEP::eV;
|
||||
G4double emax = 100*CLHEP::TeV;
|
||||
G4int nbins = 20*G4lrint(std::log10(emax/emin));
|
||||
fCrossSection = new G4PhysicsLogVector(emin, emax, nbins, true);
|
||||
f3GProbability = new G4PhysicsLogVector(emin, emax, nbins, true);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4eplusTo2GammaOKVIModel::~G4eplusTo2GammaOKVIModel() = default;
|
||||
G4eplusTo2GammaOKVIModel::~G4eplusTo2GammaOKVIModel()
|
||||
{
|
||||
if (IsMaster()) {
|
||||
delete fCrossSection;
|
||||
delete f3GProbability;
|
||||
fCrossSection = nullptr;
|
||||
f3GProbability = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eplusTo2GammaOKVIModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
f3GModel->Initialise(p, cuts);
|
||||
fCuts = &cuts;
|
||||
fGammaTh = G4EmParameters::Instance()->LowestTripletEnergy();
|
||||
f3GModel->SetDelta(fDelta);
|
||||
|
||||
if(IsMaster()) {
|
||||
if(!fCrossSection) {
|
||||
G4double emin = 10*eV;
|
||||
G4double emax = 100*TeV;
|
||||
G4int nbins = 20*G4lrint(std::log10(emax/emin));
|
||||
fCrossSection = new G4PhysicsLogVector(emin, emax, nbins, true);
|
||||
fCrossSection3G = new G4PhysicsLogVector(emin, emax, nbins, true);
|
||||
f3GProbability = new G4PhysicsLogVector(emin, emax, nbins, true);
|
||||
for(G4int i=0; i<= nbins; ++i) {
|
||||
G4double e = fCrossSection->Energy(i);
|
||||
G4double cs2 = ComputeCrossSectionPerElectron(e);
|
||||
G4double cs3 = f3GModel->ComputeCrossSectionPerElectron(e);
|
||||
cs2 += cs3;
|
||||
fCrossSection->PutValue(i, cs2);
|
||||
fCrossSection3G->PutValue(i, cs3);
|
||||
f3GProbability->PutValue(i, cs3/cs2);
|
||||
}
|
||||
fCrossSection->FillSecondDerivatives();
|
||||
fCrossSection3G->FillSecondDerivatives();
|
||||
f3GProbability->FillSecondDerivatives();
|
||||
}
|
||||
}
|
||||
// here particle change is set for the triplet model
|
||||
if(fParticleChange) { return; }
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
if (nullptr == fParticleChange) {
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
}
|
||||
// initialialise 3-gamma model before new run
|
||||
f3GModel->Initialise(p, cuts);
|
||||
fGammaTh = G4EmParameters::Instance()->LowestTripletEnergy();
|
||||
|
||||
// initialise vectors
|
||||
if (IsMaster()) {
|
||||
std::size_t num = fCrossSection->GetVectorLength();
|
||||
for (std::size_t i=0; i<num; ++i) {
|
||||
G4double e = fCrossSection->Energy(i);
|
||||
G4double cs2 = ComputeCrossSectionPerElectron(e);
|
||||
G4double cs3 = f3GModel->ComputeCrossSectionPerElectron(e);
|
||||
cs2 += cs3;
|
||||
fCrossSection->PutValue(i, cs2);
|
||||
G4double y = (cs2 > 0.0) ? cs3/cs2 : 0.0;
|
||||
f3GProbability->PutValue(i, y);
|
||||
}
|
||||
fCrossSection->FillSecondDerivatives();
|
||||
f3GProbability->FillSecondDerivatives();
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -129,16 +137,20 @@ G4eplusTo2GammaOKVIModel::ComputeCrossSectionPerElectron(G4double kinEnergy)
|
||||
// photons from the Heilter formula with the radiation correction to 3 gamma
|
||||
// annihilation channel. (A.A.) rho is changed
|
||||
|
||||
G4double ekin = std::max(eV,kinEnergy);
|
||||
G4double tau = ekin/electron_mass_c2;
|
||||
G4double ekin = std::max(CLHEP::eV, kinEnergy);
|
||||
G4double tau = ekin/CLHEP::electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gamma2 = gam*gam;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double bg = sqrt(bg2);
|
||||
G4double bg = std::sqrt(bg2);
|
||||
G4double rho = (gamma2+4.*gam+1.)*G4Log(gam+bg)/(gamma2-1.)
|
||||
- (gam+3.)/(sqrt(gam*gam - 1.));
|
||||
- (gam+3.)/(std::sqrt(gam*gam - 1.));
|
||||
G4double eGammaCMS = CLHEP::electron_mass_c2 * std::sqrt(0.5*(tau + 2.0));
|
||||
fDelta = std::max(fDeltaMin, fGammaTh/eGammaCMS);
|
||||
f3GModel->SetDelta(fDelta);
|
||||
|
||||
static const G4double pir2 = pi*classic_electr_radius*classic_electr_radius;
|
||||
static const G4double pir2 =
|
||||
CLHEP::pi*CLHEP::classic_electr_radius*CLHEP::classic_electr_radius;
|
||||
G4double cross = (pir2*rho + alpha_rcl2*2.*G4Log(fDelta)*rho*rho)/(gam+1.);
|
||||
|
||||
return cross;
|
||||
@@ -175,143 +187,54 @@ G4double G4eplusTo2GammaOKVIModel::CrossSectionPerVolume(
|
||||
// Polarisation of gamma according to M.H.L.Pryce and J.C.Ward,
|
||||
// Nature 4065 (1947) 435.
|
||||
|
||||
void
|
||||
G4eplusTo2GammaOKVIModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
|
||||
const G4MaterialCutsCouple* mcc,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double, G4double)
|
||||
void G4eplusTo2GammaOKVIModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* vdp,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double, G4double)
|
||||
{
|
||||
G4double posiKinEnergy = dp->GetKineticEnergy();
|
||||
CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
if(rndmEngine->flat() < f3GProbability->Value(posiKinEnergy)) {
|
||||
G4double cutd = std::max(fGammaTh,(*fCuts)[mcc->GetIndex()])
|
||||
/(posiKinEnergy + electron_mass_c2);
|
||||
// check cut to avoid production of 3d gamma below
|
||||
if(cutd > fDelta) {
|
||||
G4double cs30 = fCrossSection3G->Value(posiKinEnergy);
|
||||
f3GModel->SetDelta(cutd);
|
||||
G4double cs3 = f3GModel->ComputeCrossSectionPerElectron(posiKinEnergy);
|
||||
if(rndmEngine->flat()*cs30 < cs3) {
|
||||
f3GModel->SampleSecondaries(vdp, mcc, dp);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
f3GModel->SampleSecondaries(vdp, mcc, dp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
G4DynamicParticle *aGamma1, *aGamma2;
|
||||
|
||||
// Case at rest
|
||||
if(posiKinEnergy == 0.0) {
|
||||
G4double cost = 2.*rndmEngine->flat()-1.;
|
||||
G4double sint = sqrt((1. - cost)*(1. + cost));
|
||||
G4double phi = twopi * rndmEngine->flat();
|
||||
G4ThreeVector dir(sint*cos(phi), sint*sin(phi), cost);
|
||||
phi = twopi * rndmEngine->flat();
|
||||
G4double cosphi = cos(phi);
|
||||
G4double sinphi = sin(phi);
|
||||
G4ThreeVector pol(cosphi, sinphi, 0.0);
|
||||
pol.rotateUz(dir);
|
||||
aGamma1 = new G4DynamicParticle(theGamma, dir, electron_mass_c2);
|
||||
aGamma1->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
aGamma2 = new G4DynamicParticle(theGamma,-dir, electron_mass_c2);
|
||||
pol.set(-sinphi, cosphi, 0.0);
|
||||
pol.rotateUz(dir);
|
||||
aGamma2->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
|
||||
} else {
|
||||
|
||||
G4ThreeVector posiDirection = dp->GetMomentumDirection();
|
||||
|
||||
G4double tau = posiKinEnergy/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double tau2 = tau + 2.0;
|
||||
G4double sqgrate = sqrt(tau/tau2)*0.5;
|
||||
G4double sqg2m1 = sqrt(tau*tau2);
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double epsilmin = 0.5 - sqgrate;
|
||||
G4double epsilmax = 0.5 + sqgrate;
|
||||
G4double epsilqot = epsilmax/epsilmin;
|
||||
|
||||
//
|
||||
// sample the energy rate of the created gammas
|
||||
//
|
||||
G4double epsil, greject;
|
||||
|
||||
do {
|
||||
epsil = epsilmin*G4Exp(G4Log(epsilqot)*rndmEngine->flat());
|
||||
greject = 1. - epsil + (2.*gam*epsil-1.)/(epsil*tau2*tau2);
|
||||
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
|
||||
} while( greject < rndmEngine->flat());
|
||||
|
||||
//
|
||||
// scattered Gamma angles. ( Z - axis along the parent positron)
|
||||
//
|
||||
|
||||
G4double cost = (epsil*tau2-1.)/(epsil*sqg2m1);
|
||||
if(std::abs(cost) > 1.0) {
|
||||
G4cout << "### G4eplusTo2GammaOKVIModel WARNING cost= " << cost
|
||||
<< " positron Ekin(MeV)= " << posiKinEnergy
|
||||
<< " gamma epsil= " << epsil
|
||||
<< G4endl;
|
||||
if(cost > 1.0) cost = 1.0;
|
||||
else cost = -1.0;
|
||||
}
|
||||
G4double sint = sqrt((1.+cost)*(1.-cost));
|
||||
G4double phi = twopi * rndmEngine->flat();
|
||||
|
||||
//
|
||||
// kinematic of the created pair
|
||||
//
|
||||
|
||||
G4double TotalAvailableEnergy = posiKinEnergy + 2.0*electron_mass_c2;
|
||||
G4double phot1Energy = epsil*TotalAvailableEnergy;
|
||||
|
||||
G4ThreeVector phot1Direction(sint*cos(phi), sint*sin(phi), cost);
|
||||
phot1Direction.rotateUz(posiDirection);
|
||||
aGamma1 = new G4DynamicParticle (theGamma,phot1Direction, phot1Energy);
|
||||
phi = twopi * rndmEngine->flat();
|
||||
G4double cosphi = cos(phi);
|
||||
G4double sinphi = sin(phi);
|
||||
G4ThreeVector pol(cosphi, sinphi, 0.0);
|
||||
pol.rotateUz(phot1Direction);
|
||||
aGamma1->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
|
||||
G4double phot2Energy =(1.-epsil)*TotalAvailableEnergy;
|
||||
G4double posiP= sqrt(posiKinEnergy*(posiKinEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector dir = posiDirection*posiP - phot1Direction*phot1Energy;
|
||||
G4ThreeVector phot2Direction = dir.unit();
|
||||
|
||||
// create G4DynamicParticle object for the particle2
|
||||
aGamma2 = new G4DynamicParticle (theGamma,phot2Direction, phot2Energy);
|
||||
|
||||
//!!! likely problematic direction to be checked
|
||||
pol.set(-sinphi, cosphi, 0.0);
|
||||
pol.rotateUz(phot1Direction);
|
||||
cost = pol*phot2Direction;
|
||||
pol -= cost*phot2Direction;
|
||||
pol = pol.unit();
|
||||
aGamma2->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
}
|
||||
/*
|
||||
G4cout << "Annihilation in fly: e0= " << posiKinEnergy
|
||||
<< " m= " << electron_mass_c2
|
||||
<< " e1= " << phot1Energy
|
||||
<< " e2= " << phot2Energy << " dir= " << dir
|
||||
<< " -> " << phot1Direction << " "
|
||||
<< phot2Direction << G4endl;
|
||||
*/
|
||||
|
||||
vdp->push_back(aGamma1);
|
||||
vdp->push_back(aGamma2);
|
||||
|
||||
// kill primary positron
|
||||
fParticleChange->SetProposedKineticEnergy(0.0);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
// Case at rest not considered anymore
|
||||
G4double posiKinEnergy = dp->GetKineticEnergy();
|
||||
G4LorentzVector lv(dp->GetMomentum(),
|
||||
posiKinEnergy + 2*CLHEP::electron_mass_c2);
|
||||
G4double eGammaCMS = 0.5 * lv.mag();
|
||||
|
||||
if (G4UniformRand() < f3GProbability->Value(posiKinEnergy)) {
|
||||
fDelta = std::max(fDeltaMin, fGammaTh/eGammaCMS);
|
||||
f3GModel->SetDelta(fDelta);
|
||||
f3GModel->SampleSecondaries(vdp, couple, dp);
|
||||
return;
|
||||
}
|
||||
|
||||
G4ThreeVector dir1 = G4RandomDirection();
|
||||
G4double phi = CLHEP::twopi * G4UniformRand();
|
||||
G4double cosphi = std::cos(phi);
|
||||
G4double sinphi = std::sin(phi);
|
||||
G4ThreeVector pol1(cosphi, sinphi, 0.0);
|
||||
pol1.rotateUz(dir1);
|
||||
G4LorentzVector lv1(eGammaCMS*dir1, eGammaCMS);
|
||||
|
||||
G4ThreeVector pol2(-sinphi, cosphi, 0.0);
|
||||
pol2.rotateUz(dir1);
|
||||
|
||||
// transformation to lab system
|
||||
lv1.boost(lv.boostVector());
|
||||
lv -= lv1;
|
||||
|
||||
//!!! boost of polarisation vector is not yet implemented
|
||||
|
||||
// use constructors optimal for massless particle
|
||||
auto aGamma1 = new G4DynamicParticle(G4Gamma::Gamma(), lv1.vect());
|
||||
aGamma1->SetPolarization(pol1);
|
||||
auto aGamma2 = new G4DynamicParticle(G4Gamma::Gamma(), lv.vect());
|
||||
aGamma2->SetPolarization(pol2);
|
||||
|
||||
vdp->push_back(aGamma1);
|
||||
vdp->push_back(aGamma2);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -62,7 +62,6 @@ G4eplusTo3GammaOKVIModel::G4eplusTo3GammaOKVIModel(const G4ParticleDefinition*,
|
||||
: G4VEmModel(nam), fDelta(0.001)
|
||||
{
|
||||
theGamma = G4Gamma::Gamma();
|
||||
fParticleChange = nullptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -73,11 +72,7 @@ G4eplusTo3GammaOKVIModel::~G4eplusTo3GammaOKVIModel() = default;
|
||||
|
||||
void G4eplusTo3GammaOKVIModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{
|
||||
// here particle change is set for the triplet model
|
||||
if(fParticleChange) { return; }
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
}
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -183,8 +178,8 @@ G4eplusTo3GammaOKVIModel::ComputeCrossSectionPerElectron(G4double kinEnergy)
|
||||
// Calculates the cross section per electron of annihilation into 3 photons
|
||||
// from the Heilter formula.
|
||||
|
||||
G4double ekin = std::max(eV,kinEnergy);
|
||||
G4double tau = ekin/electron_mass_c2;
|
||||
G4double ekin = std::max(CLHEP::eV, kinEnergy);
|
||||
G4double tau = ekin/CLHEP::electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gamma2 = gam*gam;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
@@ -204,10 +199,6 @@ G4double G4eplusTo3GammaOKVIModel::ComputeCrossSectionPerAtom(
|
||||
G4double kineticEnergy, G4double Z,
|
||||
G4double, G4double, G4double)
|
||||
{
|
||||
// Calculates the cross section per atom of annihilation into two photons
|
||||
|
||||
|
||||
|
||||
G4double cross = Z*ComputeCrossSectionPerElectron(kineticEnergy);
|
||||
return cross;
|
||||
}
|
||||
@@ -238,149 +229,78 @@ G4eplusTo3GammaOKVIModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double, G4double)
|
||||
{
|
||||
|
||||
// let us perform sampling in C.M.S. reference frame of e- at rest and e+ on fly
|
||||
G4double posiKinEnergy = dp->GetKineticEnergy();
|
||||
G4DynamicParticle *aGamma1, *aGamma2;
|
||||
G4DynamicParticle* aGamma3 = nullptr;
|
||||
G4double border;
|
||||
G4LorentzVector lv(dp->GetMomentum(),
|
||||
posiKinEnergy + 2*CLHEP::electron_mass_c2);
|
||||
G4double eGammaCMS = 0.5 * lv.mag();
|
||||
|
||||
if(posiKinEnergy < 500*MeV) {
|
||||
border = 1. - (electron_mass_c2)/(2*(posiKinEnergy + electron_mass_c2));
|
||||
} else {
|
||||
border = 1. - (100*electron_mass_c2)/(2*(posiKinEnergy + electron_mass_c2));
|
||||
}
|
||||
border = std::min(border, 0.9999);
|
||||
// the limit value fDelta is defined by a class, which call this method
|
||||
// thickness of border defined by C.M.S. energy
|
||||
G4double border =
|
||||
1.0 - std::min(std::max(CLHEP::electron_mass_c2/eGammaCMS, fDelta), 0.1);
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
// Case at rest
|
||||
if(posiKinEnergy == 0.0) {
|
||||
G4double cost = 2.*rndmEngine->flat()-1.;
|
||||
G4double sint = sqrt((1. - cost)*(1. + cost));
|
||||
G4double phi = twopi * rndmEngine->flat();
|
||||
G4ThreeVector dir(sint*cos(phi), sint*sin(phi), cost);
|
||||
phi = twopi * rndmEngine->flat();
|
||||
G4double cosphi = cos(phi);
|
||||
G4double sinphi = sin(phi);
|
||||
G4ThreeVector pol(cosphi, sinphi, 0.0);
|
||||
pol.rotateUz(dir);
|
||||
aGamma1 = new G4DynamicParticle(theGamma, dir, electron_mass_c2);
|
||||
aGamma1->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
aGamma2 = new G4DynamicParticle(theGamma,-dir, electron_mass_c2);
|
||||
pol.set(-sinphi, cosphi, 0.0);
|
||||
pol.rotateUz(dir);
|
||||
aGamma2->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
G4ThreeVector posiDirection = dp->GetMomentumDirection();
|
||||
|
||||
} else {
|
||||
|
||||
G4ThreeVector posiDirection = dp->GetMomentumDirection();
|
||||
|
||||
// (A.A.) LIMITS FOR 1st GAMMA
|
||||
G4double xmin = 0.01;
|
||||
G4double xmax = 0.667; // CHANGE to 3/2
|
||||
// (A.A.) LIMITS FOR 1st GAMMA
|
||||
G4double xmin = 0.01;
|
||||
G4double xmax = 0.667; // CHANGE to 3/2
|
||||
|
||||
G4double d1, d0, x1, x2, dmax, x2min;
|
||||
G4double d1, d0, x1, x2, dmax, x2min;
|
||||
|
||||
// (A.A.) sampling of x1 x2 x3 (whole cycle of rejection)
|
||||
do {
|
||||
x1 = 1/((1/xmin) - ((1/xmin)-(1/xmax))*rndmEngine->flat());
|
||||
dmax = ComputeFS(posiKinEnergy, x1,1.-x1,border);
|
||||
x2min = 1.-x1;
|
||||
x2 = 1 - rndmEngine->flat()*(1-x2min);
|
||||
d1 = dmax*rndmEngine->flat();
|
||||
d0 = ComputeFS(posiKinEnergy,x1,x2,2-x1-x2);
|
||||
}
|
||||
while(d0 < d1);
|
||||
|
||||
G4double x3 = 2 - x1 - x2;
|
||||
|
||||
//
|
||||
// angles between Gammas
|
||||
//
|
||||
|
||||
G4double psi13 = 2*asin(sqrt(std::abs((x1+x3-1)/(x1*x3))));
|
||||
G4double psi12 = 2*asin(sqrt(std::abs((x1+x2-1)/(x1*x2))));
|
||||
|
||||
// sin^t
|
||||
|
||||
//G4double phi = twopi * rndmEngine->flat();
|
||||
//G4double psi = acos(x3); // Angle of the plane
|
||||
|
||||
//
|
||||
// kinematic of the created pair
|
||||
//
|
||||
|
||||
G4double TotalAvailableEnergy = posiKinEnergy + 2.0*electron_mass_c2;
|
||||
|
||||
G4double phot1Energy = 0.5*x1*TotalAvailableEnergy;
|
||||
G4double phot2Energy = 0.5*x2*TotalAvailableEnergy;
|
||||
G4double phot3Energy = 0.5*x3*TotalAvailableEnergy;
|
||||
// (A.A.) sampling of x1 x2 x3 (whole cycle of rejection)
|
||||
do {
|
||||
x1 = 1./((1./xmin) - ((1./xmin)-(1./xmax))*rndmEngine->flat());
|
||||
dmax = ComputeFS(eGammaCMS, x1, 1.-x1, border);
|
||||
x2min = 1. - x1;
|
||||
x2 = 1 - rndmEngine->flat()*(1. - x2min);
|
||||
d1 = dmax*rndmEngine->flat();
|
||||
d0 = ComputeFS(eGammaCMS, x1, x2, 2.-x1-x2);
|
||||
}
|
||||
while(d0 < d1);
|
||||
|
||||
G4double x3 = 2 - x1 - x2;
|
||||
//
|
||||
// angles between Gammas
|
||||
//
|
||||
G4double psi13 = 2*std::asin(std::sqrt(std::abs((x1+x3-1.)/(x1*x3))));
|
||||
G4double psi12 = 2*std::asin(std::sqrt(std::abs((x1+x2-1.)/(x1*x2))));
|
||||
//
|
||||
// kinematic of the created pair
|
||||
//
|
||||
G4double phot1Energy = x1*eGammaCMS;
|
||||
G4double phot2Energy = x2*eGammaCMS;
|
||||
G4double phot3Energy = x3*eGammaCMS;
|
||||
|
||||
// DIRECTIONS
|
||||
// DIRECTIONS
|
||||
|
||||
// The azimuthal angles of ql and q3 with respect to some plane
|
||||
// through the beam axis are generated at random.
|
||||
// The azimuthal angles of q1 and q3 with respect to some plane
|
||||
// through the beam axis are generated at random.
|
||||
|
||||
G4ThreeVector phot1Direction(0, 0, 1);
|
||||
G4ThreeVector phot2Direction(0, sin(psi12), cos(psi12));
|
||||
G4ThreeVector phot3Direction(0, sin(psi13), cos(psi13));
|
||||
G4ThreeVector phot1Direction(0, 0, 1);
|
||||
G4ThreeVector phot2Direction(0, std::sin(psi12), std::cos(psi12));
|
||||
G4ThreeVector phot3Direction(0, std::sin(psi13), std::cos(psi13));
|
||||
|
||||
phot1Direction.rotateUz(posiDirection);
|
||||
phot2Direction.rotateUz(posiDirection);
|
||||
phot3Direction.rotateUz(posiDirection);
|
||||
G4LorentzVector lv1(phot1Energy*phot1Direction, phot1Energy);
|
||||
G4LorentzVector lv2(phot2Energy*phot2Direction, phot2Energy);
|
||||
G4LorentzVector lv3(phot3Energy*phot3Direction, phot3Energy);
|
||||
|
||||
aGamma1 = new G4DynamicParticle (theGamma,phot1Direction, phot1Energy);
|
||||
aGamma2 = new G4DynamicParticle (theGamma,phot2Direction, phot2Energy);
|
||||
aGamma3 = new G4DynamicParticle (theGamma,phot3Direction, phot3Energy);
|
||||
auto boostV = lv.boostVector();
|
||||
lv1.boost(boostV);
|
||||
lv2.boost(boostV);
|
||||
lv3.boost(boostV);
|
||||
|
||||
auto aGamma1 = new G4DynamicParticle (theGamma, lv1.vect());
|
||||
auto aGamma2 = new G4DynamicParticle (theGamma, lv2.vect());
|
||||
auto aGamma3 = new G4DynamicParticle (theGamma, lv3.vect());
|
||||
|
||||
//POLARIZATION - ???
|
||||
/*
|
||||
|
||||
|
||||
phi = twopi * rndmEngine->flat();
|
||||
G4double cosphi = cos(phi);
|
||||
G4double sinphi = sin(phi);
|
||||
G4ThreeVector pol(cosphi, sinphi, 0.0);
|
||||
pol.rotateUz(phot1Direction);
|
||||
aGamma1->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
|
||||
G4double phot2Energy =(1.-epsil)*TotalAvailableEnergy;
|
||||
G4double posiP= sqrt(posiKinEnergy*(posiKinEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector dir = posiDirection*posiP - phot1Direction*phot1Energy;
|
||||
G4ThreeVector phot2Direction = dir.unit();
|
||||
|
||||
// create G4DynamicParticle object for the particle2
|
||||
aGamma2 = new G4DynamicParticle (theGamma,phot2Direction, phot2Energy);
|
||||
|
||||
//!!! likely problematic direction to be checked
|
||||
pol.set(-sinphi, cosphi, 0.0);
|
||||
pol.rotateUz(phot1Direction);
|
||||
cost = pol*phot2Direction;
|
||||
pol -= cost*phot2Direction;
|
||||
pol = pol.unit();
|
||||
aGamma2->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
/*
|
||||
G4cout << "Annihilation in fly: e0= " << posiKinEnergy
|
||||
<< " m= " << electron_mass_c2
|
||||
<< " e1= " << phot1Energy
|
||||
<< " e2= " << phot2Energy << " dir= " << dir
|
||||
<< " -> " << phot1Direction << " "
|
||||
<< phot2Direction << G4endl;
|
||||
*/
|
||||
//!!! POLARIZATION - not yet implemented
|
||||
|
||||
vdp->push_back(aGamma1);
|
||||
vdp->push_back(aGamma2);
|
||||
if(aGamma3 != nullptr) { vdp->push_back(aGamma3); }
|
||||
|
||||
// kill primary positron
|
||||
fParticleChange->SetProposedKineticEnergy(0.0);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
vdp->push_back(aGamma3);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -6,28 +6,69 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-05-22 V.Ivanchenko (emutils-V11-01-28)
|
||||
## 2024-06-19 S.Johnson (emutils-V11-02-10)
|
||||
- G4EmParameters - fix segmentation fault when data is unavailable
|
||||
|
||||
## 2024-06-06 I.Semeniouk & D.Bernard (emutils-V11-02-09)
|
||||
- G4EmParameters, G4EmParametersMessenger - added orto Positronion fraction flag
|
||||
|
||||
## 2024-05-27 V.Ivanchenko (emutils-V11-02-08)
|
||||
- G4VEmProcess - extended info printout for e+ annihilation at rest
|
||||
- G4VEmProcess, G4VEnergyLossProcess - improved identification of model ID
|
||||
for atomic de-excitation (fluorescence, Auger e-, PIXE).
|
||||
|
||||
## 2024-05-22 V.Ivanchenko (emutils-V11-02-07)
|
||||
- G4EmUtility - simplify computation of cross section maximum for discrete
|
||||
processes to fix the problem of FPE if -O3 compiler option is used.
|
||||
|
||||
## 2024-04-21 Gabriele Cosmo (emutils-V11-01-27)
|
||||
## 2024-05-20 H. Tran (emutils-V11-02-06)
|
||||
- G4EmParameters, G4EmLowEParameters, G4EmLowEParametersMessenger - added dna
|
||||
chemistry time step model
|
||||
|
||||
## 2024-05-14 V.Ivanchenko (emutils-V11-02-05)
|
||||
- G4EmParameters, G4EmParametersMessenger - added enumerator and a new flag
|
||||
G4PositronAtRestModel, which allows selectrion and configuration of
|
||||
the model of positron annihilation at rest.
|
||||
- G4VPositronAtRestModel - new virtual interface
|
||||
- G4EmBiasingManager - cosmetic change
|
||||
|
||||
## 2024-05-04 V.Ivanchenko (emutils-V11-02-04)
|
||||
- G4EmDataRegistry - new class to keep EM data tables
|
||||
- G4EmDataHandler - extended functionality
|
||||
- G4LossTableManager - identify master thread using std method
|
||||
- G4LossTableBUilder - more accurate use of static members and methods
|
||||
- G4VEmModel, G4VEmProcess, G4VEnergyLossProcess, G4EmTableUtil - update
|
||||
according to change in the data
|
||||
- G4VMscModel - move initialisation of tables for model to G4EmTableUtil
|
||||
|
||||
## 2024-04-21 Gabriele Cosmo (emutils-V11-02-03)
|
||||
- Fixed compilation error in G4EmConfigurator on Windows VC++ with
|
||||
C++20 Standard enabled.
|
||||
Based on [GitHub PR#69](https://github.com/Geant4/geant4/pull/69).
|
||||
|
||||
## 2023-12-15 V.Ivanchenko (emutils-V11-01-26)
|
||||
- G4VEmProcess, G4VEnergyLossProcess - minor CPU optimisation by reduction
|
||||
of number of calls for Log of kinetic energy
|
||||
## 2023-04-04 V.Ivanchenko (emutils-V11-02-02)
|
||||
- G4EmParameters - increased low-limit on maxKinEnergy parameter from
|
||||
10 MeV to 600 MeV in order to have standard ionisation and
|
||||
multiple scattering always defined for DNA physics configurations.
|
||||
|
||||
## 2023-12-01 John Allison (emutils-V11-01-25)
|
||||
## 2024-04-03 S.Okada (emutils-V11-02-01)
|
||||
- G4LowEnergyEmProcessSubType
|
||||
- add fLowEnergyTripleIonisation and fLowEnergyQuadrupleIonisation
|
||||
for implementing multiple-ionization processes in Geant4-DNA
|
||||
|
||||
## 2023-12-15 V.Ivanchenko (emutils-V11-02-00)
|
||||
- G4VEmProcess, G4VEnergyLossProcess - minor CPU optimisation by reduction
|
||||
of number of calls for Log of kinetic energy
|
||||
|
||||
## 2022-12-01 John Allison (emutils-V11-01-25)
|
||||
- G4EmParametersMessenger:
|
||||
- Fix "/process/eloss/setFluctModel" - change "eloss" to "eLoss".
|
||||
|
||||
## 2023-11-08 V.Ivanchenko (emutils-V11-01-24)
|
||||
- G4VEmModel - fixed memory leak at exit
|
||||
- G4VEmModel - fixed memory leak at exit
|
||||
|
||||
## 2023-11-07 V.Ivanchenko (emutils-V11-01-23)
|
||||
- G4EmSaturation - fixed problem #2572 (txenglish@lanl.gov)
|
||||
- G4EmSaturation - fixed problem #2572 (txenglish@lanl.gov)
|
||||
|
||||
## 2023-11-03 J.Hahnfeld (emutils-V11-01-22)
|
||||
- `G4TransportationWithMsc`: Initialize all members.
|
||||
@@ -42,8 +83,8 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
- `G4TransportationWithMsc`: Always update momentum direction.
|
||||
|
||||
## 2023-10-10 V.Ivanchenko (emutils-V11-01-18)
|
||||
- G4VEmModel - restore SetLPMFlag(..) method to allow build of CMSSW with the
|
||||
Geant4 master and G4HepEm version of CMSSW; no change of any result
|
||||
- G4VEmModel - restore SetLPMFlag(..) method to allow build of CMSSW with the
|
||||
Geant4 master and G4HepEm version of CMSSW; no change of any result
|
||||
is expected; added warning about use of obsolete method.
|
||||
|
||||
## 2023-10-06 V.Ivanchenko (emutils-V11-01-17)
|
||||
@@ -66,7 +107,7 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
- G4EmProcessSubType - new fGammaReflection = 26
|
||||
|
||||
## 2023-09-04 V.Ivanchenko (emutils-V11-01-14)
|
||||
- G4VEmModel - do not destruct G4ElementData, do not define LPM flag
|
||||
- G4VEmModel - do not destruct G4ElementData, do not define LPM flag
|
||||
|
||||
## 2023-06-16 V.Ivanchenko (emutils-V11-01-13)
|
||||
- G4LossTableManager - fixed trivial Coverity report
|
||||
@@ -119,14 +160,14 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
## 2023-02-21 V.Ivanchenko (emutils-V11-01-02)
|
||||
- G4EmExtraParameters - fixed AddPAIModel(...) method and improved comments
|
||||
- G4EmExtraParametersMessenger - fixed broadcasting
|
||||
- G4EmExtraParametersMessenger - fixed broadcasting
|
||||
|
||||
## 2023-01-10 V.Ivanchenko (emutils-V11-01-01)
|
||||
- G4EmParameters - added extra member and access method to G4LEDATA path
|
||||
allowing check environment variable for the EM data only once
|
||||
|
||||
## 2022-12-11 V.Ivanchenko (emutils-V11-01-00)
|
||||
- G4EmParameters, G4EmParametersMessenger, added parameter, UI command,
|
||||
- G4EmParameters, G4EmParametersMessenger, added parameter, UI command,
|
||||
GetSet methods - MscPositronCorrection
|
||||
|
||||
## 2022-11-23 Gabriele Cosmo (emutils-V11-00-38)
|
||||
@@ -160,11 +201,11 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
number of bins per decade
|
||||
|
||||
## 2022-08-25 V.Ivanchenko (emutils-V11-00-33)
|
||||
- G4EmExtraParameters - safe definition of StepFuction for the
|
||||
- G4EmExtraParameters - safe definition of StepFuction for the
|
||||
G4GenericIon, related to problem #2495
|
||||
|
||||
## 2022-07-08 J.Apostolakis (emutils-V11-00-32)
|
||||
- Fix in `G4TransportationWithMsc`: StartTracking now calls
|
||||
- Fix in `G4TransportationWithMsc`: StartTracking now calls
|
||||
corresponding method of G4Transportation (to initialise values
|
||||
used for propagation in field.)
|
||||
|
||||
@@ -187,7 +228,7 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
## 2022-06-07 V.Ivanchenko (emutils-V11-00-27)
|
||||
- G4VEnergyLossProcess - moved out common computations to G4EmTableUtil,
|
||||
use G4EmDataHandler, removed unused headers and methods
|
||||
use G4EmDataHandler, removed unused headers and methods
|
||||
|
||||
## 2022-05-31 V.Ivanchenko (emutils-V11-00-26)
|
||||
- G4VEmModel - fixed Coverity warning
|
||||
@@ -200,23 +241,23 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
- G4EmTableUtil - added extra methods
|
||||
- G4VEmModel, G4VEmProcess, G4VEnergyLossProcess,
|
||||
G4VMultipleScattering, G4LossTableManager - use new utiity methods,
|
||||
updated sampling of random element in compounds and random
|
||||
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)
|
||||
## 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
|
||||
- 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
|
||||
simplifing initialisation
|
||||
|
||||
## 2022-05-11 J.Hahnfeld (emutils-V11-00-20)
|
||||
- Remove dependency on `G4magneticfield`
|
||||
@@ -235,22 +276,22 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
- 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
|
||||
- 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
|
||||
- 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
|
||||
- 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
|
||||
|
||||
@@ -265,7 +306,7 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
- G4LowEnergyEmProcessSubType - add fLowEnergyScavenger (66) for DNAScavenger process
|
||||
|
||||
## 2022-03-24 V.Ivanchenko (emutils-V11-00-09)
|
||||
- G4VEnergyLossProcess - fix fluctuation model pointer if an extra
|
||||
- G4VEnergyLossProcess - fix fluctuation model pointer if an extra
|
||||
model is added on top of the default list of models
|
||||
|
||||
## 2022-03-17 V.Ivanchenko (emutils-V11-00-08)
|
||||
@@ -297,7 +338,7 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
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.
|
||||
processes at high energies.
|
||||
|
||||
## 2022-01-05 V.Ivanchenko (emutils-V11-00-02)
|
||||
- Complete internal redesign started in 2021, results are identical
|
||||
@@ -324,11 +365,11 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
10 November 21: S. Guatelli (emutils-V10-07-37)
|
||||
- changed ANSTO parameters in UI interface commands
|
||||
|
||||
|
||||
30 October 21: V.Ivanchenko (emutils-V10-07-36)
|
||||
- G4VEnergyLossProcess - exclude ion corrections only from d, t, alpha
|
||||
in order to fix #2440
|
||||
- G4ionEffectiveCharge - return back limit on effective charge
|
||||
- G4ionEffectiveCharge - return back limit on effective charge
|
||||
from 0.5 to 1 (used in previous releases)
|
||||
|
||||
25 October 21: V.Ivanchenko (emutils-V10-07-35)
|
||||
@@ -343,7 +384,7 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
12 October 21: V.Ivanchenko (emutils-V10-07-33)
|
||||
- G4ionEffectiveCharge - code clean-up
|
||||
- G4EmCorrections - do not use spline in various internal vectors,
|
||||
because correction values are small and smooth, clean-up ion
|
||||
because correction values are small and smooth, clean-up ion
|
||||
correction computations
|
||||
- G4VEnergyLossProcess - code clean-up for ions
|
||||
|
||||
@@ -356,8 +397,8 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
G4LossTableBuilder - implemented updated numbering scheme for
|
||||
secondary particle production, deprecate duplicate printout
|
||||
of processes and models, move list of EM parameters printout
|
||||
before printout on processes, code format improved
|
||||
G4EmParameters, G4EmParametersMessenger - removed obsolete
|
||||
before printout on processes, code format improved
|
||||
G4EmParameters, G4EmParametersMessenger - removed obsolete
|
||||
methods, added protection agains duplicate printout
|
||||
|
||||
23 September 21: A.Ribon (emutils-V10-07-30)
|
||||
@@ -387,19 +428,19 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
18 July 21: V.Ivanchenko (emutils-V10-07-24)
|
||||
- G4VEmFluctuationModel - changed interface - both cut value and
|
||||
max energy transfer are parameters of main methods; this
|
||||
max energy transfer are parameters of main methods; this
|
||||
is needed in order to fix problem #2390
|
||||
- G4VEnergyLossProcess, G4EmModelManager - adopted above interface
|
||||
change
|
||||
change
|
||||
|
||||
11 July 21: V.Ivanchenko (emutils-V10-07-23)
|
||||
- G4VEmProcess, G4VEnergyLossProcess, G4VMultipleScattering,
|
||||
G4LossTableBuilder, G4VEmModel, G4VMscModel, G4LossTableManager
|
||||
implement and use base material approach only if base materials
|
||||
are defined, this should bring a minor speed-up of the code and little
|
||||
- G4VEmProcess, G4VEnergyLossProcess, G4VMultipleScattering,
|
||||
G4LossTableBuilder, G4VEmModel, G4VMscModel, G4LossTableManager
|
||||
implement and use base material approach only if base materials
|
||||
are defined, this should bring a minor speed-up of the code and little
|
||||
reduction of memory; fixed problems for the case, when materials
|
||||
are changed between runs
|
||||
- G4LossTableBuilder - base material flag may be disabled
|
||||
- G4LossTableBuilder - base material flag may be disabled
|
||||
|
||||
08 June 21: V.Ivanchenko (emutils-V10-07-22)
|
||||
- G4VEmProcess, G4VEnergyLossProcess - fixed computation of cross
|
||||
@@ -408,19 +449,19 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
- G4LossTableBuilder - fixed debug printout
|
||||
|
||||
01 June 21: V.Ivanchenko (emutils-V10-07-21)
|
||||
- G4VEmProcess, G4VEnergyLossProcess - an attempt to improve
|
||||
integral option
|
||||
- G4VEmProcess, G4VEnergyLossProcess - an attempt to improve
|
||||
integral option
|
||||
|
||||
26 May 21: V.Ivanchenko (emutils-V10-07-20)
|
||||
- G4VEmProcess, G4VEnergyLossProcess, G4EmDataHandler - updated
|
||||
- G4VEmProcess, G4VEnergyLossProcess, G4EmDataHandler - updated
|
||||
method RetrievePhysicsTable(...)
|
||||
|
||||
15 May 21: V.Ivanchenko (emutils-V10-07-19)
|
||||
- G4VEmProcess, G4VEnergyLossProcess, G4EmTableType, G4EmBiasingManager,
|
||||
G4LossTableManager - updated integral approach by introduction of a
|
||||
cross section shape type and different actions depending on the type;
|
||||
addition of cache for cross section and range; removed unused methods;
|
||||
attempt to reduce number of "if" operators in the run time; integral
|
||||
cross section shape type and different actions depending on the type;
|
||||
addition of cache for cross section and range; removed unused methods;
|
||||
attempt to reduce number of "if" operators in the run time; integral
|
||||
and spline flags are set to each process individually
|
||||
- G4VMultipleScattering - fixed problem observed by CMS for specific
|
||||
Physics List
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#ifndef _G4CHEMTIMESTEPMODEL_HH
|
||||
#define _G4CHEMTIMESTEPMODEL_HH
|
||||
|
||||
enum class G4ChemTimeStepModel
|
||||
{
|
||||
Unknown = 0,
|
||||
SBS,
|
||||
IRT,
|
||||
IRT_syn,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
G4VEmModel* currentModel,
|
||||
G4ParticleChangeForLoss* pParticleChange,
|
||||
G4double& eloss,
|
||||
G4int coupleIdx,
|
||||
G4int coupleIdx,
|
||||
G4double tcut,
|
||||
G4double safety = 0.0);
|
||||
|
||||
|
||||
@@ -48,10 +48,13 @@
|
||||
#ifndef G4EmDataHandler_h
|
||||
#define G4EmDataHandler_h 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include <vector>
|
||||
#include "G4EmTableType.hh"
|
||||
#include "G4EmElementSelector.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -63,31 +66,34 @@ class G4EmDataHandler
|
||||
{
|
||||
public:
|
||||
|
||||
explicit G4EmDataHandler(size_t nTable);
|
||||
explicit G4EmDataHandler(std::size_t nTable, const G4String& nam="");
|
||||
|
||||
~G4EmDataHandler();
|
||||
|
||||
// add table
|
||||
size_t SetTable(G4PhysicsTable*);
|
||||
std::size_t SetTable(G4PhysicsTable*);
|
||||
|
||||
// update existing table
|
||||
void UpdateTable(G4PhysicsTable*, size_t idx);
|
||||
void UpdateTable(G4PhysicsTable*, std::size_t idx);
|
||||
|
||||
// save table pointer
|
||||
void SaveTable(G4PhysicsTable*, std::size_t idx);
|
||||
|
||||
// assuming that the table is already defined
|
||||
G4PhysicsTable* MakeTable(size_t idx);
|
||||
G4PhysicsTable* MakeTable(std::size_t idx);
|
||||
|
||||
// existing table may be substituted
|
||||
G4PhysicsTable* MakeTable(G4PhysicsTable*, size_t idx);
|
||||
G4PhysicsTable* MakeTable(G4PhysicsTable*, std::size_t idx);
|
||||
|
||||
// clean existing table
|
||||
void CleanTable(size_t idx);
|
||||
void CleanTable(std::size_t idx);
|
||||
|
||||
G4bool StorePhysicsTable(size_t idx,
|
||||
G4bool StorePhysicsTable(std::size_t idx,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4String& fname,
|
||||
G4bool ascii);
|
||||
|
||||
G4bool RetrievePhysicsTable(size_t idx,
|
||||
G4bool RetrievePhysicsTable(std::size_t idx,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4String& fname,
|
||||
G4bool ascii, G4bool spline);
|
||||
@@ -96,19 +102,66 @@ public:
|
||||
|
||||
const G4VEmProcess* GetMasterProcess(size_t idx) const;
|
||||
|
||||
inline const G4PhysicsTable* GetTable(size_t idx) const {
|
||||
const G4PhysicsTable* GetTable(std::size_t idx) const {
|
||||
return (idx < tLength) ? data[idx] : nullptr;
|
||||
}
|
||||
|
||||
inline G4PhysicsTable* Table(size_t idx) const {
|
||||
G4PhysicsTable* Table(std::size_t idx) const {
|
||||
return (idx < tLength) ? data[idx] : nullptr;
|
||||
}
|
||||
|
||||
inline const G4PhysicsVector* GetVector(size_t itable, size_t ivec) const
|
||||
{ return (*(data[itable]))[ivec]; }
|
||||
const G4PhysicsVector* GetVector(std::size_t itable, std::size_t ivec) const {
|
||||
return (*(data[itable]))[ivec];
|
||||
}
|
||||
|
||||
inline const std::vector<G4PhysicsTable*>& GetTables() const { return data; }
|
||||
const std::vector<G4PhysicsTable*>& GetTables() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
std::vector<G4double>* EnergyOfCrossSectionMax() const {
|
||||
return fMaxXS;
|
||||
}
|
||||
|
||||
void SetEnergyOfCrossSectionMax(std::vector<G4double>* p) {
|
||||
if (p != fMaxXS) {
|
||||
delete fMaxXS;
|
||||
fMaxXS = p;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<G4TwoPeaksXS*>* TwoPeaksXS() const {
|
||||
return fXSpeaks;
|
||||
}
|
||||
|
||||
void SetTwoPeaksXS(std::vector<G4TwoPeaksXS*>* p) {
|
||||
if (p != fXSpeaks) {
|
||||
delete fXSpeaks;
|
||||
fXSpeaks = p;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<G4EmElementSelector*>* GetElementSelectors(std::size_t i) {
|
||||
return (i < eLength) ? fElemSelectors[i] : nullptr;
|
||||
}
|
||||
|
||||
void SetElementSelectors(std::vector<G4EmElementSelector*>*, std::size_t);
|
||||
|
||||
G4CrossSectionType CrossSectionType() const {
|
||||
return fXSType;
|
||||
}
|
||||
|
||||
void SetCrossSectionType(G4CrossSectionType val) {
|
||||
fXSType = val;
|
||||
}
|
||||
|
||||
const G4String& GetName() const {
|
||||
return fName;
|
||||
}
|
||||
|
||||
void SetUseBaseParticleTable(G4bool val) {
|
||||
fUseBaseParticleTable = val;
|
||||
}
|
||||
|
||||
// hide assignment operator
|
||||
G4EmDataHandler & operator=(const G4EmDataHandler &right) = delete;
|
||||
G4EmDataHandler(const G4EmDataHandler&) = delete;
|
||||
@@ -116,8 +169,15 @@ public:
|
||||
private:
|
||||
|
||||
std::vector<G4PhysicsTable*> data;
|
||||
size_t tLength;
|
||||
std::vector<G4double>* fMaxXS;
|
||||
std::vector<G4TwoPeaksXS*>* fXSpeaks;
|
||||
std::vector<std::vector<G4EmElementSelector*>* > fElemSelectors;
|
||||
std::vector<const G4VEmProcess*> masterProcess;
|
||||
std::size_t tLength{0};
|
||||
std::size_t eLength{0};
|
||||
G4CrossSectionType fXSType{fEmNoIntegral};
|
||||
G4String fName;
|
||||
G4bool fUseBaseParticleTable{false};
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// 18 April 2024 V.Ivanchenko
|
||||
//
|
||||
// This is a singleton class to store shared EM physics data.
|
||||
// The access to data is possible only by data name.
|
||||
// Once created data pointers does not changed or deleted until the
|
||||
// end of the job, this class is responsible for destruction.
|
||||
//
|
||||
|
||||
#ifndef G4EmDataRegistry_h
|
||||
#define G4EmDataRegistry_h 1
|
||||
|
||||
#include <vector>
|
||||
#include "G4EmDataHandler.hh"
|
||||
|
||||
class G4EmDataRegistry
|
||||
{
|
||||
public:
|
||||
|
||||
static G4EmDataRegistry* Instance();
|
||||
|
||||
~G4EmDataRegistry();
|
||||
|
||||
// create or access data handler
|
||||
// nTable - number of tables in a new handler
|
||||
G4EmDataHandler* GetHandlerByName(const G4String&, std::size_t nTable);
|
||||
|
||||
// register a new handler
|
||||
void Register(G4EmDataHandler*);
|
||||
|
||||
// hide assignment operator
|
||||
G4EmDataRegistry& operator=(const G4EmDataRegistry &right) = delete;
|
||||
G4EmDataRegistry(const G4EmDataRegistry&) = delete;
|
||||
|
||||
private:
|
||||
|
||||
G4EmDataRegistry();
|
||||
|
||||
G4EmDataHandler* EmDataHandler(const G4String&);
|
||||
|
||||
static G4EmDataRegistry* instance;
|
||||
|
||||
std::vector<G4EmDataHandler*> fDataHandlers;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "globals.hh"
|
||||
#include "G4DNAModelSubType.hh"
|
||||
#include "G4EmFluoDirectory.hh"
|
||||
#include "G4ChemTimeStepModel.hh"
|
||||
#include <vector>
|
||||
|
||||
class G4EmLowEParametersMessenger;
|
||||
@@ -92,6 +93,9 @@ public:
|
||||
void SetDNAStationary(G4bool val);
|
||||
G4bool DNAStationary() const;
|
||||
|
||||
void SetChemTimeStepModel(G4ChemTimeStepModel val);
|
||||
G4ChemTimeStepModel GetChemTimeStepModel() const;
|
||||
|
||||
void SetDNAElectronMsc(G4bool val);
|
||||
G4bool DNAElectronMsc() const;
|
||||
|
||||
@@ -145,6 +149,7 @@ private:
|
||||
G4bool dnaMsc;
|
||||
|
||||
G4DNAModelSubType dnaElectronSolvation;
|
||||
G4ChemTimeStepModel fTimeStepModel;
|
||||
|
||||
G4EmFluoDirectory fFluoDirectory;
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ private:
|
||||
G4UIcmdWithAString* pixeeXsCmd;
|
||||
G4UIcmdWithAString* livCmd;
|
||||
G4UIcmdWithAString* dnaSolCmd;
|
||||
G4UIcmdWithAString* dnaChemModel;
|
||||
G4UIcmdWithAString* direFluoCmd;
|
||||
|
||||
G4UIcmdWithAString* meCmd;
|
||||
|
||||
@@ -60,8 +60,9 @@
|
||||
#include "G4EmFluoDirectory.hh"
|
||||
#include "G4EmSaturation.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4ChemTimeStepModel.hh"
|
||||
#include <vector>
|
||||
|
||||
#include <map>
|
||||
enum G4eSingleScatteringType
|
||||
{
|
||||
fWVI = 0,
|
||||
@@ -83,6 +84,12 @@ enum G4EmFluctuationType
|
||||
fUrbanFluctuation
|
||||
};
|
||||
|
||||
enum G4PositronAtRestModelType
|
||||
{
|
||||
fSimplePositronium = 0,
|
||||
fAllisonPositronium
|
||||
};
|
||||
|
||||
class G4EmParametersMessenger;
|
||||
class G4EmExtraParameters;
|
||||
class G4EmLowEParameters;
|
||||
@@ -173,6 +180,12 @@ public:
|
||||
void SetFluctuationType(G4EmFluctuationType val);
|
||||
G4EmFluctuationType FluctuationType() const;
|
||||
|
||||
void SetPositronAtRestModelType(G4PositronAtRestModelType val);
|
||||
G4PositronAtRestModelType PositronAtRestModelType() const;
|
||||
|
||||
void SetOrtoPsFraction(G4double val);
|
||||
G4double OrtoPsFraction() const;
|
||||
|
||||
void SetDNAFast(G4bool val);
|
||||
G4bool DNAFast() const;
|
||||
|
||||
@@ -327,6 +340,9 @@ public:
|
||||
void SetDNAeSolvationSubType(G4DNAModelSubType val);
|
||||
G4DNAModelSubType DNAeSolvationSubType() const;
|
||||
|
||||
//DNA chemistry model
|
||||
void SetTimeStepModel(const G4ChemTimeStepModel& model);
|
||||
G4ChemTimeStepModel GetTimeStepModel() const;
|
||||
//5d
|
||||
void SetConversionType(G4int val);
|
||||
G4int GetConversionType() const;
|
||||
@@ -469,6 +485,8 @@ private:
|
||||
G4NuclearFormfactorType nucFormfactor;
|
||||
G4eSingleScatteringType fSStype;
|
||||
G4EmFluctuationType fFluct;
|
||||
G4PositronAtRestModelType fPositronium;
|
||||
G4double fOrtoPsFraction;
|
||||
|
||||
G4String fDirLEDATA;
|
||||
};
|
||||
|
||||
@@ -142,6 +142,8 @@ private:
|
||||
G4UIcmdWithAString* nffCmd;
|
||||
G4UIcmdWithAString* ssCmd;
|
||||
G4UIcmdWithAString* fluc1Cmd;
|
||||
G4UIcmdWithAString* posiCmd;
|
||||
G4UIcmdWithADouble* ortoCmd;
|
||||
|
||||
G4UIcommand* dumpCmd;
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ class G4LossTableBuilder
|
||||
|
||||
public:
|
||||
|
||||
G4LossTableBuilder(G4bool master=true);
|
||||
explicit G4LossTableBuilder(G4bool master);
|
||||
|
||||
~G4LossTableBuilder();
|
||||
|
||||
@@ -88,18 +88,16 @@ public:
|
||||
void InitialiseBaseMaterials(const G4PhysicsTable* table=nullptr);
|
||||
|
||||
// access methods
|
||||
const std::vector<G4int>* GetCoupleIndexes() const;
|
||||
static const std::vector<G4int>* GetCoupleIndexes();
|
||||
|
||||
const std::vector<G4double>* GetDensityFactors() const;
|
||||
static const std::vector<G4double>* GetDensityFactors();
|
||||
|
||||
G4bool GetFlag(size_t idx);
|
||||
static G4bool GetFlag(std::size_t idx);
|
||||
|
||||
G4bool GetBaseMaterialFlag();
|
||||
static G4bool GetBaseMaterialFlag();
|
||||
|
||||
inline void SetSplineFlag(G4bool flag);
|
||||
|
||||
inline void SetInitialisationFlag(G4bool flag);
|
||||
|
||||
inline void SetBaseMaterialActive(G4bool flag);
|
||||
|
||||
G4LossTableBuilder & operator=(const G4LossTableBuilder &right) = delete;
|
||||
@@ -111,10 +109,10 @@ private:
|
||||
|
||||
G4bool splineFlag = true;
|
||||
G4bool isInitialized = false;
|
||||
G4bool baseMatFlag = false;
|
||||
G4bool isBaseMatActive = true;
|
||||
G4bool isInitializer = false;
|
||||
G4bool isInitializer;
|
||||
|
||||
static G4bool baseMatFlag;
|
||||
static std::vector<G4double>* theDensityFactor;
|
||||
static std::vector<G4int>* theDensityIdx;
|
||||
static std::vector<G4bool>* theFlag;
|
||||
@@ -124,19 +122,15 @@ inline void G4LossTableBuilder::SetSplineFlag(G4bool flag)
|
||||
{
|
||||
splineFlag = flag;
|
||||
}
|
||||
|
||||
/*
|
||||
inline void G4LossTableBuilder::SetInitialisationFlag(G4bool flag)
|
||||
{
|
||||
isInitialized = flag;
|
||||
}
|
||||
|
||||
*/
|
||||
inline void G4LossTableBuilder::SetBaseMaterialActive(G4bool flag)
|
||||
{
|
||||
isBaseMatActive = flag;
|
||||
if(!flag) {
|
||||
baseMatFlag = false;
|
||||
isInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo.......oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -281,7 +281,8 @@ private:
|
||||
|
||||
G4bool all_tables_are_built{false};
|
||||
G4bool startInitialisation{false};
|
||||
G4bool isMaster{true};
|
||||
G4bool resetParam{true};
|
||||
G4bool isMaster{false};
|
||||
|
||||
std::vector<G4VEnergyLossProcess*> loss_vector;
|
||||
std::vector<PD> part_vector;
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
#ifndef G4LowEnergyEmProcessSubType_h
|
||||
#define G4LowEnergyEmProcessSubType_h 1
|
||||
|
||||
enum G4LowEnergyEmProcessSubType
|
||||
{
|
||||
enum G4LowEnergyEmProcessSubType
|
||||
{
|
||||
fLowEnergyElastic = 51,
|
||||
fLowEnergyExcitation = 52,
|
||||
fLowEnergyIonisation = 53,
|
||||
@@ -57,7 +57,9 @@ enum G4LowEnergyEmProcessSubType
|
||||
fLowEnergyDoubleCap = 63,
|
||||
fLowEnergyIoniTransfer = 64,
|
||||
fLowEnergyStaticMol = 65,
|
||||
fLowEnergyScavenger = 66
|
||||
fLowEnergyScavenger = 66,
|
||||
fLowEnergyTripleIonisation = 67,
|
||||
fLowEnergyQuadrupleIonisation = 68
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -371,8 +371,6 @@ public:
|
||||
|
||||
inline void SetFluctuationFlag(G4bool val);
|
||||
|
||||
inline void SetMasterThread(G4bool val);
|
||||
|
||||
inline G4bool IsMaster() const;
|
||||
|
||||
inline void SetUseBaseMaterials(G4bool val);
|
||||
@@ -389,10 +387,12 @@ public:
|
||||
|
||||
inline void SetLocked(G4bool);
|
||||
|
||||
// obsolete method
|
||||
// obsolete methods
|
||||
[[deprecated("Use G4EmParameters::Instance()->SetLPM instead")]]
|
||||
void SetLPMFlag(G4bool);
|
||||
|
||||
void SetMasterThread(G4bool);
|
||||
|
||||
// hide assignment operator
|
||||
G4VEmModel & operator=(const G4VEmModel &right) = delete;
|
||||
G4VEmModel(const G4VEmModel&) = delete;
|
||||
@@ -707,13 +707,6 @@ inline void G4VEmModel::SetFluctuationFlag(G4bool val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline void G4VEmModel::SetMasterThread(G4bool val)
|
||||
{
|
||||
isMaster = val;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4bool G4VEmModel::IsMaster() const
|
||||
{
|
||||
return isMaster;
|
||||
|
||||
@@ -85,8 +85,6 @@ public:
|
||||
// Virtual methods to be implemented in concrete processes
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
virtual G4bool IsApplicable(const G4ParticleDefinition& p) override = 0;
|
||||
|
||||
void ProcessDescription(std::ostream& outFile) const override;
|
||||
|
||||
protected:
|
||||
@@ -197,15 +195,15 @@ protected:
|
||||
//------------------------------------------------------------------------
|
||||
// Specific methods to set, access, modify models and basic parameters
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Select model in run time
|
||||
inline G4VEmModel* SelectModel(G4double kinEnergy, size_t);
|
||||
inline G4VEmModel* SelectModel(G4double kinEnergy, std::size_t);
|
||||
|
||||
public:
|
||||
|
||||
// Select model by energy and couple index
|
||||
inline G4VEmModel* SelectModelForMaterial(G4double kinEnergy,
|
||||
size_t idxCouple) const;
|
||||
std::size_t idxCouple) const;
|
||||
|
||||
// Add model for region, smaller value of order defines which
|
||||
// model will be selected for a given energy interval
|
||||
@@ -218,7 +216,7 @@ public:
|
||||
inline G4int NumberOfModels() const;
|
||||
|
||||
// return a model from the local list
|
||||
inline G4VEmModel* EmModel(size_t index = 0) const;
|
||||
inline G4VEmModel* EmModel(std::size_t index = 0) const;
|
||||
|
||||
// Access to active model
|
||||
inline const G4VEmModel* GetCurrentModel() const;
|
||||
@@ -287,7 +285,7 @@ protected:
|
||||
|
||||
inline void SetSecondaryParticle(const G4ParticleDefinition* p);
|
||||
|
||||
inline size_t CurrentMaterialCutsCoupleIndex() const;
|
||||
inline std::size_t CurrentMaterialCutsCoupleIndex() const;
|
||||
|
||||
inline const G4MaterialCutsCouple* MaterialCutsCouple() const;
|
||||
|
||||
@@ -369,7 +367,7 @@ protected:
|
||||
private:
|
||||
|
||||
const std::vector<G4double>* theDensityFactor = nullptr;
|
||||
const std::vector<G4int>* theDensityIdx = nullptr;
|
||||
const std::vector<G4int>* theDensityIdx = nullptr;
|
||||
|
||||
// ======== parameters =========
|
||||
G4double minKinEnergy;
|
||||
@@ -404,12 +402,12 @@ protected:
|
||||
G4int augerID = _AugerElectron;
|
||||
G4int biasID = _EM;
|
||||
G4int tripletID = _TripletElectron;
|
||||
size_t currentCoupleIndex = 0;
|
||||
size_t basedCoupleIndex = 0;
|
||||
size_t coupleIdxLambda = 0;
|
||||
size_t idxLambda = 0;
|
||||
std::size_t currentCoupleIndex = 0;
|
||||
std::size_t basedCoupleIndex = 0;
|
||||
std::size_t coupleIdxLambda = 0;
|
||||
std::size_t idxLambda = 0;
|
||||
|
||||
G4bool isTheMaster = true;
|
||||
G4bool isTheMaster = false;
|
||||
G4bool baseMat = false;
|
||||
|
||||
private:
|
||||
@@ -442,7 +440,7 @@ private:
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline size_t G4VEmProcess::CurrentMaterialCutsCoupleIndex() const
|
||||
inline std::size_t G4VEmProcess::CurrentMaterialCutsCoupleIndex() const
|
||||
{
|
||||
return currentCoupleIndex;
|
||||
}
|
||||
@@ -472,15 +470,15 @@ inline G4double G4VEmProcess::GetElectronEnergyCut()
|
||||
|
||||
inline void G4VEmProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
if(couple != currentCouple) {
|
||||
if (couple != currentCouple) {
|
||||
currentCouple = couple;
|
||||
baseMaterial = currentMaterial = couple->GetMaterial();
|
||||
basedCoupleIndex = currentCoupleIndex = couple->GetIndex();
|
||||
fFactor = biasFactor;
|
||||
mfpKinEnergy = DBL_MAX;
|
||||
if(baseMat) {
|
||||
if (baseMat) {
|
||||
basedCoupleIndex = (*theDensityIdx)[currentCoupleIndex];
|
||||
if(nullptr != currentMaterial->GetBaseMaterial())
|
||||
if (nullptr != currentMaterial->GetBaseMaterial())
|
||||
baseMaterial = currentMaterial->GetBaseMaterial();
|
||||
fFactor *= (*theDensityFactor)[currentCoupleIndex];
|
||||
}
|
||||
@@ -490,7 +488,7 @@ inline void G4VEmProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline
|
||||
G4VEmModel* G4VEmProcess::SelectModel(G4double kinEnergy, size_t)
|
||||
G4VEmModel* G4VEmProcess::SelectModel(G4double kinEnergy, std::size_t)
|
||||
{
|
||||
if(1 < numberOfModels) {
|
||||
currentModel = modelManager->SelectModel(kinEnergy, currentCoupleIndex);
|
||||
@@ -503,7 +501,7 @@ G4VEmModel* G4VEmProcess::SelectModel(G4double kinEnergy, size_t)
|
||||
|
||||
inline
|
||||
G4VEmModel* G4VEmProcess::SelectModelForMaterial(G4double kinEnergy,
|
||||
size_t idxCouple) const
|
||||
std::size_t idxCouple) const
|
||||
{
|
||||
return modelManager->SelectModel(kinEnergy, idxCouple);
|
||||
}
|
||||
@@ -803,7 +801,7 @@ inline G4int G4VEmProcess::NumberOfModels() const
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline G4VEmModel* G4VEmProcess::EmModel(size_t index) const
|
||||
inline G4VEmModel* G4VEmProcess::EmModel(std::size_t index) const
|
||||
{
|
||||
return (index < emModels.size()) ? emModels[index] : nullptr;
|
||||
}
|
||||
|
||||
@@ -488,6 +488,8 @@ private:
|
||||
G4int secID = _DeltaElectron;
|
||||
G4int tripletID = _TripletElectron;
|
||||
G4int biasID = _DeltaEBelowCut;
|
||||
G4int epixeID = _ePIXE;
|
||||
G4int gpixeID = _GammaPIXE;
|
||||
G4int mainSecondaries = 1;
|
||||
|
||||
std::size_t basedCoupleIndex = 0;
|
||||
@@ -509,11 +511,11 @@ private:
|
||||
G4bool tablesAreBuilt = false;
|
||||
G4bool spline = true;
|
||||
G4bool isIon = false;
|
||||
G4bool isIonisation = true;
|
||||
G4bool isIonisation = false;
|
||||
G4bool useDeexcitation = false;
|
||||
G4bool biasFlag = false;
|
||||
G4bool weightFlag = false;
|
||||
G4bool isMaster = true;
|
||||
G4bool isMaster = false;
|
||||
G4bool baseMat = false;
|
||||
G4bool actLinLossLimit = false;
|
||||
G4bool actLossFluc = false;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
// File name: G4VPositronAtRestModel
|
||||
//
|
||||
// Author: V. Ivanchenko
|
||||
//
|
||||
// Creation date: 13 May 2024
|
||||
//
|
||||
// Class Description:
|
||||
// Abstract base class for sampling of positron annihilation at rest
|
||||
// There is a requirement to implementation of the virtual method
|
||||
// SampleSecondaries(...):
|
||||
// in the list of dynamic particles two first should be the most
|
||||
// energetic gamma from the annihilation. The number of produced
|
||||
// particles is not limited.
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef G4VPositronAtRestModel_h
|
||||
#define G4VPositronAtRestModel_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include <vector>
|
||||
|
||||
class G4Material;
|
||||
class G4DynamicParticle;
|
||||
|
||||
class G4VPositronAtRestModel
|
||||
{
|
||||
public:
|
||||
|
||||
explicit G4VPositronAtRestModel(const G4String& name) : fName(name) {};
|
||||
|
||||
virtual ~G4VPositronAtRestModel() = default;
|
||||
|
||||
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>& secParticles,
|
||||
G4double& localEnergyDeposit,
|
||||
const G4Material*) const = 0;
|
||||
|
||||
virtual void PrintGeneratorInformation() const = 0;
|
||||
|
||||
const G4String& GetName() const { return fName; };
|
||||
|
||||
G4VPositronAtRestModel& operator=
|
||||
(const G4VPositronAtRestModel& right) = delete;
|
||||
G4VPositronAtRestModel(const G4VPositronAtRestModel&) = delete;
|
||||
|
||||
private:
|
||||
|
||||
G4String fName;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,12 +8,14 @@ geant4_add_module(G4emutils
|
||||
G4AtomicShellEnumerator.hh
|
||||
G4DNAModelSubType.hh
|
||||
G4DummyModel.hh
|
||||
G4ChemTimeStepModel.hh
|
||||
G4ElectronIonPair.hh
|
||||
G4EmBiasingManager.hh
|
||||
G4EmCalculator.hh
|
||||
G4EmConfigurator.hh
|
||||
G4EmCorrections.hh
|
||||
G4EmDataHandler.hh
|
||||
G4EmDataRegistry.hh
|
||||
G4EmElementSelector.hh
|
||||
G4EmExtraParameters.hh
|
||||
G4EmExtraParametersMessenger.hh
|
||||
@@ -48,6 +50,7 @@ geant4_add_module(G4emutils
|
||||
G4VEnergyLossProcess.hh
|
||||
G4VMscModel.hh
|
||||
G4VMultipleScattering.hh
|
||||
G4VPositronAtRestModel.hh
|
||||
G4VSubCutProducer.hh
|
||||
G4ionEffectiveCharge.hh
|
||||
SOURCES
|
||||
@@ -59,6 +62,7 @@ geant4_add_module(G4emutils
|
||||
G4EmConfigurator.cc
|
||||
G4EmCorrections.cc
|
||||
G4EmDataHandler.cc
|
||||
G4EmDataRegistry.cc
|
||||
G4EmElementSelector.cc
|
||||
G4EmExtraParameters.cc
|
||||
G4EmExtraParametersMessenger.cc
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
//
|
||||
|
||||
#include "G4EmDataHandler.hh"
|
||||
#include "G4EmDataRegistry.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4PhysicsTableHelper.hh"
|
||||
@@ -49,27 +50,43 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmDataHandler::G4EmDataHandler(size_t n) : tLength(n)
|
||||
G4EmDataHandler::G4EmDataHandler(std::size_t n, const G4String& nam)
|
||||
: tLength(n), fName(nam)
|
||||
{
|
||||
data.resize(n, nullptr);
|
||||
fMaxXS = new std::vector<G4double>;
|
||||
fXSpeaks = new std::vector<G4TwoPeaksXS*>;
|
||||
G4EmDataRegistry::Instance()->Register(this);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmDataHandler::~G4EmDataHandler()
|
||||
{
|
||||
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; }
|
||||
if (!fUseBaseParticleTable) {
|
||||
for (std::size_t i=0; i<tLength; ++i) {
|
||||
CleanTable(i);
|
||||
}
|
||||
CleanTable(i);
|
||||
delete fMaxXS;
|
||||
delete fXSpeaks;
|
||||
}
|
||||
if (!fElemSelectors.empty()) {
|
||||
for (auto const & ptr : fElemSelectors) {
|
||||
if (nullptr != ptr) {
|
||||
for (auto const & p : *ptr) { delete p; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
size_t G4EmDataHandler::SetTable(G4PhysicsTable* ptr)
|
||||
std::size_t G4EmDataHandler::SetTable(G4PhysicsTable* ptr)
|
||||
{
|
||||
for (std::size_t i=0; i<tLength; ++i) {
|
||||
if (ptr == data[i]) { return i; }
|
||||
}
|
||||
data.push_back(ptr);
|
||||
++tLength;
|
||||
return tLength-1;
|
||||
@@ -77,11 +94,12 @@ size_t G4EmDataHandler::SetTable(G4PhysicsTable* ptr)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmDataHandler::UpdateTable(G4PhysicsTable* ptr, size_t idx)
|
||||
void G4EmDataHandler::UpdateTable(G4PhysicsTable* ptr, std::size_t idx)
|
||||
{
|
||||
// update table pointer but not delete previous
|
||||
if(idx < tLength) {
|
||||
if(ptr != data[idx]) { data[idx] = ptr; }
|
||||
if (idx < tLength) {
|
||||
if (ptr != data[idx]) { data[idx] = ptr; }
|
||||
data[idx] = G4PhysicsTableHelper::PreparePhysicsTable(data[idx]);
|
||||
} else {
|
||||
G4cout << "### G4EmDataHandler::UpdateTable fail for idx=" << idx
|
||||
<< " length=" << tLength << G4endl;
|
||||
@@ -90,10 +108,19 @@ void G4EmDataHandler::UpdateTable(G4PhysicsTable* ptr, size_t idx)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4PhysicsTable* G4EmDataHandler::MakeTable(size_t i)
|
||||
void G4EmDataHandler::SaveTable(G4PhysicsTable* ptr, std::size_t idx)
|
||||
{
|
||||
size_t idx = i;
|
||||
if(idx >= tLength) {
|
||||
if (idx < tLength) {
|
||||
data[idx] = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4PhysicsTable* G4EmDataHandler::MakeTable(std::size_t i)
|
||||
{
|
||||
std::size_t idx = i;
|
||||
if (idx >= tLength) {
|
||||
data.push_back(nullptr);
|
||||
idx = tLength;
|
||||
++tLength;
|
||||
@@ -104,13 +131,13 @@ G4PhysicsTable* G4EmDataHandler::MakeTable(size_t i)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4PhysicsTable* G4EmDataHandler::MakeTable(G4PhysicsTable* ptr, size_t i)
|
||||
G4PhysicsTable* G4EmDataHandler::MakeTable(G4PhysicsTable* ptr, std::size_t i)
|
||||
{
|
||||
size_t idx = i;
|
||||
std::size_t idx = i;
|
||||
// create new table only if index corresponds to the
|
||||
// position in the vector
|
||||
if(idx < tLength) {
|
||||
if(ptr != data[idx]) {
|
||||
if (idx < tLength) {
|
||||
if (ptr != data[idx]) {
|
||||
CleanTable(idx);
|
||||
data[idx] = ptr;
|
||||
}
|
||||
@@ -119,24 +146,27 @@ G4PhysicsTable* G4EmDataHandler::MakeTable(G4PhysicsTable* ptr, size_t i)
|
||||
idx = tLength;
|
||||
++tLength;
|
||||
}
|
||||
data[idx] = G4PhysicsTableHelper::PreparePhysicsTable(ptr);
|
||||
data[idx] = G4PhysicsTableHelper::PreparePhysicsTable(data[idx]);
|
||||
return data[idx];
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmDataHandler::CleanTable(size_t i)
|
||||
void G4EmDataHandler::CleanTable(std::size_t i)
|
||||
{
|
||||
if(i < tLength && nullptr != data[i]) {
|
||||
data[i]->clearAndDestroy();
|
||||
delete data[i];
|
||||
data[i] = nullptr;
|
||||
if (i < tLength && nullptr != data[i]) {
|
||||
auto ptr = data[i];
|
||||
ptr->clearAndDestroy();
|
||||
delete ptr;
|
||||
for (std::size_t j=0; j<tLength; ++j) {
|
||||
if (ptr == data[j]) { data[j] = nullptr; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4EmDataHandler::StorePhysicsTable(size_t idx,
|
||||
G4bool G4EmDataHandler::StorePhysicsTable(std::size_t idx,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4String& fname,
|
||||
G4bool ascii)
|
||||
@@ -160,7 +190,7 @@ G4bool G4EmDataHandler::StorePhysicsTable(size_t idx,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4EmDataHandler::RetrievePhysicsTable(size_t idx,
|
||||
G4bool G4EmDataHandler::RetrievePhysicsTable(std::size_t idx,
|
||||
const G4ParticleDefinition* part,
|
||||
const G4String& fname,
|
||||
G4bool ascii, G4bool spline)
|
||||
@@ -192,9 +222,25 @@ void G4EmDataHandler::SetMasterProcess(const G4VEmProcess* ptr)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
const G4VEmProcess* G4EmDataHandler::GetMasterProcess(size_t idx) const
|
||||
const G4VEmProcess* G4EmDataHandler::GetMasterProcess(std::size_t idx) const
|
||||
{
|
||||
return (idx < masterProcess.size()) ? masterProcess[idx] : nullptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmDataHandler::SetElementSelectors(std::vector<G4EmElementSelector*>* p,
|
||||
std::size_t i)
|
||||
{
|
||||
if (i < eLength) {
|
||||
if (fElemSelectors[i] != p) {
|
||||
delete fElemSelectors[i];
|
||||
}
|
||||
fElemSelectors[i] = p;
|
||||
} else {
|
||||
fElemSelectors.push_back(p);
|
||||
++eLength;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
// Author: V.Ivanchenko 18.04.2024
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "G4EmDataRegistry.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
G4EmDataRegistry* G4EmDataRegistry::instance = nullptr;
|
||||
|
||||
namespace
|
||||
{
|
||||
G4Mutex theEmData = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4EmDataRegistry* G4EmDataRegistry::Instance()
|
||||
{
|
||||
if (instance == nullptr) {
|
||||
static G4EmDataRegistry manager;
|
||||
instance = &manager;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmDataRegistry::G4EmDataRegistry()
|
||||
{
|
||||
fDataHandlers.reserve(50);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmDataRegistry::~G4EmDataRegistry()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmDataHandler*
|
||||
G4EmDataRegistry::GetHandlerByName(const G4String& nam, std::size_t n)
|
||||
{
|
||||
// handler already exist
|
||||
G4EmDataHandler* ptr = EmDataHandler(nam);
|
||||
if (nullptr != ptr) { return ptr; }
|
||||
|
||||
// create a new handler
|
||||
G4AutoLock l(&theEmData);
|
||||
ptr = EmDataHandler(nam);
|
||||
if (nullptr == ptr) {
|
||||
ptr = new G4EmDataHandler(n, nam);
|
||||
}
|
||||
l.unlock();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EmDataRegistry::Register(G4EmDataHandler* ptr)
|
||||
{
|
||||
if (nullptr == ptr) { return; }
|
||||
for (auto const & p : fDataHandlers) {
|
||||
if (p == ptr) { return; }
|
||||
}
|
||||
fDataHandlers.push_back(ptr);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EmDataHandler* G4EmDataRegistry::EmDataHandler(const G4String& nam)
|
||||
{
|
||||
G4EmDataHandler* ptr = nullptr;
|
||||
if (fDataHandlers.empty()) { return ptr; }
|
||||
for (auto const & p : fDataHandlers) {
|
||||
if (p->GetName() == nam) {
|
||||
ptr = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -76,6 +76,7 @@ void G4EmLowEParameters::Initialise()
|
||||
dnaStationary = false;
|
||||
dnaMsc = false;
|
||||
dnaElectronSolvation = fMeesungnoen2002eSolvation;
|
||||
fTimeStepModel = G4ChemTimeStepModel::Unknown;
|
||||
|
||||
fFluoDirectory = fluoDefault;
|
||||
namePIXE = "Empirical";
|
||||
@@ -195,6 +196,16 @@ G4DNAModelSubType G4EmLowEParameters::DNAeSolvationSubType() const
|
||||
return dnaElectronSolvation;
|
||||
}
|
||||
|
||||
void G4EmLowEParameters::SetChemTimeStepModel(G4ChemTimeStepModel val)
|
||||
{
|
||||
fTimeStepModel = val;
|
||||
}
|
||||
|
||||
G4ChemTimeStepModel G4EmLowEParameters::GetChemTimeStepModel() const
|
||||
{
|
||||
return fTimeStepModel;
|
||||
}
|
||||
|
||||
void G4EmLowEParameters::SetPIXECrossSectionModel(const G4String& sss)
|
||||
{
|
||||
namePIXE = sss;
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
#include "G4UIcmdWith3VectorAndUnit.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4EmLowEParameters.hh"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -164,6 +163,13 @@ G4EmLowEParametersMessenger::G4EmLowEParametersMessenger(G4EmLowEParameters* ptr
|
||||
dnaSolCmd->AvailableForStates(G4State_PreInit);
|
||||
dnaSolCmd->SetToBeBroadcasted(false);
|
||||
|
||||
dnaChemModel = new G4UIcmdWithAString("/process/chem/TimeStepModel",this);
|
||||
dnaChemModel->SetGuidance("The name of DNA chemistry time step model");
|
||||
dnaChemModel->SetParameterName("TimeStepModel",true);
|
||||
dnaChemModel->SetCandidates("SBS IRT IRT_syn");
|
||||
dnaChemModel->AvailableForStates(G4State_PreInit);
|
||||
dnaChemModel->SetToBeBroadcasted(false);
|
||||
|
||||
meCmd = new G4UIcmdWithAString("/process/em/AddMicroElecRegion",this);
|
||||
meCmd->SetGuidance("Activate MicroElec model in the G4Region");
|
||||
meCmd->SetParameterName("MicroElec",true);
|
||||
@@ -225,6 +231,7 @@ G4EmLowEParametersMessenger::~G4EmLowEParametersMessenger()
|
||||
delete pixeeXsCmd;
|
||||
delete livCmd;
|
||||
delete dnaSolCmd;
|
||||
delete dnaChemModel;
|
||||
delete direFluoCmd;
|
||||
delete meCmd;
|
||||
delete dnaCmd;
|
||||
@@ -278,6 +285,16 @@ void G4EmLowEParametersMessenger::SetNewValue(G4UIcommand* command,
|
||||
ttt = fKreipl2009eSolvation;
|
||||
}
|
||||
theParameters->SetDNAeSolvationSubType(ttt);
|
||||
} else if (command == dnaChemModel) {
|
||||
G4ChemTimeStepModel stepM = G4ChemTimeStepModel::Unknown;
|
||||
if(newValue == "IRT") {
|
||||
stepM = G4ChemTimeStepModel::IRT;
|
||||
} else if(newValue == "SBS") {
|
||||
stepM = G4ChemTimeStepModel::SBS;
|
||||
} else if (newValue == "IRT_syn") {
|
||||
stepM = G4ChemTimeStepModel::IRT_syn;
|
||||
}
|
||||
theParameters->SetChemTimeStepModel(stepM);
|
||||
} else if (command == direFluoCmd) {
|
||||
G4EmFluoDirectory ttt = fluoDefault;
|
||||
if(newValue == "Bearden") { ttt = fluoBearden; }
|
||||
|
||||
@@ -160,6 +160,7 @@ void G4EmParameters::Initialise()
|
||||
safetyFactor = 0.6;
|
||||
lambdaLimit = 1.0*CLHEP::mm;
|
||||
factorScreen = 1.0;
|
||||
fOrtoPsFraction = 0.0375; // 0.75 * 0.05
|
||||
|
||||
nbinsPerDecade = 7;
|
||||
verbose = 1;
|
||||
@@ -174,7 +175,14 @@ void G4EmParameters::Initialise()
|
||||
fSStype = fWVI;
|
||||
fFluct = fUniversalFluctuation;
|
||||
|
||||
fDirLEDATA = G4String(G4FindDataDir("G4LEDATA"));
|
||||
const char* data_dir = G4FindDataDir("G4LEDATA");
|
||||
if (nullptr != data_dir) {
|
||||
fDirLEDATA = G4String(data_dir);
|
||||
}
|
||||
else {
|
||||
G4Exception("G4EmParameters::Initialise()", "em0003", JustWarning,
|
||||
"G4LEDATA data directory was not found.");
|
||||
}
|
||||
}
|
||||
|
||||
void G4EmParameters::SetLossFluctuations(G4bool val)
|
||||
@@ -582,13 +590,13 @@ G4double G4EmParameters::MinKinEnergy() const
|
||||
void G4EmParameters::SetMaxEnergy(G4double val)
|
||||
{
|
||||
if(IsLocked()) { return; }
|
||||
if(val > std::max(minKinEnergy,9.99*CLHEP::MeV) && val < 1.e+7*CLHEP::TeV) {
|
||||
if(val > std::max(minKinEnergy,599.9*CLHEP::MeV) && val < 1.e+7*CLHEP::TeV) {
|
||||
maxKinEnergy = val;
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Value of MaxKinEnergy is out of range: "
|
||||
<< val/CLHEP::GeV
|
||||
<< " GeV is ignored; allowed range 10 MeV - 1.e+7 TeV";
|
||||
<< " GeV is ignored; allowed range 600 MeV - 1.e+7 TeV";
|
||||
PrintWarning(ed);
|
||||
}
|
||||
}
|
||||
@@ -1032,6 +1040,29 @@ G4EmFluctuationType G4EmParameters::FluctuationType() const
|
||||
return fFluct;
|
||||
}
|
||||
|
||||
void G4EmParameters::SetPositronAtRestModelType(G4PositronAtRestModelType val)
|
||||
{
|
||||
if(IsLocked()) { return; }
|
||||
fPositronium = val;
|
||||
}
|
||||
|
||||
G4PositronAtRestModelType G4EmParameters::PositronAtRestModelType() const
|
||||
{
|
||||
return fPositronium;
|
||||
}
|
||||
|
||||
void G4EmParameters::SetOrtoPsFraction(G4double val)
|
||||
{
|
||||
if(IsLocked()) { return; }
|
||||
fOrtoPsFraction = val;
|
||||
}
|
||||
|
||||
G4double G4EmParameters::OrtoPsFraction() const
|
||||
{
|
||||
return fOrtoPsFraction;
|
||||
}
|
||||
|
||||
|
||||
void G4EmParameters::SetMscStepLimitType(G4MscStepLimitType val)
|
||||
{
|
||||
if(IsLocked()) { return; }
|
||||
@@ -1453,6 +1484,13 @@ void G4EmParameters::StreamInfo(std::ostream& os) const
|
||||
<< fCParameters->DNAElectronMsc() << "\n";
|
||||
os << "Use DNA e- solvation model type "
|
||||
<< fCParameters->DNAeSolvationSubType() << "\n";
|
||||
auto chemModel = fCParameters->GetChemTimeStepModel();
|
||||
if(fCParameters->GetChemTimeStepModel() != G4ChemTimeStepModel::Unknown)
|
||||
{
|
||||
std::vector<G4String> ChemModel{"Unknown","SBS","IRT","IRT_syn"};
|
||||
os << "Use DNA Chemistry model "
|
||||
<< ChemModel.at((std::size_t)chemModel) << "\n";
|
||||
}
|
||||
os << "=======================================================================" << G4endl;
|
||||
}
|
||||
os.precision(prec);
|
||||
@@ -1485,4 +1523,14 @@ G4bool G4EmParameters::IsLocked() const
|
||||
fStateManager->GetCurrentState() != G4State_Idle));
|
||||
}
|
||||
|
||||
|
||||
void G4EmParameters::SetTimeStepModel(const G4ChemTimeStepModel& model)
|
||||
{
|
||||
fCParameters-> SetChemTimeStepModel(model);
|
||||
}
|
||||
|
||||
G4ChemTimeStepModel G4EmParameters::GetTimeStepModel() const
|
||||
{
|
||||
return fCParameters->GetChemTimeStepModel();
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
@@ -438,6 +438,20 @@ G4EmParametersMessenger::G4EmParametersMessenger(G4EmParameters* ptr)
|
||||
fluc1Cmd->AvailableForStates(G4State_PreInit);
|
||||
fluc1Cmd->SetToBeBroadcasted(false);
|
||||
|
||||
posiCmd = new G4UIcmdWithAString("/process/em/setPositronAtRestModel",this);
|
||||
posiCmd->SetGuidance("Define model of positron annihilation at rest");
|
||||
posiCmd->SetParameterName("Posi",true);
|
||||
posiCmd->SetCandidates("Simple Allison");
|
||||
posiCmd->AvailableForStates(G4State_PreInit);
|
||||
posiCmd->SetToBeBroadcasted(false);
|
||||
|
||||
ortoCmd = new G4UIcmdWithADouble("/process/em/setOrtoPositronFraction",this);
|
||||
ortoCmd->SetGuidance("Define model of positron annihilation at rest");
|
||||
ortoCmd->SetParameterName("frac",false);
|
||||
ortoCmd->SetRange("frac >= 0.0 && frac <= 1.0");
|
||||
ortoCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
ortoCmd->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");
|
||||
@@ -526,6 +540,8 @@ G4EmParametersMessenger::~G4EmParametersMessenger()
|
||||
delete nffCmd;
|
||||
delete ssCmd;
|
||||
delete fluc1Cmd;
|
||||
delete posiCmd;
|
||||
delete ortoCmd;
|
||||
|
||||
delete dumpCmd;
|
||||
}
|
||||
@@ -715,6 +731,12 @@ void G4EmParametersMessenger::SetNewValue(G4UIcommand* command,
|
||||
if(newValue == "Dummy") { x = fDummyFluctuation; }
|
||||
else if(newValue == "Urban") { x = fUrbanFluctuation; }
|
||||
theParameters->SetFluctuationType(x);
|
||||
} else if (command == posiCmd) {
|
||||
G4PositronAtRestModelType x = fSimplePositronium;
|
||||
if(newValue == "Allison") { x = fAllisonPositronium; }
|
||||
theParameters->SetPositronAtRestModelType(x);
|
||||
} else if ( command==ortoCmd ) {
|
||||
theParameters->SetOrtoPsFraction(ortoCmd->GetNewDoubleValue(newValue));
|
||||
} else if ( command==tripletCmd ) {
|
||||
theParameters->SetConversionType(tripletCmd->GetNewIntValue(newValue));
|
||||
} else if ( command==onIsolatedCmd ) {
|
||||
|
||||
@@ -66,7 +66,6 @@ G4EmTableUtil::PrepareEmProcess(G4VEmProcess* proc,
|
||||
G4VEmModel* mod = modelManager->GetModel(i);
|
||||
if(nullptr == mod) { continue; }
|
||||
mod->SetPolarAngleLimit(plimit);
|
||||
mod->SetMasterThread(master);
|
||||
if(mod->HighEnergyLimit() > maxKinEnergy) {
|
||||
mod->SetHighEnergyLimit(maxKinEnergy);
|
||||
}
|
||||
@@ -248,7 +247,7 @@ void G4EmTableUtil::BuildLambdaTable(G4VEmProcess* proc,
|
||||
G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
|
||||
}
|
||||
// build high energy table
|
||||
if(nullptr != theLambdaTablePrim) {
|
||||
if(nullptr != theLambdaTablePrim && minKinEnergyPrim < maxKinEnergy) {
|
||||
delete (*theLambdaTablePrim)[i];
|
||||
|
||||
// start not from zero and always use spline
|
||||
@@ -352,7 +351,7 @@ G4EmTableUtil::CheckIon(G4VEnergyLossProcess* proc,
|
||||
if(part->GetParticleType() == "nucleus") {
|
||||
G4String pname = part->GetParticleName();
|
||||
if(pname != "deuteron" && pname != "triton" &&
|
||||
pname != "alpha+" && pname != "alpha") {
|
||||
pname != "He3" && pname != "alpha+" && pname != "alpha") {
|
||||
|
||||
const G4ParticleDefinition* theGIon = G4GenericIon::GenericIon();
|
||||
isIon = true;
|
||||
@@ -383,7 +382,7 @@ void G4EmTableUtil::UpdateModels(G4VEnergyLossProcess* proc,
|
||||
const G4int nModels,
|
||||
G4int& secID, G4int& biasID,
|
||||
G4int& mainSec, const G4bool baseMat,
|
||||
const G4bool isMaster, const G4bool useAGen)
|
||||
const G4bool, const G4bool useAGen)
|
||||
{
|
||||
// defined ID of secondary particles
|
||||
G4int stype = proc->GetProcessSubType();
|
||||
@@ -398,7 +397,6 @@ void G4EmTableUtil::UpdateModels(G4VEnergyLossProcess* proc,
|
||||
// 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);
|
||||
@@ -546,7 +544,6 @@ void G4EmTableUtil::PrepareMscProcess(G4VMultipleScattering* proc,
|
||||
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);
|
||||
@@ -566,15 +563,37 @@ void G4EmTableUtil::BuildMscProcess(G4VMultipleScattering* proc,
|
||||
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 (firstPart == &part) {
|
||||
G4LossTableBuilder* bld = G4LossTableManager::Instance()->GetTableBuilder();
|
||||
G4bool baseMat = bld->GetBaseMaterialFlag();
|
||||
if (master) {
|
||||
for (G4int i=0; i<nModels; ++i) {
|
||||
G4VMscModel* msc = proc->GetModelByIndex(i);
|
||||
msc->SetUseBaseMaterials(baseMat);
|
||||
// table is always built for low mass particles
|
||||
if (part.GetParticleName() != "GenericIon" &&
|
||||
(part.GetPDGMass() < CLHEP::GeV || msc->ForceBuildTableFlag())) {
|
||||
G4double emin =
|
||||
std::max(msc->LowEnergyLimit(), msc->LowEnergyActivationLimit());
|
||||
G4double emax =
|
||||
std::min(msc->HighEnergyLimit(), msc->HighEnergyActivationLimit());
|
||||
emin = std::max(emin, param->MinKinEnergy());
|
||||
emax = std::min(emax, param->MaxKinEnergy());
|
||||
if (emin < emax) {
|
||||
auto table = bld->BuildTableForModel(msc->GetCrossSectionTable(),
|
||||
msc, &part, emin, emax, true);
|
||||
msc->SetCrossSectionTable(table, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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()) {
|
||||
@@ -671,7 +690,7 @@ G4bool G4EmTableUtil::RetrieveTable(G4VProcess* ptr,
|
||||
{
|
||||
G4bool res = true;
|
||||
if (nullptr == aTable) { return res; }
|
||||
if (0 < verb) {
|
||||
if (1 < verb) {
|
||||
G4cout << tname << " table for " << part->GetParticleName()
|
||||
<< " will be retrieved " << G4endl;
|
||||
}
|
||||
@@ -685,7 +704,7 @@ G4bool G4EmTableUtil::RetrieveTable(G4VProcess* ptr,
|
||||
}
|
||||
if (0 < verb) {
|
||||
G4cout << tname << " table for " << part->GetParticleName()
|
||||
<< " is Retrieved from <" << name << ">"
|
||||
<< " is retrieved from <" << name << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
|
||||
G4bool G4LossTableBuilder::baseMatFlag = false;
|
||||
std::vector<G4double>* G4LossTableBuilder::theDensityFactor = nullptr;
|
||||
std::vector<G4int>* G4LossTableBuilder::theDensityIdx = nullptr;
|
||||
std::vector<G4bool>* G4LossTableBuilder::theFlag = nullptr;
|
||||
@@ -73,19 +74,13 @@ std::vector<G4bool>* G4LossTableBuilder::theFlag = nullptr;
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LossTableBuilder::G4LossTableBuilder(G4bool master)
|
||||
: isInitializer(master)
|
||||
{
|
||||
theParameters = G4EmParameters::Instance();
|
||||
if (nullptr == theFlag) {
|
||||
if (!master) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "The table builder is instantiated in a worker thread ";
|
||||
G4Exception("G4LossTableBuilder::G4LossTableBuilder ", "em0001",
|
||||
JustWarning, ed);
|
||||
}
|
||||
theDensityFactor = new std::vector<G4double>;
|
||||
theDensityIdx = new std::vector<G4int>;
|
||||
theFlag = new std::vector<G4bool>;
|
||||
isInitializer = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,14 +100,14 @@ G4LossTableBuilder::~G4LossTableBuilder()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const std::vector<G4int>* G4LossTableBuilder::GetCoupleIndexes() const
|
||||
const std::vector<G4int>* G4LossTableBuilder::GetCoupleIndexes()
|
||||
{
|
||||
return theDensityIdx;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const std::vector<G4double>* G4LossTableBuilder::GetDensityFactors() const
|
||||
const std::vector<G4double>* G4LossTableBuilder::GetDensityFactors()
|
||||
{
|
||||
return theDensityFactor;
|
||||
}
|
||||
@@ -121,7 +116,6 @@ const std::vector<G4double>* G4LossTableBuilder::GetDensityFactors() const
|
||||
|
||||
G4bool G4LossTableBuilder::GetFlag(std::size_t idx)
|
||||
{
|
||||
if (theFlag->empty()) { InitialiseBaseMaterials(); }
|
||||
return (idx < theFlag->size()) ? (*theFlag)[idx] : false;
|
||||
}
|
||||
|
||||
@@ -129,7 +123,6 @@ G4bool G4LossTableBuilder::GetFlag(std::size_t idx)
|
||||
|
||||
G4bool G4LossTableBuilder::GetBaseMaterialFlag()
|
||||
{
|
||||
if (theFlag->empty()) { InitialiseBaseMaterials(); }
|
||||
return baseMatFlag;
|
||||
}
|
||||
|
||||
@@ -150,6 +143,7 @@ G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
|
||||
|
||||
for (std::size_t i=0; i<nCouples; ++i) {
|
||||
auto pv0 = static_cast<G4PhysicsLogVector*>((*(list[0]))[i]);
|
||||
//if (0 == i) G4cout << i << ". pv0=" << pv0 << " t:" << list[0] << G4endl;
|
||||
if(pv0 == nullptr) { continue; }
|
||||
std::size_t npoints = pv0->GetVectorLength();
|
||||
auto pv = new G4PhysicsLogVector(*pv0);
|
||||
@@ -157,6 +151,7 @@ G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
|
||||
G4double dedx = 0.0;
|
||||
for (std::size_t k=0; k<n_processes; ++k) {
|
||||
const G4PhysicsVector* pv1 = (*(list[k]))[i];
|
||||
//if (0 == i) G4cout << " " << k << ". pv1=" << pv1 << " t:" << list[k] << G4endl;
|
||||
dedx += (*pv1)[j];
|
||||
}
|
||||
pv->PutValue(j, dedx);
|
||||
@@ -311,64 +306,49 @@ void G4LossTableBuilder::InitialiseBaseMaterials(const G4PhysicsTable* table)
|
||||
|
||||
// reserve memory
|
||||
theFlag->resize(nCouples, true);
|
||||
if(nullptr == table) { return; }
|
||||
|
||||
if(baseMatFlag) {
|
||||
theDensityFactor->resize(nCouples,1.0);
|
||||
theDensityIdx->resize(nCouples);
|
||||
}
|
||||
theDensityFactor->resize(nCouples,1.0);
|
||||
theDensityIdx->resize(nCouples, 0);
|
||||
|
||||
// define default flag and index of used material cut couple
|
||||
for(G4int i=0; i<(G4int)nCouples; ++i) {
|
||||
(*theFlag)[i] = table->GetFlag(i);
|
||||
if(baseMatFlag) { (*theDensityIdx)[i] = i; }
|
||||
for (G4int i=0; i<(G4int)nCouples; ++i) {
|
||||
(*theFlag)[i] = (nullptr == table) ? true : table->GetFlag(i);
|
||||
(*theDensityIdx)[i] = i;
|
||||
}
|
||||
isInitialized = true;
|
||||
if(baseMatFlag) {
|
||||
// use base materials
|
||||
for(G4int i=0; i<(G4int)nCouples; ++i) {
|
||||
// base material is needed only for a couple which is not
|
||||
// initialised and for which tables will be computed
|
||||
auto couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
auto pcuts = couple->GetProductionCuts();
|
||||
auto mat = couple->GetMaterial();
|
||||
auto bmat = mat->GetBaseMaterial();
|
||||
if (!baseMatFlag) { return; }
|
||||
|
||||
// base material exists - find it and check if it can be reused
|
||||
if(nullptr != bmat) {
|
||||
for(G4int j=0; j<(G4int)nCouples; ++j) {
|
||||
if(j == i) { continue; }
|
||||
auto bcouple = theCoupleTable->GetMaterialCutsCouple(j);
|
||||
// use base materials
|
||||
for (G4int i=0; i<(G4int)nCouples; ++i) {
|
||||
// base material is needed only for a couple which is not
|
||||
// initialised and for which tables will be computed
|
||||
auto couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
auto pcuts = couple->GetProductionCuts();
|
||||
auto mat = couple->GetMaterial();
|
||||
auto bmat = mat->GetBaseMaterial();
|
||||
|
||||
if(bcouple->GetMaterial() == bmat &&
|
||||
bcouple->GetProductionCuts() == pcuts) {
|
||||
// base material exists - find it and check if it can be reused
|
||||
if(nullptr != bmat) {
|
||||
for(G4int j=0; j<(G4int)nCouples; ++j) {
|
||||
if(j == i) { continue; }
|
||||
auto bcouple = theCoupleTable->GetMaterialCutsCouple(j);
|
||||
|
||||
// based couple exist in the same region
|
||||
(*theDensityFactor)[i] = mat->GetDensity()/bmat->GetDensity();
|
||||
(*theDensityIdx)[i] = j;
|
||||
(*theFlag)[i] = false;
|
||||
if(bcouple->GetMaterial() == bmat &&
|
||||
bcouple->GetProductionCuts() == pcuts) {
|
||||
|
||||
// ensure that there will no double initialisation
|
||||
(*theDensityFactor)[j] = 1.0;
|
||||
(*theDensityIdx)[j] = j;
|
||||
(*theFlag)[j] = true;
|
||||
break;
|
||||
}
|
||||
// based couple exist in the same region
|
||||
(*theDensityFactor)[i] = mat->GetDensity()/bmat->GetDensity();
|
||||
(*theDensityIdx)[i] = j;
|
||||
(*theFlag)[i] = false;
|
||||
|
||||
// ensure that there will no double initialisation
|
||||
(*theDensityFactor)[j] = 1.0;
|
||||
(*theDensityIdx)[j] = j;
|
||||
(*theFlag)[j] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
G4cout << "### G4LossTableBuilder::InitialiseBaseMaterials: flag="
|
||||
<< baseMatFlag << G4endl;
|
||||
for(std::size_t i=0; i<nCouples; ++i) {
|
||||
G4cout << "CoupleIdx=" << i << " Flag= " << (*theFlag)[i] << " "
|
||||
<< theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial()->GetName()
|
||||
<< " TableFlag= " << table->GetFlag(i)
|
||||
<< " " << (*table)[i]
|
||||
<< G4endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -382,13 +362,12 @@ G4LossTableBuilder::BuildTableForModel(G4PhysicsTable* aTable,
|
||||
{
|
||||
// check input
|
||||
G4PhysicsTable* table = G4PhysicsTableHelper::PreparePhysicsTable(aTable);
|
||||
if(nullptr == table) { return table; }
|
||||
if(emin >= emax) {
|
||||
table->clearAndDestroy();
|
||||
delete table;
|
||||
table = nullptr;
|
||||
return table;
|
||||
if (nullptr == table) { return table; }
|
||||
if (aTable != nullptr && aTable != table) {
|
||||
aTable->clearAndDestroy();
|
||||
delete aTable;
|
||||
}
|
||||
|
||||
InitialiseBaseMaterials(table);
|
||||
G4int nbins = theParameters->NumberOfBinsPerDecade();
|
||||
|
||||
@@ -396,21 +375,25 @@ G4LossTableBuilder::BuildTableForModel(G4PhysicsTable* aTable,
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
std::size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
/*
|
||||
G4cout << " G4LossTableBuilder::BuildTableForModel Ncouple=" << numOfCouples
|
||||
<< " isMaster=" << isInitializer << " model:" << model->GetName()
|
||||
<< " " << part->GetParticleName() << G4endl;
|
||||
*/
|
||||
G4PhysicsLogVector* aVector = nullptr;
|
||||
|
||||
for(G4int i=0; i<(G4int)numOfCouples; ++i) {
|
||||
if ((*theFlag)[i]) {
|
||||
//G4cout << i << ". " << (*theFlag)[i] << " " << table->GetFlag(i) << G4endl;
|
||||
if (table->GetFlag(i)) {
|
||||
|
||||
// create physics vector and fill it
|
||||
auto couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
delete (*table)[i];
|
||||
|
||||
// if start from zero then change the scale
|
||||
|
||||
const G4Material* mat = couple->GetMaterial();
|
||||
|
||||
G4double tmin = std::max(emin,model->MinPrimaryEnergy(mat,part));
|
||||
G4double tmin = std::max(emin, model->MinPrimaryEnergy(mat,part));
|
||||
if(0.0 >= tmin) { tmin = CLHEP::eV; }
|
||||
G4int n = nbins;
|
||||
|
||||
@@ -424,10 +407,12 @@ G4LossTableBuilder::BuildTableForModel(G4PhysicsTable* aTable,
|
||||
|
||||
if(nullptr != aVector) {
|
||||
//G4cout << part->GetParticleName() << " in " << mat->GetName()
|
||||
// << " tmin= " << tmin << G4endl;
|
||||
// << " emin= " << tmin << " emax=" << emax << " n=" << n << G4endl;
|
||||
for(G4int j=0; j<=n; ++j) {
|
||||
aVector->PutValue(j, model->Value(couple, part,
|
||||
aVector->Energy(j)));
|
||||
G4double e = aVector->Energy(j);
|
||||
G4double y = model->Value(couple, part, e);
|
||||
//G4cout << " " << j << ") E=" << e << " y=" << y << G4endl;
|
||||
aVector->PutValue(j, y);
|
||||
}
|
||||
if(spline) { aVector->FillSecondDerivatives(); }
|
||||
}
|
||||
|
||||
@@ -71,7 +71,6 @@
|
||||
#include "G4EmTableType.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4Threading.hh"
|
||||
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Positron.hh"
|
||||
@@ -79,9 +78,11 @@
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4MuonPlus.hh"
|
||||
#include "G4MuonMinus.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
static std::once_flag applyOnce;
|
||||
G4ThreadLocal G4LossTableManager* G4LossTableManager::instance = nullptr;
|
||||
|
||||
G4LossTableManager* G4LossTableManager::Instance()
|
||||
@@ -132,13 +133,12 @@ G4LossTableManager::~G4LossTableManager()
|
||||
G4LossTableManager::G4LossTableManager()
|
||||
{
|
||||
theParameters = G4EmParameters::Instance();
|
||||
verbose = theParameters->Verbose();
|
||||
theElectron = G4Electron::Electron();
|
||||
theGenericIon= nullptr;
|
||||
if(G4Threading::IsWorkerThread()) {
|
||||
verbose = theParameters->WorkerVerbose();
|
||||
isMaster = false;
|
||||
}
|
||||
|
||||
// only one thread is the master
|
||||
std::call_once(applyOnce, [this]() { isMaster = true; });
|
||||
verbose = isMaster ? theParameters->Verbose() : theParameters->WorkerVerbose();
|
||||
|
||||
tableBuilder = new G4LossTableBuilder(isMaster);
|
||||
emCorrections = new G4EmCorrections(verbose);
|
||||
|
||||
@@ -182,7 +182,7 @@ void G4LossTableManager::Clear()
|
||||
|
||||
void G4LossTableManager::Register(G4VEnergyLossProcess* p)
|
||||
{
|
||||
if(!p) { return; }
|
||||
if (nullptr == p) { return; }
|
||||
for (G4int i=0; i<n_loss; ++i) {
|
||||
if(loss_vector[i] == p) { return; }
|
||||
}
|
||||
@@ -206,13 +206,20 @@ void G4LossTableManager::Register(G4VEnergyLossProcess* p)
|
||||
|
||||
void G4LossTableManager::ResetParameters()
|
||||
{
|
||||
// initialisation once per run
|
||||
if (!resetParam) { return; }
|
||||
resetParam = false;
|
||||
startInitialisation = true;
|
||||
verbose = theParameters->Verbose();
|
||||
if(!isMaster) {
|
||||
verbose = theParameters->WorkerVerbose();
|
||||
} else {
|
||||
if(verbose > 0) { theParameters->Dump(); }
|
||||
}
|
||||
tableBuilder->SetInitialisationFlag(false);
|
||||
|
||||
tableBuilder->InitialiseBaseMaterials();
|
||||
if (nullptr != nielCalculator) { nielCalculator->Initialise(); }
|
||||
|
||||
emCorrections->SetVerbose(verbose);
|
||||
if(nullptr != emConfigurator) { emConfigurator->SetVerbose(verbose); };
|
||||
if(nullptr != emElectronIonPair) { emElectronIonPair->SetVerbose(verbose); };
|
||||
@@ -220,13 +227,19 @@ void G4LossTableManager::ResetParameters()
|
||||
atomDeexcitation->SetVerboseLevel(verbose);
|
||||
atomDeexcitation->InitialiseAtomicDeexcitation();
|
||||
}
|
||||
if (1 < verbose) {
|
||||
G4cout << "====== G4LossTableManager::ResetParameters "
|
||||
<< " Nloss=" << loss_vector.size()
|
||||
<< " run=" << run << " master=" << isMaster
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::DeRegister(G4VEnergyLossProcess* p)
|
||||
{
|
||||
if(!p) { return; }
|
||||
if (nullptr == p) { return; }
|
||||
for (G4int i=0; i<n_loss; ++i) {
|
||||
if(loss_vector[i] == p) {
|
||||
loss_vector[i] = nullptr;
|
||||
@@ -239,7 +252,7 @@ void G4LossTableManager::DeRegister(G4VEnergyLossProcess* p)
|
||||
|
||||
void G4LossTableManager::Register(G4VMultipleScattering* p)
|
||||
{
|
||||
if(!p) { return; }
|
||||
if (nullptr == p) { return; }
|
||||
std::size_t n = msc_vector.size();
|
||||
for (std::size_t i=0; i<n; ++i) {
|
||||
if(msc_vector[i] == p) { return; }
|
||||
@@ -255,7 +268,7 @@ void G4LossTableManager::Register(G4VMultipleScattering* p)
|
||||
|
||||
void G4LossTableManager::DeRegister(G4VMultipleScattering* p)
|
||||
{
|
||||
if(!p) { return; }
|
||||
if (nullptr == p) { return; }
|
||||
std::size_t msc = msc_vector.size();
|
||||
for (std::size_t i=0; i<msc; ++i) {
|
||||
if(msc_vector[i] == p) {
|
||||
@@ -269,7 +282,7 @@ void G4LossTableManager::DeRegister(G4VMultipleScattering* p)
|
||||
|
||||
void G4LossTableManager::Register(G4VEmProcess* p)
|
||||
{
|
||||
if(!p) { return; }
|
||||
if (nullptr == p) { return; }
|
||||
std::size_t n = emp_vector.size();
|
||||
for (std::size_t i=0; i<n; ++i) {
|
||||
if(emp_vector[i] == p) { return; }
|
||||
@@ -285,7 +298,7 @@ void G4LossTableManager::Register(G4VEmProcess* p)
|
||||
|
||||
void G4LossTableManager::DeRegister(G4VEmProcess* p)
|
||||
{
|
||||
if(!p) { return; }
|
||||
if (nullptr == p) { return; }
|
||||
std::size_t emp = emp_vector.size();
|
||||
for (std::size_t i=0; i<emp; ++i) {
|
||||
if(emp_vector[i] == p) {
|
||||
@@ -299,7 +312,7 @@ void G4LossTableManager::DeRegister(G4VEmProcess* p)
|
||||
|
||||
void G4LossTableManager::Register(G4VProcess* p)
|
||||
{
|
||||
if(!p) { return; }
|
||||
if (nullptr == p) { return; }
|
||||
std::size_t n = p_vector.size();
|
||||
for (std::size_t i=0; i<n; ++i) {
|
||||
if(p_vector[i] == p) { return; }
|
||||
@@ -315,7 +328,7 @@ void G4LossTableManager::Register(G4VProcess* p)
|
||||
|
||||
void G4LossTableManager::DeRegister(G4VProcess* p)
|
||||
{
|
||||
if(!p) { return; }
|
||||
if (nullptr == p) { return; }
|
||||
std::size_t emp = p_vector.size();
|
||||
for (std::size_t i=0; i<emp; ++i) {
|
||||
if(p_vector[i] == p) {
|
||||
@@ -377,7 +390,7 @@ void G4LossTableManager::RegisterExtraParticle(
|
||||
const G4ParticleDefinition* part,
|
||||
G4VEnergyLossProcess* p)
|
||||
{
|
||||
if(!p || !part) { return; }
|
||||
if (nullptr == p || nullptr == part) { return; }
|
||||
for (G4int i=0; i<n_loss; ++i) {
|
||||
if(loss_vector[i] == p) { return; }
|
||||
}
|
||||
@@ -428,32 +441,26 @@ G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
|
||||
G4cout << "G4LossTableManager::PreparePhysicsTable for "
|
||||
<< particle->GetParticleName()
|
||||
<< " and " << p->GetProcessName() << " run= " << run
|
||||
<< " loss_vector " << loss_vector.size() << G4endl;
|
||||
}
|
||||
|
||||
if(!startInitialisation) {
|
||||
ResetParameters();
|
||||
if (1 < verbose) {
|
||||
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
|
||||
<< G4endl;
|
||||
}
|
||||
<< " loss_vector " << loss_vector.size()
|
||||
<< " run=" << run << " master=" << isMaster
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// start initialisation for the first run
|
||||
if( -1 == run ) {
|
||||
if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
|
||||
if (nullptr != emConfigurator) { emConfigurator->PrepareModels(particle, p); }
|
||||
|
||||
// initialise particles for given process
|
||||
for (G4int j=0; j<n_loss; ++j) {
|
||||
if (p == loss_vector[j] && !part_vector[j]) {
|
||||
if (p == loss_vector[j] && nullptr == part_vector[j]) {
|
||||
part_vector[j] = particle;
|
||||
if(particle->GetParticleName() == "GenericIon") {
|
||||
if (particle->GetParticleName() == "GenericIon") {
|
||||
theGenericIon = particle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
startInitialisation = true;
|
||||
ResetParameters();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -465,22 +472,17 @@ G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
|
||||
if (1 < verbose) {
|
||||
G4cout << "G4LossTableManager::PreparePhysicsTable for "
|
||||
<< particle->GetParticleName()
|
||||
<< " and " << p->GetProcessName() << G4endl;
|
||||
}
|
||||
|
||||
if(!startInitialisation) {
|
||||
ResetParameters();
|
||||
if (1 < verbose) {
|
||||
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
|
||||
<< G4endl;
|
||||
}
|
||||
<< " and " << p->GetProcessName()
|
||||
<< " run=" << run << " master=" << isMaster
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// start initialisation for the first run
|
||||
if( -1 == run ) {
|
||||
if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
|
||||
if (nullptr != emConfigurator) { emConfigurator->PrepareModels(particle, p); }
|
||||
}
|
||||
startInitialisation = true;
|
||||
|
||||
ResetParameters();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -492,22 +494,17 @@ G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
|
||||
if (1 < verbose) {
|
||||
G4cout << "G4LossTableManager::PreparePhysicsTable for "
|
||||
<< particle->GetParticleName()
|
||||
<< " and " << p->GetProcessName() << G4endl;
|
||||
}
|
||||
|
||||
if(!startInitialisation) {
|
||||
ResetParameters();
|
||||
if (1 < verbose) {
|
||||
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
|
||||
<< G4endl;
|
||||
}
|
||||
<< " and " << p->GetProcessName()
|
||||
<< " run=" << run << " master=" << isMaster
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// start initialisation for the first run
|
||||
if( -1 == run ) {
|
||||
if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
|
||||
if ( -1 == run ) {
|
||||
if (nullptr != emConfigurator) { emConfigurator->PrepareModels(particle, p); }
|
||||
}
|
||||
startInitialisation = true;
|
||||
|
||||
ResetParameters();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -516,8 +513,9 @@ void
|
||||
G4LossTableManager::BuildPhysicsTable(const G4ParticleDefinition*)
|
||||
{
|
||||
if(-1 == run && startInitialisation) {
|
||||
if(emConfigurator) { emConfigurator->Clear(); }
|
||||
if (nullptr != emConfigurator) { emConfigurator->Clear(); }
|
||||
}
|
||||
if (startInitialisation) { resetParam = true; }
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -526,7 +524,7 @@ void G4LossTableManager::LocalPhysicsTables(
|
||||
const G4ParticleDefinition* aParticle,
|
||||
G4VEnergyLossProcess* p)
|
||||
{
|
||||
if(1 < verbose) {
|
||||
if (1 < verbose) {
|
||||
G4cout << "### G4LossTableManager::LocalPhysicsTable() for "
|
||||
<< aParticle->GetParticleName()
|
||||
<< " and process " << p->GetProcessName()
|
||||
@@ -534,20 +532,21 @@ void G4LossTableManager::LocalPhysicsTables(
|
||||
}
|
||||
|
||||
if(-1 == run && startInitialisation) {
|
||||
if(emConfigurator) { emConfigurator->Clear(); }
|
||||
if (nullptr != emConfigurator) { emConfigurator->Clear(); }
|
||||
firstParticle = aParticle;
|
||||
}
|
||||
|
||||
if(startInitialisation) {
|
||||
if (startInitialisation) {
|
||||
++run;
|
||||
if(1 < verbose) {
|
||||
if (1 < verbose) {
|
||||
G4cout << "===== G4LossTableManager::LocalPhysicsTable() for run "
|
||||
<< run << " =====" << G4endl;
|
||||
}
|
||||
currentParticle = nullptr;
|
||||
startInitialisation = false;
|
||||
resetParam = true;
|
||||
for (G4int i=0; i<n_loss; ++i) {
|
||||
if(loss_vector[i]) {
|
||||
if (nullptr != loss_vector[i]) {
|
||||
tables_are_built[i] = false;
|
||||
} else {
|
||||
tables_are_built[i] = true;
|
||||
@@ -611,39 +610,28 @@ void G4LossTableManager::BuildPhysicsTable(
|
||||
}
|
||||
// clear configurator
|
||||
if(-1 == run && startInitialisation) {
|
||||
if(emConfigurator) { emConfigurator->Clear(); }
|
||||
if( nullptr != emConfigurator) { emConfigurator->Clear(); }
|
||||
firstParticle = aParticle;
|
||||
}
|
||||
if(startInitialisation) {
|
||||
++run;
|
||||
resetParam = true;
|
||||
startInitialisation = false;
|
||||
if(1 < verbose) {
|
||||
G4cout << "===== G4LossTableManager::BuildPhysicsTable() for run "
|
||||
<< run << " ===== " << atomDeexcitation << G4endl;
|
||||
}
|
||||
currentParticle = nullptr;
|
||||
all_tables_are_built= true;
|
||||
}
|
||||
|
||||
// initialisation before any table is built
|
||||
if ( startInitialisation && aParticle == firstParticle ) {
|
||||
|
||||
startInitialisation = false;
|
||||
if(1 < verbose) {
|
||||
G4cout << "### G4LossTableManager start initialisation for first particle "
|
||||
<< firstParticle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(nielCalculator) { nielCalculator->Initialise(); }
|
||||
all_tables_are_built = false;
|
||||
|
||||
for (G4int i=0; i<n_loss; ++i) {
|
||||
G4VEnergyLossProcess* el = loss_vector[i];
|
||||
|
||||
if(el) {
|
||||
if(nullptr != el) {
|
||||
isActive[i] = true;
|
||||
part_vector[i] = el->Particle();
|
||||
base_part_vector[i] = el->BaseParticle();
|
||||
tables_are_built[i] = false;
|
||||
all_tables_are_built= false;
|
||||
tables_are_built[i] = false;
|
||||
if(1 < verbose) {
|
||||
G4cout << i <<". "<< el->GetProcessName();
|
||||
if(el->Particle()) {
|
||||
@@ -675,7 +663,7 @@ void G4LossTableManager::BuildPhysicsTable(
|
||||
all_tables_are_built = true;
|
||||
|
||||
for(G4int i=0; i<n_loss; ++i) {
|
||||
if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
|
||||
if(p == loss_vector[i] && !tables_are_built[i] && nullptr == base_part_vector[i]) {
|
||||
const G4ParticleDefinition* curr_part = part_vector[i];
|
||||
if(1 < verbose) {
|
||||
G4cout << "### Build Table for " << p->GetProcessName()
|
||||
@@ -701,12 +689,6 @@ void G4LossTableManager::BuildPhysicsTable(
|
||||
<< "all_tables_are_built= " << all_tables_are_built << " "
|
||||
<< aParticle->GetParticleName() << " proc: " << p << G4endl;
|
||||
}
|
||||
if(all_tables_are_built) {
|
||||
if(1 < verbose) {
|
||||
G4cout << "%%%%% All dEdx and Range tables are built for master run= "
|
||||
<< run << " %%%%%" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
@@ -720,13 +702,13 @@ void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
|
||||
|
||||
if (!tables_are_built[j] && part == base_part_vector[j]) {
|
||||
tables_are_built[j] = true;
|
||||
// for base particle approach only ionisation table should be used
|
||||
proc->SetDEDXTable(base_proc->IonisationTable(),fRestricted);
|
||||
proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
|
||||
proc->SetCSDARangeTable(base_proc->CSDARangeTable());
|
||||
proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
|
||||
proc->SetInverseRangeTable(base_proc->InverseRangeTable());
|
||||
proc->SetLambdaTable(base_proc->LambdaTable());
|
||||
proc->SetIonisation(base_proc->IsIonisationProcess());
|
||||
if(proc->IsIonisationProcess()) {
|
||||
range_vector[j] = base_proc->RangeTableForLoss();
|
||||
inv_range_vector[j] = base_proc->InverseRangeTable();
|
||||
@@ -736,7 +718,7 @@ void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
|
||||
// << " added to map " << proc << G4endl;
|
||||
}
|
||||
if (1 < verbose) {
|
||||
G4cout << "For " << proc->GetProcessName()
|
||||
G4cout << " CopyTables for " << proc->GetProcessName()
|
||||
<< " for " << part_vector[j]->GetParticleName()
|
||||
<< " base_part= " << part->GetParticleName()
|
||||
<< " tables are assigned"
|
||||
@@ -752,7 +734,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
const G4ParticleDefinition* aParticle)
|
||||
{
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildTables() for "
|
||||
G4cout << " G4LossTableManager::BuildTables(part) for "
|
||||
<< aParticle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
@@ -771,7 +753,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
|
||||
for (i=0; i<n_loss; ++i) {
|
||||
p = loss_vector[i];
|
||||
if (p) {
|
||||
if (nullptr != p) {
|
||||
G4bool yes = (aParticle == part_vector[i]);
|
||||
|
||||
// possible case of process sharing between particle/anti-particle
|
||||
@@ -819,8 +801,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
G4int nSubRegions = em->NumberOfSubCutoffRegions();
|
||||
|
||||
if (1 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildTables() start to build range tables"
|
||||
<< " and the sum of " << n_dedx << " processes"
|
||||
G4cout << " Start to build the sum of " << n_dedx << " processes"
|
||||
<< " iem= " << iem << " em= " << em->GetProcessName()
|
||||
<< " buildCSDARange= " << theParameters->BuildCSDARange()
|
||||
<< " nSubRegions= " << nSubRegions;
|
||||
@@ -832,8 +813,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
// do not build tables if producer class is defined
|
||||
if(subcutProducer) { nSubRegions = 0; }
|
||||
|
||||
dedx = em->DEDXTable();
|
||||
em->SetIonisation(true);
|
||||
dedx = em->DEDXTable();
|
||||
em->SetDEDXTable(dedx, fIsIonisation);
|
||||
|
||||
if (1 < n_dedx) {
|
||||
@@ -843,15 +823,6 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
em->SetDEDXTable(dedx, fRestricted);
|
||||
}
|
||||
|
||||
/*
|
||||
if(2==run && "e-" == aParticle->GetParticleName()) {
|
||||
G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
|
||||
G4cout << (*dedx) << G4endl;
|
||||
G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
|
||||
G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
|
||||
G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
|
||||
}
|
||||
*/
|
||||
dedx_vector[iem] = dedx;
|
||||
|
||||
G4PhysicsTable* range = em->RangeTableForLoss();
|
||||
@@ -865,18 +836,13 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(
|
||||
tableBuilder->BuildRangeTable(dedx, range);
|
||||
tableBuilder->BuildInverseRangeTable(range, invrange);
|
||||
|
||||
// if(1<verbose) G4cout << *dedx << G4endl;
|
||||
|
||||
em->SetRangeTableForLoss(range);
|
||||
em->SetInverseRangeTable(invrange);
|
||||
|
||||
// if(1<verbose) G4cout << *range << G4endl;
|
||||
|
||||
std::vector<G4PhysicsTable*> listCSDA;
|
||||
|
||||
for (i=0; i<n_dedx; ++i) {
|
||||
p = loss_list[i];
|
||||
if(p != em) { p->SetIonisation(false); }
|
||||
if(build_flags[i]) {
|
||||
p->SetLambdaTable(p->BuildLambdaTable(fRestricted));
|
||||
}
|
||||
@@ -983,7 +949,7 @@ G4ElectronIonPair* G4LossTableManager::ElectronIonPair()
|
||||
|
||||
void G4LossTableManager::SetNIELCalculator(G4NIELCalculator* ptr)
|
||||
{
|
||||
if(ptr && ptr != nielCalculator) {
|
||||
if(nullptr != ptr && ptr != nielCalculator) {
|
||||
delete nielCalculator;
|
||||
nielCalculator = ptr;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,6 @@ void G4TransportationWithMsc::PreparePhysicsTable(const G4ParticleDefinition& pa
|
||||
if (fType == ScatteringType::MultipleScattering) {
|
||||
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);
|
||||
|
||||
@@ -74,7 +74,8 @@ G4VEmModel::G4VEmModel(const G4String& nam):
|
||||
xsec.resize(nsec);
|
||||
fEmManager = G4LossTableManager::Instance();
|
||||
fEmManager->Register(this);
|
||||
|
||||
isMaster = fEmManager->IsMaster();
|
||||
|
||||
G4LossTableBuilder* bld = fEmManager->GetTableBuilder();
|
||||
theDensityFactor = bld->GetDensityFactors();
|
||||
theDensityIdx = bld->GetCoupleIndexes();
|
||||
@@ -396,13 +397,7 @@ G4VEmModel::SetParticleChange(G4VParticleChange* p, G4VEmFluctuationModel* f)
|
||||
|
||||
void G4VEmModel::SetCrossSectionTable(G4PhysicsTable* p, G4bool isLocal)
|
||||
{
|
||||
if(p != xSectionTable) {
|
||||
if(xSectionTable != nullptr && localTable) {
|
||||
xSectionTable->clearAndDestroy();
|
||||
delete xSectionTable;
|
||||
}
|
||||
xSectionTable = p;
|
||||
}
|
||||
xSectionTable = p;
|
||||
localTable = isLocal;
|
||||
}
|
||||
|
||||
@@ -419,6 +414,11 @@ void G4VEmModel::SetLPMFlag(G4bool)
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VEmModel::SetMasterThread(G4bool)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4VEmModel::ModelDescription(std::ostream& outFile) const
|
||||
|
||||
@@ -153,7 +153,7 @@ void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
|
||||
|
||||
G4String pname = part.GetParticleName();
|
||||
if(pname != "deuteron" && pname != "triton" &&
|
||||
pname != "alpha" && pname != "alpha+" &&
|
||||
pname != "He3" && pname != "alpha" && pname != "alpha+" &&
|
||||
pname != "helium" && pname != "hydrogen") {
|
||||
|
||||
particle = G4GenericIon::GenericIon();
|
||||
@@ -272,8 +272,14 @@ void G4VEmProcess::StreamInfo(std::ostream& out,
|
||||
}
|
||||
if(fXSType != fEmNoIntegral) { out << " XStype:" << fXSType; }
|
||||
if(applyCuts) { out << " applyCuts:1 "; }
|
||||
out << " SubType=" << GetProcessSubType();
|
||||
if(biasFactor != 1.0) { out << " BiasingFactor= " << biasFactor; }
|
||||
G4int subtype = GetProcessSubType();
|
||||
out << " SubType=" << subtype;
|
||||
if (subtype == fAnnihilation) {
|
||||
G4int mod = theParameters->PositronAtRestModelType();
|
||||
const G4String namp[2] = {"Simple", "Allison"};
|
||||
out << " AtRestModel:" << namp[mod];
|
||||
}
|
||||
if(biasFactor != 1.0) { out << " BiasingFactor=" << biasFactor; }
|
||||
out << " BuildTable=" << buildLambdaTable << G4endl;
|
||||
if(buildLambdaTable) {
|
||||
if(particle == &part) {
|
||||
@@ -554,7 +560,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
|
||||
G4double time = track.GetGlobalTime();
|
||||
|
||||
G4int n1(0), n2(0);
|
||||
if(num > mainSecondaries) {
|
||||
if(num0 > mainSecondaries) {
|
||||
currentModel->FillNumberOfSecondaries(n1, n2);
|
||||
}
|
||||
|
||||
@@ -608,7 +614,7 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
|
||||
t->SetCreatorModelID(augerID);
|
||||
}
|
||||
} else {
|
||||
t->SetCreatorModelID(secID);
|
||||
t->SetCreatorModelID(biasID);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
@@ -218,6 +218,7 @@ G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
|
||||
}
|
||||
|
||||
tablesAreBuilt = false;
|
||||
if (GetProcessSubType() == fIonisation) { SetIonisation(true); }
|
||||
|
||||
G4LossTableBuilder* bld = lManager->GetTableBuilder();
|
||||
lManager->PreparePhysicsTable(&part, this);
|
||||
@@ -962,7 +963,18 @@ void G4VEnergyLossProcess::FillSecondariesAlongStep(G4double wt)
|
||||
if(nullptr != t) {
|
||||
t->SetWeight(weight);
|
||||
pParticleChange->AddSecondary(t);
|
||||
if(i >= n0) { t->SetCreatorModelID(biasID); }
|
||||
G4int pdg = t->GetDefinition()->GetPDGEncoding();
|
||||
if (i < n0) {
|
||||
if (pdg == 22) {
|
||||
t->SetCreatorModelID(gpixeID);
|
||||
} else if (pdg == 11) {
|
||||
t->SetCreatorModelID(epixeID);
|
||||
} else {
|
||||
t->SetCreatorModelID(biasID);
|
||||
}
|
||||
} else {
|
||||
t->SetCreatorModelID(biasID);
|
||||
}
|
||||
}
|
||||
}
|
||||
scTracks.clear();
|
||||
@@ -1110,17 +1122,19 @@ G4bool G4VEnergyLossProcess::StorePhysicsTable(
|
||||
{
|
||||
if (!isMaster || nullptr != baseParticle || part != particle ) return true;
|
||||
for(std::size_t i=0; i<7; ++i) {
|
||||
if(nullptr != theData->Table(i)) {
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4VEnergyLossProcess::StorePhysicsTable i=" << i
|
||||
<< " " << particle->GetParticleName()
|
||||
<< " " << GetProcessName()
|
||||
<< " " << tnames[i] << " " << theData->Table(i) << G4endl;
|
||||
}
|
||||
if(!G4EmTableUtil::StoreTable(this, part, theData->Table(i),
|
||||
dir, tnames[i], verboseLevel, ascii)) {
|
||||
return false;
|
||||
}
|
||||
// ionisation table only for ionisation process
|
||||
if (nullptr == theData->Table(i) || (!isIonisation && 1 == i)) {
|
||||
continue;
|
||||
}
|
||||
if (-1 < verboseLevel) {
|
||||
G4cout << "G4VEnergyLossProcess::StorePhysicsTable i=" << i
|
||||
<< " " << particle->GetParticleName()
|
||||
<< " " << GetProcessName()
|
||||
<< " " << tnames[i] << " " << theData->Table(i) << G4endl;
|
||||
}
|
||||
if (!G4EmTableUtil::StoreTable(this, part, theData->Table(i),
|
||||
dir, tnames[i], verboseLevel, ascii)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -1134,6 +1148,8 @@ G4VEnergyLossProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
|
||||
{
|
||||
if (!isMaster || nullptr != baseParticle || part != particle ) return true;
|
||||
for(std::size_t i=0; i<7; ++i) {
|
||||
// ionisation table only for ionisation process
|
||||
if (!isIonisation && 1 == i) { continue; }
|
||||
if(!G4EmTableUtil::RetrieveTable(this, part, theData->Table(i), dir, tnames[i],
|
||||
verboseLevel, ascii, spline)) {
|
||||
return false;
|
||||
|
||||
@@ -74,7 +74,7 @@ G4VMscModel::~G4VMscModel() = default;
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4ParticleChangeForMSC*
|
||||
G4VMscModel::GetParticleChangeForMSC(const G4ParticleDefinition* p)
|
||||
G4VMscModel::GetParticleChangeForMSC(const G4ParticleDefinition*)
|
||||
{
|
||||
// recomputed for each new run
|
||||
if(nullptr == safetyHelper) {
|
||||
@@ -88,25 +88,6 @@ G4VMscModel::GetParticleChangeForMSC(const G4ParticleDefinition* p)
|
||||
} else {
|
||||
change = new G4ParticleChangeForMSC();
|
||||
}
|
||||
if(IsMaster() && nullptr != p) {
|
||||
|
||||
// table is always built for low mass particles
|
||||
if(p->GetParticleName() != "GenericIon" &&
|
||||
(p->GetPDGMass() < CLHEP::GeV || ForceBuildTableFlag()) ) {
|
||||
|
||||
G4EmParameters* param = G4EmParameters::Instance();
|
||||
G4LossTableBuilder* builder =
|
||||
G4LossTableManager::Instance()->GetTableBuilder();
|
||||
G4double emin = std::max(LowEnergyLimit(), LowEnergyActivationLimit());
|
||||
G4double emax = std::min(HighEnergyLimit(), HighEnergyActivationLimit());
|
||||
emin = std::max(emin, param->MinKinEnergy());
|
||||
emax = std::min(emax, param->MaxKinEnergy());
|
||||
if(emin < emax) {
|
||||
xSectionTable = builder->BuildTableForModel(xSectionTable, this, p,
|
||||
emin, emax, useSpline);
|
||||
}
|
||||
}
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,25 +141,24 @@ void
|
||||
G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part)
|
||||
{
|
||||
G4bool master = emManager->IsMaster();
|
||||
if(nullptr == firstParticle) { firstParticle = ∂ }
|
||||
if (nullptr == firstParticle) { firstParticle = ∂ }
|
||||
|
||||
emManager->PreparePhysicsTable(&part, this);
|
||||
currParticle = nullptr;
|
||||
|
||||
if(firstParticle == &part) {
|
||||
baseMat = emManager->GetTableBuilder()->GetBaseMaterialFlag();
|
||||
|
||||
G4EmTableUtil::PrepareMscProcess(this, part, modelManager,
|
||||
stepLimit, facrange,
|
||||
latDisplacement, master,
|
||||
isIon, baseMat);
|
||||
stepLimit, facrange,
|
||||
latDisplacement, master,
|
||||
isIon, baseMat);
|
||||
|
||||
numberOfModels = modelManager->NumberOfModels();
|
||||
currentModel = GetModelByIndex(0);
|
||||
|
||||
if(nullptr == safetyHelper) {
|
||||
if (nullptr == safetyHelper) {
|
||||
safetyHelper = G4TransportationManager::GetTransportationManager()
|
||||
->GetSafetyHelper();
|
||||
->GetSafetyHelper();
|
||||
safetyHelper->InitialiseHelper();
|
||||
}
|
||||
}
|
||||
@@ -171,8 +170,8 @@ void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
{
|
||||
G4bool master = emManager->IsMaster();
|
||||
|
||||
if(firstParticle == &part) {
|
||||
emManager->BuildPhysicsTable(firstParticle);
|
||||
if(firstParticle == &part) {
|
||||
emManager->BuildPhysicsTable(&part);
|
||||
}
|
||||
const G4VMultipleScattering* ptr = this;
|
||||
if(!master) {
|
||||
|
||||
@@ -6,10 +6,14 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-01-10 Soon Yung Jun (xrays-V11-01-10)
|
||||
## 2024-05-16 Vladimir Grichine (xrays-V11-02-02)
|
||||
- G4XTRGaussRadModel.hh/.cc class was added with improved account
|
||||
on the origin of theXTR photon
|
||||
|
||||
## 2024-01-10 Soon Yung Jun (xrays-V11-02-01)
|
||||
- G4Scintillation::sample_time - refactor the scintillation time sampling
|
||||
|
||||
## 2023-12-16 Vladimir Grichine
|
||||
## 2023-12-16 Vladimir Grichine (xrays-V11-02-00)
|
||||
- G4GaussXTRadiator, G4VXTRenergyLoss - flexible summation in
|
||||
SpectralXTRdEdx, clean-up in GetStackFactor based on std::complex methods
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Process describing a radiator of X-ray transition radiation.
|
||||
// Regular radiator with thicknesses of plates and gas gaps are Gauss-distributed.
|
||||
// We suppose that:
|
||||
// formation zone ~ mean thickness << absorption length
|
||||
// for each material and in the range 1-100 keV. This allows us to simplify
|
||||
// interference effects in radiator stack (GetStackFactor method).
|
||||
// The XTR photons are moved to the end of radiator.
|
||||
//
|
||||
// History:
|
||||
//
|
||||
// 19.04.24 V. Grichine, first version
|
||||
//
|
||||
|
||||
#ifndef G4XTRGaussRadModel_h
|
||||
#define G4XTRGaussRadModel_h 1
|
||||
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4VXTRenergyLoss.hh"
|
||||
|
||||
class G4XTRGaussRadModel : public G4VXTRenergyLoss
|
||||
{
|
||||
public:
|
||||
explicit G4XTRGaussRadModel(
|
||||
G4LogicalVolume* anEnvelope, G4double, G4double, G4Material*, G4Material*, G4double, G4double,
|
||||
G4int, const G4String& processName = "XTRGaussRadModel");
|
||||
~G4XTRGaussRadModel() override;
|
||||
|
||||
// reimplementation of base class function in analytical way
|
||||
|
||||
G4double SpectralXTRdEdx(G4double energy) override;
|
||||
|
||||
G4double GetStackFactor(G4double energy, G4double gamma,
|
||||
G4double varAngle) override;
|
||||
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -19,6 +19,7 @@ geant4_add_module(G4xrays
|
||||
G4VTransitionRadiation.hh
|
||||
G4VXTRenergyLoss.hh
|
||||
G4XTRGammaRadModel.hh
|
||||
G4XTRGaussRadModel.hh
|
||||
G4XTRRegularRadModel.hh
|
||||
G4XTRTransparentRegRadModel.hh
|
||||
G4XrayReflection.hh
|
||||
@@ -38,6 +39,7 @@ geant4_add_module(G4xrays
|
||||
G4VTransitionRadiation.cc
|
||||
G4VXTRenergyLoss.cc
|
||||
G4XTRGammaRadModel.cc
|
||||
G4XTRGaussRadModel.cc
|
||||
G4XTRRegularRadModel.cc
|
||||
G4XTRTransparentRegRadModel.cc
|
||||
G4XrayReflection.cc)
|
||||
|
||||
@@ -144,10 +144,10 @@ G4double G4GaussXTRadiator::GetStackFactor(G4double energy,
|
||||
|
||||
G4complex ordernn = ( order1 + order2 )*nn;
|
||||
|
||||
G4complex Ha = exp( order1 );
|
||||
G4complex Hb = exp( order2 );
|
||||
G4complex Ha = std::exp( order1 );
|
||||
G4complex Hb = std::exp( order2 );
|
||||
G4complex H = Ha * Hb;
|
||||
G4complex Hn = exp( ordernn );
|
||||
G4complex Hn = std::exp( ordernn );
|
||||
|
||||
G4complex F1 = ( 1.0 - Ha ) * ( 1.0 - Hb ) * nn / ( 1. - H );
|
||||
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// 19.04.24 V. Grichine, first version
|
||||
//
|
||||
|
||||
#include "G4XTRGaussRadModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4NistManager.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace CLHEP;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, destructor
|
||||
|
||||
G4XTRGaussRadModel::G4XTRGaussRadModel(
|
||||
G4LogicalVolume* anEnvelope, G4double alphaPlate, G4double alphaGas, G4Material* foilMat, G4Material* gasMat,
|
||||
G4double aa, G4double b, G4int n, const G4String& processName)
|
||||
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, aa, b, n, processName)
|
||||
{
|
||||
if( verboseLevel > 0 )
|
||||
G4cout << "G4XTRGaussRadModel EM process is called"
|
||||
<< G4endl;
|
||||
|
||||
fAlphaPlate = alphaPlate; // ~40
|
||||
fAlphaGas = alphaGas; // ~10
|
||||
fExitFlux = true; // XTR photons are moved to the end of radiator
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4XTRGaussRadModel::~G4XTRGaussRadModel() = default;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void G4XTRGaussRadModel::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Simulation of forward X-ray transition radiation generated by\n"
|
||||
"relativistic charged particles crossing the interface between\n"
|
||||
"two materials.\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4XTRGaussRadModel::SpectralXTRdEdx(G4double energy)
|
||||
{
|
||||
static constexpr G4double cofPHC = 4. * pi * hbarc;
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, theta2, theta2k;
|
||||
G4double aMa, bMb, sigma, dump;
|
||||
G4int k, kMax, kMin;
|
||||
|
||||
aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick * GetGasLinearPhotoAbs(energy);
|
||||
sigma = 0.5 * (aMa + bMb);
|
||||
dump = std::exp(-fPlateNumber * sigma);
|
||||
if(verboseLevel > 2)
|
||||
G4cout << " dump = " << dump << G4endl;
|
||||
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
|
||||
cof1 = fPlateThick * tmp;
|
||||
cof2 = fGasThick * tmp;
|
||||
|
||||
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
|
||||
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
|
||||
cofMin /= cofPHC;
|
||||
|
||||
theta2 = cofPHC / (energy * (fPlateThick + fGasThick));
|
||||
|
||||
kMin = G4int(cofMin);
|
||||
if(cofMin > kMin)
|
||||
kMin++;
|
||||
|
||||
kMax = kMin + 200; // 99; // 49; //
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
G4cout << cof1 << " " << cof2 << " " << cofMin << G4endl;
|
||||
G4cout << "kMin = " << kMin << "; kMax = " << kMax << G4endl;
|
||||
}
|
||||
for(k = kMin; k <= kMax; ++k)
|
||||
{
|
||||
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
|
||||
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
|
||||
if(k == kMin && kMin == G4int(cofMin))
|
||||
{
|
||||
sum +=
|
||||
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
theta2k = std::sqrt(theta2 * std::abs(k - cofMin));
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
G4cout << k << " " << theta2k << " "
|
||||
<< std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result
|
||||
<< " " << sum << G4endl;
|
||||
}
|
||||
}
|
||||
result = 2 * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
|
||||
result *= dump * (-1 + dump + 2 * fPlateNumber);
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Approximation for radiator interference factor for the case of
|
||||
// Gauss-distributed regular radiator. The plate and gas gap thicknesses
|
||||
// are Gauss distributed with RMS
|
||||
// sa and sb for plate and gas, respectively.
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones.
|
||||
// The XTR photons are moved to the end of radiator
|
||||
|
||||
|
||||
G4double G4XTRGaussRadModel::GetStackFactor(G4double energy,
|
||||
G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
G4double result(0.);
|
||||
|
||||
G4double Ma, Mb, aMa, bMb, sigma;
|
||||
|
||||
G4double sa = fPlateThick/fAlphaPlate;
|
||||
G4double sb = fGasThick/fAlphaGas;
|
||||
|
||||
Ma = GetPlateLinearPhotoAbs(energy);
|
||||
aMa = fPlateThick * Ma;
|
||||
Mb = GetGasLinearPhotoAbs(energy);
|
||||
bMb = fGasThick * Mb;
|
||||
sigma = aMa + bMb; // m1*t1+m2*t2 dimensionless
|
||||
G4double nn = G4double( fPlateNumber );
|
||||
|
||||
// Gauss fluctuation of foil and gas gaps according to
|
||||
// RMS = sa = a/fAlphaPlate and RMS = sb = b/fAlphaGas
|
||||
|
||||
G4complex med(0.,1.);
|
||||
G4complex Z1 = GetPlateComplexFZ( energy, gamma, varAngle);
|
||||
G4complex por1 = -0.5*med*fPlateThick/Z1 - 0.125*sa*sa/Z1/Z1;
|
||||
|
||||
G4complex Z2 = GetGasComplexFZ( energy, gamma, varAngle);
|
||||
G4complex por2 = -0.5*med*fGasThick/Z2 - 0.125*sb*sb/Z2/Z2;
|
||||
|
||||
G4complex npor = (por1+por2)*nn;
|
||||
|
||||
G4complex Ha = exp(por1);
|
||||
G4complex Hb = exp(por2);
|
||||
|
||||
G4complex H = Ha*Hb;
|
||||
G4complex Hn = exp(npor);
|
||||
|
||||
G4complex A = ( 1.0 - Ha ) * ( 1.0 - Hb ) / ( 1. - H );
|
||||
G4complex B1 = ( 1.0 - Ha ) * ( 1.0 - Ha ) * Hb / ( 1. - H );
|
||||
|
||||
G4complex R = B1*( exp(-sigma*nn) - Hn )/( exp(-sigma) - H );
|
||||
|
||||
R += A * ( 1 - exp(-sigma*nn) ) / ( 1. - exp(-sigma) ); // -> A*nn
|
||||
|
||||
R *= OneInterfaceXTRdEdx(energy, gamma, varAngle);
|
||||
|
||||
result = 2.0 * std::real(R);
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user