Import Geant4 11.1.0.beta source tree
This commit is contained in:
+7
@@ -114,6 +114,13 @@ private:
|
||||
G4DNADingfelderChargeDecreaseModel & operator=(const G4DNADingfelderChargeDecreaseModel &right);
|
||||
G4DNADingfelderChargeDecreaseModel(const G4DNADingfelderChargeDecreaseModel&);
|
||||
|
||||
// Reusable particle definitions
|
||||
G4ParticleDefinition* protonDef;
|
||||
G4ParticleDefinition* alphaPlusPlusDef;
|
||||
G4ParticleDefinition* alphaPlusDef;
|
||||
G4ParticleDefinition* hydrogenDef;
|
||||
G4ParticleDefinition* heliumDef;
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
+6
@@ -115,6 +115,12 @@ private:
|
||||
G4DNADingfelderChargeIncreaseModel & operator=(const G4DNADingfelderChargeIncreaseModel &right);
|
||||
G4DNADingfelderChargeIncreaseModel(const G4DNADingfelderChargeIncreaseModel&);
|
||||
|
||||
// Reusable particle definitions
|
||||
G4ParticleDefinition* hydrogenDef;
|
||||
G4ParticleDefinition* alphaPlusPlusDef;
|
||||
G4ParticleDefinition* alphaPlusDef;
|
||||
G4ParticleDefinition* heliumDef;
|
||||
|
||||
};
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include "G4ITReaction.hh"
|
||||
#include "G4DNAEventSet.hh"
|
||||
#include "G4DNAUpdateSystemModel.hh"
|
||||
#include "G4H2O2.hh"
|
||||
#include <CLHEP/Units/SystemOfUnits.h>
|
||||
class G4VITStepModel;
|
||||
class G4DNAGillespieDirectMethod;
|
||||
class G4UserMeshAction;
|
||||
@@ -66,8 +68,8 @@ class G4DNAEventScheduler : public IEventScheduler
|
||||
void SetEndTime(const G4double&);
|
||||
G4double GetStartTime() const;
|
||||
G4double GetEndTime() const;
|
||||
[[maybe_unused]] G4double GetTimeStep() const;
|
||||
[[maybe_unused]] void SetStartTime(G4double time);
|
||||
G4double GetTimeStep() const;
|
||||
void SetStartTime(G4double time);
|
||||
|
||||
inline void SetVerbose(G4int verbose) { fVerbose = verbose; }
|
||||
inline G4int GetVerbose() const;
|
||||
@@ -79,13 +81,13 @@ class G4DNAEventScheduler : public IEventScheduler
|
||||
void RunInMesh();
|
||||
void Run();
|
||||
|
||||
[[maybe_unused]] void AddTimeToRecord(const G4double& time);
|
||||
void AddTimeToRecord(const G4double& time);
|
||||
|
||||
void RecordTime();
|
||||
void ClearAndReChargeCounter();
|
||||
void PrintRecordTime();
|
||||
void Stop();
|
||||
[[maybe_unused]] void SetMaxNbSteps(G4int);
|
||||
void SetMaxNbSteps(G4int);
|
||||
std::map<G4double /*time*/, MapCounter> GetCounterMap() const;
|
||||
G4DNAMesh* GetMesh() const;
|
||||
G4int GetPixels() const;
|
||||
@@ -93,22 +95,25 @@ class G4DNAEventScheduler : public IEventScheduler
|
||||
static G4bool CheckingReactionRadius(G4double resolution);
|
||||
|
||||
private:
|
||||
G4int fVerbose;
|
||||
G4bool fInitialized;
|
||||
G4double fStartTime;
|
||||
G4double fEndTime;
|
||||
G4int fStepNumber;
|
||||
G4int fMaxStep;
|
||||
G4bool fRunning;
|
||||
G4double fTimeStep;
|
||||
G4double fGlobalTime;
|
||||
G4double fJumpingNumber;
|
||||
G4double fReactionNumber;
|
||||
G4int fVerbose = 0;
|
||||
G4bool fInitialized = false;
|
||||
G4double fStartTime = 1 * CLHEP::picosecond;
|
||||
G4double fEndTime = 10000 * CLHEP::second;
|
||||
G4int fStepNumber = 0;
|
||||
G4int fMaxStep = INT_MAX;
|
||||
G4bool fRunning = true;
|
||||
G4double fTimeStep = DBL_MAX;
|
||||
G4double fGlobalTime = 1 * CLHEP::picosecond;
|
||||
G4double fJumpingNumber = 0;
|
||||
G4double fReactionNumber = 0;
|
||||
G4int fPixel;
|
||||
G4bool fIsChangeMesh;
|
||||
G4bool fSetChangeMesh;
|
||||
G4int fStepNumberInMesh;
|
||||
G4bool fIsChangeMesh = false;
|
||||
G4bool fSetChangeMesh = true;
|
||||
G4int fStepNumberInMesh = 0;
|
||||
G4double fInitialPixels;
|
||||
G4double fTransferTime = 0.;
|
||||
const G4double C = 20;
|
||||
const G4double D = G4H2O2::Definition()->GetDiffusionCoefficient(); // this is the biggest D
|
||||
|
||||
std::unique_ptr<G4DNAMesh> fpMesh;
|
||||
std::unique_ptr<G4DNAGillespieDirectMethod> fpGillespieReaction;
|
||||
@@ -116,7 +121,6 @@ class G4DNAEventScheduler : public IEventScheduler
|
||||
std::unique_ptr<G4DNAUpdateSystemModel> fpUpdateSystem;
|
||||
std::unique_ptr<G4UserMeshAction> fpUserMeshAction;
|
||||
// an aternative Counter
|
||||
|
||||
std::map<G4double /*time*/, MapCounter> fCounterMap;
|
||||
std::set<G4double> fTimeToRecord;
|
||||
std::set<G4double>::iterator fLastRecoredTime;
|
||||
|
||||
@@ -34,43 +34,42 @@
|
||||
#include "G4MoleculeTable.hh"
|
||||
#include "G4ITTrackHolder.hh"
|
||||
#include "G4DNAEventSet.hh"
|
||||
|
||||
class G4DNAMolecularReactionTable;
|
||||
class G4DNAMolecularReactionData;
|
||||
class G4DNAScavengerMaterial;
|
||||
class G4MolecularConfiguration;
|
||||
class G4DNAGillespieDirectMethod
|
||||
{
|
||||
public:
|
||||
G4DNAGillespieDirectMethod();
|
||||
~G4DNAGillespieDirectMethod();
|
||||
using MolType = const G4MolecularConfiguration*;
|
||||
using Key = unsigned int;
|
||||
using Index = G4Voxel::Index;
|
||||
using Index = G4VDNAMesh::Index;
|
||||
using Voxel = G4DNAMesh::Voxel;
|
||||
using JumpingData = std::pair<MolType, Index>;
|
||||
using ReactionData = const G4DNAMolecularReactionData;
|
||||
using EventIt = G4DNAEventSet::EventSet::iterator;
|
||||
|
||||
G4double PropensityFunction(const Index& index, ReactionData* data);
|
||||
G4double PropensityFunction(const Index& index, MolType moleType);
|
||||
G4double PropensityFunction(const Voxel& voxel, ReactionData* data);
|
||||
G4double PropensityFunction(const Voxel& voxel, MolType moleType);
|
||||
inline void SetVoxelMesh(G4DNAMesh& mesh) { fpMesh = &mesh; }
|
||||
void SetTimeStep(const G4double& stepTime);
|
||||
G4double Reaction(const Index& index);
|
||||
G4double DiffusiveJumping(const Index& index);
|
||||
G4double ComputeNumberInNode(const Index& index, MolType type);
|
||||
G4double VolumeOfNode(const Index& index);
|
||||
void Initialize();
|
||||
void CreateEvent(unsigned int key);
|
||||
void CreateEvent(const Index& index);
|
||||
void SetEventSet(G4DNAEventSet*);
|
||||
|
||||
private:
|
||||
G4double Reaction(const Voxel& voxel);
|
||||
G4double DiffusiveJumping(const Voxel& voxel);
|
||||
G4double ComputeNumberInNode(const Voxel& voxel, MolType type);
|
||||
G4double VolumeOfNode(const Voxel& voxel);
|
||||
G4DNAMolecularReactionTable* fMolecularReactions;
|
||||
G4DNAMesh* fpMesh;
|
||||
G4DNAMesh* fpMesh = nullptr;
|
||||
G4double fTimeStep;
|
||||
G4DNAEventSet* fpEventSet;
|
||||
G4double fVerbose;
|
||||
G4DNAEventSet* fpEventSet = nullptr;
|
||||
G4double fVerbose = 0;
|
||||
std::map<G4double /*Propensity*/, ReactionData*> fReactionDataMap;
|
||||
std::map<G4double /*Propensity*/, JumpingData> fJumpingDataMap;
|
||||
G4bool FindScavenging(const Index& index, MolType, G4double&);
|
||||
G4DNAScavengerMaterial* fpScavengerMaterial;
|
||||
G4bool FindScavenging(const Voxel& voxel, MolType, G4double&);
|
||||
G4DNAScavengerMaterial* fpScavengerMaterial = nullptr;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
/*
|
||||
* G4DNAIRT_geometries.hh
|
||||
*
|
||||
* Created on: Jul 23, 2019
|
||||
* Author: W. G. Shin
|
||||
* J. Ramos-Mendez and B. Faddegon
|
||||
*/
|
||||
|
||||
#ifndef G4DNAIRT_geometries_HH_
|
||||
#define G4DNAIRT_geometries_HH_
|
||||
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
#include "G4DNAMolecularReaction.hh"
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
#include "G4MoleculeTable.hh"
|
||||
|
||||
#include "G4VDNAReactionModel.hh"
|
||||
#include "G4VITReactionProcess.hh"
|
||||
|
||||
#include "G4ITReactionTable.hh"
|
||||
#include "G4ITTrackHolder.hh"
|
||||
#include "G4ITReaction.hh"
|
||||
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4VITReactionProcess.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4VDNAMolecularGeometry.hh"
|
||||
|
||||
#include "AddClone_def.hh"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class G4DNAMolecularReactionTable;
|
||||
class G4VDNAReactionModel;
|
||||
class G4ErrorFunction;
|
||||
|
||||
class G4DNAIRT_geometries : public G4VITReactionProcess
|
||||
{
|
||||
public:
|
||||
|
||||
G4DNAIRT_geometries();
|
||||
explicit G4DNAIRT_geometries(G4VDNAReactionModel*);
|
||||
~G4DNAIRT_geometries() override;
|
||||
G4DNAIRT_geometries(const G4DNAIRT_geometries& other) = delete;
|
||||
G4DNAIRT_geometries& operator=(const G4DNAIRT_geometries& other) = delete;
|
||||
|
||||
G4bool TestReactibility(const G4Track&,
|
||||
const G4Track&,
|
||||
G4double ,
|
||||
G4bool ) override;
|
||||
std::vector<std::unique_ptr<G4ITReactionChange>> FindReaction(G4ITReactionSet*, const G4double, const G4double, const G4bool) override;
|
||||
std::unique_ptr<G4ITReactionChange> MakeReaction(const G4Track&, const G4Track&) override;
|
||||
|
||||
void SetReactionModel(G4VDNAReactionModel*);
|
||||
|
||||
void Initialize() override;
|
||||
void SpaceBinning();
|
||||
void IRTSampling();
|
||||
void Sampling(G4Track*);
|
||||
|
||||
G4double GetIndependentReactionTime(const G4MolecularConfiguration*, const G4MolecularConfiguration*, G4double);
|
||||
G4int FindBin(G4int, G4double, G4double, G4double);
|
||||
G4double SamplePDC(G4double , G4double );
|
||||
|
||||
protected:
|
||||
const G4DNAMolecularReactionTable*& fMolReactionTable;
|
||||
G4VDNAReactionModel* fpReactionModel;
|
||||
|
||||
private:
|
||||
G4ITTrackHolder* fTrackHolder;
|
||||
G4ITReactionSet* fReactionSet;
|
||||
G4ErrorFunction* erfc;
|
||||
|
||||
std::map<G4int,std::map<G4int,std::map<G4int,std::vector<G4Track*>>>> spaceBinned;
|
||||
std::vector<std::pair<G4ThreeVector,G4Track*>> positionMap;
|
||||
|
||||
G4double fRCutOff;
|
||||
G4double timeMin;
|
||||
G4double timeMax;
|
||||
|
||||
G4double fXMin, fYMin, fZMin;
|
||||
G4double fXMax, fYMax, fZMax;
|
||||
G4int fNx, fNy, fNz;
|
||||
G4int xiniIndex, yiniIndex, ziniIndex;
|
||||
G4int xendIndex, yendIndex, zendIndex;
|
||||
|
||||
G4VDNAMolecularGeometry* fGeometry;
|
||||
};
|
||||
|
||||
#endif /* G4DNAIRT_geometries_HH_ */
|
||||
+19
-24
@@ -30,34 +30,29 @@
|
||||
#define G4DNAIndependentReactionTimeModel_hh 1
|
||||
#include "G4String.hh"
|
||||
#include "G4VITStepModel.hh"
|
||||
#include <G4ReferenceCast.hh>
|
||||
|
||||
class G4DNAMolecularReactionTable;
|
||||
class G4VDNAReactionModel;
|
||||
class G4VReactionTypeManager;
|
||||
class G4DNAIndependentReactionTimeModel
|
||||
: public G4VITStepModel
|
||||
class G4DNAIndependentReactionTimeModel : public G4VITStepModel
|
||||
{
|
||||
|
||||
public:
|
||||
explicit G4DNAIndependentReactionTimeModel(const G4String& name = "DNAIndependentReactionTimeModel");
|
||||
G4DNAIndependentReactionTimeModel(const G4String& name,
|
||||
std::unique_ptr<G4VITTimeStepComputer> pTimeStepper,
|
||||
std::unique_ptr<G4VITReactionProcess> pReactionProcess);
|
||||
G4DNAIndependentReactionTimeModel(const G4DNAIndependentReactionTimeModel&) = delete;
|
||||
~G4DNAIndependentReactionTimeModel() override;
|
||||
public:
|
||||
explicit G4DNAIndependentReactionTimeModel(
|
||||
const G4String& name = "DNAIndependentReactionTimeModel");
|
||||
G4DNAIndependentReactionTimeModel(
|
||||
const G4String& name, std::unique_ptr<G4VITTimeStepComputer> pTimeStepper,
|
||||
std::unique_ptr<G4VITReactionProcess> pReactionProcess);
|
||||
G4DNAIndependentReactionTimeModel(const G4DNAIndependentReactionTimeModel&) =
|
||||
delete;
|
||||
~G4DNAIndependentReactionTimeModel() override;
|
||||
void PrintInfo() override;
|
||||
void Initialize() override;
|
||||
void SetReactionModel(G4VDNAReactionModel*);
|
||||
G4VDNAReactionModel* GetReactionModel();
|
||||
|
||||
void PrintInfo() override;
|
||||
|
||||
void Initialize() override;
|
||||
|
||||
void SetReactionModel(G4VDNAReactionModel*);
|
||||
G4VDNAReactionModel* GetReactionModel();
|
||||
|
||||
void SetReactionTypeManager(G4VReactionTypeManager* pReactionProcessManager);
|
||||
|
||||
protected:
|
||||
const G4DNAMolecularReactionTable*& fMolecularReactionTable;
|
||||
std::unique_ptr<G4VDNAReactionModel> fpReactionModel;
|
||||
std::unique_ptr<G4VReactionTypeManager> fReactionTypeManager;
|
||||
protected:
|
||||
const G4DNAMolecularReactionTable*& fMolecularReactionTable =
|
||||
reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable);
|
||||
std::unique_ptr<G4VDNAReactionModel> fpReactionModel;
|
||||
};
|
||||
#endif
|
||||
+47
-52
@@ -33,15 +33,15 @@
|
||||
#include "G4VITTimeStepComputer.hh"
|
||||
#include "G4KDTreeResult.hh"
|
||||
#include "G4IRTUtils.hh"
|
||||
#include "G4VReactionType.hh"
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include "G4ITTrackHolder.hh"
|
||||
#include "G4ITReaction.hh"
|
||||
#include "G4ReferenceCast.hh"
|
||||
|
||||
class G4VReactionTypeManager;
|
||||
class G4VDNAReactionModel;
|
||||
class G4DNAMolecularReactionTable;
|
||||
class G4MolecularConfiguration;
|
||||
class G4DNAReactionTypeManager;
|
||||
class G4Molecule;
|
||||
class G4ITReactionSet;
|
||||
class G4ITReactionChange;
|
||||
@@ -50,61 +50,56 @@ class G4ITTrackHolder;
|
||||
|
||||
class G4DNAIndependentReactionTimeStepper : public G4VITTimeStepComputer
|
||||
{
|
||||
public:
|
||||
G4DNAIndependentReactionTimeStepper();
|
||||
~G4DNAIndependentReactionTimeStepper() override = default;
|
||||
G4DNAIndependentReactionTimeStepper(const G4DNAIndependentReactionTimeStepper&) = delete;
|
||||
G4DNAIndependentReactionTimeStepper& operator=(const G4DNAIndependentReactionTimeStepper&) = delete;
|
||||
public:
|
||||
G4DNAIndependentReactionTimeStepper();
|
||||
~G4DNAIndependentReactionTimeStepper() override = default;
|
||||
G4DNAIndependentReactionTimeStepper(
|
||||
const G4DNAIndependentReactionTimeStepper&) = delete;
|
||||
G4DNAIndependentReactionTimeStepper& operator =(
|
||||
const G4DNAIndependentReactionTimeStepper&) = delete;
|
||||
|
||||
void Prepare() override;
|
||||
G4double CalculateStep(const G4Track&, const G4double&) override;
|
||||
G4double CalculateMinTimeStep(G4double, G4double) override;
|
||||
void Prepare() override;
|
||||
G4double CalculateStep(const G4Track&, const G4double&) override;
|
||||
G4double CalculateMinTimeStep(G4double, G4double) override;
|
||||
|
||||
void SetReactionModel(G4VDNAReactionModel*);
|
||||
G4VDNAReactionModel* GetReactionModel();
|
||||
void SetReactionModel(G4VDNAReactionModel*);
|
||||
G4VDNAReactionModel* GetReactionModel();
|
||||
|
||||
std::unique_ptr<G4ITReactionChange>
|
||||
FindReaction(G4ITReactionSet* pReactionSet,
|
||||
const G4double& currentStepTime = 0,
|
||||
const G4double& previousStepTime = 0,
|
||||
const G4bool& reachedUserStepTimeLimit = false);
|
||||
std::unique_ptr<G4ITReactionChange> FindReaction(
|
||||
G4ITReactionSet* pReactionSet, const G4double& currentStepTime = 0,
|
||||
const G4double& previousStepTime = 0,
|
||||
const G4bool& reachedUserStepTimeLimit = false);
|
||||
void SetReactionProcess(G4VITReactionProcess* pReactionProcess);
|
||||
void SetVerbose(G4int);
|
||||
|
||||
void SetReactionProcess(G4VITReactionProcess* pReactionProcess);
|
||||
private:
|
||||
void InitializeForNewTrack();
|
||||
class Utils;
|
||||
void CheckAndRecordResults(const Utils& utils);
|
||||
|
||||
void SetReactionTypeManager(G4VReactionTypeManager* typeManager);
|
||||
void SetVerbose(G4int);
|
||||
private:
|
||||
void InitializeForNewTrack();
|
||||
ReactionType GetReactionType(const G4Track& trackA, const G4Track& trackB);
|
||||
G4double GetTimeToEncounter(const G4Track& trackA, const G4Track& trackB);
|
||||
|
||||
class Utils;
|
||||
G4bool fHasAlreadyReachedNullTime = false;
|
||||
const G4DNAMolecularReactionTable*& fMolecularReactionTable =
|
||||
reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable);
|
||||
G4VDNAReactionModel* fReactionModel = nullptr;
|
||||
G4ITTrackHolder* fpTrackContainer = G4ITTrackHolder::Instance();
|
||||
G4ITReactionSet* fReactionSet = G4ITReactionSet::Instance();
|
||||
G4int fVerbose = 0;
|
||||
G4double fRCutOff = G4IRTUtils::GetRCutOff();
|
||||
G4VITReactionProcess* fpReactionProcess = nullptr;
|
||||
std::map<G4int, G4ThreeVector> fSampledPositions;
|
||||
std::set<G4int> fCheckedTracks;
|
||||
|
||||
void CheckAndRecordResults(const Utils& utils);
|
||||
|
||||
G4double GetTimeToEncounter(const G4Track& trackA,
|
||||
const G4Track& trackB);
|
||||
|
||||
G4bool fHasAlreadyReachedNullTime;
|
||||
const G4DNAMolecularReactionTable*& fMolecularReactionTable;
|
||||
G4VDNAReactionModel* fReactionModel;
|
||||
G4ITTrackHolder* fpTrackContainer;
|
||||
G4ITReactionSet* fReactionSet;
|
||||
G4int fVerbose;
|
||||
G4double fRCutOff;
|
||||
G4DNAReactionTypeManager* fReactionTypeManager;
|
||||
|
||||
G4VITReactionProcess* fpReactionProcess;
|
||||
std::map<G4int,G4ThreeVector> fSampledPositions;
|
||||
|
||||
class Utils
|
||||
{
|
||||
public:
|
||||
Utils(const G4Track& tA, const G4Track& tB);
|
||||
~Utils() = default;
|
||||
const G4Track& fTrackA;
|
||||
const G4Track& fTrackB;
|
||||
const G4Molecule* fpMoleculeA;
|
||||
const G4Molecule* fpMoleculeB;
|
||||
};
|
||||
class Utils
|
||||
{
|
||||
public:
|
||||
Utils(const G4Track& tA, const G4Track& tB);
|
||||
~Utils() = default;
|
||||
const G4Track& fTrackA;
|
||||
const G4Track& fTrackB;
|
||||
const G4Molecule* fpMoleculeA;
|
||||
const G4Molecule* fpMoleculeB;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -131,6 +131,13 @@ private:
|
||||
G4DNAMillerGreenExcitationModel & operator=(const G4DNAMillerGreenExcitationModel &right);
|
||||
G4DNAMillerGreenExcitationModel(const G4DNAMillerGreenExcitationModel&);
|
||||
|
||||
// Reusable particle definitions
|
||||
G4ParticleDefinition* protonDef;
|
||||
G4ParticleDefinition* hydrogenDef;
|
||||
G4ParticleDefinition* alphaPlusPlusDef;
|
||||
G4ParticleDefinition* alphaPlusDef;
|
||||
G4ParticleDefinition* heliumDef;
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Created on 2022/03/03
|
||||
//
|
||||
// Authors: A.D. Dominguez-Munoz, M.I. Gallardo, M.C. Bordage,
|
||||
// Z. Francis, S. Incerti, M.A. Cortes-Giraldo
|
||||
//
|
||||
// Contact: M.A. Cortes-Giraldo (miancortes -at- us.es)
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef G4DNARPWBAExcitationModel_h
|
||||
#define G4DNARPWBAExcitationModel_h 1
|
||||
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4DNACrossSectionDataSet.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4DNAWaterExcitationStructure.hh"
|
||||
#include "G4NistManager.hh"
|
||||
|
||||
class G4DNARPWBAExcitationModel : public G4VEmModel
|
||||
{
|
||||
public:
|
||||
explicit G4DNARPWBAExcitationModel(
|
||||
const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& nam = "DNARPWBAExcitationModel");
|
||||
|
||||
~G4DNARPWBAExcitationModel() override;
|
||||
G4DNARPWBAExcitationModel& operator=(const G4DNARPWBAExcitationModel& right) =
|
||||
delete;
|
||||
G4DNARPWBAExcitationModel(const G4DNARPWBAExcitationModel&) = delete;
|
||||
void Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector& = *(new G4DataVector())) override;
|
||||
|
||||
G4double CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p, G4double ekin,
|
||||
G4double emin, G4double emax) override;
|
||||
|
||||
G4double GetPartialCrossSection(const G4Material*, G4int level,
|
||||
const G4ParticleDefinition*,
|
||||
G4double kineticEnergy) override;
|
||||
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*, const G4DynamicParticle*,
|
||||
G4double tmin, G4double maxEnergy) override;
|
||||
|
||||
inline void SelectStationary(const G4bool& input);
|
||||
|
||||
protected:
|
||||
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
|
||||
|
||||
private:
|
||||
// Partial cross section
|
||||
G4int RandomSelect(G4double energy);
|
||||
G4DNAWaterExcitationStructure waterStructure;
|
||||
G4bool statCode = false;
|
||||
// Water density table
|
||||
const std::vector<G4double>* fpMolWaterDensity = nullptr;
|
||||
G4bool isInitialised = false;
|
||||
G4int verboseLevel = 0;
|
||||
const G4ParticleDefinition* fParticleDefinition = G4Proton::ProtonDefinition();
|
||||
G4double fLowEnergy = 0;
|
||||
G4double fHighEnergy = 0;
|
||||
G4String fTableFile;
|
||||
std::unique_ptr<G4DNACrossSectionDataSet> fTableData;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline void G4DNARPWBAExcitationModel::SelectStationary(const G4bool& input)
|
||||
{
|
||||
statCode = input;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Created on 2022/03/03
|
||||
//
|
||||
// Authors: A.D. Dominguez-Munoz, M.I. Gallardo, M.C. Bordage,
|
||||
// Z. Francis, S. Incerti, M.A. Cortes-Giraldo
|
||||
//
|
||||
// Contact: M.A. Cortes-Giraldo (miancortes -at- us.es)
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef G4DNARPWBAIonisationModel_h
|
||||
#define G4DNARPWBAIonisationModel_h 1
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4DNACrossSectionDataSet.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4DNAGenericIonsManager.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4DNAWaterIonisationStructure.hh"
|
||||
#include "G4VAtomDeexcitation.hh"
|
||||
#include "G4NistManager.hh"
|
||||
|
||||
class G4DNARPWBAIonisationModel : public G4VEmModel
|
||||
{
|
||||
public:
|
||||
G4DNARPWBAIonisationModel(const G4ParticleDefinition* p = nullptr,
|
||||
const G4String& nam = "DNARPWBAIonisationModel");
|
||||
~G4DNARPWBAIonisationModel() override;
|
||||
G4DNARPWBAIonisationModel& operator=(const G4DNARPWBAIonisationModel& right) =
|
||||
delete;
|
||||
G4DNARPWBAIonisationModel(const G4DNARPWBAIonisationModel&) = delete;
|
||||
void Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector& = *(new G4DataVector())) override;
|
||||
|
||||
G4double CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p, G4double ekin,
|
||||
G4double emin, G4double emax) override;
|
||||
void SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple*, const G4DynamicParticle*,
|
||||
G4double tmin, G4double maxEnergy) override;
|
||||
G4double GetPartialCrossSection(const G4Material*, G4int /*level*/,
|
||||
const G4ParticleDefinition*,
|
||||
G4double /*kineticEnergy*/) override;
|
||||
G4double DifferentialCrossSection(const G4double& k, const G4double& energyTransfer,
|
||||
const G4int& shell);
|
||||
G4double TransferedEnergy(G4double incomingParticleEnergy, G4int shell,
|
||||
const G4double& random);
|
||||
inline void SelectFasterComputation(const G4bool& input);
|
||||
inline void SelectStationary(const G4bool& input);
|
||||
inline void SelectSPScaling(const G4bool& input);
|
||||
|
||||
protected:
|
||||
G4ParticleChangeForGamma* fParticleChangeForGamma = nullptr;
|
||||
|
||||
private:
|
||||
using MapData = std::map<G4String, std::unique_ptr<G4DNACrossSectionDataSet>,
|
||||
std::less<G4String>>;
|
||||
using TriDimensionMap = std::map<G4double, std::map<G4double, G4double>>;
|
||||
using VecMap = std::map<G4double, std::vector<G4double>>;
|
||||
// methods
|
||||
G4double RandomizeEjectedElectronEnergy(const G4double&, const G4int& );
|
||||
G4double RandomizeEjectedElectronEnergyFromCumulatedDcs(const G4double& incomingParticleEnergy,
|
||||
const G4int& shell);
|
||||
G4double Interpolate(const G4double& e1, const G4double& e2, const G4double& e, const G4double& xs1,
|
||||
const G4double& xs2);
|
||||
G4double QuadInterpolator(const G4double& e11, const G4double& e12, const G4double& e21,
|
||||
const G4double& e22, const G4double& x11, const G4double& x12,
|
||||
const G4double& x21, const G4double& x22, const G4double& t1,
|
||||
const G4double& t2, const G4double& t, const G4double& e);
|
||||
//shoud change to array ?
|
||||
G4int RandomSelect(G4double energy);
|
||||
void InitialiseForProton(const G4ParticleDefinition*);
|
||||
G4bool InEnergyLimit(const G4double&);
|
||||
|
||||
//members
|
||||
G4bool fasterCode = false;
|
||||
G4bool statCode = false;
|
||||
G4bool spScaling = true;
|
||||
// Water density table
|
||||
const std::vector<G4double>* fpMolWaterDensity = nullptr;
|
||||
// Deexcitation manager to produce fluo photons and e-
|
||||
G4VAtomDeexcitation* fAtomDeexcitation = nullptr;
|
||||
G4double lowEnergyLimit = 0;
|
||||
G4double highEnergyLimit = 0;
|
||||
G4bool isInitialised = false;
|
||||
G4int verboseLevel = 0;
|
||||
// Cross section
|
||||
|
||||
std::unique_ptr<G4DNACrossSectionDataSet> fpTotalCrossSection;
|
||||
// Final state
|
||||
G4DNAWaterIonisationStructure waterStructure;
|
||||
TriDimensionMap eDiffCrossSectionData[6];
|
||||
TriDimensionMap eNrjTransfData[6]; // for cumulated dcs
|
||||
TriDimensionMap pDiffCrossSectionData[6];
|
||||
TriDimensionMap pNrjTransfData[6]; // for cumulated dcs
|
||||
std::vector<G4double> eTdummyVec;
|
||||
std::vector<G4double> pTdummyVec;
|
||||
VecMap eVecm;
|
||||
VecMap pVecm;
|
||||
VecMap eProbaShellMap[6]; // for cumulated dcs
|
||||
VecMap pProbaShellMap[6]; // for cumulated dcs
|
||||
const G4ParticleDefinition* fProtonDef = G4Proton::ProtonDefinition();
|
||||
};
|
||||
|
||||
inline void G4DNARPWBAIonisationModel::SelectFasterComputation(
|
||||
const G4bool& input)
|
||||
{
|
||||
fasterCode = input;
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline void G4DNARPWBAIonisationModel::SelectStationary(const G4bool& input)
|
||||
{
|
||||
statCode = input;
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
inline void G4DNARPWBAIonisationModel::SelectSPScaling(const G4bool& input)
|
||||
{
|
||||
spScaling = input;
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#endif
|
||||
+18
@@ -158,12 +158,30 @@ private:
|
||||
G4double Sum(G4double energy, const G4String& particle);
|
||||
|
||||
G4int RandomSelect(G4double energy,const G4String& particle );
|
||||
|
||||
G4ParticleDefinition* GetDNAIonParticleDefinition(const G4ParticleDefinition* particleDefinition);
|
||||
|
||||
//
|
||||
|
||||
G4DNARuddIonisationExtendedModel & operator=(const G4DNARuddIonisationExtendedModel &right);
|
||||
G4DNARuddIonisationExtendedModel(const G4DNARuddIonisationExtendedModel&);
|
||||
|
||||
// Reusable particle definitions
|
||||
G4ParticleDefinition* protonDef;
|
||||
G4ParticleDefinition* hydrogenDef;
|
||||
G4ParticleDefinition* alphaPlusPlusDef;
|
||||
G4ParticleDefinition* alphaPlusDef;
|
||||
G4ParticleDefinition* heliumDef;
|
||||
|
||||
//G4ParticleDefinition* lithiumDef;
|
||||
//G4ParticleDefinition* berylliumDef;
|
||||
//G4ParticleDefinition* boronDef;
|
||||
G4ParticleDefinition* carbonDef;
|
||||
G4ParticleDefinition* nitrogenDef;
|
||||
G4ParticleDefinition* oxygenDef;
|
||||
G4ParticleDefinition* siliconDef;
|
||||
G4ParticleDefinition* ironDef;
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -155,6 +155,13 @@ private:
|
||||
G4DNARuddIonisationModel & operator=(const G4DNARuddIonisationModel &right);
|
||||
G4DNARuddIonisationModel(const G4DNARuddIonisationModel&);
|
||||
|
||||
// Reusable particle definitions
|
||||
G4ParticleDefinition* protonDef;
|
||||
G4ParticleDefinition* hydrogenDef;
|
||||
G4ParticleDefinition* alphaPlusPlusDef;
|
||||
G4ParticleDefinition* alphaPlusDef;
|
||||
G4ParticleDefinition* heliumDef;
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ public :
|
||||
virtual void InitialiseToPrint(const G4MolecularConfiguration*) ;
|
||||
virtual G4double GetReactionRadius(const G4MolecularConfiguration*,
|
||||
const G4MolecularConfiguration*);
|
||||
virtual G4double GetReactionRadius(const G4int);
|
||||
virtual G4double GetReactionRadius(const G4int&);
|
||||
|
||||
virtual G4bool FindReaction(const G4Track&,
|
||||
const G4Track&,
|
||||
|
||||
@@ -36,7 +36,7 @@ class G4DNAMolecularReactionData;
|
||||
class G4DNAUpdateSystemModel : public G4VUpdateSystemModel
|
||||
{
|
||||
public:
|
||||
using Index = G4Voxel::Index;
|
||||
using Index = G4VDNAMesh::Index;
|
||||
using MolType = const G4MolecularConfiguration*;
|
||||
using JumpingData = std::pair<MolType, Index>;
|
||||
using ReactionData = const G4DNAMolecularReactionData;
|
||||
@@ -45,21 +45,18 @@ class G4DNAUpdateSystemModel : public G4VUpdateSystemModel
|
||||
~G4DNAUpdateSystemModel() override = default;
|
||||
void UpdateSystem(const Index& index, const ReactionData& data);
|
||||
void UpdateSystem(const Index& index, const JumpingData& data);
|
||||
|
||||
void KillMolecule(const Index& index, MolType type);
|
||||
void CreateMolecule(const Index& index, MolType);
|
||||
|
||||
void JumpTo(const Index& index, MolType type);
|
||||
void JumpIn(const Index& index, MolType);
|
||||
|
||||
void SetMesh(G4DNAMesh*);
|
||||
void SetGlobalTime(const G4double& globalTime) { fGlobalTime = globalTime; }
|
||||
void SetVerbose(G4int verbose) { fVerbose = verbose; }
|
||||
|
||||
private:
|
||||
G4DNAMesh* fpMesh;
|
||||
G4int fVerbose;
|
||||
G4double fGlobalTime;
|
||||
void KillMolecule(const Index& index, MolType type);
|
||||
void CreateMolecule(const Index& index, MolType);
|
||||
void JumpTo(const Index& index, MolType type);
|
||||
void JumpIn(const Index& index, MolType);
|
||||
G4DNAMesh* fpMesh = nullptr;
|
||||
G4int fVerbose = 0;
|
||||
G4double fGlobalTime = DBL_MAX;
|
||||
};
|
||||
|
||||
#endif // G4DNAUPDATESYSTEMMODEL_HH
|
||||
|
||||
+23
-24
@@ -32,35 +32,34 @@
|
||||
#include "G4VDNAReactionModel.hh"
|
||||
#include <vector>
|
||||
class G4DNAMolecularReactionData;
|
||||
class G4VReactionTypeManager;
|
||||
class G4DNAReactionTypeManager;
|
||||
class G4DiffusionControlledReactionModel : public G4VDNAReactionModel
|
||||
{
|
||||
public :
|
||||
G4DiffusionControlledReactionModel();
|
||||
~G4DiffusionControlledReactionModel() override;
|
||||
public:
|
||||
G4DiffusionControlledReactionModel();
|
||||
~G4DiffusionControlledReactionModel() override;
|
||||
|
||||
G4DiffusionControlledReactionModel(const G4DiffusionControlledReactionModel&) = delete;
|
||||
G4DiffusionControlledReactionModel& operator=(const G4DiffusionControlledReactionModel&) = delete;
|
||||
G4DiffusionControlledReactionModel(
|
||||
const G4DiffusionControlledReactionModel&) = delete;
|
||||
G4DiffusionControlledReactionModel& operator =(
|
||||
const G4DiffusionControlledReactionModel&) = delete;
|
||||
|
||||
void Initialise(const G4MolecularConfiguration*, const G4Track&) override;
|
||||
void InitialiseToPrint(const G4MolecularConfiguration*) override;
|
||||
G4double GetReactionRadius(const G4MolecularConfiguration*,
|
||||
const G4MolecularConfiguration*) override;
|
||||
G4double GetReactionRadius(G4int) override;
|
||||
void Initialise(const G4MolecularConfiguration*, const G4Track&) override;
|
||||
void InitialiseToPrint(const G4MolecularConfiguration*) override;
|
||||
G4double GetReactionRadius(const G4MolecularConfiguration*,
|
||||
const G4MolecularConfiguration*) override;
|
||||
G4double GetReactionRadius(const G4int&) override;
|
||||
|
||||
G4bool FindReaction(const G4Track&,
|
||||
const G4Track&,
|
||||
G4double /*reactionRadius*/,
|
||||
G4double& /*separationDistance*/,
|
||||
G4bool /*alongStepInteraction*/) override
|
||||
{return true;}
|
||||
|
||||
void SetReactionTypeManager(G4VReactionTypeManager* typeManager);
|
||||
|
||||
private :
|
||||
const std::vector<const G4DNAMolecularReactionData*>* fpReactionData ;
|
||||
G4DNAReactionTypeManager* fReactionTypeManager;
|
||||
G4bool FindReaction(const G4Track&, const G4Track&,
|
||||
G4double /*reactionRadius*/,
|
||||
G4double& /*separationDistance*/,
|
||||
G4bool /*alongStepInteraction*/) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
G4double GetTimeToEncounter(const G4Track& trackA, const G4Track& trackB);
|
||||
|
||||
private:
|
||||
const std::vector<const G4DNAMolecularReactionData*>* fpReactionData =
|
||||
nullptr;
|
||||
};
|
||||
#endif
|
||||
+24
-26
@@ -23,34 +23,32 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// 20/2/2019
|
||||
// Author : HoangTRAN
|
||||
#ifndef G4VDNAHitModel_hh
|
||||
#define G4VDNAHitModel_hh
|
||||
#include "globals.hh"
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
class G4DNAComponentNode;
|
||||
class G4VPhysicalVolume;
|
||||
class G4Track;
|
||||
|
||||
#ifndef G4DNAPartiallyDiffusionControlled_h
|
||||
#define G4DNAPartiallyDiffusionControlled_h 1
|
||||
#include "G4DNAReactionTypeManager.hh"
|
||||
#include "G4VReactionType.hh"
|
||||
|
||||
class G4MolecularConfiguration;
|
||||
|
||||
class G4DNAPartiallyDiffusionControlled
|
||||
: public G4VReactionType
|
||||
class G4VDNAHitModel
|
||||
{
|
||||
public:
|
||||
G4DNAPartiallyDiffusionControlled();
|
||||
~G4DNAPartiallyDiffusionControlled() override;
|
||||
G4DNAPartiallyDiffusionControlled(const G4DNAPartiallyDiffusionControlled& other) = delete;
|
||||
G4DNAPartiallyDiffusionControlled& operator=(const G4DNAPartiallyDiffusionControlled& other) = delete;
|
||||
using DNANode =
|
||||
std::variant<const G4DNAComponentNode*, /*for dnadamage chain*/
|
||||
const G4VPhysicalVolume* /*for molecularDNA chain*/>;
|
||||
|
||||
G4double GetTimeToEncounter(const G4Track& trackA,
|
||||
const G4Track& trackB) override;
|
||||
public:
|
||||
explicit G4VDNAHitModel(const G4String& name);
|
||||
virtual ~G4VDNAHitModel() = default;
|
||||
// delete assignment operator
|
||||
G4VDNAHitModel& operator=(const G4VDNAHitModel& right) = delete;
|
||||
G4VDNAHitModel(const G4VDNAHitModel&) = delete;
|
||||
virtual G4double CalculateReactionTime(const G4Track& trackA, DNANode&) = 0;
|
||||
virtual G4bool DoReaction(const G4Track& track, const G4double&,
|
||||
const DNANode&) = 0;
|
||||
|
||||
G4bool GeminateRecombinationProbability(const G4MolecularConfiguration*,
|
||||
const G4MolecularConfiguration*) override;
|
||||
|
||||
private:
|
||||
|
||||
G4double GetDiffusionCoefficient(const G4MolecularConfiguration*,
|
||||
const G4MolecularConfiguration*);
|
||||
private:
|
||||
const G4String fName;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
@@ -23,7 +23,6 @@ geant4_add_module(G4emdna-models
|
||||
G4DNAELSEPAElasticModel.hh
|
||||
G4DNAIonElasticModel.hh
|
||||
G4DNAIRT.hh
|
||||
G4DNAIRT_geometries.hh
|
||||
G4DNAIRTMoleculeEncounterStepper.hh
|
||||
G4DNAMeltonAttachmentModel.hh
|
||||
G4DNAMillerGreenExcitationModel.hh
|
||||
@@ -67,13 +66,14 @@ geant4_add_module(G4emdna-models
|
||||
G4DNAIndependentReactionTimeModel.hh
|
||||
G4DNAIndependentReactionTimeStepper.hh
|
||||
G4DNAMakeReaction.hh
|
||||
G4DNAPartiallyDiffusionControlled.hh
|
||||
G4DNATotallyDiffusionControlled.hh
|
||||
G4DNAUpdateSystemModel.hh
|
||||
G4DNAGillespieDirectMethod.hh
|
||||
G4VUpdateSystemModel.hh
|
||||
G4DNAUpdateSystemModel.hh
|
||||
G4DNAEventScheduler.hh
|
||||
G4DNARPWBAExcitationModel.hh
|
||||
G4DNARPWBAIonisationModel.hh
|
||||
G4VDNAHitModel.hh
|
||||
SOURCES
|
||||
G4DNABornAngle.cc
|
||||
G4DNABornExcitationModel1.cc
|
||||
@@ -93,7 +93,6 @@ geant4_add_module(G4emdna-models
|
||||
G4DNAEmfietzoglouIonisationModel.cc
|
||||
G4DNAIonElasticModel.cc
|
||||
G4DNAIRT.cc
|
||||
G4DNAIRT_geometries.cc
|
||||
G4DNAIRTMoleculeEncounterStepper.cc
|
||||
G4DNAMeltonAttachmentModel.cc
|
||||
G4DNAMillerGreenExcitationModel.cc
|
||||
@@ -136,12 +135,13 @@ geant4_add_module(G4emdna-models
|
||||
G4DNAIndependentReactionTimeModel.cc
|
||||
G4DNAIndependentReactionTimeStepper.cc
|
||||
G4DNAMakeReaction.cc
|
||||
G4DNAPartiallyDiffusionControlled.cc
|
||||
G4DNATotallyDiffusionControlled.cc
|
||||
G4DNAUpdateSystemModel.cc
|
||||
G4DNAGillespieDirectMethod.cc
|
||||
G4DNAUpdateSystemModel.cc
|
||||
G4DNAEventScheduler.cc)
|
||||
G4DNAEventScheduler.cc
|
||||
G4DNARPWBAExcitationModel.cc
|
||||
G4DNARPWBAIonisationModel.cc
|
||||
G4VDNAHitModel.cc)
|
||||
|
||||
geant4_module_link_libraries(G4emdna-models
|
||||
PUBLIC
|
||||
|
||||
@@ -100,7 +100,7 @@ void G4DNABornExcitationModel2::Initialise(const G4ParticleDefinition* particle,
|
||||
fParticleDefinition = particle;
|
||||
|
||||
std::ostringstream fullFileName;
|
||||
char *path = std::getenv("G4LEDATA");
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
if(G4String(path) == "")
|
||||
{
|
||||
|
||||
@@ -124,7 +124,7 @@ void G4DNABornIonisationModel1::Initialise(const G4ParticleDefinition* particle,
|
||||
|
||||
G4double scaleFactor = (1.e-22 / 3.343) * m*m;
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
// *** ELECTRON
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ void G4DNABornIonisationModel2::Initialise(const G4ParticleDefinition* particle,
|
||||
fParticleDef = particle;
|
||||
|
||||
// Energy limits
|
||||
char *path = std::getenv("G4LEDATA");
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
// ***
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ void G4DNACPA100ElasticModel::Initialise(const G4ParticleDefinition*
|
||||
|
||||
// For final state
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
if (!path)
|
||||
{
|
||||
|
||||
@@ -136,7 +136,7 @@ void G4DNACPA100IonisationModel::Initialise(const G4ParticleDefinition* particle
|
||||
|
||||
G4double scaleFactor = 1.e-20 * m*m;
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
// *** ELECTRON
|
||||
|
||||
@@ -952,8 +952,16 @@ G4double G4DNACPA100IonisationModel::RandomTransferedEnergy
|
||||
<< nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
|
||||
*/
|
||||
|
||||
}
|
||||
// Avoids cases where cum xs is 1 in last bin only and zero everywhere else
|
||||
|
||||
if (valuePROB11==0. && valuePROB12==1.)
|
||||
{
|
||||
G4double interpolatedvalue2 = Interpolate(valuePROB21, valuePROB22, random, nrjTransf21, nrjTransf22);
|
||||
G4double valueNrjTransf = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
|
||||
return valueNrjTransf;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ void G4DNAChampionElasticModel::Initialise(const G4ParticleDefinition* particle,
|
||||
|
||||
// For final state
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
if (!path)
|
||||
{
|
||||
|
||||
+40
-51
@@ -30,6 +30,12 @@
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4Alpha.hh"
|
||||
|
||||
|
||||
static G4Pow * gpow = G4Pow::GetInstance();
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -87,9 +93,11 @@ void G4DNADingfelderChargeDecreaseModel::Initialise(const G4ParticleDefinition*
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
|
||||
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
|
||||
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
|
||||
protonDef = G4Proton::ProtonDefinition();
|
||||
alphaPlusPlusDef = G4Alpha::Alpha();
|
||||
alphaPlusDef = instance->GetIon("alpha+");
|
||||
hydrogenDef = instance->GetIon("hydrogen");
|
||||
heliumDef = instance->GetIon("helium");
|
||||
|
||||
G4String proton;
|
||||
G4String alphaPlusPlus;
|
||||
@@ -220,16 +228,12 @@ G4double G4DNADingfelderChargeDecreaseModel::CrossSectionPerVolume(const G4Mater
|
||||
}
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (
|
||||
particleDefinition != G4Proton::ProtonDefinition()
|
||||
particleDefinition != protonDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha++")
|
||||
particleDefinition != alphaPlusPlusDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha+")
|
||||
particleDefinition != alphaPlusDef
|
||||
)
|
||||
|
||||
return 0;
|
||||
@@ -365,17 +369,14 @@ G4int G4DNADingfelderChargeDecreaseModel::NumberOfFinalStates(G4ParticleDefiniti
|
||||
if (particleDefinition == G4Proton::Proton())
|
||||
return 1;
|
||||
|
||||
G4DNAGenericIonsManager*instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha++"))
|
||||
if (particleDefinition == alphaPlusPlusDef)
|
||||
{
|
||||
if (finalStateIndex == 0)
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -386,20 +387,18 @@ G4int G4DNADingfelderChargeDecreaseModel::NumberOfFinalStates(G4ParticleDefiniti
|
||||
G4ParticleDefinition* G4DNADingfelderChargeDecreaseModel::OutgoingParticleDefinition(G4ParticleDefinition* particleDefinition,
|
||||
G4int finalStateIndex)
|
||||
{
|
||||
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
|
||||
|
||||
if (particleDefinition == G4Proton::Proton())
|
||||
return instance->GetIon("hydrogen");
|
||||
return hydrogenDef;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha++"))
|
||||
if (particleDefinition == alphaPlusPlusDef)
|
||||
{
|
||||
if (finalStateIndex == 0)
|
||||
return instance->GetIon("alpha+");
|
||||
return instance->GetIon("helium");
|
||||
return alphaPlusDef;
|
||||
return heliumDef;
|
||||
}
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
return instance->GetIon("helium");
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
return heliumDef;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -413,12 +412,10 @@ G4double G4DNADingfelderChargeDecreaseModel::WaterBindingEnergyConstant(G4Partic
|
||||
// Rad. Phys. Chem. 59 p.267 by Dingf. et al.
|
||||
// W + 10.79 eV -> W+ + e-
|
||||
|
||||
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
|
||||
|
||||
if (particleDefinition == G4Proton::Proton())
|
||||
return 10.79 * eV;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha++"))
|
||||
if (particleDefinition == alphaPlusPlusDef)
|
||||
{
|
||||
// Binding energy for W+ -> W++ + e- 10.79 eV
|
||||
// Binding energy for W -> W+ + e- 10.79 eV
|
||||
@@ -432,7 +429,7 @@ G4double G4DNADingfelderChargeDecreaseModel::WaterBindingEnergyConstant(G4Partic
|
||||
return 10.79 * 2 * eV;
|
||||
}
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
{
|
||||
// Binding energy for W+ -> W++ + e- 10.79 eV
|
||||
// Binding energy for W -> W+ + e- 10.79 eV
|
||||
@@ -451,12 +448,10 @@ G4double G4DNADingfelderChargeDecreaseModel::WaterBindingEnergyConstant(G4Partic
|
||||
G4double G4DNADingfelderChargeDecreaseModel::OutgoingParticleBindingEnergyConstant(G4ParticleDefinition* particleDefinition,
|
||||
G4int finalStateIndex)
|
||||
{
|
||||
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
|
||||
|
||||
if (particleDefinition == G4Proton::Proton())
|
||||
return 13.6 * eV;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha++"))
|
||||
if (particleDefinition == alphaPlusPlusDef)
|
||||
{
|
||||
// Binding energy for He+ -> He++ + e- 54.509 eV
|
||||
// Binding energy for He -> He+ + e- 24.587 eV
|
||||
@@ -467,7 +462,7 @@ G4double G4DNADingfelderChargeDecreaseModel::OutgoingParticleBindingEnergyConsta
|
||||
return (54.509 + 24.587) * eV;
|
||||
}
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
{
|
||||
// Binding energy for He+ -> He++ + e- 54.509 eV
|
||||
// Binding energy for He -> He+ + e- 24.587 eV
|
||||
@@ -485,16 +480,14 @@ G4double G4DNADingfelderChargeDecreaseModel::PartialCrossSection(G4double k,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
G4DNAGenericIonsManager* instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition())
|
||||
if (particleDefinition == protonDef)
|
||||
particleTypeIndex = 0;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha++"))
|
||||
if (particleDefinition == alphaPlusPlusDef)
|
||||
particleTypeIndex = 1;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
particleTypeIndex = 2;
|
||||
|
||||
//
|
||||
@@ -526,7 +519,7 @@ G4double G4DNADingfelderChargeDecreaseModel::PartialCrossSection(G4double k,
|
||||
//
|
||||
|
||||
x1[index][particleTypeIndex] = x0[index][particleTypeIndex]
|
||||
+ std::pow((a0[index][particleTypeIndex] - a1[index][particleTypeIndex])
|
||||
+ gpow->powA((a0[index][particleTypeIndex] - a1[index][particleTypeIndex])
|
||||
/ (c0[index][particleTypeIndex]
|
||||
* d0[index][particleTypeIndex]),
|
||||
1. / (d0[index][particleTypeIndex] - 1.));
|
||||
@@ -534,12 +527,12 @@ G4double G4DNADingfelderChargeDecreaseModel::PartialCrossSection(G4double k,
|
||||
- a1[index][particleTypeIndex]) * x1[index][particleTypeIndex]
|
||||
+ b0[index][particleTypeIndex]
|
||||
- c0[index][particleTypeIndex]
|
||||
* std::pow(x1[index][particleTypeIndex]
|
||||
* gpow->powA(x1[index][particleTypeIndex]
|
||||
- x0[index][particleTypeIndex],
|
||||
d0[index][particleTypeIndex]);
|
||||
}
|
||||
|
||||
G4double x(std::log10(k / eV));
|
||||
G4double x(G4Log(k / eV)/gpow->logZ(10));
|
||||
G4double y;
|
||||
|
||||
if (x < x0[index][particleTypeIndex])
|
||||
@@ -547,12 +540,12 @@ G4double G4DNADingfelderChargeDecreaseModel::PartialCrossSection(G4double k,
|
||||
else if (x < x1[index][particleTypeIndex])
|
||||
y = a0[index][particleTypeIndex] * x + b0[index][particleTypeIndex]
|
||||
- c0[index][particleTypeIndex]
|
||||
* std::pow(x - x0[index][particleTypeIndex],
|
||||
* gpow->powA(x - x0[index][particleTypeIndex],
|
||||
d0[index][particleTypeIndex]);
|
||||
else
|
||||
y = a1[index][particleTypeIndex] * x + b1[index][particleTypeIndex];
|
||||
|
||||
return f0[index][particleTypeIndex] * std::pow(10., y) * m * m;
|
||||
return f0[index][particleTypeIndex] * gpow->powA(10., y) * m * m;
|
||||
|
||||
}
|
||||
|
||||
@@ -560,16 +553,14 @@ G4int G4DNADingfelderChargeDecreaseModel::RandomSelect(G4double k,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition())
|
||||
if (particleDefinition == protonDef)
|
||||
particleTypeIndex = 0;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha++"))
|
||||
if (particleDefinition == alphaPlusPlusDef)
|
||||
particleTypeIndex = 1;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
particleTypeIndex = 2;
|
||||
|
||||
const G4int n = numberOfPartialCrossSections[particleTypeIndex];
|
||||
@@ -608,16 +599,14 @@ G4double G4DNADingfelderChargeDecreaseModel::Sum(G4double k,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
G4DNAGenericIonsManager* instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition())
|
||||
if (particleDefinition == protonDef)
|
||||
particleTypeIndex = 0;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha++"))
|
||||
if (particleDefinition == alphaPlusPlusDef)
|
||||
particleTypeIndex = 1;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
particleTypeIndex = 2;
|
||||
|
||||
G4double totalCrossSection = 0.;
|
||||
|
||||
+40
-50
@@ -29,6 +29,11 @@
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4Alpha.hh"
|
||||
|
||||
static G4Pow * gpow = G4Pow::GetInstance();
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -85,9 +90,10 @@ void G4DNADingfelderChargeIncreaseModel::Initialise(const G4ParticleDefinition*
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
|
||||
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
|
||||
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
|
||||
hydrogenDef = instance->GetIon("hydrogen");
|
||||
alphaPlusPlusDef = G4Alpha::Alpha();
|
||||
alphaPlusDef = instance->GetIon("alpha+");
|
||||
heliumDef = instance->GetIon("helium");
|
||||
|
||||
G4String hydrogen;
|
||||
G4String alphaPlus;
|
||||
@@ -208,15 +214,12 @@ G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Mater
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (
|
||||
particleDefinition != instance->GetIon("hydrogen")
|
||||
particleDefinition != hydrogenDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha+")
|
||||
particleDefinition != alphaPlusDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("helium")
|
||||
particleDefinition != heliumDef
|
||||
)
|
||||
|
||||
return 0;
|
||||
@@ -248,7 +251,7 @@ G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Mater
|
||||
if (k >= lowLim && k <= highLim)
|
||||
{
|
||||
//HYDROGEN
|
||||
if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
if (particleDefinition == hydrogenDef)
|
||||
{
|
||||
const G4double aa = 2.835;
|
||||
const G4double bb = 0.310;
|
||||
@@ -260,8 +263,8 @@ G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Mater
|
||||
G4double t = k / (proton_mass_c2/electron_mass_c2);
|
||||
G4double x = t / rr;
|
||||
G4double temp = 4.0 * pi * Bohr_radius/nm * Bohr_radius/nm * fac;
|
||||
G4double sigmal = temp * cc * (std::pow(x,dd));
|
||||
G4double sigmah = temp * (aa * std::log(1.0 + x) + bb) / x;
|
||||
G4double sigmal = temp * cc * (gpow->powA(x,dd));
|
||||
G4double sigmah = temp * (aa * G4Log(1.0 + x) + bb) / x;
|
||||
totalCrossSection = 1.0/(1.0/sigmal + 1.0/sigmah) *m*m;
|
||||
}
|
||||
else
|
||||
@@ -327,11 +330,8 @@ void G4DNADingfelderChargeIncreaseModel::SampleSecondaries(std::vector<
|
||||
|
||||
fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
G4DNAGenericIonsManager* instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
G4double electronK;
|
||||
if (definition == instance->GetIon("hydrogen")) electronK = inK*electron_mass_c2/proton_mass_c2;
|
||||
if (definition == hydrogenDef) electronK = inK*electron_mass_c2/proton_mass_c2;
|
||||
else electronK = inK*electron_mass_c2/(particleMass);
|
||||
|
||||
if (outK<0)
|
||||
@@ -362,16 +362,14 @@ G4int G4DNADingfelderChargeIncreaseModel::NumberOfFinalStates(G4ParticleDefiniti
|
||||
G4int finalStateIndex)
|
||||
|
||||
{
|
||||
G4DNAGenericIonsManager* instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
if (particleDefinition == hydrogenDef)
|
||||
return 2;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
return 2;
|
||||
|
||||
if (particleDefinition == instance->GetIon("helium"))
|
||||
if (particleDefinition == heliumDef)
|
||||
{
|
||||
if (finalStateIndex == 0)
|
||||
return 2;
|
||||
@@ -386,19 +384,18 @@ G4int G4DNADingfelderChargeIncreaseModel::NumberOfFinalStates(G4ParticleDefiniti
|
||||
G4ParticleDefinition* G4DNADingfelderChargeIncreaseModel::OutgoingParticleDefinition(G4ParticleDefinition* particleDefinition,
|
||||
G4int finalStateIndex)
|
||||
{
|
||||
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
if (particleDefinition == hydrogenDef)
|
||||
return G4Proton::Proton();
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
return instance->GetIon("alpha++");
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
return alphaPlusPlusDef;
|
||||
|
||||
if (particleDefinition == instance->GetIon("helium"))
|
||||
if (particleDefinition == heliumDef)
|
||||
{
|
||||
if (finalStateIndex == 0)
|
||||
return instance->GetIon("alpha+");
|
||||
return instance->GetIon("alpha++");
|
||||
return alphaPlusDef;
|
||||
return alphaPlusPlusDef;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -409,19 +406,18 @@ G4ParticleDefinition* G4DNADingfelderChargeIncreaseModel::OutgoingParticleDefini
|
||||
G4double G4DNADingfelderChargeIncreaseModel::IncomingParticleBindingEnergyConstant(G4ParticleDefinition* particleDefinition,
|
||||
G4int finalStateIndex)
|
||||
{
|
||||
G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance());
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
if (particleDefinition == hydrogenDef)
|
||||
return 13.6 * eV;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
{
|
||||
// Binding energy for He+ -> He++ + e- 54.509 eV
|
||||
// Binding energy for He -> He+ + e- 24.587 eV
|
||||
return 54.509 * eV;
|
||||
}
|
||||
|
||||
if (particleDefinition == instance->GetIon("helium"))
|
||||
if (particleDefinition == heliumDef)
|
||||
{
|
||||
// Binding energy for He+ -> He++ + e- 54.509 eV
|
||||
// Binding energy for He -> He+ + e- 24.587 eV
|
||||
@@ -441,13 +437,11 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
particleTypeIndex = 0;
|
||||
|
||||
if (particleDefinition == instance->GetIon("helium"))
|
||||
if (particleDefinition == heliumDef)
|
||||
particleTypeIndex = 1;
|
||||
|
||||
//
|
||||
@@ -481,7 +475,7 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
|
||||
//
|
||||
|
||||
x1[index][particleTypeIndex] = x0[index][particleTypeIndex]
|
||||
+ std::pow((a0[index][particleTypeIndex] - a1[index][particleTypeIndex])
|
||||
+ gpow->powA((a0[index][particleTypeIndex] - a1[index][particleTypeIndex])
|
||||
/ (c0[index][particleTypeIndex]
|
||||
* d0[index][particleTypeIndex]),
|
||||
1. / (d0[index][particleTypeIndex] - 1.));
|
||||
@@ -489,12 +483,12 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
|
||||
- a1[index][particleTypeIndex]) * x1[index][particleTypeIndex]
|
||||
+ b0[index][particleTypeIndex]
|
||||
- c0[index][particleTypeIndex]
|
||||
* std::pow(x1[index][particleTypeIndex]
|
||||
* gpow->powA(x1[index][particleTypeIndex]
|
||||
- x0[index][particleTypeIndex],
|
||||
d0[index][particleTypeIndex]);
|
||||
}
|
||||
|
||||
G4double x(std::log10(k / eV));
|
||||
G4double x(G4Log(k / eV)/gpow->logZ(10));
|
||||
G4double y;
|
||||
|
||||
if (x < x0[index][particleTypeIndex])
|
||||
@@ -502,12 +496,12 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
|
||||
else if (x < x1[index][particleTypeIndex])
|
||||
y = a0[index][particleTypeIndex] * x + b0[index][particleTypeIndex]
|
||||
- c0[index][particleTypeIndex]
|
||||
* std::pow(x - x0[index][particleTypeIndex],
|
||||
* gpow->powA(x - x0[index][particleTypeIndex],
|
||||
d0[index][particleTypeIndex]);
|
||||
else
|
||||
y = a1[index][particleTypeIndex] * x + b1[index][particleTypeIndex];
|
||||
|
||||
return f0[index][particleTypeIndex] * std::pow(10., y) * m * m;
|
||||
return f0[index][particleTypeIndex] * gpow->powA(10., y) * m * m;
|
||||
|
||||
}
|
||||
|
||||
@@ -517,16 +511,14 @@ G4int G4DNADingfelderChargeIncreaseModel::RandomSelect(G4double k,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
if (particleDefinition == hydrogenDef)
|
||||
return 0;
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
particleTypeIndex = 0;
|
||||
|
||||
if (particleDefinition == instance->GetIon("helium"))
|
||||
if (particleDefinition == heliumDef)
|
||||
particleTypeIndex = 1;
|
||||
|
||||
const G4int n = numberOfPartialCrossSections[particleTypeIndex];
|
||||
@@ -565,13 +557,11 @@ G4double G4DNADingfelderChargeIncreaseModel::Sum(G4double k,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha+"))
|
||||
if (particleDefinition == alphaPlusDef)
|
||||
particleTypeIndex = 0;
|
||||
|
||||
if (particleDefinition == instance->GetIon("helium"))
|
||||
if (particleDefinition == heliumDef)
|
||||
particleTypeIndex = 1;
|
||||
|
||||
G4double totalCrossSection = 0.;
|
||||
|
||||
@@ -212,7 +212,7 @@ const G4DataVector& )
|
||||
fpData_Au->LoadData(fileZElectron);
|
||||
|
||||
std::ostringstream eFullFileNameZ;
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4Exception("G4DNAELSEPAElasticModel::Initialise","em0002",
|
||||
@@ -306,7 +306,7 @@ const G4DataVector& )
|
||||
|
||||
std::ostringstream eFullFileNameZ;
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4Exception("G4DNAELSEPAElasticModel::Initialise","em0004",
|
||||
|
||||
@@ -127,7 +127,7 @@ void G4DNAEmfietzoglouIonisationModel::Initialise(const G4ParticleDefinition* pa
|
||||
|
||||
G4double scaleFactor = (1.e-22 / 3.343) * m*m;
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
// *** ELECTRON
|
||||
|
||||
|
||||
@@ -36,31 +36,17 @@
|
||||
#include "G4UserMeshAction.hh"
|
||||
#include "G4MoleculeCounter.hh"
|
||||
#include "G4DNAScavengerMaterial.hh"
|
||||
#include "G4Molecule.hh"
|
||||
|
||||
G4DNAEventScheduler::G4DNAEventScheduler(const G4DNABoundingBox& boundingBox,
|
||||
G4int pixel)
|
||||
: IEventScheduler()
|
||||
, fVerbose(0)
|
||||
, fInitialized(false)
|
||||
, fStartTime(1 * ps)
|
||||
, fEndTime(10000 * s)
|
||||
, fStepNumber(0)
|
||||
, fMaxStep(INT_MAX)
|
||||
, fRunning(true)
|
||||
, fTimeStep(DBL_MAX)
|
||||
, fGlobalTime(fStartTime)
|
||||
, fJumpingNumber(0)
|
||||
, fReactionNumber(0)
|
||||
, fPixel(pixel)
|
||||
, fIsChangeMesh(false)
|
||||
, fSetChangeMesh(true)
|
||||
, fStepNumberInMesh(0)
|
||||
, fInitialPixels(fPixel)
|
||||
, fpMesh(new G4DNAMesh(boundingBox, fPixel))
|
||||
, fpGillespieReaction(new G4DNAGillespieDirectMethod())
|
||||
, fpEventSet(new G4DNAEventSet())
|
||||
, fpUpdateSystem(new G4DNAUpdateSystemModel())
|
||||
, fpUserMeshAction(nullptr)
|
||||
{
|
||||
if(!CheckingReactionRadius(fpMesh->GetResolution()))
|
||||
{
|
||||
@@ -76,7 +62,9 @@ void G4DNAEventScheduler::ClearAndReChargeCounter()
|
||||
fCounterMap.clear();
|
||||
if(fTimeToRecord.empty())
|
||||
{
|
||||
G4cout << "fTimeToRecord is empty " << G4endl;
|
||||
G4String WarMessage = "fTimeToRecord is empty ";
|
||||
G4Exception("G4DNAEventScheduler::ClearAndReChargeCounter()",
|
||||
"TimeToRecord is empty", JustWarning, WarMessage);
|
||||
}
|
||||
fLastRecoredTime = fTimeToRecord.begin();
|
||||
|
||||
@@ -114,12 +102,18 @@ void G4DNAEventScheduler::ClearAndReChargeCounter()
|
||||
}
|
||||
fCounterMap[time_mol][molecule] = n_mol;
|
||||
}
|
||||
|
||||
fLastRecoredTime++;
|
||||
}
|
||||
G4MoleculeCounter::Instance()->ResetCounter(); // reset
|
||||
G4MoleculeCounter::Instance()->Use(false); // no more used
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "G4VMoleculeCounter is not used";
|
||||
G4Exception("G4DNAEventScheduler::ClearAndReChargeCounter()",
|
||||
"G4DNAEventScheduler010", JustWarning, exceptionDescription);
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]] void G4DNAEventScheduler::AddTimeToRecord(const G4double& time)
|
||||
@@ -135,7 +129,7 @@ G4DNAEventScheduler::~G4DNAEventScheduler() = default;
|
||||
void G4DNAEventScheduler::Voxelizing()
|
||||
{
|
||||
auto pMainList = G4ITTrackHolder::Instance()->GetMainList();
|
||||
std::map<G4DNAMesh::Key, MapList> TrackKeyMap;
|
||||
std::map<G4VDNAMesh::Index, MapList> TrackKeyMap;
|
||||
for(auto track : *pMainList)
|
||||
{
|
||||
auto molType = GetMolecule(track)->GetMolecularConfiguration();
|
||||
@@ -148,7 +142,7 @@ void G4DNAEventScheduler::Voxelizing()
|
||||
continue;
|
||||
}
|
||||
|
||||
auto key = fpMesh->GetKey(track->GetPosition());
|
||||
auto key = fpMesh->GetIndex(track->GetPosition());
|
||||
if(TrackKeyMap.find(key) != TrackKeyMap.end())
|
||||
{
|
||||
std::map<MolType, size_t>& TrackTypeMap = TrackKeyMap[key];
|
||||
@@ -169,7 +163,7 @@ void G4DNAEventScheduler::Voxelizing()
|
||||
|
||||
for(auto& it : TrackKeyMap)
|
||||
{
|
||||
fpMesh->SetVoxelMapList(it.first, std::move(it.second));
|
||||
fpMesh->InitializeVoxel(it.first, std::move(it.second));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,29 +174,26 @@ void G4DNAEventScheduler::ReVoxelizing(G4int pixel)
|
||||
|
||||
auto begin = fpMesh->begin();
|
||||
auto end = fpMesh->end();
|
||||
std::map<G4DNAMesh::Key, MapList> TrackKeyMap;
|
||||
std::map<G4VDNAMesh::Index, MapList> TrackKeyMap;
|
||||
for(; begin != end; begin++)
|
||||
{
|
||||
auto index = fpMesh->GetIndex(begin->first);
|
||||
auto newKey = newMesh->GetKey(fpMesh->GetIndex(index, fPixel));
|
||||
auto node = begin->second;
|
||||
// if (node == nullptr) continue;
|
||||
if(TrackKeyMap.find(newKey) == TrackKeyMap.end())
|
||||
auto index = std::get<0>(*begin);
|
||||
auto newIndex = fpMesh->ConvertIndex(index, fPixel);
|
||||
if(TrackKeyMap.find(newIndex) == TrackKeyMap.end())
|
||||
{
|
||||
TrackKeyMap[newKey] = node->GetMapList();
|
||||
TrackKeyMap[newIndex] = std::get<2>(*begin);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(const auto& it : node->GetMapList())
|
||||
for(const auto& it : std::get<2>(*begin))
|
||||
{
|
||||
TrackKeyMap[newKey][it.first] += it.second;
|
||||
TrackKeyMap[newIndex][it.first] += it.second;
|
||||
}
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
G4cout << "key : " << begin->first << " index : " << index
|
||||
<< " new index : " << fpMesh->GetIndex(index, fPixel)
|
||||
<< " new key : " << newKey
|
||||
<< " number: " << node->GetMapList().begin()->second << G4endl;
|
||||
G4cout << " ReVoxelizing:: Old index : " << index
|
||||
<< " new index : " << fpMesh->ConvertIndex(index, fPixel)
|
||||
<< " number: " << std::get<2>(*begin).begin()->second << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,7 +201,7 @@ void G4DNAEventScheduler::ReVoxelizing(G4int pixel)
|
||||
|
||||
for(auto& it : TrackKeyMap)
|
||||
{
|
||||
fpMesh->SetVoxelMapList(it.first, std::move(it.second));
|
||||
fpMesh->InitializeVoxel(it.first, std::move(it.second));
|
||||
}
|
||||
}
|
||||
void G4DNAEventScheduler::Reset()
|
||||
@@ -252,7 +243,7 @@ void G4DNAEventScheduler::Initialize()
|
||||
G4Scheduler::Instance()->GetScavengerMaterial());
|
||||
if(pScavengerMaterial == nullptr)
|
||||
{
|
||||
G4cout << "pScavengerMaterial == nullptr" << G4endl;
|
||||
G4cout << "There is no scavenger" << G4endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -319,22 +310,29 @@ G4double G4DNAEventScheduler::GetStartTime() const { return fStartTime; }
|
||||
|
||||
G4double G4DNAEventScheduler::GetEndTime() const { return fEndTime; }
|
||||
|
||||
[[maybe_unused]] G4double G4DNAEventScheduler::GetTimeStep() const { return fTimeStep; }
|
||||
[[maybe_unused]] G4double G4DNAEventScheduler::GetTimeStep() const
|
||||
{
|
||||
return fTimeStep;
|
||||
}
|
||||
|
||||
G4int G4DNAEventScheduler::GetVerbose() const { return fVerbose; }
|
||||
|
||||
[[maybe_unused]] void G4DNAEventScheduler::SetMaxNbSteps(G4int max) { fMaxStep = max; }
|
||||
[[maybe_unused]] void G4DNAEventScheduler::SetMaxNbSteps(G4int max)
|
||||
{
|
||||
fMaxStep = max;
|
||||
}
|
||||
|
||||
[[maybe_unused]] void G4DNAEventScheduler::SetStartTime(G4double time)
|
||||
{
|
||||
fStartTime = time;
|
||||
fStartTime = time;
|
||||
fGlobalTime = fStartTime;
|
||||
}
|
||||
|
||||
void G4DNAEventScheduler::Stop() { fRunning = false; }
|
||||
void G4DNAEventScheduler::Run()
|
||||
{
|
||||
G4Timer localtimer;
|
||||
if(fVerbose > 0)
|
||||
if(fVerbose > 2)
|
||||
{
|
||||
localtimer.Start();
|
||||
G4cout << "***G4DNAEventScheduler::Run*** for Pixel : " << fPixel << G4endl;
|
||||
@@ -343,7 +341,7 @@ void G4DNAEventScheduler::Run()
|
||||
{
|
||||
RunInMesh();
|
||||
}
|
||||
if(fVerbose > 0)
|
||||
if(fVerbose > 2)
|
||||
{
|
||||
if(!fRunning)
|
||||
{
|
||||
@@ -360,7 +358,8 @@ void G4DNAEventScheduler::Run()
|
||||
G4cout << "***G4DNAEventScheduler::Ending::"
|
||||
<< G4BestUnit(fGlobalTime, "Time")
|
||||
<< " Events left : " << fpEventSet->size() << G4endl;
|
||||
if(fVerbose > 1) {
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
fpMesh->PrintMesh();
|
||||
}
|
||||
G4cout << " Computing Time : " << localtimer << G4endl;
|
||||
@@ -374,18 +373,14 @@ void G4DNAEventScheduler::RunInMesh()
|
||||
{
|
||||
InitializeInMesh();
|
||||
}
|
||||
G4Timer localtimerInMesh;
|
||||
// if (fVerbose > 0)
|
||||
if(fVerbose > 0)
|
||||
{
|
||||
localtimerInMesh.Start();
|
||||
G4double C = 20;
|
||||
G4double D = G4MoleculeTable::Instance()
|
||||
->GetConfiguration("H2O2")
|
||||
->GetDiffusionCoefficient();
|
||||
G4double transferTime = std::pow(fpMesh->GetResolution(), 2) * C / (6 * D);
|
||||
G4cout << "***G4DNAEventScheduler::RunInMesh*** for Pixel : " << fPixel
|
||||
<< " transferTime : " << G4BestUnit(transferTime, "Time") << G4endl;
|
||||
G4cout << " resolution : " << G4BestUnit(fpMesh->GetResolution(), "Length")
|
||||
G4double resolution = fpMesh->GetResolution();
|
||||
G4cout << "At Time : " << std::setw(7) << G4BestUnit(fGlobalTime, "Time")
|
||||
<< " the Mesh has " << fPixel << " x " << fPixel << " x " << fPixel
|
||||
<< " voxels with Resolution " << G4BestUnit(resolution, "Length")
|
||||
<< " during next "
|
||||
<< G4BestUnit(resolution * resolution * C / (6 * D), "Time")
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
@@ -400,6 +395,7 @@ void G4DNAEventScheduler::RunInMesh()
|
||||
}
|
||||
|
||||
// if diffusive jumping is avaiable, EventSet is never empty
|
||||
|
||||
while(!fpEventSet->Empty() && !fIsChangeMesh && fEndTime > fGlobalTime)
|
||||
{
|
||||
Stepping();
|
||||
@@ -415,37 +411,31 @@ void G4DNAEventScheduler::RunInMesh()
|
||||
G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
|
||||
<< " fTimeStep : " << G4BestUnit(fTimeStep, "Time") << G4endl;
|
||||
}
|
||||
|
||||
G4double C = 20;
|
||||
G4double D = G4MoleculeTable::Instance()
|
||||
->GetConfiguration("H2O2")
|
||||
->GetDiffusionCoefficient();
|
||||
if(D == 0)
|
||||
G4double resolution = fpMesh->GetResolution();
|
||||
fTransferTime = resolution * resolution * C / (6 * D);
|
||||
if(fTransferTime == 0)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "D == 0";
|
||||
exceptionDescription << "fTransferTime == 0";
|
||||
G4Exception("G4DNAEventScheduler::RunInMesh", "G4DNAEventScheduler001",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
}
|
||||
G4double transferTime = std::pow(fpMesh->GetResolution(), 2) * C / (6 * D);
|
||||
|
||||
// if(fStepNumberInMesh > 40000 && fPixel != 1)
|
||||
if(transferTime < fTimeStep &&
|
||||
fPixel != 1) // dont change Mesj if fPixel == 1
|
||||
if(fTransferTime < fTimeStep &&
|
||||
fPixel != 1) // dont change Mesh if fPixel == 1
|
||||
{
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
G4cout << " Pixels : " << fPixel << " resolution : "
|
||||
<< G4BestUnit(fpMesh->GetResolution(), "Length")
|
||||
<< " fStepNumberInMesh : " << fStepNumberInMesh
|
||||
<< " at fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
|
||||
<< " at fTimeStep : " << G4BestUnit(fTimeStep, "Time")
|
||||
<< " fReactionNumber : " << fReactionNumber
|
||||
<< " transferTime : " << G4BestUnit(transferTime, "Time")
|
||||
<< G4endl;
|
||||
}
|
||||
if(fSetChangeMesh)
|
||||
{
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
G4cout << " Pixels : " << fPixel << " resolution : "
|
||||
<< G4BestUnit(fpMesh->GetResolution(), "Length")
|
||||
<< " fStepNumberInMesh : " << fStepNumberInMesh
|
||||
<< " at fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
|
||||
<< " at fTimeStep : " << G4BestUnit(fTimeStep, "Time")
|
||||
<< " fReactionNumber : " << fReactionNumber
|
||||
<< " transferTime : " << G4BestUnit(fTransferTime, "Time")
|
||||
<< G4endl;
|
||||
}
|
||||
fIsChangeMesh = true;
|
||||
}
|
||||
}
|
||||
@@ -453,11 +443,10 @@ void G4DNAEventScheduler::RunInMesh()
|
||||
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
localtimerInMesh.Stop();
|
||||
G4cout << "***G4DNAEventScheduler::Ending::"
|
||||
<< G4BestUnit(fGlobalTime, "Time")
|
||||
<< " Event left : " << fpEventSet->size() << G4endl;
|
||||
G4cout << " Computing Time : " << localtimerInMesh << " Due to : ";
|
||||
G4cout << " Due to : ";
|
||||
if(fpEventSet->Empty())
|
||||
{
|
||||
G4cout << "EventSet is Empty" << G4endl;
|
||||
@@ -492,18 +481,17 @@ void G4DNAEventScheduler::RunInMesh()
|
||||
void G4DNAEventScheduler::Stepping() // this event loop
|
||||
{
|
||||
fStepNumber < fMaxStep ? fStepNumber++ : fRunning = false;
|
||||
|
||||
if(fpEventSet->size() > fpMesh->size())
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "fpEventSet->size() > fpMesh->size()";
|
||||
exceptionDescription
|
||||
<< "impossible that fpEventSet->size() > fpMesh->size()";
|
||||
G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler002",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
};
|
||||
}
|
||||
|
||||
auto selected = fpEventSet->begin();
|
||||
const auto& key = (*selected)->GetKey();
|
||||
auto index = fpMesh->GetIndex(key);
|
||||
auto selected = fpEventSet->begin();
|
||||
auto index = (*selected)->GetIndex();
|
||||
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
@@ -522,8 +510,31 @@ void G4DNAEventScheduler::Stepping() // this event loop
|
||||
|
||||
fpUpdateSystem->SetGlobalTime(fTimeStep +
|
||||
fStartTime); // this is just for printing
|
||||
|
||||
if(pJumping == nullptr && pReaction == nullptr)
|
||||
fpGillespieReaction->SetTimeStep(fTimeStep);
|
||||
if(pJumping == nullptr && pReaction != nullptr)
|
||||
{
|
||||
fpUpdateSystem->UpdateSystem(index, *pReaction);
|
||||
fpEventSet->RemoveEvent(selected);
|
||||
// create new event
|
||||
fpGillespieReaction->CreateEvent(index);
|
||||
fReactionNumber++;
|
||||
// recordTime in reaction
|
||||
RecordTime();
|
||||
}
|
||||
else if(pJumping != nullptr && pReaction == nullptr)
|
||||
{
|
||||
// dont change this
|
||||
fpUpdateSystem->UpdateSystem(index, *pJumping);
|
||||
// save jumping Index before delete selected event
|
||||
auto jumpingIndex = pJumping->second;
|
||||
fpEventSet->RemoveEvent(selected);
|
||||
// create new event
|
||||
// should create Jumping before key
|
||||
fpGillespieReaction->CreateEvent(jumpingIndex);
|
||||
fpGillespieReaction->CreateEvent(index);
|
||||
fJumpingNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "pJumping == nullptr && pReaction == nullptr";
|
||||
@@ -531,34 +542,6 @@ void G4DNAEventScheduler::Stepping() // this event loop
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
}
|
||||
|
||||
fpGillespieReaction->SetTimeStep(fTimeStep);
|
||||
|
||||
if(pJumping == nullptr)
|
||||
{
|
||||
fpUpdateSystem->UpdateSystem(index, *pReaction);
|
||||
|
||||
fpEventSet->RemoveEvent(selected);
|
||||
// create new event
|
||||
fpGillespieReaction->CreateEvent(key);
|
||||
fReactionNumber++;
|
||||
|
||||
// recordTime in reaction
|
||||
RecordTime();
|
||||
}
|
||||
else if(pReaction == nullptr)
|
||||
{
|
||||
// dont change this
|
||||
fpUpdateSystem->UpdateSystem(index, *pJumping);
|
||||
auto jumpingKey = fpMesh->GetKey(pJumping->second);
|
||||
fpEventSet->RemoveEvent(selected);
|
||||
|
||||
// create new event
|
||||
// should create Jumping before key
|
||||
fpGillespieReaction->CreateEvent(jumpingKey);
|
||||
fpGillespieReaction->CreateEvent(key);
|
||||
|
||||
fJumpingNumber++;
|
||||
}
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
G4cout << "G4DNAEventScheduler::Stepping::end "
|
||||
@@ -583,45 +566,23 @@ void G4DNAEventScheduler::RecordTime()
|
||||
auto end = fpMesh->end();
|
||||
for(; begin != end; begin++)
|
||||
{
|
||||
auto node = begin->second;
|
||||
if(node == nullptr) {
|
||||
const auto& mapData = std::get<2>(*begin);
|
||||
if(mapData.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for(const auto& it : node->GetMapList())
|
||||
for(const auto& it : mapData)
|
||||
{
|
||||
fCounterMap[recordTime][it.first] += it.second;
|
||||
}
|
||||
}
|
||||
fLastRecoredTime++;
|
||||
|
||||
#ifdef DEBUG
|
||||
PrintRecordTime();
|
||||
G4MoleculeTable* pMoleculeTable = G4MoleculeTable::Instance();
|
||||
auto iter = pMoleculeTable->GetConfigurationIterator();
|
||||
iter.reset();
|
||||
while(iter())
|
||||
{
|
||||
auto conf = iter.value();
|
||||
|
||||
G4cout << "GlobalTime : " << G4BestUnit(fGlobalTime, "Time")
|
||||
<< " recordTime : " << G4BestUnit(recordTime, "Time") << " "
|
||||
<< conf->GetName()
|
||||
<< " number : " << fCounterMap[recordTime][conf]
|
||||
<< " MoleculeCounter : "
|
||||
<< G4MoleculeCounter::Instance()->GetCurrentNumberOf(conf)
|
||||
<< G4endl;
|
||||
|
||||
assert(G4MoleculeCounter::Instance()->GetCurrentNumberOf(conf) ==
|
||||
fCounterMap[recordTime][conf]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void G4DNAEventScheduler::PrintRecordTime()
|
||||
{
|
||||
G4cout << "fCounterMap.size : " << fCounterMap.size() << G4endl;
|
||||
|
||||
G4cout << "CounterMap.size : " << fCounterMap.size() << G4endl;
|
||||
for(const auto& i : fCounterMap)
|
||||
{
|
||||
auto map = i.second;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
#include "G4DNAGillespieDirectMethod.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
@@ -33,15 +32,10 @@
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4DNAScavengerMaterial.hh"
|
||||
#include "G4Scheduler.hh"
|
||||
#include <cassert>
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
|
||||
G4DNAGillespieDirectMethod::G4DNAGillespieDirectMethod()
|
||||
: fMolecularReactions(G4DNAMolecularReactionTable::Instance())
|
||||
, fpMesh(nullptr)
|
||||
, fTimeStep(0)
|
||||
, fpEventSet(nullptr)
|
||||
, fVerbose(0)
|
||||
, fpScavengerMaterial(nullptr)
|
||||
{}
|
||||
|
||||
G4DNAGillespieDirectMethod::~G4DNAGillespieDirectMethod() = default;
|
||||
@@ -53,34 +47,40 @@ void G4DNAGillespieDirectMethod::SetEventSet(G4DNAEventSet* pEventSet)
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
G4double G4DNAGillespieDirectMethod::VolumeOfNode(const Index& index)
|
||||
G4double G4DNAGillespieDirectMethod::VolumeOfNode(const Voxel& voxel)
|
||||
{
|
||||
auto LengthY = fpMesh->GetBoundingBox(index).Getyhi() -
|
||||
fpMesh->GetBoundingBox(index).Getylo();
|
||||
auto LengthX = fpMesh->GetBoundingBox(index).Getxhi() -
|
||||
fpMesh->GetBoundingBox(index).Getxlo();
|
||||
auto LengthZ = fpMesh->GetBoundingBox(index).Getzhi() -
|
||||
fpMesh->GetBoundingBox(index).Getzlo();
|
||||
G4double V = LengthY * LengthX * LengthZ;
|
||||
assert(V > 0);
|
||||
auto box = std::get<1>(voxel);
|
||||
auto LengthY = box.Getyhi() - box.Getylo();
|
||||
auto LengthX = box.Getxhi() - box.Getxlo();
|
||||
auto LengthZ = box.Getzhi() - box.Getzlo();
|
||||
G4double V = LengthY * LengthX * LengthZ;
|
||||
if(V <= 0)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "V > 0 !! ";
|
||||
G4Exception("G4DNAGillespieDirectMethod::VolumeOfNode",
|
||||
"G4DNAGillespieDirectMethod03", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
return V;
|
||||
}
|
||||
G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
|
||||
G4double G4DNAGillespieDirectMethod::PropensityFunction(const Voxel& voxel,
|
||||
MolType moleType)
|
||||
{
|
||||
if(moleType->GetDiffusionCoefficient() == 0)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
const auto& node = fpMesh->GetVoxelMapList(index);
|
||||
G4double alpha = 0;
|
||||
auto it = node.find(moleType);
|
||||
const auto& node = std::get<2>(voxel);
|
||||
const auto& box = std::get<1>(voxel);
|
||||
|
||||
G4double alpha = 0;
|
||||
auto it = node.find(moleType);
|
||||
if(it != node.end())
|
||||
{
|
||||
auto LengthY = fpMesh->GetBoundingBox(index).Getyhi() -
|
||||
fpMesh->GetBoundingBox(index).Getylo();
|
||||
G4double d = it->first->GetDiffusionCoefficient() / std::pow(LengthY, 2);
|
||||
alpha = d * it->second;
|
||||
auto LengthY = box.Getyhi() - box.Getylo();
|
||||
G4double d = it->first->GetDiffusionCoefficient() / std::pow(LengthY, 2);
|
||||
alpha = d * it->second;
|
||||
|
||||
#ifdef DEBUG
|
||||
G4cout << it->first->GetName() << " " << it->second
|
||||
@@ -92,20 +92,20 @@ G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
|
||||
return alpha;
|
||||
}
|
||||
|
||||
G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
|
||||
G4double G4DNAGillespieDirectMethod::PropensityFunction(const Voxel& voxel,
|
||||
ReactionData* data)
|
||||
{
|
||||
G4double value;
|
||||
auto ConfA = data->GetReactant1();
|
||||
auto ConfB = data->GetReactant2();
|
||||
G4double scavengerNumber = 0;
|
||||
auto typeANumber = FindScavenging(index, ConfA, scavengerNumber)
|
||||
? scavengerNumber
|
||||
: ComputeNumberInNode(index, ConfA);
|
||||
auto typeANumber = FindScavenging(voxel, ConfA, scavengerNumber)
|
||||
? scavengerNumber
|
||||
: ComputeNumberInNode(voxel, ConfA);
|
||||
|
||||
auto typeBNumber = FindScavenging(index, ConfB, scavengerNumber)
|
||||
auto typeBNumber = FindScavenging(voxel, ConfB, scavengerNumber)
|
||||
? scavengerNumber
|
||||
: ComputeNumberInNode(index, ConfB);
|
||||
: ComputeNumberInNode(voxel, ConfB);
|
||||
|
||||
if(typeANumber == 0 || typeBNumber == 0)
|
||||
{
|
||||
@@ -113,7 +113,7 @@ G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
|
||||
}
|
||||
|
||||
auto k =
|
||||
data->GetObservedReactionRateConstant() / (Avogadro * VolumeOfNode(index));
|
||||
data->GetObservedReactionRateConstant() / (Avogadro * VolumeOfNode(voxel));
|
||||
if(ConfA == ConfB)
|
||||
{
|
||||
value = typeANumber * (typeBNumber - 1) * k;
|
||||
@@ -125,17 +125,19 @@ G4double G4DNAGillespieDirectMethod::PropensityFunction(const Index& index,
|
||||
|
||||
if(value < 0)
|
||||
{
|
||||
G4cout << "G4DNAGillespieDirectMethod::PropensityFunction for : "
|
||||
<< ConfA->GetName() << "(" << typeANumber << ") + "
|
||||
<< ConfB->GetName() << "(" << typeBNumber
|
||||
<< ") : propensity : " << value
|
||||
<< " GetObservedReactionRateConstant : "
|
||||
<< data->GetObservedReactionRateConstant()
|
||||
<< " GetEffectiveReactionRadius : "
|
||||
<< G4BestUnit(data->GetEffectiveReactionRadius(), "Length")
|
||||
<< " k : " << k << " volume : " << VolumeOfNode(index)
|
||||
<< " Index : " << index << G4endl;
|
||||
assert(false);
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription
|
||||
<< "G4DNAGillespieDirectMethod::PropensityFunction for : "
|
||||
<< ConfA->GetName() << "(" << typeANumber << ") + " << ConfB->GetName()
|
||||
<< "(" << typeBNumber << ") : propensity : " << value
|
||||
<< " GetObservedReactionRateConstant : "
|
||||
<< data->GetObservedReactionRateConstant()
|
||||
<< " GetEffectiveReactionRadius : "
|
||||
<< G4BestUnit(data->GetEffectiveReactionRadius(), "Length")
|
||||
<< " k : " << k << " volume : " << VolumeOfNode(voxel) << G4endl;
|
||||
G4Exception("G4DNAGillespieDirectMethod::PropensityFunction",
|
||||
"G4DNAGillespieDirectMethod013", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -161,11 +163,11 @@ void G4DNAGillespieDirectMethod::Initialize()
|
||||
auto end = fpMesh->end();
|
||||
for(; begin != end; begin++)
|
||||
{
|
||||
auto key = begin->first;
|
||||
auto index = std::get<0>(*begin);
|
||||
#ifdef DEBUG
|
||||
fpMesh->PrintVoxel(fpMesh->GetIndex(key));
|
||||
fpMesh->PrintVoxel(index);
|
||||
#endif
|
||||
CreateEvent(key);
|
||||
CreateEvent(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,13 +175,22 @@ void G4DNAGillespieDirectMethod::SetTimeStep(const G4double& stepTime)
|
||||
{
|
||||
fTimeStep = stepTime;
|
||||
}
|
||||
void G4DNAGillespieDirectMethod::CreateEvent(unsigned int key)
|
||||
void G4DNAGillespieDirectMethod::CreateEvent(const Index& index)
|
||||
{
|
||||
const auto& voxel = fpMesh->GetVoxel(index);
|
||||
if(std::get<2>(voxel).empty())
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "This voxel : " << index
|
||||
<< " is not ready to make event" << G4endl;
|
||||
G4Exception("G4DNAGillespieDirectMethod::CreateEvent",
|
||||
"G4DNAGillespieDirectMethod05", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
G4double r1 = G4UniformRand();
|
||||
G4double r2 = G4UniformRand();
|
||||
auto index = fpMesh->GetIndex(key);
|
||||
G4double dAlpha0 = DiffusiveJumping(index);
|
||||
G4double rAlpha0 = Reaction(index);
|
||||
G4double dAlpha0 = DiffusiveJumping(voxel);
|
||||
G4double rAlpha0 = Reaction(voxel);
|
||||
G4double alphaTotal = dAlpha0 + rAlpha0;
|
||||
|
||||
if(alphaTotal == 0)
|
||||
@@ -202,7 +213,7 @@ void G4DNAGillespieDirectMethod::CreateEvent(unsigned int key)
|
||||
<< G4endl;
|
||||
}
|
||||
auto rSelectedIter = fReactionDataMap.upper_bound(r2 * alphaTotal);
|
||||
fpEventSet->CreateEvent(timeStep, key, rSelectedIter->second);
|
||||
fpEventSet->CreateEvent(timeStep, index, rSelectedIter->second);
|
||||
}
|
||||
else if(dAlpha0 > 0)
|
||||
{
|
||||
@@ -216,26 +227,31 @@ void G4DNAGillespieDirectMethod::CreateEvent(unsigned int key)
|
||||
auto dSelectedIter = fJumpingDataMap.upper_bound(r2 * alphaTotal - rAlpha0);
|
||||
auto pDSelected =
|
||||
std::make_unique<std::pair<MolType, Index>>(dSelectedIter->second);
|
||||
fpEventSet->CreateEvent(timeStep, key, std::move(pDSelected));
|
||||
fpEventSet->CreateEvent(timeStep, index, std::move(pDSelected));
|
||||
}
|
||||
#ifdef DEBUG
|
||||
G4cout << G4endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
G4double G4DNAGillespieDirectMethod::Reaction(const Index& index)
|
||||
G4double G4DNAGillespieDirectMethod::Reaction(const Voxel& voxel)
|
||||
{
|
||||
fReactionDataMap.clear();
|
||||
G4double alpha0 = 0;
|
||||
auto dataList = fMolecularReactions->GetVectorOfReactionData();
|
||||
const auto& dataList =
|
||||
fMolecularReactions->GetVectorOfReactionData(); // shoud make a member
|
||||
if(dataList.empty())
|
||||
{
|
||||
G4cout << "MolecularReactionTable empty" << G4endl;
|
||||
assert(false);
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "MolecularReactionTable empty" << G4endl;
|
||||
G4Exception("G4DNAGillespieDirectMethod::Reaction",
|
||||
"G4DNAGillespieDirectMethod01", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
|
||||
for(const auto& it : dataList)
|
||||
{
|
||||
auto propensity = PropensityFunction(index, it);
|
||||
auto propensity = PropensityFunction(voxel, it);
|
||||
if(propensity == 0)
|
||||
{
|
||||
continue;
|
||||
@@ -249,10 +265,11 @@ G4double G4DNAGillespieDirectMethod::Reaction(const Index& index)
|
||||
return alpha0;
|
||||
}
|
||||
|
||||
G4double G4DNAGillespieDirectMethod::DiffusiveJumping(const Index& index)
|
||||
G4double G4DNAGillespieDirectMethod::DiffusiveJumping(const Voxel& voxel)
|
||||
{
|
||||
fJumpingDataMap.clear();
|
||||
G4double alpha0 = 0;
|
||||
auto index = std::get<0>(voxel);
|
||||
auto NeighboringVoxels = fpMesh->FindNeighboringVoxels(index);
|
||||
if(NeighboringVoxels.empty())
|
||||
{
|
||||
@@ -261,8 +278,8 @@ G4double G4DNAGillespieDirectMethod::DiffusiveJumping(const Index& index)
|
||||
auto iter = G4MoleculeTable::Instance()->GetConfigurationIterator();
|
||||
while(iter())
|
||||
{
|
||||
const auto conf = iter.value();
|
||||
auto propensity = PropensityFunction(index, conf);
|
||||
const auto* conf = iter.value();
|
||||
auto propensity = PropensityFunction(voxel, conf);
|
||||
if(propensity == 0)
|
||||
{
|
||||
continue;
|
||||
@@ -286,11 +303,11 @@ G4double G4DNAGillespieDirectMethod::DiffusiveJumping(const Index& index)
|
||||
}
|
||||
|
||||
G4double G4DNAGillespieDirectMethod::ComputeNumberInNode(
|
||||
const Index& index, MolType type) // depend node ?
|
||||
const Voxel& voxel, MolType type) // depend node ?
|
||||
{
|
||||
if(type->GetDiffusionCoefficient() != 0)
|
||||
{
|
||||
const auto& node = fpMesh->GetVoxelMapList(index);
|
||||
const auto& node = std::get<2>(voxel);
|
||||
const auto& it = node.find(type);
|
||||
return (it != node.end()) ? (it->second) : 0;
|
||||
}
|
||||
@@ -300,7 +317,7 @@ G4double G4DNAGillespieDirectMethod::ComputeNumberInNode(
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4DNAGillespieDirectMethod::FindScavenging(const Index& index,
|
||||
G4bool G4DNAGillespieDirectMethod::FindScavenging(const Voxel& voxel,
|
||||
MolType moletype,
|
||||
G4double& numberOfScavenger)
|
||||
{
|
||||
@@ -309,7 +326,7 @@ G4bool G4DNAGillespieDirectMethod::FindScavenging(const Index& index,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto volumeOfNode = VolumeOfNode(index);
|
||||
auto volumeOfNode = VolumeOfNode(voxel);
|
||||
if(G4MoleculeTable::Instance()->GetConfiguration("H2O") == moletype)
|
||||
{
|
||||
auto factor = Avogadro * volumeOfNode;
|
||||
@@ -326,19 +343,12 @@ G4bool G4DNAGillespieDirectMethod::FindScavenging(const Index& index,
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double numberInDouble =
|
||||
volumeOfNode * std::floor(totalNumber) / fpMesh->GetBoundingBox().Volume();
|
||||
auto numberInInterg = (int) (std::floor(numberInDouble));
|
||||
G4double ram = G4UniformRand();
|
||||
G4double change = numberInDouble - numberInInterg;
|
||||
if(ram > change)
|
||||
{
|
||||
numberOfScavenger = numberInInterg;
|
||||
}
|
||||
else
|
||||
{
|
||||
numberOfScavenger = numberInInterg + 1;
|
||||
}
|
||||
G4double numberInDouble = volumeOfNode * std::floor(totalNumber) /
|
||||
fpMesh->GetBoundingBox().Volume();
|
||||
auto numberInInterg = (int64_t) (std::floor(numberInDouble));
|
||||
G4double change = numberInDouble - numberInInterg;
|
||||
G4UniformRand() > change ? numberOfScavenger = numberInInterg
|
||||
: numberOfScavenger = numberInInterg + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,12 @@ void G4DNAIRT::Sampling(G4Track* track){
|
||||
|
||||
auto fReactionDatas = fMolReactionTable->GetReactionData(molConfA);
|
||||
G4double index = -1;
|
||||
//change the scavenging filter of the IRT beyond 1 us proposed by Naoki and Jose
|
||||
if(timeMax > 1*us)
|
||||
{
|
||||
minTime = timeMax;
|
||||
}
|
||||
//
|
||||
|
||||
for(size_t u=0; u<fReactionDatas->size();u++){
|
||||
if((*fReactionDatas)[u]->GetReactant2()->GetDiffusionCoefficient() == 0){
|
||||
|
||||
@@ -1,642 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
/*
|
||||
* G4DNAIRT_geometries.cc
|
||||
*
|
||||
* Created on: Jul 23, 2019
|
||||
* Author: W. G. Shin
|
||||
* J. Ramos-Mendez and B. Faddegon
|
||||
*/
|
||||
|
||||
|
||||
#include "G4DNAIRT_geometries.hh"
|
||||
#include "G4ErrorFunction.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
#include "G4MolecularConfiguration.hh"
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4ITReactionChange.hh"
|
||||
#include "G4ITTrackHolder.hh"
|
||||
#include "G4ITReaction.hh"
|
||||
#include "G4Scheduler.hh"
|
||||
#include "G4MoleculeTable.hh"
|
||||
#include "G4NavigationHistory.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4VDNAMolecularGeometry.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4DNAIRT_geometries::G4DNAIRT_geometries() :
|
||||
G4VITReactionProcess(),
|
||||
fMolReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable)),
|
||||
fpReactionModel(nullptr),
|
||||
fTrackHolder(G4ITTrackHolder::Instance()),
|
||||
fReactionSet(nullptr),
|
||||
fGeometry(nullptr)
|
||||
{
|
||||
timeMin = G4Scheduler::Instance()->GetStartTime();
|
||||
timeMax = G4Scheduler::Instance()->GetEndTime();
|
||||
|
||||
fXMin = 1e9*nm;
|
||||
fYMin = 1e9*nm;
|
||||
fZMin = 1e9*nm;
|
||||
|
||||
fXMax = 0e0*nm;
|
||||
fYMax = 0e0*nm;
|
||||
fZMax = 0e0*nm;
|
||||
|
||||
fNx = 0;
|
||||
fNy = 0;
|
||||
fNz = 0;
|
||||
|
||||
xiniIndex = 0, yiniIndex = 0, ziniIndex = 0;
|
||||
xendIndex = 0, yendIndex = 0, zendIndex = 0;
|
||||
|
||||
fRCutOff =
|
||||
1.45 * nm + 2 * std::sqrt(8*9.46e9*nm*nm/s * timeMax); // 95% confidence level
|
||||
|
||||
erfc = new G4ErrorFunction();
|
||||
}
|
||||
|
||||
|
||||
G4DNAIRT_geometries::G4DNAIRT_geometries(G4VDNAReactionModel* pReactionModel)
|
||||
: G4DNAIRT_geometries()
|
||||
{
|
||||
fpReactionModel = pReactionModel;
|
||||
}
|
||||
|
||||
G4DNAIRT_geometries::~G4DNAIRT_geometries()
|
||||
{
|
||||
delete erfc;
|
||||
}
|
||||
|
||||
void G4DNAIRT_geometries::Initialize(){
|
||||
|
||||
timeMin = G4Scheduler::Instance()->GetGlobalTime();
|
||||
timeMax = std::min(timeMin + G4Scheduler::Instance()->GetLimitingTimeStep(),
|
||||
G4Scheduler::Instance()->GetEndTime());
|
||||
if(timeMin == 0) return;
|
||||
|
||||
fTrackHolder = G4ITTrackHolder::Instance();
|
||||
if(fTrackHolder->GetMainList()->size() == 0) return;
|
||||
|
||||
fReactionSet = G4ITReactionSet::Instance();
|
||||
fReactionSet->CleanAllReaction();
|
||||
fReactionSet->SortByTime();
|
||||
|
||||
spaceBinned.clear();
|
||||
positionMap.clear();
|
||||
|
||||
fRCutOff =
|
||||
1.45 * nm + 2 * std::sqrt(8*9.46e9*nm*nm/s * (timeMax - timeMin));
|
||||
|
||||
xiniIndex = 0;
|
||||
yiniIndex = 0;
|
||||
ziniIndex = 0;
|
||||
xendIndex = 0;
|
||||
yendIndex = 0;
|
||||
zendIndex = 0;
|
||||
|
||||
fXMin = 1e9*nm;
|
||||
fYMin = 1e9*nm;
|
||||
fZMin = 1e9*nm;
|
||||
|
||||
fXMax = 0e0*nm;
|
||||
fYMax = 0e0*nm;
|
||||
fZMax = 0e0*nm;
|
||||
|
||||
fNx = 0;
|
||||
fNy = 0;
|
||||
fNz = 0;
|
||||
|
||||
fGeometry = fMolReactionTable->GetGeometry();
|
||||
|
||||
SpaceBinning(); // 1. binning the space
|
||||
IRTSampling(); // 2. Sampling of the IRT
|
||||
|
||||
}
|
||||
|
||||
void G4DNAIRT_geometries::SpaceBinning(){
|
||||
G4double time_step = G4Scheduler::Instance()->GetPreviousTimeStep()*ps;
|
||||
|
||||
auto it_begin = fTrackHolder->GetMainList()->begin();
|
||||
while(it_begin != fTrackHolder->GetMainList()->end()){
|
||||
|
||||
// for diffusion
|
||||
G4double D = GetMolecule(*it_begin)->GetDiffusionCoefficient();
|
||||
G4double sqrt_2Dt = sqrt(2 * D * time_step);
|
||||
|
||||
G4double x = G4RandGauss::shoot(0,sqrt_2Dt);
|
||||
G4double y = G4RandGauss::shoot(0,sqrt_2Dt);
|
||||
G4double z = G4RandGauss::shoot(0,sqrt_2Dt);
|
||||
|
||||
G4ThreeVector position_ori = it_begin->GetPosition();
|
||||
G4ThreeVector position = position_ori + G4ThreeVector(x,y,z);
|
||||
it_begin->SetPosition(position);
|
||||
it_begin->SetGlobalTime(timeMax);
|
||||
|
||||
if ( fXMin > position.x() ) fXMin = position.x();
|
||||
if ( fYMin > position.y() ) fYMin = position.y();
|
||||
if ( fZMin > position.z() ) fZMin = position.z();
|
||||
|
||||
if ( fXMax < position.x() ) fXMax = position.x();
|
||||
if ( fYMax < position.y() ) fYMax = position.y();
|
||||
if ( fZMax < position.z() ) fZMax = position.z();
|
||||
|
||||
++it_begin;
|
||||
}
|
||||
|
||||
fNx = G4int((fXMax-fXMin)/fRCutOff) == 0 ? 1 : G4int((fXMax-fXMin)/fRCutOff);
|
||||
fNy = G4int((fYMax-fYMin)/fRCutOff) == 0 ? 1 : G4int((fYMax-fYMin)/fRCutOff);
|
||||
fNz = G4int((fZMax-fZMin)/fRCutOff) == 0 ? 1 : G4int((fZMax-fZMin)/fRCutOff);
|
||||
|
||||
}
|
||||
|
||||
void G4DNAIRT_geometries::IRTSampling(){
|
||||
|
||||
auto it_begin = fTrackHolder->GetMainList()->begin();
|
||||
while(it_begin != fTrackHolder->GetMainList()->end()){
|
||||
G4int I = FindBin(fNx, fXMin, fXMax, it_begin->GetPosition().x());
|
||||
G4int J = FindBin(fNy, fYMin, fYMax, it_begin->GetPosition().y());
|
||||
G4int K = FindBin(fNz, fZMin, fZMax, it_begin->GetPosition().z());
|
||||
|
||||
spaceBinned[I][J][K].push_back(*it_begin);
|
||||
|
||||
Sampling(*it_begin);
|
||||
++it_begin;
|
||||
}
|
||||
}
|
||||
|
||||
void G4DNAIRT_geometries::Sampling(G4Track* track){
|
||||
G4Molecule* molA = G4Molecule::GetMolecule(track);
|
||||
const G4MolecularConfiguration* molConfA = molA->GetMolecularConfiguration();
|
||||
if(molConfA->GetDiffusionCoefficient() == 0) return;
|
||||
|
||||
const vector<const G4MolecularConfiguration*>* reactivesVector =
|
||||
fMolReactionTable->CanReactWith(molConfA);
|
||||
|
||||
if(reactivesVector == nullptr) return;
|
||||
|
||||
G4double globalTime = G4Scheduler::Instance()->GetGlobalTime();
|
||||
G4double minTime = timeMax;
|
||||
|
||||
xiniIndex = FindBin(fNx, fXMin, fXMax, track->GetPosition().x()-fRCutOff);
|
||||
xendIndex = FindBin(fNx, fXMin, fXMax, track->GetPosition().x()+fRCutOff);
|
||||
yiniIndex = FindBin(fNy, fYMin, fYMax, track->GetPosition().y()-fRCutOff);
|
||||
yendIndex = FindBin(fNy, fYMin, fYMax, track->GetPosition().y()+fRCutOff);
|
||||
ziniIndex = FindBin(fNz, fZMin, fZMax, track->GetPosition().z()-fRCutOff);
|
||||
zendIndex = FindBin(fNz, fZMin, fZMax, track->GetPosition().z()+fRCutOff);
|
||||
|
||||
for ( G4int ii = xiniIndex; ii <= xendIndex; ++ii ) {
|
||||
for ( G4int jj = yiniIndex; jj <= yendIndex; ++jj ) {
|
||||
for ( G4int kk = ziniIndex; kk <= zendIndex; ++kk ) {
|
||||
|
||||
std::vector<G4Track*> spaceBin = spaceBinned[ii][jj][kk];
|
||||
for ( G4int n = 0; n < (G4int)spaceBinned[ii][jj][kk].size(); ++n ) {
|
||||
if(!spaceBin[n] || track == spaceBin[n]) continue;
|
||||
if(spaceBin[n]->GetTrackStatus() == fStopButAlive) continue;
|
||||
|
||||
G4Molecule* molB = G4Molecule::GetMolecule(spaceBin[n]);
|
||||
if(!molB) continue;
|
||||
|
||||
const G4MolecularConfiguration* molConfB = molB->GetMolecularConfiguration();
|
||||
if(molConfB->GetDiffusionCoefficient() == 0) continue;
|
||||
|
||||
auto it = std::find(reactivesVector->begin(), reactivesVector->end(), molConfB);
|
||||
if(it == reactivesVector->end()) continue;
|
||||
|
||||
G4ThreeVector orgPosB = spaceBin[n]->GetPosition();
|
||||
G4double dt = track->GetGlobalTime() - spaceBin[n]->GetGlobalTime();
|
||||
G4ThreeVector newPosB = orgPosB;
|
||||
|
||||
if(dt > 0){
|
||||
G4double sigma, x, y, z;
|
||||
G4double diffusionCoefficient = G4Molecule::GetMolecule(spaceBin[n])->GetDiffusionCoefficient();
|
||||
|
||||
sigma = std::sqrt(2.0 * diffusionCoefficient * dt);
|
||||
|
||||
x = G4RandGauss::shoot(0., 1.0)*sigma;
|
||||
y = G4RandGauss::shoot(0., 1.0)*sigma;
|
||||
z = G4RandGauss::shoot(0., 1.0)*sigma;
|
||||
|
||||
newPosB = orgPosB + G4ThreeVector(x,y,z);
|
||||
}else if(dt < 0) continue;
|
||||
|
||||
G4double r0 = (newPosB - track->GetPosition()).mag();
|
||||
G4double irt = GetIndependentReactionTime(molConfA,
|
||||
molConfB,
|
||||
r0);
|
||||
if(irt>=0 && irt<timeMax - globalTime)
|
||||
{
|
||||
irt += globalTime;
|
||||
if(irt < minTime) minTime = irt;
|
||||
#ifdef DEBUG
|
||||
G4cout<<irt<<'\t'<<molConfA->GetName()<<" "<<track->GetTrackID()<<'\t'<<molConfB->GetName()<<" "<<spaceBin[n]->GetTrackID()<<'\n';
|
||||
#endif
|
||||
fReactionSet->AddReaction(irt,track,spaceBin[n]);
|
||||
}
|
||||
}
|
||||
spaceBin.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scavenging & first order reactions
|
||||
|
||||
auto fReactionDatas = fMolReactionTable->GetReactionData(molConfA);
|
||||
G4int index = -1;
|
||||
|
||||
for(size_t u=0; u<fReactionDatas->size();++u){
|
||||
auto molB = (*fReactionDatas)[u]->GetReactant2();
|
||||
if(molB == G4MoleculeTable::Instance()->GetConfiguration("H2O(B)") ||
|
||||
molB == G4MoleculeTable::Instance()->GetConfiguration("H3Op(B)") ||
|
||||
molB == G4MoleculeTable::Instance()->GetConfiguration("OHm(B)")){
|
||||
G4double kObs = (*fReactionDatas)[u]->GetObservedReactionRateConstant();
|
||||
if(kObs == 0) continue;
|
||||
G4double time = -(std::log(1.0 - G4UniformRand())/kObs) + globalTime;
|
||||
if( time < minTime && time >= globalTime && time < timeMax){
|
||||
minTime = time;
|
||||
index = (G4int)u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(index != -1){
|
||||
#ifdef DEBUG
|
||||
G4cout<<"scavenged: "<<minTime<<'\t'<<molConfA->GetName()<<it_begin->GetTrackID()<<'\n';
|
||||
#endif
|
||||
G4Molecule* fakeMol = new G4Molecule((*fReactionDatas)[index]->GetReactant2());
|
||||
G4Track* fakeTrack = fakeMol->BuildTrack(globalTime,track->GetPosition());
|
||||
fTrackHolder->Push(fakeTrack);
|
||||
fReactionSet->AddReaction(minTime, track, fakeTrack);
|
||||
}
|
||||
|
||||
|
||||
// DNA reactions
|
||||
if(fGeometry == nullptr) return;
|
||||
|
||||
const G4VTouchable* touchable = track->GetTouchable();
|
||||
if(touchable == nullptr) return;
|
||||
|
||||
const G4LogicalVolume* logicalVolume = touchable->GetVolume()->GetLogicalVolume();
|
||||
|
||||
const G4ThreeVector& globalPos = track->GetPosition();
|
||||
const G4ThreeVector& localPos = touchable->GetHistory()->GetTopTransform().TransformPoint(globalPos);
|
||||
|
||||
G4double D = GetMolecule(track)->GetDiffusionCoefficient();
|
||||
G4double time_step = abs(timeMax - timeMin);
|
||||
G4double search_range = 2*sqrt(2*D*time_step);
|
||||
|
||||
std::vector<G4VPhysicalVolume*> result_pv;
|
||||
result_pv.clear();
|
||||
fGeometry->FindNearbyMolecules(logicalVolume,
|
||||
localPos,
|
||||
result_pv,
|
||||
search_range);
|
||||
|
||||
if(result_pv.empty()) return;
|
||||
|
||||
for(auto physicalVolume : result_pv){
|
||||
const G4Material* material = physicalVolume->GetLogicalVolume()->GetMaterial();
|
||||
G4MolecularConfiguration* dna_molConf =
|
||||
G4DNAMolecularMaterial::Instance()->GetMolecularConfiguration(material);
|
||||
|
||||
auto it = std::find(reactivesVector->begin(), reactivesVector->end(), dna_molConf);
|
||||
if(it == reactivesVector->end()) continue;
|
||||
G4ThreeVector pos = physicalVolume->GetTranslation();
|
||||
|
||||
G4ThreeVector globalPos_DNA = touchable->GetHistory()->GetTopTransform().Inverse().TransformPoint(pos);
|
||||
|
||||
G4double r0 = (pos - localPos).mag();
|
||||
G4double irt = GetIndependentReactionTime(molConfA,dna_molConf,r0);
|
||||
|
||||
if(irt>=0 && irt<timeMax - globalTime)
|
||||
{
|
||||
|
||||
index = -1;
|
||||
for(size_t i=0;i<positionMap.size();++i){
|
||||
if(globalPos_DNA == positionMap[i].first){
|
||||
index = (G4int)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
G4Track* DNATrack;
|
||||
if(index == -1){
|
||||
auto DNAMol = new G4Molecule(dna_molConf);
|
||||
DNATrack = DNAMol->BuildTrack(globalTime,globalPos_DNA);
|
||||
DNATrack->SetTrackStatus(fAlive);
|
||||
fTrackHolder->Push(DNATrack);
|
||||
positionMap.push_back(std::make_pair(globalPos_DNA,DNATrack));
|
||||
}else{
|
||||
DNATrack = positionMap[index].second;
|
||||
}
|
||||
|
||||
irt += globalTime;
|
||||
if(irt < minTime) minTime = irt;
|
||||
#ifdef DEBUG
|
||||
G4cout<<irt<<'\t'<<globalPos_DNA<<'\t'<<molConfA->GetName()<<" "<<track->GetTrackID()<<'\t'<<dna_molConf->GetName()<<" "<<DNATrack->GetTrackID()<<'\n';
|
||||
#endif
|
||||
fReactionSet->AddReaction(irt,track,DNATrack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4double G4DNAIRT_geometries::GetIndependentReactionTime(const G4MolecularConfiguration* molA, const G4MolecularConfiguration* molB, G4double distance) {
|
||||
const auto pMoleculeA = molA;
|
||||
const auto pMoleculeB = molB;
|
||||
auto fReactionData = fMolReactionTable->GetReactionData(pMoleculeA, pMoleculeB);
|
||||
G4int reactionType = fReactionData->GetReactionType();
|
||||
G4double r0 = distance;
|
||||
if(r0 == 0) r0 += 1e-3*nm;
|
||||
G4double irt = -1 * ps;
|
||||
G4double D = molA->GetDiffusionCoefficient() +
|
||||
molB->GetDiffusionCoefficient();
|
||||
if(D == 0) D += 1e-20*(m2/s);
|
||||
G4double rc = fReactionData->GetOnsagerRadius();
|
||||
|
||||
if ( reactionType == 0){
|
||||
G4double sigma = fReactionData->GetEffectiveReactionRadius();
|
||||
|
||||
if(sigma > r0) return 0; // contact reaction
|
||||
if( rc != 0) r0 = -rc / (1-std::exp(rc/r0));
|
||||
|
||||
G4double Winf = sigma/r0;
|
||||
G4double W = G4UniformRand();
|
||||
|
||||
if ( W > 0 && W < Winf ) irt = (0.25/D) * std::pow( (r0-sigma)/erfc->erfcInv(r0*W/sigma), 2 );
|
||||
|
||||
return irt;
|
||||
}
|
||||
else if ( reactionType == 1 ){
|
||||
G4double sigma = fReactionData->GetReactionRadius();
|
||||
G4double kact = fReactionData->GetActivationRateConstant();
|
||||
G4double kdif = fReactionData->GetDiffusionRateConstant();
|
||||
G4double kobs = fReactionData->GetObservedReactionRateConstant();
|
||||
|
||||
G4double a, b, Winf;
|
||||
|
||||
if ( rc == 0 ) {
|
||||
a = 1/sigma * kact / kobs;
|
||||
b = (r0 - sigma) / 2;
|
||||
} else {
|
||||
G4double v = kact/Avogadro/(4*CLHEP::pi*pow(sigma,2) * exp(-rc / sigma));
|
||||
G4double alpha = v+rc*D/(pow(sigma,2)*(1-exp(-rc/sigma)));
|
||||
a = 4*pow(sigma,2)*alpha/(D*pow(rc,2))*pow(sinh(rc/(2*sigma)),2);
|
||||
b = rc/4*(cosh(rc/(2*r0))/sinh(rc/(2*r0))-cosh(rc/(2*sigma))/sinh(rc/(2*sigma)));
|
||||
r0 = -rc/(1-std::exp(rc/r0));
|
||||
sigma = fReactionData->GetEffectiveReactionRadius();
|
||||
}
|
||||
|
||||
if(sigma > r0){
|
||||
if(fReactionData->GetProbability() > G4UniformRand()) return 0;
|
||||
else return irt;
|
||||
}
|
||||
Winf = sigma / r0 * kobs / kdif;
|
||||
|
||||
if(Winf > G4UniformRand()) irt = SamplePDC(a,b)/D;
|
||||
return irt;
|
||||
}
|
||||
|
||||
return -1 * ps;
|
||||
}
|
||||
|
||||
G4int G4DNAIRT_geometries::FindBin(G4int n, G4double xmin, G4double xmax, G4double value) {
|
||||
|
||||
G4int bin = -1;
|
||||
if ( value <= xmin )
|
||||
bin = 0; //1;
|
||||
else if ( value >= xmax) //!(xmax < value) ) //value >= xmax )
|
||||
bin = n-1; //n;
|
||||
else
|
||||
bin = G4int( n * ( value - xmin )/( xmax - xmin ) ); //bin = 1 + G4int( n * ( value - xmin )/( xmax - xmin ) );
|
||||
|
||||
if ( bin < 0 ) bin = 0;
|
||||
if ( bin >= n ) bin = n-1;
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
G4double G4DNAIRT_geometries::SamplePDC(G4double a, G4double b) {
|
||||
|
||||
G4double p = 2.0 * std::sqrt(2.0*b/a);
|
||||
G4double q = 2.0 / std::sqrt(2.0*b/a);
|
||||
G4double M = max(1.0/(a*a),3.0*b/a);
|
||||
|
||||
G4double X, U, lambdax;
|
||||
|
||||
G4int ntrials = 0;
|
||||
while(1) {
|
||||
|
||||
// Generate X
|
||||
U = G4UniformRand();
|
||||
if ( U < p/(p + q * M) ) X = pow(U * (p + q * M) / 2, 2);
|
||||
else X = pow(2/((1-U)*(p+q*M)/M),2);
|
||||
|
||||
U = G4UniformRand();
|
||||
|
||||
lambdax = std::exp(-b*b/X) * ( 1.0 - a * std::sqrt(CLHEP::pi * X) * erfc->erfcx(b/std::sqrt(X) + a*std::sqrt(X)));
|
||||
|
||||
if ((X <= 2.0*b/a && U <= lambdax) ||
|
||||
(X >= 2.0*b/a && U*M/X <= lambdax)) break;
|
||||
|
||||
ntrials++;
|
||||
|
||||
if ( ntrials > 10000 ){
|
||||
G4cout<<"Totally rejected"<<'\n';
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
return X;
|
||||
}
|
||||
|
||||
std::unique_ptr<G4ITReactionChange> G4DNAIRT_geometries::MakeReaction(const G4Track& trackA,
|
||||
const G4Track& trackB)
|
||||
{
|
||||
|
||||
std::unique_ptr<G4ITReactionChange> pChanges(new G4ITReactionChange());
|
||||
pChanges->Initialize(trackA, trackB);
|
||||
|
||||
const auto pMoleculeA = GetMolecule(trackA)->GetMolecularConfiguration();
|
||||
const auto pMoleculeB = GetMolecule(trackB)->GetMolecularConfiguration();
|
||||
const auto pReactionData = fMolReactionTable->GetReactionData(pMoleculeA, pMoleculeB);
|
||||
|
||||
G4double globalTime = G4Scheduler::Instance()->GetGlobalTime();
|
||||
G4double effectiveReactionRadius = pReactionData->GetEffectiveReactionRadius();
|
||||
|
||||
const G4double D1 = pMoleculeA->GetDiffusionCoefficient();
|
||||
const G4double D2 = pMoleculeB->GetDiffusionCoefficient();
|
||||
|
||||
G4ThreeVector r1 = trackA.GetPosition();
|
||||
G4ThreeVector r2 = trackB.GetPosition();
|
||||
|
||||
if(r1 == r2) r2 += G4ThreeVector(0,0,1e-3*nm);
|
||||
|
||||
G4ThreeVector S1 = r1 - r2;
|
||||
|
||||
G4double r0 = S1.mag();
|
||||
|
||||
S1.setMag(effectiveReactionRadius);
|
||||
|
||||
G4double dt = globalTime - trackA.GetGlobalTime();
|
||||
|
||||
if(dt != 0 && (D1 + D2) != 0 && r0 != 0){
|
||||
G4double s12 = 2.0 * D1 * dt;
|
||||
G4double s22 = 2.0 * D2 * dt;
|
||||
if(s12 == 0) r2 = r1;
|
||||
else if(s22 == 0) r1 = r2;
|
||||
else{
|
||||
G4double alpha = effectiveReactionRadius * r0 / (2*(D1 + D2)*dt);
|
||||
G4ThreeVector S2 = (r1 + (s12 / s22)*r2) + G4ThreeVector(G4RandGauss::shoot(0, s12 + s22 * s22 / s12),
|
||||
G4RandGauss::shoot(0, s12 + s22 * s22 / s12),
|
||||
G4RandGauss::shoot(0, s12 + s22 * s22 / s12));
|
||||
|
||||
S1.setPhi(rad * G4UniformRand() * 2.0 * CLHEP::pi);
|
||||
S1.setTheta(rad * std::acos(1.0 + 1./alpha * std::log(1.0 - G4UniformRand() * (1 - std::exp(-2.0 * alpha)))));
|
||||
|
||||
r1 = (D1 * S1 + D2 * S2) / (D1 + D2);
|
||||
r2 = D2 * (S2 - S1) / (D1 + D2);
|
||||
}
|
||||
}
|
||||
|
||||
auto pTrackA = const_cast<G4Track*>(pChanges->GetTrackA());
|
||||
auto pTrackB = const_cast<G4Track*>(pChanges->GetTrackB());
|
||||
|
||||
pTrackA->SetPosition(r1);
|
||||
pTrackB->SetPosition(r2);
|
||||
|
||||
pTrackA->SetGlobalTime(globalTime);
|
||||
pTrackB->SetGlobalTime(globalTime);
|
||||
|
||||
pTrackA->SetTrackStatus(fStopButAlive);
|
||||
pTrackB->SetTrackStatus(fStopButAlive);
|
||||
|
||||
const G4int nbProducts = pReactionData->GetNbProducts();
|
||||
|
||||
if(nbProducts){
|
||||
|
||||
const G4double sqrD1 = D1 == 0. ? 0. : std::sqrt(D1);
|
||||
const G4double sqrD2 = D2 == 0. ? 0. : std::sqrt(D2);
|
||||
const G4double inv_numerator = 1./(sqrD1 + sqrD2);
|
||||
const G4ThreeVector reactionSite = sqrD2 * inv_numerator * trackA.GetPosition()
|
||||
+ sqrD1 * inv_numerator * trackB.GetPosition();
|
||||
|
||||
std::vector<G4ThreeVector> position;
|
||||
|
||||
if(nbProducts == 1){
|
||||
position.push_back(reactionSite);
|
||||
}else if(nbProducts == 2){
|
||||
position.push_back(trackA.GetPosition());
|
||||
position.push_back(trackB.GetPosition());
|
||||
}else if (nbProducts == 3){
|
||||
position.push_back(reactionSite);
|
||||
position.push_back(trackA.GetPosition());
|
||||
position.push_back(trackB.GetPosition());
|
||||
}
|
||||
|
||||
for(G4int u = 0; u < nbProducts; ++u){
|
||||
|
||||
auto product = new G4Molecule(pReactionData->GetProduct(u));
|
||||
auto productTrack = product->BuildTrack(globalTime,
|
||||
position[u]);
|
||||
|
||||
productTrack->SetTrackStatus(fAlive);
|
||||
fTrackHolder->Push(productTrack);
|
||||
|
||||
pChanges->AddSecondary(productTrack);
|
||||
|
||||
G4int I = FindBin(fNx, fXMin, fXMax, position[u].x());
|
||||
G4int J = FindBin(fNy, fYMin, fYMax, position[u].y());
|
||||
G4int K = FindBin(fNz, fZMin, fZMax, position[u].z());
|
||||
|
||||
spaceBinned[I][J][K].push_back(productTrack);
|
||||
|
||||
Sampling(productTrack);
|
||||
}
|
||||
}
|
||||
|
||||
fTrackHolder->MergeSecondariesWithMainList();
|
||||
pChanges->KillParents(true);
|
||||
return pChanges;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::unique_ptr<G4ITReactionChange>> G4DNAIRT_geometries::FindReaction(
|
||||
G4ITReactionSet* pReactionSet,
|
||||
const G4double /*currentStepTime*/,
|
||||
const G4double fGlobalTime,
|
||||
const G4bool /*reachedUserStepTimeLimit*/)
|
||||
{
|
||||
std::vector<std::unique_ptr<G4ITReactionChange>> fReactionInfo;
|
||||
fReactionInfo.clear();
|
||||
|
||||
if (pReactionSet == nullptr)
|
||||
{
|
||||
return fReactionInfo;
|
||||
}
|
||||
|
||||
auto fReactionsetInTime = pReactionSet->GetReactionsPerTime();
|
||||
assert(fReactionsetInTime.begin() != fReactionsetInTime.end());
|
||||
|
||||
auto it_begin = fReactionsetInTime.begin();
|
||||
while(it_begin != fReactionsetInTime.end())
|
||||
{
|
||||
G4double irt = it_begin->get()->GetTime();
|
||||
|
||||
if(fGlobalTime < irt) break;
|
||||
|
||||
pReactionSet->SelectThisReaction(*it_begin);
|
||||
|
||||
G4Track* pTrackA = it_begin->get()->GetReactants().first;
|
||||
G4Track* pTrackB = it_begin->get()->GetReactants().second;
|
||||
auto pReactionChange = MakeReaction(*pTrackA, *pTrackB);
|
||||
|
||||
if(pReactionChange){
|
||||
fReactionInfo.push_back(std::move(pReactionChange));
|
||||
}
|
||||
|
||||
fReactionsetInTime = pReactionSet->GetReactionsPerTime();
|
||||
it_begin = fReactionsetInTime.begin();
|
||||
}
|
||||
|
||||
return fReactionInfo;
|
||||
}
|
||||
|
||||
G4bool G4DNAIRT_geometries::TestReactibility(const G4Track& /*trackA*/,
|
||||
const G4Track& /*trackB*/,
|
||||
G4double /*currentStepTime*/,
|
||||
G4bool /*userStepTimeLimit*/) /*const*/
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void G4DNAIRT_geometries::SetReactionModel(G4VDNAReactionModel* model)
|
||||
{
|
||||
fpReactionModel = model;
|
||||
}
|
||||
+63
-69
@@ -27,108 +27,102 @@
|
||||
#include "globals.hh"
|
||||
#include "G4DNAMakeReaction.hh"
|
||||
#include <G4DNAMolecularReactionTable.hh>
|
||||
#include <memory>
|
||||
#include "G4DNAIndependentReactionTimeModel.hh"
|
||||
#include "G4DNAIndependentReactionTimeStepper.hh"
|
||||
#include "G4DiffusionControlledReactionModel.hh"
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4ReferenceCast.hh"
|
||||
#include "G4VDNAReactionModel.hh"
|
||||
#include "G4DNAReactionTypeManager.hh"
|
||||
#include "G4ChemicalMoleculeFinder.hh"
|
||||
|
||||
G4DNAIndependentReactionTimeModel::G4DNAIndependentReactionTimeModel(const G4String& name)
|
||||
: G4DNAIndependentReactionTimeModel(name,
|
||||
std::unique_ptr<G4DNAIndependentReactionTimeStepper>
|
||||
(new G4DNAIndependentReactionTimeStepper()),
|
||||
std::unique_ptr<G4DNAMakeReaction>
|
||||
(new G4DNAMakeReaction()))
|
||||
G4DNAIndependentReactionTimeModel::G4DNAIndependentReactionTimeModel(
|
||||
const G4String& name)
|
||||
: G4DNAIndependentReactionTimeModel(
|
||||
name, std::make_unique<G4DNAIndependentReactionTimeStepper>(),
|
||||
std::make_unique<G4DNAMakeReaction>())
|
||||
{}
|
||||
|
||||
G4DNAIndependentReactionTimeModel::G4DNAIndependentReactionTimeModel(const G4String& name,
|
||||
std::unique_ptr<G4VITTimeStepComputer> pTimeStepper,
|
||||
std::unique_ptr<G4VITReactionProcess> pReactionProcess)
|
||||
: G4VITStepModel(std::move(pTimeStepper),
|
||||
std::move(pReactionProcess),
|
||||
name)
|
||||
, fMolecularReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable))
|
||||
G4DNAIndependentReactionTimeModel::G4DNAIndependentReactionTimeModel(
|
||||
const G4String& name, std::unique_ptr<G4VITTimeStepComputer> pTimeStepper,
|
||||
std::unique_ptr<G4VITReactionProcess> pReactionProcess)
|
||||
: G4VITStepModel(std::move(pTimeStepper), std::move(pReactionProcess), name)
|
||||
{
|
||||
fType1 = G4Molecule::ITType();
|
||||
fType2 = G4Molecule::ITType();
|
||||
fType1 = G4Molecule::ITType();
|
||||
fType2 = G4Molecule::ITType();
|
||||
}
|
||||
|
||||
G4DNAIndependentReactionTimeModel::~G4DNAIndependentReactionTimeModel() = default;
|
||||
G4DNAIndependentReactionTimeModel::~G4DNAIndependentReactionTimeModel() =
|
||||
default;
|
||||
|
||||
void G4DNAIndependentReactionTimeModel::Initialize()
|
||||
{
|
||||
if(fpReactionTable == nullptr)
|
||||
{
|
||||
SetReactionTable(G4DNAMolecularReactionTable::GetReactionTable());
|
||||
}
|
||||
if(fpReactionTable == nullptr)
|
||||
{
|
||||
SetReactionTable(G4DNAMolecularReactionTable::GetReactionTable());
|
||||
}
|
||||
|
||||
if(!fpReactionModel)
|
||||
{
|
||||
fpReactionModel.reset(new G4DiffusionControlledReactionModel());
|
||||
}
|
||||
if(!fpReactionModel)
|
||||
{
|
||||
fpReactionModel = std::make_unique<G4DiffusionControlledReactionModel>();
|
||||
}
|
||||
|
||||
fpReactionModel->SetReactionTable((const G4DNAMolecularReactionTable*) fpReactionTable);
|
||||
fpReactionModel->SetReactionTable(
|
||||
(const G4DNAMolecularReactionTable*) fpReactionTable);
|
||||
|
||||
((G4DiffusionControlledReactionModel*) fpReactionModel.get())->SetReactionTypeManager(fReactionTypeManager.get());
|
||||
((G4DNAMakeReaction*) fpReactionProcess.get())
|
||||
->SetReactionModel(fpReactionModel.get());
|
||||
|
||||
((G4DNAMakeReaction*) fpReactionProcess.get())->SetReactionModel(fpReactionModel.get());
|
||||
((G4DNAMakeReaction*) fpReactionProcess.get())
|
||||
->SetTimeStepComputer(fpTimeStepper.get());
|
||||
|
||||
((G4DNAMakeReaction*) fpReactionProcess.get())->SetTimeStepComputer(fpTimeStepper.get());
|
||||
|
||||
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())->SetReactionModel(fpReactionModel.get());
|
||||
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())
|
||||
->SetReactionModel(fpReactionModel.get());
|
||||
|
||||
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())->SetReactionTypeManager(fReactionTypeManager.get());
|
||||
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())
|
||||
->SetReactionProcess((fpReactionProcess).get());
|
||||
|
||||
((G4DNAIndependentReactionTimeStepper*) fpTimeStepper.get())->SetReactionProcess((fpReactionProcess).get());
|
||||
|
||||
G4ChemicalMoleculeFinder::Instance()->Clear();
|
||||
G4VITStepModel::Initialize();
|
||||
G4ChemicalMoleculeFinder::Instance()->Clear();
|
||||
G4ChemicalMoleculeFinder::Instance()->SetOctreeUsed(true);
|
||||
G4VITStepModel::Initialize();
|
||||
}
|
||||
void G4DNAIndependentReactionTimeModel::PrintInfo()
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if(G4Threading::IsMultithreadedApplication())
|
||||
if(G4Threading::IsMultithreadedApplication())
|
||||
{
|
||||
if(G4Threading::G4GetThreadId() == 0)
|
||||
{
|
||||
if(G4Threading::G4GetThreadId() == 0)
|
||||
{
|
||||
G4VITStepModel::PrintInfo();
|
||||
G4cout<<G4endl;
|
||||
G4cout << fName << " will be used ==========================" << G4endl;
|
||||
G4cout<<G4endl;
|
||||
G4cout << "==============================="
|
||||
"========================================"<<G4endl;
|
||||
G4cout<<G4endl;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4VITStepModel::PrintInfo();
|
||||
G4cout<<G4endl;
|
||||
G4cout << fName << " will be used ==========================" << G4endl;
|
||||
G4cout<<G4endl;
|
||||
G4cout << "==============================="
|
||||
"========================================"<<G4endl;
|
||||
G4cout<<G4endl;
|
||||
|
||||
G4VITStepModel::PrintInfo();
|
||||
G4cout << G4endl;
|
||||
G4cout << fName << " will be used ==========================" << G4endl;
|
||||
G4cout << G4endl;
|
||||
G4cout << "==============================="
|
||||
"========================================"
|
||||
<< G4endl;
|
||||
G4cout << G4endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4VITStepModel::PrintInfo();
|
||||
G4cout << G4endl;
|
||||
G4cout << fName << " will be used ==========================" << G4endl;
|
||||
G4cout << G4endl;
|
||||
G4cout << "==============================="
|
||||
"========================================"
|
||||
<< G4endl;
|
||||
G4cout << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeModel::SetReactionModel(G4VDNAReactionModel* pReactionModel)
|
||||
void G4DNAIndependentReactionTimeModel::SetReactionModel(
|
||||
G4VDNAReactionModel* pReactionModel)
|
||||
{
|
||||
fpReactionModel.reset(pReactionModel);
|
||||
fpReactionModel.reset(pReactionModel);
|
||||
}
|
||||
|
||||
G4VDNAReactionModel* G4DNAIndependentReactionTimeModel::GetReactionModel()
|
||||
{
|
||||
return fpReactionModel.get();
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeModel::SetReactionTypeManager(G4VReactionTypeManager* pReactionProcessManager)
|
||||
{
|
||||
fReactionTypeManager.reset(pReactionProcessManager);
|
||||
}
|
||||
return fpReactionModel.get();
|
||||
}
|
||||
+361
-374
@@ -25,465 +25,452 @@
|
||||
// 20/2/2019
|
||||
// Author: HoangTRAN
|
||||
|
||||
#include <memory>
|
||||
#include "G4DNAIndependentReactionTimeStepper.hh"
|
||||
#include "G4VDNAReactionModel.hh"
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
#include "G4memory.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4ChemicalMoleculeFinder.hh"
|
||||
#include "G4MolecularConfiguration.hh"
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAReactionTypeManager.hh"
|
||||
#include "G4DNAMakeReaction.hh"
|
||||
#include "G4ITReaction.hh"
|
||||
#include "G4ITReactionChange.hh"
|
||||
#include "G4Scheduler.hh"
|
||||
#include "G4ITTrackHolder.hh"
|
||||
#include "G4IRTUtils.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4DiffusionControlledReactionModel.hh"
|
||||
using namespace std;
|
||||
using namespace CLHEP;
|
||||
|
||||
G4DNAIndependentReactionTimeStepper::Utils::Utils(const G4Track& trackA,
|
||||
const G4Track& trackB)
|
||||
: fTrackA(trackA)
|
||||
, fTrackB(trackB)
|
||||
: fTrackA(trackA)
|
||||
, fTrackB(trackB)
|
||||
{
|
||||
fpMoleculeA = GetMolecule(trackA);
|
||||
fpMoleculeB = GetMolecule(trackA);
|
||||
fpMoleculeA = GetMolecule(trackA);
|
||||
fpMoleculeB = GetMolecule(trackA);
|
||||
}
|
||||
|
||||
G4DNAIndependentReactionTimeStepper::G4DNAIndependentReactionTimeStepper()
|
||||
: G4VITTimeStepComputer()
|
||||
, fHasAlreadyReachedNullTime(false)
|
||||
, fMolecularReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable))
|
||||
, fReactionModel(nullptr)
|
||||
, fpTrackContainer(G4ITTrackHolder::Instance())
|
||||
, fReactionSet(G4ITReactionSet::Instance())
|
||||
, fVerbose(0)
|
||||
, fRCutOff(G4IRTUtils::GetRCutOff())
|
||||
, fReactionTypeManager(nullptr)
|
||||
, fpReactionProcess(nullptr)
|
||||
: G4VITTimeStepComputer()
|
||||
{
|
||||
fReactionSet->SortByTime();
|
||||
fReactionSet->SortByTime();
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::Prepare()
|
||||
{
|
||||
G4VITTimeStepComputer::Prepare();
|
||||
fSampledPositions.clear();
|
||||
BuildChemicalMoleculeFinder()
|
||||
G4VITTimeStepComputer::Prepare();
|
||||
fSampledPositions.clear();
|
||||
BuildChemicalMoleculeFinder()
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::InitializeForNewTrack()
|
||||
{
|
||||
if (fReactants != nullptr)
|
||||
{
|
||||
fReactants.reset();
|
||||
}
|
||||
fSampledMinTimeStep = DBL_MAX;
|
||||
fHasAlreadyReachedNullTime = false;
|
||||
if(fReactants != nullptr)
|
||||
{
|
||||
fReactants.reset();
|
||||
}
|
||||
fSampledMinTimeStep = DBL_MAX;
|
||||
fHasAlreadyReachedNullTime = false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline G4bool IsInf(T value)
|
||||
G4double G4DNAIndependentReactionTimeStepper::CalculateStep(
|
||||
const G4Track& trackA, const G4double& userMinTimeStep)
|
||||
{
|
||||
return std::numeric_limits<T>::has_infinity
|
||||
&& value == std::numeric_limits<T>::infinity();
|
||||
}
|
||||
G4double
|
||||
G4DNAIndependentReactionTimeStepper::CalculateStep(const G4Track& trackA,
|
||||
const G4double& userMinTimeStep)
|
||||
{
|
||||
auto pMoleculeA = GetMolecule(trackA);
|
||||
InitializeForNewTrack();
|
||||
fUserMinTimeStep = userMinTimeStep;
|
||||
auto pMoleculeA = GetMolecule(trackA);
|
||||
InitializeForNewTrack();
|
||||
fUserMinTimeStep = userMinTimeStep;
|
||||
fCheckedTracks.insert(trackA.GetTrackID());
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (fVerbose)
|
||||
{
|
||||
G4cout
|
||||
<< "_______________________________________________________________________"
|
||||
<< G4endl;
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep" << G4endl;
|
||||
G4cout << "Check done for molecule : " << pMoleculeA->GetName()
|
||||
<< " (" << trackA.GetTrackID() << ") "
|
||||
<< G4endl;
|
||||
}
|
||||
if(fVerbose != 0)
|
||||
{
|
||||
G4cout << "________________________________________________________________"
|
||||
"_______"
|
||||
<< G4endl;
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep" << G4endl;
|
||||
G4cout << "Check done for molecule : " << pMoleculeA->GetName() << " ("
|
||||
<< trackA.GetTrackID() << ") " << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto pMolConfA = pMoleculeA->GetMolecularConfiguration();
|
||||
auto pMolConfA = pMoleculeA->GetMolecularConfiguration();
|
||||
|
||||
const auto pReactantList = fMolecularReactionTable->CanReactWith(pMolConfA);
|
||||
const auto pReactantList = fMolecularReactionTable->CanReactWith(pMolConfA);
|
||||
|
||||
if (!pReactantList)
|
||||
{
|
||||
if(pReactantList == nullptr)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if (fVerbose > 1)
|
||||
{
|
||||
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
|
||||
G4cout << "!!! WARNING" << G4endl;
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will return infinity "
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
return DBL_MAX;
|
||||
<< pMoleculeA->GetName()
|
||||
<< " does not have any reactants given in the reaction table."
|
||||
<< G4endl;
|
||||
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
|
||||
}
|
||||
#endif
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
G4int nbReactives = pReactantList->size();
|
||||
G4int nbReactives = pReactantList->size();
|
||||
|
||||
if (nbReactives == 0)
|
||||
{
|
||||
if(nbReactives == 0)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
// DEBUG
|
||||
if (fVerbose)
|
||||
{
|
||||
G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
|
||||
G4cout << "!!! WARNING" << G4endl;
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will return infinity "
|
||||
// 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;
|
||||
}
|
||||
<< 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;
|
||||
}
|
||||
#endif
|
||||
return DBL_MAX;
|
||||
}
|
||||
fReactants.reset(new vector<G4Track*>());
|
||||
fReactionModel->Initialise(pMolConfA, trackA);
|
||||
for (G4int i = 0; i < nbReactives; i++)
|
||||
return DBL_MAX;
|
||||
}
|
||||
fReactants = std::make_shared<vector<G4Track*>>();
|
||||
fReactionModel->Initialise(pMolConfA, trackA);
|
||||
for(G4int i = 0; i < nbReactives; i++)
|
||||
{
|
||||
auto pMoleculeB = (*pReactantList)[i];
|
||||
G4int key = pMoleculeB->GetMoleculeID();
|
||||
|
||||
// fRCutOff = G4IRTUtils::GetRCutOff(1 * ps);
|
||||
fRCutOff = G4IRTUtils::GetRCutOff();
|
||||
//______________________________________________________________
|
||||
// Retrieve reaction range
|
||||
const G4double Reff = fReactionModel->GetReactionRadius(i);
|
||||
std::vector<std::pair<G4TrackList::iterator, G4double>> resultIndices;
|
||||
resultIndices.clear();
|
||||
G4ChemicalMoleculeFinder::Instance()->FindNearestInRange(
|
||||
trackA, key, fRCutOff, resultIndices);
|
||||
|
||||
if(resultIndices.empty())
|
||||
{
|
||||
auto pMoleculeB = (*pReactantList)[i];
|
||||
G4int key = pMoleculeB->GetMoleculeID();
|
||||
|
||||
//fRCutOff = G4IRTUtils::GetRCutOff(1 * ps);
|
||||
fRCutOff = G4IRTUtils::GetRCutOff();
|
||||
//______________________________________________________________
|
||||
// Retrieve reaction range
|
||||
const G4double Reff = fReactionModel->GetReactionRadius(i);
|
||||
std::vector<std::pair<G4TrackList::iterator,G4double>> resultIndices;
|
||||
resultIndices.clear();
|
||||
G4ChemicalMoleculeFinder::Instance()->
|
||||
FindNearestInRange(trackA,
|
||||
key,
|
||||
fRCutOff,
|
||||
resultIndices);
|
||||
|
||||
if(resultIndices.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for(auto& it : resultIndices)
|
||||
{
|
||||
G4Track* pTrackB = *(std::get<0>(it));
|
||||
|
||||
if(pTrackB == &trackA)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(pTrackB == nullptr)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No trackB no valid";
|
||||
G4Exception("G4DNAIndependentReactionTimeModel"
|
||||
"::BuildReactionMap()", "NO_TRACK02",
|
||||
FatalException, exceptionDescription);
|
||||
}
|
||||
Utils utils(trackA, *pTrackB);
|
||||
|
||||
auto pMolB = GetMolecule(pTrackB);
|
||||
auto pMolConfB = pMolB->GetMolecularConfiguration();
|
||||
G4double distance = (trackA.GetPosition() - pTrackB->GetPosition()).mag();
|
||||
if(distance * distance < Reff * Reff)
|
||||
{
|
||||
auto processTable = *(fReactionTypeManager->GetReactionTypeTable());
|
||||
auto typeOfReaction = (G4int)GetReactionType(trackA, *pTrackB);
|
||||
if(processTable[typeOfReaction]->
|
||||
GeminateRecombinationProbability(pMolConfA, pMolConfB))
|
||||
{
|
||||
if (!fHasAlreadyReachedNullTime)
|
||||
{
|
||||
fReactants->clear();
|
||||
fHasAlreadyReachedNullTime = true;
|
||||
}
|
||||
fSampledMinTimeStep = 0.;
|
||||
CheckAndRecordResults(utils);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double tempMinET = GetTimeToEncounter(trackA, *pTrackB);
|
||||
if(tempMinET < 0 ||
|
||||
tempMinET > G4Scheduler::Instance()->GetEndTime())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (tempMinET >= fSampledMinTimeStep)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fSampledMinTimeStep = tempMinET;
|
||||
fReactants->clear();
|
||||
CheckAndRecordResults(utils);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for(auto& it : resultIndices)
|
||||
{
|
||||
G4Track* pTrackB = *(std::get<0>(it));
|
||||
|
||||
if(pTrackB == &trackA)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(pTrackB == nullptr)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No trackB no valid";
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper"
|
||||
"::CalculateStep()",
|
||||
"G4DNAIndependentReactionTimeStepper007", FatalException,
|
||||
exceptionDescription);
|
||||
}
|
||||
|
||||
if(fCheckedTracks.find(pTrackB->GetTrackID()) != fCheckedTracks.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Utils utils(trackA, *pTrackB);
|
||||
|
||||
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(reactionData->GetProbability() > G4UniformRand())
|
||||
{
|
||||
if(!fHasAlreadyReachedNullTime)
|
||||
{
|
||||
fReactants->clear();
|
||||
fHasAlreadyReachedNullTime = true;
|
||||
}
|
||||
fSampledMinTimeStep = 0.;
|
||||
CheckAndRecordResults(utils);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double tempMinET = GetTimeToEncounter(trackA, *pTrackB);
|
||||
if(tempMinET < 0 || tempMinET > G4Scheduler::Instance()->GetEndTime())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(tempMinET >= fSampledMinTimeStep)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fSampledMinTimeStep = tempMinET;
|
||||
fReactants->clear();
|
||||
CheckAndRecordResults(utils);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if (fVerbose)
|
||||
if(fVerbose != 0)
|
||||
{
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will finally "
|
||||
"return :"
|
||||
<< G4BestUnit(fSampledMinTimeStep, "Time") << G4endl;
|
||||
|
||||
if(fVerbose > 1)
|
||||
{
|
||||
G4cout << "G4DNAIndependentReactionTimeStepper::CalculateStep will finally return :"
|
||||
<< G4BestUnit(fSampledMinTimeStep, "Time") << G4endl;
|
||||
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++)
|
||||
{
|
||||
G4Track* trackB = *it;
|
||||
G4cout << GetMolecule(trackB)->GetName() << " ("
|
||||
<< trackB->GetTrackID() << ") \t ";
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
vector<G4Track*>::iterator it;
|
||||
for(it = fReactants->begin(); it != fReactants->end(); it++)
|
||||
{
|
||||
G4Track* trackB = *it;
|
||||
G4cout << GetMolecule(trackB)->GetName() << " (" << trackB->GetTrackID()
|
||||
<< ") \t ";
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (const auto& it : *fReactants)
|
||||
{
|
||||
auto pTrackB = it;
|
||||
fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
|
||||
}
|
||||
return fSampledMinTimeStep;
|
||||
return fSampledMinTimeStep;
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::CheckAndRecordResults(const Utils& utils)
|
||||
void G4DNAIndependentReactionTimeStepper::CheckAndRecordResults(
|
||||
const Utils& utils)
|
||||
{
|
||||
if (utils.fTrackB.GetTrackStatus() != fAlive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(utils.fTrackB.GetTrackStatus() != fAlive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (&utils.fTrackB == &utils.fTrackA)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription<< "A track is reacting with itself"
|
||||
" (which is impossible) ie fpTrackA == trackB"<< G4endl;
|
||||
exceptionDescription << "Molecule A is of type : "
|
||||
<< utils.fpMoleculeA->GetName() << " with trackID : "
|
||||
<< utils.fTrackA.GetTrackID()<<" and B : "
|
||||
<< utils.fpMoleculeB->GetName() << " with trackID : "
|
||||
<< utils.fTrackB.GetTrackID() << G4endl;
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
|
||||
"G4DNAIndependentReactionTimeStepper003", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
if(&utils.fTrackB == &utils.fTrackA)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "A track is reacting with itself"
|
||||
" (which is impossible) ie fpTrackA == trackB"
|
||||
<< G4endl;
|
||||
exceptionDescription << "Molecule A is of type : "
|
||||
<< utils.fpMoleculeA->GetName()
|
||||
<< " with trackID : " << utils.fTrackA.GetTrackID()
|
||||
<< " and B : " << utils.fpMoleculeB->GetName()
|
||||
<< " with trackID : " << utils.fTrackB.GetTrackID()
|
||||
<< G4endl;
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
|
||||
"G4DNAIndependentReactionTimeStepper003", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
exceptionDescription << "fpTrackA : trackID : " << utils.fTrackA.GetTrackID()
|
||||
<< "\t Name :" << utils.fpMoleculeA->GetName()
|
||||
<< "\t fpTrackA->GetGlobalTime() = "
|
||||
<< G4BestUnit(utils.fTrackA.GetGlobalTime(), "Time") << G4endl;
|
||||
exceptionDescription << "fpTrackA : trackID : "
|
||||
<< utils.fTrackA.GetTrackID()
|
||||
<< "\t Name :" << utils.fpMoleculeA->GetName()
|
||||
<< "\t fpTrackA->GetGlobalTime() = "
|
||||
<< G4BestUnit(utils.fTrackA.GetGlobalTime(), "Time")
|
||||
<< G4endl;
|
||||
|
||||
exceptionDescription << "trackB : trackID : " << utils.fTrackB.GetTrackID()
|
||||
<< "\t Name :" << utils.fpMoleculeB->GetName()
|
||||
<< "\t trackB->GetGlobalTime() = "
|
||||
<< G4BestUnit(utils.fTrackB.GetGlobalTime(), "Time") << G4endl;
|
||||
exceptionDescription << "trackB : trackID : " << utils.fTrackB.GetTrackID()
|
||||
<< "\t Name :" << utils.fpMoleculeB->GetName()
|
||||
<< "\t trackB->GetGlobalTime() = "
|
||||
<< G4BestUnit(utils.fTrackB.GetGlobalTime(), "Time")
|
||||
<< G4endl;
|
||||
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
|
||||
"G4DNAIndependentReactionTimeStepper004", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
fReactants->push_back(const_cast<G4Track*>(&utils.fTrackB));
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::RetrieveResults",
|
||||
"G4DNAIndependentReactionTimeStepper004", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
fReactants->push_back(const_cast<G4Track*>(&utils.fTrackB));
|
||||
}
|
||||
|
||||
std::unique_ptr<G4ITReactionChange>
|
||||
G4DNAIndependentReactionTimeStepper::FindReaction(G4ITReactionSet* pReactionSet,
|
||||
const G4double& currentStepTime,
|
||||
const G4double& /*previousStepTime*/,
|
||||
const G4bool& /*reachedUserStepTimeLimit*/)
|
||||
G4DNAIndependentReactionTimeStepper::FindReaction(
|
||||
G4ITReactionSet* pReactionSet, const G4double& currentStepTime,
|
||||
const G4double& /*previousStepTime*/,
|
||||
const G4bool& /*reachedUserStepTimeLimit*/)
|
||||
{
|
||||
if (pReactionSet == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
G4ITReactionPerTime& reactionPerTime = pReactionSet->GetReactionsPerTime();
|
||||
if(reactionPerTime.empty())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto reaction_i = reactionPerTime.begin();
|
||||
reaction_i != reactionPerTime.end();
|
||||
reaction_i = reactionPerTime.begin())
|
||||
{
|
||||
G4Track* pTrackA = (*reaction_i)->GetReactants().first;
|
||||
if (pTrackA->GetTrackStatus() == fStopAndKill)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
G4Track* pTrackB = (*reaction_i)->GetReactant(pTrackA);
|
||||
if (pTrackB->GetTrackStatus() == fStopAndKill)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pTrackB == pTrackA)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription
|
||||
<< "The IT reaction process sent back a reaction between trackA and trackB. ";
|
||||
exceptionDescription << "The problem is trackA == trackB";
|
||||
G4Exception("G4ITModelProcessor::FindReaction",
|
||||
"ITModelProcessor005",
|
||||
FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
pReactionSet->SelectThisReaction(*reaction_i);
|
||||
if(fpReactionProcess != nullptr && fpReactionProcess->TestReactibility(*pTrackA,
|
||||
*pTrackB,
|
||||
currentStepTime,
|
||||
false))
|
||||
{
|
||||
pTrackA->SetPosition(fSampledPositions[pTrackA->GetTrackID()]);
|
||||
pTrackB->SetPosition(fSampledPositions[pTrackB->GetTrackID()]);
|
||||
auto pReactionChange = fpReactionProcess->MakeReaction(*pTrackA, *pTrackB);
|
||||
if (pReactionChange == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return pReactionChange;
|
||||
}
|
||||
}
|
||||
if(pReactionSet == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
G4ITReactionPerTime& reactionPerTime = pReactionSet->GetReactionsPerTime();
|
||||
if(reactionPerTime.empty())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for(auto reaction_i = reactionPerTime.begin();
|
||||
reaction_i != reactionPerTime.end(); reaction_i = reactionPerTime.begin())
|
||||
{
|
||||
G4Track* pTrackA = (*reaction_i)->GetReactants().first;
|
||||
if(pTrackA->GetTrackStatus() == fStopAndKill)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
G4Track* pTrackB = (*reaction_i)->GetReactant(pTrackA);
|
||||
if(pTrackB->GetTrackStatus() == fStopAndKill)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(pTrackB == pTrackA)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "The IT reaction process sent back a reaction "
|
||||
"between trackA and trackB. ";
|
||||
exceptionDescription << "The problem is trackA == trackB";
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::FindReaction",
|
||||
"G4DNAIndependentReactionTimeStepper02", FatalErrorInArgument,
|
||||
exceptionDescription);
|
||||
}
|
||||
pReactionSet->SelectThisReaction(*reaction_i);
|
||||
if(fpReactionProcess != nullptr &&
|
||||
fpReactionProcess->TestReactibility(*pTrackA, *pTrackB, currentStepTime,
|
||||
false))
|
||||
{
|
||||
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 ";
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::FindReaction",
|
||||
"G4DNAIndependentReactionTimeStepper0001",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
}
|
||||
|
||||
pTrackA->SetPosition(fSampledPositions[pTrackA->GetTrackID()]);
|
||||
pTrackB->SetPosition(fSampledPositions[pTrackB->GetTrackID()]);
|
||||
auto pReactionChange =
|
||||
fpReactionProcess->MakeReaction(*pTrackA, *pTrackB);
|
||||
if(pReactionChange == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return pReactionChange;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionModel(G4VDNAReactionModel* pReactionModel)
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionModel(
|
||||
G4VDNAReactionModel* pReactionModel)
|
||||
{
|
||||
fReactionModel = pReactionModel;
|
||||
fReactionModel = pReactionModel;
|
||||
}
|
||||
|
||||
G4VDNAReactionModel* G4DNAIndependentReactionTimeStepper::GetReactionModel()
|
||||
{
|
||||
return fReactionModel;
|
||||
return fReactionModel;
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::SetVerbose(G4int flag)
|
||||
{
|
||||
fVerbose = flag;
|
||||
fVerbose = flag;
|
||||
}
|
||||
|
||||
ReactionType G4DNAIndependentReactionTimeStepper::GetReactionType(const G4Track& trackA,
|
||||
const G4Track& trackB)
|
||||
G4double G4DNAIndependentReactionTimeStepper::GetTimeToEncounter(
|
||||
const G4Track& trackA, const G4Track& trackB)
|
||||
{
|
||||
auto pMoleculeA = GetMolecule(trackA)->GetMolecularConfiguration();
|
||||
auto pMoleculeB = GetMolecule(trackB)->GetMolecularConfiguration();
|
||||
auto pData = fMolecularReactionTable->GetReactionData(pMoleculeA,pMoleculeB);
|
||||
G4int reactionID = pData->GetReactionID();
|
||||
return fReactionTypeManager->GetReactionTypeByID(reactionID);
|
||||
G4double timeToReaction =
|
||||
dynamic_cast<G4DiffusionControlledReactionModel*>(fReactionModel)
|
||||
->GetTimeToEncounter(trackA, trackB);
|
||||
return timeToReaction;
|
||||
}
|
||||
|
||||
G4double G4DNAIndependentReactionTimeStepper::GetTimeToEncounter(const G4Track& trackA,
|
||||
const G4Track& trackB)
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionProcess(
|
||||
G4VITReactionProcess* pReactionProcess)
|
||||
{
|
||||
if(fReactionTypeManager == nullptr)
|
||||
fpReactionProcess = pReactionProcess;
|
||||
}
|
||||
G4double G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep(
|
||||
G4double /*currentGlobalTime*/, G4double definedMinTimeStep)
|
||||
{
|
||||
G4double fTSTimeStep = DBL_MAX;
|
||||
fCheckedTracks.clear();
|
||||
|
||||
for(auto pTrack : *fpTrackContainer->GetMainList())
|
||||
{
|
||||
if(pTrack == nullptr)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "fpProManager is not "
|
||||
"initialized ";
|
||||
G4Exception("G4DNAIndependentReactionTimeModel::"
|
||||
"GetIndependentReactionTime()",
|
||||
"G4DNAIndependentReactionTimeModel002",
|
||||
FatalErrorInArgument,exceptionDescription);
|
||||
}
|
||||
auto processTable = *(fReactionTypeManager->GetReactionTypeTable());
|
||||
ReactionType reactionType = GetReactionType(trackA,trackB);
|
||||
|
||||
#ifdef DEBUG
|
||||
G4cout<<"A: "<<GetMolecule(trackA)->GetName()<<"("<<trackA.GetTrackID()<<")"<<" + B : "
|
||||
<<GetMolecule(trackB)->GetName()<<"("<<trackB.GetTrackID()<<")"<<G4endl;
|
||||
#endif
|
||||
|
||||
return processTable[(G4int)reactionType]->GetTimeToEncounter(trackA,trackB);
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionTypeManager(G4VReactionTypeManager* typeManager)
|
||||
{
|
||||
fReactionTypeManager = ((G4DNAReactionTypeManager*)typeManager);
|
||||
}
|
||||
|
||||
void G4DNAIndependentReactionTimeStepper::SetReactionProcess(G4VITReactionProcess* pReactionProcess)
|
||||
{
|
||||
fpReactionProcess = pReactionProcess;
|
||||
}
|
||||
G4double G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep(G4double /*currentGlobalTime*/, G4double definedMinTimeStep)
|
||||
{
|
||||
G4double fTSTimeStep = DBL_MAX;
|
||||
|
||||
for (auto pTrack : *fpTrackContainer->GetMainList())
|
||||
{
|
||||
if (pTrack == nullptr)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No track found.";
|
||||
G4Exception("G4Scheduler::CalculateMinStep", "ITScheduler006",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
continue;
|
||||
}
|
||||
|
||||
G4TrackStatus trackStatus = pTrack->GetTrackStatus();
|
||||
if (trackStatus == fStopAndKill || trackStatus == fStopButAlive)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
G4double sampledMinTimeStep = CalculateStep(*pTrack, definedMinTimeStep);
|
||||
G4TrackVectorHandle reactants = GetReactants();
|
||||
|
||||
if (sampledMinTimeStep < fTSTimeStep)
|
||||
{
|
||||
fTSTimeStep = sampledMinTimeStep;
|
||||
fReactionSet->CleanAllReaction();
|
||||
if (reactants)
|
||||
{
|
||||
fReactionSet->AddReactions(fTSTimeStep,
|
||||
const_cast<G4Track*>(pTrack),
|
||||
reactants);
|
||||
ResetReactants();
|
||||
}
|
||||
}
|
||||
else if (fTSTimeStep == sampledMinTimeStep && G4bool(reactants))
|
||||
{
|
||||
fReactionSet->AddReactions(fTSTimeStep,
|
||||
const_cast<G4Track*>(pTrack),
|
||||
reactants);
|
||||
ResetReactants();
|
||||
}
|
||||
else if (reactants)
|
||||
{
|
||||
ResetReactants();
|
||||
}
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No track found.";
|
||||
G4Exception("G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep",
|
||||
"G4DNAIndependentReactionTimeStepper006",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
continue;
|
||||
}
|
||||
|
||||
return fTSTimeStep;
|
||||
G4TrackStatus trackStatus = pTrack->GetTrackStatus();
|
||||
if(trackStatus == fStopAndKill || trackStatus == fStopButAlive)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
G4double sampledMinTimeStep = CalculateStep(*pTrack, definedMinTimeStep);
|
||||
G4TrackVectorHandle reactants = GetReactants();
|
||||
|
||||
if(sampledMinTimeStep < fTSTimeStep)
|
||||
{
|
||||
fTSTimeStep = sampledMinTimeStep;
|
||||
fReactionSet->CleanAllReaction();
|
||||
if(reactants)
|
||||
{
|
||||
fReactionSet->AddReactions(fTSTimeStep, const_cast<G4Track*>(pTrack),
|
||||
reactants);
|
||||
|
||||
fSampledPositions[pTrack->GetTrackID()] = pTrack->GetPosition();
|
||||
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);
|
||||
|
||||
fSampledPositions[pTrack->GetTrackID()] = pTrack->GetPosition();
|
||||
for(const auto& it : *fReactants)
|
||||
{
|
||||
auto pTrackB = it;
|
||||
// G4cout<<"position : "<<pTrackB->GetTrackID()<<G4endl;
|
||||
fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
|
||||
}
|
||||
ResetReactants();
|
||||
}
|
||||
else if(reactants)
|
||||
{
|
||||
ResetReactants();
|
||||
}
|
||||
}
|
||||
|
||||
return fTSTimeStep;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ G4DNAIonElasticModel::Initialise (
|
||||
|
||||
G4double scaleFactor = 1e-16*cm*cm;
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
if (!path)
|
||||
{
|
||||
|
||||
+41
-46
@@ -30,7 +30,10 @@
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4Alpha.hh"
|
||||
|
||||
static G4Pow * gpow = G4Pow::GetInstance();
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
@@ -86,11 +89,11 @@ void G4DNAMillerGreenExcitationModel::Initialise(const G4ParticleDefinition* par
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
|
||||
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
|
||||
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
|
||||
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
|
||||
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
|
||||
protonDef = G4Proton::ProtonDefinition();
|
||||
hydrogenDef = instance->GetIon("hydrogen");
|
||||
alphaPlusPlusDef = G4Alpha::Alpha();
|
||||
alphaPlusDef = instance->GetIon("alpha+");
|
||||
heliumDef = instance->GetIon("helium");
|
||||
|
||||
G4String proton;
|
||||
G4String hydrogen;
|
||||
@@ -232,19 +235,16 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (
|
||||
particleDefinition != G4Proton::ProtonDefinition()
|
||||
particleDefinition != protonDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("hydrogen")
|
||||
particleDefinition != hydrogenDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha++")
|
||||
particleDefinition != alphaPlusPlusDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha+")
|
||||
particleDefinition != alphaPlusDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("helium")
|
||||
particleDefinition != heliumDef
|
||||
)
|
||||
|
||||
return 0;
|
||||
@@ -279,9 +279,9 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
|
||||
// add ONE or TWO electron-water excitation for alpha+ and helium
|
||||
/*
|
||||
if ( particleDefinition == instance->GetIon("alpha+")
|
||||
if ( particleDefinition == alphaPlusDef
|
||||
||
|
||||
particleDefinition == instance->GetIon("helium")
|
||||
particleDefinition == heliumDef
|
||||
)
|
||||
{
|
||||
|
||||
@@ -295,10 +295,10 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
excitationXS->CrossSectionPerVolume(material,G4Electron::ElectronDefinition(),k*0.511/3728,tmp,tmp)
|
||||
/material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
if ( particleDefinition == instance->GetIon("alpha+") )
|
||||
if ( particleDefinition == alphaPlusDef )
|
||||
crossSection = crossSection + sigmaExcitation ;
|
||||
|
||||
if ( particleDefinition == instance->GetIon("helium") )
|
||||
if ( particleDefinition == heliumDef )
|
||||
crossSection = crossSection + 2*sigmaExcitation ;
|
||||
|
||||
delete excitationXS;
|
||||
@@ -315,10 +315,10 @@ G4double G4DNAMillerGreenExcitationModel::CrossSectionPerVolume(const G4Material
|
||||
excitationXS->CrossSectionPerVolume(material,G4Electron::ElectronDefinition(),k*0.511/3728,tmp,tmp)
|
||||
/material->GetAtomicNumDensityVector()[1];
|
||||
|
||||
if ( particleDefinition == instance->GetIon("alpha+") )
|
||||
if ( particleDefinition == alphaPlusDef )
|
||||
crossSection = crossSection + sigmaExcitation ;
|
||||
|
||||
if ( particleDefinition == instance->GetIon("helium") )
|
||||
if ( particleDefinition == heliumDef )
|
||||
crossSection = crossSection + 2*sigmaExcitation ;
|
||||
|
||||
delete excitationXS;
|
||||
@@ -421,14 +421,12 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
|
||||
const G4double Eliq[5]={ 8.17*eV, 10.13*eV, 11.31*eV, 12.91*eV, 14.50*eV};
|
||||
|
||||
G4int particleTypeIndex = 0;
|
||||
G4DNAGenericIonsManager* instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition()) particleTypeIndex=0;
|
||||
if (particleDefinition == instance->GetIon("hydrogen")) particleTypeIndex=0;
|
||||
if (particleDefinition == instance->GetIon("alpha++")) particleTypeIndex=1;
|
||||
if (particleDefinition == instance->GetIon("alpha+")) particleTypeIndex=2;
|
||||
if (particleDefinition == instance->GetIon("helium")) particleTypeIndex=3;
|
||||
|
||||
if (particleDefinition == protonDef) particleTypeIndex=0;
|
||||
if (particleDefinition == hydrogenDef) particleTypeIndex=0;
|
||||
if (particleDefinition == alphaPlusPlusDef) particleTypeIndex=1;
|
||||
if (particleDefinition == alphaPlusDef) particleTypeIndex=2;
|
||||
if (particleDefinition == heliumDef) particleTypeIndex=3;
|
||||
|
||||
G4double tCorrected;
|
||||
tCorrected = k * kineticEnergyCorrection[particleTypeIndex];
|
||||
@@ -440,21 +438,21 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
|
||||
G4int z = 10;
|
||||
|
||||
G4double numerator;
|
||||
numerator = std::pow(z * aj[excitationLevel], omegaj[excitationLevel]) *
|
||||
std::pow(tCorrected - Eliq[excitationLevel], nu);
|
||||
numerator = gpow->powA(z * aj[excitationLevel], omegaj[excitationLevel]) *
|
||||
gpow->powA(tCorrected - Eliq[excitationLevel], nu);
|
||||
|
||||
// H case : see S. Uehara et al. IJRB 77, 2, 139-154 (2001) - section 3.3
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
numerator = std::pow(z * 0.75*aj[excitationLevel], omegaj[excitationLevel]) *
|
||||
std::pow(tCorrected - Eliq[excitationLevel], nu);
|
||||
if (particleDefinition == hydrogenDef)
|
||||
numerator = gpow->powA(z * 0.75*aj[excitationLevel], omegaj[excitationLevel]) *
|
||||
gpow->powA(tCorrected - Eliq[excitationLevel], nu);
|
||||
|
||||
|
||||
G4double power;
|
||||
power = omegaj[excitationLevel] + nu;
|
||||
|
||||
G4double denominator;
|
||||
denominator = std::pow(jj[excitationLevel], power) + std::pow(tCorrected, power);
|
||||
denominator = gpow->powA(jj[excitationLevel], power) + gpow->powA(tCorrected, power);
|
||||
|
||||
G4double zEff = particleDefinition->GetPDGCharge() / eplus + particleDefinition->GetLeptonNumber();
|
||||
|
||||
@@ -462,7 +460,7 @@ G4double G4DNAMillerGreenExcitationModel::PartialCrossSection(G4double k, G4int
|
||||
sCoefficient[1][particleTypeIndex] * S_2s(k, Eliq[excitationLevel], slaterEffectiveCharge[1][particleTypeIndex], 2.) +
|
||||
sCoefficient[2][particleTypeIndex] * S_2p(k, Eliq[excitationLevel], slaterEffectiveCharge[2][particleTypeIndex], 2.) );
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen")) zEff = 1.;
|
||||
if (particleDefinition == hydrogenDef) zEff = 1.;
|
||||
|
||||
G4double cross = sigma0 * zEff * zEff * numerator / denominator;
|
||||
|
||||
@@ -478,14 +476,11 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
|
||||
G4double value = 0.;
|
||||
std::deque<G4double> values;
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if ( particle == instance->GetIon("alpha++") ||
|
||||
particle == G4Proton::ProtonDefinition()||
|
||||
particle == instance->GetIon("hydrogen") ||
|
||||
particle == instance->GetIon("alpha+") ||
|
||||
particle == instance->GetIon("helium")
|
||||
if ( particle == alphaPlusPlusDef ||
|
||||
particle == protonDef||
|
||||
particle == hydrogenDef ||
|
||||
particle == alphaPlusDef ||
|
||||
particle == heliumDef
|
||||
)
|
||||
{
|
||||
while (i > 0)
|
||||
@@ -511,9 +506,9 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
|
||||
/*
|
||||
// add ONE or TWO electron-water excitation for alpha+ and helium
|
||||
|
||||
if ( particle == instance->GetIon("alpha+")
|
||||
if ( particle == alphaPlusDef
|
||||
||
|
||||
particle == instance->GetIon("helium")
|
||||
particle == heliumDef
|
||||
)
|
||||
{
|
||||
while (i>0)
|
||||
@@ -529,8 +524,8 @@ G4int G4DNAMillerGreenExcitationModel::RandomSelect(G4double k,const G4ParticleD
|
||||
|
||||
G4double partial = PartialCrossSection(k,i,particle);
|
||||
|
||||
if (particle == instance->GetIon("alpha+")) partial = PartialCrossSection(k,i,particle) + sigmaExcitation;
|
||||
if (particle == instance->GetIon("helium")) partial = PartialCrossSection(k,i,particle) + 2*sigmaExcitation;
|
||||
if (particle == alphaPlusDef) partial = PartialCrossSection(k,i,particle) + sigmaExcitation;
|
||||
if (particle == heliumDef) partial = PartialCrossSection(k,i,particle) + 2*sigmaExcitation;
|
||||
|
||||
values.push_front(partial);
|
||||
value += partial;
|
||||
|
||||
@@ -203,7 +203,7 @@ void G4DNAPTBElasticModel::ReadDiffCSFile(const G4String& materialName,
|
||||
// This method is not yet standard.
|
||||
|
||||
// get the path of the G4LEDATA data folder
|
||||
char *path = std::getenv("G4LEDATA");
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
// if it is not found then quit and print error message
|
||||
if(!path)
|
||||
{
|
||||
|
||||
@@ -437,7 +437,7 @@ void G4DNAPTBIonisationModel::ReadDiffCSFile(const G4String& materialName,
|
||||
// To read and save the informations contained within the differential cross section files
|
||||
|
||||
// get the path of the G4LEDATA data folder
|
||||
char *path = std::getenv("G4LEDATA");
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
// if it is not found then quit and print error message
|
||||
if(!path)
|
||||
{
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
|
||||
#include "G4DNAPartiallyDiffusionControlled.hh"
|
||||
#include "G4IRTUtils.hh"
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
#include "G4VDNAReactionModel.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4MolecularConfiguration.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4ITReactionChange.hh"
|
||||
#include "G4VReactionType.hh"
|
||||
#include "G4Electron_aq.hh"
|
||||
#include "G4ErrorFunction.hh"
|
||||
G4DNAPartiallyDiffusionControlled::G4DNAPartiallyDiffusionControlled()
|
||||
: G4VReactionType()
|
||||
{}
|
||||
|
||||
G4DNAPartiallyDiffusionControlled::~G4DNAPartiallyDiffusionControlled() = default;
|
||||
|
||||
G4bool
|
||||
G4DNAPartiallyDiffusionControlled::GeminateRecombinationProbability(const G4MolecularConfiguration* mA,
|
||||
const G4MolecularConfiguration* mB)
|
||||
{
|
||||
auto reactionData = G4DNAMolecularReactionTable::Instance()
|
||||
->GetReactionData(mA, mB);
|
||||
|
||||
G4double D = GetDiffusionCoefficient(mA, mB);
|
||||
G4double R = mA->GetVanDerVaalsRadius() + mB->GetVanDerVaalsRadius();
|
||||
|
||||
const G4double Rs = 0.3 * nm;
|
||||
G4double kobs = reactionData->GetObservedReactionRateConstant() / Avogadro;
|
||||
if(mA->GetCharge() * mB->GetCharge() == 0)
|
||||
{
|
||||
G4double kdif = 4 * CLHEP::pi * D * R * Avogadro;
|
||||
G4double kact = G4IRTUtils::GetKact(kobs, kdif);
|
||||
return G4UniformRand() < Rs / ( Rs + ( kdif / kact ) * ( R + Rs ));
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double rc = 0.71 * nm * mA->GetCharge() *
|
||||
mB->GetCharge();
|
||||
G4double sigmaEff = G4IRTUtils::EffectiveDistance(rc, R);
|
||||
G4double kdif = 4 * CLHEP::pi * D * sigmaEff;
|
||||
G4double kact = G4IRTUtils::GetKact(kobs, kdif);
|
||||
G4double a = std::exp( -rc / R );
|
||||
G4double b = std::exp( -rc / ( R + Rs ) );
|
||||
G4double Preact = ( a - b ) / ( a - b - ( kdif / kact ) * ( 1 - a ) );
|
||||
|
||||
return G4UniformRand() < Preact;
|
||||
}
|
||||
}
|
||||
|
||||
G4double
|
||||
G4DNAPartiallyDiffusionControlled::GetDiffusionCoefficient(const G4MolecularConfiguration* mA,
|
||||
const G4MolecularConfiguration* mB)
|
||||
{
|
||||
G4double D;
|
||||
|
||||
if(mA == mB)
|
||||
{
|
||||
D = (mA->GetDiffusionCoefficient());
|
||||
}
|
||||
else
|
||||
{
|
||||
D = (mA->GetDiffusionCoefficient() +
|
||||
mB->GetDiffusionCoefficient());
|
||||
}
|
||||
return D;
|
||||
}
|
||||
|
||||
G4double G4DNAPartiallyDiffusionControlled::GetTimeToEncounter(const G4Track& trackA,
|
||||
const G4Track& trackB)
|
||||
{
|
||||
auto pMolConfA = GetMolecule(trackA)->GetMolecularConfiguration();
|
||||
auto pMolConfB = GetMolecule(trackB)->GetMolecularConfiguration();
|
||||
|
||||
G4double D = GetDiffusionCoefficient(pMolConfA, pMolConfB);
|
||||
auto reactionData = G4DNAMolecularReactionTable::Instance()
|
||||
->GetReactionData(pMolConfA, pMolConfB);
|
||||
G4double Reff;
|
||||
G4double kobs = reactionData->GetObservedReactionRateConstant();
|
||||
G4double distance = (trackA.GetPosition() - trackB.GetPosition()).mag();
|
||||
G4double SmoluchowskiRadius;
|
||||
G4double RVal = pMolConfA->GetVanDerVaalsRadius() + pMolConfB->GetVanDerVaalsRadius();
|
||||
|
||||
if((pMolConfA->GetCharge() != 0) &&
|
||||
(pMolConfB->GetCharge() != 0))
|
||||
{
|
||||
G4double rc = 0.71 * nm * pMolConfA->GetCharge() *
|
||||
pMolConfB->GetCharge();
|
||||
distance = G4IRTUtils::EffectiveDistance( rc, distance );
|
||||
Reff = G4IRTUtils::EffectiveDistance( rc, RVal );
|
||||
SmoluchowskiRadius = Reff;
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoluchowskiRadius = RVal;
|
||||
}
|
||||
|
||||
G4double Winf = SmoluchowskiRadius / distance;
|
||||
G4double U1 = G4UniformRand();
|
||||
G4double U2 = G4UniformRand();
|
||||
G4double U = G4UniformRand();
|
||||
G4double X = 0;
|
||||
G4double irt_1 = -1.0 * ps;
|
||||
G4double irt_2;
|
||||
|
||||
G4double kdif = 4 * CLHEP::pi * D * SmoluchowskiRadius * Avogadro;
|
||||
G4double kact = G4IRTUtils::GetKact(kobs, kdif);
|
||||
|
||||
if ( U < Winf )
|
||||
{
|
||||
G4double d = ( distance - SmoluchowskiRadius ) /
|
||||
G4ErrorFunction::erfcInv( U / Winf );
|
||||
irt_1 = ( 1.0 / ( 4 * D ) ) * d * d;
|
||||
}
|
||||
|
||||
if( irt_1 < 0)
|
||||
{
|
||||
return irt_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double rateFactor = kact / ( kact + kdif );
|
||||
if( U1 > rateFactor )
|
||||
{
|
||||
return -1.0 * ps;
|
||||
}
|
||||
G4double Y = std::abs(G4RandGauss::shoot(0.0,std::sqrt(2)));
|
||||
|
||||
if( Y > 0)
|
||||
{
|
||||
X = - ( G4Log( U2 ) ) / Y;
|
||||
}
|
||||
|
||||
G4double f = X * SmoluchowskiRadius * kdif / ( kact + kdif );
|
||||
irt_2 = ( f * f ) / D ;
|
||||
}
|
||||
|
||||
return irt_1 + irt_2;
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ G4int G4DNAQuinnPlasmonExcitationModel::GetNValenceElectron(G4int z)
|
||||
|
||||
if(!datadir)
|
||||
{
|
||||
datadir = getenv("G4LEDATA");
|
||||
datadir = G4FindDataDir("G4LEDATA");
|
||||
if(!datadir)
|
||||
{
|
||||
G4Exception("G4DNAQuinnPlasmonExcitationModel::GetNValenceElectron()"
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Created on 2022/03/03
|
||||
//
|
||||
// Authors: A.D. Dominguez-Munoz, M.I. Gallardo, M.C. Bordage,
|
||||
// Z. Francis, S. Incerti, M.A. Cortes-Giraldo
|
||||
//
|
||||
// Contact: M.A. Cortes-Giraldo (miancortes -at- us.es)
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4DNARPWBAExcitationModel.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNARPWBAExcitationModel::G4DNARPWBAExcitationModel(
|
||||
const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VEmModel(nam)
|
||||
{
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
if(verboseLevel > 0)
|
||||
{
|
||||
G4cout << "RPWBA excitation model is constructed " << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNARPWBAExcitationModel::~G4DNARPWBAExcitationModel() = default;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNARPWBAExcitationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
if(isInitialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Calling G4DNARPWBAExcitationModel::Initialise()" << G4endl;
|
||||
}
|
||||
|
||||
if(fParticleDefinition != nullptr && fParticleDefinition != particle)
|
||||
{
|
||||
G4Exception("G4DNARPWBAExcitationModel::Initialise", "em0001",
|
||||
FatalException,
|
||||
"Model already initialized for another particle type.");
|
||||
}
|
||||
|
||||
fTableFile = "dna/sigma_excitation_p_RPWBA";
|
||||
fLowEnergy = 100. * MeV;
|
||||
fHighEnergy = 300. * MeV;
|
||||
|
||||
//SetLowEnergyLimit(fLowEnergy);
|
||||
//SetHighEnergyLimit(fHighEnergy);
|
||||
|
||||
G4double scaleFactor = 1 * cm * cm;
|
||||
fTableData = make_unique<G4DNACrossSectionDataSet>(new G4LogLogInterpolation,
|
||||
eV, scaleFactor);
|
||||
fTableData->LoadData(fTableFile);
|
||||
|
||||
if(verboseLevel > 0)
|
||||
{
|
||||
G4cout << "RPWBA excitation model is initialized " << G4endl
|
||||
<< "Energy range: " << LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / keV << " keV for "
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
// Initialize water density pointer
|
||||
if(G4Material::GetMaterial("G4_WATER") != nullptr){
|
||||
fpMolWaterDensity =
|
||||
G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(
|
||||
G4Material::GetMaterial("G4_WATER"));
|
||||
}else{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "G4_WATER does not exist :";
|
||||
G4Exception("G4DNARPWBAIonisationModel::Initialise", "em00020",
|
||||
FatalException, exceptionDescription);
|
||||
}
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNARPWBAExcitationModel::CrossSectionPerVolume(
|
||||
const G4Material* material, const G4ParticleDefinition* particleDefinition,
|
||||
G4double ekin, G4double, G4double)
|
||||
{
|
||||
if(verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNARPWBAExcitationModel"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(fTableData == nullptr)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No cross section data ";
|
||||
G4Exception("G4DNARPWBAIonisationModel::CrossSectionPerVolume", "em00120",
|
||||
FatalException, exceptionDescription);
|
||||
}
|
||||
|
||||
if(particleDefinition != fParticleDefinition)
|
||||
return 0;
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4double sigma = 0;
|
||||
|
||||
G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
|
||||
|
||||
if(ekin >= fLowEnergy && ekin <= fHighEnergy)
|
||||
{
|
||||
sigma = fTableData->FindValue(ekin);
|
||||
}
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "G4DNARPWBAExcitationModel - XS INFO START" << G4endl;
|
||||
G4cout << "Kinetic energy(eV)=" << ekin / eV
|
||||
<< " particle : " << particleDefinition->GetParticleName() << G4endl;
|
||||
G4cout << "Cross section per water molecule (cm^2)=" << sigma / cm / cm
|
||||
<< G4endl;
|
||||
G4cout << "Cross section per water molecule (cm^-1)="
|
||||
<< sigma * waterDensity / (1. / cm) << G4endl;
|
||||
G4cout << "G4DNARPWBAExcitationModel - XS INFO END" << G4endl;
|
||||
}
|
||||
|
||||
return sigma * waterDensity;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNARPWBAExcitationModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* /*fvect*/,
|
||||
const G4MaterialCutsCouple* /*couple*/,
|
||||
const G4DynamicParticle* aDynamicParticle, G4double, G4double)
|
||||
{
|
||||
if(verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Calling SampleSecondaries() of G4DNARPWBAExcitationModel"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4double k = aDynamicParticle->GetKineticEnergy();
|
||||
|
||||
G4int level = RandomSelect(k);
|
||||
G4double excitationEnergy = waterStructure.ExcitationEnergy(level);
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
|
||||
if(newEnergy > 0)
|
||||
{
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(
|
||||
aDynamicParticle->GetMomentumDirection());
|
||||
|
||||
if(!statCode){
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
}
|
||||
else{
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(k);
|
||||
}
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
}
|
||||
|
||||
const G4Track* theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
|
||||
G4DNAChemistryManager::Instance()->CreateWaterMolecule(
|
||||
eExcitedMolecule, level, theIncomingTrack);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARPWBAExcitationModel::GetPartialCrossSection(
|
||||
const G4Material*, G4int level, const G4ParticleDefinition* particle,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
if(fParticleDefinition != particle)
|
||||
{
|
||||
G4Exception("G4DNARPWBAExcitationModel::GetPartialCrossSection",
|
||||
"RPWBAParticleType", FatalException,
|
||||
"Model initialized for another particle type.");
|
||||
}
|
||||
|
||||
return fTableData->GetComponent(level)->FindValue(kineticEnergy);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int G4DNARPWBAExcitationModel::RandomSelect(G4double k)
|
||||
{
|
||||
G4int level = 0;
|
||||
|
||||
G4double* valuesBuffer = new G4double[fTableData->NumberOfComponents()];
|
||||
const size_t n(fTableData->NumberOfComponents());
|
||||
size_t i(n);
|
||||
G4double value = 0.;
|
||||
|
||||
while(i > 0)
|
||||
{
|
||||
i--;
|
||||
valuesBuffer[i] = fTableData->GetComponent(i)->FindValue(k);
|
||||
value += valuesBuffer[i];
|
||||
}
|
||||
|
||||
value *= G4UniformRand();
|
||||
i = n;
|
||||
|
||||
while(i > 0)
|
||||
{
|
||||
i--;
|
||||
|
||||
if(valuesBuffer[i] > value)
|
||||
{
|
||||
delete[] valuesBuffer;
|
||||
return i;
|
||||
}
|
||||
value -= valuesBuffer[i];
|
||||
}
|
||||
delete[] valuesBuffer;
|
||||
|
||||
return level;
|
||||
}
|
||||
@@ -0,0 +1,724 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Created on 2022/03/03
|
||||
//
|
||||
// Authors: A.D. Dominguez-Munoz, M.I. Gallardo, M.C. Bordage,
|
||||
// Z. Francis, S. Incerti, M.A. Cortes-Giraldo
|
||||
//
|
||||
// Contact: M.A. Cortes-Giraldo (miancortes -at- us.es)
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4DNARPWBAIonisationModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UAtomicDeexcitation.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4DNABornAngle.hh"
|
||||
#include "G4Exp.hh"
|
||||
using namespace std;
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
G4DNARPWBAIonisationModel::G4DNARPWBAIonisationModel(
|
||||
const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VEmModel(nam)
|
||||
{
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if(verboseLevel > 0)
|
||||
{
|
||||
G4cout << "RPWBA ionisation model is constructed " << G4endl;
|
||||
}
|
||||
SetDeexcitationFlag(true);
|
||||
SetAngularDistribution(new G4DNABornAngle());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNARPWBAIonisationModel::~G4DNARPWBAIonisationModel()
|
||||
{
|
||||
eVecm.clear();
|
||||
pVecm.clear();
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4DNARPWBAIonisationModel::InEnergyLimit(const G4double& k)
|
||||
{
|
||||
if(lowEnergyLimit == highEnergyLimit)
|
||||
{
|
||||
G4Exception("G4DNARPWBAIonisationModel::InEnergyLimit", "em0102",
|
||||
FatalException, "lowEnergyLimit == highEnergyLimit");
|
||||
}
|
||||
if(k >= lowEnergyLimit && k <= highEnergyLimit)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
void G4DNARPWBAIonisationModel::InitialiseForProton(
|
||||
const G4ParticleDefinition* part)
|
||||
{
|
||||
if(part != fProtonDef)
|
||||
{
|
||||
G4Exception("G4DNARPWBAIonisationModel::CrossSectionPerVolume", "em0002",
|
||||
FatalException, "Model not applicable to particle type.");
|
||||
}
|
||||
// Energy limits
|
||||
G4String fileProton("dna/sigma_ionisation_p_RPWBA");
|
||||
G4double scaleFactor = 1 * cm * cm;
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
lowEnergyLimit = 100. * MeV;
|
||||
highEnergyLimit = 300. * MeV;
|
||||
fpTotalCrossSection = make_unique<G4DNACrossSectionDataSet>(
|
||||
new G4LogLogInterpolation, eV, scaleFactor);
|
||||
fpTotalCrossSection->LoadData(fileProton);
|
||||
|
||||
// Final state
|
||||
|
||||
std::ostringstream pFullFileName;
|
||||
fasterCode ? pFullFileName
|
||||
<< path << "/dna/sigmadiff_cumulated_ionisation_p_RPWBA.dat.dat"
|
||||
: pFullFileName << path << "/dna/sigmadiff_ionisation_p_RPWBA.dat";
|
||||
std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
|
||||
if(!pDiffCrossSection)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "Missing data file: " + pFullFileName.str();
|
||||
G4Exception("G4DNARPWBAIonisationModel::Initialise", "em0003",
|
||||
FatalException, exceptionDescription);
|
||||
}
|
||||
|
||||
pTdummyVec.push_back(0.);
|
||||
while(!pDiffCrossSection.eof())
|
||||
{
|
||||
G4double tDummy;
|
||||
G4double eDummy;
|
||||
pDiffCrossSection >> tDummy >> eDummy;
|
||||
if(tDummy != pTdummyVec.back())
|
||||
{
|
||||
pTdummyVec.push_back(tDummy);
|
||||
}
|
||||
|
||||
for(G4int j = 0; j < 5; j++)
|
||||
{
|
||||
pDiffCrossSection >> pDiffCrossSectionData[j][tDummy][eDummy];
|
||||
|
||||
if(fasterCode)
|
||||
{
|
||||
pNrjTransfData[j][tDummy][pDiffCrossSectionData[j][tDummy][eDummy]] =
|
||||
eDummy;
|
||||
pProbaShellMap[j][tDummy].push_back(
|
||||
pDiffCrossSectionData[j][tDummy][eDummy]);
|
||||
}
|
||||
|
||||
// SI - only if eof is not reached !
|
||||
if(!pDiffCrossSection.eof() && !fasterCode)
|
||||
{
|
||||
pDiffCrossSectionData[j][tDummy][eDummy] *= scaleFactor;
|
||||
}
|
||||
|
||||
if(!fasterCode)
|
||||
{
|
||||
pVecm[tDummy].push_back(eDummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// be careful about this
|
||||
// SetLowEnergyLimit(lowEnergyLimit);
|
||||
// SetHighEnergyLimit(highEnergyLimit);
|
||||
}
|
||||
|
||||
void G4DNARPWBAIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
if(isInitialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Calling G4DNARPWBAIonisationModel::Initialise()"
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
InitialiseForProton(particle);
|
||||
|
||||
if(verboseLevel > 0)
|
||||
{
|
||||
G4cout << "RPWBA ionisation model is initialized " << G4endl
|
||||
<< "Energy range: " << LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / keV << " keV for "
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
// Initialize water density pointer
|
||||
if(G4Material::GetMaterial("G4_WATER") != nullptr)
|
||||
{
|
||||
fpMolWaterDensity =
|
||||
G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(
|
||||
G4Material::GetMaterial("G4_WATER"));
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "G4_WATER does not exist :";
|
||||
G4Exception("G4DNARPWBAIonisationModel::Initialise", "em00020",
|
||||
FatalException, exceptionDescription);
|
||||
}
|
||||
fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNARPWBAIonisationModel::CrossSectionPerVolume(
|
||||
const G4Material* material, const G4ParticleDefinition* particleDefinition,
|
||||
G4double ekin, G4double, G4double)
|
||||
{
|
||||
if(particleDefinition != fProtonDef)
|
||||
{
|
||||
G4Exception("G4DNARPWBAIonisationModel::CrossSectionPerVolume", "em0402",
|
||||
FatalException, "Model not applicable to particle type.");
|
||||
}
|
||||
if(verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNARPWBAIonisationModel"
|
||||
<< G4endl;
|
||||
}
|
||||
G4double sigma;
|
||||
G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
|
||||
|
||||
if(InEnergyLimit(ekin))
|
||||
{
|
||||
sigma = fpTotalCrossSection->FindValue(ekin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// nput energy is outside this interval the cross section is set to zero
|
||||
// should add a warning or exception ?
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "G4DNARPWBAIonisationModel - XS INFO START" << G4endl;
|
||||
G4cout << "Kinetic energy(eV)=" << ekin / eV
|
||||
<< " particle : " << fProtonDef->GetParticleName() << G4endl;
|
||||
G4cout << "Cross section per water molecule (cm^2)=" << sigma / cm / cm
|
||||
<< G4endl;
|
||||
G4cout << "Cross section per water molecule (cm^-1)="
|
||||
<< sigma * waterDensity / (1. / cm) << G4endl;
|
||||
G4cout << "G4DNARPWBAIonisationModel - XS INFO END" << G4endl;
|
||||
}
|
||||
|
||||
return sigma * waterDensity;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNARPWBAIonisationModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* fvect, const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* particle, G4double, G4double)
|
||||
{
|
||||
if(verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Calling SampleSecondaries() of G4DNARPWBAIonisationModel"
|
||||
<< G4endl;
|
||||
}
|
||||
G4double k = particle->GetKineticEnergy();
|
||||
if(InEnergyLimit(k))
|
||||
{
|
||||
G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
|
||||
G4double particleMass = particle->GetDefinition()->GetPDGMass();
|
||||
G4double totalEnergy = k + particleMass;
|
||||
G4double pSquare = k * (totalEnergy + particleMass);
|
||||
G4double totalMomentum = std::sqrt(pSquare);
|
||||
G4int ionizationShell;
|
||||
|
||||
if(!fasterCode)
|
||||
{
|
||||
ionizationShell = RandomSelect(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
// fasterCode = true
|
||||
do
|
||||
{
|
||||
ionizationShell = RandomSelect(k);
|
||||
} while(k < 19 * eV && ionizationShell == 2 &&
|
||||
particle->GetDefinition() == G4Electron::ElectronDefinition());
|
||||
}
|
||||
|
||||
G4double bindingEnergy = 0;
|
||||
bindingEnergy = waterStructure.IonisationEnergy(ionizationShell);
|
||||
|
||||
// SI: additional protection if tcs interpolation method is modified
|
||||
if(k < bindingEnergy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//
|
||||
G4double secondaryKinetic;
|
||||
if(!fasterCode)
|
||||
{
|
||||
secondaryKinetic = RandomizeEjectedElectronEnergy(k, ionizationShell);
|
||||
}
|
||||
else
|
||||
{
|
||||
secondaryKinetic =
|
||||
RandomizeEjectedElectronEnergyFromCumulatedDcs(k, ionizationShell);
|
||||
}
|
||||
|
||||
G4int Z = 8; // water Z (6 Oxygen + 2 hydrogen)
|
||||
G4ThreeVector deltaDirection =
|
||||
GetAngularDistribution()->SampleDirectionForShell(
|
||||
particle, secondaryKinetic, Z, ionizationShell, couple->GetMaterial());
|
||||
|
||||
if(secondaryKinetic > 0){
|
||||
auto dp = new G4DynamicParticle(G4Electron::Electron(), deltaDirection,
|
||||
secondaryKinetic);
|
||||
fvect->push_back(dp);
|
||||
}
|
||||
|
||||
if(particle->GetDefinition() == G4Electron::ElectronDefinition()){
|
||||
G4double deltaTotalMomentum = std::sqrt(
|
||||
secondaryKinetic * (secondaryKinetic + 2. * electron_mass_c2));
|
||||
|
||||
G4double finalPx = totalMomentum * primaryDirection.x() -
|
||||
deltaTotalMomentum * deltaDirection.x();
|
||||
G4double finalPy = totalMomentum * primaryDirection.y() -
|
||||
deltaTotalMomentum * deltaDirection.y();
|
||||
G4double finalPz = totalMomentum * primaryDirection.z() -
|
||||
deltaTotalMomentum * deltaDirection.z();
|
||||
G4double finalMomentum =
|
||||
std::sqrt(finalPx * finalPx + finalPy * finalPy + finalPz * finalPz);
|
||||
finalPx /= finalMomentum;
|
||||
finalPy /= finalMomentum;
|
||||
finalPz /= finalMomentum;
|
||||
G4ThreeVector direction;
|
||||
direction.set(finalPx, finalPy, finalPz);
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(direction.unit());
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection);
|
||||
}
|
||||
|
||||
// AM: sample deexcitation
|
||||
// here we assume that H_{2}O electronic levels are the same as Oxygen.
|
||||
// this can be considered true with a rough 10% error in energy on K-shell,
|
||||
|
||||
size_t secNumberInit; // need to know at a certain point the energy of
|
||||
// secondaries
|
||||
size_t
|
||||
secNumberFinal; // So I'll make the diference and then sum the energies
|
||||
|
||||
G4double scatteredEnergy = k - bindingEnergy - secondaryKinetic;
|
||||
|
||||
// SI: only atomic deexcitation from K shell is considered
|
||||
if((fAtomDeexcitation != nullptr) && ionizationShell == 4)
|
||||
{
|
||||
const G4AtomicShell* shell =
|
||||
fAtomDeexcitation->GetAtomicShell(Z, G4AtomicShellEnumerator(0));
|
||||
secNumberInit = fvect->size();
|
||||
fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
|
||||
secNumberFinal = fvect->size();
|
||||
|
||||
if(secNumberFinal > secNumberInit){
|
||||
for(size_t i = secNumberInit; i < secNumberFinal; ++i){
|
||||
if(bindingEnergy >= ((*fvect)[i])->GetKineticEnergy())
|
||||
{
|
||||
bindingEnergy -= ((*fvect)[i])->GetKineticEnergy();
|
||||
}else{
|
||||
delete(*fvect)[i];
|
||||
(*fvect)[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This should never happen
|
||||
if(bindingEnergy < 0.0)
|
||||
{
|
||||
G4Exception("G4DNARPWBAIonisatioModel::SampleSecondaries()", "em2050",
|
||||
FatalException, "Negative local energy deposit");
|
||||
}
|
||||
|
||||
// bindingEnergy has been decreased
|
||||
// by the amount of energy taken away by deexc. products
|
||||
if(!statCode){
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(scatteredEnergy);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(bindingEnergy);
|
||||
}else{
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(k);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(k - scatteredEnergy);
|
||||
}
|
||||
const G4Track* theIncomingTrack =
|
||||
fParticleChangeForGamma->GetCurrentTrack();
|
||||
G4DNAChemistryManager::Instance()->CreateWaterMolecule(
|
||||
eIonizedMolecule, ionizationShell, theIncomingTrack);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARPWBAIonisationModel::RandomizeEjectedElectronEnergy(
|
||||
const G4double& k, const G4int& shell)
|
||||
{
|
||||
G4double maximumKineticEnergyTransfer =
|
||||
4. * (electron_mass_c2 / proton_mass_c2) * k;
|
||||
|
||||
G4double crossSectionMaximum = 0.;
|
||||
for(G4double value = waterStructure.IonisationEnergy(shell);
|
||||
value <= 4. * waterStructure.IonisationEnergy(shell); value += 0.1 * eV)
|
||||
{
|
||||
G4double differentialCrossSection =
|
||||
DifferentialCrossSection(k / eV, value / eV, shell);
|
||||
if(differentialCrossSection >= crossSectionMaximum)
|
||||
{
|
||||
crossSectionMaximum = differentialCrossSection;
|
||||
}
|
||||
}
|
||||
|
||||
G4double secondaryElectronKineticEnergy = 0.;
|
||||
do
|
||||
{
|
||||
secondaryElectronKineticEnergy =
|
||||
G4UniformRand() * maximumKineticEnergyTransfer;
|
||||
} while(G4UniformRand() * crossSectionMaximum >=
|
||||
DifferentialCrossSection(k / eV,
|
||||
(secondaryElectronKineticEnergy +
|
||||
waterStructure.IonisationEnergy(shell)) /
|
||||
eV,
|
||||
shell));
|
||||
|
||||
return secondaryElectronKineticEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4double G4DNARPWBAIonisationModel::DifferentialCrossSection(
|
||||
const G4double& kine, const G4double& energyTransfer,
|
||||
const G4int& ionizationLevelIndex)
|
||||
{
|
||||
G4double k = kine;
|
||||
G4double sigma = 0.;
|
||||
if(energyTransfer >=
|
||||
waterStructure.IonisationEnergy(ionizationLevelIndex) / eV)
|
||||
{
|
||||
G4double valueT1 = 0;
|
||||
G4double valueT2 = 0;
|
||||
G4double valueE21 = 0;
|
||||
G4double valueE22 = 0;
|
||||
G4double valueE12 = 0;
|
||||
G4double valueE11 = 0;
|
||||
|
||||
G4double xs11 = 0;
|
||||
G4double xs12 = 0;
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
|
||||
// Protection against out of boundary access - proton case : 100 MeV
|
||||
|
||||
if(k == pTdummyVec.back())
|
||||
{
|
||||
k = k * (1. - 1e-12);
|
||||
}
|
||||
// k should be in eV and energy transfer eV also
|
||||
auto t2 = std::upper_bound(pTdummyVec.begin(), pTdummyVec.end(), k);
|
||||
auto t1 = t2 - 1;
|
||||
|
||||
auto e12 = std::upper_bound(pVecm[(*t1)].begin(), pVecm[(*t1)].end(),
|
||||
energyTransfer);
|
||||
auto e11 = e12 - 1;
|
||||
|
||||
auto e22 = std::upper_bound(pVecm[(*t2)].begin(), pVecm[(*t2)].end(),
|
||||
energyTransfer);
|
||||
auto e21 = e22 - 1;
|
||||
|
||||
valueT1 = *t1;
|
||||
valueT2 = *t2;
|
||||
valueE21 = *e21;
|
||||
valueE22 = *e22;
|
||||
valueE12 = *e12;
|
||||
valueE11 = *e11;
|
||||
|
||||
xs11 = pDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE11];
|
||||
xs12 = pDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE12];
|
||||
xs21 = pDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE21];
|
||||
xs22 = pDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE22];
|
||||
|
||||
G4double xsProduct = xs11 * xs12 * xs21 * xs22;
|
||||
if(xsProduct != 0.)
|
||||
{
|
||||
sigma =
|
||||
QuadInterpolator(valueE11, valueE12, valueE21, valueE22, xs11, xs12,
|
||||
xs21, xs22, valueT1, valueT2, k, energyTransfer);
|
||||
}
|
||||
}
|
||||
return sigma;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARPWBAIonisationModel::Interpolate(const G4double& e1,
|
||||
const G4double& e2,
|
||||
const G4double& e,
|
||||
const G4double& xs1,
|
||||
const G4double& xs2)
|
||||
{
|
||||
G4double value = 0.;
|
||||
|
||||
// Log-log interpolation by default
|
||||
|
||||
if(e1 != 0 && e2 != 0 && (std::log10(e2) - std::log10(e1)) != 0 &&
|
||||
!fasterCode)
|
||||
{
|
||||
G4double a =
|
||||
(std::log10(xs2) - std::log10(xs1)) / (std::log10(e2) - std::log10(e1));
|
||||
G4double b = std::log10(xs2) - a * std::log10(e2);
|
||||
G4double sigma = a * std::log10(e) + b;
|
||||
value = (std::pow(10., sigma));
|
||||
}
|
||||
// Switch to lin-lin interpolation
|
||||
/*
|
||||
if ((e2-e1)!=0)
|
||||
{
|
||||
G4double d1 = xs1;
|
||||
G4double d2 = xs2;
|
||||
value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
|
||||
}
|
||||
*/
|
||||
|
||||
// Switch to log-lin interpolation for faster code
|
||||
if((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 && fasterCode)
|
||||
{
|
||||
G4double d1 = std::log10(xs1);
|
||||
G4double d2 = std::log10(xs2);
|
||||
value = std::pow(10., (d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
|
||||
}
|
||||
|
||||
// Switch to lin-lin interpolation for faster code
|
||||
// in case one of xs1 or xs2 (=cum proba) value is zero
|
||||
|
||||
if((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) && fasterCode)
|
||||
{
|
||||
G4double d1 = xs1;
|
||||
G4double d2 = xs2;
|
||||
value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARPWBAIonisationModel::QuadInterpolator(
|
||||
const G4double& e11, const G4double& e12, const G4double& e21,
|
||||
const G4double& e22, const G4double& xs11, const G4double& xs12,
|
||||
const G4double& xs21, const G4double& xs22, const G4double& t1,
|
||||
const G4double& t2, const G4double& t, const G4double& e)
|
||||
{
|
||||
G4double interpolatedvalue1 = Interpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = Interpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value =
|
||||
Interpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
G4double G4DNARPWBAIonisationModel::GetPartialCrossSection(
|
||||
const G4Material* /*material*/, G4int level,
|
||||
const G4ParticleDefinition* particle, G4double kineticEnergy)
|
||||
{
|
||||
if(fpTotalCrossSection != nullptr && particle != fProtonDef)
|
||||
{
|
||||
G4Exception("G4DNARPWBAIonisationModel::GetPartialCrossSection", "em0010",
|
||||
FatalException, "Model not applicable to particle type.");
|
||||
}
|
||||
return fpTotalCrossSection->GetComponent(level)->FindValue(kineticEnergy);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int G4DNARPWBAIonisationModel::RandomSelect(G4double k)
|
||||
{
|
||||
if(fpTotalCrossSection == nullptr)
|
||||
{
|
||||
G4Exception("G4DNARPWBAIonisationModel::RandomSelect", "em0010",
|
||||
FatalException, "Model not applicable to particle type.");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto valuesBuffer = new G4double[fpTotalCrossSection->NumberOfComponents()];
|
||||
const size_t n(fpTotalCrossSection->NumberOfComponents());
|
||||
size_t i(n);
|
||||
G4double value = 0.;
|
||||
while(i > 0)
|
||||
{
|
||||
i--;
|
||||
valuesBuffer[i] = fpTotalCrossSection->GetComponent(i)->FindValue(k);
|
||||
value += valuesBuffer[i];
|
||||
}
|
||||
value *= G4UniformRand();
|
||||
i = n;
|
||||
|
||||
while(i > 0)
|
||||
{
|
||||
i--;
|
||||
if(valuesBuffer[i] > value)
|
||||
{
|
||||
delete[] valuesBuffer;
|
||||
return i;
|
||||
}
|
||||
value -= valuesBuffer[i];
|
||||
}
|
||||
delete[] valuesBuffer;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double
|
||||
G4DNARPWBAIonisationModel::RandomizeEjectedElectronEnergyFromCumulatedDcs(
|
||||
const G4double& k, const G4int& shell)
|
||||
{
|
||||
G4double secondaryElectronKineticEnergy = 0.;
|
||||
G4double random = G4UniformRand();
|
||||
secondaryElectronKineticEnergy =
|
||||
TransferedEnergy(k / eV, shell, random) * eV -
|
||||
waterStructure.IonisationEnergy(shell);
|
||||
if(secondaryElectronKineticEnergy < 0.)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
return secondaryElectronKineticEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNARPWBAIonisationModel::TransferedEnergy(G4double k,
|
||||
G4int ionizationLevelIndex,
|
||||
const G4double& random)
|
||||
{
|
||||
G4double nrj = 0.;
|
||||
G4double valueK1 = 0;
|
||||
G4double valueK2 = 0;
|
||||
G4double valuePROB21 = 0;
|
||||
G4double valuePROB22 = 0;
|
||||
G4double valuePROB12 = 0;
|
||||
G4double valuePROB11 = 0;
|
||||
G4double nrjTransf11 = 0;
|
||||
G4double nrjTransf12 = 0;
|
||||
G4double nrjTransf21 = 0;
|
||||
G4double nrjTransf22 = 0;
|
||||
// Protection against out of boundary access - proton case : 100 MeV
|
||||
if(k == pTdummyVec.back())
|
||||
{
|
||||
k = k * (1. - 1e-12);
|
||||
}
|
||||
// k should be in eV
|
||||
|
||||
auto k2 = std::upper_bound(pTdummyVec.begin(), pTdummyVec.end(), k);
|
||||
auto k1 = k2 - 1;
|
||||
|
||||
// SI : the following condition avoids situations where random > last vector
|
||||
// element,
|
||||
// for eg. when the last element is zero
|
||||
if(random <= pProbaShellMap[ionizationLevelIndex][(*k1)].back() &&
|
||||
random <= pProbaShellMap[ionizationLevelIndex][(*k2)].back())
|
||||
{
|
||||
auto prob12 = std::upper_bound(
|
||||
pProbaShellMap[ionizationLevelIndex][(*k1)].begin(),
|
||||
pProbaShellMap[ionizationLevelIndex][(*k1)].end(), random);
|
||||
auto prob11 = prob12 - 1;
|
||||
auto prob22 = std::upper_bound(
|
||||
pProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
|
||||
pProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
|
||||
|
||||
auto prob21 = prob22 - 1;
|
||||
|
||||
valueK1 = *k1;
|
||||
valueK2 = *k2;
|
||||
valuePROB21 = *prob21;
|
||||
valuePROB22 = *prob22;
|
||||
valuePROB12 = *prob12;
|
||||
valuePROB11 = *prob11;
|
||||
|
||||
nrjTransf11 = pNrjTransfData[ionizationLevelIndex][valueK1][valuePROB11];
|
||||
nrjTransf12 = pNrjTransfData[ionizationLevelIndex][valueK1][valuePROB12];
|
||||
nrjTransf21 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
|
||||
nrjTransf22 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
|
||||
}
|
||||
|
||||
// Avoids cases where cum xs is zero for k1 and is not for k2 (with always
|
||||
// k1<k2)
|
||||
|
||||
if(random > pProbaShellMap[ionizationLevelIndex][(*k1)].back())
|
||||
{
|
||||
auto prob22 = std::upper_bound(
|
||||
pProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
|
||||
pProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
|
||||
auto prob21 = prob22 - 1;
|
||||
|
||||
valueK1 = *k1;
|
||||
valueK2 = *k2;
|
||||
valuePROB21 = *prob21;
|
||||
valuePROB22 = *prob22;
|
||||
nrjTransf21 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
|
||||
nrjTransf22 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
|
||||
|
||||
G4double interpolatedvalue2 =
|
||||
Interpolate(valuePROB21, valuePROB22, random, nrjTransf21, nrjTransf22);
|
||||
|
||||
G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
|
||||
return value;
|
||||
}
|
||||
G4double nrjTransfProduct =
|
||||
nrjTransf11 * nrjTransf12 * nrjTransf21 * nrjTransf22;
|
||||
|
||||
if(nrjTransfProduct != 0.)
|
||||
{
|
||||
nrj = QuadInterpolator(valuePROB11, valuePROB12, valuePROB21, valuePROB22,
|
||||
nrjTransf11, nrjTransf12, nrjTransf21, nrjTransf22,
|
||||
valueK1, valueK2, k, random);
|
||||
}
|
||||
return nrj;
|
||||
}
|
||||
@@ -116,7 +116,7 @@ void G4DNARelativisticIonisationModel::Initialise(const G4ParticleDefinition* pa
|
||||
|
||||
std::ostringstream eFullFileNameZ;
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4Exception("G4DNARelativisticIonisationModel::Initialise","em0006",
|
||||
@@ -404,7 +404,7 @@ void G4DNARelativisticIonisationModel::LoadAtomicStates(
|
||||
const char *datadir = path;
|
||||
if(!datadir)
|
||||
{
|
||||
datadir = getenv("G4LEDATA");
|
||||
datadir = G4FindDataDir("G4LEDATA");
|
||||
if(!datadir)
|
||||
{
|
||||
G4Exception("G4DNARelativisticIonisationModel::LoadAtomicStates()",
|
||||
|
||||
+110
-80
@@ -39,6 +39,12 @@
|
||||
#include "G4DNARuddAngle.hh"
|
||||
#include "G4DeltaAngle.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4Alpha.hh"
|
||||
|
||||
static G4Pow * gpow = G4Pow::GetInstance();
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -130,9 +136,9 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
G4String fileAlphaPlusPlus("dna/sigma_ionisation_alphaplusplus_rudd");
|
||||
G4String fileAlphaPlus("dna/sigma_ionisation_alphaplus_rudd");
|
||||
G4String fileHelium("dna/sigma_ionisation_he_rudd");
|
||||
G4String fileLithium("dna/sigma_ionisation_li_rudd");
|
||||
G4String fileBeryllium("dna/sigma_ionisation_be_rudd");
|
||||
G4String fileBoron("dna/sigma_ionisation_b_rudd");
|
||||
//G4String fileLithium("dna/sigma_ionisation_li_rudd");
|
||||
//G4String fileBeryllium("dna/sigma_ionisation_be_rudd");
|
||||
//G4String fileBoron("dna/sigma_ionisation_b_rudd");
|
||||
G4String fileCarbon("dna/sigma_ionisation_c_rudd");
|
||||
G4String fileNitrogen("dna/sigma_ionisation_n_rudd");
|
||||
G4String fileOxygen("dna/sigma_ionisation_o_rudd");
|
||||
@@ -141,35 +147,29 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
|
||||
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
|
||||
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
|
||||
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
|
||||
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
|
||||
protonDef = G4Proton::ProtonDefinition();
|
||||
hydrogenDef = instance->GetIon("hydrogen");
|
||||
alphaPlusPlusDef = G4Alpha::Alpha();
|
||||
alphaPlusDef = instance->GetIon("alpha+");
|
||||
heliumDef = instance->GetIon("helium");
|
||||
|
||||
//G4ParticleDefinition* carbonDef = instance->GetIon("carbon");
|
||||
//G4ParticleDefinition* nitrogenDef = instance->GetIon("nitrogen");
|
||||
//G4ParticleDefinition* oxygenDef = instance->GetIon("oxygen");
|
||||
//G4ParticleDefinition* siliconDef = instance->GetIon("silicon");
|
||||
//G4ParticleDefinition* ironDef = instance->GetIon("iron");
|
||||
G4ParticleDefinition* lithiumDef = G4IonTable::GetIonTable()->GetIon(3,7);
|
||||
G4ParticleDefinition* berylliumDef = G4IonTable::GetIonTable()->GetIon(4,9);
|
||||
G4ParticleDefinition* boronDef = G4IonTable::GetIonTable()->GetIon(5,11);
|
||||
G4ParticleDefinition* carbonDef = G4IonTable::GetIonTable()->GetIon(6,12);
|
||||
G4ParticleDefinition* nitrogenDef = G4IonTable::GetIonTable()->GetIon(7,14);
|
||||
G4ParticleDefinition* oxygenDef = G4IonTable::GetIonTable()->GetIon(8,16);
|
||||
G4ParticleDefinition* siliconDef = G4IonTable::GetIonTable()->GetIon(14,28);
|
||||
G4ParticleDefinition* ironDef = G4IonTable::GetIonTable()->GetIon(26,56);
|
||||
//
|
||||
carbonDef = instance->GetIon("carbon");
|
||||
nitrogenDef = instance->GetIon("nitrogen");
|
||||
oxygenDef = instance->GetIon("oxygen");
|
||||
siliconDef = instance->GetIon("silicon");
|
||||
ironDef = instance->GetIon("iron");
|
||||
//lithiumDef = G4IonTable::GetIonTable()->GetIon(3,7);
|
||||
//berylliumDef = G4IonTable::GetIonTable()->GetIon(4,9);
|
||||
//boronDef = G4IonTable::GetIonTable()->GetIon(5,11);
|
||||
|
||||
G4String proton;
|
||||
G4String hydrogen;
|
||||
G4String alphaPlusPlus;
|
||||
G4String alphaPlus;
|
||||
G4String helium;
|
||||
G4String lithium;
|
||||
G4String beryllium;
|
||||
G4String boron;
|
||||
//G4String lithium;
|
||||
//G4String beryllium;
|
||||
//G4String boron;
|
||||
G4String carbon;
|
||||
G4String nitrogen;
|
||||
G4String oxygen;
|
||||
@@ -262,7 +262,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
tableData[helium] = tableHelium;
|
||||
|
||||
// **********************************************************************************************
|
||||
|
||||
/*
|
||||
lithium = lithiumDef->GetParticleName();
|
||||
tableFile[lithium] = fileLithium;
|
||||
|
||||
@@ -272,7 +272,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
lowEnergyLimit[lithium] = 0.5*7*MeV;
|
||||
highEnergyLimit[lithium] = 1e6*7*MeV;
|
||||
//
|
||||
|
||||
|
||||
// Cross section
|
||||
|
||||
G4DNACrossSectionDataSet* tableLithium = new G4DNACrossSectionDataSet(new G4LogLogInterpolation,
|
||||
@@ -280,7 +280,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
scaleFactor );
|
||||
tableLithium->LoadData(fileLithium);
|
||||
tableData[lithium] = tableLithium;
|
||||
|
||||
|
||||
// **********************************************************************************************
|
||||
|
||||
beryllium = berylliumDef->GetParticleName();
|
||||
@@ -320,7 +320,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
scaleFactor );
|
||||
tableBoron->LoadData(fileBoron);
|
||||
tableData[boron] = tableBoron;
|
||||
|
||||
*/
|
||||
// **********************************************************************************************
|
||||
|
||||
carbon = carbonDef->GetParticleName();
|
||||
@@ -457,7 +457,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
SetLowEnergyLimit(lowEnergyLimit[alphaPlusPlus]);
|
||||
SetHighEnergyLimit(highEnergyLimit[alphaPlusPlus]);
|
||||
}
|
||||
|
||||
/*
|
||||
if (particle==lithiumDef)
|
||||
{
|
||||
SetLowEnergyLimit(lowEnergyLimit[lithium]);
|
||||
@@ -475,7 +475,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
SetLowEnergyLimit(lowEnergyLimit[boron]);
|
||||
SetHighEnergyLimit(highEnergyLimit[boron]);
|
||||
}
|
||||
|
||||
*/
|
||||
if (particle==carbonDef)
|
||||
{
|
||||
SetLowEnergyLimit(lowEnergyLimit[carbon]);
|
||||
@@ -533,7 +533,7 @@ void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* pa
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
const G4ParticleDefinition* partDef,
|
||||
G4double k,
|
||||
G4double,
|
||||
G4double)
|
||||
@@ -545,21 +545,20 @@ G4double G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Materia
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNARuddIonisationExtendedModel" << G4endl;
|
||||
|
||||
auto particleDefinition = GetDNAIonParticleDefinition(partDef);
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (
|
||||
particleDefinition != G4Proton::ProtonDefinition()
|
||||
particleDefinition != protonDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("hydrogen")
|
||||
particleDefinition != hydrogenDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha++")
|
||||
particleDefinition != alphaPlusPlusDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha+")
|
||||
particleDefinition != alphaPlusDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("helium")
|
||||
particleDefinition != heliumDef
|
||||
&&
|
||||
// SI
|
||||
//particleDefinition != instance->GetIon("carbon")
|
||||
@@ -569,21 +568,23 @@ G4double G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Materia
|
||||
//particleDefinition != instance->GetIon("oxygen")
|
||||
//&&
|
||||
//particleDefinition != instance->GetIon("iron")
|
||||
particleDefinition != G4IonTable::GetIonTable()->GetIon(3,7)
|
||||
/*
|
||||
particleDefinition != lithiumDef
|
||||
&&
|
||||
particleDefinition != G4IonTable::GetIonTable()->GetIon(4,9)
|
||||
particleDefinition != berylliumDef
|
||||
&&
|
||||
particleDefinition != G4IonTable::GetIonTable()->GetIon(5,11)
|
||||
particleDefinition != boronDef
|
||||
&&
|
||||
particleDefinition != G4IonTable::GetIonTable()->GetIon(6,12)
|
||||
*/
|
||||
particleDefinition != carbonDef
|
||||
&&
|
||||
particleDefinition != G4IonTable::GetIonTable()->GetIon(7,14)
|
||||
particleDefinition != nitrogenDef
|
||||
&&
|
||||
particleDefinition != G4IonTable::GetIonTable()->GetIon(8,16)
|
||||
particleDefinition != oxygenDef
|
||||
&&
|
||||
particleDefinition != G4IonTable::GetIonTable()->GetIon(14,28)
|
||||
particleDefinition != siliconDef
|
||||
&&
|
||||
particleDefinition != G4IonTable::GetIonTable()->GetIon(26,56)
|
||||
particleDefinition != ironDef
|
||||
//
|
||||
)
|
||||
|
||||
@@ -591,15 +592,15 @@ G4double G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Materia
|
||||
|
||||
G4double lowLim = 0;
|
||||
|
||||
if ( particleDefinition == G4Proton::ProtonDefinition()
|
||||
|| particleDefinition == instance->GetIon("hydrogen")
|
||||
if ( particleDefinition == protonDef
|
||||
|| particleDefinition == hydrogenDef
|
||||
)
|
||||
|
||||
lowLim = lowEnergyLimitOfModelForA[1];
|
||||
|
||||
else if ( particleDefinition == instance->GetIon("alpha++")
|
||||
|| particleDefinition == instance->GetIon("alpha+")
|
||||
|| particleDefinition == instance->GetIon("helium")
|
||||
else if ( particleDefinition == alphaPlusPlusDef
|
||||
|| particleDefinition == alphaPlusDef
|
||||
|| particleDefinition == heliumDef
|
||||
)
|
||||
|
||||
lowLim = lowEnergyLimitOfModelForA[4];
|
||||
@@ -682,29 +683,30 @@ void G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicPa
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4DNARuddIonisationExtendedModel" << G4endl;
|
||||
auto particleDefinition = GetDNAIonParticleDefinition(particle->GetDefinition());
|
||||
|
||||
G4double lowLim = 0;
|
||||
G4double highLim = 0;
|
||||
|
||||
// ZF: the following line summarizes the commented part
|
||||
|
||||
if(particle->GetDefinition()->GetAtomicMass() <= 4) lowLim = killBelowEnergyForA[particle->GetDefinition()->GetAtomicMass()];
|
||||
if(particle->GetDefinition()->GetAtomicMass() <= 4) lowLim = killBelowEnergyForA[particleDefinition->GetAtomicMass()];
|
||||
|
||||
else lowLim = killBelowEnergyForA[5]*particle->GetDefinition()->GetAtomicMass();
|
||||
else lowLim = killBelowEnergyForA[5]*particleDefinition->GetAtomicMass();
|
||||
|
||||
/*
|
||||
|
||||
if(particle->GetDefinition()->GetAtomicMass() >= 5) lowLim = killBelowEnergyForA[5]*particle->GetDefinition()->GetAtomicMass();
|
||||
|
||||
if ( particle->GetDefinition() == G4Proton::ProtonDefinition()
|
||||
|| particle->GetDefinition() == instance->GetIon("hydrogen")
|
||||
if ( particle->GetDefinition() == protonDef
|
||||
|| particle->GetDefinition() == hydrogenDef
|
||||
)
|
||||
|
||||
lowLim = killBelowEnergyForA[1];
|
||||
|
||||
if ( particle->GetDefinition() == instance->GetIon("alpha++")
|
||||
|| particle->GetDefinition() == instance->GetIon("alpha+")
|
||||
|| particle->GetDefinition() == instance->GetIon("helium")
|
||||
if ( particle->GetDefinition() == alphaPlusPlusDef
|
||||
|| particle->GetDefinition() == alphaPlusDef
|
||||
|| particle->GetDefinition() == heliumDef
|
||||
)
|
||||
|
||||
lowLim = killBelowEnergyForA[4];
|
||||
@@ -714,7 +716,7 @@ void G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicPa
|
||||
|
||||
G4double k = particle->GetKineticEnergy();
|
||||
|
||||
const G4String& particleName = particle->GetDefinition()->GetParticleName();
|
||||
const G4String& particleName = particleDefinition->GetParticleName();
|
||||
|
||||
// SI - the following is useless since lowLim is already defined
|
||||
/*
|
||||
@@ -736,7 +738,7 @@ void G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicPa
|
||||
|
||||
// SI: no strict limits, like in the non extended version of the model
|
||||
{
|
||||
G4ParticleDefinition* definition = particle->GetDefinition();
|
||||
G4ParticleDefinition* definition = particleDefinition;
|
||||
G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
|
||||
/*
|
||||
G4double particleMass = definition->GetPDGMass();
|
||||
@@ -987,8 +989,7 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
|
||||
|
||||
G4double energyTransfer = proposed_ws + Bj_energy;
|
||||
proposed_ws/=Bj_energy;
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
G4double tau = 0.;
|
||||
G4double A_ion = 0.;
|
||||
tau = (electron_mass_c2 / particleDefinition->GetPDGMass()) * k;
|
||||
@@ -1017,8 +1018,8 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
|
||||
|
||||
G4bool isHelium = false;
|
||||
|
||||
if ( particleDefinition == G4Proton::ProtonDefinition()
|
||||
|| particleDefinition == instance->GetIon("hydrogen")
|
||||
if ( particleDefinition == protonDef
|
||||
|| particleDefinition == hydrogenDef
|
||||
)
|
||||
{
|
||||
return(rejection_term);
|
||||
@@ -1028,12 +1029,12 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
|
||||
{
|
||||
G4double Z = particleDefinition->GetAtomicNumber();
|
||||
|
||||
G4double x = 100.*std::sqrt(beta2)/std::pow(Z,(2./3.));
|
||||
G4double x = 100.*std::sqrt(beta2)/gpow->powA(Z,(2./3.));
|
||||
G4double Zeffion = Z*(1.-G4Exp(-1.316*x+0.112*x*x-0.0650*x*x*x));
|
||||
rejection_term*=Zeffion*Zeffion;
|
||||
}
|
||||
|
||||
else if (particleDefinition == instance->GetIon("alpha++") )
|
||||
else if (particleDefinition == alphaPlusPlusDef )
|
||||
{
|
||||
isHelium = true;
|
||||
slaterEffectiveCharge[0]=0.;
|
||||
@@ -1044,7 +1045,7 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
|
||||
sCoefficient[2]=0.;
|
||||
}
|
||||
|
||||
else if (particleDefinition == instance->GetIon("alpha+") )
|
||||
else if (particleDefinition == alphaPlusDef )
|
||||
{
|
||||
isHelium = true;
|
||||
slaterEffectiveCharge[0]=2.0;
|
||||
@@ -1057,7 +1058,7 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
|
||||
sCoefficient[2]=0.15;
|
||||
}
|
||||
|
||||
else if (particleDefinition == instance->GetIon("helium") )
|
||||
else if (particleDefinition == heliumDef )
|
||||
{
|
||||
isHelium = true;
|
||||
slaterEffectiveCharge[0]=1.7;
|
||||
@@ -1068,9 +1069,9 @@ G4double G4DNARuddIonisationExtendedModel::RejectionFunction(G4ParticleDefinitio
|
||||
sCoefficient[2]=0.25;
|
||||
}
|
||||
|
||||
// if ( particleDefinition == instance->GetIon("helium")
|
||||
// || particleDefinition == instance->GetIon("alpha+")
|
||||
// || particleDefinition == instance->GetIon("alpha++")
|
||||
// if ( particleDefinition == heliumDef
|
||||
// || particleDefinition == alphaPlusDef
|
||||
// || particleDefinition == alphaPlusPlusDef
|
||||
// )
|
||||
|
||||
if (isHelium)
|
||||
@@ -1167,9 +1168,9 @@ G4double G4DNARuddIonisationExtendedModel::ProposedSampledEnergy(G4ParticleDefin
|
||||
|
||||
G4double v = std::sqrt(v2);
|
||||
//G4double wc = 4.*v2 - 2.*v - (Ry/(4.*Bj_energy));
|
||||
G4double L1 = (C1* std::pow(v,(D1))) / (1.+ E1*std::pow(v, (D1+4.)));
|
||||
G4double L2 = C2*std::pow(v,(D2));
|
||||
G4double H1 = (A1*std::log(1.+v2)) / (v2+(B1/v2));
|
||||
G4double L1 = (C1* gpow->powA(v,(D1))) / (1.+ E1*gpow->powA(v, (D1+4.)));
|
||||
G4double L2 = C2*gpow->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);
|
||||
@@ -1280,12 +1281,10 @@ G4double G4DNARuddIonisationExtendedModel::R(G4double t,
|
||||
G4double G4DNARuddIonisationExtendedModel::CorrectionFactor(G4ParticleDefinition* particleDefinition, G4double k, G4int shell)
|
||||
{
|
||||
// ZF Shortened
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == instance->GetIon("hydrogen") && shell < 4)
|
||||
if (particleDefinition == hydrogenDef && shell < 4)
|
||||
{
|
||||
G4double value = (std::log10(k/eV)-4.2)/0.5;
|
||||
G4double value = ((G4Log(k/eV)/gpow->logZ(10))-4.2)/0.5;
|
||||
// The following values are provided by M. Dingfelder (priv. comm)
|
||||
return((0.6/(1+G4Exp(value))) + 0.9);
|
||||
}
|
||||
@@ -1416,3 +1415,34 @@ G4double G4DNARuddIonisationExtendedModel::Sum(G4double /* energy */, const G4St
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4ParticleDefinition* G4DNARuddIonisationExtendedModel::GetDNAIonParticleDefinition(const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
//for proton, hydrogen, alphas
|
||||
if(particleDefinition->GetAtomicMass() <= 4)
|
||||
{
|
||||
return const_cast<G4ParticleDefinition*>(particleDefinition);
|
||||
}
|
||||
else{
|
||||
auto instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
auto PDGEncoding = particleDefinition->GetPDGEncoding();
|
||||
if(PDGEncoding == 1000140280){
|
||||
return instance->GetIon("silicon");
|
||||
}else if(PDGEncoding == 1000260560){
|
||||
return instance->GetIon("iron");
|
||||
}else if(PDGEncoding == 1000080160){
|
||||
return instance->GetIon("oxygen");
|
||||
}else if(PDGEncoding == 1000070140){
|
||||
return instance->GetIon("nitrogen");
|
||||
}else if(PDGEncoding == 1000060120){
|
||||
return instance->GetIon("carbon");
|
||||
}
|
||||
G4ExceptionDescription description;
|
||||
description << "DNA physics does not support this ion : "<<particleDefinition->GetParticleName()<< G4endl;
|
||||
G4Exception("G4DNARuddIonisationExtendedModel::GetDNAIonParticleDefinition()",
|
||||
"em2051",FatalException,description);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,11 @@
|
||||
#include "G4DNARuddAngle.hh"
|
||||
#include "G4DeltaAngle.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Alpha.hh"
|
||||
|
||||
static G4Pow * gpow = G4Pow::GetInstance();
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
@@ -128,11 +132,11 @@ void G4DNARuddIonisationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
|
||||
G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
|
||||
G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
|
||||
G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
|
||||
G4ParticleDefinition* heliumDef = instance->GetIon("helium");
|
||||
protonDef = G4Proton::ProtonDefinition();
|
||||
hydrogenDef = instance->GetIon("hydrogen");
|
||||
alphaPlusPlusDef = G4Alpha::Alpha();
|
||||
alphaPlusDef = instance->GetIon("alpha+");
|
||||
heliumDef = instance->GetIon("helium");
|
||||
|
||||
G4String proton;
|
||||
G4String hydrogen;
|
||||
@@ -298,34 +302,31 @@ G4double G4DNARuddIonisationModel::CrossSectionPerVolume(const G4Material* mater
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (
|
||||
particleDefinition != G4Proton::ProtonDefinition()
|
||||
particleDefinition != protonDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("hydrogen")
|
||||
particleDefinition != hydrogenDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha++")
|
||||
particleDefinition != alphaPlusPlusDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("alpha+")
|
||||
particleDefinition != alphaPlusDef
|
||||
&&
|
||||
particleDefinition != instance->GetIon("helium")
|
||||
particleDefinition != heliumDef
|
||||
)
|
||||
|
||||
return 0;
|
||||
|
||||
G4double lowLim = 0;
|
||||
|
||||
if ( particleDefinition == G4Proton::ProtonDefinition()
|
||||
|| particleDefinition == instance->GetIon("hydrogen")
|
||||
if ( particleDefinition == protonDef
|
||||
|| particleDefinition == hydrogenDef
|
||||
)
|
||||
|
||||
lowLim = lowEnergyLimitOfModelForZ1;
|
||||
|
||||
if ( particleDefinition == instance->GetIon("alpha++")
|
||||
|| particleDefinition == instance->GetIon("alpha+")
|
||||
|| particleDefinition == instance->GetIon("helium")
|
||||
if ( particleDefinition == alphaPlusPlusDef
|
||||
|| particleDefinition == alphaPlusDef
|
||||
|| particleDefinition == heliumDef
|
||||
)
|
||||
|
||||
lowLim = lowEnergyLimitOfModelForZ2;
|
||||
@@ -416,18 +417,15 @@ void G4DNARuddIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>
|
||||
G4double lowLim = 0;
|
||||
G4double highLim = 0;
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if ( particle->GetDefinition() == G4Proton::ProtonDefinition()
|
||||
|| particle->GetDefinition() == instance->GetIon("hydrogen")
|
||||
if ( particle->GetDefinition() == protonDef
|
||||
|| particle->GetDefinition() == hydrogenDef
|
||||
)
|
||||
|
||||
lowLim = killBelowEnergyForZ1;
|
||||
|
||||
if ( particle->GetDefinition() == instance->GetIon("alpha++")
|
||||
|| particle->GetDefinition() == instance->GetIon("alpha+")
|
||||
|| particle->GetDefinition() == instance->GetIon("helium")
|
||||
if ( particle->GetDefinition() == alphaPlusPlusDef
|
||||
|| particle->GetDefinition() == alphaPlusDef
|
||||
|| particle->GetDefinition() == heliumDef
|
||||
)
|
||||
|
||||
lowLim = killBelowEnergyForZ2;
|
||||
@@ -605,18 +603,15 @@ G4double G4DNARuddIonisationModel::RandomizeEjectedElectronEnergy(G4ParticleDefi
|
||||
{
|
||||
G4double maximumKineticEnergyTransfer = 0.;
|
||||
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition()
|
||||
|| particleDefinition == instance->GetIon("hydrogen"))
|
||||
if (particleDefinition == protonDef
|
||||
|| particleDefinition == hydrogenDef)
|
||||
{
|
||||
maximumKineticEnergyTransfer = 4. * (electron_mass_c2 / proton_mass_c2) * k;
|
||||
}
|
||||
|
||||
else if (particleDefinition == instance->GetIon("helium")
|
||||
|| particleDefinition == instance->GetIon("alpha+")
|
||||
|| particleDefinition == instance->GetIon("alpha++"))
|
||||
else if (particleDefinition == heliumDef
|
||||
|| particleDefinition == alphaPlusDef
|
||||
|| particleDefinition == alphaPlusPlusDef)
|
||||
{
|
||||
maximumKineticEnergyTransfer = 4. * (0.511 / 3728) * k;
|
||||
}
|
||||
@@ -663,15 +658,15 @@ G4double G4DNARuddIonisationModel::RandomizeEjectedElectronEnergy(G4ParticleDefi
|
||||
|
||||
G4double maxSecKinetic = 0.;
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition()
|
||||
|| particleDefinition == instance->GetIon("hydrogen"))
|
||||
if (particleDefinition == protonDef
|
||||
|| particleDefinition == hydrogenDef)
|
||||
{
|
||||
maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
|
||||
}
|
||||
|
||||
else if (particleDefinition == instance->GetIon("helium")
|
||||
|| particleDefinition == instance->GetIon("alpha+")
|
||||
|| particleDefinition == instance->GetIon("alpha++"))
|
||||
else if (particleDefinition == heliumDef
|
||||
|| particleDefinition == alphaPlusDef
|
||||
|| particleDefinition == alphaPlusPlusDef)
|
||||
{
|
||||
maxSecKinetic = 4.* (0.511 / 3728) * k;
|
||||
}
|
||||
@@ -760,9 +755,6 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
const G4double n = 2.;
|
||||
const G4double Gj[5] = { 0.99, 1.11, 1.11, 0.52, 1. };
|
||||
|
||||
G4DNAGenericIonsManager* instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
G4double wBig = (energyTransfer
|
||||
- waterStructure.IonisationEnergy(ionizationLevelIndex));
|
||||
if (wBig < 0)
|
||||
@@ -780,26 +772,26 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
G4bool isProtonOrHydrogen = false;
|
||||
G4bool isHelium = false;
|
||||
|
||||
if (particleDefinition == G4Proton::ProtonDefinition()
|
||||
|| particleDefinition == instance->GetIon("hydrogen"))
|
||||
if (particleDefinition == protonDef
|
||||
|| particleDefinition == hydrogenDef)
|
||||
{
|
||||
isProtonOrHydrogen = true;
|
||||
tau = (electron_mass_c2 / proton_mass_c2) * k;
|
||||
}
|
||||
|
||||
else if (particleDefinition == instance->GetIon("helium")
|
||||
|| particleDefinition == instance->GetIon("alpha+")
|
||||
|| particleDefinition == instance->GetIon("alpha++"))
|
||||
else if (particleDefinition == heliumDef
|
||||
|| particleDefinition == alphaPlusDef
|
||||
|| particleDefinition == alphaPlusPlusDef)
|
||||
{
|
||||
isHelium = true;
|
||||
tau = (0.511 / 3728.) * k;
|
||||
}
|
||||
|
||||
G4double S = 4. * pi * Bohr_radius * Bohr_radius * n
|
||||
* std::pow((Ry / Bj[ionizationLevelIndex]), 2);
|
||||
* gpow->powN((Ry / Bj[ionizationLevelIndex]), 2);
|
||||
if (j == 4)
|
||||
S = 4. * pi * Bohr_radius * Bohr_radius * n
|
||||
* std::pow((Ry / waterStructure.IonisationEnergy(ionizationLevelIndex)),
|
||||
* gpow->powN((Ry / waterStructure.IonisationEnergy(ionizationLevelIndex)),
|
||||
2);
|
||||
|
||||
G4double v2 = tau / Bj[ionizationLevelIndex];
|
||||
@@ -812,9 +804,9 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
wc = 4. * v2 - 2. * v
|
||||
- (Ry / (4. * waterStructure.IonisationEnergy(ionizationLevelIndex)));
|
||||
|
||||
G4double L1 = (C1 * std::pow(v, (D1))) / (1. + E1 * std::pow(v, (D1 + 4.)));
|
||||
G4double L2 = C2 * std::pow(v, (D2));
|
||||
G4double H1 = (A1 * std::log(1. + v2)) / (v2 + (B1 / v2));
|
||||
G4double L1 = (C1 * gpow->powA(v, (D1))) / (1. + E1 * gpow->powA(v, (D1 + 4.)));
|
||||
G4double L2 = C2 * gpow->powA(v, (D2));
|
||||
G4double H1 = (A1 * G4Log(1. + v2)) / (v2 + (B1 / v2));
|
||||
G4double H2 = (A2 / v2) + (B2 / (v2 * v2));
|
||||
|
||||
G4double F1 = L1 + H1;
|
||||
@@ -824,28 +816,28 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
CorrectionFactor(particleDefinition, k) * Gj[j]
|
||||
* (S / Bj[ionizationLevelIndex])
|
||||
* ((F1 + w * F2)
|
||||
/ (std::pow((1. + w), 3)
|
||||
/ (gpow->powN((1. + w), 3)
|
||||
* (1. + G4Exp(alphaConst * (w - wc) / v))));
|
||||
|
||||
if (j == 4)
|
||||
sigma = CorrectionFactor(particleDefinition, k) * Gj[j]
|
||||
* (S / waterStructure.IonisationEnergy(ionizationLevelIndex))
|
||||
* ((F1 + w * F2)
|
||||
/ (std::pow((1. + w), 3)
|
||||
/ (gpow->powN((1. + w), 3)
|
||||
* (1. + G4Exp(alphaConst * (w - wc) / v))));
|
||||
|
||||
if ((particleDefinition == instance->GetIon("hydrogen"))
|
||||
if ((particleDefinition == hydrogenDef)
|
||||
&& (ionizationLevelIndex == 4))
|
||||
{
|
||||
// sigma = Gj[j] * (S/Bj[ionizationLevelIndex])
|
||||
sigma = Gj[j] * (S / waterStructure.IonisationEnergy(ionizationLevelIndex))
|
||||
* ((F1 + w * F2)
|
||||
/ (std::pow((1. + w), 3)
|
||||
/ (gpow->powN((1. + w), 3)
|
||||
* (1. + G4Exp(alphaConst * (w - wc) / v))));
|
||||
}
|
||||
|
||||
// if ( particleDefinition == G4Proton::ProtonDefinition()
|
||||
// || particleDefinition == instance->GetIon("hydrogen")
|
||||
// if ( particleDefinition == protonDef
|
||||
// || particleDefinition == hydrogenDef
|
||||
// )
|
||||
|
||||
if (isProtonOrHydrogen)
|
||||
@@ -853,7 +845,7 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
return (sigma);
|
||||
}
|
||||
|
||||
if (particleDefinition == instance->GetIon("alpha++"))
|
||||
if (particleDefinition == alphaPlusPlusDef)
|
||||
{
|
||||
slaterEffectiveCharge[0] = 0.;
|
||||
slaterEffectiveCharge[1] = 0.;
|
||||
@@ -863,7 +855,7 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
sCoefficient[2] = 0.;
|
||||
}
|
||||
|
||||
else if (particleDefinition == instance->GetIon("alpha+"))
|
||||
else if (particleDefinition == alphaPlusDef)
|
||||
{
|
||||
slaterEffectiveCharge[0] = 2.0;
|
||||
// The following values are provided by M. Dingfelder (priv. comm)
|
||||
@@ -875,7 +867,7 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
sCoefficient[2] = 0.15;
|
||||
}
|
||||
|
||||
else if (particleDefinition == instance->GetIon("helium"))
|
||||
else if (particleDefinition == heliumDef)
|
||||
{
|
||||
slaterEffectiveCharge[0] = 1.7;
|
||||
slaterEffectiveCharge[1] = 1.15;
|
||||
@@ -885,22 +877,22 @@ G4double G4DNARuddIonisationModel::DifferentialCrossSection(G4ParticleDefinition
|
||||
sCoefficient[2] = 0.25;
|
||||
}
|
||||
|
||||
// if ( particleDefinition == instance->GetIon("helium")
|
||||
// || particleDefinition == instance->GetIon("alpha+")
|
||||
// || particleDefinition == instance->GetIon("alpha++")
|
||||
// if ( particleDefinition == heliumDef
|
||||
// || particleDefinition == alphaPlusDef
|
||||
// || particleDefinition == alphaPlusPlusDef
|
||||
// )
|
||||
if (isHelium)
|
||||
{
|
||||
sigma = Gj[j] * (S / Bj[ionizationLevelIndex])
|
||||
* ((F1 + w * F2)
|
||||
/ (std::pow((1. + w), 3)
|
||||
/ (gpow->powN((1. + w), 3)
|
||||
* (1. + G4Exp(alphaConst * (w - wc) / v))));
|
||||
|
||||
if (j == 4)
|
||||
sigma = Gj[j]
|
||||
* (S / waterStructure.IonisationEnergy(ionizationLevelIndex))
|
||||
* ((F1 + w * F2)
|
||||
/ (std::pow((1. + w), 3)
|
||||
/ (gpow->powN((1. + w), 3)
|
||||
* (1. + G4Exp(alphaConst * (w - wc) / v))));
|
||||
|
||||
G4double zEff = particleDefinition->GetPDGCharge() / eplus
|
||||
@@ -995,15 +987,13 @@ G4double G4DNARuddIonisationModel::R(G4double t,
|
||||
G4double G4DNARuddIonisationModel::CorrectionFactor(G4ParticleDefinition* particleDefinition,
|
||||
G4double k)
|
||||
{
|
||||
G4DNAGenericIonsManager *instance;
|
||||
instance = G4DNAGenericIonsManager::Instance();
|
||||
|
||||
if (particleDefinition == G4Proton::Proton())
|
||||
{
|
||||
return (1.);
|
||||
} else if (particleDefinition == instance->GetIon("hydrogen"))
|
||||
} else if (particleDefinition == hydrogenDef)
|
||||
{
|
||||
G4double value = (std::log10(k / eV) - 4.2) / 0.5;
|
||||
G4double value = (G4Log(k / eV)/gpow->logZ(10) - 4.2) / 0.5;
|
||||
// The following values are provided by M. Dingfelder (priv. comm)
|
||||
return ((0.6 / (1 + G4Exp(value))) + 0.9);
|
||||
} else
|
||||
|
||||
@@ -136,7 +136,7 @@ Initialise(const G4ParticleDefinition* /*particle*/,
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
|
||||
char *path = getenv("G4LEDATA");
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
std::ostringstream eFullFileName;
|
||||
eFullFileName << path << "/dna/sigma_excitationvib_e_sanche.dat";
|
||||
std::ifstream input(eFullFileName.str().c_str());
|
||||
|
||||
@@ -58,7 +58,7 @@ G4double G4DNASmoluchowskiReactionModel::GetReactionRadius(const G4MolecularConf
|
||||
return __output;
|
||||
}
|
||||
|
||||
G4double G4DNASmoluchowskiReactionModel::GetReactionRadius(const G4int __i)
|
||||
G4double G4DNASmoluchowskiReactionModel::GetReactionRadius(const G4int& __i)
|
||||
{
|
||||
G4double __output = (*fpReactionData)[__i]->GetEffectiveReactionRadius();
|
||||
return __output;
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// 20/2/2019
|
||||
// Author : HoangTRAN
|
||||
|
||||
#include "G4DNATotallyDiffusionControlled.hh"
|
||||
#include "G4IRTUtils.hh"
|
||||
#include "G4DNAMolecularReactionTable.hh"
|
||||
#include "G4VDNAReactionModel.hh"
|
||||
#include "G4OctreeFinder.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4MolecularConfiguration.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4Electron_aq.hh"
|
||||
#include "G4Hydrogen.hh"
|
||||
#include "G4ErrorFunction.hh"
|
||||
G4DNATotallyDiffusionControlled::G4DNATotallyDiffusionControlled()
|
||||
: G4VReactionType()
|
||||
{}
|
||||
G4DNATotallyDiffusionControlled::~G4DNATotallyDiffusionControlled() = default;
|
||||
|
||||
G4double G4DNATotallyDiffusionControlled::GetTimeToEncounter(const G4Track& trackA,
|
||||
const G4Track& trackB)
|
||||
{
|
||||
auto pMolConfA = GetMolecule(trackA)->GetMolecularConfiguration();
|
||||
auto pMolConfB = GetMolecule(trackB)->GetMolecularConfiguration();
|
||||
|
||||
G4double D = GetDiffusionCoefficient(pMolConfA, pMolConfB);
|
||||
auto reactionData = G4DNAMolecularReactionTable::Instance()
|
||||
->GetReactionData(pMolConfA, pMolConfB);
|
||||
G4double kobs = reactionData->GetObservedReactionRateConstant();
|
||||
G4double distance = (trackA.GetPosition() - trackB.GetPosition()).mag();
|
||||
G4double Reff = kobs / ( 4 * CLHEP::pi * D * Avogadro );
|
||||
|
||||
if( distance < Reff )
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "distance = "<< distance
|
||||
<< " is uncorrected with "
|
||||
<<" Reff = "<<Reff
|
||||
<<" for : "<<pMolConfA->GetName()
|
||||
<<" and "<<pMolConfB->GetName();
|
||||
G4Exception("G4DNATotallyDiffusionControlled"
|
||||
"::GetTimeToEncounter()", "G4DNATotallyDiffusionControlled02",
|
||||
FatalException, exceptionDescription);
|
||||
}
|
||||
|
||||
G4double Winf = Reff / distance;
|
||||
G4double U = G4UniformRand();
|
||||
G4double irt = -1.0 * ps;
|
||||
|
||||
if ( U < Winf )
|
||||
{
|
||||
G4double d = ( distance - Reff ) /
|
||||
G4ErrorFunction::erfcInv( U / Winf );
|
||||
irt = ( 1.0 / ( 4 * D ) ) * d * d;
|
||||
}
|
||||
return irt;
|
||||
}
|
||||
G4bool G4DNATotallyDiffusionControlled::
|
||||
GeminateRecombinationProbability(const G4MolecularConfiguration* pMolA,
|
||||
const G4MolecularConfiguration* pMolB)
|
||||
{
|
||||
if(pMolA->GetDefinition() == G4Electron_aq::Definition() ||
|
||||
pMolA->GetDefinition() == G4Hydrogen::Definition())
|
||||
{
|
||||
G4bool spinA;
|
||||
G4bool spinB;
|
||||
spinA = G4UniformRand() < 0.5;
|
||||
if(spinA &&
|
||||
(pMolB->GetDefinition() == G4Electron_aq::Definition() ||
|
||||
pMolB->GetDefinition() == G4Hydrogen::Definition()))
|
||||
{
|
||||
spinB = G4UniformRand() < 0.5;
|
||||
if( !spinB )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4DNATotallyDiffusionControlled::GetDiffusionCoefficient(const G4MolecularConfiguration* mA,
|
||||
const G4MolecularConfiguration* mB)
|
||||
{
|
||||
G4double D;
|
||||
if(mA == mB)
|
||||
{
|
||||
D = (mA->GetDiffusionCoefficient());
|
||||
}
|
||||
else
|
||||
{
|
||||
D = (mA->GetDiffusionCoefficient() +
|
||||
mB->GetDiffusionCoefficient());//
|
||||
}
|
||||
return D;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#include "G4Scheduler.hh"
|
||||
G4DNAUpdateSystemModel::G4DNAUpdateSystemModel()
|
||||
: G4VUpdateSystemModel()
|
||||
, fpMesh(nullptr)
|
||||
, fVerbose(0)
|
||||
, fGlobalTime(DBL_MAX)
|
||||
{}
|
||||
|
||||
void G4DNAUpdateSystemModel::SetMesh(G4DNAMesh* pMesh) { fpMesh = pMesh; }
|
||||
@@ -48,10 +45,13 @@ void G4DNAUpdateSystemModel::KillMolecule(const Index& index, MolType type)
|
||||
{
|
||||
if(iter->second <= 0)
|
||||
{
|
||||
G4cout << "G4DNAUpdateSystemModel::KillMolecule::molecule : "
|
||||
<< type->GetName() << " index : " << index
|
||||
<< " number : " << iter->second << G4endl;
|
||||
assert(false);
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription
|
||||
<< "G4DNAUpdateSystemModel::KillMolecule::molecule : "
|
||||
<< type->GetName() << " index : " << index
|
||||
<< " number : " << iter->second << G4endl;
|
||||
G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler002",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
}
|
||||
iter->second--;
|
||||
if(G4VMoleculeCounter::Instance()->InUse())
|
||||
@@ -70,10 +70,13 @@ void G4DNAUpdateSystemModel::KillMolecule(const Index& index, MolType type)
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "index : " << index << " " << type->GetName() << G4endl;
|
||||
G4cout << "This molecule is not belong scavengers or particle-base"
|
||||
<< G4endl;
|
||||
assert(false);
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription
|
||||
<< "index : " << index << " " << type->GetName()
|
||||
<< " This molecule is not belong scavengers or particle-base"
|
||||
<< G4endl;
|
||||
G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler002",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,24 +84,28 @@ void G4DNAUpdateSystemModel::KillMolecule(const Index& index, MolType type)
|
||||
void G4DNAUpdateSystemModel::JumpTo(const Index& index, MolType type)
|
||||
{
|
||||
auto& node = fpMesh->GetVoxelMapList(index);
|
||||
|
||||
auto iter = node.find(type);
|
||||
auto iter = node.find(type);
|
||||
if(iter != node.end())
|
||||
{
|
||||
if(iter->second <= 0)
|
||||
{
|
||||
G4cout << "G4DNAUpdateSystemModel::KillMolecule::molecule : "
|
||||
<< type->GetName() << " index : " << index
|
||||
<< " number : " << iter->second << G4endl;
|
||||
assert(false);
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "G4DNAUpdateSystemModel::JumpTo::molecule : "
|
||||
<< type->GetName() << " index : " << index
|
||||
<< " number : " << iter->second;
|
||||
G4Exception("G4DNAUpdateSystemModel::JumpTo", "G4DNAUpdateSystemModel001",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
}
|
||||
iter->second--;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "index : " << index << " " << type->GetName() << G4endl;
|
||||
G4cout << "This molecule is not belong particle-base" << G4endl;
|
||||
assert(false);
|
||||
fpMesh->PrintVoxel(index);
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "index : " << index << " " << type->GetName()
|
||||
<< " There is no this type";
|
||||
G4Exception("G4DNAUpdateSystemModel::JumpTo", "G4DNAUpdateSystemModel002",
|
||||
FatalErrorInArgument, exceptionDescription);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,34 +179,9 @@ void G4DNAUpdateSystemModel::UpdateSystem(const Index& index,
|
||||
if(fVerbose != 0)
|
||||
{
|
||||
G4cout << data.GetProduct(j)->GetName();
|
||||
// for test
|
||||
// G4cout<<" fGlobalTime : "<<fGlobalTime;
|
||||
// end fortest
|
||||
}
|
||||
#endif
|
||||
CreateMolecule(index, data.GetProduct(j));
|
||||
//#define DEBUG 1
|
||||
|
||||
#ifdef DEBUG
|
||||
if(G4MoleculeCounter::Instance()->InUse())
|
||||
if(fpMesh->GetNumberOfType(data.GetProduct(j)) !=
|
||||
G4MoleculeCounter::Instance()->GetCurrentNumberOf(
|
||||
data.GetProduct(j)))
|
||||
{
|
||||
G4cout << "*********G4DNAUpdateSystemModel::DEBUG::GetNumberOfType("
|
||||
<< data.GetProduct(j)->GetName()
|
||||
<< ") : " << fpMesh->GetNumberOfType(data.GetProduct(j))
|
||||
<< G4endl;
|
||||
G4cout << "G4MoleculeCounter::GetCurrentNumberOf ("
|
||||
<< data.GetProduct(j)->GetName() << ") : "
|
||||
<< G4MoleculeCounter::Instance()->GetCurrentNumberOf(
|
||||
data.GetProduct(j))
|
||||
<< G4endl;
|
||||
G4MoleculeCounter::Instance()->Dump();
|
||||
throw;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -208,9 +190,6 @@ void G4DNAUpdateSystemModel::UpdateSystem(const Index& index,
|
||||
if(fVerbose != 0)
|
||||
{
|
||||
G4cout << "No product";
|
||||
// for test
|
||||
// G4cout<<" fGlobalTime : "<<fGlobalTime;
|
||||
// end fortest
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -221,40 +200,7 @@ void G4DNAUpdateSystemModel::UpdateSystem(const Index& index,
|
||||
}
|
||||
#endif
|
||||
KillMolecule(index, reactant1);
|
||||
#ifdef DEBUG
|
||||
if(G4MoleculeCounter::Instance()->InUse())
|
||||
if(fpMesh->GetNumberOfType(reactant1) !=
|
||||
G4MoleculeCounter::Instance()->GetCurrentNumberOf(reactant1))
|
||||
{
|
||||
G4cout << "*********G4DNAUpdateSystemModel::DEBUG::GetNumberOfType("
|
||||
<< reactant1->GetName()
|
||||
<< ") : " << fpMesh->GetNumberOfType(reactant1) << G4endl;
|
||||
G4cout << "G4MoleculeCounter::GetCurrentNumberOf ("
|
||||
<< reactant1->GetName() << ") : "
|
||||
<< G4MoleculeCounter::Instance()->GetCurrentNumberOf(reactant1)
|
||||
<< G4endl;
|
||||
G4MoleculeCounter::Instance()->Dump();
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
KillMolecule(index, reactant2);
|
||||
#ifdef DEBUG
|
||||
|
||||
if(G4MoleculeCounter::Instance()->InUse())
|
||||
if(fpMesh->GetNumberOfType(reactant2) !=
|
||||
G4MoleculeCounter::Instance()->GetCurrentNumberOf(reactant2))
|
||||
{
|
||||
G4cout << "*********G4DNAUpdateSystemModel::DEBUG::GetNumberOfType("
|
||||
<< reactant2->GetName()
|
||||
<< ") : " << fpMesh->GetNumberOfType(reactant2) << G4endl;
|
||||
G4cout << "G4MoleculeCounter::GetCurrentNumberOf ("
|
||||
<< reactant2->GetName() << ") : "
|
||||
<< G4MoleculeCounter::Instance()->GetCurrentNumberOf(reactant2)
|
||||
<< G4endl;
|
||||
G4MoleculeCounter::Instance()->Dump();
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4DNAUpdateSystemModel::UpdateSystem(const Index& index,
|
||||
|
||||
+126
-56
@@ -32,78 +32,148 @@
|
||||
#include "G4Exp.hh"
|
||||
#include "G4IRTUtils.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAReactionTypeManager.hh"
|
||||
#include "G4Electron_aq.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Molecule.hh"
|
||||
#include "G4ErrorFunction.hh"
|
||||
|
||||
G4DiffusionControlledReactionModel::G4DiffusionControlledReactionModel()
|
||||
: G4VDNAReactionModel()
|
||||
, fpReactionData(nullptr)
|
||||
, fReactionTypeManager(nullptr)
|
||||
: G4VDNAReactionModel()
|
||||
{}
|
||||
|
||||
G4DiffusionControlledReactionModel::~G4DiffusionControlledReactionModel() =
|
||||
default;
|
||||
|
||||
void G4DiffusionControlledReactionModel::Initialise(
|
||||
const G4MolecularConfiguration* pMolecule, const G4Track&)
|
||||
{
|
||||
fpReactionData = fpReactionTable->GetReactionData(pMolecule);
|
||||
}
|
||||
|
||||
G4DiffusionControlledReactionModel::~G4DiffusionControlledReactionModel() = default;
|
||||
|
||||
void G4DiffusionControlledReactionModel::Initialise(const G4MolecularConfiguration* pMolecule,
|
||||
const G4Track&)
|
||||
void G4DiffusionControlledReactionModel::InitialiseToPrint(
|
||||
const G4MolecularConfiguration* pMolecule)
|
||||
{
|
||||
fpReactionData = fpReactionTable->GetReactionData(pMolecule);
|
||||
fpReactionData = fpReactionTable->GetReactionData(pMolecule);
|
||||
}
|
||||
|
||||
void G4DiffusionControlledReactionModel::InitialiseToPrint(const G4MolecularConfiguration* pMolecule)
|
||||
G4double G4DiffusionControlledReactionModel::GetReactionRadius(
|
||||
const G4MolecularConfiguration* pMol1, const G4MolecularConfiguration* pMol2)
|
||||
{
|
||||
fpReactionData = fpReactionTable->GetReactionData(pMolecule);
|
||||
auto reactionData = fpReactionTable->GetReactionData(pMol1, pMol2);
|
||||
if(reactionData == nullptr)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No reactionData"
|
||||
<< " for : " << pMol1->GetName() << " and "
|
||||
<< pMol2->GetName();
|
||||
G4Exception("G4DiffusionControlledReactionModel"
|
||||
"::GetReactionRadius()",
|
||||
"G4DiffusionControlledReactionModel00", FatalException,
|
||||
exceptionDescription);
|
||||
}
|
||||
return reactionData->GetEffectiveReactionRadius();
|
||||
}
|
||||
|
||||
G4double G4DiffusionControlledReactionModel::GetReactionRadius(const G4MolecularConfiguration* pMol1,
|
||||
const G4MolecularConfiguration* pMol2)
|
||||
G4double G4DiffusionControlledReactionModel::GetReactionRadius(const G4int& i)
|
||||
{
|
||||
auto reactionData = fpReactionTable->GetReactionData(pMol1, pMol2);
|
||||
if(reactionData == nullptr)
|
||||
auto pMol1 = (*fpReactionData)[i]->GetReactant1();
|
||||
auto pMol2 = (*fpReactionData)[i]->GetReactant2();
|
||||
return GetReactionRadius(pMol1, pMol2);
|
||||
}
|
||||
|
||||
G4double G4DiffusionControlledReactionModel::GetTimeToEncounter(
|
||||
const G4Track& trackA, const G4Track& trackB)
|
||||
{
|
||||
auto pMolConfA = GetMolecule(trackA)->GetMolecularConfiguration();
|
||||
auto pMolConfB = GetMolecule(trackB)->GetMolecularConfiguration();
|
||||
|
||||
G4double D =
|
||||
pMolConfA->GetDiffusionCoefficient() + pMolConfB->GetDiffusionCoefficient();
|
||||
|
||||
if(D == 0)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "The total diffusion coefficient for : "
|
||||
<< pMolConfA->GetName() << " and "
|
||||
<< pMolConfB->GetName() << " is null ";
|
||||
G4Exception("G4DiffusionControlledReactionModel"
|
||||
"::GetTimeToEncounter()",
|
||||
"G4DiffusionControlledReactionModel03", FatalException,
|
||||
exceptionDescription);
|
||||
}
|
||||
|
||||
auto reactionData = G4DNAMolecularReactionTable::Instance()->GetReactionData(
|
||||
pMolConfA, pMolConfB);
|
||||
G4double kobs = reactionData->GetObservedReactionRateConstant();
|
||||
G4double distance = (trackA.GetPosition() - trackB.GetPosition()).mag();
|
||||
G4double SmoluchowskiRadius = reactionData->GetEffectiveReactionRadius();
|
||||
|
||||
if(distance == 0 || distance < SmoluchowskiRadius)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "distance = " << distance << " is uncorrected with "
|
||||
<< " Reff = " << SmoluchowskiRadius
|
||||
<< " for : " << pMolConfA->GetName() << " and "
|
||||
<< pMolConfB->GetName();
|
||||
G4Exception("G4DiffusionControlledReactionModel"
|
||||
"::GetTimeToEncounter()",
|
||||
"G4DiffusionControlledReactionModel02", FatalException,
|
||||
exceptionDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double Winf = SmoluchowskiRadius / distance;
|
||||
G4double U = G4UniformRand();
|
||||
G4double X = 0;
|
||||
G4double irt_1 = -1.0 * ps;
|
||||
if(Winf > 0 && U < Winf)
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "No reactionData"
|
||||
<<" for : "<<pMol1->GetName()
|
||||
<<" and "<<pMol2->GetName();
|
||||
G4Exception("G4DiffusionControlledReactionModel"
|
||||
"::GetReactionRadius()", "G4DiffusionControlledReactionModel00",
|
||||
FatalException, exceptionDescription);
|
||||
G4double erfcIn = G4ErrorFunction::erfcInv(U / Winf);
|
||||
if(erfcIn != 0)
|
||||
{
|
||||
G4double d =
|
||||
(distance - SmoluchowskiRadius) / erfcIn;
|
||||
irt_1 = (1.0 / (4 * D)) * d * d;
|
||||
}
|
||||
}
|
||||
G4double kobs = reactionData->GetObservedReactionRateConstant();
|
||||
G4double D;
|
||||
if(pMol1 == pMol2)
|
||||
{
|
||||
D = (pMol1->GetDiffusionCoefficient());
|
||||
|
||||
if(reactionData->GetReactionType() == 0) // Totally diffused contr
|
||||
{
|
||||
return irt_1;
|
||||
}
|
||||
|
||||
if(irt_1 < 0)
|
||||
{
|
||||
return irt_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
D = (pMol1->GetDiffusionCoefficient() +
|
||||
pMol2->GetDiffusionCoefficient());//
|
||||
G4double kdif = 4 * CLHEP::pi * D * SmoluchowskiRadius * Avogadro;
|
||||
|
||||
if(pMolConfA == pMolConfB)
|
||||
{
|
||||
kdif /= 2;
|
||||
}
|
||||
G4double kact = G4IRTUtils::GetKact(kobs, kdif);
|
||||
G4double sumOfk = kact + kdif;
|
||||
if(sumOfk != 0)
|
||||
{
|
||||
G4double rateFactor = kact / sumOfk;
|
||||
if(G4UniformRand() > rateFactor)
|
||||
{
|
||||
return -1.0 * ps;
|
||||
}
|
||||
G4double Y = std::abs(G4RandGauss::shoot(0.0, std::sqrt(2)));
|
||||
|
||||
if(Y > 0)
|
||||
{
|
||||
X = -(G4Log(G4UniformRand())) / Y;
|
||||
}
|
||||
G4double f = X * SmoluchowskiRadius * kdif / sumOfk;
|
||||
G4double irt_2 = (f * f) / D;
|
||||
return irt_1 + irt_2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( D == 0 )
|
||||
{
|
||||
G4ExceptionDescription exceptionDescription;
|
||||
exceptionDescription << "D = "<< D
|
||||
<< " is uncorrected"
|
||||
<<" for : "<<pMol1->GetName()
|
||||
<<" and "<<pMol2->GetName();
|
||||
G4Exception("G4DiffusionControlledReactionModel"
|
||||
"::GetReactionRadius()", "G4DiffusionControlledReactionModel01",
|
||||
FatalException, exceptionDescription);
|
||||
}
|
||||
|
||||
G4double Reff = kobs / ( 4 * CLHEP::pi * D * Avogadro );
|
||||
return Reff;
|
||||
}
|
||||
|
||||
G4double G4DiffusionControlledReactionModel::GetReactionRadius(G4int i)
|
||||
{
|
||||
auto pMol1 = (*fpReactionData)[i]->GetReactant1();
|
||||
auto pMol2 = (*fpReactionData)[i]->GetReactant2();
|
||||
return GetReactionRadius(pMol1,pMol2);
|
||||
}
|
||||
|
||||
void G4DiffusionControlledReactionModel::SetReactionTypeManager(G4VReactionTypeManager* typeManager)
|
||||
{
|
||||
fReactionTypeManager = ((G4DNAReactionTypeManager*)typeManager);
|
||||
}
|
||||
return -1.0 * ps;
|
||||
}
|
||||
|
||||
+4
-33
@@ -23,36 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// 20/2/2019
|
||||
// Author : HoangTRAN
|
||||
|
||||
#ifndef G4DNATotallyDiffusionControlled_h
|
||||
#define G4DNATotallyDiffusionControlled_h 1
|
||||
#include "G4DNAReactionTypeManager.hh"
|
||||
#include "G4VReactionType.hh"
|
||||
|
||||
class G4MolecularConfiguration;
|
||||
|
||||
class G4DNAMolecularReactionTable;
|
||||
class G4VDNAReactionModel;
|
||||
|
||||
class G4DNATotallyDiffusionControlled
|
||||
: public G4VReactionType
|
||||
{
|
||||
public:
|
||||
G4DNATotallyDiffusionControlled();
|
||||
~G4DNATotallyDiffusionControlled() override;
|
||||
|
||||
G4DNATotallyDiffusionControlled(const G4DNATotallyDiffusionControlled& other) = delete;
|
||||
G4DNATotallyDiffusionControlled& operator=(const G4DNATotallyDiffusionControlled& other) = delete;
|
||||
|
||||
G4double GetTimeToEncounter(const G4Track& trackA,
|
||||
const G4Track& trackB) override;
|
||||
|
||||
G4bool GeminateRecombinationProbability(const G4MolecularConfiguration* pConfMolA,
|
||||
const G4MolecularConfiguration* pConfMolB) override;
|
||||
private:
|
||||
G4double GetDiffusionCoefficient(const G4MolecularConfiguration* pMA,
|
||||
const G4MolecularConfiguration* pMB);
|
||||
};
|
||||
#endif
|
||||
#include "G4VDNAHitModel.hh"
|
||||
G4VDNAHitModel::G4VDNAHitModel(const G4String& name)
|
||||
: fName(name)
|
||||
{}
|
||||
@@ -84,7 +84,7 @@ G4double G4VLEPTSModel::GetMeanFreePath(const G4Material* aMaterial,
|
||||
void G4VLEPTSModel::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
//CHECK IF PATH VARIABLE IS DEFINED
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
if( !path ) {
|
||||
G4Exception("G4VLEPTSModel",
|
||||
"",
|
||||
|
||||
Reference in New Issue
Block a user