76 secondaryParticle(nullptr),
77 buildLambdaTable(true),
79 theLambdaTable(nullptr),
80 theLambdaTablePrim(nullptr),
86 currentCouple(nullptr),
90 currentModel(nullptr),
92 currentParticle(nullptr)
98 minKinEnergy = 0.1*keV;
99 maxKinEnergy = 100.0*TeV;
102 actBinning = actSpline = actMinKinEnergy = actMaxKinEnergy =
false;
106 logLambdaFactor =
G4Log(lambdaFactor);
109 biasFactor = fFactor = 1.0;
116 theCuts = theCutsGamma = theCutsElectron = theCutsPositron =
nullptr;
177void G4VEmProcess::Clear()
197 modelManager->
AddEmModel(order, p, fm, region);
205 for(
auto & em : emModels) {
if(em == ptr) {
return; } }
206 emModels.push_back(ptr);
213 return (index < emModels.size()) ? emModels[index] :
nullptr;
249 return modelManager->
GetModel(idx, ver);
264 if(pname !=
"deuteron" && pname !=
"triton" &&
265 pname !=
"alpha" && pname !=
"He3" &&
266 pname !=
"alpha+" && pname !=
"helium" &&
267 pname !=
"hydrogen") {
275 G4cout <<
"G4VEmProcess::PreparePhysicsTable() for "
282 if(particle != &part) {
return; }
295 theEnergyOfCrossSectionMax.resize(n, 0.0);
296 theCrossSectionMax.resize(n,
DBL_MAX);
311 logLambdaFactor =
G4Log(lambdaFactor);
316 for(
G4int i=0; i<numberOfModels; ++i) {
318 if(0 == i) { currentModel = mod; }
327 theCuts = modelManager->
Initialise(particle,secondaryParticle,
339 if(
isTheMaster && minKinEnergyPrim < maxKinEnergy){
340 theLambdaTablePrim = theData->
MakeTable(1);
373 G4cout <<
"### G4VEmProcess::BuildPhysicsTable() for "
375 <<
" and particle " << num
376 <<
" buildLambdaTable= " << buildLambdaTable
382 if(particle == &part) {
389 if(theLambdaTable) { FindLambdaMax(); }
394 for(
G4int i=0; i<numberOfModels; ++i) {
403 if(buildLambdaTable || minKinEnergyPrim < maxKinEnergy) {
412 num ==
"e+" || num ==
"mu+" ||
413 num ==
"mu-" || num ==
"proton"||
414 num ==
"pi+" || num ==
"pi-" ||
415 num ==
"kaon+" || num ==
"kaon-" ||
416 num ==
"alpha" || num ==
"anti_proton" ||
417 num ==
"GenericIon"|| num ==
"alpha++" ||
418 num ==
"alpha+" || num ==
"helium" ||
425 G4cout <<
"### G4VEmProcess::BuildPhysicsTable() done for "
427 <<
" and particle " << num
434void G4VEmProcess::BuildLambdaTable()
437 G4cout <<
"G4EmProcess::BuildLambdaTable() for process "
457 scale =
G4Log(scale);
458 if(actBinning) { nbin = std::max(nbin, nLambdaBins); }
459 G4double emax1 = std::min(maxKinEnergy, minKinEnergyPrim);
461 for(
size_t i=0; i<numOfCouples; ++i) {
470 if(buildLambdaTable) {
471 delete (*theLambdaTable)[i];
484 if(emax <= emin) { emax = 2*emin; }
486 if(bin < 3) { bin = 3; }
494 if(minKinEnergyPrim < maxKinEnergy) {
495 delete (*theLambdaTablePrim)[i];
500 if(bin < 3) { bin = 3; }
503 bVectorPrim = aVectorPrim;
518 if(buildLambdaTable) { FindLambdaMax(); }
521 G4cout <<
"Lambda table is built for "
529void G4VEmProcess::StreamInfo(std::ostream& out,
533 out << std::setprecision(6);
537 if (integral) { out <<
","; }
539 if(integral) { out <<
" integral:1 "; }
540 if(applyCuts) { out <<
" applyCuts:1 "; }
542 if(biasFactor != 1.0) { out <<
" BiasingFactor= " << biasFactor; }
543 out <<
" BuildTable=" << buildLambdaTable <<
G4endl;
544 if(buildLambdaTable) {
545 if(particle == &part) {
546 size_t length = theLambdaTable->
length();
547 for(
size_t i=0; i<length; ++i) {
550 out <<
" Lambda table from ";
554 if(emin > minKinEnergy) { out <<
"threshold "; }
558 <<
", " <<
G4lrint(nbin/std::log10(emax/emin))
559 <<
" bins/decade, spline: "
565 out <<
" Used Lambda table of "
569 if(minKinEnergyPrim < maxKinEnergy) {
570 if(particle == &part) {
571 size_t length = theLambdaTablePrim->
length();
572 for(
size_t i=0; i<length; ++i) {
575 out <<
" LambdaPrime table from "
585 out <<
" Used LambdaPrime table of "
593 out <<
" LambdaTable address= " << theLambdaTable <<
G4endl;
594 if(theLambdaTable && particle == &part) {
595 out << (*theLambdaTable) <<
G4endl;
609 if(isIon) { massRatio = proton_mass_c2/currentParticle->
GetPDGMass(); }
637 if(!currentModel->
IsActive(scaledEnergy)) {
698 if(e <= epeak && e/lambdaFactor >=
mfpKinEnergy) {
return; }
709 const G4double preStepLambda1 = GetCurrentLambda(e1,loge+logLambdaFactor);
752 <<
" E(MeV)= " << finalT/MeV
754 << lx <<
" (postLambda) "
764 G4double scaledEnergy = finalT*massRatio;
771 weight /= biasFactor;
777 G4cout <<
"G4VEmProcess::PostStepDoIt: Sample secondary; E= "
817 for (
G4int i=0; i<num; ++i) {
830 }
else if (p == thePositron) {
834 e += 2.0*electron_mass_c2;
894 if ( theLambdaTable && part == particle) {
902 <<
" in the directory <" << directory
905 G4cout <<
"Fail to store Physics Table for "
908 <<
" in the directory <" << directory
912 if ( theLambdaTablePrim && part == particle) {
918 G4cout <<
"Physics table prim is stored for "
921 <<
" in the directory <" << directory
924 G4cout <<
"Fail to store Physics Table Prim for "
927 <<
" in the directory <" << directory
941 G4cout <<
"G4VEmProcess::RetrievePhysicsTable() for "
947 if((!buildLambdaTable && minKinEnergyPrim > maxKinEnergy)
948 || particle != part) {
return yes; }
952 if(buildLambdaTable) {
959 G4cout <<
"Lambda table for " << particleName
960 <<
" is Retrieved from <"
965 size_t n = theLambdaTable->
length();
966 for(
size_t i=0; i<n; ++i) {
967 if((* theLambdaTable)[i]) {
968 (* theLambdaTable)[i]->SetSpline(
true);
974 G4cout <<
"Lambda table for " << particleName <<
" in file <"
975 << filename <<
"> is not exist"
980 if(minKinEnergyPrim < maxKinEnergy) {
987 G4cout <<
"Lambda table prim for " << particleName
988 <<
" is Retrieved from <"
993 size_t n = theLambdaTablePrim->
length();
994 for(
size_t i=0; i<n; ++i) {
995 if((* theLambdaTablePrim)[i]) {
996 (* theLambdaTablePrim)[i]->SetSpline(
true);
1002 G4cout <<
"Lambda table prim for " << particleName <<
" in file <"
1003 << filename <<
"> is not exist"
1021 if(buildLambdaTable) {
1022 cross = GetCurrentLambda(kineticEnergy,
1023 (logKinEnergy <
DBL_MAX) ? logKinEnergy :
G4Log(kineticEnergy));
1032 return std::max(cross, 0.0);
1051 const G4double xs = GetCurrentLambda(kinEnergy,
1053 return (0.0 < xs) ? 1.0/xs :
DBL_MAX;
1063 return (currentModel) ?
1070void G4VEmProcess::FindLambdaMax()
1073 G4cout <<
"### G4VEmProcess::FindLambdaMax: "
1077 size_t n = theLambdaTable->
length();
1084 for (i=0; i<
n; ++i) {
1085 pv = (*theLambdaTable)[i];
1091 for (
size_t j=0; j<nb; ++j) {
1100 theEnergyOfCrossSectionMax[i] = emax;
1101 theCrossSectionMax[i] = smax;
1104 <<
" Max CS at i= " << i <<
" emax(MeV)= " << emax/MeV
1105 <<
" lambda= " << smax <<
G4endl;
1110 for (i=0; i<
n; ++i) {
1111 pv = (*theLambdaTable)[i];
1113 G4int j = (*theDensityIdx)[i];
1114 theEnergyOfCrossSectionMax[i] = theEnergyOfCrossSectionMax[j];
1115 theCrossSectionMax[i] = (*theDensityFactor)[i]*theCrossSectionMax[j];
1148 G4cout <<
"### SetCrossSectionBiasingFactor: for "
1151 <<
" biasFactor= " << f <<
" weightFlag= " << flag
1165 G4cout <<
"### ActivateForcedInteraction: for "
1168 <<
" length(mm)= " << length/mm
1169 <<
" in G4Region <" << r
1170 <<
"> weightFlag= " << flag
1184 if (0.0 <= factor) {
1193 G4cout <<
"### ActivateSecondaryBiasing: for "
1195 <<
" factor= " << factor
1196 <<
" in G4Region <" << region
1197 <<
"> energyLimit(MeV)= " << energyLimit/MeV
1207 if(5 < n && n < 10000000) {
1212 PrintWarning(
"SetLambdaBinning", e);
1220 if(1.e-3*eV < e && e < maxKinEnergy) {
1221 nLambdaBins =
G4lrint(nLambdaBins*
G4Log(maxKinEnergy/e)
1222 /
G4Log(maxKinEnergy/minKinEnergy));
1224 actMinKinEnergy =
true;
1225 }
else { PrintWarning(
"SetMinKinEnergy", e); }
1232 if(minKinEnergy < e && e < 1.e+6*TeV) {
1233 nLambdaBins =
G4lrint(nLambdaBins*
G4Log(e/minKinEnergy)
1234 /
G4Log(maxKinEnergy/minKinEnergy));
1236 actMaxKinEnergy =
true;
1237 }
else { PrintWarning(
"SetMaxKinEnergy", e); }
1245 e <= theParameters->
MaxKinEnergy()) { minKinEnergyPrim = e; }
1246 else { PrintWarning(
"SetMinKinEnergyPrim", e); }
1262 return GetCurrentLambda(kinEnergy,
G4Log(kinEnergy));
1269 G4String ss =
"G4VEmProcess::" + tit;
1271 ed <<
"Parameter is out of range: " << val
1272 <<
" it will have no effect!\n" <<
" Process "
1284 StreamInfo(out, *particle,
true);
double A(double temperature)
G4double condition(const G4ErrorSymMatrix &m)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Log(G4double x)
G4GLOB_DLL std::ostream G4cout
G4double GetLogKineticEnergy() const
const G4ParticleDefinition * GetParticleDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
G4bool ForcedInteractionRegion(G4int coupleIdx)
G4double ApplySecondaryBiasing(std::vector< G4DynamicParticle * > &, const G4Track &track, G4VEmModel *currentModel, G4ParticleChangeForGamma *pParticleChange, G4double &eloss, G4int coupleIdx, G4double tcut, G4double safety=0.0)
void ActivateSecondaryBiasing(const G4String ®ion, G4double factor, G4double energyLimit)
void ResetForcedInteraction()
void Initialise(const G4ParticleDefinition &part, const G4String &procName, G4int verbose)
G4double GetWeight(G4int i)
void ActivateForcedInteraction(G4double length=0.0, const G4String &r="")
G4bool SecondaryBiasingRegion(G4int coupleIdx)
G4double GetStepLimit(G4int coupleIdx, G4double previousStep)
G4PhysicsTable * MakeTable(size_t idx)
void AddEmModel(G4int, G4VEmModel *, G4VEmFluctuationModel *, const G4Region *)
void UpdateEmModel(const G4String &model_name, G4double emin, G4double emax)
void DumpModelList(std::ostream &out, G4int verb)
G4int NumberOfModels() const
void SetFluoFlag(G4bool val)
const G4DataVector * Initialise(const G4ParticleDefinition *part, const G4ParticleDefinition *secPart, G4double minSubRange, G4int verb)
void FillLambdaVector(G4PhysicsVector *, const G4MaterialCutsCouple *, G4bool startFromNull=true, G4EmTableType t=fRestricted)
G4int NumberOfRegionModels(size_t index_couple) const
G4VEmModel * GetRegionModel(G4int idx, size_t index_couple)
G4VEmModel * GetModel(G4int idx, G4bool ver=false)
static G4EmParameters * Instance()
G4int NumberOfBins() const
G4double MinKinEnergy() const
G4int NumberOfBinsPerDecade() const
G4double MscThetaLimit() const
void DefineRegParamForEM(G4VEmProcess *) const
G4int WorkerVerbose() const
G4double MaxKinEnergy() const
G4double LambdaFactor() const
static G4GenericIon * GenericIon()
const std::vector< G4double > * GetDensityFactors() const
const std::vector< G4int > * GetCoupleIndexes() const
void InitialiseBaseMaterials(const G4PhysicsTable *table=nullptr)
G4bool GetFlag(size_t idx)
static G4LossTableManager * Instance()
G4LossTableBuilder * GetTableBuilder()
void PreparePhysicsTable(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p, G4bool theMaster)
void DeRegister(G4VEnergyLossProcess *p)
void Register(G4VEnergyLossProcess *p)
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
void InitializeForPostStep(const G4Track &)
G4double GetProposedKineticEnergy() const
G4ProcessManager * GetProcessManager() const
const G4String & GetParticleType() const
G4double GetPDGMass() const
const G4String & GetParticleName() const
const G4String & GetParticleSubType() const
static G4int Register(const G4String &)
static void SetPhysicsVector(G4PhysicsTable *physTable, std::size_t idx, G4PhysicsVector *vec)
static G4bool RetrievePhysicsTable(G4PhysicsTable *physTable, const G4String &fileName, G4bool ascii)
G4bool StorePhysicsTable(const G4String &filename, G4bool ascii=false)
std::size_t length() const
G4double Energy(std::size_t index) const
G4double GetMaxEnergy() const
void FillSecondDerivatives()
std::size_t GetVectorLength() const
static G4Positron * Positron()
G4ProcessVector * GetAtRestProcessVector(G4ProcessVectorTypeIndex typ=typeGPIL) 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()
G4double GetSafety() const
G4StepPoint * GetPostStepPoint() const
G4TrackStatus GetTrackStatus() const
const G4ParticleDefinition * GetParticleDefinition() const
void SetWeight(G4double aValue)
const G4ThreeVector & GetPosition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4double GetGlobalTime() const
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
G4double GetKineticEnergy() const
G4int GetParentID() const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
void SetCreatorModelIndex(G4int idx)
void SetPolarAngleLimit(G4double)
void SetHighEnergyLimit(G4double)
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0., G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void SetMasterThread(G4bool val)
G4double LowEnergyLimit() const
virtual G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
const G4Element * GetCurrentElement() const
void SetParticleChange(G4VParticleChange *, G4VEmFluctuationModel *f=nullptr)
G4double HighEnergyLimit() const
G4bool IsActive(G4double kinEnergy) const
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin=0.0, G4double tmax=DBL_MAX)=0
virtual void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel)
void DefineMaterial(const G4MaterialCutsCouple *couple)
G4VEmModel * GetModelByIndex(G4int idx=0, G4bool ver=false) const
G4double MeanFreePath(const G4Track &track)
G4PhysicsVector * LambdaPhysicsVector(const G4MaterialCutsCouple *)
void CurrentSetup(const G4MaterialCutsCouple *, G4double energy)
G4double CrossSectionPerVolume(G4double kineticEnergy, const G4MaterialCutsCouple *couple, G4double logKinEnergy=DBL_MAX)
virtual void StreamProcessInfo(std::ostream &) const
G4VEmProcess(const G4String &name, G4ProcessType type=fElectromagnetic)
G4LossTableManager * lManager
G4EmBiasingManager * biasManager
virtual void BuildPhysicsTable(const G4ParticleDefinition &) override
G4VEmModel * EmModel(size_t index=0) const
G4double preStepLogKinEnergy
virtual G4double MinPrimaryEnergy(const G4ParticleDefinition *, const G4Material *)
G4double ComputeCrossSectionPerAtom(G4double kineticEnergy, G4double Z, G4double A=0., G4double cut=0.0)
G4PhysicsTable * LambdaTable() const
void SetMinKinEnergy(G4double e)
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &) override
virtual void StartTracking(G4Track *) override
void AddEmModel(G4int, G4VEmModel *, const G4Region *region=nullptr)
void SetEmModel(G4VEmModel *, G4int index=0)
void SetCrossSectionBiasingFactor(G4double f, G4bool flag=true)
virtual void InitialiseProcess(const G4ParticleDefinition *)=0
void SetLambdaBinning(G4int nbins)
const std::vector< G4double > * theDensityFactor
virtual G4bool RetrievePhysicsTable(const G4ParticleDefinition *, const G4String &directory, G4bool ascii) override
virtual void ProcessDescription(std::ostream &outFile) const override
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
void UpdateEmModel(const G4String &, G4double, G4double)
virtual G4VEmProcess * GetEmProcess(const G4String &name)
G4double MaxKinEnergy() const
G4VEmModel * SelectModel(G4double kinEnergy, size_t index)
std::vector< G4DynamicParticle * > secParticles
void ActivateForcedInteraction(G4double length=0.0, const G4String &r="", G4bool flag=true)
const G4ParticleDefinition * theElectron
G4EmParameters * theParameters
const G4MaterialCutsCouple * currentCouple
const G4ParticleDefinition * theGamma
G4PhysicsTable * LambdaTablePrim() const
virtual G4bool StorePhysicsTable(const G4ParticleDefinition *, const G4String &directory, G4bool ascii=false) override
void ActivateSecondaryBiasing(const G4String ®ion, G4double factor, G4double energyLimit)
G4double preStepKinEnergy
size_t currentCoupleIndex
G4double GetLambda(G4double kinEnergy, const G4MaterialCutsCouple *couple)
G4ParticleChangeForGamma fParticleChange
const std::vector< G4int > * theDensityIdx
void SetParticle(const G4ParticleDefinition *p)
G4VEmModel * GetRegionModel(G4int idx, size_t couple_index) const
void SetMinKinEnergyPrim(G4double e)
virtual void PreparePhysicsTable(const G4ParticleDefinition &) override
void SetMaxKinEnergy(G4double e)
G4int GetNumberOfRegionModels(size_t couple_index) const
const G4Material * currentMaterial
const G4Element * GetCurrentElement() const
virtual G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
G4int GetNumberOfModels() const
G4double GetParentWeight() const
void ProposeTrackStatus(G4TrackStatus status)
void SetSecondaryWeightByProcess(G4bool)
void ProposeWeight(G4double finalWeight)
G4double GetLocalEnergyDeposit() const
void AddSecondary(G4Track *aSecondary)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetNumberOfSecondaries(G4int totSecondaries)
G4TrackStatus GetTrackStatus() const
G4double currentInteractionLength
G4double theInitialNumberOfInteractionLength
void SetVerboseLevel(G4int value)
const G4VProcess * GetMasterProcess() const
void ClearNumberOfInteractionLengthLeft()
G4double theNumberOfInteractionLengthLeft
G4VParticleChange * pParticleChange
G4int GetProcessSubType() const
const G4String & GetPhysicsTableFileName(const G4ParticleDefinition *, const G4String &directory, const G4String &tableName, G4bool ascii=false)
const G4String & GetProcessName() const