112 G4cout <<
"MicroElec inelastic model is constructed " <<
G4endl;
117 fAtomDeexcitation =
nullptr;
125 SEFromFermiLevel =
false;
134 TCSMap::iterator pos2;
135 for (pos2 = tableTCS.begin(); pos2 != tableTCS.end(); ++pos2) {
136 MapData* tableData = pos2->second;
137 for (
auto pos = tableData->begin(); pos != tableData->end(); ++pos)
146 dataDiffCSMap::iterator iterator_proba;
148 for (iterator_proba = eNrjTransStorage.begin(); iterator_proba != eNrjTransStorage.end(); ++iterator_proba) {
149 vector<TriDimensionMap>* eNrjTransfData = iterator_proba->second;
150 eNrjTransfData->clear();
151 delete eNrjTransfData;
153 eNrjTransStorage.clear();
155 for (iterator_proba = pNrjTransStorage.begin(); iterator_proba != pNrjTransStorage.end(); ++iterator_proba) {
156 vector<TriDimensionMap>* pNrjTransfData = iterator_proba->second;
157 pNrjTransfData->clear();
158 delete pNrjTransfData;
160 pNrjTransStorage.clear();
163 for (iterator_proba = eDiffDatatable.begin(); iterator_proba != eDiffDatatable.end(); ++iterator_proba) {
164 vector<TriDimensionMap>* eDiffCrossSectionData = iterator_proba->second;
165 eDiffCrossSectionData->clear();
166 delete eDiffCrossSectionData;
168 eDiffDatatable.clear();
170 for (iterator_proba = pDiffDatatable.begin(); iterator_proba != pDiffDatatable.end(); ++iterator_proba) {
171 vector<TriDimensionMap>* pDiffCrossSectionData = iterator_proba->second;
172 pDiffCrossSectionData->clear();
173 delete pDiffCrossSectionData;
175 pDiffDatatable.clear();
178 dataProbaShellMap::iterator iterator_probaShell;
180 for (iterator_probaShell = eProbaShellStorage.begin(); iterator_probaShell != eProbaShellStorage.end(); ++iterator_probaShell) {
181 vector<VecMap>* eProbaShellMap = iterator_probaShell->second;
182 eProbaShellMap->clear();
183 delete eProbaShellMap;
185 eProbaShellStorage.clear();
187 for (iterator_probaShell = pProbaShellStorage.begin(); iterator_probaShell != pProbaShellStorage.end(); ++iterator_probaShell) {
188 vector<VecMap>* pProbaShellMap = iterator_probaShell->second;
189 pProbaShellMap->clear();
190 delete pProbaShellMap;
192 pProbaShellStorage.clear();
195 TranfEnergyMap::iterator iterator_nrjtransf;
196 for (iterator_nrjtransf = eVecmStorage.begin(); iterator_nrjtransf != eVecmStorage.end(); ++iterator_nrjtransf) {
197 VecMap* eVecm = iterator_nrjtransf->second;
201 eVecmStorage.clear();
202 for (iterator_nrjtransf = pVecmStorage.begin(); iterator_nrjtransf != pVecmStorage.end(); ++iterator_nrjtransf) {
203 VecMap* pVecm = iterator_nrjtransf->second;
207 pVecmStorage.clear();
210 incidentEnergyMap::iterator iterator_energy;
211 for (iterator_energy = eIncidentEnergyStorage.begin(); iterator_energy != eIncidentEnergyStorage.end(); ++iterator_energy) {
212 std::vector<G4double>* eTdummyVec = iterator_energy->second;
216 eIncidentEnergyStorage.clear();
218 for (iterator_energy = pIncidentEnergyStorage.begin(); iterator_energy != pIncidentEnergyStorage.end(); ++iterator_energy) {
219 std::vector<G4double>* pTdummyVec = iterator_energy->second;
223 pIncidentEnergyStorage.clear();
226 MapStructure::iterator iterator_matStructure;
227 for (iterator_matStructure = tableMaterialsStructures.begin();
228 iterator_matStructure != tableMaterialsStructures.end(); ++iterator_matStructure) {
229 currentMaterialStructure = iterator_matStructure->second;
230 delete currentMaterialStructure;
232 tableMaterialsStructures.clear();
233 currentMaterialStructure =
nullptr;
241 if (isInitialised) {
return; }
243 if (verboseLevel > 3)
244 G4cout <<
"Calling G4MicroElecInelasticModel_new::Initialise()" <<
G4endl;
266 lowEnergyLimit[electron] = 2 * eV;
267 highEnergyLimit[electron] = 10.0 * MeV;
273 for (
G4int i = 0; i < numOfCouples; ++i) {
275 G4cout <<
"Material " << i + 1 <<
" / " << numOfCouples <<
" : " << material->
GetName() <<
G4endl;
276 if (material->
GetName() ==
"Vacuum")
continue;
278 MapData* tableData =
new MapData;
281 tableMaterialsStructures[mat] = currentMaterialStructure;
282 if (particle == electronDef) {
284 G4String fileElectron(
"Inelastic/" + modelName +
"_sigma_inelastic_e-_" + mat);
288 tableData->insert(make_pair(electron, tableE));
291 std::ostringstream eFullFileName;
293 eFullFileName << path <<
"/microelec/Inelastic/cumulated_" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat";
295 G4cout <<
"Inelastic/cumulated_" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat" <<
G4endl;
298 eFullFileName << path <<
"/microelec/Inelastic/" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat";
300 G4cout <<
"Inelastic/" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat" <<
G4endl;
303 std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
304 if (!eDiffCrossSection)
306 std::stringstream ss;
307 ss <<
"Missing data " << eFullFileName.str().c_str();
308 std::string sortieString = ss.str();
310 if (fasterCode)
G4Exception(
"G4MicroElecInelasticModel_new::Initialise",
"em0003",
314 G4Exception(
"G4MicroElecInelasticModel_new::Initialise",
"em0003",
315 FatalException,
"Missing data file:/microelec/sigmadiff_inelastic_e_Si.dat");
323 vector<TriDimensionMap>* eDiffCrossSectionData =
324 new vector<TriDimensionMap>;
325 vector<TriDimensionMap>* eNrjTransfData =
326 new vector<TriDimensionMap>;
327 vector<VecMap>* eProbaShellMap =
new vector<VecMap>;
328 vector<G4double>* eTdummyVec =
new vector<G4double>;
329 VecMap* eVecm =
new VecMap;
331 for (
int j = 0; j < currentMaterialStructure->
NumberOfLevels(); j++)
333 eDiffCrossSectionData->push_back(TriDimensionMap());
334 eNrjTransfData->push_back(TriDimensionMap());
335 eProbaShellMap->push_back(VecMap());
338 eTdummyVec->push_back(0.);
339 while (!eDiffCrossSection.eof())
343 eDiffCrossSection >> tDummy >> eDummy;
344 if (tDummy != eTdummyVec->back()) eTdummyVec->push_back(tDummy);
347 for (
int j = 0; j < currentMaterialStructure->
NumberOfLevels(); j++)
349 eDiffCrossSection >> tmp;
350 (*eDiffCrossSectionData)[j][tDummy][eDummy] = tmp;
354 (*eNrjTransfData)[j][tDummy][(*eDiffCrossSectionData)[j][tDummy][eDummy]] = eDummy;
355 (*eProbaShellMap)[j][tDummy].push_back((*eDiffCrossSectionData)[j][tDummy][eDummy]);
358 if (!eDiffCrossSection.eof()) (*eDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
359 (*eVecm)[tDummy].push_back(eDummy);
368 eNrjTransStorage[mat] = eNrjTransfData;
369 eProbaShellStorage[mat] = eProbaShellMap;
372 eDiffDatatable[mat] = eDiffCrossSectionData;
373 eVecmStorage[mat] = eVecm;
375 eIncidentEnergyStorage[mat] = eTdummyVec;
384 if (particle == protonDef)
387 G4String fileProton(
"Inelastic/" + modelName +
"_sigma_inelastic_p_" + mat);
G4cout << fileProton <<
G4endl;
390 tableData->insert(make_pair(proton, tableP));
393 std::ostringstream pFullFileName;
395 pFullFileName << path <<
"/microelec/Inelastic/cumulated_" + modelName +
"_sigmadiff_inelastic_p_" + mat +
".dat";
397 G4cout <<
"Inelastic/cumulated_" + modelName +
"_sigmadiff_inelastic_p_" + mat +
".dat" <<
G4endl;
400 pFullFileName << path <<
"/microelec/Inelastic/" + modelName +
"_sigmadiff_inelastic_p_" + mat +
".dat";
402 G4cout <<
"Inelastic/" + modelName +
"_sigmadiff_inelastic_e-_" + mat +
".dat" <<
G4endl;
405 std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
406 if (!pDiffCrossSection)
408 if (fasterCode)
G4Exception(
"G4MicroElecInelasticModel_new::Initialise",
"em0003",
409 FatalException,
"Missing data file:/microelec/sigmadiff_cumulated_inelastic_p_Si.dat");
411 G4Exception(
"G4MicroElecInelasticModel_new::Initialise",
"em0003",
412 FatalException,
"Missing data file:/microelec/sigmadiff_inelastic_p_Si.dat");
422 vector<TriDimensionMap>* pDiffCrossSectionData =
423 new vector<TriDimensionMap>;
424 vector<TriDimensionMap>* pNrjTransfData =
425 new vector<TriDimensionMap>;
426 vector<VecMap>* pProbaShellMap =
428 vector<G4double>* pTdummyVec =
429 new vector<G4double>;
430 VecMap* eVecm =
new VecMap;
432 for (
int j = 0; j < currentMaterialStructure->
NumberOfLevels(); ++j)
435 pDiffCrossSectionData->push_back(TriDimensionMap());
436 pNrjTransfData->push_back(TriDimensionMap());
437 pProbaShellMap->push_back(VecMap());
440 pTdummyVec->push_back(0.);
441 while (!pDiffCrossSection.eof())
445 pDiffCrossSection >> tDummy >> eDummy;
446 if (tDummy != pTdummyVec->back()) pTdummyVec->push_back(tDummy);
449 for (
int j = 0; j < currentMaterialStructure->
NumberOfLevels(); j++)
451 pDiffCrossSection >> tmp;
452 (*pDiffCrossSectionData)[j][tDummy][eDummy] = tmp;
459 (*pNrjTransfData)[j][tDummy][(*pDiffCrossSectionData)[j][tDummy][eDummy]] = eDummy;
460 (*pProbaShellMap)[j][tDummy].push_back((*pDiffCrossSectionData)[j][tDummy][eDummy]);
463 if (!pDiffCrossSection.eof()) (*pDiffCrossSectionData)[j][tDummy][eDummy] *= scaleFactor;
464 (*eVecm)[tDummy].push_back(eDummy);
471 pNrjTransStorage[mat] = pNrjTransfData;
472 pProbaShellStorage[mat] = pProbaShellMap;
475 pDiffDatatable[mat] = pDiffCrossSectionData;
476 pVecmStorage[mat] = eVecm;
478 pIncidentEnergyStorage[mat] = pTdummyVec;
486 tableTCS[mat] = tableData;
488 if (particle==electronDef)
494 if (particle==protonDef)
502 G4cout <<
"MicroElec Inelastic model is initialized " <<
G4endl
507 <<
" with mass (amu) " << particle->
GetPDGMass()/proton_mass_c2
515 isInitialised =
true;
526 if (verboseLevel > 3)
G4cout <<
"Calling CrossSectionPerVolume() of G4MicroElecInelasticModel" <<
G4endl;
529 currentMaterial = material->
GetName().substr(3, material->
GetName().size());
531 MapStructure::iterator structPos;
532 structPos = tableMaterialsStructures.find(currentMaterial);
535 TCSMap::iterator tablepos;
536 tablepos = tableTCS.find(currentMaterial);
538 if (tablepos == tableTCS.end() )
541 str += currentMaterial +
" TCS Table not found!";
545 else if(structPos == tableMaterialsStructures.end())
548 str += currentMaterial +
" Structure not found!";
553 MapData* tableData = tablepos->second;
554 currentMaterialStructure = structPos->second;
563 G4double Zeff = 1.0, Zeff2 = Zeff*Zeff;
566 if (Mion_c2 > proton_mass_c2)
568 ekin *= proton_mass_c2 / Mion_c2;
569 nameLocal =
"proton";
575 if (ekin >= lowLim && ekin < highLim)
577 std::map< G4String, G4MicroElecCrossSectionDataSet_new*, std::less<G4String> >::iterator pos;
578 pos = tableData->find(nameLocal);
580 if (pos != tableData->end())
587 if (Mion_c2 > proton_mass_c2) {
590 Zeff =
BKZ(ekin / (proton_mass_c2 / Mion_c2), Mion_c2 / c_squared,
Z, currentMaterialStructure->
Energy(i));
605 G4Exception(
"G4MicroElecInelasticModel_new::CrossSectionPerVolume",
607 "Model not applicable to particle type.");
615 if (verboseLevel > 3)
617 G4cout <<
"---> Kinetic energy (eV)=" << ekin / eV <<
G4endl;
618 G4cout <<
" - Cross section per Si atom (cm^2)=" << sigma / cm2 <<
G4endl;
619 G4cout <<
" - Cross section per Si atom (cm^-1)=" << sigma*density / (1. / cm) <<
G4endl;
622 return (sigma)*density;}
635 if (verboseLevel > 3)
636 G4cout <<
"Calling SampleSecondaries() of G4MicroElecInelasticModel" <<
G4endl;
647 G4String nameLocal2 = particleName ;
649 G4double originalMass = particleMass;
652 if (particleMass > proton_mass_c2)
654 k *= proton_mass_c2/particleMass ;
656 nameLocal2 =
"proton" ;
659 if (k >= lowLim && k < highLim)
662 G4double totalEnergy = ekin + particleMass;
663 G4double pSquare = ekin * (totalEnergy + particleMass);
664 G4double totalMomentum = std::sqrt(pSquare);
668 Shell = RandomSelect(k,nameLocal2,originalMass, originalZ);
673 if (verboseLevel > 3)
675 G4cout <<
"---> Kinetic energy (eV)=" << k/eV <<
G4endl ;
676 G4cout <<
"Shell: " << Shell <<
", energy: " << bindingEnergy/eV <<
G4endl;
681 std::size_t secNumberInit = 0;
682 std::size_t secNumberFinal = 0;
686 if (k<limitEnergy)
return;
688 G4int Z = currentMaterialStructure->
GetZ(Shell);
692 if(fAtomDeexcitation && shellEnum >=0)
697 secNumberInit = fvect->size();
699 secNumberFinal = fvect->size();
703 SEFromFermiLevel =
false;
706 secondaryKinetic = RandomizeEjectedElectronEnergy(PartDef, k, Shell, originalMass, originalZ);
710 secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulatedDcs(PartDef, k, Shell) ;
713 if (verboseLevel > 3)
716 G4cout <<
"Shell: " << Shell <<
" Kin. energy (eV)=" << k/eV
717 <<
" Sec. energy (eV)=" << secondaryKinetic/eV <<
G4endl;
726 G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
728 G4double finalPx = totalMomentum*primaryDirection.
x() - deltaTotalMomentum*deltaDirection.
x();
729 G4double finalPy = totalMomentum*primaryDirection.
y() - deltaTotalMomentum*deltaDirection.
y();
730 G4double finalPz = totalMomentum*primaryDirection.
z() - deltaTotalMomentum*deltaDirection.
z();
731 G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
732 finalPx /= finalMomentum;
733 finalPy /= finalMomentum;
734 finalPz /= finalMomentum;
737 direction.
set(finalPx,finalPy,finalPz);
745 for (std::size_t j=secNumberInit; j < secNumberFinal; ++j) {
746 deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();
748 if (SEFromFermiLevel) limitEnergy = currentMaterialStructure->
GetEnergyGap();
752 if (secondaryKinetic>0)
755 fvect->push_back(dp);
762G4double G4MicroElecInelasticModel_new::RandomizeEjectedElectronEnergy(
766 G4double secondaryElectronKineticEnergy=0.;
772 G4double maxEnergy = maximumEnergyTransfer;
773 G4int nEnergySteps = 100;
776 G4double stpEnergy(std::pow(maxEnergy/value, 1./
static_cast<G4double>(nEnergySteps-1)));
777 G4int step(nEnergySteps);
783 crossSectionMaximum = std::max(crossSectionMaximum, differentialCrossSection);
790 (maximumEnergyTransfer-currentMaterialStructure->
GetLimitEnergy(shell));
793 (secondaryElectronKineticEnergy+currentMaterialStructure->
GetLimitEnergy(shell)),shell));
799 currentMaterialStructure->
Energy(shell),
800 originalMass/c_squared, electron_mass_c2/c_squared);
805 G4double maxEnergy = maximumEnergyTransfer;
806 G4int nEnergySteps = 100;
809 G4double stpEnergy(std::pow(maxEnergy/value, 1./
static_cast<G4double>(nEnergySteps-1)));
810 G4int step(nEnergySteps);
817 crossSectionMaximum = std::max(crossSectionMaximum, differentialCrossSection);
828 secondaryElectronKineticEnergy =
832 return std::max(secondaryElectronKineticEnergy, 0.0);
837G4double G4MicroElecInelasticModel_new::RandomizeEjectedElectronEnergyFromCumulatedDcs(
840 G4double secondaryElectronKineticEnergy = 0.;
843 secondaryElectronKineticEnergy = TransferedEnergy(particleDefinition, k, shell, random)
846 if (isnan(secondaryElectronKineticEnergy)) { secondaryElectronKineticEnergy = k - currentMaterialStructure->
GetLimitEnergy(shell); }
848 if (secondaryElectronKineticEnergy < 0.) {
849 secondaryElectronKineticEnergy = k - currentMaterialStructure->
GetEnergyGap();
850 SEFromFermiLevel =
true;
852 return secondaryElectronKineticEnergy;
857G4double G4MicroElecInelasticModel_new::TransferedEnergy(
860 G4int ionizationLevelIndex,
875 G4double maximumEnergyTransfer1 = 0;
876 G4double maximumEnergyTransfer2 = 0;
877 G4double maximumEnergyTransferP = 4.* (electron_mass_c2 / proton_mass_c2) * k;
882 dataDiffCSMap::iterator iterator_Nrj;
883 iterator_Nrj = eNrjTransStorage.find(currentMaterial);
885 dataProbaShellMap::iterator iterator_Proba;
886 iterator_Proba = eProbaShellStorage.find(currentMaterial);
888 incidentEnergyMap::iterator iterator_Tdummy;
889 iterator_Tdummy = eIncidentEnergyStorage.find(currentMaterial);
891 if(iterator_Nrj == eNrjTransStorage.end() || iterator_Proba == eProbaShellStorage.end() ||
892 iterator_Tdummy == eIncidentEnergyStorage.end())
895 str += currentMaterial +
" not found!";
896 G4Exception(
"G4MicroElecInelasticModel_new::TransferedEnergy",
"em0002",
900 vector<TriDimensionMap>* eNrjTransfData = iterator_Nrj->second;
901 vector<VecMap>* eProbaShellMap = iterator_Proba->second;
902 vector<G4double>* eTdummyVec = iterator_Tdummy->second;
905 auto k2 = std::upper_bound(eTdummyVec->begin(),
911 if (random <= (*eProbaShellMap)[ionizationLevelIndex][(*k1)].back()
912 && random <= (*eProbaShellMap)[ionizationLevelIndex][(*k2)].back())
915 std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k1)].begin(),
916 (*eProbaShellMap)[ionizationLevelIndex][(*k1)].end(),
919 auto prob11 = prob12 - 1;
922 std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
923 (*eProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
926 auto prob21 = prob22 - 1;
930 valuePROB21 = *prob21;
931 valuePROB22 = *prob22;
932 valuePROB12 = *prob12;
933 valuePROB11 = *prob11;
937 else nrjTransf11 = (*eNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB11];
938 if (valuePROB12 == 1)
940 if ((valueK1 + bindingEnergy) / 2. > valueK1)
941 maximumEnergyTransfer1 = valueK1;
945 nrjTransf12 = maximumEnergyTransfer1;
948 nrjTransf12 = (*eNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB12];
951 else nrjTransf21 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
952 if (valuePROB22 == 1)
954 if ((valueK2 + bindingEnergy) / 2. > valueK2) maximumEnergyTransfer2 = valueK2;
955 else maximumEnergyTransfer2 = (valueK2 +
bindingEnergy) / 2.;
957 nrjTransf22 = maximumEnergyTransfer2;
959 else nrjTransf22 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
963 if (random > (*eProbaShellMap)[ionizationLevelIndex][(*k1)].back())
966 std::upper_bound((*eProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
967 (*eProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
969 auto prob21 = prob22 - 1;
973 valuePROB21 = *prob21;
974 valuePROB22 = *prob22;
976 nrjTransf21 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
977 nrjTransf22 = (*eNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
979 G4double interpolatedvalue2 = Interpolate(valuePROB21,
986 G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
995 dataDiffCSMap::iterator iterator_Nrj;
996 iterator_Nrj = pNrjTransStorage.find(currentMaterial);
998 dataProbaShellMap::iterator iterator_Proba;
999 iterator_Proba = pProbaShellStorage.find(currentMaterial);
1001 incidentEnergyMap::iterator iterator_Tdummy;
1002 iterator_Tdummy = pIncidentEnergyStorage.find(currentMaterial);
1004 if (iterator_Nrj == pNrjTransStorage.end() || iterator_Proba == pProbaShellStorage.end() ||
1005 iterator_Tdummy == pIncidentEnergyStorage.end())
1008 str += currentMaterial +
" not found!";
1009 G4Exception(
"G4MicroElecInelasticModel_new::TransferedEnergy",
"em0002",
1014 vector<TriDimensionMap>* pNrjTransfData = iterator_Nrj->second;
1015 vector<VecMap>* pProbaShellMap = iterator_Proba->second;
1016 vector<G4double>* pTdummyVec = iterator_Tdummy->second;
1018 auto k2 = std::upper_bound(pTdummyVec->begin(),
1026 if (random <= (*pProbaShellMap)[ionizationLevelIndex][(*k1)].back()
1027 && random <= (*pProbaShellMap)[ionizationLevelIndex][(*k2)].back())
1030 std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k1)].begin(),
1031 (*pProbaShellMap)[ionizationLevelIndex][(*k1)].end(),
1033 auto prob11 = prob12 - 1;
1035 std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
1036 (*pProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
1038 auto prob21 = prob22 - 1;
1042 valuePROB21 = *prob21;
1043 valuePROB22 = *prob22;
1044 valuePROB12 = *prob12;
1045 valuePROB11 = *prob11;
1050 else nrjTransf11 = (*pNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB11];
1052 if (valuePROB12 == 1) nrjTransf12 = maximumEnergyTransferP;
1053 else nrjTransf12 = (*pNrjTransfData)[ionizationLevelIndex][valueK1][valuePROB12];
1056 else nrjTransf21 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
1058 if (valuePROB22 == 1) nrjTransf22 = maximumEnergyTransferP;
1059 else nrjTransf22 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
1064 if (random > (*pProbaShellMap)[ionizationLevelIndex][(*k1)].back())
1067 std::upper_bound((*pProbaShellMap)[ionizationLevelIndex][(*k2)].begin(),
1068 (*pProbaShellMap)[ionizationLevelIndex][(*k2)].end(),
1071 auto prob21 = prob22 - 1;
1075 valuePROB21 = *prob21;
1076 valuePROB22 = *prob22;
1078 nrjTransf21 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB21];
1079 nrjTransf22 = (*pNrjTransfData)[ionizationLevelIndex][valueK2][valuePROB22];
1081 G4double interpolatedvalue2 = Interpolate(valuePROB21,
1088 G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
1095 G4double nrjTransfProduct = nrjTransf11 * nrjTransf12 * nrjTransf21 * nrjTransf22;
1097 if (nrjTransfProduct != 0.)
1099 nrj = QuadInterpolator(valuePROB11,
1126 if (energyTransfer >= currentMaterialStructure->
GetLimitEnergy(LevelIndex))
1143 dataDiffCSMap::iterator iterator_Proba;
1144 iterator_Proba = eDiffDatatable.find(currentMaterial);
1146 incidentEnergyMap::iterator iterator_Nrj;
1147 iterator_Nrj = eIncidentEnergyStorage.find(currentMaterial);
1149 TranfEnergyMap::iterator iterator_TransfNrj;
1150 iterator_TransfNrj = eVecmStorage.find(currentMaterial);
1152 if (iterator_Proba != eDiffDatatable.end() && iterator_Nrj != eIncidentEnergyStorage.end()
1153 && iterator_TransfNrj!= eVecmStorage.end())
1155 vector<TriDimensionMap>* eDiffCrossSectionData = (iterator_Proba->second);
1156 vector<G4double>* eTdummyVec = iterator_Nrj->second;
1157 VecMap* eVecm = iterator_TransfNrj->second;
1160 auto t2 = std::upper_bound(eTdummyVec->begin(), eTdummyVec->end(), k);
1163 if (energyTransfer <= (*eVecm)[(*t1)].back() && energyTransfer <= (*eVecm)[(*t2)].back())
1165 auto e12 = std::upper_bound((*eVecm)[(*t1)].begin(), (*eVecm)[(*t1)].end(), energyTransfer);
1167 auto e22 = std::upper_bound((*eVecm)[(*t2)].begin(), (*eVecm)[(*t2)].end(), energyTransfer);
1177 xs11 = (*eDiffCrossSectionData)[LevelIndex][valueT1][valueE11];
1178 xs12 = (*eDiffCrossSectionData)[LevelIndex][valueT1][valueE12];
1179 xs21 = (*eDiffCrossSectionData)[LevelIndex][valueT2][valueE21];
1180 xs22 = (*eDiffCrossSectionData)[LevelIndex][valueT2][valueE22];
1185 str += currentMaterial +
" not found!";
1192 dataDiffCSMap::iterator iterator_Proba;
1193 iterator_Proba = pDiffDatatable.find(currentMaterial);
1195 incidentEnergyMap::iterator iterator_Nrj;
1196 iterator_Nrj = pIncidentEnergyStorage.find(currentMaterial);
1198 TranfEnergyMap::iterator iterator_TransfNrj;
1199 iterator_TransfNrj = pVecmStorage.find(currentMaterial);
1201 if (iterator_Proba != pDiffDatatable.end() && iterator_Nrj != pIncidentEnergyStorage.end()
1202 && iterator_TransfNrj != pVecmStorage.end())
1204 vector<TriDimensionMap>* pDiffCrossSectionData = (iterator_Proba->second);
1205 vector<G4double>* pTdummyVec = iterator_Nrj->second;
1206 VecMap* pVecm = iterator_TransfNrj->second;
1210 std::upper_bound(pTdummyVec->begin(), pTdummyVec->end(), k);
1212 if (energyTransfer <= (*pVecm)[(*t1)].back() && energyTransfer <= (*pVecm)[(*t2)].back())
1214 auto e12 = std::upper_bound((*pVecm)[(*t1)].begin(), (*pVecm)[(*t1)].end(), energyTransfer);
1216 auto e22 = std::upper_bound((*pVecm)[(*t2)].begin(), (*pVecm)[(*t2)].end(), energyTransfer);
1226 xs11 = (*pDiffCrossSectionData)[LevelIndex][valueT1][valueE11];
1227 xs12 = (*pDiffCrossSectionData)[LevelIndex][valueT1][valueE12];
1228 xs21 = (*pDiffCrossSectionData)[LevelIndex][valueT2][valueE21];
1229 xs22 = (*pDiffCrossSectionData)[LevelIndex][valueT2][valueE22];
1234 str += currentMaterial +
" not found!";
1239 G4double xsProduct = xs11 * xs12 * xs21 * xs22;
1240 if (xsProduct != 0.)
1242 sigma = QuadInterpolator( valueE11, valueE12,
1267 if (e1 != 0 && e2 != 0 && (e2-e1) != 0 && !fasterCode)
1269 G4double a = std::log(xs2/xs1)/ std::log(e2/e1);
1270 G4double b = std::log(xs2) - a * std::log(e2);
1271 G4double sigma = a * std::log(e) + b;
1272 value = (std::exp(sigma));
1276 if ((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 && fasterCode)
1280 value = std::exp((d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
1285 if ((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) && fasterCode)
1289 value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
1304 G4double interpolatedvalue1 = Interpolate(e11, e12, e, xs11, xs12);
1305 G4double interpolatedvalue2 = Interpolate(e21, e22, e, xs21, xs22);
1306 G4double value = Interpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
1316 TCSMap::iterator tablepos;
1317 tablepos = tableTCS.find(currentMaterial);
1318 MapData* tableData = tablepos->second;
1320 std::map< G4String,G4MicroElecCrossSectionDataSet_new*,std::less<G4String> >::iterator
pos;
1321 pos = tableData->find(particle);
1323 std::vector<G4double> Zeff(currentMaterialStructure->
NumberOfLevels(), 1.0);
1324 if(originalMass>proton_mass_c2) {
1326 Zeff[nl] =
BKZ(k/(proton_mass_c2/originalMass), originalMass/c_squared, originalZ, currentMaterialStructure->
Energy(nl));
1330 if (pos != tableData->end())
1345 value += valuesBuffer[i];
1355 if (valuesBuffer[i] > value)
1357 delete[] valuesBuffer;
1360 value -= valuesBuffer[i];
1363 if (valuesBuffer)
delete[] valuesBuffer;
1369 G4Exception(
"G4MicroElecInelasticModel_new::RandomSelect",
"em0002",
FatalException,
"Model not applicable to particle type.");
1379 return c_light*std::sqrt(x*(x + 2.0))/(x + 1.0);
1388 G4double v2f = 2*M1/(M1+M2)*v1i + (M2-M1)/(M1+M2)*-1*v2i;
1389 G4double vtransfer2a = v2f*v2f-v2i*v2i;
1391 v2f = 2*M1/(M1+M2)*v1i + (M2-M1)/(M1+M2)*v2i;
1392 G4double vtransfer2b = v2f*v2f-v2i*v2i;
1394 G4double vtransfer2 = std::max(vtransfer2a, vtransfer2b);
1395 return 0.5*M2*vtransfer2;
1401 return (x < 0.) ? 1.0 : 0.0;
1408 G4double r = vF*( std::pow(v/vF+1., 3.) - fabs(std::pow(v/vF-1., 3.))
1409 + 4.*(v/vF)*(v/vF) ) +
stepFunc(v/vF-1.) * (3./2.*v/vF -
1410 4.*(v/vF)*(v/vF) + 3.*std::pow(v/vF, 3.)
1411 - 0.5*std::pow(v/vF, 5.));
1412 return r/(10.*v/vF);
1420 G4double hbar = hbar_Planck, hbar2 = hbar*hbar, me = electron_mass_c2/c_squared, Ry = me*elm_coupling*elm_coupling/(2*hbar2);
1421 G4double hartree = 2*Ry,
a0 = Bohr_radius, velocity =
a0*hartree/hbar;
1427 G4double a = std::pow(4./9./CLHEP::pi, 1./3.);
1428 G4double vF = std::pow(wp*wp/(3.*a*a*a), 1./3.);
1431 G4double yr = vr/std::pow(Zp, 2./3.);
1433 if(Zp==2) q = 1-exp(-c*vr/(Zp-5./16.));
1434 else q = 1.-exp(-c*(yr-0.07));
1437 if(Neq<=2) l0 = 3./(Zp-0.3*(Neq-1))/2.;
1438 else l0 = 0.48*std::pow(Neq, 2./3.)/(Zp-Neq/7.);
1441 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)
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
G4double FindShellValue(G4double argEnergy, G4int shell) const
const G4VEMDataSet * GetComponent(G4int componentId) const override
size_t NumberOfComponents(void) const override
G4bool LoadData(const G4String &argFileName) override
G4double FindValue(G4double e, G4int componentId=0) const 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)
G4ParticleChangeForGamma * fParticleChangeForGamma
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 GetInelasticModelHighLimit(G4int pdg)
G4bool IsShellWeaklyBound(G4int level)
G4double GetLimitEnergy(G4int level)
G4int GetEADL_Enumerator(G4int shell)
G4double GetZ(G4int Shell)
G4double Energy(G4int level)
G4double GetInelasticModelLowLimit(G4int pdg)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
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 const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
virtual G4double FindValue(G4double x, G4int componentId=0) const =0
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)
void SetAngularDistribution(G4VEmAngularDistribution *)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4double bindingEnergy(G4int A, G4int Z)