Import Geant4 11.2.0.beta source tree
This commit is contained in:
@@ -29,552 +29,359 @@
|
||||
//
|
||||
// Users are requested to cite the following papers:
|
||||
// - M. Terrissol, A. Baudre, Radiat. Prot. Dosim. 31 (1990) 175-177
|
||||
// - M.C. Bordage, J. Bordes, S. Edel, M. Terrissol, X. Franceries,
|
||||
// - M.C. Bordage, J. Bordes, S. Edel, M. Terrissol, X. Franceries,
|
||||
// M. Bardies, N. Lampe, S. Incerti, Phys. Med. 32 (2016) 1833-1840
|
||||
//
|
||||
// Authors of this class:
|
||||
// Authors of this class:
|
||||
// M.C. Bordage, M. Terrissol, S. Edel, J. Bordes, S. Incerti
|
||||
//
|
||||
// 15.01.2014: creation
|
||||
//
|
||||
// Based on the study by S. Zein et. al. Nucl. Inst. Meth. B 488 (2021) 70-82
|
||||
// 1/2/2023 : Hoang added modification
|
||||
|
||||
#include "G4DNACPA100ElasticModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include "G4DNAMaterialManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
using namespace std;
|
||||
|
||||
// #define CPA100_VERBOSE
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNACPA100ElasticModel::G4DNACPA100ElasticModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),isInitialised(false)
|
||||
G4DNACPA100ElasticModel::G4DNACPA100ElasticModel(const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VDNAModel(nam, "all")
|
||||
{
|
||||
|
||||
SetLowEnergyLimit(11*eV);
|
||||
SetHighEnergyLimit(255955*eV);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
#ifdef UEHARA_VERBOSE
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "CPA100 Elastic model is constructed " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit()/eV << " eV - "
|
||||
<< HighEnergyLimit()/ keV << " keV"
|
||||
<< G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
fParticleChangeForGamma = 0;
|
||||
fpMolWaterDensity = 0;
|
||||
|
||||
// Selection of stationary mode
|
||||
|
||||
statCode = false;
|
||||
fpGuanine = G4Material::GetMaterial("G4_GUANINE", false);
|
||||
fpG4_WATER = G4Material::GetMaterial("G4_WATER", false);
|
||||
fpDeoxyribose = G4Material::GetMaterial("G4_DEOXYRIBOSE", false);
|
||||
fpCytosine = G4Material::GetMaterial("G4_CYTOSINE", false);
|
||||
fpThymine = G4Material::GetMaterial("G4_THYMINE", false);
|
||||
fpAdenine = G4Material::GetMaterial("G4_ADENINE", false);
|
||||
fpPhosphate = G4Material::GetMaterial("G4_PHOSPHORIC_ACID", false);
|
||||
fpParticle = G4Electron::ElectronDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNACPA100ElasticModel::~G4DNACPA100ElasticModel()
|
||||
{
|
||||
// For total cross section
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
for (pos = tableData.begin(); pos != tableData.end(); ++pos)
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
delete table;
|
||||
}
|
||||
|
||||
// For final state
|
||||
eVecm.clear();
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNACPA100ElasticModel::Initialise(const G4ParticleDefinition*
|
||||
particle,
|
||||
const G4DataVector& /*cuts*/)
|
||||
void G4DNACPA100ElasticModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
|
||||
#ifdef UEHARA_VERBOSE
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNACPA100ElasticModel::Initialise()" << G4endl;
|
||||
#endif
|
||||
|
||||
if(particle->GetParticleName() != "e-")
|
||||
{
|
||||
G4Exception("*** WARNING: the G4DNACPA100ElasticModel is "
|
||||
"not intented to be used with another particle than the electron",
|
||||
"",FatalException,"") ;
|
||||
}
|
||||
|
||||
// Energy limits
|
||||
|
||||
if (LowEnergyLimit() < 11.*eV)
|
||||
{
|
||||
G4cout << "G4DNACPA100ElasticModel: low energy limit increased from " <<
|
||||
LowEnergyLimit()/eV << " eV to " << 11 << " eV" << G4endl;
|
||||
SetLowEnergyLimit(11.*eV);
|
||||
}
|
||||
|
||||
if (HighEnergyLimit() > 255955.*eV)
|
||||
{
|
||||
G4cout << "G4DNACPA100ElasticModel: high energy limit decreased from " <<
|
||||
HighEnergyLimit()/keV << " keV to " << 255.955 << " keV"
|
||||
<< G4endl;
|
||||
SetHighEnergyLimit(255955.*eV);
|
||||
}
|
||||
|
||||
// Reading of data files
|
||||
|
||||
G4double scaleFactor = 1e-20*m*m;
|
||||
|
||||
G4String fileElectron("dna/sigma_elastic_e_cpa100");
|
||||
|
||||
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
|
||||
G4String electron;
|
||||
|
||||
// *** ELECTRON
|
||||
|
||||
// For total cross section
|
||||
|
||||
electron = electronDef->GetParticleName();
|
||||
|
||||
tableFile[electron] = fileElectron;
|
||||
|
||||
G4DNACrossSectionDataSet* tableE =
|
||||
new G4DNACrossSectionDataSet(new G4LogLogInterpolation,
|
||||
eV,scaleFactor );
|
||||
|
||||
/*
|
||||
G4DNACrossSectionDataSet* tableE =
|
||||
new G4DNACrossSectionDataSet(new G4DNACPA100LogLogInterpolation,
|
||||
eV,scaleFactor );
|
||||
*/
|
||||
|
||||
tableE->LoadData(fileElectron);
|
||||
|
||||
tableData[electron] = tableE;
|
||||
|
||||
// For final state
|
||||
|
||||
const char *path = G4FindDataDir("G4LEDATA");
|
||||
|
||||
if (!path)
|
||||
{
|
||||
G4Exception("G4DNACPA100ElasticModel::Initialise","em0006",
|
||||
FatalException,"G4LEDATA environment variable not set.");
|
||||
if (isInitialised) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream eFullFileName;
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling G4DNACPA100ExcitationModel::Initialise()" << G4endl;
|
||||
}
|
||||
|
||||
eFullFileName << path
|
||||
<< "/dna/sigmadiff_cumulated_elastic_e_cpa100.dat";
|
||||
|
||||
std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
|
||||
|
||||
if (!eDiffCrossSection)
|
||||
G4Exception("G4DNACPA100ElasticModel::Initialise","em0003",
|
||||
FatalException,
|
||||
"Missing data file:/dna/sigmadiff_cumulated_elastic_e_cpa100.dat");
|
||||
|
||||
// March 25th, 2014 - Vaclav Stepan, Sebastien Incerti
|
||||
// Added clear for MT
|
||||
|
||||
eTdummyVec.clear();
|
||||
eVecm.clear();
|
||||
eDiffCrossSectionData.clear();
|
||||
|
||||
//
|
||||
|
||||
eTdummyVec.push_back(0.);
|
||||
|
||||
while(!eDiffCrossSection.eof())
|
||||
{
|
||||
G4double tDummy;
|
||||
G4double eDummy;
|
||||
eDiffCrossSection>>tDummy>>eDummy;
|
||||
|
||||
// SI : mandatory eVecm initialization
|
||||
|
||||
if (tDummy != eTdummyVec.back())
|
||||
{
|
||||
eTdummyVec.push_back(tDummy);
|
||||
eVecm[tDummy].push_back(0.);
|
||||
if (!G4DNAMaterialManager::Instance()->IsLocked()) {
|
||||
if (p != fpParticle) {
|
||||
std::ostringstream oss;
|
||||
oss << " Model is not applied for this particle " << p->GetParticleName();
|
||||
G4Exception("G4DNACPA100ElasticModel::G4DNACPA100ElasticModel", "CPA001", FatalException,
|
||||
oss.str().c_str());
|
||||
}
|
||||
|
||||
eDiffCrossSection>>eDiffCrossSectionData[tDummy][eDummy];
|
||||
|
||||
if (eDummy != eVecm[tDummy].back()) eVecm[tDummy].push_back(eDummy);
|
||||
char* path = getenv("G4LEDATA");
|
||||
|
||||
if (!path) {
|
||||
G4Exception("G4DNACPA100ElasticModel::Initialise", "em0006", FatalException,
|
||||
"G4LEDATA environment variable not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t index;
|
||||
if (fpG4_WATER != nullptr) {
|
||||
index = fpG4_WATER->GetIndex();
|
||||
fLevels[index] = 1.214e-4;
|
||||
AddCrossSectionData(index, p, "dna/sigma_elastic_e_cpa100",
|
||||
"dna/sigmadiff_cumulated_elastic_e_cpa100", 1e-20 * m * m);
|
||||
SetLowELimit(index, p, 11. * eV);
|
||||
SetHighELimit(index, p, 255955. * eV);
|
||||
}
|
||||
if (fpGuanine != nullptr) {
|
||||
index = fpGuanine->GetIndex();
|
||||
fLevels[index] = 1.4504480e-05;
|
||||
AddCrossSectionData(index, p, "dna/sigma_elastic_e_cpa100_guanine",
|
||||
"dna/sigmadiff_cumulated_elastic_e_cpa100_guanine", 1 * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpDeoxyribose != nullptr) {
|
||||
index = fpDeoxyribose->GetIndex();
|
||||
fLevels[index] = 1.6343100e-05;
|
||||
AddCrossSectionData(index, p, "dna/sigma_elastic_e_cpa100_deoxyribose",
|
||||
"dna/sigmadiff_cumulated_elastic_e_cpa100_deoxyribose", 1 * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpCytosine != nullptr) {
|
||||
index = fpCytosine->GetIndex();
|
||||
fLevels[index] = 1.9729660e-05;
|
||||
AddCrossSectionData(index, p, "dna/sigma_elastic_e_cpa100_cytosine",
|
||||
"dna/sigmadiff_cumulated_elastic_e_cpa100_cytosine", 1 * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpThymine != nullptr) {
|
||||
index = fpThymine->GetIndex();
|
||||
fLevels[index] = 1.7381300e-05;
|
||||
AddCrossSectionData(index, p, "dna/sigma_elastic_e_cpa100_thymine",
|
||||
"dna/sigmadiff_cumulated_elastic_e_cpa100_thymine", 1 * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpAdenine != nullptr) {
|
||||
index = fpAdenine->GetIndex();
|
||||
fLevels[index] = 1.6221800e-05;
|
||||
AddCrossSectionData(index, p, "dna/sigma_elastic_e_cpa100_adenine",
|
||||
"dna/sigmadiff_cumulated_elastic_e_cpa100_adenine", 1 * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpPhosphate != nullptr) {
|
||||
index = fpPhosphate->GetIndex();
|
||||
fLevels[index] = 2.2369600e-05;
|
||||
AddCrossSectionData(index, p, "dna/sigma_elastic_e_cpa100_phosphoric_acid",
|
||||
"dna/sigmadiff_cumulated_elastic_e_cpa100_phosphoric_acid", 1 * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
|
||||
// Load data
|
||||
LoadCrossSectionData(p);
|
||||
G4DNAMaterialManager::Instance()->SetMasterDataModel(DNAModelType::fDNAElastics, this);
|
||||
fpModelData = this;
|
||||
}
|
||||
else {
|
||||
auto dataModel = dynamic_cast<G4DNACPA100ElasticModel*>(
|
||||
G4DNAMaterialManager::Instance()->GetModel(DNAModelType::fDNAElastics));
|
||||
if (dataModel == nullptr) {
|
||||
G4cout << "G4DNACPA100ElasticModel::CrossSectionPerVolume:: not good modelData" << G4endl;
|
||||
G4Exception("G4DNACPA100ElasticModel::CrossSectionPerVolume", "em004", FatalException,
|
||||
"no modelData is registered");
|
||||
}
|
||||
else {
|
||||
fpModelData = dataModel;
|
||||
}
|
||||
}
|
||||
|
||||
// End final state
|
||||
|
||||
#ifdef UEHARA_VERBOSE
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for CPA100 Elastic model" << G4endl;
|
||||
#endif
|
||||
|
||||
#ifdef UEHARA_VERBOSE
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "CPA100 Elastic model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / keV << " keV"
|
||||
<< G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize water density pointer
|
||||
fpMolWaterDensity = G4DNAMolecularMaterial::Instance()
|
||||
->GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER"));
|
||||
|
||||
if (isInitialised) { return; }
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNACPA100ElasticModel::CrossSectionPerVolume
|
||||
(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
G4double)
|
||||
G4double G4DNACPA100ElasticModel::CrossSectionPerVolume(const G4Material* pMaterial,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin, G4double, G4double)
|
||||
{
|
||||
|
||||
#ifdef UEHARA_VERBOSE
|
||||
if (verboseLevel > 3)
|
||||
G4cout <<
|
||||
"Calling CrossSectionPerVolume() of G4DNACPA100ElasticModel" << G4endl;
|
||||
#endif
|
||||
|
||||
// Calculate total cross section for model
|
||||
|
||||
G4double sigma=0;
|
||||
|
||||
G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
|
||||
|
||||
// Get the name of the current particle
|
||||
const G4String& particleName = p->GetParticleName();
|
||||
auto materialID = pMaterial->GetIndex();
|
||||
|
||||
if (ekin <= HighEnergyLimit() && ekin >= LowEnergyLimit())
|
||||
{
|
||||
//SI : XS must not be zero otherwise sampling of secondaries
|
||||
// method ignored
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
pos = tableData.find(particleName);
|
||||
|
||||
if (pos != tableData.end())
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
if (table != 0)
|
||||
{
|
||||
sigma = table->FindValue(ekin);
|
||||
//
|
||||
//Dump in non-MT mode
|
||||
//
|
||||
/*
|
||||
G4double minEnergy = 10.481 * eV;
|
||||
G4double maxEnergy = 255955. * eV;
|
||||
G4int nEnergySteps = 1000;
|
||||
G4double energy(minEnergy);
|
||||
G4double
|
||||
stpEnergy(std::pow(maxEnergy/energy,
|
||||
1./static_cast<G4double>(nEnergySteps-1)));
|
||||
G4int step(nEnergySteps);
|
||||
system ("rm -rf elastic-cpa100.out");
|
||||
FILE* myFile=fopen("elastic-cpa100.out","a");
|
||||
while (step>0)
|
||||
{
|
||||
step--;
|
||||
fprintf (myFile,"%16.9le %16.9le\n",
|
||||
energy/eV,
|
||||
table->FindValue(energy)/(1e-20*m*m));
|
||||
energy*=stpEnergy;
|
||||
}
|
||||
fclose (myFile);
|
||||
abort();
|
||||
*/
|
||||
//
|
||||
// end of dump
|
||||
//
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNACPA100ElasticModel::ComputeCrossSectionPerVolume",
|
||||
"em0002",
|
||||
FatalException,"Model not applicable to particle type.");
|
||||
}
|
||||
// set killBelowEnergy value for current material
|
||||
fKillBelowEnergy = fpModelData->GetLowELimit(materialID, p);
|
||||
|
||||
G4double sigma = 0.;
|
||||
|
||||
if (ekin < fpModelData->GetHighELimit(materialID, p)) {
|
||||
if (ekin < fKillBelowEnergy) {
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
auto tableData = fpModelData->GetData();
|
||||
|
||||
if ((*tableData)[materialID][p] == nullptr) {
|
||||
G4Exception("G4DNACPA100ElasticModel::CrossSectionPerVolume", "em00236", FatalException,
|
||||
"No model is registered");
|
||||
}
|
||||
sigma = (*tableData)[materialID][p]->FindValue(ekin);
|
||||
}
|
||||
|
||||
#ifdef UEHARA_VERBOSE
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
if (verboseLevel > 2) {
|
||||
auto MolDensity =
|
||||
(*G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(pMaterial))[materialID];
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "G4DNACPA100ElasticModel - XS INFO START" << G4endl;
|
||||
G4cout << "Kinetic energy(eV)=" << ekin/eV << " particle : " << particleName << 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 << " - Cross section per water molecule (cm^-1)="
|
||||
// << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
G4cout << "G4DNACPA100ElasticModel - XS INFO END" << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
return sigma*waterDensity;
|
||||
G4cout << "°°° G4DNACPA100ElasticModel - XS INFO START" << G4endl;
|
||||
G4cout << "°°° Kinetic energy(eV)=" << ekin / eV << " particle : " << particleName << G4endl;
|
||||
G4cout << "°°° lowLim (eV) = " << GetLowELimit(materialID, p) / eV
|
||||
<< " highLim (eV) : " << GetHighELimit(materialID, p) / eV << G4endl;
|
||||
G4cout << "°°° Materials = " << (*G4Material::GetMaterialTable())[materialID]->GetName()
|
||||
<< G4endl;
|
||||
G4cout << "°°° Cross section per molecule (cm^2)=" << sigma / cm / cm << G4endl;
|
||||
G4cout << "°°° Cross section per Phosphate molecule (cm^-1)=" << sigma * MolDensity / (1. / cm)
|
||||
<< G4endl;
|
||||
G4cout << "°°° G4DNACPA100ElasticModel - XS INFO END" << G4endl;
|
||||
}
|
||||
|
||||
auto MolDensity =
|
||||
(*G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(pMaterial))[materialID];
|
||||
return sigma * MolDensity;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNACPA100ElasticModel::SampleSecondaries(std::vector<G4DynamicParticle*>* /*fvect*/,
|
||||
const G4MaterialCutsCouple* /*couple*/,
|
||||
const G4DynamicParticle* aDynamicElectron,
|
||||
G4double,
|
||||
G4double)
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicElectron, G4double,
|
||||
G4double)
|
||||
{
|
||||
#ifdef UEHARA_VERBOSE
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4DNACPA100ElasticModel" << G4endl;
|
||||
#endif
|
||||
|
||||
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
|
||||
|
||||
G4double cosTheta = RandomizeCosTheta(electronEnergy0);
|
||||
G4double phi = 2. * pi * G4UniformRand();
|
||||
auto materialID = couple->GetMaterial()->GetIndex();
|
||||
auto p = aDynamicElectron->GetParticleDefinition();
|
||||
|
||||
G4ThreeVector zVers = aDynamicElectron->GetMomentumDirection();
|
||||
if (p != fpParticle) {
|
||||
G4Exception("G4DNACPA100ElasticModel::SampleSecondaries", "em00436", FatalException,
|
||||
"This particle is not applied for this model");
|
||||
}
|
||||
if (electronEnergy0 < fKillBelowEnergy) {
|
||||
return;
|
||||
}
|
||||
G4double cosTheta = fpModelData->RandomizeCosTheta(electronEnergy0, materialID);
|
||||
G4double phi = 2. * CLHEP::pi * G4UniformRand();
|
||||
|
||||
//G4ThreeVector xVers = zVers.orthogonal();
|
||||
//G4ThreeVector yVers = zVers.cross(xVers);
|
||||
//G4double xDir = std::sqrt(1. - cosTheta*cosTheta);
|
||||
//G4double yDir = xDir;
|
||||
//xDir *= std::cos(phi);
|
||||
//yDir *= std::sin(phi);
|
||||
|
||||
// Computation of scattering angles (from Subroutine DIRAN in CPA100)
|
||||
const G4ThreeVector& zVers = aDynamicElectron->GetMomentumDirection();
|
||||
|
||||
G4double CT1, ST1, CF1, SF1, CT2, ST2, CF2, SF2;
|
||||
G4double sinTheta = std::sqrt (1-cosTheta*cosTheta);
|
||||
|
||||
CT1=0;
|
||||
ST1=0;
|
||||
CF1=0;
|
||||
SF1=0;
|
||||
CT2=0;
|
||||
ST2=0;
|
||||
CF2=0;
|
||||
SF2=0;
|
||||
G4double sinTheta = std::sqrt(1 - cosTheta * cosTheta);
|
||||
|
||||
CT1 = zVers.z();
|
||||
ST1=std::sqrt(1.-CT1*CT1);
|
||||
ST1 = std::sqrt(1. - CT1 * CT1);
|
||||
|
||||
if (ST1!=0) CF1 = zVers.x()/ST1; else CF1 = std::cos(2. * pi * G4UniformRand());
|
||||
if (ST1!=0) SF1 = zVers.y()/ST1; else SF1 = std::sqrt(1.-CF1*CF1);
|
||||
if (ST1 != 0)
|
||||
CF1 = zVers.x() / ST1;
|
||||
else
|
||||
CF1 = std::cos(2. * CLHEP::pi * G4UniformRand());
|
||||
if (ST1 != 0)
|
||||
SF1 = zVers.y() / ST1;
|
||||
else
|
||||
SF1 = std::sqrt(1. - CF1 * CF1);
|
||||
|
||||
G4double A3, A4, A5, A2, A1;
|
||||
A3=0;
|
||||
A4=0;
|
||||
A5=0;
|
||||
A2=0;
|
||||
A1=0;
|
||||
|
||||
A3 = sinTheta*std::cos(phi);
|
||||
A4 = A3*CT1 + ST1*cosTheta;
|
||||
A3 = sinTheta * std::cos(phi);
|
||||
A4 = A3 * CT1 + ST1 * cosTheta;
|
||||
A5 = sinTheta * std::sin(phi);
|
||||
A2 = A4 * SF1 + A5 * CF1;
|
||||
A1 = A4 * CF1 - A5 * SF1;
|
||||
|
||||
CT2 = CT1*cosTheta - ST1*A3;
|
||||
ST2 = std::sqrt(1.-CT2*CT2);
|
||||
CT2 = CT1 * cosTheta - ST1 * A3;
|
||||
ST2 = std::sqrt(1. - CT2 * CT2);
|
||||
|
||||
if (ST2==0) ST2=1E-6;
|
||||
CF2 = A1/ST2;
|
||||
SF2 = A2/ST2;
|
||||
if (ST2 == 0) ST2 = 1E-6;
|
||||
CF2 = A1 / ST2;
|
||||
SF2 = A2 / ST2;
|
||||
G4ThreeVector zPrimeVers(ST2 * CF2, ST2 * SF2, CT2);
|
||||
|
||||
/*
|
||||
G4cout << "CT1=" << CT1 << G4endl;
|
||||
G4cout << "ST1=" << ST1 << G4endl;
|
||||
G4cout << "CF1=" << CF1 << G4endl;
|
||||
G4cout << "SF1=" << SF1 << G4endl;
|
||||
G4cout << "cosTheta=" << cosTheta << G4endl;
|
||||
G4cout << "sinTheta=" << sinTheta << G4endl;
|
||||
G4cout << "cosPhi=" << std::cos(phi) << G4endl;
|
||||
G4cout << "sinPhi=" << std::sin(phi) << G4endl;
|
||||
G4cout << "CT2=" << CT2 << G4endl;
|
||||
G4cout << "ST2=" << ST2 << G4endl;
|
||||
G4cout << "CF2=" << CF2 << G4endl;
|
||||
G4cout << "SF2=" << SF2 << G4endl;
|
||||
*/
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
|
||||
|
||||
G4ThreeVector zPrimeVers(ST2*CF2,ST2*SF2,CT2);
|
||||
|
||||
//
|
||||
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit()) ;
|
||||
|
||||
if (!statCode)
|
||||
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy
|
||||
(electronEnergy0-1.214E-4*(1.-cosTheta)*electronEnergy0);
|
||||
|
||||
else fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
|
||||
|
||||
//
|
||||
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(1.214E-4*(1.-cosTheta)*electronEnergy0);
|
||||
|
||||
auto EnergyDeposit = fpModelData->GetElasticLevel(materialID) * (1. - cosTheta) * electronEnergy0;
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(EnergyDeposit);
|
||||
if (statCode) {
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
|
||||
}
|
||||
else {
|
||||
auto newEnergy = electronEnergy0 - EnergyDeposit;
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNACPA100ElasticModel::Theta
|
||||
(G4ParticleDefinition *, G4double k, G4double integrDiff)
|
||||
G4double G4DNACPA100ElasticModel::Theta(const G4ParticleDefinition* p, G4double k,
|
||||
G4double integrDiff, const std::size_t& materialID)
|
||||
{
|
||||
|
||||
G4double theta = 0.;
|
||||
G4double valueT1 = 0;
|
||||
G4double valueT2 = 0;
|
||||
G4double valueE21 = 0;
|
||||
G4double valueE22 = 0;
|
||||
G4double valueE12 = 0;
|
||||
G4double valueE11 = 0;
|
||||
G4double xs11 = 0;
|
||||
G4double xs12 = 0;
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
G4double theta, valueT1, valueT2, valueE21, valueE22, valueE12, valueE11;
|
||||
G4double xs11 = 0;
|
||||
G4double xs12 = 0;
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
if (p == G4Electron::ElectronDefinition()) {
|
||||
if (k == tValuesVec[materialID][p].back()) {
|
||||
k = k * (1. - 1e-12);
|
||||
}
|
||||
auto t2 =
|
||||
std::upper_bound(tValuesVec[materialID][p].begin(), tValuesVec[materialID][p].end(), k);
|
||||
auto t1 = t2 - 1;
|
||||
|
||||
// Protection against out of boundary access
|
||||
if (k==eTdummyVec.back()) k=k*(1.-1e-12);
|
||||
//
|
||||
auto e12 = std::upper_bound(eValuesVect[materialID][p][(*t1)].begin(),
|
||||
eValuesVect[materialID][p][(*t1)].end(), integrDiff);
|
||||
auto e11 = e12 - 1;
|
||||
|
||||
std::vector<G4double>::iterator t2 = std::upper_bound(eTdummyVec.begin(),eTdummyVec.end(), k);
|
||||
std::vector<G4double>::iterator t1 = t2-1;
|
||||
|
||||
std::vector<G4double>::iterator e12 = std::upper_bound(eVecm[(*t1)].begin(),eVecm[(*t1)].end(),
|
||||
integrDiff);
|
||||
std::vector<G4double>::iterator e11 = e12-1;
|
||||
|
||||
std::vector<G4double>::iterator e22 = std::upper_bound(eVecm[(*t2)].begin(),eVecm[(*t2)].end(),
|
||||
integrDiff);
|
||||
std::vector<G4double>::iterator e21 = e22-1;
|
||||
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
auto e22 = std::upper_bound(eValuesVect[materialID][p][(*t2)].begin(),
|
||||
eValuesVect[materialID][p][(*t2)].end(), integrDiff);
|
||||
auto e21 = e22 - 1;
|
||||
|
||||
valueT1 = *t1;
|
||||
valueT2 = *t2;
|
||||
valueE21 = *e21;
|
||||
valueE22 = *e22;
|
||||
valueE12 = *e12;
|
||||
valueE11 = *e11;
|
||||
|
||||
xs11 = diffCrossSectionData[materialID][p][valueT1][valueE11];
|
||||
xs12 = diffCrossSectionData[materialID][p][valueT1][valueE12];
|
||||
xs21 = diffCrossSectionData[materialID][p][valueT2][valueE21];
|
||||
xs22 = diffCrossSectionData[materialID][p][valueT2][valueE22];
|
||||
}
|
||||
|
||||
if (xs11 == 0 && xs12 == 0 && xs21 == 0 && xs22 == 0) {
|
||||
return (0.);
|
||||
}
|
||||
|
||||
theta = QuadInterpolator(valueE11, valueE12, valueE21, valueE22, xs11, xs12, xs21, xs22, valueT1,
|
||||
valueT2, k, integrDiff);
|
||||
|
||||
xs11 = eDiffCrossSectionData[valueT1][valueE11];
|
||||
xs12 = eDiffCrossSectionData[valueT1][valueE12];
|
||||
xs21 = eDiffCrossSectionData[valueT2][valueE21];
|
||||
xs22 = eDiffCrossSectionData[valueT2][valueE22];
|
||||
|
||||
//TEST CPA100
|
||||
//if(k==valueT1) xs22 = eDiffCrossSectionData[valueT1][valueE12];
|
||||
|
||||
if (xs11==0 && xs12==0 && xs21==0 && xs22==0) return (0.);
|
||||
|
||||
theta = QuadInterpolator(
|
||||
valueE11, valueE12,
|
||||
valueE21, valueE22,
|
||||
xs11, xs12,
|
||||
xs21, xs22,
|
||||
valueT1, valueT2,
|
||||
k, integrDiff);
|
||||
|
||||
return theta;
|
||||
|
||||
//TEST CPA100
|
||||
//return xs22;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNACPA100ElasticModel::LinLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
G4double G4DNACPA100ElasticModel::LinLogInterpolate(G4double e1, G4double e2, G4double e,
|
||||
G4double xs1, G4double xs2)
|
||||
{
|
||||
G4double d1 = std::log(xs1);
|
||||
G4double d2 = std::log(xs2);
|
||||
G4double value = std::exp(d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
|
||||
G4double value = std::exp(d1 + (d2 - d1) * (e - e1) / (e2 - e1));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNACPA100ElasticModel::LinLinInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
G4double G4DNACPA100ElasticModel::LinLinInterpolate(G4double e1, G4double e2, G4double e,
|
||||
G4double xs1, G4double xs2)
|
||||
{
|
||||
G4double d1 = xs1;
|
||||
G4double d2 = xs2;
|
||||
G4double value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
|
||||
G4double value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNACPA100ElasticModel::LogLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double xs2)
|
||||
G4double G4DNACPA100ElasticModel::LogLogInterpolate(G4double e1, G4double e2, G4double e,
|
||||
G4double xs1, G4double xs2)
|
||||
{
|
||||
G4double a = (std::log10(xs2)-std::log10(xs1)) / (std::log10(e2)-std::log10(e1));
|
||||
G4double b = std::log10(xs2) - a*std::log10(e2);
|
||||
G4double sigma = a*std::log10(e) + b;
|
||||
G4double value = (std::pow(10.,sigma));
|
||||
G4double a = (std::log10(xs2) - std::log10(xs1)) / (std::log10(e2) - std::log10(e1));
|
||||
G4double b = std::log10(xs2) - a * std::log10(e2);
|
||||
G4double sigma = a * std::log10(e) + b;
|
||||
G4double value = (std::pow(10., sigma));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4double G4DNACPA100ElasticModel::QuadInterpolator(G4double e11, G4double e12,
|
||||
G4double e21, G4double e22,
|
||||
G4double xs11, G4double xs12,
|
||||
G4double xs21, G4double xs22,
|
||||
G4double t1, G4double t2,
|
||||
G4double t, G4double e)
|
||||
G4double G4DNACPA100ElasticModel::QuadInterpolator(G4double e11, G4double e12, G4double e21,
|
||||
G4double e22, G4double xs11, G4double xs12,
|
||||
G4double xs21, G4double xs22, G4double t1,
|
||||
G4double t2, G4double t, G4double e)
|
||||
{
|
||||
// Log-Log
|
||||
/*
|
||||
G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
/*
|
||||
G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
|
||||
|
||||
// Lin-Log
|
||||
G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
// Lin-Log
|
||||
G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
|
||||
// Lin-Lin
|
||||
G4double interpolatedvalue1 = LinLinInterpolate(e11, e12, e, xs11, xs12);
|
||||
@@ -586,53 +393,73 @@ G4double G4DNACPA100ElasticModel::QuadInterpolator(G4double e11, G4double e12,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNACPA100ElasticModel::RandomizeCosTheta(G4double k)
|
||||
G4double G4DNACPA100ElasticModel::RandomizeCosTheta(G4double k, const std::size_t& materialID)
|
||||
{
|
||||
|
||||
G4double integrdiff=0; // PROBABILITY between 0 and 1.
|
||||
G4double uniformRand=G4UniformRand();
|
||||
G4double integrdiff = 0; // PROBABILITY between 0 and 1.
|
||||
G4double uniformRand = G4UniformRand();
|
||||
integrdiff = uniformRand;
|
||||
|
||||
G4double cosTheta=0.;
|
||||
|
||||
// 1 - COS THETA is read from the data file
|
||||
cosTheta = 1 - Theta(G4Electron::ElectronDefinition(),k/eV,integrdiff);
|
||||
|
||||
//
|
||||
//
|
||||
//Dump
|
||||
//
|
||||
//G4cout << "theta=" << theta << G4endl;
|
||||
//G4cout << "cos theta=" << std::cos(theta*pi/180) << G4endl;
|
||||
//G4cout << "sin theta=" << std::sin(theta*pi/180) << G4endl;
|
||||
//G4cout << "acos(cos theta)=" << std::acos(cosTheta) << G4endl;
|
||||
//G4cout << "cos theta="<< cosTheta << G4endl;
|
||||
//G4cout << "1 - cos theta="<< 1. - cosTheta << G4endl;
|
||||
//G4cout << "sin theta=" << std::sqrt(1-cosTheta*cosTheta) << G4endl;
|
||||
//
|
||||
/*
|
||||
G4double minProb = 0; // we scan probability between 0 and one
|
||||
G4double maxProb = 1;
|
||||
G4int nProbSteps = 100;
|
||||
G4double prob(minProb);
|
||||
G4double stepProb((maxProb-minProb)/static_cast<G4double>(nProbSteps));
|
||||
G4int step(nProbSteps);
|
||||
system ("rm -rf elastic-cumul-cpa100-100keV.out");
|
||||
FILE* myFile=fopen("elastic-cumul-cpa100-100keV.out","a");
|
||||
while (step>=0)
|
||||
{
|
||||
step--;
|
||||
fprintf (myFile,"%16.9le %16.9le\n",
|
||||
prob,
|
||||
Theta(G4Electron::ElectronDefinition(),100000,prob)); // SELECT NRJ IN eV !!!
|
||||
prob=prob+stepProb;
|
||||
}
|
||||
fclose (myFile);
|
||||
abort();
|
||||
*/
|
||||
//
|
||||
// end of dump
|
||||
//
|
||||
|
||||
return cosTheta;
|
||||
G4double cosTheta = 0.;
|
||||
cosTheta = 1 - Theta(G4Electron::ElectronDefinition(), k / eV, integrdiff, materialID);
|
||||
// cosTheta = std::cos(theta * CLHEP::pi / 180); ???
|
||||
return cosTheta;
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNACPA100ElasticModel::ReadDiffCSFile(const std::size_t& materialName,
|
||||
const G4ParticleDefinition* particleName,
|
||||
const G4String& file, const G4double&)
|
||||
{
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
if (!path) {
|
||||
G4Exception("G4DNACPA100ElasticModel::ReadAllDiffCSFiles", "em0006", FatalException,
|
||||
"G4LEDATA environment variable not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream fullFileName;
|
||||
fullFileName << path << "/" << file << ".dat";
|
||||
|
||||
std::ifstream diffCrossSection(fullFileName.str().c_str());
|
||||
// error if file is not there
|
||||
std::stringstream endPath;
|
||||
if (!diffCrossSection) {
|
||||
endPath << "Missing data file: " << file;
|
||||
G4Exception("G4DNACPA100ElasticModel::Initialise", "em0003", FatalException,
|
||||
endPath.str().c_str());
|
||||
}
|
||||
|
||||
tValuesVec[materialName][particleName].push_back(0.);
|
||||
|
||||
G4String line;
|
||||
while (std::getline(diffCrossSection, line)) {
|
||||
//
|
||||
std::istringstream testIss(line);
|
||||
G4String test;
|
||||
testIss >> test;
|
||||
if (test == "#") {
|
||||
continue;
|
||||
}
|
||||
// check if line is empty
|
||||
else if (line.empty()) {
|
||||
continue;
|
||||
}
|
||||
std::istringstream iss(line);
|
||||
|
||||
G4double tDummy;
|
||||
G4double eDummy;
|
||||
|
||||
iss >> tDummy >> eDummy;
|
||||
|
||||
if (tDummy != tValuesVec[materialName][particleName].back()) {
|
||||
// Add the current T value
|
||||
tValuesVec[materialName][particleName].push_back(tDummy);
|
||||
// Make it correspond to a default zero E value
|
||||
eValuesVect[materialName][particleName][tDummy].push_back(0.);
|
||||
}
|
||||
iss >> diffCrossSectionData[materialName][particleName][tDummy][eDummy];
|
||||
|
||||
if (eDummy != eValuesVect[materialName][particleName][tDummy].back()) {
|
||||
eValuesVect[materialName][particleName][tDummy].push_back(eDummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,12 +37,15 @@
|
||||
//
|
||||
// 15.01.2014: creation
|
||||
//
|
||||
// 1/2/2023 : Hoang added modification for DNA cross sections
|
||||
|
||||
#include "G4DNACPA100ExcitationModel.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAMaterialManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -52,387 +55,271 @@ using namespace std;
|
||||
|
||||
G4DNACPA100ExcitationModel::G4DNACPA100ExcitationModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
:G4VEmModel(nam),isInitialised(false)
|
||||
: G4VDNAModel(nam, "all")
|
||||
{
|
||||
fpMolWaterDensity = 0;
|
||||
|
||||
SetLowEnergyLimit(11*eV);
|
||||
SetHighEnergyLimit(255955*eV);
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "CPA100 excitation model is constructed " << G4endl;
|
||||
}
|
||||
fParticleChangeForGamma = 0;
|
||||
|
||||
// Selection of stationary mode
|
||||
|
||||
statCode = false;
|
||||
fpGuanine = G4Material::GetMaterial("G4_GUANINE", false);
|
||||
fpG4_WATER = G4Material::GetMaterial("G4_WATER", false);
|
||||
fpDeoxyribose = G4Material::GetMaterial("G4_DEOXYRIBOSE", false);
|
||||
fpCytosine = G4Material::GetMaterial("G4_CYTOSINE", false);
|
||||
fpThymine = G4Material::GetMaterial("G4_THYMINE", false);
|
||||
fpAdenine = G4Material::GetMaterial("G4_ADENINE", false);
|
||||
fpPhosphate = G4Material::GetMaterial("G4_PHOSPHORIC_ACID", false);
|
||||
fpParticle = G4Electron::ElectronDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNACPA100ExcitationModel::~G4DNACPA100ExcitationModel()
|
||||
{
|
||||
// Cross section
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
for (pos = tableData.begin(); pos != tableData.end(); ++pos)
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
delete table;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNACPA100ExcitationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
void G4DNACPA100ExcitationModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
if (isInitialised) {
|
||||
return;
|
||||
}
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling G4DNACPA100ExcitationModel::Initialise()" << G4endl;
|
||||
}
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNACPA100ExcitationModel::Initialise()" << G4endl;
|
||||
|
||||
G4String fileElectron("dna/sigma_excitation_e_cpa100");
|
||||
|
||||
G4double scaleFactor = 1.e-20 *m*m;
|
||||
|
||||
// *** ELECTRON
|
||||
|
||||
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
|
||||
G4String electron;
|
||||
electron = electronDef->GetParticleName();
|
||||
|
||||
tableFile[electron] = fileElectron;
|
||||
|
||||
// Cross section
|
||||
|
||||
G4DNACrossSectionDataSet* tableE
|
||||
= new G4DNACrossSectionDataSet(new G4LogLogInterpolation, eV, scaleFactor );
|
||||
|
||||
/*
|
||||
G4DNACrossSectionDataSet* tableE =
|
||||
new G4DNACrossSectionDataSet(new G4DNACPA100LogLogInterpolation, eV, scaleFactor );
|
||||
*/
|
||||
|
||||
tableE->LoadData(fileElectron);
|
||||
|
||||
tableData[electron] = tableE;
|
||||
|
||||
//
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "CPA100 excitation model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / keV << " keV for "
|
||||
<< particle->GetParticleName()
|
||||
<< G4endl;
|
||||
if (!G4DNAMaterialManager::Instance()->IsLocked()) {
|
||||
if (p != fpParticle) {
|
||||
std::ostringstream oss;
|
||||
oss << " Model is not applied for this particle " << p->GetParticleName();
|
||||
G4Exception("G4DNACPA100ExcitationModel::G4DNACPA100ExcitationModel", "CPA001",
|
||||
FatalException, oss.str().c_str());
|
||||
}
|
||||
|
||||
// Initialize water density pointer
|
||||
fpMolWaterDensity =
|
||||
G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER"));
|
||||
char* path = getenv("G4LEDATA");
|
||||
|
||||
if (isInitialised) return;
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
if (!path) {
|
||||
G4Exception("G4DNACPA100ExcitationModel::Initialise", "em0006", FatalException,
|
||||
"G4LEDATA environment variable not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t index;
|
||||
if (fpG4_WATER != nullptr) {
|
||||
index = fpG4_WATER->GetIndex();
|
||||
AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100", 1.e-20 * m * m);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 255955 * eV);
|
||||
}
|
||||
if (fpGuanine != nullptr) {
|
||||
index = fpGuanine->GetIndex();
|
||||
AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_guanine", 1. * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpDeoxyribose != nullptr) {
|
||||
index = fpDeoxyribose->GetIndex();
|
||||
AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_deoxyribose", 1. * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpCytosine != nullptr) {
|
||||
index = fpCytosine->GetIndex();
|
||||
AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_cytosine", 1. * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpThymine != nullptr) {
|
||||
index = fpThymine->GetIndex();
|
||||
AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_thymine", 1. * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpAdenine != nullptr) {
|
||||
index = fpAdenine->GetIndex();
|
||||
AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_adenine", 1. * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
if (fpPhosphate != nullptr) {
|
||||
index = fpPhosphate->GetIndex();
|
||||
AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_phosphoric_acid", 1. * cm * cm);
|
||||
SetLowELimit(index, p, 11 * eV);
|
||||
SetHighELimit(index, p, 1 * MeV);
|
||||
}
|
||||
|
||||
LoadCrossSectionData(p);
|
||||
G4DNAMaterialManager::Instance()->SetMasterDataModel(DNAModelType::fDNAExcitation, this);
|
||||
fpModelData = this;
|
||||
}
|
||||
else {
|
||||
auto dataModel = dynamic_cast<G4DNACPA100ExcitationModel*>(
|
||||
G4DNAMaterialManager::Instance()->GetModel(DNAModelType::fDNAExcitation));
|
||||
if (dataModel == nullptr) {
|
||||
G4cout << "G4DNACPA100ExcitationModel::CrossSectionPerVolume:: not good modelData" << G4endl;
|
||||
throw;
|
||||
}
|
||||
else {
|
||||
fpModelData = dataModel;
|
||||
}
|
||||
}
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNACPA100ExcitationModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double ekin,
|
||||
G4double,
|
||||
G4double)
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin, G4double, G4double)
|
||||
{
|
||||
// Get the name of the current particle
|
||||
G4String particleName = p->GetParticleName();
|
||||
auto MatID = material->GetIndex();
|
||||
// initialise variables
|
||||
G4double lowLim;
|
||||
G4double highLim;
|
||||
G4double sigma = 0;
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNACPA100ExcitationModel" << G4endl;
|
||||
// Get the low energy limit for the current particle
|
||||
lowLim = fpModelData->GetLowELimit(MatID, p);
|
||||
|
||||
if (particleDefinition != G4Electron::ElectronDefinition()) return 0;
|
||||
// Get the high energy limit for the current particle
|
||||
highLim = fpModelData->GetHighELimit(MatID, p);
|
||||
|
||||
// Calculate total cross section for model
|
||||
// Check that we are in the correct energy range
|
||||
if (ekin >= lowLim && ekin < highLim) {
|
||||
// Get the map with all the data tables
|
||||
auto Data = fpModelData->GetData();
|
||||
|
||||
G4double sigma=0;
|
||||
|
||||
G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
|
||||
|
||||
const G4String& particleName = particleDefinition->GetParticleName();
|
||||
|
||||
if (ekin >= LowEnergyLimit() && ekin <= HighEnergyLimit())
|
||||
{
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
pos = tableData.find(particleName);
|
||||
|
||||
if (pos != tableData.end())
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
if (table != 0)
|
||||
{
|
||||
sigma = table->FindValue(ekin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNACPA100ExcitationModel::CrossSectionPerVolume","em0002",
|
||||
FatalException,"Model not applicable to particle type.");
|
||||
}
|
||||
if ((*Data)[MatID][p] == nullptr) {
|
||||
G4Exception("G4DNACPA100ExcitationModel::CrossSectionPerVolume", "em00236", FatalException,
|
||||
"No model is registered");
|
||||
}
|
||||
// Retrieve the cross section value
|
||||
sigma = (*Data)[MatID][p]->FindValue(ekin);
|
||||
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "G4DNACPA100ExcitationModel - XS INFO START" << G4endl;
|
||||
G4cout << "Kinetic energy(eV)=" << ekin/eV << " particle : " << particleName << 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 << " - Cross section per water molecule (cm^-1)="
|
||||
// << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl;
|
||||
G4cout << "G4DNACPA100ExcitationModel - XS INFO END" << G4endl;
|
||||
if (verboseLevel > 2) {
|
||||
auto MolDensity =
|
||||
(*G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(material))[MatID];
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "°°° G4DNACPA100ExcitationModel - XS INFO START" << G4endl;
|
||||
G4cout << "°°° Kinetic energy(eV)=" << ekin / eV << " particle : " << particleName << G4endl;
|
||||
G4cout << "°°° lowLim (eV) = " << lowLim / eV << " highLim (eV) : " << highLim / eV << G4endl;
|
||||
G4cout << "°°° Materials = " << (*G4Material::GetMaterialTable())[MatID]->GetName() << G4endl;
|
||||
G4cout << "°°° Cross section per " << MatID << " ID molecule (cm^2)=" << sigma / cm / cm
|
||||
<< G4endl;
|
||||
G4cout << "°°° Cross section per Phosphate molecule (cm^-1)="
|
||||
<< sigma * MolDensity / (1. / cm) << G4endl;
|
||||
G4cout << "°°° G4DNACPA100ExcitationModel - XS INFO END" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
return sigma*waterDensity;
|
||||
|
||||
// Return the cross section value
|
||||
auto MolDensity = (*G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(material))[MatID];
|
||||
return sigma * MolDensity;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNACPA100ExcitationModel::SampleSecondaries(std::vector<G4DynamicParticle*>* ,
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle* aDynamicParticle,
|
||||
G4double,
|
||||
G4double)
|
||||
void G4DNACPA100ExcitationModel::SampleSecondaries(std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicParticle,
|
||||
G4double, G4double)
|
||||
{
|
||||
auto materialID = couple->GetMaterial()->GetIndex();
|
||||
G4double k = aDynamicParticle->GetKineticEnergy();
|
||||
const auto& particle = aDynamicParticle->GetDefinition();
|
||||
G4double lowLim = fpModelData->GetLowELimit(materialID, particle);
|
||||
G4double highLim = fpModelData->GetHighELimit(materialID, particle);
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4DNACPA100ExcitationModel" << G4endl;
|
||||
// Check if we are in the correct energy range
|
||||
if (k >= lowLim && k < highLim) {
|
||||
G4int level;
|
||||
G4double excitationEnergy;
|
||||
G4double newEnergy;
|
||||
if (materialID == fpG4_WATER->GetIndex()) {
|
||||
level = fpModelData->RandomSelectShell(k, particle, materialID);
|
||||
excitationEnergy = eStructure.ExcitationEnergy(level, materialID);
|
||||
}
|
||||
else {
|
||||
do {
|
||||
level = eStructure.NumberOfLevels(materialID) * G4UniformRand();
|
||||
excitationEnergy = eStructure.ExcitationEnergy(level, materialID);
|
||||
} while ((k - eStructure.ExcitationEnergy(level, materialID)) < 0);
|
||||
}
|
||||
newEnergy = k - excitationEnergy;
|
||||
|
||||
G4double k = aDynamicParticle->GetKineticEnergy();
|
||||
|
||||
const G4String& particleName = aDynamicParticle->GetDefinition()->GetParticleName();
|
||||
|
||||
G4int level = RandomSelect(k,particleName);
|
||||
G4double excitationEnergy = waterStructure.ExcitationEnergy(level);
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
|
||||
if (newEnergy > 0)
|
||||
{
|
||||
// fParticleChangeForGamma->ProposeMomentumDirection(aDynamicParticle->GetMomentumDirection());
|
||||
|
||||
// We take into account direction change as described page 87 (II.92) in thesis by S. Edel
|
||||
|
||||
G4double cosTheta =
|
||||
|
||||
(excitationEnergy/k) / (1. + (k/(2*electron_mass_c2))*(1.-excitationEnergy/k) );
|
||||
|
||||
cosTheta = std::sqrt(1.-cosTheta);
|
||||
|
||||
G4double phi = 2. * pi * G4UniformRand();
|
||||
|
||||
G4ThreeVector zVers = aDynamicParticle->GetMomentumDirection();
|
||||
|
||||
//G4ThreeVector xVers = zVers.orthogonal();
|
||||
//G4ThreeVector yVers = zVers.cross(xVers);
|
||||
//G4double xDir = std::sqrt(1. - cosTheta*cosTheta);
|
||||
//G4double yDir = xDir;
|
||||
//xDir *= std::cos(phi);
|
||||
//yDir *= std::sin(phi);
|
||||
// G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
|
||||
|
||||
// Computation of scattering angles (from Subroutine DIRAN in CPA100)
|
||||
|
||||
G4double CT1, ST1, CF1, SF1, CT2, ST2, CF2, SF2;
|
||||
G4double sinTheta = std::sqrt (1-cosTheta*cosTheta);
|
||||
|
||||
CT1=0;
|
||||
ST1=0;
|
||||
CF1=0;
|
||||
SF1=0;
|
||||
CT2=0;
|
||||
ST2=0;
|
||||
CF2=0;
|
||||
SF2=0;
|
||||
|
||||
CT1 = zVers.z();
|
||||
ST1=std::sqrt(1.-CT1*CT1);
|
||||
|
||||
if (ST1!=0) CF1 = zVers.x()/ST1; else CF1 = std::cos(2. * pi * G4UniformRand());
|
||||
if (ST1!=0) SF1 = zVers.y()/ST1; else SF1 = std::sqrt(1.-CF1*CF1);
|
||||
|
||||
G4double A3, A4, A5, A2, A1;
|
||||
A3=0;
|
||||
A4=0;
|
||||
A5=0;
|
||||
A2=0;
|
||||
A1=0;
|
||||
|
||||
A3 = sinTheta*std::cos(phi);
|
||||
A4 = A3*CT1 + ST1*cosTheta;
|
||||
A5 = sinTheta * std::sin(phi);
|
||||
A2 = A4 * SF1 + A5 * CF1;
|
||||
A1 = A4 * CF1 - A5 * SF1;
|
||||
|
||||
CT2 = CT1*cosTheta - ST1*A3;
|
||||
ST2 = std::sqrt(1.-CT2*CT2);
|
||||
|
||||
if (ST2==0) ST2=1E-6;
|
||||
CF2 = A1/ST2;
|
||||
SF2 = A2/ST2;
|
||||
|
||||
/*
|
||||
G4cout << "CT1=" << CT1 << G4endl;
|
||||
G4cout << "ST1=" << ST1 << G4endl;
|
||||
G4cout << "CF1=" << CF1 << G4endl;
|
||||
G4cout << "SF1=" << SF1 << G4endl;
|
||||
G4cout << "cosTheta=" << cosTheta << G4endl;
|
||||
G4cout << "sinTheta=" << sinTheta << G4endl;
|
||||
G4cout << "cosPhi=" << std::cos(phi) << G4endl;
|
||||
G4cout << "sinPhi=" << std::sin(phi) << G4endl;
|
||||
G4cout << "CT2=" << CT2 << G4endl;
|
||||
G4cout << "ST2=" << ST2 << G4endl;
|
||||
G4cout << "CF2=" << CF2 << G4endl;
|
||||
G4cout << "SF2=" << SF2 << G4endl;
|
||||
*/
|
||||
|
||||
G4ThreeVector zPrimeVers(ST2*CF2,ST2*SF2,CT2);
|
||||
|
||||
//
|
||||
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit()) ;
|
||||
|
||||
//
|
||||
|
||||
if (!statCode) fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
else fParticleChangeForGamma->SetProposedKineticEnergy(k);
|
||||
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
if (k - newEnergy <= 0) {
|
||||
G4cout << "k : " << k << " newEnergy : " << newEnergy << G4endl;
|
||||
G4cout << "newEnergy : " << newEnergy << " k : " << k
|
||||
<< " excitationEnergy: " << excitationEnergy << G4endl;
|
||||
G4cout << "G4DNACPA100ExcitationModel::level : " << eStructure.NumberOfLevels(materialID)
|
||||
<< " excitationEnergy : " << excitationEnergy << G4endl;
|
||||
G4cout << "°°° Materials = " << (*G4Material::GetMaterialTable())[materialID]->GetName()
|
||||
<< G4endl;
|
||||
G4cout << "Attention an error occured !!!" << G4endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
// Chemistry
|
||||
if (newEnergy >= 0) {
|
||||
// We take into account direction change as described page 87 (II.92) in thesis by S. Edel
|
||||
|
||||
const G4Track * theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
|
||||
G4DNAChemistryManager::Instance()->CreateWaterMolecule(eExcitedMolecule,
|
||||
level,
|
||||
theIncomingTrack);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int G4DNACPA100ExcitationModel::RandomSelect(G4double k, const G4String& particle)
|
||||
{
|
||||
G4int level = 0;
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
pos = tableData.find(particle);
|
||||
|
||||
if (pos != tableData.end())
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
|
||||
if (table != 0)
|
||||
{
|
||||
G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
|
||||
const G4int n = (G4int)table->NumberOfComponents();
|
||||
G4int i(n);
|
||||
G4double value = 0.;
|
||||
|
||||
//Verification
|
||||
/*
|
||||
G4double tmp=10.481*eV;
|
||||
G4cout << table->GetComponent(0)->FindValue(tmp)/(1e-20*m*m) << G4endl;
|
||||
G4cout << table->GetComponent(1)->FindValue(tmp)/(1e-20*m*m) << G4endl;
|
||||
G4cout << table->GetComponent(2)->FindValue(tmp)/(1e-20*m*m) << G4endl;
|
||||
G4cout << table->GetComponent(3)->FindValue(tmp)/(1e-20*m*m) << G4endl;
|
||||
G4cout << table->GetComponent(4)->FindValue(tmp)/(1e-20*m*m) << G4endl;
|
||||
G4cout <<
|
||||
table->GetComponent(0)->FindValue(tmp)/(1e-20*m*m) +
|
||||
table->GetComponent(1)->FindValue(tmp)/(1e-20*m*m) +
|
||||
table->GetComponent(2)->FindValue(tmp)/(1e-20*m*m) +
|
||||
table->GetComponent(3)->FindValue(tmp)/(1e-20*m*m) +
|
||||
table->GetComponent(4)->FindValue(tmp)/(1e-20*m*m)
|
||||
<< G4endl;
|
||||
abort();
|
||||
*/
|
||||
//
|
||||
//Dump
|
||||
//
|
||||
/*
|
||||
G4double minEnergy = 10.481 * eV;
|
||||
G4double maxEnergy = 255955. * eV;
|
||||
G4int nEnergySteps = 1000;
|
||||
G4double energy(minEnergy);
|
||||
G4double stpEnergy(std::pow(maxEnergy/energy, 1./static_cast<G4double>(nEnergySteps-1)));
|
||||
G4int step(nEnergySteps);
|
||||
system ("rm -rf excitation-cap100.out");
|
||||
FILE* myFile=fopen("excitation-cpa100.out","a");
|
||||
while (step>0)
|
||||
{
|
||||
step--;
|
||||
fprintf (myFile,"%16.9le %16.9le %16.9le %16.9le %16.9le %16.9le %16.9le \n",
|
||||
energy/eV,
|
||||
table->GetComponent(0)->FindValue(energy)/(1e-20*m*m),
|
||||
table->GetComponent(1)->FindValue(energy)/(1e-20*m*m),
|
||||
table->GetComponent(2)->FindValue(energy)/(1e-20*m*m),
|
||||
table->GetComponent(3)->FindValue(energy)/(1e-20*m*m),
|
||||
table->GetComponent(4)->FindValue(energy)/(1e-20*m*m),
|
||||
table->GetComponent(0)->FindValue(energy)/(1e-20*m*m)+
|
||||
table->GetComponent(1)->FindValue(energy)/(1e-20*m*m)+
|
||||
table->GetComponent(2)->FindValue(energy)/(1e-20*m*m)+
|
||||
table->GetComponent(3)->FindValue(energy)/(1e-20*m*m)+
|
||||
table->GetComponent(4)->FindValue(energy)/(1e-20*m*m)
|
||||
);
|
||||
energy*=stpEnergy;
|
||||
}
|
||||
fclose (myFile);
|
||||
abort();
|
||||
*/
|
||||
//
|
||||
// end of dump
|
||||
//
|
||||
|
||||
while (i>0)
|
||||
{
|
||||
i--;
|
||||
valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
|
||||
value += valuesBuffer[i];
|
||||
}
|
||||
|
||||
value *= G4UniformRand();
|
||||
|
||||
i = n;
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
|
||||
if (valuesBuffer[i] > value)
|
||||
{
|
||||
delete[] valuesBuffer;
|
||||
return i;
|
||||
}
|
||||
value -= valuesBuffer[i];
|
||||
}
|
||||
|
||||
if (valuesBuffer) delete[] valuesBuffer;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4DNACPA100ExcitationModel::RandomSelect","em0002",
|
||||
FatalException,"Model not applicable to particle type.");
|
||||
}
|
||||
return level;
|
||||
G4double cosTheta =
|
||||
(excitationEnergy / k) / (1. + (k / (2 * electron_mass_c2)) * (1. - excitationEnergy / k));
|
||||
|
||||
cosTheta = std::sqrt(1. - cosTheta);
|
||||
G4double phi = 2. * pi * G4UniformRand();
|
||||
const G4ThreeVector& zVers = aDynamicParticle->GetMomentumDirection();
|
||||
// Computation of scattering angles (from Subroutine DIRAN in CPA100)
|
||||
|
||||
G4double CT1, ST1, CF1, SF1, CT2, ST2, CF2, SF2;
|
||||
G4double sinTheta = std::sqrt(1 - cosTheta * cosTheta);
|
||||
CT1 = zVers.z();
|
||||
ST1 = std::sqrt(1. - CT1 * CT1);
|
||||
|
||||
ST1 != 0 ? CF1 = zVers.x() / ST1 : CF1 = std::cos(2. * pi * G4UniformRand());
|
||||
ST1 != 0 ? SF1 = zVers.y() / ST1 : SF1 = std::sqrt(1. - CF1 * CF1);
|
||||
G4double A3, A4, A5, A2, A1;
|
||||
A3 = sinTheta * std::cos(phi);
|
||||
A4 = A3 * CT1 + ST1 * cosTheta;
|
||||
A5 = sinTheta * std::sin(phi);
|
||||
A2 = A4 * SF1 + A5 * CF1;
|
||||
A1 = A4 * CF1 - A5 * SF1;
|
||||
|
||||
CT2 = CT1 * cosTheta - ST1 * A3;
|
||||
ST2 = std::sqrt(1. - CT2 * CT2);
|
||||
|
||||
if (ST2 == 0) {
|
||||
ST2 = 1E-6;
|
||||
}
|
||||
CF2 = A1 / ST2;
|
||||
SF2 = A2 / ST2;
|
||||
|
||||
G4ThreeVector zPrimeVers(ST2 * CF2, ST2 * SF2, CT2);
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
|
||||
if (!statCode) {
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
}
|
||||
else {
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(k);
|
||||
}
|
||||
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
|
||||
// Chemistry only for water;
|
||||
if (materialID == fpG4_WATER->GetIndex()) {
|
||||
const G4Track* theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
|
||||
G4DNAChemistryManager::Instance()->CreateWaterMolecule(eExcitedMolecule, level,
|
||||
theIncomingTrack);
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4cerr << "newEnergy : " << newEnergy << " k : " << k
|
||||
<< " excitationEnergy: " << excitationEnergy << G4endl;
|
||||
G4cerr << "G4DNACPA100ExcitationModel::level : " << eStructure.NumberOfLevels(materialID)
|
||||
<< " excitationEnergy : " << excitationEnergy << G4endl;
|
||||
G4cerr << "°°° Materials = " << (*G4Material::GetMaterialTable())[materialID]->GetName()
|
||||
<< G4endl;
|
||||
G4cerr << "Attention an error occured !!!" << G4endl;
|
||||
G4Exception("G4DNACPA100ExcitationModel::SampleSecondaries", "em00236", FatalException,
|
||||
"model is not registered for this energy");
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4cerr << "k : " << k << " lowLim : " << lowLim << " highLim : " << highLim << G4endl;
|
||||
G4Exception("G4DNACPA100ExcitationModel::SampleSecondaries", "em00236", FatalException,
|
||||
"model is not registered for this energy");
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+7
-30
@@ -43,39 +43,16 @@ using namespace std;
|
||||
|
||||
G4DNADingfelderChargeIncreaseModel::G4DNADingfelderChargeIncreaseModel(const G4ParticleDefinition*,
|
||||
const G4String& nam) :
|
||||
G4VEmModel(nam), isInitialised(false)
|
||||
G4VEmModel(nam)
|
||||
{
|
||||
fpMolWaterDensity = 0;
|
||||
|
||||
numberOfPartialCrossSections[0] = 0;
|
||||
numberOfPartialCrossSections[1] = 0;
|
||||
|
||||
verboseLevel = 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << "Dingfelder charge increase model is constructed " << G4endl;
|
||||
}
|
||||
fParticleChangeForGamma = 0;
|
||||
|
||||
// Selection of stationary mode
|
||||
|
||||
statCode = false;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNADingfelderChargeIncreaseModel::~G4DNADingfelderChargeIncreaseModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNADingfelderChargeIncreaseModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
@@ -340,7 +317,7 @@ void G4DNADingfelderChargeIncreaseModel::SampleSecondaries(std::vector<
|
||||
FatalException,"Final kinetic energy is negative.");
|
||||
}
|
||||
|
||||
G4DynamicParticle* dp = new G4DynamicParticle(OutgoingParticleDefinition(definition,finalStateIndex),
|
||||
auto dp = new G4DynamicParticle(OutgoingParticleDefinition(definition,finalStateIndex),
|
||||
aDynamicParticle->GetMomentumDirection(),
|
||||
outK);
|
||||
|
||||
@@ -432,8 +409,8 @@ G4double G4DNADingfelderChargeIncreaseModel::IncomingParticleBindingEnergyConsta
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
|
||||
G4int index,
|
||||
G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(const G4double& k,
|
||||
const G4int& index,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
@@ -507,7 +484,7 @@ G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4int G4DNADingfelderChargeIncreaseModel::RandomSelect(G4double k,
|
||||
G4int G4DNADingfelderChargeIncreaseModel::RandomSelect(const G4double& k,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
@@ -522,7 +499,7 @@ G4int G4DNADingfelderChargeIncreaseModel::RandomSelect(G4double k,
|
||||
particleTypeIndex = 1;
|
||||
|
||||
const G4int n = numberOfPartialCrossSections[particleTypeIndex];
|
||||
G4double* values(new G4double[n]);
|
||||
auto values(new G4double[n]);
|
||||
G4double value = 0;
|
||||
G4int i = n;
|
||||
|
||||
@@ -553,7 +530,7 @@ G4int G4DNADingfelderChargeIncreaseModel::RandomSelect(G4double k,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DNADingfelderChargeIncreaseModel::Sum(G4double k,
|
||||
G4double G4DNADingfelderChargeIncreaseModel::Sum(const G4double& k,
|
||||
const G4ParticleDefinition* particleDefinition)
|
||||
{
|
||||
G4int particleTypeIndex = 0;
|
||||
|
||||
@@ -1,79 +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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Contact authors: S. Meylan, C. Villagrasa
|
||||
//
|
||||
// email: sylvain.meylan@symalgo-tech.com, carmen.villagrasa@irsn.fr
|
||||
|
||||
#include "../include/G4DNADummyModel.hh"
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4DNADummyModel::G4DNADummyModel(const G4String& applyToMaterial, const G4ParticleDefinition* p, const G4String& nam, G4VEmModel* emModel)
|
||||
: G4VDNAModel(nam, applyToMaterial)
|
||||
{
|
||||
fpEmModel = emModel;
|
||||
fpParticleDef = p;
|
||||
}
|
||||
|
||||
G4DNADummyModel::~G4DNADummyModel()
|
||||
{
|
||||
// There is no need to delete the model because it will be done in some G4 class.
|
||||
//if(fpEmModel) delete fpEmModel;
|
||||
}
|
||||
|
||||
void G4DNADummyModel::Initialise(const G4ParticleDefinition* particle, const G4DataVector& v, G4ParticleChangeForGamma* changeForGamme)
|
||||
{
|
||||
fMaterialMolPerVol = G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER") );
|
||||
|
||||
fpEmModel->SetParticleChange(changeForGamme, nullptr);
|
||||
fpEmModel->Initialise(particle, v);
|
||||
|
||||
// MatManagSys
|
||||
EnableForMaterialAndParticle("G4_WATER", fpParticleDef->GetParticleName() );
|
||||
SetLowELimit("G4_WATER", fpParticleDef->GetParticleName(), fpEmModel->LowEnergyLimit() );
|
||||
SetHighELimit("G4_WATER",fpParticleDef->GetParticleName(), fpEmModel->HighEnergyLimit() );
|
||||
}
|
||||
|
||||
G4double G4DNADummyModel::CrossSectionPerVolume(const G4Material* material, const G4String& /*materialName*/, const G4ParticleDefinition* p, G4double ekin, G4double emin, G4double emax)
|
||||
{
|
||||
G4double crossSectionTimesDensity = fpEmModel->CrossSectionPerVolume(material, p, ekin, emin, emax);
|
||||
G4double crossSection = crossSectionTimesDensity / GetNumMoleculePerVolumeUnitForMaterial(G4Material::GetMaterial("G4_WATER") );
|
||||
|
||||
return crossSection;
|
||||
}
|
||||
|
||||
void G4DNADummyModel::SampleSecondaries(std::vector<G4DynamicParticle*>* a, const G4MaterialCutsCouple* b, const G4String& /*materialName*/, const G4DynamicParticle* c, G4ParticleChangeForGamma* /*particleChangeForGamma*/, G4double tmin, G4double tmax)
|
||||
{
|
||||
fpEmModel->SampleSecondaries(a, b, c, tmin, tmax);
|
||||
}
|
||||
|
||||
G4double G4DNADummyModel::GetNumMoleculePerVolumeUnitForMaterial(const G4Material* mat)
|
||||
{
|
||||
return fMaterialMolPerVol->at(mat->GetIndex() );
|
||||
}
|
||||
|
||||
|
||||
@@ -38,23 +38,13 @@
|
||||
#include "G4DNAScavengerMaterial.hh"
|
||||
#include "G4Molecule.hh"
|
||||
|
||||
G4DNAEventScheduler::G4DNAEventScheduler(const G4DNABoundingBox& boundingBox,
|
||||
G4int pixel)
|
||||
G4DNAEventScheduler::G4DNAEventScheduler()
|
||||
: IEventScheduler()
|
||||
, fPixel(pixel)
|
||||
, fInitialPixels(fPixel)
|
||||
, fpMesh(new G4DNAMesh(boundingBox, fPixel))
|
||||
, fpGillespieReaction(new G4DNAGillespieDirectMethod())
|
||||
, fpEventSet(new G4DNAEventSet())
|
||||
, fpUpdateSystem(new G4DNAUpdateSystemModel())
|
||||
{
|
||||
if(!CheckingReactionRadius(fpMesh->GetResolution()))
|
||||
{
|
||||
G4String WarMessage = "resolution is not good : " +
|
||||
std::to_string(fpMesh->GetResolution() / nm);
|
||||
G4Exception("G4DNAEventScheduler::InitializeInMesh()", "WrongResolution",
|
||||
JustWarning, WarMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void G4DNAEventScheduler::ClearAndReChargeCounter()
|
||||
@@ -230,12 +220,21 @@ void G4DNAEventScheduler::Reset()
|
||||
fpMesh->Reset();
|
||||
}
|
||||
|
||||
void G4DNAEventScheduler::Initialize()
|
||||
void G4DNAEventScheduler::Initialize(const G4DNABoundingBox& boundingBox,
|
||||
G4int pixel)
|
||||
{
|
||||
if(!fInitialized)
|
||||
{
|
||||
fPixel = fInitialPixels;
|
||||
fpMesh = std::make_unique<G4DNAMesh>(fpMesh->GetBoundingBox(), fPixel);
|
||||
fPixel = pixel;
|
||||
fpMesh = std::make_unique<G4DNAMesh>(boundingBox, pixel);
|
||||
|
||||
if(!CheckingReactionRadius(fpMesh->GetResolution()))
|
||||
{
|
||||
G4String WarMessage = "resolution is not good : " +
|
||||
std::to_string(fpMesh->GetResolution() / nm);
|
||||
G4Exception("G4DNAEventScheduler::InitializeInMesh()", "WrongResolution",
|
||||
JustWarning, WarMessage);
|
||||
}
|
||||
|
||||
// Scavenger();
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,528 +29,513 @@
|
||||
//
|
||||
|
||||
#include "G4DNAPTBElasticModel.hh"
|
||||
|
||||
#include "G4DNAChampionElasticModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAMaterialManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4DNAPTBElasticModel::G4DNAPTBElasticModel(const G4String& applyToMaterial, const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
: G4VDNAModel(nam, applyToMaterial)
|
||||
G4DNAPTBElasticModel::G4DNAPTBElasticModel(const G4String& applyToMaterial,
|
||||
const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VDNAModel(nam, applyToMaterial)
|
||||
{
|
||||
fKillBelowEnergy = 10*eV; // will be override by the limits defined for each material
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "PTB Elastic model is constructed " << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNAPTBElasticModel::~G4DNAPTBElasticModel()
|
||||
{
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "PTB Elastic model is constructed : " << G4endl;
|
||||
}
|
||||
fpTHF = G4Material::GetMaterial("THF", false);
|
||||
fpPY = G4Material::GetMaterial("PY", false);
|
||||
fpPU = G4Material::GetMaterial("PU", false);
|
||||
fpTMP = G4Material::GetMaterial("TMP", false);
|
||||
fpG4_WATER = G4Material::GetMaterial("G4_WATER", false);
|
||||
fpBackbone_THF = G4Material::GetMaterial("backbone_THF", false);
|
||||
fpCytosine_PY = G4Material::GetMaterial("cytosine_PY", false);
|
||||
fpThymine_PY = G4Material::GetMaterial("thymine_PY", false);
|
||||
fpAdenine_PU = G4Material::GetMaterial("adenine_PU", false);
|
||||
fpBackbone_TMP = G4Material::GetMaterial("backbone_TMP", false);
|
||||
fpGuanine_PU = G4Material::GetMaterial("guanine_PU", false);
|
||||
fpN2 = G4Material::GetMaterial("N2", false);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAPTBElasticModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& /*cuts*/, G4ParticleChangeForGamma*)
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNAPTBElasticModel::Initialise()" << G4endl;
|
||||
if (isInitialised) {
|
||||
return;
|
||||
}
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Calling G4DNAPTBElasticModel::Initialise()" << G4endl;
|
||||
}
|
||||
if (particle != G4Electron::ElectronDefinition()) {
|
||||
std::ostringstream oss;
|
||||
oss << " Model is not applied for this particle " << particle->GetParticleName();
|
||||
G4Exception("G4DNAPTBElasticModel::G4DNAPTBElasticModel", "PTB001", FatalException,
|
||||
oss.str().c_str());
|
||||
}
|
||||
G4double scaleFactor = 1e-16 * cm * cm;
|
||||
//*******************************************************
|
||||
// Cross section data
|
||||
//*******************************************************
|
||||
|
||||
G4double scaleFactor = 1e-16*cm*cm;
|
||||
std::size_t index;
|
||||
// MPietrzak, adding paths for N2
|
||||
if (fpN2 != nullptr) {
|
||||
index = fpN2->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_N2",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_N2", scaleFactor);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1.02 * MeV);
|
||||
}
|
||||
// MPietrzak
|
||||
|
||||
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
|
||||
if (fpTHF != nullptr) {
|
||||
index = fpTHF->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_THF",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_THF", scaleFactor);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
|
||||
//*******************************************************
|
||||
// Cross section data
|
||||
//*******************************************************
|
||||
if (fpPY != nullptr) {
|
||||
index = fpPY->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PY",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
|
||||
if(particle == electronDef)
|
||||
{
|
||||
G4String particleName = particle->GetParticleName();
|
||||
if (fpPU != nullptr) {
|
||||
index = fpPU->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PU",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
|
||||
// MPietrzak, adding paths for N2
|
||||
AddCrossSectionData("N2",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_N2",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_N2",
|
||||
scaleFactor);
|
||||
SetLowELimit("N2", particleName, 10*eV);
|
||||
SetHighELimit("N2", particleName, 1.02*MeV);
|
||||
// MPietrzak
|
||||
if (fpTMP != nullptr) {
|
||||
index = fpTMP->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_TMP",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_TMP", scaleFactor);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
//????
|
||||
if (fpG4_WATER != nullptr) {
|
||||
index = fpG4_WATER->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e_champion",
|
||||
"dna/sigmadiff_cumulated_elastic_e_champion", scaleFactor);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
// DNA materials
|
||||
//
|
||||
if (fpBackbone_THF != nullptr) {
|
||||
index = fpBackbone_THF->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_THF",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_THF", scaleFactor * 33. / 30);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
|
||||
AddCrossSectionData("THF",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_THF",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_THF",
|
||||
scaleFactor);
|
||||
SetLowELimit("THF", particleName, 10*eV);
|
||||
SetHighELimit("THF", particleName, 1*keV);
|
||||
if (fpCytosine_PY != nullptr) {
|
||||
index = fpCytosine_PY->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PY",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor * 42. / 30);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
|
||||
AddCrossSectionData("PY",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_PY",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PY",
|
||||
scaleFactor);
|
||||
SetLowELimit("PY", particleName, 10*eV);
|
||||
SetHighELimit("PY", particleName, 1*keV);
|
||||
if (fpThymine_PY != nullptr) {
|
||||
index = fpThymine_PY->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PY",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor * 48. / 30);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
|
||||
AddCrossSectionData("PU",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_PU",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PU",
|
||||
scaleFactor);
|
||||
SetLowELimit("PU", particleName, 10*eV);
|
||||
SetHighELimit("PU", particleName, 1*keV);
|
||||
if (fpAdenine_PU != nullptr) {
|
||||
index = fpAdenine_PU->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PU",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor * 50. / 44);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
if (fpGuanine_PU != nullptr) {
|
||||
index = fpGuanine_PU->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PU",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor * 56. / 44);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
|
||||
AddCrossSectionData("TMP",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_TMP",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_TMP",
|
||||
scaleFactor);
|
||||
SetLowELimit("TMP", particleName, 10*eV);
|
||||
SetHighELimit("TMP", particleName, 1*keV);
|
||||
if (fpBackbone_TMP != nullptr) {
|
||||
index = fpBackbone_TMP->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_TMP",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_TMP", scaleFactor * 33. / 50);
|
||||
SetLowELimit(index, particle, 10 * eV);
|
||||
SetHighELimit(index, particle, 1 * keV);
|
||||
}
|
||||
|
||||
AddCrossSectionData("G4_WATER",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e_champion",
|
||||
"dna/sigmadiff_cumulated_elastic_e_champion",
|
||||
scaleFactor);
|
||||
SetLowELimit("G4_WATER", particleName, 10*eV);
|
||||
SetHighELimit("G4_WATER", particleName, 1*keV);
|
||||
|
||||
// DNA materials
|
||||
//
|
||||
AddCrossSectionData("backbone_THF",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_THF",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_THF",
|
||||
scaleFactor*33./30);
|
||||
SetLowELimit("backbone_THF", particleName, 10*eV);
|
||||
SetHighELimit("backbone_THF", particleName, 1*keV);
|
||||
|
||||
AddCrossSectionData("cytosine_PY",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_PY",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PY",
|
||||
scaleFactor*42./30);
|
||||
SetLowELimit("cytosine_PY", particleName, 10*eV);
|
||||
SetHighELimit("cytosine_PY", particleName, 1*keV);
|
||||
|
||||
AddCrossSectionData("thymine_PY",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_PY",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PY",
|
||||
scaleFactor*48./30);
|
||||
SetLowELimit("thymine_PY", particleName, 10*eV);
|
||||
SetHighELimit("thymine_PY", particleName, 1*keV);
|
||||
|
||||
AddCrossSectionData("adenine_PU",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_PU",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PU",
|
||||
scaleFactor*50./44);
|
||||
SetLowELimit("adenine_PU", particleName, 10*eV);
|
||||
SetHighELimit("adenine_PU", particleName, 1*keV);
|
||||
|
||||
AddCrossSectionData("guanine_PU",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_PU",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_PU",
|
||||
scaleFactor*56./44);
|
||||
SetLowELimit("guanine_PU", particleName, 10*eV);
|
||||
SetHighELimit("guanine_PU", particleName, 1*keV);
|
||||
|
||||
AddCrossSectionData("backbone_TMP",
|
||||
particleName,
|
||||
"dna/sigma_elastic_e-_PTB_TMP",
|
||||
"dna/sigmadiff_cumulated_elastic_e-_PTB_TMP",
|
||||
scaleFactor*33./50);
|
||||
SetLowELimit("backbone_TMP", particleName, 10*eV);
|
||||
SetHighELimit("backbone_TMP", particleName, 1*keV);
|
||||
}
|
||||
|
||||
//*******************************************************
|
||||
if (!G4DNAMaterialManager::Instance()->IsLocked()) {
|
||||
// Load the data
|
||||
//*******************************************************
|
||||
|
||||
LoadCrossSectionData(particle->GetParticleName() );
|
||||
|
||||
//*******************************************************
|
||||
// Verbose output
|
||||
//*******************************************************
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for PTB Elastic model" << G4endl;
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "PTB Elastic model is initialized " << G4endl;
|
||||
LoadCrossSectionData(particle);
|
||||
G4DNAMaterialManager::Instance()->SetMasterDataModel(DNAModelType::fDNAElastics, this);
|
||||
fpModelData = this;
|
||||
}
|
||||
else {
|
||||
auto dataModel = dynamic_cast<G4DNAPTBElasticModel*>(
|
||||
G4DNAMaterialManager::Instance()->GetModel(DNAModelType::fDNAElastics));
|
||||
if (dataModel == nullptr) {
|
||||
G4cout << "G4DNAPTBElasticModel::Initialise:: not good modelData" << G4endl;
|
||||
G4Exception("G4DNAPTBElasticModel::Initialise", "PTB0006", FatalException,
|
||||
"not good modelData");
|
||||
}
|
||||
else {
|
||||
fpModelData = dataModel;
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel > 2) {
|
||||
G4cout << "Loaded cross section files for PTB Elastic model" << G4endl;
|
||||
}
|
||||
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAPTBElasticModel::ReadDiffCSFile(const G4String& materialName,
|
||||
const G4String& particleName,
|
||||
const G4String& file,
|
||||
const G4double)
|
||||
void G4DNAPTBElasticModel::ReadDiffCSFile(const std::size_t& materialName,
|
||||
const G4ParticleDefinition* particleName,
|
||||
const G4String& file, const G4double&)
|
||||
{
|
||||
// Method to read and save the information contained within the differential cross section files.
|
||||
// This method is not yet standard.
|
||||
// Method to read and save the information contained within the differential cross section files.
|
||||
// This method is not yet standard.
|
||||
|
||||
// get the path of the G4LEDATA data folder
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
// if it is not found then quit and print error message
|
||||
if(!path)
|
||||
{
|
||||
G4Exception("G4DNAPTBElasticModel::ReadAllDiffCSFiles","em0006",
|
||||
FatalException,"G4LEDATA environment variable not set.");
|
||||
return;
|
||||
// get the path of the G4LEDATA data folder
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
// if it is not found then quit and print error message
|
||||
if (!path) {
|
||||
G4Exception("G4DNAPTBElasticModel::ReadAllDiffCSFiles", "em0006", FatalException,
|
||||
"G4LEDATA environment variable not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
// build the fullFileName path of the data file
|
||||
std::ostringstream fullFileName;
|
||||
fullFileName << path << "/" << file << ".dat";
|
||||
|
||||
// open the data file
|
||||
std::ifstream diffCrossSection(fullFileName.str().c_str());
|
||||
// error if file is not there
|
||||
std::stringstream endPath;
|
||||
if (!diffCrossSection) {
|
||||
endPath << "Missing data file: " << file;
|
||||
G4Exception("G4DNAPTBElasticModel::Initialise", "em0003", FatalException,
|
||||
endPath.str().c_str());
|
||||
}
|
||||
|
||||
tValuesVec[materialName][particleName].push_back(0.);
|
||||
|
||||
G4String line;
|
||||
|
||||
// read the file line by line until we reach the end of file point
|
||||
while (std::getline(diffCrossSection, line)) {
|
||||
// check if the line is comment or empty
|
||||
//
|
||||
std::istringstream testIss(line);
|
||||
G4String test;
|
||||
testIss >> test;
|
||||
// check first caracter to determine if following information is data or comments
|
||||
if (test == "#") {
|
||||
// skip the line by beginning a new while loop.
|
||||
continue;
|
||||
}
|
||||
// check if line is empty
|
||||
else if (line.empty()) {
|
||||
// skip the line by beginning a new while loop.
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// end of the check
|
||||
|
||||
// transform the line into a iss
|
||||
std::istringstream iss(line);
|
||||
|
||||
// Variables to be filled by the input file
|
||||
G4double tDummy;
|
||||
G4double eDummy;
|
||||
|
||||
// fill the variables with the content of the line
|
||||
iss >> tDummy >> eDummy;
|
||||
|
||||
// SI : mandatory Vecm initialization
|
||||
|
||||
// Fill two vectors contained in maps of types:
|
||||
// [materialName][particleName]=vector
|
||||
// [materialName][particleName][T]=vector
|
||||
// to list all the incident energies (tValues) and all the output energies (eValues) within the
|
||||
// file
|
||||
//
|
||||
// Check if we already have the current T value in the vector.
|
||||
// If not then add it
|
||||
if (tDummy != tValuesVec[materialName][particleName].back()) {
|
||||
// Add the current T value
|
||||
tValuesVec[materialName][particleName].push_back(tDummy);
|
||||
// Make it correspond to a default zero E value
|
||||
eValuesVect[materialName][particleName][tDummy].push_back(0.);
|
||||
}
|
||||
|
||||
// build the fullFileName path of the data file
|
||||
std::ostringstream fullFileName;
|
||||
fullFileName << path <<"/"<< file<<".dat";
|
||||
// Put the differential cross section value of the input file within the diffCrossSectionData
|
||||
// map
|
||||
iss >> diffCrossSectionData[materialName][particleName][tDummy][eDummy];
|
||||
|
||||
// open the data file
|
||||
std::ifstream diffCrossSection (fullFileName.str().c_str());
|
||||
// error if file is not there
|
||||
std::stringstream endPath;
|
||||
if (!diffCrossSection)
|
||||
{
|
||||
endPath << "Missing data file: "<<file;
|
||||
G4Exception("G4DNAPTBElasticModel::Initialise","em0003",
|
||||
FatalException, endPath.str().c_str());
|
||||
}
|
||||
|
||||
tValuesVec[materialName][particleName].push_back(0.);
|
||||
|
||||
G4String line;
|
||||
|
||||
// read the file line by line until we reach the end of file point
|
||||
while(std::getline(diffCrossSection, line))
|
||||
{
|
||||
// check if the line is comment or empty
|
||||
//
|
||||
std::istringstream testIss(line);
|
||||
G4String test;
|
||||
testIss >> test;
|
||||
// check first caracter to determine if following information is data or comments
|
||||
if(test=="#")
|
||||
{
|
||||
// skip the line by beginning a new while loop.
|
||||
continue;
|
||||
}
|
||||
// check if line is empty
|
||||
else if(line.empty())
|
||||
{
|
||||
// skip the line by beginning a new while loop.
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// end of the check
|
||||
|
||||
// transform the line into a iss
|
||||
std::istringstream iss(line);
|
||||
|
||||
// Variables to be filled by the input file
|
||||
double tDummy;
|
||||
double eDummy;
|
||||
|
||||
// fill the variables with the content of the line
|
||||
iss>>tDummy>>eDummy;
|
||||
|
||||
// SI : mandatory Vecm initialization
|
||||
|
||||
// Fill two vectors contained in maps of types:
|
||||
// [materialName][particleName]=vector
|
||||
// [materialName][particleName][T]=vector
|
||||
// to list all the incident energies (tValues) and all the output energies (eValues) within the file
|
||||
//
|
||||
// Check if we already have the current T value in the vector.
|
||||
// If not then add it
|
||||
if (tDummy != tValuesVec[materialName][particleName].back())
|
||||
{
|
||||
// Add the current T value
|
||||
tValuesVec[materialName][particleName].push_back(tDummy);
|
||||
|
||||
// Make it correspond to a default zero E value
|
||||
eValuesVect[materialName][particleName][tDummy].push_back(0.);
|
||||
}
|
||||
|
||||
// Put the differential cross section value of the input file within the diffCrossSectionData map
|
||||
iss>>diffCrossSectionData[materialName][particleName][tDummy][eDummy];
|
||||
|
||||
// If the current E value (eDummy) is different from the one already registered in the eVector then add it to the vector
|
||||
if (eDummy != eValuesVect[materialName][particleName][tDummy].back()) eValuesVect[materialName][particleName][tDummy].push_back(eDummy);
|
||||
// If the current E value (eDummy) is different from the one already registered in the eVector
|
||||
// then add it to the vector
|
||||
if (eDummy != eValuesVect[materialName][particleName][tDummy].back()) {
|
||||
eValuesVect[materialName][particleName][tDummy].push_back(eDummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAPTBElasticModel::CrossSectionPerVolume(const G4Material* /*material*/,
|
||||
const G4String& materialName,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin,
|
||||
G4double /*emin*/,
|
||||
G4double /*emax*/)
|
||||
G4double G4DNAPTBElasticModel::CrossSectionPerVolume(const G4Material* pMaterial,
|
||||
const G4ParticleDefinition* p, G4double ekin,
|
||||
G4double /*emin*/, G4double /*emax*/)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNAPTBElasticModel" << G4endl;
|
||||
if (verboseLevel > 3){
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNAPTBElasticModel" << G4endl;
|
||||
}
|
||||
|
||||
// Get the name of the current particle
|
||||
const G4String& particleName = p->GetParticleName();
|
||||
// Get the name of the current particle
|
||||
const G4String& particleName = p->GetParticleName();
|
||||
const std::size_t& materialID = pMaterial->GetIndex();
|
||||
|
||||
// set killBelowEnergy value for current material
|
||||
fKillBelowEnergy = GetLowELimit(materialName, particleName);
|
||||
// set killBelowEnergy value for current material
|
||||
fKillBelowEnergy = fpModelData->GetLowELimit(materialID, p);
|
||||
// initialise the return value (cross section) to zero
|
||||
G4double sigma = 0.;
|
||||
|
||||
// initialise the return value (cross section) to zero
|
||||
G4double sigma(0);
|
||||
|
||||
// check if we are below the high energy limit
|
||||
if (ekin < GetHighELimit(materialName, particleName) )
|
||||
{
|
||||
// This is used to kill the particle if its kinetic energy is below fKillBelowEnergy.
|
||||
// If the energy is lower then we return a maximum cross section and thus the SampleSecondaries method will be called for sure.
|
||||
// SampleSecondaries will remove the particle from the simulation.
|
||||
//
|
||||
//SI : XS must not be zero otherwise sampling of secondaries method ignored
|
||||
if (ekin < fKillBelowEnergy) return DBL_MAX;
|
||||
|
||||
// Get the tables with the cross section data
|
||||
TableMapData* tableData = GetTableData();
|
||||
|
||||
// Retrieve the cross section value
|
||||
sigma = (*tableData)[materialName][particleName]->FindValue(ekin);
|
||||
// check if we are below the high energy limit
|
||||
if (ekin < fpModelData->GetHighELimit(materialID, p)) {
|
||||
// This is used to kill the particle if its kinetic energy is below fKillBelowEnergy.
|
||||
// If the energy is lower then we return a maximum cross section and thus the SampleSecondaries
|
||||
// method will be called for sure. SampleSecondaries will remove the particle from the
|
||||
// simulation.
|
||||
//
|
||||
// SI : XS must not be zero otherwise sampling of secondaries method ignored
|
||||
if (ekin < fKillBelowEnergy) {
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "°°° G4DNAPTBElasticModel - XS INFO START" << G4endl;
|
||||
G4cout << "°°° Kinetic energy(eV)=" << ekin/eV << " particle : " << particleName << G4endl;
|
||||
G4cout << "°°° Cross section per molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << "°°° G4DNAPTBElasticModel - XS INFO END" << G4endl;
|
||||
// Get the tables with the cross section data
|
||||
auto tableData = fpModelData->GetData();
|
||||
if ((*tableData)[materialID][p] == nullptr) {
|
||||
G4Exception("G4DNAPTBElasticModel::CrossSectionPerVolume", "em00236", FatalException,
|
||||
"No model is registered");
|
||||
}
|
||||
// Retrieve the cross section value
|
||||
sigma = (*tableData)[materialID][p]->FindValue(ekin);
|
||||
}
|
||||
|
||||
// Return the cross section
|
||||
return sigma;
|
||||
if (verboseLevel > 2) {
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "°°° G4DNAPTBElasticModel - XS INFO START" << G4endl;
|
||||
G4cout << "°°° Kinetic energy(eV)=" << ekin / eV << " particle : " << particleName << G4endl;
|
||||
G4cout << "°°° Cross section per molecule (cm^2)=" << sigma / cm / cm << G4endl;
|
||||
G4cout << "°°° G4DNAPTBElasticModel - XS INFO END" << G4endl;
|
||||
}
|
||||
|
||||
// Return the cross section
|
||||
auto MolDensity =
|
||||
(*G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(pMaterial))[materialID];
|
||||
return sigma * MolDensity;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAPTBElasticModel::SampleSecondaries(std::vector<G4DynamicParticle*>* /*fvect*/,
|
||||
const G4MaterialCutsCouple* /*couple*/,
|
||||
const G4String& materialName,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicElectron,
|
||||
G4ParticleChangeForGamma* particleChangeForGamma,
|
||||
G4double /*tmin*/,
|
||||
G4double /*tmax*/)
|
||||
G4double /*tmin*/, G4double /*tmax*/)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4DNAPTBElasticModel" << G4endl;
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling SampleSecondaries() of G4DNAPTBElasticModel" << G4endl;
|
||||
}
|
||||
|
||||
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
|
||||
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
|
||||
const std::size_t& materialID = couple->GetIndex();
|
||||
auto p = aDynamicElectron->GetParticleDefinition();
|
||||
|
||||
const G4String& particleName = aDynamicElectron->GetParticleDefinition()->GetParticleName();
|
||||
// set killBelowEnergy value for material
|
||||
fKillBelowEnergy = fpModelData->GetLowELimit(materialID, p);
|
||||
|
||||
// set killBelowEnergy value for material
|
||||
fKillBelowEnergy = GetLowELimit(materialName, particleName);
|
||||
// If the particle (electron here) energy is below the kill limit then we remove it from the
|
||||
// simulation
|
||||
if (electronEnergy0 < fKillBelowEnergy) {
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(0.);
|
||||
fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(electronEnergy0);
|
||||
}
|
||||
// If we are above the kill limite and below the high limit then we proceed
|
||||
else if (electronEnergy0 >= fKillBelowEnergy && electronEnergy0 < GetHighELimit(materialID, p)) {
|
||||
// Random sampling of the cosTheta
|
||||
G4double cosTheta = fpModelData->RandomizeCosTheta(electronEnergy0, materialID);
|
||||
|
||||
// If the particle (electron here) energy is below the kill limit then we remove it from the simulation
|
||||
if (electronEnergy0 < fKillBelowEnergy)
|
||||
{
|
||||
particleChangeForGamma->SetProposedKineticEnergy(0.);
|
||||
particleChangeForGamma->ProposeTrackStatus(fStopAndKill);
|
||||
particleChangeForGamma->ProposeLocalEnergyDeposit(electronEnergy0);
|
||||
}
|
||||
// If we are above the kill limite and below the high limit then we proceed
|
||||
else if (electronEnergy0>= fKillBelowEnergy && electronEnergy0 < GetHighELimit(materialName, particleName) )
|
||||
{
|
||||
// Random sampling of the cosTheta
|
||||
G4double cosTheta = RandomizeCosTheta(electronEnergy0, materialName);
|
||||
// Random sampling of phi
|
||||
G4double phi = 2. * CLHEP::pi * G4UniformRand();
|
||||
|
||||
// Random sampling of phi
|
||||
G4double phi = 2. * pi * G4UniformRand();
|
||||
auto zVers = aDynamicElectron->GetMomentumDirection();
|
||||
auto xVers = zVers.orthogonal();
|
||||
auto yVers = zVers.cross(xVers);
|
||||
|
||||
G4ThreeVector zVers = aDynamicElectron->GetMomentumDirection();
|
||||
G4ThreeVector xVers = zVers.orthogonal();
|
||||
G4ThreeVector yVers = zVers.cross(xVers);
|
||||
G4double xDir = std::sqrt(1. - cosTheta * cosTheta);
|
||||
G4double yDir = xDir;
|
||||
xDir *= std::cos(phi);
|
||||
yDir *= std::sin(phi);
|
||||
|
||||
G4double xDir = std::sqrt(1. - cosTheta*cosTheta);
|
||||
G4double yDir = xDir;
|
||||
xDir *= std::cos(phi);
|
||||
yDir *= std::sin(phi);
|
||||
// Particle direction after ModelInterface
|
||||
G4ThreeVector zPrikeVers((xDir * xVers + yDir * yVers + cosTheta * zVers));
|
||||
|
||||
// Particle direction after ModelInterface
|
||||
G4ThreeVector zPrikeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
|
||||
// Give the new direction
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(zPrikeVers.unit());
|
||||
|
||||
// Give the new direction
|
||||
particleChangeForGamma->ProposeMomentumDirection(zPrikeVers.unit()) ;
|
||||
|
||||
// Update the energy which does not change here
|
||||
particleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
|
||||
}
|
||||
// Update the energy which does not change here
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAPTBElasticModel::Theta
|
||||
(G4ParticleDefinition * particleDefinition, G4double k, G4double integrDiff, const G4String& materialName)
|
||||
{
|
||||
G4double theta = 0.;
|
||||
G4double valueT1 = 0;
|
||||
G4double valueT2 = 0;
|
||||
G4double valueE21 = 0;
|
||||
G4double valueE22 = 0;
|
||||
G4double valueE12 = 0;
|
||||
G4double valueE11 = 0;
|
||||
G4double xs11 = 0;
|
||||
G4double xs12 = 0;
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
G4String particleName = particleDefinition->GetParticleName();
|
||||
G4double G4DNAPTBElasticModel::Theta(const G4ParticleDefinition* p, G4double k, G4double integrDiff,
|
||||
const std::size_t& materialID)
|
||||
{
|
||||
G4double theta = 0.;
|
||||
G4double valueT1 = 0;
|
||||
G4double valueT2 = 0;
|
||||
G4double valueE21 = 0;
|
||||
G4double valueE22 = 0;
|
||||
G4double valueE12 = 0;
|
||||
G4double valueE11 = 0;
|
||||
G4double xs11 = 0;
|
||||
G4double xs12 = 0;
|
||||
G4double xs21 = 0;
|
||||
G4double xs22 = 0;
|
||||
if (p == G4Electron::ElectronDefinition()) {
|
||||
auto t2 =
|
||||
std::upper_bound(tValuesVec[materialID][p].begin(), tValuesVec[materialID][p].end(), k);
|
||||
auto t1 = t2 - 1;
|
||||
|
||||
if (particleDefinition == G4Electron::ElectronDefinition())
|
||||
{
|
||||
std::vector<double>::iterator t2 = std::upper_bound(tValuesVec[materialName][particleName].begin(),tValuesVec[materialName][particleName].end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
auto e12 = std::upper_bound(eValuesVect[materialID][p][(*t1)].begin(),
|
||||
eValuesVect[materialID][p][(*t1)].end(), integrDiff);
|
||||
auto e11 = e12 - 1;
|
||||
|
||||
std::vector<double>::iterator e12 = std::upper_bound(eValuesVect[materialName][particleName][(*t1)].begin(),eValuesVect[materialName][particleName][(*t1)].end(), integrDiff);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
auto e22 = std::upper_bound(eValuesVect[materialID][p][(*t2)].begin(),
|
||||
eValuesVect[materialID][p][(*t2)].end(), integrDiff);
|
||||
auto e21 = e22 - 1;
|
||||
|
||||
std::vector<double>::iterator e22 = std::upper_bound(eValuesVect[materialName][particleName][(*t2)].begin(),eValuesVect[materialName][particleName][(*t2)].end(), integrDiff);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
valueT1 = *t1;
|
||||
valueT2 = *t2;
|
||||
valueE21 = *e21;
|
||||
valueE22 = *e22;
|
||||
valueE12 = *e12;
|
||||
valueE11 = *e11;
|
||||
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
xs11 = diffCrossSectionData[materialID][p][valueT1][valueE11];
|
||||
xs12 = diffCrossSectionData[materialID][p][valueT1][valueE12];
|
||||
xs21 = diffCrossSectionData[materialID][p][valueT2][valueE21];
|
||||
xs22 = diffCrossSectionData[materialID][p][valueT2][valueE22];
|
||||
}
|
||||
|
||||
xs11 = diffCrossSectionData[materialName][particleName][valueT1][valueE11];
|
||||
xs12 = diffCrossSectionData[materialName][particleName][valueT1][valueE12];
|
||||
xs21 = diffCrossSectionData[materialName][particleName][valueT2][valueE21];
|
||||
xs22 = diffCrossSectionData[materialName][particleName][valueT2][valueE22];
|
||||
}
|
||||
if (xs11 == 0 && xs12 == 0 && xs21 == 0 && xs22 == 0) {
|
||||
return (0.);
|
||||
}
|
||||
|
||||
if (xs11==0 && xs12==0 && xs21==0 && xs22==0) return (0.);
|
||||
theta = QuadInterpolator(valueE11, valueE12, valueE21, valueE22, xs11, xs12, xs21, xs22, valueT1,
|
||||
valueT2, k, integrDiff);
|
||||
|
||||
theta = QuadInterpolator ( valueE11, valueE12,
|
||||
valueE21, valueE22,
|
||||
xs11, xs12,
|
||||
xs21, xs22,
|
||||
valueT1, valueT2,
|
||||
k, integrDiff );
|
||||
|
||||
return theta;
|
||||
return theta;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAPTBElasticModel::LinLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double G4DNAPTBElasticModel::LinLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double d1 = std::log(xs1);
|
||||
G4double d2 = std::log(xs2);
|
||||
G4double value = std::exp(d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
|
||||
return value;
|
||||
G4double d1 = std::log(xs1);
|
||||
G4double d2 = std::log(xs2);
|
||||
G4double value = std::exp(d1 + (d2 - d1) * (e - e1) / (e2 - e1));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAPTBElasticModel::LinLinInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double G4DNAPTBElasticModel::LinLinInterpolate(G4double e1, G4double e2, G4double e, G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double d1 = xs1;
|
||||
G4double d2 = xs2;
|
||||
G4double value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
|
||||
return value;
|
||||
G4double d1 = xs1;
|
||||
G4double d2 = xs2;
|
||||
G4double value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAPTBElasticModel::LogLogInterpolate(G4double e1,
|
||||
G4double e2,
|
||||
G4double e,
|
||||
G4double xs1,
|
||||
G4double G4DNAPTBElasticModel::LogLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1,
|
||||
G4double xs2)
|
||||
{
|
||||
G4double a = (std::log10(xs2)-std::log10(xs1)) / (std::log10(e2)-std::log10(e1));
|
||||
G4double b = std::log10(xs2) - a*std::log10(e2);
|
||||
G4double sigma = a*std::log10(e) + b;
|
||||
G4double value = (std::pow(10.,sigma));
|
||||
return value;
|
||||
G4double a = (std::log10(xs2) - std::log10(xs1)) / (std::log10(e2) - std::log10(e1));
|
||||
G4double b = std::log10(xs2) - a * std::log10(e2);
|
||||
G4double sigma = a * std::log10(e) + b;
|
||||
G4double value = (std::pow(10., sigma));
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAPTBElasticModel::QuadInterpolator(G4double e11, G4double e12,
|
||||
G4double e21, G4double e22,
|
||||
G4double xs11, G4double xs12,
|
||||
G4double xs21, G4double xs22,
|
||||
G4double t1, G4double t2,
|
||||
G4double t, G4double e)
|
||||
G4double G4DNAPTBElasticModel::QuadInterpolator(G4double e11, G4double e12, G4double e21,
|
||||
G4double e22, G4double xs11, G4double xs12,
|
||||
G4double xs21, G4double xs22, G4double t1,
|
||||
G4double t2, G4double t, G4double e)
|
||||
{
|
||||
// Log-Log
|
||||
/*
|
||||
G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
// Log-Log
|
||||
/*
|
||||
G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
|
||||
|
||||
// Lin-Log
|
||||
G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
// Lin-Log
|
||||
G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
*/
|
||||
|
||||
// Lin-Lin
|
||||
G4double interpolatedvalue1 = LinLinInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLinInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLinInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
// Lin-Lin
|
||||
G4double interpolatedvalue1 = LinLinInterpolate(e11, e12, e, xs11, xs12);
|
||||
G4double interpolatedvalue2 = LinLinInterpolate(e21, e22, e, xs21, xs22);
|
||||
G4double value = LinLinInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAPTBElasticModel::RandomizeCosTheta(G4double k, const G4String& materialName)
|
||||
G4double G4DNAPTBElasticModel::RandomizeCosTheta(const G4double& k, const std::size_t& materialID)
|
||||
{
|
||||
G4double integrdiff=0;
|
||||
G4double uniformRand=G4UniformRand();
|
||||
integrdiff = uniformRand;
|
||||
G4double integrdiff = 0;
|
||||
G4double uniformRand = G4UniformRand();
|
||||
integrdiff = uniformRand;
|
||||
|
||||
G4double theta=0.;
|
||||
G4double cosTheta=0.;
|
||||
theta = Theta(G4Electron::ElectronDefinition(),k/eV,integrdiff, materialName);
|
||||
G4double theta = 0.;
|
||||
G4double cosTheta = 0.;
|
||||
theta = Theta(G4Electron::ElectronDefinition(), k / eV, integrdiff, materialID);
|
||||
|
||||
cosTheta= std::cos(theta*pi/180);
|
||||
cosTheta = std::cos(theta * CLHEP::pi / 180);
|
||||
|
||||
return cosTheta;
|
||||
return cosTheta;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -29,316 +29,316 @@
|
||||
//
|
||||
|
||||
#include "G4DNAPTBExcitationModel.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAMaterialManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4DNAPTBExcitationModel::G4DNAPTBExcitationModel(const G4String& applyToMaterial, const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
: G4VDNAModel(nam, applyToMaterial)
|
||||
G4DNAPTBExcitationModel::G4DNAPTBExcitationModel(const G4String& applyToMaterial,
|
||||
const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VDNAModel(nam, applyToMaterial)
|
||||
{
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale:
|
||||
// 0 = nothing
|
||||
// 1 = warning for energy non-conservation
|
||||
// 2 = details of energy budget
|
||||
// 3 = calculation of cross sections, file openings, sampling of atoms
|
||||
// 4 = entering in methods
|
||||
fpTHF = G4Material::GetMaterial("THF", false);
|
||||
fpPY = G4Material::GetMaterial("PY", false);
|
||||
fpPU = G4Material::GetMaterial("PU", false);
|
||||
fpTMP = G4Material::GetMaterial("TMP", false);
|
||||
fpG4_WATER = G4Material::GetMaterial("G4_WATER", false);
|
||||
fpBackbone_THF = G4Material::GetMaterial("backbone_THF", false);
|
||||
fpCytosine_PY = G4Material::GetMaterial("cytosine_PY", false);
|
||||
fpThymine_PY = G4Material::GetMaterial("thymine_PY", false);
|
||||
fpAdenine_PU = G4Material::GetMaterial("adenine_PU", false);
|
||||
fpBackbone_TMP = G4Material::GetMaterial("backbone_TMP", false);
|
||||
fpGuanine_PU = G4Material::GetMaterial("guanine_PU", false);
|
||||
fpN2 = G4Material::GetMaterial("N2", false);
|
||||
// initialisation of mean energy loss for each material
|
||||
|
||||
// initialisation of mean energy loss for each material
|
||||
tableMeanEnergyPTB["THF"] = 8.01*eV;
|
||||
tableMeanEnergyPTB["PY"] = 7.61*eV;
|
||||
tableMeanEnergyPTB["PU"] = 7.61*eV;
|
||||
tableMeanEnergyPTB["TMP"] = 8.01*eV;
|
||||
if (fpTHF != nullptr) {
|
||||
fTableMeanEnergyPTB[fpTHF->GetIndex()] = 8.01 * eV;
|
||||
}
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "PTB excitation model is constructed " << G4endl;
|
||||
}
|
||||
}
|
||||
if (fpPY != nullptr) {
|
||||
fTableMeanEnergyPTB[fpPY->GetIndex()] = 7.61 * eV;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNAPTBExcitationModel::~G4DNAPTBExcitationModel()
|
||||
{
|
||||
if (fpPU != nullptr) {
|
||||
fTableMeanEnergyPTB[fpPU->GetIndex()] = 7.61 * eV;
|
||||
}
|
||||
if (fpTMP) {
|
||||
fTableMeanEnergyPTB[fpTMP->GetIndex()] = 8.01 * eV;
|
||||
}
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "PTB excitation model is constructed " << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAPTBExcitationModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& /*cuts*/, G4ParticleChangeForGamma*)
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNAPTBExcitationModel::Initialise()" << G4endl;
|
||||
if (isInitialised) {
|
||||
return;
|
||||
}
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
G4cout << "Calling G4DNAPTBExcitationModel::Initialise()" << G4endl;
|
||||
}
|
||||
|
||||
G4double scaleFactor = 1e-16*cm*cm;
|
||||
G4double scaleFactorBorn = (1.e-22 / 3.343) * m*m;
|
||||
if (particle != G4Electron::ElectronDefinition()) {
|
||||
std::ostringstream oss;
|
||||
oss << " Model is not applied for this particle " << particle->GetParticleName();
|
||||
G4Exception("G4DNAPTBExcitationModel::Initialise", "PTB001", FatalException, oss.str().c_str());
|
||||
}
|
||||
|
||||
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
|
||||
G4double scaleFactor = 1e-16 * cm * cm;
|
||||
G4double scaleFactorBorn = (1.e-22 / 3.343) * m * m;
|
||||
|
||||
//*******************************************************
|
||||
// Cross section data
|
||||
//*******************************************************
|
||||
//*******************************************************
|
||||
// Cross section data
|
||||
//*******************************************************
|
||||
std::size_t index;
|
||||
if (fpTHF != nullptr) {
|
||||
index = fpTHF->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_THF", scaleFactor);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
if (fpPY != nullptr) {
|
||||
index = fpPY->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PY", scaleFactor);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
|
||||
if(particle == electronDef)
|
||||
{
|
||||
G4String particleName = particle->GetParticleName();
|
||||
if (fpPU != nullptr) {
|
||||
index = fpPU->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PU", scaleFactor);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
|
||||
AddCrossSectionData("THF",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_THF",
|
||||
scaleFactor);
|
||||
SetLowELimit("THF", particleName, 9.*eV);
|
||||
SetHighELimit("THF", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("PY",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_PY",
|
||||
scaleFactor);
|
||||
SetLowELimit("PY", particleName, 9.*eV);
|
||||
SetHighELimit("PY", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("PU",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_PU",
|
||||
scaleFactor);
|
||||
SetLowELimit("PU", particleName, 9.*eV);
|
||||
SetHighELimit("PU", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("TMP",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_TMP",
|
||||
scaleFactor);
|
||||
SetLowELimit("TMP", particleName, 9.*eV);
|
||||
SetHighELimit("TMP", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("G4_WATER",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e_born",
|
||||
scaleFactorBorn);
|
||||
SetLowELimit("G4_WATER", particleName, 9.*eV);
|
||||
SetHighELimit("G4_WATER", particleName, 1.*keV);
|
||||
|
||||
// DNA materials
|
||||
//
|
||||
AddCrossSectionData("backbone_THF",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_THF",
|
||||
scaleFactor*33./30);
|
||||
SetLowELimit("backbone_THF", particleName, 9.*eV);
|
||||
SetHighELimit("backbone_THF", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("cytosine_PY",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_PY",
|
||||
scaleFactor*42./30);
|
||||
SetLowELimit("cytosine_PY", particleName, 9.*eV);
|
||||
SetHighELimit("cytosine_PY", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("thymine_PY",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_PY",
|
||||
scaleFactor*48./30);
|
||||
SetLowELimit("thymine_PY", particleName, 9.*eV);
|
||||
SetHighELimit("thymine_PY", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("adenine_PU",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_PU",
|
||||
scaleFactor*50./44);
|
||||
SetLowELimit("adenine_PU", particleName, 9.*eV);
|
||||
SetHighELimit("adenine_PU", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("guanine_PU",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_PU",
|
||||
scaleFactor*56./44);
|
||||
SetLowELimit("guanine_PU", particleName, 9.*eV);
|
||||
SetHighELimit("guanine_PU", particleName, 1.*keV);
|
||||
|
||||
AddCrossSectionData("backbone_TMP",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_TMP",
|
||||
scaleFactor*33./50);
|
||||
SetLowELimit("backbone_TMP", particleName, 9.*eV);
|
||||
SetHighELimit("backbone_TMP", particleName, 1.*keV);
|
||||
|
||||
// MPietrzak, adding paths for N2
|
||||
AddCrossSectionData("N2",
|
||||
particleName,
|
||||
"dna/sigma_excitation_e-_PTB_N2",
|
||||
scaleFactor);
|
||||
SetLowELimit("N2", particleName, 13.*eV);
|
||||
SetHighELimit("N2", particleName, 1.02*MeV);
|
||||
// MPietrzak
|
||||
}
|
||||
|
||||
//*******************************************************
|
||||
if (fpTMP != nullptr) {
|
||||
index = fpTMP->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_TMP", scaleFactor);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
if (fpG4_WATER != nullptr) {
|
||||
index = fpG4_WATER->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e_born", scaleFactorBorn);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
// DNA materials
|
||||
//
|
||||
if (fpBackbone_THF != nullptr) {
|
||||
index = fpBackbone_THF->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_THF", scaleFactor * 33. / 30);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
if (fpCytosine_PY != nullptr) {
|
||||
index = fpCytosine_PY->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PY", scaleFactor * 42. / 30);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
if (fpThymine_PY != nullptr) {
|
||||
index = fpThymine_PY->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PY", scaleFactor * 48. / 30);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
if (fpAdenine_PU != nullptr) {
|
||||
index = fpAdenine_PU->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PU", scaleFactor * 50. / 44);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
if (fpGuanine_PU != nullptr) {
|
||||
index = fpGuanine_PU->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_PU", scaleFactor * 56. / 44);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
if (fpBackbone_TMP != nullptr) {
|
||||
index = fpBackbone_TMP->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_TMP", scaleFactor * 33. / 50);
|
||||
SetLowELimit(index, particle, 9. * eV);
|
||||
SetHighELimit(index, particle, 1. * keV);
|
||||
}
|
||||
// MPietrzak, adding paths for N2
|
||||
if (fpN2 != nullptr) {
|
||||
index = fpN2->GetIndex();
|
||||
AddCrossSectionData(index, particle, "dna/sigma_excitation_e-_PTB_N2", scaleFactor);
|
||||
SetLowELimit(index, particle, 13. * eV);
|
||||
SetHighELimit(index, particle, 1.02 * MeV);
|
||||
}
|
||||
if (!G4DNAMaterialManager::Instance()->IsLocked()) {
|
||||
// Load data
|
||||
//*******************************************************
|
||||
|
||||
LoadCrossSectionData(particle->GetParticleName() );
|
||||
|
||||
//*******************************************************
|
||||
// Verbose
|
||||
//*******************************************************
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "PTB excitation model is initialized " << G4endl;
|
||||
LoadCrossSectionData(particle);
|
||||
G4DNAMaterialManager::Instance()->SetMasterDataModel(DNAModelType::fDNAExcitation, this);
|
||||
fpModelData = this;
|
||||
}
|
||||
else {
|
||||
auto dataModel = dynamic_cast<G4DNAPTBExcitationModel*>(
|
||||
G4DNAMaterialManager::Instance()->GetModel(DNAModelType::fDNAExcitation));
|
||||
if (dataModel == nullptr) {
|
||||
G4cout << "G4DNAPTBExcitationModel::Initialise:: not good modelData" << G4endl;
|
||||
G4Exception("G4DNAPTBExcitationModel::Initialise", "PTB0006", FatalException,
|
||||
"not good modelData");
|
||||
}
|
||||
else {
|
||||
fpModelData = dataModel;
|
||||
}
|
||||
}
|
||||
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAPTBExcitationModel::CrossSectionPerVolume(const G4Material* /*material*/,
|
||||
const G4String& materialName,
|
||||
const G4ParticleDefinition* particleDefinition,
|
||||
G4double ekin,
|
||||
G4double /*emin*/,
|
||||
G4double G4DNAPTBExcitationModel::CrossSectionPerVolume(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double ekin, G4double /*emin*/,
|
||||
G4double /*emax*/)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNAPTBExcitationModel" << G4endl;
|
||||
// Get the name of the current particle
|
||||
G4String particleName = p->GetParticleName();
|
||||
const std::size_t& MatID = material->GetIndex();
|
||||
// initialise variables
|
||||
G4double lowLim;
|
||||
G4double highLim;
|
||||
G4double sigma = 0;
|
||||
|
||||
// Get the name of the current particle
|
||||
G4String particleName = particleDefinition->GetParticleName();
|
||||
// Get the low energy limit for the current particle
|
||||
lowLim = fpModelData->GetLowELimit(MatID, p);
|
||||
|
||||
// initialise variables
|
||||
G4double lowLim = 0;
|
||||
G4double highLim = 0;
|
||||
G4double sigma=0;
|
||||
// Get the high energy limit for the current particle
|
||||
highLim = fpModelData->GetHighELimit(MatID, p);
|
||||
|
||||
// Get the low energy limit for the current particle
|
||||
lowLim = GetLowELimit(materialName, particleName);
|
||||
|
||||
// Get the high energy limit for the current particle
|
||||
highLim = GetHighELimit(materialName, particleName);
|
||||
|
||||
// Check that we are in the correct energy range
|
||||
if (ekin >= lowLim && ekin < highLim)
|
||||
{
|
||||
// Get the map with all the data tables
|
||||
TableMapData* tableData = GetTableData();
|
||||
|
||||
// Retrieve the cross section value
|
||||
sigma = (*tableData)[materialName][particleName]->FindValue(ekin);
|
||||
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "°°° G4DNAPTBExcitationModel - XS INFO START" << G4endl;
|
||||
G4cout << "°°° Kinetic energy(eV)=" << ekin/eV << " particle : " << particleName << G4endl;
|
||||
G4cout << "°°° Cross section per "<< materialName <<" molecule (cm^2)=" << sigma/cm/cm << G4endl;
|
||||
G4cout << "°°° G4DNAPTBExcitationModel - XS INFO END" << G4endl;
|
||||
}
|
||||
// Check that we are in the correct energy range
|
||||
if (ekin >= lowLim && ekin < highLim) {
|
||||
// Get the map with all the data tables
|
||||
auto Data = fpModelData->GetData();
|
||||
|
||||
if ((*Data)[MatID][p] == nullptr) {
|
||||
G4Exception("G4DNAPTBExcitationModel::CrossSectionPerVolume", "em00236", FatalException,
|
||||
"No model is registered");
|
||||
}
|
||||
// Retrieve the cross section value
|
||||
sigma = (*Data)[MatID][p]->FindValue(ekin);
|
||||
|
||||
// Return the cross section value
|
||||
return sigma;
|
||||
if (verboseLevel > 2) {
|
||||
G4cout << "__________________________________" << G4endl;
|
||||
G4cout << "°°° G4DNAPTBExcitationModel - XS INFO START" << G4endl;
|
||||
G4cout << "°°° Kinetic energy(eV)=" << ekin / eV << " particle : " << particleName << G4endl;
|
||||
G4cout << "°°° Cross section per " << MatID << " ID molecule (cm^2)=" << sigma / cm / cm
|
||||
<< G4endl;
|
||||
G4cout << "°°° G4DNAPTBExcitationModel - XS INFO END" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the cross section value
|
||||
auto MolDensity =
|
||||
(*G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(material))[MatID];
|
||||
return sigma * MolDensity;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAPTBExcitationModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* /*couple*/,
|
||||
const G4String& materialName,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicParticle,
|
||||
G4ParticleChangeForGamma* particleChangeForGamma,
|
||||
G4double /*tmin*/,
|
||||
G4double /*tmax*/)
|
||||
G4double /*tmin*/, G4double /*tmax*/)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4DNAPTBExcitationModel" << G4endl;
|
||||
const std::size_t& materialID = (std::size_t)couple->GetIndex();
|
||||
|
||||
// Get the incident particle kinetic energy
|
||||
G4double k = aDynamicParticle->GetKineticEnergy();
|
||||
//Get the particle name
|
||||
const G4String& particleName = aDynamicParticle->GetDefinition()->GetParticleName();
|
||||
// Get the energy limits
|
||||
G4double lowLim = GetLowELimit(materialName, particleName);
|
||||
G4double highLim = GetHighELimit(materialName, particleName);
|
||||
// Get the incident particle kinetic energy
|
||||
G4double k = aDynamicParticle->GetKineticEnergy();
|
||||
// Get the particle name
|
||||
const auto& particle = aDynamicParticle->GetDefinition();
|
||||
// Get the energy limits
|
||||
G4double lowLim = fpModelData->GetLowELimit(materialID, particle);
|
||||
G4double highLim = fpModelData->GetHighELimit(materialID, particle);
|
||||
|
||||
// Check if we are in the correct energy range
|
||||
if (k >= lowLim && k < highLim)
|
||||
{
|
||||
if(materialName=="N2")
|
||||
{
|
||||
// Check if we are in the correct energy range
|
||||
if (k >= lowLim && k < highLim) {
|
||||
if (fpN2 != nullptr && materialID == fpN2->GetIndex()) {
|
||||
// Retrieve the excitation energy for the current material
|
||||
G4int level = fpModelData->RandomSelectShell(k, particle, materialID);
|
||||
G4double excitationEnergy = ptbExcitationStructure.ExcitationEnergy(level, fpN2->GetIndex());
|
||||
|
||||
// Retrieve the excitation energy for the current material
|
||||
G4int level = RandomSelectShell(k,particleName,materialName);
|
||||
G4double excitationEnergy = ptbExcitationStructure.ExcitationEnergy(level, materialName);
|
||||
// Calculate the new energy of the particle
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
|
||||
// Calculate the new energy of the particle
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
|
||||
// Check that the new energy is above zero before applying it the particle.
|
||||
// Otherwise, do nothing.
|
||||
if (newEnergy > 0)
|
||||
{
|
||||
particleChangeForGamma->ProposeMomentumDirection(aDynamicParticle->GetMomentumDirection());
|
||||
particleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
particleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
G4double ioniThres = ptbIonisationStructure.IonisationEnergy(0,materialName);
|
||||
// if excitation energy greater than ionisation threshold, then autoionisaiton
|
||||
if((excitationEnergy>ioniThres)&&(G4UniformRand()<0.5))
|
||||
{
|
||||
particleChangeForGamma->ProposeLocalEnergyDeposit(ioniThres);
|
||||
// energy of ejected electron
|
||||
G4double secondaryKinetic = excitationEnergy - ioniThres;
|
||||
// random direction
|
||||
G4double cosTheta = 2*G4UniformRand() - 1., phi = CLHEP::twopi*G4UniformRand();
|
||||
G4double sinTheta = std::sqrt(1. - cosTheta*cosTheta);
|
||||
G4double ux = sinTheta*std::cos(phi),
|
||||
uy = sinTheta*std::sin(phi),
|
||||
uz = cosTheta;
|
||||
G4ThreeVector deltaDirection(ux,uy,uz);
|
||||
// Create the new particle with its characteristics
|
||||
G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic) ;
|
||||
fvect->push_back(dp);
|
||||
}
|
||||
} else {
|
||||
G4ExceptionDescription description;
|
||||
description<<"Kinetic energy <= 0 at "<<materialName<<" material !!!";
|
||||
G4Exception("G4DNAPTBExcitationModel::SampleSecondaries","",FatalException,description);
|
||||
}
|
||||
} else if(materialName!="G4_WATER"){
|
||||
// Retrieve the excitation energy for the current material
|
||||
G4double excitationEnergy = tableMeanEnergyPTB[materialName];
|
||||
// Calculate the new energy of the particle
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
// Check that the new energy is above zero before applying it the particle.
|
||||
// Otherwise, do nothing.
|
||||
if (newEnergy > 0){
|
||||
particleChangeForGamma->ProposeMomentumDirection(aDynamicParticle->GetMomentumDirection());
|
||||
particleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
particleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
} else {
|
||||
G4ExceptionDescription description;
|
||||
description<<"Kinetic energy <= 0 at "<<materialName<<" material !!!";
|
||||
G4Exception("G4DNAPTBExcitationModel::SampleSecondaries","",FatalException,description);
|
||||
}
|
||||
} else {
|
||||
G4int level = RandomSelectShell(k,particleName, materialName);
|
||||
G4double excitationEnergy = waterStructure.ExcitationEnergy(level);
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
|
||||
if (newEnergy > 0){
|
||||
particleChangeForGamma->ProposeMomentumDirection(aDynamicParticle->GetMomentumDirection());
|
||||
particleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
particleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
const G4Track * theIncomingTrack = particleChangeForGamma->GetCurrentTrack();
|
||||
G4DNAChemistryManager::Instance()->CreateWaterMolecule(eExcitedMolecule,
|
||||
level,
|
||||
theIncomingTrack);
|
||||
} else {
|
||||
G4ExceptionDescription description;
|
||||
description<<"Kinetic energy <= 0 at "<<materialName<<" material !!!";
|
||||
G4Exception("G4DNAPTBExcitationModel::SampleSecondaries","",FatalException,description);
|
||||
}
|
||||
// Check that the new energy is above zero before applying it the particle.
|
||||
// Otherwise, do nothing.
|
||||
if (newEnergy > 0) {
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(aDynamicParticle->GetMomentumDirection());
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
G4double ioniThres = ptbIonisationStructure.IonisationEnergy(0, fpN2->GetIndex());
|
||||
// if excitation energy greater than ionisation threshold, then autoionisaiton
|
||||
if ((excitationEnergy > ioniThres) && (G4UniformRand() < 0.5)) {
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(ioniThres);
|
||||
// energy of ejected electron
|
||||
G4double secondaryKinetic = excitationEnergy - ioniThres;
|
||||
// random direction
|
||||
G4double cosTheta = 2 * G4UniformRand() - 1., phi = CLHEP::twopi * G4UniformRand();
|
||||
G4double sinTheta = std::sqrt(1. - cosTheta * cosTheta);
|
||||
G4double ux = sinTheta * std::cos(phi), uy = sinTheta * std::sin(phi), uz = cosTheta;
|
||||
G4ThreeVector deltaDirection(ux, uy, uz);
|
||||
// Create the new particle with its characteristics
|
||||
auto dp = new G4DynamicParticle(G4Electron::Electron(), deltaDirection, secondaryKinetic);
|
||||
fvect->push_back(dp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4ExceptionDescription description;
|
||||
description << "Kinetic energy <= 0 at " << fpN2->GetName() << " material !!!";
|
||||
G4Exception("G4DNAPTBExcitationModel::SampleSecondaries", "", FatalException, description);
|
||||
}
|
||||
}
|
||||
|
||||
else if (fpG4_WATER == nullptr || materialID != fpG4_WATER->GetIndex()) {
|
||||
// Retrieve the excitation energy for the current material
|
||||
G4double excitationEnergy = fTableMeanEnergyPTB[materialID];
|
||||
// Calculate the new energy of the particle
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
// Check that the new energy is above zero before applying it the particle.
|
||||
// Otherwise, do nothing.
|
||||
if (newEnergy > 0) {
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(aDynamicParticle->GetMomentumDirection());
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
}
|
||||
else {
|
||||
G4ExceptionDescription description;
|
||||
description << "Kinetic energy <= 0 at " << materialID << " index material !!!";
|
||||
G4Exception("G4DNAPTBExcitationModel::SampleSecondaries", "", FatalException, description);
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4int level = RandomSelectShell(k, particle, materialID);
|
||||
G4double excitationEnergy = waterStructure.ExcitationEnergy(level);
|
||||
G4double newEnergy = k - excitationEnergy;
|
||||
|
||||
if (newEnergy > 0) {
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(aDynamicParticle->GetMomentumDirection());
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
|
||||
fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
|
||||
const G4Track* theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
|
||||
G4DNAChemistryManager::Instance()->CreateWaterMolecule(eExcitedMolecule, level,
|
||||
theIncomingTrack);
|
||||
}
|
||||
else {
|
||||
G4ExceptionDescription description;
|
||||
description << "Kinetic energy <= 0 at " << materialID << " ID material !!!";
|
||||
G4Exception("G4DNAPTBExcitationModel::SampleSecondaries", "", FatalException, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+509
-802
File diff suppressed because it is too large
Load Diff
@@ -26,71 +26,60 @@
|
||||
//
|
||||
|
||||
#include "G4DNAVacuumModel.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4DNAChemistryManager.hh"
|
||||
#include "G4DNAMolecularMaterial.hh"
|
||||
|
||||
G4DNAVacuumModel::G4DNAVacuumModel(const G4String& applyToMaterial, const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
: G4VDNAModel(nam, applyToMaterial)
|
||||
G4DNAVacuumModel::G4DNAVacuumModel(
|
||||
const G4String& applyToMaterial, const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VDNAModel(nam, applyToMaterial)
|
||||
{
|
||||
verboseLevel = 0;
|
||||
verboseLevel = 0;
|
||||
|
||||
if( verboseLevel>0 )
|
||||
{
|
||||
G4cout << "G4DNAVacuumModel is constructed " << G4endl;
|
||||
}
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "G4DNAVacuumModel is constructed " << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DNAVacuumModel::~G4DNAVacuumModel()
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNAVacuumModel::Initialise()" << G4endl;
|
||||
|
||||
{
|
||||
if (verboseLevel > 3) G4cout << "Calling G4DNAVacuumModel::Initialise()" << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAVacuumModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& /*cuts*/, G4ParticleChangeForGamma*)
|
||||
void G4DNAVacuumModel::Initialise(
|
||||
const G4ParticleDefinition* particle, const G4DataVector& /*cuts*/)
|
||||
{
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling G4DNAVacuumModel::Initialise()" << G4endl;
|
||||
|
||||
EnableForMaterialAndParticle("G4_Galactic", particle->GetParticleName() );
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling G4DNAVacuumModel::Initialise()" << G4endl;
|
||||
}
|
||||
if(G4Material::GetMaterial("G4_Galactic",false) != nullptr)
|
||||
{
|
||||
auto index = (G4int)G4Material::GetMaterial("G4_Galactic")->GetIndex();
|
||||
EnableForMaterialAndParticle(index, particle);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4DNAVacuumModel::CrossSectionPerVolume(const G4Material* /*material*/,
|
||||
const G4String& /*materialName*/,
|
||||
const G4ParticleDefinition* /*particleDefinition*/,
|
||||
G4double /*ekin*/,
|
||||
G4double /*emin*/,
|
||||
G4double /*emax*/)
|
||||
G4double G4DNAVacuumModel::CrossSectionPerVolume(const G4Material* /*material*/, const G4ParticleDefinition* /*particleDefinition*/,
|
||||
G4double /*ekin*/, G4double /*emin*/, G4double /*emax*/)
|
||||
{
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNAVacuumModel" << G4endl;
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4DNAVacuumModel" << G4endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4DNAVacuumModel::SampleSecondaries(std::vector<G4DynamicParticle*>* /*fvect*/,
|
||||
const G4MaterialCutsCouple* /*couple*/,
|
||||
const G4String& /*materialName*/,
|
||||
const G4DynamicParticle* /*aDynamicParticle*/,
|
||||
G4ParticleChangeForGamma* /*particleChangeForGamma*/,
|
||||
G4double /*tmin*/,
|
||||
G4double /*tmax*/)
|
||||
const G4MaterialCutsCouple* /*couple*/,
|
||||
const G4DynamicParticle* /*aDynamicParticle*/, G4double /*tmin*/, G4double /*tmax*/)
|
||||
{
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4DNAVacuumModel" << G4endl;
|
||||
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "Calling SampleSecondaries() of G4DNAVacuumModel" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,258 +29,247 @@
|
||||
//
|
||||
|
||||
#include "G4VDNAModel.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4VDNAModel::G4VDNAModel(const G4String &nam, const G4String &applyToMaterial)
|
||||
: fStringOfMaterials(applyToMaterial), fName(nam)
|
||||
G4VDNAModel::G4VDNAModel(const G4String& nam, const G4String& applyToMaterial)
|
||||
: G4VEmModel(nam), fStringOfMaterials(applyToMaterial)
|
||||
{}
|
||||
|
||||
G4VDNAModel::~G4VDNAModel() = default;
|
||||
|
||||
void G4VDNAModel::AddCrossSectionData(const std::size_t& materialID,
|
||||
const G4ParticleDefinition* particleName,
|
||||
const G4String& fileCS, const G4String& fileDiffCS,
|
||||
const G4double& scaleFactor)
|
||||
{
|
||||
|
||||
fModelMaterials.push_back(materialID);
|
||||
fModelParticles.push_back(particleName);
|
||||
fModelCSFiles.push_back(fileCS);
|
||||
fModelDiffCSFiles.push_back(fileDiffCS);
|
||||
fModelScaleFactors.push_back(scaleFactor);
|
||||
}
|
||||
|
||||
G4VDNAModel::~G4VDNAModel()
|
||||
void G4VDNAModel::AddCrossSectionData(const std::size_t& materialID,
|
||||
const G4ParticleDefinition* particleName,
|
||||
const G4String& fileCS, const G4double& scaleFactor)
|
||||
{
|
||||
// Clean fTableData
|
||||
std::map<G4String, std::map<G4String,G4DNACrossSectionDataSet*,std::less<G4String> > >::iterator posOuter;
|
||||
std::map<G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator posInner;
|
||||
// iterate on each material
|
||||
for (posOuter = fTableData.begin(); posOuter != fTableData.end(); ++posOuter)
|
||||
{
|
||||
// iterate on each particle
|
||||
for(posInner = posOuter->second.begin(); posInner != posOuter->second.end(); ++posInner)
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = posInner->second;
|
||||
if(table != 0) delete table;
|
||||
}
|
||||
fModelMaterials.push_back(materialID);
|
||||
fModelParticles.push_back(particleName);
|
||||
fModelCSFiles.push_back(fileCS);
|
||||
fModelScaleFactors.push_back(scaleFactor);
|
||||
}
|
||||
|
||||
void G4VDNAModel::LoadCrossSectionData(const G4ParticleDefinition* particleName)
|
||||
{
|
||||
G4String fileElectron, fileDiffElectron = "";
|
||||
G4String materialName, modelParticleName;
|
||||
G4double scaleFactor;
|
||||
std::size_t materialID;
|
||||
|
||||
const G4ParticleDefinition* pParticle;
|
||||
|
||||
// construct applyToMatVect with materials specified by the user
|
||||
std::vector<G4String> applyToMatVect = BuildApplyToMatVect(fStringOfMaterials);
|
||||
|
||||
// iterate on each material contained into the fStringOfMaterials variable (through
|
||||
// applyToMatVect)
|
||||
for (unsigned int i = 0; i < applyToMatVect.size(); ++i) {
|
||||
auto pMat = G4Material::GetMaterial(applyToMatVect[i], false);
|
||||
if (applyToMatVect[i] != "all" && pMat == nullptr) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
void G4VDNAModel::AddCrossSectionData(G4String materialName, G4String particleName, G4String fileCS, G4String fileDiffCS, G4double scaleFactor)
|
||||
{
|
||||
fModelMaterials.push_back(materialName);
|
||||
fModelParticles.push_back(particleName);
|
||||
fModelCSFiles.push_back(fileCS);
|
||||
fModelDiffCSFiles.push_back(fileDiffCS);
|
||||
fModelScaleFactors.push_back(scaleFactor);
|
||||
}
|
||||
// We have selected a material coming from applyToMatVect
|
||||
// We try to find if this material correspond to a model registered material
|
||||
// If it is, then isMatFound becomes true
|
||||
G4bool isMatFound = false;
|
||||
|
||||
void G4VDNAModel::AddCrossSectionData(G4String materialName, G4String particleName, G4String fileCS, G4double scaleFactor)
|
||||
{
|
||||
fModelMaterials.push_back(materialName);
|
||||
fModelParticles.push_back(particleName);
|
||||
fModelCSFiles.push_back(fileCS);
|
||||
fModelScaleFactors.push_back(scaleFactor);
|
||||
}
|
||||
// We iterate on each model registered materials to load the CS data
|
||||
// We have to do a for loop because of the "all" option
|
||||
// applyToMatVect[i] == "all" implies applyToMatVect.size()=1 and we want to iterate on all
|
||||
// registered materials
|
||||
for (std::size_t j = 0; j < fModelMaterials.size(); ++j) {
|
||||
if (applyToMatVect[i] == "all" || pMat->GetIndex() == fModelMaterials[j]) {
|
||||
isMatFound = true;
|
||||
materialID = fModelMaterials[j];
|
||||
pParticle = fModelParticles[j];
|
||||
fileElectron = fModelCSFiles[j];
|
||||
if (!fModelDiffCSFiles.empty()) fileDiffElectron = fModelDiffCSFiles[j];
|
||||
scaleFactor = fModelScaleFactors[j];
|
||||
|
||||
void G4VDNAModel::LoadCrossSectionData(const G4String& particleName)
|
||||
{
|
||||
G4String fileElectron, fileDiffElectron;
|
||||
G4String materialName, modelParticleName;
|
||||
G4double scaleFactor;
|
||||
ReadAndSaveCSFile(materialID, pParticle, fileElectron, scaleFactor);
|
||||
|
||||
// construct applyToMatVect with materials specified by the user
|
||||
std::vector<G4String> applyToMatVect = BuildApplyToMatVect(fStringOfMaterials);
|
||||
|
||||
// iterate on each material contained into the fStringOfMaterials variable (through applyToMatVect)
|
||||
for(unsigned int i=0;i<applyToMatVect.size();++i)
|
||||
{
|
||||
// We have selected a material coming from applyToMatVect
|
||||
// We try to find if this material correspond to a model registered material
|
||||
// If it is, then isMatFound becomes true
|
||||
G4bool isMatFound = false;
|
||||
|
||||
// We iterate on each model registered materials to load the CS data
|
||||
// We have to do a for loop because of the "all" option
|
||||
// applyToMatVect[i] == "all" implies applyToMatVect.size()=1 and we want to iterate on all registered materials
|
||||
for(unsigned int j=0;j<fModelMaterials.size();++j)
|
||||
{
|
||||
if(applyToMatVect[i] == fModelMaterials[j] || applyToMatVect[i] == "all")
|
||||
{
|
||||
isMatFound = true;
|
||||
materialName = fModelMaterials[j];
|
||||
modelParticleName = fModelParticles[j];
|
||||
fileElectron = fModelCSFiles[j];
|
||||
if(!fModelDiffCSFiles.empty()) fileDiffElectron = fModelDiffCSFiles[j];
|
||||
scaleFactor = fModelScaleFactors[j];
|
||||
|
||||
ReadAndSaveCSFile(materialName, modelParticleName, fileElectron, scaleFactor);
|
||||
|
||||
if(!fModelDiffCSFiles.empty()) ReadDiffCSFile(materialName, modelParticleName, fileDiffElectron, scaleFactor);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// check if we found a correspondance, if not: fatal error
|
||||
if(!isMatFound)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << applyToMatVect[i] << " material was not found. It means the material specified in the UserPhysicsList is not a model material for ";
|
||||
oss << particleName;
|
||||
G4Exception("G4VDNAModel::LoadCrossSectionData","em0003",
|
||||
FatalException, oss.str().c_str());
|
||||
return;
|
||||
}
|
||||
if (fileDiffElectron != "")
|
||||
ReadDiffCSFile(materialID, pParticle, fileDiffElectron, scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
// check if we found a correspondance, if not: fatal error
|
||||
if (!isMatFound) {
|
||||
std::ostringstream oss;
|
||||
oss << applyToMatVect[i]
|
||||
<< " material was not found. It means the material specified in the UserPhysicsList is "
|
||||
"not a model material for ";
|
||||
oss << particleName;
|
||||
G4Exception("G4VDNAModel::LoadCrossSectionData", "em0003", FatalException, oss.str().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4VDNAModel::ReadDiffCSFile(const G4String&, const G4String&, const G4String&, const G4double)
|
||||
void G4VDNAModel::ReadDiffCSFile(const std::size_t&, const G4ParticleDefinition*, const G4String&,
|
||||
const G4double&)
|
||||
{
|
||||
G4String text("ReadDiffCSFile must be implemented in the model class using a differential cross section data file");
|
||||
G4String text(
|
||||
"ReadDiffCSFile must be implemented in the model class using a differential cross section data "
|
||||
"file");
|
||||
|
||||
G4Exception("G4VDNAModel::ReadDiffCSFile","em0003",
|
||||
FatalException, text);
|
||||
G4Exception("G4VDNAModel::ReadDiffCSFile", "em0003", FatalException, text);
|
||||
}
|
||||
|
||||
void G4VDNAModel::EnableForMaterialAndParticle(const G4String &materialName, const G4String &particleName)
|
||||
void G4VDNAModel::EnableForMaterialAndParticle(const std::size_t& materialID,
|
||||
const G4ParticleDefinition* p)
|
||||
{
|
||||
fTableData[materialName][particleName] = 0;
|
||||
fData[materialID][p] = nullptr;
|
||||
}
|
||||
|
||||
std::vector<G4String> G4VDNAModel::BuildApplyToMatVect(const G4String& materials)
|
||||
{
|
||||
// output material vector
|
||||
std::vector<G4String> materialVect;
|
||||
// output material vector
|
||||
std::vector<G4String> materialVect;
|
||||
|
||||
// if we don't find any "/" then it means we only have one "material" (could be the "all" option)
|
||||
if(materials.find("/")==std::string::npos)
|
||||
{
|
||||
// we add the material to the output vector
|
||||
materialVect.push_back(materials);
|
||||
// if we don't find any "/" then it means we only have one "material" (could be the "all" option)
|
||||
if (materials.find("/") == std::string::npos) {
|
||||
// we add the material to the output vector
|
||||
materialVect.push_back(materials);
|
||||
}
|
||||
// if we have several materials listed in the string then we must retrieve them
|
||||
else {
|
||||
G4String materialsNonIdentified = materials;
|
||||
|
||||
while (materialsNonIdentified.find_first_of("/") != std::string::npos) {
|
||||
// we select the first material and stop at the "/" caracter
|
||||
G4String mat = materialsNonIdentified.substr(0, materialsNonIdentified.find_first_of("/"));
|
||||
materialVect.push_back(mat);
|
||||
|
||||
// we remove the previous material from the materialsNonIdentified string
|
||||
materialsNonIdentified = materialsNonIdentified.substr(
|
||||
materialsNonIdentified.find_first_of("/") + 1,
|
||||
materialsNonIdentified.size() - materialsNonIdentified.find_first_of("/"));
|
||||
}
|
||||
// if we have several materials listed in the string then we must retrieve them
|
||||
else
|
||||
{
|
||||
G4String materialsNonIdentified = materials;
|
||||
|
||||
while(materialsNonIdentified.find_first_of("/") != std::string::npos)
|
||||
{
|
||||
// we select the first material and stop at the "/" caracter
|
||||
G4String mat = materialsNonIdentified.substr(0, materialsNonIdentified.find_first_of("/"));
|
||||
materialVect.push_back(mat);
|
||||
// we don't find "/" anymore, it means we only have one material string left
|
||||
// we get it
|
||||
materialVect.push_back(materialsNonIdentified);
|
||||
}
|
||||
|
||||
// we remove the previous material from the materialsNonIdentified string
|
||||
materialsNonIdentified = materialsNonIdentified.substr(materialsNonIdentified.find_first_of("/")+1,
|
||||
materialsNonIdentified.size()-materialsNonIdentified.find_first_of("/"));
|
||||
return materialVect;
|
||||
}
|
||||
|
||||
void G4VDNAModel::ReadAndSaveCSFile(const std::size_t& materialID, const G4ParticleDefinition* p,
|
||||
const G4String& file, const G4double& scaleFactor)
|
||||
{
|
||||
fData[materialID][p] =
|
||||
std::make_unique<G4DNACrossSectionDataSet>(new G4LogLogInterpolation, eV, scaleFactor);
|
||||
fData[materialID][p]->LoadData(file);
|
||||
}
|
||||
|
||||
G4int G4VDNAModel::RandomSelectShell(const G4double& k, const G4ParticleDefinition* particle,
|
||||
const std::size_t& materialID)
|
||||
{
|
||||
G4int level = 0;
|
||||
|
||||
auto pos = fData[materialID].find(particle);
|
||||
|
||||
if (pos != fData[materialID].end()) {
|
||||
G4DNACrossSectionDataSet* table = pos->second.get();
|
||||
|
||||
if (table != nullptr) {
|
||||
auto valuesBuffer = new G4double[table->NumberOfComponents()];
|
||||
auto n = (G4int)table->NumberOfComponents();
|
||||
G4int i(n);
|
||||
G4double value = 0.;
|
||||
|
||||
while (i > 0) {
|
||||
--i;
|
||||
valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
|
||||
value += valuesBuffer[i];
|
||||
}
|
||||
|
||||
value *= G4UniformRand();
|
||||
|
||||
i = n;
|
||||
|
||||
while (i > 0) {
|
||||
--i;
|
||||
|
||||
if (valuesBuffer[i] > value) {
|
||||
delete[] valuesBuffer;
|
||||
return i;
|
||||
}
|
||||
value -= valuesBuffer[i];
|
||||
}
|
||||
|
||||
// we don't find "/" anymore, it means we only have one material string left
|
||||
// we get it
|
||||
materialVect.push_back(materialsNonIdentified);
|
||||
delete[] valuesBuffer;
|
||||
}
|
||||
|
||||
return materialVect;
|
||||
}
|
||||
else {
|
||||
G4cout << "particle : " << particle->GetParticleName()
|
||||
<< " Materials : " << (*G4Material::GetMaterialTable())[materialID]->GetName() << " "
|
||||
<< this->GetName() << G4endl;
|
||||
G4Exception("G4VDNAModel::RandomSelectShell", "em0002", FatalException,
|
||||
"Model not applicable to particle type : ");
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
void G4VDNAModel::ReadAndSaveCSFile(const G4String& materialName,
|
||||
const G4String& particleName,
|
||||
const G4String& file, G4double scaleFactor)
|
||||
G4bool G4VDNAModel::IsMaterialDefine(const std::size_t& materialID)
|
||||
{
|
||||
fTableData[materialName][particleName] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, eV, scaleFactor);
|
||||
fTableData[materialName][particleName]->LoadData(file);
|
||||
// Check if the given material is defined in the simulation
|
||||
|
||||
G4bool exist(false);
|
||||
|
||||
G4double matTableSize = G4Material::GetMaterialTable()->size();
|
||||
|
||||
for (int i = 0; i < matTableSize; i++) {
|
||||
if (materialID == G4Material::GetMaterialTable()->at(i)->GetIndex()) {
|
||||
exist = true;
|
||||
return exist;
|
||||
}
|
||||
}
|
||||
|
||||
G4Exception("G4VDNAModel::IsMaterialDefine", "em0003", FatalException,
|
||||
"Materials are not defined!!");
|
||||
return exist;
|
||||
}
|
||||
|
||||
G4int G4VDNAModel::RandomSelectShell(G4double k, const G4String& particle, const G4String& materialName)
|
||||
G4bool G4VDNAModel::IsMaterialExistingInModel(const std::size_t& materialID)
|
||||
{
|
||||
G4int level = 0;
|
||||
// Check if the given material is defined in the current model class
|
||||
|
||||
TableMapData* tableData = GetTableData();
|
||||
|
||||
std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
|
||||
pos = (*tableData)[materialName].find(particle);
|
||||
|
||||
if (pos != (*tableData)[materialName].end())
|
||||
{
|
||||
G4DNACrossSectionDataSet* table = pos->second;
|
||||
|
||||
if (table != 0)
|
||||
{
|
||||
G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
|
||||
const G4int n = (G4int)table->NumberOfComponents();
|
||||
G4int i(n);
|
||||
G4double value = 0.;
|
||||
|
||||
while (i>0)
|
||||
{
|
||||
--i;
|
||||
valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
|
||||
value += valuesBuffer[i];
|
||||
}
|
||||
|
||||
value *= G4UniformRand();
|
||||
|
||||
i = n;
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
--i;
|
||||
|
||||
if (valuesBuffer[i] > value)
|
||||
{
|
||||
delete[] valuesBuffer;
|
||||
return i;
|
||||
}
|
||||
value -= valuesBuffer[i];
|
||||
}
|
||||
|
||||
if (valuesBuffer) delete[] valuesBuffer;
|
||||
|
||||
}
|
||||
for (const auto& it : fModelMaterials) {
|
||||
if (it == materialID) {
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4VDNAModel::RandomSelectShell","em0002",
|
||||
FatalException,"Model not applicable to particle type.");
|
||||
}
|
||||
return level;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
G4bool G4VDNAModel::IsMaterialDefine(const G4String& materialName)
|
||||
G4bool G4VDNAModel::IsParticleExistingInModelForMaterial(const G4ParticleDefinition* particleName,
|
||||
const std::size_t& materialID)
|
||||
{
|
||||
// Check if the given material is defined in the simulation
|
||||
// To check two things:
|
||||
// 1- is the material existing in model ?
|
||||
// 2- if yes, is the particle defined for that material ?
|
||||
|
||||
G4bool exist (false);
|
||||
|
||||
double matTableSize = G4Material::GetMaterialTable()->size();
|
||||
|
||||
for(int i=0;i<matTableSize;i++)
|
||||
{
|
||||
if(materialName == G4Material::GetMaterialTable()->at(i)->GetName())
|
||||
{
|
||||
exist = true;
|
||||
return exist;
|
||||
}
|
||||
}
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
G4bool G4VDNAModel::IsMaterialExistingInModel(const G4String& materialName)
|
||||
{
|
||||
// Check if the given material is defined in the current model class
|
||||
|
||||
if (fTableData.find(materialName) == fTableData.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsMaterialExistingInModel(materialID)) {
|
||||
for (const auto& it : fModelParticles) {
|
||||
if (it == particleName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4VDNAModel::IsParticleExistingInModelForMaterial(const G4String& particleName, const G4String& materialName)
|
||||
{
|
||||
// To check two things:
|
||||
// 1- is the material existing in model ?
|
||||
// 2- if yes, is the particle defined for that material ?
|
||||
|
||||
if(IsMaterialExistingInModel(materialName))
|
||||
{
|
||||
if (fTableData[materialName].find(particleName) == fTableData[materialName].end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user