Import Geant4 11.2.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2023-06-30 09:09:57 +02:00
parent aef78ca386
commit dd1f179cda
3780 changed files with 212808 additions and 142780 deletions
@@ -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
@@ -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
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;
}