69 if (verboseLevel > 3) {
70 G4cout <<
"Calling G4DNACPA100ExcitationModel::Initialise()" <<
G4endl;
74 if (p != fpParticle) {
75 std::ostringstream oss;
76 oss <<
" Model is not applied for this particle " << p->
GetParticleName();
83 if (path ==
nullptr) {
85 "G4LEDATA environment variable not set.");
90 if (fpG4_WATER !=
nullptr) {
92 fLevels[index] = 1.214e-4;
94 "dna/sigmadiff_cumulated_elastic_e_cpa100", 1e-20 * m * m);
98 if (fpGuanine !=
nullptr) {
100 fLevels[index] = 1.4504480e-05;
102 "dna/sigmadiff_cumulated_elastic_e_cpa100_guanine", 1 * cm * cm);
106 if (fpDeoxyribose !=
nullptr) {
108 fLevels[index] = 1.6343100e-05;
110 "dna/sigmadiff_cumulated_elastic_e_cpa100_deoxyribose", 1 * cm * cm);
114 if (fpCytosine !=
nullptr) {
116 fLevels[index] = 1.9729660e-05;
118 "dna/sigmadiff_cumulated_elastic_e_cpa100_cytosine", 1 * cm * cm);
122 if (fpThymine !=
nullptr) {
124 fLevels[index] = 1.7381300e-05;
126 "dna/sigmadiff_cumulated_elastic_e_cpa100_thymine", 1 * cm * cm);
130 if (fpAdenine !=
nullptr) {
132 fLevels[index] = 1.6221800e-05;
134 "dna/sigmadiff_cumulated_elastic_e_cpa100_adenine", 1 * cm * cm);
138 if (fpPhosphate !=
nullptr) {
140 fLevels[index] = 2.2369600e-05;
142 "dna/sigmadiff_cumulated_elastic_e_cpa100_phosphoric_acid", 1 * cm * cm);
155 if (dataModel ==
nullptr) {
156 G4cout <<
"G4DNACPA100ElasticModel::CrossSectionPerVolume:: not good modelData" <<
G4endl;
158 "no modelData is registered");
161 fpModelData = dataModel;
166 isInitialised =
true;
177 auto materialID = pMaterial->
GetIndex();
180 fKillBelowEnergy = fpModelData->
GetLowELimit(materialID, p);
185 if (ekin < fKillBelowEnergy) {
189 auto tableData = fpModelData->
GetData();
191 if ((*tableData)[materialID][p] ==
nullptr) {
193 "No model is registered");
195 sigma = (*tableData)[materialID][p]->FindValue(ekin);
198 if (verboseLevel > 2) {
201 G4cout <<
"__________________________________" <<
G4endl;
202 G4cout <<
"°°° G4DNACPA100ElasticModel - XS INFO START" <<
G4endl;
203 G4cout <<
"°°° Kinetic energy(eV)=" << ekin / eV <<
" particle : " << particleName <<
G4endl;
208 G4cout <<
"°°° Cross section per molecule (cm^2)=" << sigma / cm / cm <<
G4endl;
209 G4cout <<
"°°° Cross section per Phosphate molecule (cm^-1)=" << sigma * MolDensity / (1. / cm)
211 G4cout <<
"°°° G4DNACPA100ElasticModel - XS INFO END" <<
G4endl;
216 return sigma * MolDensity;
230 if (p != fpParticle) {
232 "This particle is not applied for this model");
234 if (electronEnergy0 < fKillBelowEnergy) {
237 G4double cosTheta = fpModelData->RandomizeCosTheta(electronEnergy0, materialID);
242 G4double CT1, ST1, CF1, SF1, CT2, ST2, CF2, SF2;
243 G4double sinTheta = std::sqrt(1 - cosTheta * cosTheta);
246 ST1 = std::sqrt(1. - CT1 * CT1);
249 CF1 = zVers.
x() / ST1;
253 SF1 = zVers.
y() / ST1;
255 SF1 = std::sqrt(1. - CF1 * CF1);
259 A3 = sinTheta * std::cos(phi);
260 A4 = A3 * CT1 + ST1 * cosTheta;
261 A5 = sinTheta * std::sin(phi);
262 A2 = A4 * SF1 + A5 * CF1;
263 A1 = A4 * CF1 - A5 * SF1;
265 CT2 = CT1 * cosTheta - ST1 * A3;
266 ST2 = std::sqrt(1. - CT2 * CT2);
268 if (ST2 == 0) ST2 = 1E-6;
275 auto EnergyDeposit = fpModelData->
GetElasticLevel(materialID) * (1. - cosTheta) * electronEnergy0;
281 auto newEnergy = electronEnergy0 - EnergyDeposit;
287 G4double integrDiff,
const std::size_t& materialID)
289 G4double theta, valueT1, valueT2, valueE21, valueE22, valueE12, valueE11;
295 if (k == tValuesVec[materialID][p].back()) {
296 k = k * (1. - 1e-12);
299 std::upper_bound(tValuesVec[materialID][p].begin(), tValuesVec[materialID][p].end(), k);
302 auto e12 = std::upper_bound(eValuesVect[materialID][p][(*t1)].begin(),
303 eValuesVect[materialID][p][(*t1)].end(), integrDiff);
306 auto e22 = std::upper_bound(eValuesVect[materialID][p][(*t2)].begin(),
307 eValuesVect[materialID][p][(*t2)].end(), integrDiff);
317 xs11 = diffCrossSectionData[materialID][p][valueT1][valueE11];
318 xs12 = diffCrossSectionData[materialID][p][valueT1][valueE12];
319 xs21 = diffCrossSectionData[materialID][p][valueT2][valueE21];
320 xs22 = diffCrossSectionData[materialID][p][valueT2][valueE22];
323 if (xs11 == 0 && xs12 == 0 && xs21 == 0 && xs22 == 0) {
327 theta = QuadInterpolator(valueE11, valueE12, valueE21, valueE22, xs11, xs12, xs21, xs22, valueT1,
328 valueT2, k, integrDiff);
340 G4double value = std::exp(d1 + (d2 - d1) * (e - e1) / (e2 - e1));
351 G4double value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
360 G4double a = (std::log10(xs2) - std::log10(xs1)) / (std::log10(e2) - std::log10(e1));
361 G4double b = std::log10(xs2) - a * std::log10(e2);
362 G4double sigma = a * std::log10(e) + b;
363 G4double value = (std::pow(10., sigma));
388 G4double interpolatedvalue1 = LinLinInterpolate(e11, e12, e, xs11, xs12);
389 G4double interpolatedvalue2 = LinLinInterpolate(e21, e22, e, xs21, xs22);
390 G4double value = LinLinInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
397G4double G4DNACPA100ElasticModel::RandomizeCosTheta(
G4double k,
const std::size_t& materialID)
401 integrdiff = uniformRand;
409void G4DNACPA100ElasticModel::ReadDiffCSFile(
const std::size_t& materialName,
414 if (path ==
nullptr) {
416 "G4LEDATA environment variable not set.");
420 std::ostringstream fullFileName;
421 fullFileName << path <<
"/" << file <<
".dat";
423 std::ifstream diffCrossSection(fullFileName.str().c_str());
425 std::stringstream endPath;
426 if (!diffCrossSection) {
427 endPath <<
"Missing data file: " << file;
429 endPath.str().c_str());
432 tValuesVec[materialName][particleName].push_back(0.);
435 while (std::getline(diffCrossSection, line)) {
437 std::istringstream testIss(line);
447 std::istringstream iss(line);
452 iss >> tDummy >> eDummy;
454 if (tDummy != tValuesVec[materialName][particleName].back()) {
456 tValuesVec[materialName][particleName].push_back(tDummy);
458 eValuesVect[materialName][particleName][tDummy].push_back(0.);
460 iss >> diffCrossSectionData[materialName][particleName][tDummy][eDummy];
462 if (eDummy != eValuesVect[materialName][particleName][tDummy].back()) {
463 eValuesVect[materialName][particleName][tDummy].push_back(eDummy);
const char * G4FindDataDir(const char *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cout
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
SampleSecondaries Each model must implement SampleSecondaries to decide if a particle will be created...
G4DNACPA100ElasticModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="DNACPA100ElasticModel")
G4double GetElasticLevel(const std::size_t &l)
G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax) override
CrossSectionPerVolume Every model must implement its own CrossSectionPerVolume method....
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
Initialise Each model must implement an Initialize method.
static G4DNAMaterialManager * Instance()
void SetMasterDataModel(const DNAModelType &t, G4VEmModel *m)
G4VEmModel * GetModel(const DNAModelType &t)
const std::vector< G4double > * GetNumMolPerVolTableFor(const G4Material *) const
Retrieve a table of molecular densities (number of molecules per unit volume) in the G4 unit system f...
static G4DNAMolecularMaterial * Instance()
const G4ThreeVector & GetMomentumDirection() const
const G4ParticleDefinition * GetParticleDefinition() const
G4double GetKineticEnergy() const
static G4Electron * ElectronDefinition()
const G4Material * GetMaterial() const
std::size_t GetIndex() const
static G4MaterialTable * GetMaterialTable()
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
const G4String & GetParticleName() const
G4String GetName()
GetName.
void LoadCrossSectionData(const G4ParticleDefinition *particleName)
LoadCrossSectionData Method to loop on all the registered materials in the model and load the corresp...
void SetLowELimit(const size_t &materialID, const G4ParticleDefinition *particle, G4double lim)
SetLowEnergyLimit.
void SetHighELimit(const size_t &materialID, const G4ParticleDefinition *particle, G4double lim)
SetHighEnergyLimit.
G4double GetHighELimit(const size_t &materialID, const G4ParticleDefinition *particle)
GetHighEnergyLimit.
void AddCrossSectionData(const size_t &materialName, const G4ParticleDefinition *particleName, const G4String &fileCS, const G4String &fileDiffCS, const G4double &scaleFactor)
AddCrossSectionData Method used during the initialization of the model class to add a new material....
G4double GetLowELimit(const size_t &materialID, const G4ParticleDefinition *particle)
GetLowEnergyLimit.
MaterialParticleMapData * GetData()
GetTableData.
G4ParticleChangeForGamma * GetParticleChangeForGamma()
void ProposeLocalEnergyDeposit(G4double anEnergyPart)