94 #ifndef G4VEnergyLossProcess_h
95 #define G4VEnergyLossProcess_h 1
460 inline G4double GetLimitScaledRangeForScaledEnergy(
G4double scaledKinEnergy);
463 inline void ComputeLambdaForScaledEnergy(
G4double scaledKinEnergy);
486 std::vector<G4VEmModel*> emModels;
489 std::vector<const G4Region*> scoffRegions;
493 std::vector<G4VEnergyLossProcess*> scProcesses;
511 size_t idxDEDXunRestricted;
512 size_t idxIonisation;
513 size_t idxIonisationSub;
517 size_t idxInverseRange;
521 std::vector<G4double> theDEDXAtMaxEnergy;
522 std::vector<G4double> theRangeAtMaxEnergy;
523 std::vector<G4double> theEnergyOfCrossSectionMax;
524 std::vector<G4double> theCrossSectionMax;
526 const std::vector<G4double>* theDensityFactor;
527 const std::vector<G4int>* theDensityIdx;
549 G4bool lossFluctuationFlag;
569 std::vector<G4DynamicParticle*> secParticles;
570 std::vector<G4Track*> scTracks;
577 size_t currentCoupleIndex;
578 size_t basedCoupleIndex;
607 return currentCoupleIndex;
614 currentModel = modelManager->
SelectModel(kinEnergy, currentCoupleIndex);
621 G4double kinEnergy,
size_t& idx)
const
631 if(couple != currentCouple) {
632 currentCouple = couple;
634 currentCoupleIndex = couple->
GetIndex();
635 basedCoupleIndex = (*theDensityIdx)[currentCoupleIndex];
636 fFactor = chargeSqRatio*biasFactor*(*theDensityFactor)[currentCoupleIndex];
637 reduceFactor = 1.0/(fFactor*massRatio);
639 idxLambda = idxSubLambda = 0;
648 massRatio = massratio;
649 fFactor = charge2ratio*biasFactor*(*theDensityFactor)[currentCoupleIndex];
650 chargeSqRatio = charge2ratio;
651 reduceFactor = 1.0/(fFactor*massRatio);
663 G4double x = fFactor*(*theDEDXTable)[basedCoupleIndex]->Value(e, idxDEDX);
664 if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
673 fFactor*(*theDEDXSubTable)[basedCoupleIndex]->Value(e, idxDEDXSub);
674 if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
680 inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(
G4double e)
683 fFactor*(*theIonisationTable)[basedCoupleIndex]->Value(e, idxIonisation);
684 if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
694 (*theIonisationSubTable)[basedCoupleIndex]->Value(e, idxIonisationSub);
695 if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
701 inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(
G4double e)
706 if(basedCoupleIndex != lastIdx || preStepRangeEnergy != e) {
707 lastIdx = basedCoupleIndex;
708 preStepRangeEnergy = e;
710 ((*theRangeTableForLoss)[basedCoupleIndex])->Value(e, idxRange);
711 if(e < minKinEnergy) { computedRange *= std::sqrt(e/minKinEnergy); }
717 return computedRange;
723 G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(
G4double e)
726 if (e < maxKinEnergyCSDA) {
727 x = ((*theCSDARangeTable)[basedCoupleIndex])->Value(e, idxCSDA);
728 if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
730 x = theRangeAtMaxEnergy[basedCoupleIndex] +
731 (e - maxKinEnergyCSDA)/theDEDXAtMaxEnergy[basedCoupleIndex];
746 if(r >= rmin) { e = v->
Value(r, idxInverseRange); }
749 e = minKinEnergy*x*
x;
758 return fFactor*((*theLambdaTable)[basedCoupleIndex])->Value(e, idxLambda);
767 DefineMaterial(couple);
768 return GetDEDXForScaledEnergy(kineticEnergy*massRatio);
777 DefineMaterial(couple);
778 return GetSubDEDXForScaledEnergy(kineticEnergy*massRatio);
788 DefineMaterial(couple);
789 if(theCSDARangeTable) {
790 x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)
792 }
else if(theRangeTableForLoss) {
793 x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
804 DefineMaterial(couple);
806 if(theCSDARangeTable) {
807 x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
819 DefineMaterial(couple);
821 GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
833 DefineMaterial(couple);
834 return ScaledKinEnergyForLoss(range/reduceFactor)/massRatio;
843 DefineMaterial(couple);
845 if(theLambdaTable) { x = GetLambdaForScaledEnergy(kineticEnergy*massRatio); }
851 inline void G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(
G4double e)
853 mfpKinEnergy = theEnergyOfCrossSectionMax[currentCoupleIndex];
854 if (e <= mfpKinEnergy) {
855 preStepLambda = GetLambdaForScaledEnergy(e);
859 if(e1 > mfpKinEnergy) {
860 preStepLambda = GetLambdaForScaledEnergy(e);
861 G4double preStepLambda1 = GetLambdaForScaledEnergy(e1);
862 if(preStepLambda1 > preStepLambda) {
864 preStepLambda = preStepLambda1;
867 preStepLambda = fFactor*theCrossSectionMax[currentCoupleIndex];
897 secondaryParticle =
p;
925 return secondaryParticle;
932 lossFluctuationFlag = val;
990 if(val > 0.0 && val <= 1.0) { lambdaFactor = val; }
999 if (dRoverRange > 0.999) { dRoverRange = 1.0; }
1006 lowestKinEnergy = val;
1013 return nSCoffRegions;
1048 return minKinEnergy;
1056 if(e < maxKinEnergyCSDA) { maxKinEnergyCSDA = e; }
1063 return maxKinEnergy;
1070 maxKinEnergyCSDA = e;
1084 return tablesAreBuilt;
1091 return theDEDXTable;
1098 return theDEDXSubTable;
1105 return theDEDXunRestrictedTable;
1112 return theIonisationTable;
1119 return theIonisationSubTable;
1126 return theCSDARangeTable;
1133 return theSecondaryRangeTable;
1140 return theRangeTableForLoss;
1147 return theInverseRangeTable;
1154 return theLambdaTable;
1161 return theSubLambdaTable;
G4double GetKineticEnergy(G4double &range, const G4MaterialCutsCouple *)
G4VEnergyLossProcess(const G4String &name="EnergyLoss", G4ProcessType type=fElectromagnetic)
G4double condition(const G4ErrorSymMatrix &m)
void SetDEDXTable(G4PhysicsTable *p, G4EmTableType tType)
void SetIntegral(G4bool val)
void SetMaxKinEnergyForCSDARange(G4double e)
void SetDynamicMassCharge(G4double massratio, G4double charge2ratio)
void PrintInfoDefinition(const G4ParticleDefinition &part)
void SetIonisation(G4bool val)
void BuildPhysicsTable(const G4ParticleDefinition &)
G4double GetDEDX(G4double &kineticEnergy, const G4MaterialCutsCouple *)
G4PhysicsTable * SubLambdaTable() const
G4PhysicsTable * RangeTableForLoss() const
G4double GetContinuousStepLimit(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety)
G4PhysicsTable * SecondaryRangeTable() const
G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
G4double GetRangeForLoss(G4double &kineticEnergy, const G4MaterialCutsCouple *)
void AddCollaborativeProcess(G4VEnergyLossProcess *)
void ActivateForcedInteraction(G4double length=0.0, const G4String ®ion="", G4bool flag=true)
void SetLinearLossLimit(G4double val)
G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
void SetStepFunction(G4double v1, G4double v2)
G4PhysicsTable * CSDARangeTable() const
G4bool StorePhysicsTable(const G4ParticleDefinition *, const G4String &directory, G4bool ascii=false)
G4ParticleChangeForLoss fParticleChange
G4double GetCSDARange(G4double &kineticEnergy, const G4MaterialCutsCouple *)
void SelectModel(G4double kinEnergy)
void SetLambdaBinning(G4int nbins)
G4VEmModel * GetModelByIndex(G4int idx=0, G4bool ver=false) const
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
G4int NumberOfModels() const
G4PhysicsTable * IonisationTableForSubsec() const
G4double GetDEDXForSubsec(G4double &kineticEnergy, const G4MaterialCutsCouple *)
void ActivateSecondaryBiasing(const G4String ®ion, G4double factor, G4double energyLimit)
void SetFluctModel(G4VEmFluctuationModel *)
G4PhysicsVector * LambdaPhysicsVector(const G4MaterialCutsCouple *, G4double cut)
G4PhysicsTable * IonisationTable() const
G4PhysicsTable * BuildLambdaTable(G4EmTableType tType=fRestricted)
G4PhysicsTable * LambdaTable() const
void SetInverseRangeTable(G4PhysicsTable *p)
const G4ParticleDefinition * SecondaryParticle() const
void SetCrossSectionBiasingFactor(G4double f, G4bool flag=true)
G4VEmFluctuationModel * FluctModel()
G4double SampleSubCutSecondaries(std::vector< G4Track * > &, const G4Step &, G4VEmModel *model, G4int matIdx)
G4PhysicsTable * DEDXTable() const
const G4ParticleDefinition const G4Material *G4double range
const G4Element * GetCurrentElement() const
void SetLossFluctuations(G4bool val)
void SetDEDXBinningForCSDARange(G4int nbins)
const XML_Char XML_Content * model
virtual ~G4VEnergyLossProcess()
G4int NumberOfSubCutoffRegions() const
G4bool IsIntegral() const
void SetMaxKinEnergy(G4double e)
G4double GetLambda(G4double &kineticEnergy, const G4MaterialCutsCouple *)
G4VParticleChange * AlongStepDoIt(const G4Track &, const G4Step &)
const G4ParticleDefinition * BaseParticle() const
void AddEmModel(G4int, G4VEmModel *, G4VEmFluctuationModel *fluc=0, const G4Region *region=0)
G4PhysicsTable * DEDXTableForSubsec() const
G4double Energy(size_t index) const
G4double Value(G4double theEnergy, size_t &lastidx) const
G4double AlongStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
void SetSecondaryParticle(const G4ParticleDefinition *p)
G4bool RetrievePhysicsTable(const G4ParticleDefinition *, const G4String &directory, G4bool ascii)
void PreparePhysicsTable(const G4ParticleDefinition &)
void SetLambdaTable(G4PhysicsTable *p)
virtual void PrintInfo()=0
G4PhysicsTable * InverseRangeTable() const
G4double CrossSectionBiasingFactor() const
void StartTracking(G4Track *)
const G4ParticleDefinition * Particle() const
void SetCurrentCouple(const G4MaterialCutsCouple *)
G4double MeanFreePath(const G4Track &track)
void UpdateEmModel(const G4String &, G4double, G4double)
G4bool TablesAreBuilt() const
virtual G4bool IsApplicable(const G4ParticleDefinition &p)=0
void SetEmModel(G4VEmModel *, G4int index=1)
G4double ContinuousStepLimit(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety)
G4double MinKinEnergy() const
G4double MaxKinEnergy() const
G4VEmModel * SelectModel(G4double &energy, size_t &index)
void SetCSDARangeTable(G4PhysicsTable *pRange)
G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple, const G4DynamicParticle *dp, G4double length)
void SetMinSubRange(G4double val)
void SetSecondaryRangeTable(G4PhysicsTable *p)
G4PhysicsTable * DEDXunRestrictedTable() const
void SetLambdaFactor(G4double val)
void SetLowestEnergyLimit(G4double)
void SetSubLambdaTable(G4PhysicsTable *p)
virtual G4double MinPrimaryEnergy(const G4ParticleDefinition *, const G4Material *, G4double cut)
void ActivateSubCutoff(G4bool val, const G4Region *region=0)
void SetRangeTableForLoss(G4PhysicsTable *p)
void SetParticle(const G4ParticleDefinition *p)
void SetBaseParticle(const G4ParticleDefinition *p)
G4PhysicsTable * BuildDEDXTable(G4EmTableType tType=fRestricted)
G4VEmModel * EmModel(G4int index=1) const
G4VEmModel * SelectModelForMaterial(G4double kinEnergy, size_t &idx) const
void SetDEDXBinning(G4int nbins)
G4double GetRange(G4double &kineticEnergy, const G4MaterialCutsCouple *)
virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition *, const G4ParticleDefinition *)=0
const G4Material * GetMaterial() const
void SetRandomStep(G4bool val)
size_t CurrentMaterialCutsCoupleIndex() const
G4double CrossSectionPerVolume(G4double kineticEnergy, const G4MaterialCutsCouple *couple)
G4bool IsIonisationProcess() const
void SetMinKinEnergy(G4double e)