109 p->clearAndDestroy();
116 p->clearAndDestroy();
123 p->clearAndDestroy();
130 p->clearAndDestroy();
164 if(anAdjPartDef && aProcess)
183 if(anAdjPartDef && aProcess)
249 G4cout <<
"========== Computation of cross section matrices for adjoint "
254 G4cout <<
"Build adjoint cross section matrices for " << aModel->GetName()
256 if(aModel->GetUseMatrix())
258 std::vector<G4AdjointCSMatrix*>* aListOfMat1 =
259 new std::vector<G4AdjointCSMatrix*>();
260 std::vector<G4AdjointCSMatrix*>* aListOfMat2 =
261 new std::vector<G4AdjointCSMatrix*>();
262 if(aModel->GetUseMatrixPerElement())
264 if(aModel->GetUseOnlyOneMatrixForAllElements())
266 std::vector<G4AdjointCSMatrix*> two_matrices =
268 aListOfMat1->push_back(two_matrices[0]);
269 aListOfMat2->push_back(two_matrices[1]);
273 for(
const auto& anElement : *theElementTable)
277 std::vector<G4AdjointCSMatrix*> two_matrices =
279 aListOfMat1->push_back(two_matrices[0]);
280 aListOfMat2->push_back(two_matrices[1]);
286 for(
const auto& aMaterial : *theMaterialTable)
288 std::vector<G4AdjointCSMatrix*> two_matrices =
290 aListOfMat1->push_back(two_matrices[0]);
291 aListOfMat2->push_back(two_matrices[1]);
296 aModel->SetCSMatrices(aListOfMat1, aListOfMat2);
300 G4cout <<
"The model " << aModel->GetName()
301 <<
" does not use cross section matrices" <<
G4endl;
302 std::vector<G4AdjointCSMatrix*> two_empty_matrices;
307 G4cout <<
" All adjoint cross section matrices are computed!"
310 <<
"======================================================================"
330 for(
size_t j = 0; j < theCoupleTable->
GetTableSize(); ++j)
350 for(
size_t j = 0; j < theCoupleTable->
GetTableSize(); ++j)
357 G4bool Emin_found =
false;
360 for(
size_t l = 0; l <
fNbins; ++l)
372 size_t mat_index = couple->
GetIndex();
385 if(totCS > sigma_max)
390 if(totCS > 0 && !Emin_found)
408 for(
size_t eindex = 0; eindex <
fNbins; ++eindex)
415 if(totCS > sigma_max)
420 if(totCS > 0 && !Emin_found)
460 G4double Ekin_nuc,
size_t index_model,
G4bool is_scat_proj_to_proj,
464 if(is_scat_proj_to_proj)
497 ->Value(e_sigma_max);
511 ->Value(e_sigma_max);
526 if(lastEkin != PreStepEkin || aPartDef != lastPartDef ||
532 lastEkin = PreStepEkin;
533 lastPartDef = aPartDef;
534 if(prefwdCS > 0. && preadjCS > 0.)
567 corr_fac *= std::exp((pre_adjCS - pre_fwdCS) * step_length);
586 G4double Tcut,
G4bool isScatProjToProj, std::vector<G4double>& CS_Vs_Element)
591 static G4double lastPrimaryEnergy = 0.;
605 if(EminSec >= EmaxSec)
608 G4bool need_to_compute =
false;
609 if(aMaterial != lastMaterial || PrimEnergy != lastPrimaryEnergy ||
612 lastMaterial = aMaterial;
613 lastPrimaryEnergy = PrimEnergy;
618 need_to_compute =
true;
624 need_to_compute =
true;
631 need_to_compute =
false;
640 size_t ind_model = 0;
654 CS_Vs_Element.clear();
673 if(PrimEnergy > Tlow)
676 for(
size_t i = 0; i < n_el; ++i)
682 CS_Vs_Element.push_back(CS);
686 for(
size_t i = 0; i < n_el; ++i)
698 if(PrimEnergy > Tlow)
700 CS_Vs_Element.push_back(CS *
707 size_t ind_mat = aMaterial->
GetIndex();
716 if(PrimEnergy > Tlow)
718 CS_Vs_Element.push_back(CS);
724 for(
const auto& cs_vs_el : CS_Vs_Element)
738 std::vector<G4double> CS_Vs_Element;
740 isScatProjToProj, CS_Vs_Element);
743 for(
size_t i = 0; i < CS_Vs_Element.size(); ++i)
745 SumCS += CS_Vs_Element[i];
765 std::vector<G4double> CS_Vs_Element;
787 const std::vector<G4double>* aVec =
790 Tlow = (*aVec)[aCouple->
GetIndex()];
793 if(Ekin <= adjModel->GetHighEnergyLimit() &&
827std::vector<G4AdjointCSMatrix*>
830 G4int nbin_pro_decade)
842 EkinMaxForProd = EkinMaxForProd / 2.;
845 G4double dE = std::pow(10., 1. / nbin_pro_decade);
847 std::pow(10.,
double(
int(std::log10(EkinMin) * nbin_pro_decade) + 1) /
848 nbin_pro_decade) /
dE;
851 while(E1 < EkinMaxForProd)
855 std::vector<std::vector<double>*> aMat =
860 std::vector<double>* log_ESecVec = aMat[0];
861 std::vector<double>* log_CSVec = aMat[1];
862 G4double log_adjointCS = log_CSVec->back();
864 for(
size_t j = 0; j < log_CSVec->size(); ++j)
867 (*log_CSVec)[j] = 0.;
870 std::log(1. - std::exp((*log_CSVec)[j] - log_adjointCS) + 1e-50);
872 (*log_CSVec)[log_CSVec->size() - 1] =
873 (*log_CSVec)[log_CSVec->size() - 2] - std::log(1000.);
874 theCSMatForProdToProjBackwardScattering->
AddData(
875 std::log(E1), log_adjointCS, log_ESecVec, log_CSVec, 0);
882 E2 = std::pow(10.,
G4double(
int(std::log10(EkinMin) * nbin_pro_decade) + 1) /
883 nbin_pro_decade) /
dE;
886 while(E1 < EkinMaxForScat)
890 std::vector<std::vector<G4double>*> aMat =
892 E1,
Z,
A, nbin_pro_decade);
895 std::vector<G4double>* log_ESecVec = aMat[0];
896 std::vector<G4double>* log_CSVec = aMat[1];
897 G4double log_adjointCS = log_CSVec->back();
899 for(
size_t j = 0; j < log_CSVec->size(); ++j)
902 (*log_CSVec)[j] = 0.;
905 std::log(1. - std::exp((*log_CSVec)[j] - log_adjointCS) + 1e-50);
907 (*log_CSVec)[log_CSVec->size() - 1] =
908 (*log_CSVec)[log_CSVec->size() - 2] - std::log(1000.);
909 theCSMatForScatProjToProjBackwardScattering->
AddData(
910 std::log(E1), log_adjointCS, log_ESecVec, log_CSVec, 0);
916 std::vector<G4AdjointCSMatrix*> res;
917 res.push_back(theCSMatForProdToProjBackwardScattering);
918 res.push_back(theCSMatForScatProjToProjBackwardScattering);
924std::vector<G4AdjointCSMatrix*>
937 EkinMaxForProd /= 2.;
940 G4double dE = std::pow(10., 1. / nbin_pro_decade);
942 std::pow(10.,
double(
int(std::log10(EkinMin) * nbin_pro_decade) + 1) /
943 nbin_pro_decade) /
dE;
946 while(E1 < EkinMaxForProd)
950 std::vector<std::vector<G4double>*> aMat =
952 aMaterial, E1, nbin_pro_decade);
955 std::vector<G4double>* log_ESecVec = aMat[0];
956 std::vector<G4double>* log_CSVec = aMat[1];
957 G4double log_adjointCS = log_CSVec->back();
960 for(
size_t j = 0; j < log_CSVec->size(); ++j)
963 (*log_CSVec)[j] = 0.;
966 std::log(1. - std::exp((*log_CSVec)[j] - log_adjointCS));
968 (*log_CSVec)[log_CSVec->size() - 1] =
969 (*log_CSVec)[log_CSVec->size() - 2] - std::log(1000.);
970 theCSMatForProdToProjBackwardScattering->
AddData(
971 std::log(E1), log_adjointCS, log_ESecVec, log_CSVec, 0);
980 std::pow(10.,
G4double(
G4int(std::log10(EkinMin) * nbin_pro_decade) + 1) /
984 while(E1 < EkinMaxForScat)
988 std::vector<std::vector<G4double>*> aMat =
990 aMaterial, E1, nbin_pro_decade);
993 std::vector<G4double>* log_ESecVec = aMat[0];
994 std::vector<G4double>* log_CSVec = aMat[1];
995 G4double log_adjointCS = log_CSVec->back();
997 for(
size_t j = 0; j < log_CSVec->size(); ++j)
1000 (*log_CSVec)[j] = 0.;
1003 std::log(1. - std::exp((*log_CSVec)[j] - log_adjointCS));
1005 (*log_CSVec)[log_CSVec->size() - 1] =
1006 (*log_CSVec)[log_CSVec->size() - 2] - std::log(1000.);
1008 theCSMatForScatProjToProjBackwardScattering->
AddData(
1009 std::log(E1), log_adjointCS, log_ESecVec, log_CSVec, 0);
1015 std::vector<G4AdjointCSMatrix*> res;
1016 res.push_back(theCSMatForProdToProjBackwardScattering);
1017 res.push_back(theCSMatForScatProjToProjBackwardScattering);
1032 else if(theFwdPartDef ==
fFwdIon)
1047 else if(theAdjPartDef ==
fAdjIon)
1071 if(aPartDef != currentParticleDef)
1090 std::vector<double>* theLogPrimEnergyVector =
1092 if(theLogPrimEnergyVector->empty())
1094 G4cout <<
"No data are contained in the given AdjointCSMatrix!" <<
G4endl;
1097 G4double log_Tcut = std::log(Tcut);
1098 G4double log_E = std::log(aPrimEnergy);
1100 if(aPrimEnergy <= Tcut || log_E > theLogPrimEnergyVector->back())
1107 G4double aLogPrimEnergy1, aLogPrimEnergy2;
1110 std::vector<G4double>* aLogSecondEnergyVector1 =
nullptr;
1111 std::vector<G4double>* aLogSecondEnergyVector2 =
nullptr;
1112 std::vector<G4double>* aLogProbVector1 =
nullptr;
1113 std::vector<G4double>* aLogProbVector2 =
nullptr;
1114 std::vector<size_t>* aLogProbVectorIndex1 =
nullptr;
1115 std::vector<size_t>* aLogProbVectorIndex2 =
nullptr;
1117 anAdjointCSMatrix->
GetData(ind, aLogPrimEnergy1, aLogCS1, log01,
1118 aLogSecondEnergyVector1, aLogProbVector1,
1119 aLogProbVectorIndex1);
1120 anAdjointCSMatrix->
GetData(ind + 1, aLogPrimEnergy2, aLogCS2, log02,
1121 aLogSecondEnergyVector2, aLogProbVector2,
1122 aLogProbVectorIndex2);
1123 if (! (aLogProbVector1 && aLogProbVector2 &&
1124 aLogSecondEnergyVector1 && aLogSecondEnergyVector2)){
1130 G4double log_minimum_prob1, log_minimum_prob2;
1132 log_Tcut, *aLogSecondEnergyVector1, *aLogProbVector1);
1134 log_Tcut, *aLogSecondEnergyVector2, *aLogProbVector2);
1135 aLogCS1 += log_minimum_prob1;
1136 aLogCS2 += log_minimum_prob2;
1140 log_E, aLogPrimEnergy1, aLogPrimEnergy2, aLogCS1, aLogCS2);
1141 return std::exp(log_adjointCS);
static const G4double e1[44]
std::vector< G4Element * > G4ElementTable
std::vector< G4Material * > G4MaterialTable
G4GLOB_DLL std::ostream G4cout
static constexpr G4int fNbins
std::vector< G4bool > fIsScatProjToProj
void BuildTotalSigmaTables()
std::vector< G4PhysicsTable * > fSigmaTableForAdjointModelScatProjToProj
size_t RegisterEmAdjointModel(G4VEmAdjointModel *)
void RegisterAdjointParticle(G4ParticleDefinition *aPartDef)
G4ParticleDefinition * fFwdIon
G4ParticleDefinition * GetForwardParticleEquivalent(G4ParticleDefinition *theAdjPartDef)
std::vector< std::vector< G4VEnergyLossProcess * > * > fForwardLossProcesses
void GetMaxAdjTotalCS(G4ParticleDefinition *aPartDef, const G4MaterialCutsCouple *aCouple, G4double &e_sigma_max, G4double &sigma_max)
G4double GetCrossSectionCorrection(G4ParticleDefinition *aPartDef, G4double PreStepEkin, const G4MaterialCutsCouple *aCouple, G4bool &fwd_is_used)
G4double GetTotalForwardCS(G4ParticleDefinition *aPartDef, G4double Ekin, const G4MaterialCutsCouple *aCouple)
std::vector< std::vector< G4AdjointCSMatrix * > > fAdjointCSMatricesForScatProjToProj
G4double ComputeTotalAdjointCS(const G4MaterialCutsCouple *aMatCutCouple, G4ParticleDefinition *aPart, G4double PrimEnergy)
std::vector< G4PhysicsTable * > fTotalFwdSigmaTable
G4double ComputeAdjointCS(G4Material *aMaterial, G4VEmAdjointModel *aModel, G4double PrimEnergy, G4double Tcut, G4bool isScatProjToProj, std::vector< G4double > &AdjointCS_for_each_element)
G4MaterialCutsCouple * fCurrentCouple
std::vector< std::vector< G4double > > fEminForFwdSigmaTables
G4ParticleDefinition * fAdjIon
void DefineCurrentParticle(const G4ParticleDefinition *aPartDef)
std::vector< std::vector< G4VEmProcess * > * > fForwardProcesses
std::vector< G4AdjointCSMatrix * > BuildCrossSectionsModelAndMaterial(G4VEmAdjointModel *aModel, G4Material *aMaterial, G4int nbin_pro_decade)
std::vector< std::vector< G4double > > fEminForAdjSigmaTables
G4ParticleDefinition * GetAdjointParticleEquivalent(G4ParticleDefinition *theFwdPartDef)
static constexpr G4double fTmin
void DefineCurrentMaterial(const G4MaterialCutsCouple *couple)
size_t fCurrentParticleIndex
G4Element * SampleElementFromCSMatrices(G4Material *aMaterial, G4VEmAdjointModel *aModel, G4double PrimEnergy, G4double Tcut, G4bool isScatProjToProj)
G4double GetContinuousWeightCorrection(G4ParticleDefinition *aPartDef, G4double PreStepEkin, G4double AfterStepEkin, const G4MaterialCutsCouple *aCouple, G4double step_length)
std::vector< G4PhysicsTable * > fTotalAdjSigmaTable
G4double GetPostStepWeightCorrection()
void GetEminForTotalCS(G4ParticleDefinition *aPartDef, const G4MaterialCutsCouple *aCouple, G4double &emin_adj, G4double &emin_fwd)
std::vector< G4PhysicsTable * > fSigmaTableForAdjointModelProdToProj
G4Material * fCurrentMaterial
std::vector< std::vector< G4double > > fEkinofAdjSigmaMax
static G4AdjointCSManager * GetAdjointCSManager()
std::vector< G4AdjointCSMatrix * > BuildCrossSectionsModelAndElement(G4VEmAdjointModel *aModel, G4int Z, G4int A, G4int nbin_pro_decade)
static constexpr G4double fTmax
G4double GetTotalAdjointCS(G4ParticleDefinition *aPartDef, G4double Ekin, const G4MaterialCutsCouple *aCouple)
std::vector< G4ParticleDefinition * > fAdjointParticlesInAction
std::vector< G4VEmAdjointModel * > fAdjointModels
G4double GetAdjointSigma(G4double Ekin_nuc, size_t index_model, G4bool is_scat_proj_to_proj, const G4MaterialCutsCouple *aCouple)
std::vector< std::vector< G4double > > fLastAdjointCSVsModelsAndElements
void RegisterEmProcess(G4VEmProcess *aProcess, G4ParticleDefinition *aPartDef)
G4double fLastCSCorrectionFactor
void BuildCrossSectionMatrices()
std::vector< std::vector< G4double > > fEkinofFwdSigmaMax
void RegisterEnergyLossProcess(G4VEnergyLossProcess *aProcess, G4ParticleDefinition *aPartDef)
void GetMaxFwdTotalCS(G4ParticleDefinition *aPartDef, const G4MaterialCutsCouple *aCouple, G4double &e_sigma_max, G4double &sigma_max)
std::vector< std::vector< G4AdjointCSMatrix * > > fAdjointCSMatricesForProdToProj
std::vector< size_t > fIndexOfAdjointEMModelInAction
static G4ThreadLocal G4AdjointCSManager * fInstance
G4bool IsScatProjToProj()
G4bool GetData(unsigned int i, G4double &aPrimEnergy, G4double &aCS, G4double &log0, std::vector< double > *&aLogSecondEnergyVector, std::vector< double > *&aLogProbVector, std::vector< size_t > *&aLogProbVectorIndex)
std::vector< double > * GetLogPrimEnergyVector()
void AddData(G4double aPrimEnergy, G4double aCS, std::vector< double > *aLogSecondEnergyVector, std::vector< double > *aLogProbVector, size_t n_pro_decade=0)
static G4AdjointElectron * AdjointElectron()
static G4AdjointGamma * AdjointGamma()
G4double LinearInterpolation(G4double &x, G4double &x1, G4double &x2, G4double &y1, G4double &y2)
static G4AdjointInterpolator * GetInstance()
size_t FindPositionForLogVector(G4double &x, std::vector< G4double > &x_vec)
G4double InterpolateForLogVector(G4double &x, std::vector< G4double > &x_vec, std::vector< G4double > &y_vec)
static G4AdjointProton * AdjointProton()
static G4Electron * Electron()
static G4ElementTable * GetElementTable()
const G4Material * GetMaterial() const
const G4Element * GetElement(G4int iel) const
size_t GetNumberOfElements() const
const G4double * GetVecNbOfAtomsPerVolume() const
static G4MaterialTable * GetMaterialTable()
G4double GetPDGMass() const
const G4String & GetParticleName() const
void PutValue(const std::size_t index, const G4double value)
G4double Energy(const std::size_t index) const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
static G4Proton * Proton()
virtual G4double GetSecondAdjEnergyMaxForProdToProj(G4double primAdjEnergy)
G4bool GetSecondPartOfSameType()
G4bool GetUseOnlyOneMatrixForAllElements()
virtual G4double GetSecondAdjEnergyMinForScatProjToProj(G4double primAdjEnergy, G4double tcut=0.)
virtual G4double GetSecondAdjEnergyMaxForScatProjToProj(G4double primAdjEnergy)
std::vector< std::vector< double > * > ComputeAdjointCrossSectionVectorPerAtomForSecond(G4double kinEnergyProd, G4double Z, G4double A=0., G4int nbin_pro_decade=10)
G4ParticleDefinition * GetAdjointEquivalentOfDirectPrimaryParticleDefinition()
G4double GetLowEnergyLimit()
G4ParticleDefinition * GetAdjointEquivalentOfDirectSecondaryParticleDefinition()
G4bool GetApplyCutInRange()
virtual G4double AdjointCrossSection(const G4MaterialCutsCouple *aCouple, G4double primEnergy, G4bool isScatProjToProj)
std::vector< std::vector< double > * > ComputeAdjointCrossSectionVectorPerVolumeForSecond(G4Material *aMaterial, G4double kinEnergyProd, G4int nbin_pro_decade=10)
G4bool GetUseMatrixPerElement()
virtual G4double GetSecondAdjEnergyMinForProdToProj(G4double primAdjEnergy)
std::vector< std::vector< double > * > ComputeAdjointCrossSectionVectorPerVolumeForScatProj(G4Material *aMaterial, G4double kinEnergyProd, G4int nbin_pro_decade=10)
std::vector< std::vector< double > * > ComputeAdjointCrossSectionVectorPerAtomForScatProj(G4double kinEnergyProd, G4double Z, G4double A=0., G4int nbin_pro_decade=10)
G4double GetHighEnergyLimit()
virtual G4double GetChargeSquareRatio(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments