Import Geant4 11.4.0 source tree
This commit is contained in:
@@ -107,7 +107,7 @@ G4IonParametrisedLossModel::G4IonParametrisedLossModel(
|
||||
nmbBins(90),
|
||||
nmbSubBins(100),
|
||||
particleChangeLoss(0),
|
||||
corrFactor(1.0),
|
||||
chargeSquareRatio(1.0),
|
||||
energyLossLimit(0.01),
|
||||
cutEnergies(0),
|
||||
isInitialised(false)
|
||||
@@ -216,17 +216,11 @@ G4double G4IonParametrisedLossModel::MaxSecondaryEnergy(
|
||||
G4double G4IonParametrisedLossModel::GetChargeSquareRatio(
|
||||
const G4ParticleDefinition* particle,
|
||||
const G4Material* material,
|
||||
G4double kineticEnergy) { // Kinetic energy
|
||||
G4double kinEnergy) { // Kinetic energy
|
||||
|
||||
G4double chargeSquareRatio = corrections ->
|
||||
EffectiveChargeSquareRatio(particle,
|
||||
material,
|
||||
kineticEnergy);
|
||||
corrFactor = chargeSquareRatio *
|
||||
corrections -> EffectiveChargeCorrection(particle,
|
||||
material,
|
||||
kineticEnergy);
|
||||
return corrFactor;
|
||||
chargeSquareRatio =
|
||||
corrections->EffectiveChargeSquareRatio(particle, material, kinEnergy);
|
||||
return chargeSquareRatio;
|
||||
}
|
||||
|
||||
// #########################################################################
|
||||
@@ -581,14 +575,10 @@ G4double G4IonParametrisedLossModel::ComputeDEDXPerVolume(
|
||||
dEdx += corrections -> ComputeIonCorrections(particle,
|
||||
material, kineticEnergy);
|
||||
}
|
||||
|
||||
dEdx *= factor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (dEdx < 0.0) dEdx = 0.0;
|
||||
|
||||
return dEdx;
|
||||
}
|
||||
|
||||
@@ -903,9 +893,11 @@ void G4IonParametrisedLossModel::UpdateDEDXCache(
|
||||
// #########################################################################
|
||||
|
||||
void G4IonParametrisedLossModel::CorrectionsAlongStep(
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dynamicParticle,
|
||||
const G4double& length,
|
||||
const G4Material* material,
|
||||
const G4ParticleDefinition* particle,
|
||||
const G4double kineticEnergy,
|
||||
const G4double cutEnergy,
|
||||
const G4double& length,
|
||||
G4double& eloss) {
|
||||
|
||||
// ############## Corrections for along step energy loss calculation ######
|
||||
@@ -920,130 +912,72 @@ void G4IonParametrisedLossModel::CorrectionsAlongStep(
|
||||
//
|
||||
// (Implementation partly adapted from G4BraggIonModel/G4BetheBlochModel)
|
||||
|
||||
const G4ParticleDefinition* particle = dynamicParticle -> GetDefinition();
|
||||
const G4Material* material = couple -> GetMaterial();
|
||||
|
||||
G4double kineticEnergy = dynamicParticle -> GetKineticEnergy();
|
||||
|
||||
if(kineticEnergy == eloss) { return; }
|
||||
|
||||
G4double cutEnergy = DBL_MAX;
|
||||
std::size_t cutIndex = couple -> GetIndex();
|
||||
cutEnergy = cutEnergies[cutIndex];
|
||||
|
||||
UpdateDEDXCache(particle, material, cutEnergy);
|
||||
|
||||
LossTableList::iterator iter = dedxCacheIter;
|
||||
|
||||
// If parameterization for ions is available the electronic energy loss
|
||||
// is overwritten
|
||||
if(iter != lossTableList.end()) {
|
||||
|
||||
// The energy loss is calculated using the ComputeDEDXPerVolume function
|
||||
// and the step length (it is assumed that dE/dx does not change
|
||||
// considerably along the step)
|
||||
eloss =
|
||||
length * ComputeDEDXPerVolume(material, particle,
|
||||
kineticEnergy, cutEnergy);
|
||||
if (iter != lossTableList.end()) {
|
||||
// The energy loss is calculated using the ComputeDEDXPerVolume function
|
||||
// and the step length (it is assumed that dE/dx does not change
|
||||
// considerably along the step)
|
||||
eloss = length * ComputeDEDXPerVolume(material, particle,
|
||||
kineticEnergy, cutEnergy);
|
||||
|
||||
#ifdef PRINT_DEBUG
|
||||
G4cout.precision(6);
|
||||
G4cout << "########################################################"
|
||||
<< G4endl
|
||||
<< "# G4IonParametrisedLossModel::CorrectionsAlongStep"
|
||||
<< G4endl
|
||||
<< "# cut(MeV) = " << cutEnergy/MeV
|
||||
<< G4endl;
|
||||
|
||||
G4cout << "#"
|
||||
<< std::setw(13) << std::right << "E(MeV)"
|
||||
<< std::setw(14) << "l(um)"
|
||||
<< std::setw(14) << "l*dE/dx(MeV)"
|
||||
<< std::setw(14) << "(l*dE/dx)/E"
|
||||
<< G4endl
|
||||
<< "# ------------------------------------------------------"
|
||||
<< G4endl;
|
||||
|
||||
G4cout << std::setw(14) << std::right << kineticEnergy / MeV
|
||||
<< std::setw(14) << length / um
|
||||
<< std::setw(14) << eloss / MeV
|
||||
<< std::setw(14) << eloss / kineticEnergy * 100.0
|
||||
<< G4endl;
|
||||
G4cout.precision(6);
|
||||
G4cout << "########################################################" << G4endl
|
||||
<< "# G4IonParametrisedLossModel::CorrectionsAlongStep" << G4endl
|
||||
<< "# cut(MeV) = " << cutEnergy/MeV << G4endl;
|
||||
G4cout << "#"
|
||||
<< std::setw(13) << std::right << "E(MeV)"
|
||||
<< std::setw(14) << "l(um)"
|
||||
<< std::setw(14) << "l*dE/dx(MeV)"
|
||||
<< std::setw(14) << "(l*dE/dx)/E"
|
||||
<< G4endl
|
||||
<< "# ------------------------------------------------------" << G4endl;
|
||||
G4cout << std::setw(14) << std::right << kineticEnergy / MeV
|
||||
<< std::setw(14) << length / um
|
||||
<< std::setw(14) << eloss / MeV
|
||||
<< std::setw(14) << eloss / kineticEnergy * 100.0
|
||||
<< G4endl;
|
||||
#endif
|
||||
|
||||
// If the energy loss exceeds a certain fraction of the kinetic energy
|
||||
// (the fraction is indicated by the parameter "energyLossLimit") then
|
||||
// the range tables are used to derive a more accurate value of the
|
||||
// energy loss
|
||||
if(eloss > energyLossLimit * kineticEnergy) {
|
||||
|
||||
eloss = ComputeLossForStep(couple, particle,
|
||||
kineticEnergy,length);
|
||||
// If the energy loss exceeds a certain fraction of the kinetic energy
|
||||
// (the fraction is indicated by the parameter "energyLossLimit") then
|
||||
// the range tables are used to derive a more accurate value of the
|
||||
// energy loss
|
||||
if (eloss > energyLossLimit * kineticEnergy) {
|
||||
eloss = ComputeLossForStep(CurrentCouple(), particle,
|
||||
kineticEnergy,length);
|
||||
|
||||
#ifdef PRINT_DEBUG
|
||||
G4cout << "# Correction applied:"
|
||||
<< G4endl;
|
||||
|
||||
G4cout << std::setw(14) << std::right << kineticEnergy / MeV
|
||||
<< std::setw(14) << length / um
|
||||
<< std::setw(14) << eloss / MeV
|
||||
<< std::setw(14) << eloss / kineticEnergy * 100.0
|
||||
<< G4endl;
|
||||
G4cout << "# Correction applied:" << G4endl;
|
||||
G4cout << std::setw(14) << std::right << kineticEnergy / MeV
|
||||
<< std::setw(14) << length / um
|
||||
<< std::setw(14) << eloss / MeV
|
||||
<< std::setw(14) << eloss / kineticEnergy * 100.0
|
||||
<< G4endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For all corrections below a kinetic energy between the Pre- and
|
||||
// Post-step energy values is used
|
||||
G4double energy = kineticEnergy - eloss * 0.5;
|
||||
if(energy < 0.0) energy = kineticEnergy * 0.5;
|
||||
if (energy < 0.0) energy = kineticEnergy * 0.5;
|
||||
|
||||
G4double chargeSquareRatio = corrections ->
|
||||
EffectiveChargeSquareRatio(particle,
|
||||
material,
|
||||
energy);
|
||||
GetModelOfFluctuations() -> SetParticleAndCharge(particle,
|
||||
chargeSquareRatio);
|
||||
G4double q2 = corrections->EffectiveChargeSquareRatio(particle, material,
|
||||
energy);
|
||||
GetModelOfFluctuations()->SetParticleAndCharge(particle, q2);
|
||||
|
||||
// A correction is applied considering the change of the effective charge
|
||||
// along the step (the parameter "corrFactor" refers to the effective
|
||||
// along the step (the parameter "chargeSquareRatio" refers to the effective
|
||||
// charge at the beginning of the step). Note: the correction is not
|
||||
// applied for energy loss values deriving directly from parameterized
|
||||
// ion stopping power tables
|
||||
G4double transitionEnergy = dedxCacheTransitionEnergy;
|
||||
|
||||
if(iter != lossTableList.end() && transitionEnergy < kineticEnergy) {
|
||||
chargeSquareRatio *= corrections -> EffectiveChargeCorrection(particle,
|
||||
material,
|
||||
energy);
|
||||
|
||||
G4double chargeSquareRatioCorr = chargeSquareRatio/corrFactor;
|
||||
eloss *= chargeSquareRatioCorr;
|
||||
}
|
||||
else if (iter == lossTableList.end()) {
|
||||
|
||||
chargeSquareRatio *= corrections -> EffectiveChargeCorrection(particle,
|
||||
material,
|
||||
energy);
|
||||
|
||||
G4double chargeSquareRatioCorr = chargeSquareRatio/corrFactor;
|
||||
eloss *= chargeSquareRatioCorr;
|
||||
}
|
||||
|
||||
// Ion high order corrections are applied if the current model does not
|
||||
// overwrite the energy loss (i.e. when the effective charge approach is
|
||||
// used)
|
||||
if(iter == lossTableList.end()) {
|
||||
|
||||
G4double scaledKineticEnergy = kineticEnergy * dedxCacheGenIonMassRatio;
|
||||
G4double lowEnergyLimit = betheBlochModel -> LowEnergyLimit();
|
||||
|
||||
// Corrections are only applied in the Bethe-Bloch energy region
|
||||
if(scaledKineticEnergy > lowEnergyLimit)
|
||||
eloss += length *
|
||||
corrections -> IonHighOrderCorrections(particle, couple, energy);
|
||||
}
|
||||
eloss *= q2/chargeSquareRatio;
|
||||
}
|
||||
|
||||
// #########################################################################
|
||||
|
||||
@@ -118,7 +118,6 @@ G4MicroElecElasticModel_new::G4MicroElecElasticModel_new(const G4ParticleDefinit
|
||||
killElectron = false;
|
||||
acousticModelEnabled = false;
|
||||
currentMaterialName = "";
|
||||
isOkToBeInitialised = false;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -167,124 +166,116 @@ G4MicroElecElasticModel_new::~G4MicroElecElasticModel_new()
|
||||
|
||||
void G4MicroElecElasticModel_new::Initialise(const G4ParticleDefinition* /*particle*/,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
if (isOkToBeInitialised == true && isInitialised == false) {
|
||||
|
||||
{
|
||||
if (verboseLevel > -1)
|
||||
G4cout << "Calling G4MicroElecElasticModel_new::Initialise()" << G4endl;
|
||||
// Energy limits
|
||||
// Reading of data files
|
||||
|
||||
|
||||
G4double scaleFactor = 1e-18 * cm * cm;
|
||||
|
||||
G4ProductionCutsTable* theCoupleTable =
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
|
||||
G4int numOfCouples = (G4int)theCoupleTable->GetTableSize();
|
||||
|
||||
|
||||
for (G4int i = 0; i < numOfCouples; ++i) {
|
||||
const G4Material* material =
|
||||
theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
|
||||
|
||||
//theCoupleTable->GetMaterialCutsCouple(i)->;
|
||||
|
||||
const G4Material* material = theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
|
||||
|
||||
G4cout << "MicroElasticModel, Material " << i + 1 << " / " << numOfCouples << " : " << material->GetName() << G4endl;
|
||||
if (material->GetName() == "Vacuum") continue;
|
||||
|
||||
|
||||
G4String matName = material->GetName().substr(3, material->GetName().size());
|
||||
G4cout<< matName<< G4endl;
|
||||
|
||||
|
||||
currentMaterialStructure = new G4MicroElecMaterialStructure(matName);
|
||||
lowEnergyLimitTable[matName]=currentMaterialStructure->GetElasticModelLowLimit();
|
||||
highEnergyLimitTable[matName]=currentMaterialStructure->GetElasticModelHighLimit();
|
||||
workFunctionTable[matName] = currentMaterialStructure->GetWorkFunction();
|
||||
|
||||
|
||||
delete currentMaterialStructure;
|
||||
|
||||
|
||||
G4cout << "Reading TCS file" << G4endl;
|
||||
G4String fileElectron = "Elastic/elsepa_elastic_cross_e_" + matName;
|
||||
G4cout << "Elastic Total Cross file : " << fileElectron << G4endl;
|
||||
|
||||
|
||||
G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
|
||||
G4String electron = electronDef->GetParticleName();
|
||||
|
||||
|
||||
// For total cross section
|
||||
MapData* tableData = new MapData();
|
||||
|
||||
|
||||
G4MicroElecCrossSectionDataSet_new* tableE = new G4MicroElecCrossSectionDataSet_new(new G4LogLogInterpolation, eV, scaleFactor);
|
||||
tableE->LoadData(fileElectron);
|
||||
tableData->insert(make_pair(electron, tableE));
|
||||
tableTCS[matName] = tableData; //Storage of TCS
|
||||
|
||||
|
||||
// For final state
|
||||
const char* path = G4FindDataDir("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4Exception("G4MicroElecElasticModel_new::Initialise","em0006",FatalException,"G4LEDATA environment variable not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
G4Exception("G4MicroElecElasticModel_new::Initialise","em0006",FatalException,"G4LEDATA environment variable not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
//Reading DCS file
|
||||
std::ostringstream eFullFileName;
|
||||
eFullFileName << path << "/microelec/Elastic/elsepa_elastic_cumulated_diffcross_e_" + matName + ".dat";
|
||||
G4cout << "Elastic Cumulated Diff Cross : " << eFullFileName.str().c_str() << G4endl;
|
||||
std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
|
||||
|
||||
|
||||
if (!eDiffCrossSection)
|
||||
G4Exception("G4MicroElecElasticModel_new::Initialise", "em0003", FatalException, "Missing data file: /microelec/sigmadiff_cumulated_elastic_e_Si.dat");
|
||||
|
||||
G4Exception("G4MicroElecElasticModel_new::Initialise", "em0003", FatalException, "Missing data file: /microelec/sigmadiff_cumulated_elastic_e_Si.dat");
|
||||
|
||||
// October 21th, 2014 - Melanie Raine
|
||||
// Added clear for MT
|
||||
// Diff Cross Sections in cumulated mode
|
||||
TriDimensionMap* eDiffCrossSectionData = new TriDimensionMap(); //Angles
|
||||
std::vector<G4double>* eTdummyVec = new std::vector<G4double>; //Incident energy vector
|
||||
VecMap* eProbVec = new VecMap; //Probabilities
|
||||
|
||||
|
||||
eTdummyVec->push_back(0.);
|
||||
|
||||
|
||||
while (!eDiffCrossSection.eof())
|
||||
{
|
||||
G4double tDummy; //incident energy
|
||||
G4double eProb; //Proba
|
||||
eDiffCrossSection >> tDummy >> eProb;
|
||||
{
|
||||
G4double tDummy; //incident energy
|
||||
G4double eProb; //Proba
|
||||
eDiffCrossSection >> tDummy >> eProb;
|
||||
|
||||
// SI : mandatory eVecm initialization
|
||||
if (tDummy != eTdummyVec->back())
|
||||
{
|
||||
eTdummyVec->push_back(tDummy); //adding values for incident energy points
|
||||
(*eProbVec)[tDummy].push_back(0.); //adding probability for the first angle, equal to 0
|
||||
// SI : mandatory eVecm initialization
|
||||
if (tDummy != eTdummyVec->back())
|
||||
{
|
||||
eTdummyVec->push_back(tDummy); //adding values for incident energy points
|
||||
(*eProbVec)[tDummy].push_back(0.); //adding probability for the first angle, equal to 0
|
||||
}
|
||||
|
||||
eDiffCrossSection >> (*eDiffCrossSectionData)[tDummy][eProb]; //adding Angle Value to map
|
||||
|
||||
if (eProb != (*eProbVec)[tDummy].back()) {
|
||||
(*eProbVec)[tDummy].push_back(eProb); //Adding cumulated proba to map
|
||||
}
|
||||
|
||||
eDiffCrossSection >> (*eDiffCrossSectionData)[tDummy][eProb]; //adding Angle Value to map
|
||||
|
||||
if (eProb != (*eProbVec)[tDummy].back()) {
|
||||
(*eProbVec)[tDummy].push_back(eProb); //Adding cumulated proba to map
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Filling maps for the material
|
||||
thetaDataStorage[matName] = eDiffCrossSectionData;
|
||||
eIncidentEnergyStorage[matName] = eTdummyVec;
|
||||
eProbaStorage[matName] = eProbVec;
|
||||
}
|
||||
// End final state
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for MicroElec Elastic model" << G4endl;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << "MicroElec Elastic model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / MeV << " MeV"
|
||||
<< G4endl; // system("pause"); linux doesn't like
|
||||
}
|
||||
|
||||
if (isInitialised) { return; }
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
// End final state
|
||||
|
||||
if (verboseLevel > 2)
|
||||
G4cout << "Loaded cross section files for MicroElec Elastic model" << G4endl;
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << "MicroElec Elastic model is initialized " << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / MeV << " MeV"
|
||||
<< G4endl; // system("pause"); linux doesn't like
|
||||
}
|
||||
|
||||
if (isInitialised) { return; }
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -298,10 +289,8 @@ G4double G4MicroElecElasticModel_new::CrossSectionPerVolume(const G4Material* ma
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling CrossSectionPerVolume() of G4MicroElecElasticModel" << G4endl;
|
||||
|
||||
isOkToBeInitialised = true;
|
||||
currentMaterialName = material->GetName().substr(3, material->GetName().size());
|
||||
const G4DataVector cuts;
|
||||
Initialise(p, cuts);
|
||||
// Calculate total cross section for model
|
||||
MapEnergy::iterator lowEPos;
|
||||
lowEPos = lowEnergyLimitTable.find(currentMaterialName);
|
||||
@@ -324,13 +313,10 @@ G4double G4MicroElecElasticModel_new::CrossSectionPerVolume(const G4Material* ma
|
||||
lowEnergyLimit = lowEPos->second;
|
||||
highEnergyLimit = highEPos->second;
|
||||
killBelowEnergy = killEPos->second;
|
||||
|
||||
}
|
||||
|
||||
if (ekin < killBelowEnergy) {
|
||||
|
||||
return DBL_MAX; }
|
||||
|
||||
if (ekin < killBelowEnergy) { return DBL_MAX; }
|
||||
|
||||
G4double sigma=0;
|
||||
|
||||
//Phonon for SiO2
|
||||
@@ -345,11 +331,11 @@ G4double G4MicroElecElasticModel_new::CrossSectionPerVolume(const G4Material* ma
|
||||
Aac = 17 * Ebz, //A screening parameter
|
||||
Eac = 3.5 * 1.6e-19, //C deformation potential
|
||||
prefactor = 2.2;// Facteur pour modifier les MFP
|
||||
|
||||
|
||||
return AcousticCrossSectionPerVolume(ekin, kbz, rho, cs, Aac, Eac, prefactor);
|
||||
}
|
||||
|
||||
else if (currentMaterialName == "ALUMINUM_OXIDE" && ekin < 20 * eV) {
|
||||
else if (currentMaterialName == "ALUMINUM_OXIDE" && ekin < 20 * eV) {
|
||||
acousticModelEnabled = true;
|
||||
|
||||
//Values for Al2O3
|
||||
@@ -360,17 +346,17 @@ else if (currentMaterialName == "ALUMINUM_OXIDE" && ekin < 20 * eV) {
|
||||
Eac = 2.1622471654789847e-18, //C deformation potential
|
||||
prefactor = 1;
|
||||
return AcousticCrossSectionPerVolume(ekin, kbz, rho, cs, Aac, Eac, prefactor);
|
||||
}
|
||||
}
|
||||
//Elastic
|
||||
else {
|
||||
acousticModelEnabled = false;
|
||||
|
||||
|
||||
G4double density = material->GetTotNbOfAtomsPerVolume();
|
||||
const G4String& particleName = p->GetParticleName();
|
||||
|
||||
|
||||
TCSMap::iterator tablepos;
|
||||
tablepos = tableTCS.find(currentMaterialName);
|
||||
|
||||
|
||||
if (tablepos != tableTCS.end())
|
||||
{
|
||||
MapData* tableData = tablepos->second;
|
||||
@@ -379,35 +365,32 @@ else if (currentMaterialName == "ALUMINUM_OXIDE" && ekin < 20 * eV) {
|
||||
{
|
||||
std::map< G4String, G4MicroElecCrossSectionDataSet_new*, std::less<G4String> >::iterator pos;
|
||||
pos = tableData->find(particleName);
|
||||
|
||||
if (pos != tableData->end())
|
||||
{
|
||||
G4MicroElecCrossSectionDataSet_new* table = pos->second;
|
||||
if (table != 0)
|
||||
|
||||
if (pos != tableData->end()){
|
||||
G4MicroElecCrossSectionDataSet_new* table = pos->second;
|
||||
if (table != 0)
|
||||
{
|
||||
sigma = table->FindValue(ekin);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4MicroElecElasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, "Model not applicable to particle type.");
|
||||
G4Exception("G4MicroElecElasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, "Model not applicable to particle type.");
|
||||
}
|
||||
}
|
||||
else return 1 / DBL_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
G4String str = "Material ";
|
||||
str += currentMaterialName + " TCS table not found!";
|
||||
G4Exception("G4MicroElecElasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, str);
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel > 3)
|
||||
{
|
||||
if (verboseLevel > 3) {
|
||||
G4cout << "---> Kinetic energy(eV)=" << ekin / eV << G4endl;
|
||||
G4cout << " - Cross section per Si atom (cm^2)=" << sigma / cm / cm << G4endl;
|
||||
G4cout << " - Cross section per Si atom (cm^-1)=" << sigma*density / (1. / cm) << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Hsing-YinChangaAndrewAlvaradoaTreyWeberaJaimeMarianab Monte Carlo modeling of low-energy electron-induced secondary electron emission yields in micro-architected boron nitride surfaces - ScienceDirect, (n.d.). https://www.sciencedirect.com/science/article/pii/S0168583X19304069 (accessed April 1, 2022).
|
||||
if (currentMaterialName == "BORON_NITRIDE") {
|
||||
@@ -474,13 +457,12 @@ void G4MicroElecElasticModel_new::SampleSecondaries(std::vector<G4DynamicParticl
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
|
||||
if (verboseLevel > 3)
|
||||
G4cout << "Calling SampleSecondaries() of G4MicroElecElasticModel" << G4endl;
|
||||
|
||||
G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
|
||||
|
||||
if (electronEnergy0 < killBelowEnergy)
|
||||
if (electronEnergy0 < killBelowEnergy)
|
||||
{
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(0.);
|
||||
fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
|
||||
@@ -488,34 +470,33 @@ void G4MicroElecElasticModel_new::SampleSecondaries(std::vector<G4DynamicParticl
|
||||
return;
|
||||
}
|
||||
|
||||
if (electronEnergy0 < highEnergyLimit)
|
||||
{
|
||||
G4double cosTheta = 0;
|
||||
if (acousticModelEnabled)
|
||||
{
|
||||
cosTheta = 1 - 2 * G4UniformRand(); //Isotrope
|
||||
}
|
||||
else if (electronEnergy0 >= lowEnergyLimit)
|
||||
{
|
||||
if (electronEnergy0 < highEnergyLimit)
|
||||
{
|
||||
G4double cosTheta = 0;
|
||||
if (acousticModelEnabled)
|
||||
{
|
||||
cosTheta = 1 - 2 * G4UniformRand(); //Isotrope
|
||||
}
|
||||
else if (electronEnergy0 >= lowEnergyLimit)
|
||||
{
|
||||
cosTheta = RandomizeCosTheta(electronEnergy0);
|
||||
}
|
||||
}
|
||||
G4double phi = 2. * pi * G4UniformRand();
|
||||
|
||||
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);
|
||||
|
||||
G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
|
||||
|
||||
G4double phi = 2. * pi * G4UniformRand();
|
||||
|
||||
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);
|
||||
|
||||
G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
|
||||
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
|
||||
}
|
||||
fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
|
||||
fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -569,37 +550,36 @@ G4double G4MicroElecElasticModel_new::Theta
|
||||
iterator_proba = eProbaStorage.find(currentMaterialName);
|
||||
|
||||
if (iterator_angle != thetaDataStorage.end() && iterator_energy != eIncidentEnergyStorage.end() && iterator_proba != eProbaStorage.end())
|
||||
{
|
||||
TriDimensionMap* eDiffCrossSectionData = iterator_angle->second; //Theta points
|
||||
std::vector<G4double>* eTdummyVec = iterator_energy->second;
|
||||
VecMap* eVecm = iterator_proba->second;
|
||||
{
|
||||
TriDimensionMap* eDiffCrossSectionData = iterator_angle->second; //Theta points
|
||||
std::vector<G4double>* eTdummyVec = iterator_energy->second;
|
||||
VecMap* eVecm = iterator_proba->second;
|
||||
|
||||
auto t2 = std::upper_bound(eTdummyVec->begin(), eTdummyVec->end(), k);
|
||||
auto t1 = t2 - 1;
|
||||
auto e12 = std::upper_bound((*eVecm)[(*t1)].begin(), (*eVecm)[(*t1)].end(), integrDiff);
|
||||
auto e11 = e12 - 1;
|
||||
auto e22 = std::upper_bound((*eVecm)[(*t2)].begin(), (*eVecm)[(*t2)].end(), integrDiff);
|
||||
auto e21 = e22 - 1;
|
||||
auto t2 = std::upper_bound(eTdummyVec->begin(), eTdummyVec->end(), k);
|
||||
auto t1 = t2 - 1;
|
||||
auto e12 = std::upper_bound((*eVecm)[(*t1)].begin(), (*eVecm)[(*t1)].end(), integrDiff);
|
||||
auto e11 = e12 - 1;
|
||||
auto e22 = std::upper_bound((*eVecm)[(*t2)].begin(), (*eVecm)[(*t2)].end(), integrDiff);
|
||||
auto e21 = e22 - 1;
|
||||
|
||||
valueT1 = *t1;
|
||||
valueT2 = *t2;
|
||||
valueE21 = *e21;
|
||||
valueE22 = *e22;
|
||||
valueE12 = *e12;
|
||||
valueE11 = *e11;
|
||||
|
||||
xs11 = (*eDiffCrossSectionData)[valueT1][valueE11];
|
||||
xs12 = (*eDiffCrossSectionData)[valueT1][valueE12];
|
||||
xs21 = (*eDiffCrossSectionData)[valueT2][valueE21];
|
||||
xs22 = (*eDiffCrossSectionData)[valueT2][valueE22];
|
||||
}
|
||||
valueT1 = *t1;
|
||||
valueT2 = *t2;
|
||||
valueE21 = *e21;
|
||||
valueE22 = *e22;
|
||||
valueE12 = *e12;
|
||||
valueE11 = *e11;
|
||||
|
||||
xs11 = (*eDiffCrossSectionData)[valueT1][valueE11];
|
||||
xs12 = (*eDiffCrossSectionData)[valueT1][valueE12];
|
||||
xs21 = (*eDiffCrossSectionData)[valueT2][valueE21];
|
||||
xs22 = (*eDiffCrossSectionData)[valueT2][valueE22];
|
||||
}
|
||||
else
|
||||
{
|
||||
G4String str = "Material ";
|
||||
str += currentMaterialName + " not found!";
|
||||
G4Exception("G4MicroElecElasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, str);
|
||||
}
|
||||
|
||||
{
|
||||
G4String str = "Material ";
|
||||
str += currentMaterialName + " not found!";
|
||||
G4Exception("G4MicroElecElasticModel_new::ComputeCrossSectionPerVolume", "em0002", FatalException, str);
|
||||
}
|
||||
}
|
||||
|
||||
if (xs11==0 || xs12==0 ||xs21==0 ||xs22==0) return (0.);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,7 +70,6 @@ G4MicroElecLOPhononModel::G4MicroElecLOPhononModel(const G4ParticleDefinition*,
|
||||
void G4MicroElecLOPhononModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector& /*cuts*/)
|
||||
{
|
||||
if (isInitialised) { return; }
|
||||
fParticleChangeForGamma = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
}
|
||||
@@ -134,6 +133,11 @@ CrossSectionPerVolume(const G4Material* material,
|
||||
|
||||
G4double hw = (phononEnergy / eV) * e;
|
||||
G4double n = 1.0 / (std::exp(hw / (kb*T)) - 1); //Phonon distribution
|
||||
|
||||
if (E<=hw)
|
||||
{
|
||||
return 1 / DBL_MAX;
|
||||
}
|
||||
|
||||
if (absor) // Absorption
|
||||
{
|
||||
@@ -151,8 +155,7 @@ CrossSectionPerVolume(const G4Material* material,
|
||||
G4double MFP = (std::sqrt(2 * E / m0) / P)*m;
|
||||
|
||||
if (material->GetName() == "G4_SILICON_DIOXIDE") { return 2 / MFP; }
|
||||
return 1/(MFP);
|
||||
// correction CI 12/1/2023 add
|
||||
return 1/(MFP);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -131,7 +131,6 @@ void G4MicroElecSurface::Initialise()
|
||||
|
||||
void G4MicroElecSurface::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
{
|
||||
if (isInitialised) { return; }
|
||||
|
||||
G4ProductionCutsTable* theCoupleTable =
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
@@ -183,7 +182,6 @@ G4VParticleChange* G4MicroElecSurface::PostStepDoIt(const G4Track& aTrack, const
|
||||
theParticleMomentum = aParticle->GetTotalMomentum();
|
||||
previousMomentum = oldMomentum;
|
||||
oldMomentum = aParticle->GetMomentumDirection();
|
||||
|
||||
|
||||
// Fisrt case: not a boundary
|
||||
if (pPostStepPoint->GetStepStatus() != fGeomBoundary
|
||||
@@ -368,15 +366,18 @@ G4VParticleChange* G4MicroElecSurface::PostStepDoIt(const G4Track& aTrack, const
|
||||
ekint=aStep.GetPostStepPoint()->GetKineticEnergy();
|
||||
thetat= GetIncidentAngle(); //angle d'incidence
|
||||
G4double ekinNormalt=ekint*std::cos(thetat)*std::cos(thetat);
|
||||
|
||||
thetaft=std::asin(std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat));//Angle de refraction
|
||||
if(std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat)>1.0)
|
||||
{
|
||||
thetaft=std::asin(1.0);
|
||||
G4double sin_thetaft = std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat);
|
||||
G4double cos_thetaft = 0.0;
|
||||
//Refraction angle
|
||||
|
||||
if (1.0-sin_thetaft*sin_thetaft>0) {
|
||||
cos_thetaft = std::sqrt(1.0-sin_thetaft*sin_thetaft);
|
||||
}
|
||||
else {
|
||||
cos_thetaft = 0.0;
|
||||
}
|
||||
|
||||
G4double aleat=G4UniformRand();
|
||||
|
||||
G4double waveVectort=std::sqrt(2*9.1093826E-31*1.602176487E-19)/(6.6260755E-34/(2.0*pi));
|
||||
|
||||
// Parameter for an exponential barrier of potential (Thesis P68)
|
||||
@@ -384,7 +385,7 @@ G4VParticleChange* G4MicroElecSurface::PostStepDoIt(const G4Track& aTrack, const
|
||||
|
||||
crossingProbability=0;
|
||||
|
||||
G4double kft=waveVectort*std::sqrt(ekint+energyThreshold)*std::cos(thetaft);
|
||||
G4double kft=waveVectort*std::sqrt(ekint+energyThreshold)*cos_thetaft;
|
||||
G4double kit=waveVectort*std::sqrt(ekinNormalt);
|
||||
|
||||
crossingProbability=1-(std::pow(std::sinh(pi*at*(kit-kft)), 2.0)/std::pow(std::sinh(pi*at*(kit+kft)), 2.0));
|
||||
@@ -399,16 +400,17 @@ G4VParticleChange* G4MicroElecSurface::PostStepDoIt(const G4Track& aTrack, const
|
||||
flag_franchissement_surface = true;
|
||||
}
|
||||
|
||||
thetaft=std::abs(thetaft-thetat);
|
||||
// calculation of cos_thetaft for thetaft=std::abs(thetaft-thetat);
|
||||
cos_thetaft = cos_thetaft*std::cos(thetat)+sin_thetaft*std::sin(thetat);
|
||||
|
||||
G4ThreeVector zVerst = aStep.GetPostStepPoint()->GetMomentumDirection();
|
||||
G4ThreeVector xVerst = zVerst.orthogonal();
|
||||
G4ThreeVector yVerst = zVerst.cross(xVerst);
|
||||
|
||||
G4double xDirt = std::sqrt(1. - std::cos(thetaft)*std::cos(thetaft));
|
||||
G4double xDirt = std::sqrt(1. - cos_thetaft*cos_thetaft);
|
||||
G4double yDirt = xDirt;
|
||||
|
||||
G4ThreeVector zPrimeVerst=((xDirt*xVerst + yDirt*yVerst + std::cos(thetaft)*zVerst));
|
||||
G4ThreeVector zPrimeVerst=((xDirt*xVerst + yDirt*yVerst + cos_thetaft*zVerst));
|
||||
|
||||
aParticleChange.ProposeMomentumDirection(zPrimeVerst.unit());
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ G4double G4eIonisationSpectrum::Probability(G4int Z,
|
||||
G4double x1 = std::min(0.5,(t0 + bindingEnergy)/energy);
|
||||
G4double x2 = std::min(0.5,(tm + bindingEnergy)/energy);
|
||||
|
||||
if(verbose > 1 || (Z==4 && e>= 1.0 && e<= 0.0)) {
|
||||
if (verbose > 1) {
|
||||
G4cout << "G4eIonisationSpectrum::Probability: Z= " << Z
|
||||
<< "; shell= " << shell
|
||||
<< "; E(keV)= " << e/keV
|
||||
@@ -137,14 +137,11 @@ G4double G4eIonisationSpectrum::Probability(G4int Z,
|
||||
<< Z << ". Please check and/or update it " << G4endl;
|
||||
}
|
||||
|
||||
if(e >= 1. && e <= 0. && Z == 4) p.push_back(0.0);
|
||||
|
||||
|
||||
G4double val = IntSpectrum(x1, x2, p);
|
||||
G4double x0 = (lowestE + bindingEnergy)/energy;
|
||||
G4double nor = IntSpectrum(x0, 0.5, p);
|
||||
|
||||
if(verbose > 1 || (Z==4 && e>= 1.0 && e<= 0.0)) {
|
||||
if (verbose > 1) {
|
||||
G4cout << "tcut= " << tMin
|
||||
<< "; tMax= " << tMax
|
||||
<< "; x0= " << x0
|
||||
|
||||
Reference in New Issue
Block a user