112 G4cout <<
"MicroElec inelastic model is constructed " <<
G4endl;
117 fAtomDeexcitation =
nullptr;
118 fParticleChangeForGamma =
nullptr;
125 SEFromFermiLevel =
false;
134 for (
auto const& p : tableTCS) {
135 MapData* tableData = p.second;
136 for (
auto const& pos : *tableData) {
delete pos.second; }
142 for (
auto const & obj : eDiffDatatable) {
143 auto ptr = obj.second;
148 for (
auto const & obj : pDiffDatatable) {
149 auto ptr = obj.second;
155 for (
auto const & obj : eNrjTransStorage) {
158 for (
auto const & obj : pNrjTransStorage) {
163 for (
auto const& p : eProbaShellStorage) {
167 for (
auto const& p : pProbaShellStorage) {
172 for (
auto const& p : eIncidentEnergyStorage) {
176 for (
auto const& p : pIncidentEnergyStorage) {
181 for (
auto const& p : eVecmStorage) {
185 for (
auto const& p : pVecmStorage) {
190 for (
auto const& p : tableMaterialsStructures) {
201 if (verboseLevel > 3)
202 G4cout <<
"Calling G4MicroElecInelasticModel_new::Initialise()" <<
G4endl;
224 lowEnergyLimit[electron] = 2 * eV;
225 highEnergyLimit[electron] = 10.0 * MeV;
231 for (
G4int i = 0; i < numOfCouples; ++i) {
233 G4cout <<
"Material " << i + 1 <<
" / " << numOfCouples <<
" : " << material->
GetName() <<
G4endl;
234 if (material->
GetName() ==
"Vacuum")
continue;
236 MapData* tableData =
new MapData;
239 tableMaterialsStructures[mat] = currentMaterialStructure;
240 if (particle == electronDef) {
242 G4String fileElectron(
"Inelastic/" + modelName +
"_sigma_inelastic_e-_" + mat);
246 tableData->insert(make_pair(electron, tableE));
249 std::ostringstream eFullFileName;
251 eFullFileName << path <<
"/microelec/Inelastic/cumulated_" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat";
253 G4cout <<
"Inelastic/cumulated_" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat" <<
G4endl;
256 eFullFileName << path <<
"/microelec/Inelastic/" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat";
258 G4cout <<
"Inelastic/" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat" <<
G4endl;
261 std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
262 if (!eDiffCrossSection)
264 std::stringstream ss;
265 ss <<
"Missing data " << eFullFileName.str().c_str();
266 std::string sortieString = ss.str();
268 if (fasterCode)
G4Exception(
"G4MicroElecInelasticModel_new::Initialise",
"em0003",
271 G4Exception(
"G4MicroElecInelasticModel_new::Initialise",
"em0003",
272 FatalException,
"Missing data file:/microelec/sigmadiff_inelastic_e_Si.dat");
281 vector<TriDimensionMap>* eDiffCrossSectionData =
new vector<TriDimensionMap>;
282 vector<TriDimensionMap>* eNrjTransfData =
new vector<TriDimensionMap>;
283 vector<VecMap>* eProbaShellMap =
new vector<VecMap>;
284 vector<G4double>* eTdummyVec =
new vector<G4double>;
285 VecMap* eVecm =
new VecMap;
287 for (
G4int j = 0; j < currentMaterialStructure->NumberOfLevels(); ++j)
289 eDiffCrossSectionData->push_back(TriDimensionMap());
290 eNrjTransfData->push_back(TriDimensionMap());
291 eProbaShellMap->push_back(VecMap());
294 eTdummyVec->push_back(0.);
295 while (!eDiffCrossSection.eof())
299 eDiffCrossSection >> tDummy >> eDummy;
300 if (tDummy != eTdummyVec->back()) eTdummyVec->push_back(tDummy);
303 for (
G4int j = 0; j < currentMaterialStructure->NumberOfLevels(); ++j)
305 eDiffCrossSection >> tmp;
306 (*eDiffCrossSectionData)[j][tDummy][eDummy] = tmp;
310 (*eNrjTransfData)[j][tDummy][(*eDiffCrossSectionData)[j][tDummy][eDummy]] = eDummy;
311 (*eProbaShellMap)[j][tDummy].push_back((*eDiffCrossSectionData)[j][tDummy][eDummy]);
314 (*eDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
315 (*eVecm)[tDummy].push_back(eDummy);
323 eNrjTransStorage[mat] = eNrjTransfData;
324 eProbaShellStorage[mat] = eProbaShellMap;
327 eDiffDatatable[mat] = eDiffCrossSectionData;
328 eVecmStorage[mat] = eVecm;
330 eIncidentEnergyStorage[mat] = eTdummyVec;
334 delete eProbaShellMap;
335 delete eNrjTransfData;
338 delete eDiffCrossSectionData;
344 if (particle == protonDef)
347 G4String fileProton(
"Inelastic/" + modelName +
"_sigma_inelastic_p_" + mat);
G4cout << fileProton <<
G4endl;
350 tableData->insert(make_pair(proton, tableP));
353 std::ostringstream pFullFileName;
355 pFullFileName << path <<
"/microelec/Inelastic/cumulated_" + modelName +
"_sigmadiff_inelastic_p_" + mat +
".dat";
357 G4cout <<
"Inelastic/cumulated_" + modelName +
"_sigmadiff_inelastic_p_" + mat +
".dat" <<
G4endl;
360 pFullFileName << path <<
"/microelec/Inelastic/" + modelName +
"_sigmadiff_inelastic_p_" + mat +
".dat";
362 G4cout <<
"Inelastic/" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat" <<
G4endl;
365 std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
366 if (!pDiffCrossSection)
368 if (fasterCode)
G4Exception(
"G4MicroElecInelasticModel_new::Initialise",
"em0003",
369 FatalException,
"Missing data file:/microelec/sigmadiff_cumulated_inelastic_p_Si.dat");
371 G4Exception(
"G4MicroElecInelasticModel_new::Initialise",
"em0003",
372 FatalException,
"Missing data file:/microelec/sigmadiff_inelastic_p_Si.dat");
381 vector<TriDimensionMap>* pDiffCrossSectionData =
382 new vector<TriDimensionMap>;
383 vector<TriDimensionMap>* pNrjTransfData =
384 new vector<TriDimensionMap>;
385 vector<VecMap>* pProbaShellMap =
387 vector<G4double>* pTdummyVec =
388 new vector<G4double>;
389 VecMap* pVecm =
new VecMap;
391 for (
G4int j = 0; j < currentMaterialStructure->NumberOfLevels(); ++j)
394 pDiffCrossSectionData->push_back(TriDimensionMap());
395 pNrjTransfData->push_back(TriDimensionMap());
396 pProbaShellMap->push_back(VecMap());
399 pTdummyVec->push_back(0.);
400 while (!pDiffCrossSection.eof())
404 pDiffCrossSection >> tDummy >> eDummy;
405 if (tDummy != pTdummyVec->back()) pTdummyVec->push_back(tDummy);
408 for (
G4int j = 0; j < currentMaterialStructure->NumberOfLevels(); j++)
410 pDiffCrossSection >> tmp;
411 (*pDiffCrossSectionData)[j][tDummy][eDummy] = tmp;
417 (*pNrjTransfData)[j][tDummy][(*pDiffCrossSectionData)[j][tDummy][eDummy]] = eDummy;
418 (*pProbaShellMap)[j][tDummy].push_back((*pDiffCrossSectionData)[j][tDummy][eDummy]);
421 (*pDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
422 (*pVecm)[tDummy].push_back(eDummy);
429 pNrjTransStorage[mat] = pNrjTransfData;
430 pProbaShellStorage[mat] = pProbaShellMap;
433 pDiffDatatable[mat] = pDiffCrossSectionData;
434 pVecmStorage[mat] = pVecm;
436 pIncidentEnergyStorage[mat] = pTdummyVec;
440 delete pProbaShellMap;
441 delete pNrjTransfData;
443 delete pDiffCrossSectionData;
447 tableTCS[mat] = tableData;
449 if (particle==electronDef)
455 if (particle==protonDef)
463 G4cout <<
"MicroElec Inelastic model is initialized " <<
G4endl
468 <<
" with mass (amu) " << particle->
GetPDGMass()/proton_mass_c2
475 isInitialised =
true;
486 if (verboseLevel > 3)
G4cout <<
"Calling CrossSectionPerVolume() of G4MicroElecInelasticModel" <<
G4endl;
489 currentMaterial = material->
GetName().substr(3, material->
GetName().size());
491 MapStructure::iterator structPos;
492 structPos = tableMaterialsStructures.find(currentMaterial);
495 TCSMap::iterator tablepos;
496 tablepos = tableTCS.find(currentMaterial);
498 if (tablepos == tableTCS.end() )
501 str += currentMaterial +
" TCS Table not found!";
505 else if(structPos == tableMaterialsStructures.end())
508 str += currentMaterial +
" Structure not found!";
513 MapData* tableData = tablepos->second;
514 currentMaterialStructure = structPos->second;
523 G4double Zeff = 1.0, Zeff2 = Zeff*Zeff;
526 if (Mion_c2 > proton_mass_c2)
528 ekin *= proton_mass_c2 / Mion_c2;
529 nameLocal =
"proton";
532 G4double lowLim = currentMaterialStructure->GetInelasticModelLowLimit(pdg);
533 G4double highLim = currentMaterialStructure->GetInelasticModelHighLimit(pdg);
535 if (ekin >= lowLim && ekin < highLim)
537 std::map< G4String, G4MicroElecCrossSectionDataSet_new*, std::less<G4String> >::iterator pos;
538 pos = tableData->find(nameLocal);
540 if (pos != tableData->end())
545 sigma = table->FindValue(ekin);
547 if (Mion_c2 > proton_mass_c2) {
549 for (
G4int i = 0; i < currentMaterialStructure->NumberOfLevels(); i++) {
550 Zeff =
BKZ(ekin / (proton_mass_c2 / Mion_c2), Mion_c2 / c_squared, Z, currentMaterialStructure->Energy(i));
552 sigma += Zeff2*table->FindShellValue(ekin, i);
558 sigma = table->FindValue(ekin);
564 G4Exception(
"G4MicroElecInelasticModel_new::CrossSectionPerVolume",
566 "Model not applicable to particle type.");
574 if (verboseLevel > 3)
576 G4cout <<
"---> Kinetic energy (eV)=" << ekin / eV <<
G4endl;
577 G4cout <<
" - Cross section per Si atom (cm^2)=" << sigma / cm2 <<
G4endl;
578 G4cout <<
" - Cross section per Si atom (cm^-1)=" << sigma*density / (1. / cm) <<
G4endl;
581 return (sigma)*density;
593 if (verboseLevel > 3)
594 G4cout <<
"Calling SampleSecondaries() of G4MicroElecInelasticModel" <<
G4endl;
597 G4double lowLim = currentMaterialStructure->GetInelasticModelLowLimit(pdg);
598 G4double highLim = currentMaterialStructure->GetInelasticModelHighLimit(pdg);
605 G4String nameLocal2 = particleName ;
607 G4double originalMass = particleMass;
610 if (particleMass > proton_mass_c2)
612 k *= proton_mass_c2/particleMass ;
614 nameLocal2 =
"proton" ;
617 if (k >= lowLim && k < highLim)
620 G4double totalEnergy = ekin + particleMass;
621 G4double pSquare = ekin * (totalEnergy + particleMass);
622 G4double totalMomentum = std::sqrt(pSquare);
626 Shell = RandomSelect(k,nameLocal2,originalMass, originalZ);
628 G4double bindingEnergy = currentMaterialStructure->Energy(Shell);
629 G4double limitEnergy = currentMaterialStructure->GetLimitEnergy(Shell);
631 G4bool weaklyBound = currentMaterialStructure->IsShellWeaklyBound(Shell);
633 if (verboseLevel > 3)
635 G4cout <<
"---> Kinetic energy (eV)=" << k/eV <<
G4endl ;
636 G4cout <<
"Shell: " << Shell <<
", energy: " << bindingEnergy/eV <<
G4endl;
641 if (weaklyBound && k > currentMaterialStructure->GetEnergyGap()) {
642 limitEnergy = currentMaterialStructure->GetEnergyGap();
649 std::size_t secNumberInit = 0;
650 std::size_t secNumberFinal = 0;
653 G4int Z = currentMaterialStructure->GetZ(Shell);
654 G4int shellEnum = currentMaterialStructure->GetEADL_Enumerator(Shell);
655 if (currentMaterialStructure->IsShellWeaklyBound(Shell)) { shellEnum = -1; }
656 if(fAtomDeexcitation && shellEnum >=0)
660 const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
661 secNumberInit = fvect->size();
662 fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
663 secNumberFinal = fvect->size();
667 SEFromFermiLevel =
false;
670 secondaryKinetic = RandomizeEjectedElectronEnergy(PartDef, k, Shell, originalMass, originalZ);
674 secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulatedDcs(PartDef, k, Shell) ;
677 if (verboseLevel > 3)
680 G4cout <<
"Shell: " << Shell <<
" Kin. energy (eV)=" << k/eV<<
" Sec. energy (eV)=" << secondaryKinetic/eV <<
G4endl;
687 G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
689 G4double finalPx = totalMomentum*primaryDirection.
x() - deltaTotalMomentum*deltaDirection.
x();
690 G4double finalPy = totalMomentum*primaryDirection.
y() - deltaTotalMomentum*deltaDirection.
y();
691 G4double finalPz = totalMomentum*primaryDirection.
z() - deltaTotalMomentum*deltaDirection.
z();
692 G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
693 finalPx /= finalMomentum;
694 finalPy /= finalMomentum;
695 finalPz /= finalMomentum;
698 direction.
set(finalPx,finalPy,finalPz);
700 fParticleChangeForGamma->ProposeMomentumDirection(direction.
unit());
702 else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection);
706 for (std::size_t j=secNumberInit; j < secNumberFinal; ++j) {
707 deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();
717 fParticleChangeForGamma->SetProposedKineticEnergy(ekin - secondaryKinetic-limitEnergy);
718 fParticleChangeForGamma->ProposeLocalEnergyDeposit(limitEnergy-deexSecEnergy);
720 if (secondaryKinetic>0)
723 fvect->push_back(dp);
730G4double G4MicroElecInelasticModel_new::RandomizeEjectedElectronEnergy(
734 G4double secondaryElectronKineticEnergy=0.;
740 G4double maxEnergy = maximumEnergyTransfer;
741 G4int nEnergySteps = 100;
744 G4double stpEnergy(std::pow(maxEnergy/value, 1./
static_cast<G4double>(nEnergySteps-1)));
745 G4int step(nEnergySteps);
751 crossSectionMaximum = std::max(crossSectionMaximum, differentialCrossSection);
758 (maximumEnergyTransfer-currentMaterialStructure->GetLimitEnergy(shell));
761 (secondaryElectronKineticEnergy+currentMaterialStructure->GetLimitEnergy(shell)),shell));
763 return secondaryElectronKineticEnergy;
769 currentMaterialStructure->Energy(shell),
770 originalMass/c_squared, electron_mass_c2/c_squared);
774 G4double minEnergy = currentMaterialStructure->GetLimitEnergy(shell);
775 G4double maxEnergy = maximumEnergyTransfer;
776 G4int nEnergySteps = 100;
779 G4double stpEnergy(std::pow(maxEnergy/value, 1./
static_cast<G4double>(nEnergySteps-1)));
780 G4int step(nEnergySteps);
786 crossSectionMaximum = std::max(crossSectionMaximum, differentialCrossSection);
797 secondaryElectronKineticEnergy = energyTransfer-currentMaterialStructure->GetLimitEnergy(shell);
800 return std::max(secondaryElectronKineticEnergy, 0.0);
805G4double G4MicroElecInelasticModel_new::RandomizeEjectedElectronEnergyFromCumulatedDcs(
808 G4double secondaryElectronKineticEnergy = 0.;
810 G4bool weaklyBound = currentMaterialStructure->IsShellWeaklyBound(shell);
811 G4double transf = TransferedEnergy(particleDefinition, k, shell, random);
813 secondaryElectronKineticEnergy = transf - currentMaterialStructure->GetLimitEnergy(shell);
814 if(secondaryElectronKineticEnergy <= 0.) {
815 secondaryElectronKineticEnergy = 0.0;
819 secondaryElectronKineticEnergy = transf - currentMaterialStructure->GetLimitEnergy(shell);
821 if (secondaryElectronKineticEnergy <= 0.) {
822 secondaryElectronKineticEnergy = 0.0;
823 SEFromFermiLevel =
true;
827 return secondaryElectronKineticEnergy;
832G4double G4MicroElecInelasticModel_new::TransferedEnergy(
835 G4int ionizationLevelIndex,
850 G4double maximumEnergyTransfer1 = 0;
851 G4double maximumEnergyTransfer2 = 0;
852 G4double maximumEnergyTransferP = 4.* (electron_mass_c2 / proton_mass_c2) * k;
857 dataDiffCSMap::iterator iterator_Nrj;
858 iterator_Nrj = eNrjTransStorage.find(currentMaterial);
860 dataProbaShellMap::iterator iterator_Proba;
861 iterator_Proba = eProbaShellStorage.find(currentMaterial);
863 incidentEnergyMap::iterator iterator_Tdummy;
864 iterator_Tdummy = eIncidentEnergyStorage.find(currentMaterial);
866 if(iterator_Nrj == eNrjTransStorage.end() || iterator_Proba == eProbaShellStorage.end() || iterator_Tdummy == eIncidentEnergyStorage.end())
868 G4String str =
"Material ";
869 str += currentMaterial +
" not found!";
870 G4Exception(
"G4MicroElecInelasticModel_new::TransferedEnergy",
"em0002",
875 vector<TriDimensionMap>* eNrjTransfData = iterator_Nrj->second;
876 vector<VecMap>* eProbaShellMap = iterator_Proba->second;
877 vector<G4double>* eTdummyVec = iterator_Tdummy->second;
880 auto k2 = std::upper_bound(eTdummyVec->begin(),eTdummyVec->end(),k);
884 if (random <= (*eProbaShellMap)[ionizationLevelIndex][(*k1)].back()
885 && random <= (*eProbaShellMap)[ionizationLevelIndex][(*k2)].back())
888 std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k1)].begin(),
889 (*eProbaShellMap)[ionizationLevelIndex][(*k1)].end(),
892 auto prob11 = prob12 - 1;
895 std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
896 (*eProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
899 auto prob21 = prob22 - 1;
903 valuePROB21 = *prob21;
904 valuePROB22 = *prob22;
905 valuePROB12 = *prob12;
906 valuePROB11 = *prob11;
910 else nrjTransf11 = (*eNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB11];
912 if (valuePROB12 == 1)
914 if ((valueK1 + bindingEnergy) / 2. > valueK1)
915 maximumEnergyTransfer1 = valueK1;
918 nrjTransf12 = maximumEnergyTransfer1;
921 nrjTransf12 = (*eNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB12];
924 else nrjTransf21 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
926 if (valuePROB22 == 1)
928 if ((valueK2 + bindingEnergy) / 2. > valueK2) maximumEnergyTransfer2 = valueK2;
929 else maximumEnergyTransfer2 = (valueK2 +
bindingEnergy) / 2.;
930 nrjTransf22 = maximumEnergyTransfer2;
932 else nrjTransf22 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
935 if (random > (*eProbaShellMap)[ionizationLevelIndex][(*k1)].back())
938 std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
939 (*eProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
941 auto prob21 = prob22 - 1;
945 valuePROB21 = *prob21;
946 valuePROB22 = *prob22;
948 nrjTransf21 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
949 nrjTransf22 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
951 G4double interpolatedvalue2 = Interpolate(valuePROB21,
958 G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
966 dataDiffCSMap::iterator iterator_Nrj;
967 iterator_Nrj = pNrjTransStorage.find(currentMaterial);
969 dataProbaShellMap::iterator iterator_Proba;
970 iterator_Proba = pProbaShellStorage.find(currentMaterial);
972 incidentEnergyMap::iterator iterator_Tdummy;
973 iterator_Tdummy = pIncidentEnergyStorage.find(currentMaterial);
975 if (iterator_Nrj == pNrjTransStorage.end() || iterator_Proba == pProbaShellStorage.end() || iterator_Tdummy == pIncidentEnergyStorage.end())
977 G4String str =
"Material ";
978 str += currentMaterial +
" not found!";
983 vector<TriDimensionMap>* pNrjTransfData = iterator_Nrj->second;
984 vector<VecMap>* pProbaShellMap = iterator_Proba->second;
985 vector<G4double>* pTdummyVec = iterator_Tdummy->second;
987 auto k2 = std::upper_bound(pTdummyVec->begin(),
995 if (random <= (*pProbaShellMap)[ionizationLevelIndex][(*k1)].back()
996 && random <= (*pProbaShellMap)[ionizationLevelIndex][(*k2)].back())
999 std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k1)].begin(),
1000 (*pProbaShellMap)[ionizationLevelIndex][(*k1)].end(),
1002 auto prob11 = prob12 - 1;
1004 std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
1005 (*pProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
1007 auto prob21 = prob22 - 1;
1011 valuePROB21 = *prob21;
1012 valuePROB22 = *prob22;
1013 valuePROB12 = *prob12;
1014 valuePROB11 = *prob11;
1019 else nrjTransf11 = (*pNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB11];
1021 if (valuePROB12 == 1) nrjTransf12 = maximumEnergyTransferP;
1022 else nrjTransf12 = (*pNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB12];
1025 else nrjTransf21 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
1027 if (valuePROB22 == 1) nrjTransf22 = maximumEnergyTransferP;
1028 else nrjTransf22 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
1032 if (random > (*pProbaShellMap)[ionizationLevelIndex][(*k1)].back())
1035 std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
1036 (*pProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
1039 auto prob21 = prob22 - 1;
1043 valuePROB21 = *prob21;
1044 valuePROB22 = *prob22;
1046 nrjTransf21 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
1047 nrjTransf22 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
1049 G4double interpolatedvalue2 = Interpolate(valuePROB21,
1055 G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
1061 G4double nrjTransfProduct = nrjTransf11 * nrjTransf12 * nrjTransf21 * nrjTransf22;
1063 if (nrjTransfProduct != 0.)
1065 nrj = QuadInterpolator(valuePROB11,
1092 if (energyTransfer >= currentMaterialStructure->GetLimitEnergy(LevelIndex))
1108 dataDiffCSMap::iterator iterator_Proba;
1109 iterator_Proba = eDiffDatatable.find(currentMaterial);
1111 incidentEnergyMap::iterator iterator_Nrj;
1112 iterator_Nrj = eIncidentEnergyStorage.find(currentMaterial);
1114 TranfEnergyMap::iterator iterator_TransfNrj;
1115 iterator_TransfNrj = eVecmStorage.find(currentMaterial);
1117 if (iterator_Proba != eDiffDatatable.end() && iterator_Nrj != eIncidentEnergyStorage.end()
1118 && iterator_TransfNrj!= eVecmStorage.end())
1120 vector<TriDimensionMap>* eDiffCrossSectionData = (iterator_Proba->second);
1121 vector<G4double>* eTdummyVec = iterator_Nrj->second;
1122 VecMap* eVecm = iterator_TransfNrj->second;
1125 auto t2 = std::upper_bound(eTdummyVec->begin(), eTdummyVec->end(), k);
1128 if (energyTransfer <= (*eVecm)[(*t1)].back() && energyTransfer <= (*eVecm)[(*t2)].back())
1130 auto e12 = std::upper_bound((*eVecm)[(*t1)].begin(), (*eVecm)[(*t1)].end(), energyTransfer);
1132 auto e22 = std::upper_bound((*eVecm)[(*t2)].begin(), (*eVecm)[(*t2)].end(), energyTransfer);
1142 xs11 = (*eDiffCrossSectionData)[LevelIndex][valueT1][valueE11];
1143 xs12 = (*eDiffCrossSectionData)[LevelIndex][valueT1][valueE12];
1144 xs21 = (*eDiffCrossSectionData)[LevelIndex][valueT2][valueE21];
1145 xs22 = (*eDiffCrossSectionData)[LevelIndex][valueT2][valueE22];
1150 str += currentMaterial +
" not found!";
1157 dataDiffCSMap::iterator iterator_Proba;
1158 iterator_Proba = pDiffDatatable.find(currentMaterial);
1160 incidentEnergyMap::iterator iterator_Nrj;
1161 iterator_Nrj = pIncidentEnergyStorage.find(currentMaterial);
1163 TranfEnergyMap::iterator iterator_TransfNrj;
1164 iterator_TransfNrj = pVecmStorage.find(currentMaterial);
1166 if (iterator_Proba != pDiffDatatable.end() && iterator_Nrj != pIncidentEnergyStorage.end()
1167 && iterator_TransfNrj != pVecmStorage.end())
1169 vector<TriDimensionMap>* pDiffCrossSectionData = (iterator_Proba->second);
1170 vector<G4double>* pTdummyVec = iterator_Nrj->second;
1171 VecMap* pVecm = iterator_TransfNrj->second;
1175 std::upper_bound(pTdummyVec->begin(), pTdummyVec->end(), k);
1177 if (energyTransfer <= (*pVecm)[(*t1)].back() && energyTransfer <= (*pVecm)[(*t2)].back())
1179 auto e12 = std::upper_bound((*pVecm)[(*t1)].begin(), (*pVecm)[(*t1)].end(), energyTransfer);
1181 auto e22 = std::upper_bound((*pVecm)[(*t2)].begin(), (*pVecm)[(*t2)].end(), energyTransfer);
1191 xs11 = (*pDiffCrossSectionData)[LevelIndex][valueT1][valueE11];
1192 xs12 = (*pDiffCrossSectionData)[LevelIndex][valueT1][valueE12];
1193 xs21 = (*pDiffCrossSectionData)[LevelIndex][valueT2][valueE21];
1194 xs22 = (*pDiffCrossSectionData)[LevelIndex][valueT2][valueE22];
1199 str += currentMaterial +
" not found!";
1204 G4double xsProduct = xs11 * xs12 * xs21 * xs22;
1205 if (xsProduct != 0.)
1207 sigma = QuadInterpolator( valueE11, valueE12,
1230 if (e == e1 || e1 == e2 ) {
return xs1; }
1231 if (e == e2) {
return xs2; }
1234 if (e1 > 0. && e2 > 0. && xs1 > 0. && xs2 > 0. && !fasterCode)
1236 G4double a = std::log(xs2/xs1)/ std::log(e2/e1);
1237 G4double b = std::log(xs2) - a * std::log(e2);
1238 G4double sigma = a * std::log(e) + b;
1239 value = (std::exp(sigma));
1243 else if (xs1 > 0. && xs2 > 0. && fasterCode)
1247 value = std::exp((d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
1256 value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
1271 G4double interpolatedvalue1 = Interpolate(e11, e12, e, xs11, xs12);
1272 G4double interpolatedvalue2 = Interpolate(e21, e22, e, xs21, xs22);
1273 G4double value = Interpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
1283 TCSMap::iterator tablepos;
1284 tablepos = tableTCS.find(currentMaterial);
1285 if (tablepos == tableTCS.end()) {
1290 MapData* tableData = tablepos->second;
1292 std::map< G4String,G4MicroElecCrossSectionDataSet_new*,std::less<G4String> >::iterator
pos;
1293 pos = tableData->find(particle);
1295 std::vector<G4double> Zeff(currentMaterialStructure->NumberOfLevels(), 1.0);
1296 if(originalMass>proton_mass_c2) {
1297 for(
G4int nl=0;nl<currentMaterialStructure->NumberOfLevels();nl++) {
1298 Zeff[nl] =
BKZ(k/(proton_mass_c2/originalMass), originalMass/c_squared, originalZ, currentMaterialStructure->Energy(nl));
1302 if (pos != tableData->end())
1304 G4MicroElecCrossSectionDataSet_new*
table =
pos->second;
1316 valuesBuffer[i] =
table->GetComponent(i)->FindValue(k)*Zeff[i]*Zeff[i];
1317 value += valuesBuffer[i];
1327 if (valuesBuffer[i] > value)
1329 delete[] valuesBuffer;
1332 value -= valuesBuffer[i];
1335 if (valuesBuffer)
delete[] valuesBuffer;
1341 G4Exception(
"G4MicroElecInelasticModel_new::RandomSelect",
"em0002",
FatalException,
"Model not applicable to particle type.");
1351 return c_light*std::sqrt(x*(x + 2.0))/(x + 1.0);
1360 G4double v2f = 2*M1/(M1+M2)*v1i + (M2-M1)/(M1+M2)*-1*v2i;
1361 G4double vtransfer2a = v2f*v2f-v2i*v2i;
1363 v2f = 2*M1/(M1+M2)*v1i + (M2-M1)/(M1+M2)*v2i;
1364 G4double vtransfer2b = v2f*v2f-v2i*v2i;
1366 G4double vtransfer2 = std::max(vtransfer2a, vtransfer2b);
1367 return 0.5*M2*vtransfer2;
1373 return (x < 0.) ? 1.0 : 0.0;
1380 G4double r = vF*( std::pow(v/vF+1., 3.) - fabs(std::pow(v/vF-1., 3.))
1381 + 4.*(v/vF)*(v/vF) ) +
stepFunc(v/vF-1.) * (3./2.*v/vF -
1382 4.*(v/vF)*(v/vF) + 3.*std::pow(v/vF, 3.)
1383 - 0.5*std::pow(v/vF, 5.));
1384 return r/(10.*v/vF);
1392 G4double hbar = hbar_Planck, hbar2 = hbar*hbar, me = electron_mass_c2/c_squared, Ry = me*elm_coupling*elm_coupling/(2*hbar2);
1393 G4double hartree = 2*Ry,
a0 = Bohr_radius, velocity =
a0*hartree/hbar;
1399 G4double a = std::pow(4./9./CLHEP::pi, 1./3.);
1400 G4double vF = std::pow(wp*wp/(3.*a*a*a), 1./3.);
1403 G4double yr = vr/std::pow(Zp, 2./3.);
1405 if(Zp==2) q = 1-exp(-c*vr/(Zp-5./16.));
1406 else q = 1.-exp(-c*(yr-0.07));
1409 if(Neq<=2) l0 = 3./(Zp-0.3*(Neq-1))/2.;
1410 else l0 = 0.48*std::pow(Neq, 2./3.)/(Zp-Neq/7.);
1413 return Zp*(q + c*(1.-q)/vF/vF/2.0 * log(1.+std::pow(2.*l0*vF,2.)));
const char * G4FindDataDir(const char *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4ThreeVector G4ParticleMomentum
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
const G4ThreeVector & GetMomentumDirection() const
const G4ParticleDefinition * GetParticleDefinition() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * ElectronDefinition()
static G4Electron * Electron()
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
G4double GetTotNbOfAtomsPerVolume() const
const G4String & GetName() const
G4bool LoadData(const G4String &argFileName) override
G4double DifferentialCrossSection(const G4ParticleDefinition *aParticleDefinition, G4double k, G4double energyTransfer, G4int shell)
G4double stepFunc(G4double x)
G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax) override
G4MicroElecInelasticModel_new(const G4ParticleDefinition *p=nullptr, const G4String &nam="MicroElecInelasticModel")
~G4MicroElecInelasticModel_new() override
G4double ComputeElasticQmax(G4double T1i, G4double T2i, G4double m1, G4double m2)
G4double BKZ(G4double Ep, G4double mp, G4int Zp, G4double EF)
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
G4double ComputeRelativistVelocity(G4double E, G4double mass)
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
G4double vrkreussler(G4double v, G4double vF)
G4double GetLimitEnergy(G4int level)
G4int GetAtomicNumber() const
G4double GetPDGMass() const
G4int GetPDGEncoding() const
G4double GetPDGCharge() const
const G4String & GetParticleName() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
static G4Proton * ProtonDefinition()
virtual G4ThreeVector & SampleDirectionForShell(const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, G4int shellID, const G4Material *)
void SetHighEnergyLimit(G4double)
G4VEmAngularDistribution * GetAngularDistribution()
G4ParticleChangeForGamma * GetParticleChangeForGamma()
G4double LowEnergyLimit() const
G4double HighEnergyLimit() const
void SetLowEnergyLimit(G4double)
void SetDeexcitationFlag(G4bool val)
G4VEmModel(const G4String &nam)
void SetAngularDistribution(G4VEmAngularDistribution *)
G4double bindingEnergy(G4int A, G4int Z)