Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:59:21

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 // -------------------------------------------------------------------
0028 //
0029 // GEANT4 Class header file
0030 //
0031 //
0032 // File name:     G4VEnergyLossProcess
0033 //
0034 // Author:        Vladimir Ivanchenko on base of Laszlo Urban code
0035 //
0036 // Creation date: 03.01.2002
0037 //
0038 // Modifications: Vladimir Ivanchenko
0039 //
0040 // Class Description:
0041 //
0042 // It is the unified energy loss process it calculates the continuous
0043 // energy loss for charged particles using a set of Energy Loss
0044 // models valid for different energy regions. There are a possibility
0045 // to create and access to dE/dx and range tables, or to calculate
0046 // that information on fly.
0047 
0048 // -------------------------------------------------------------------
0049 //
0050 
0051 #ifndef G4VEnergyLossProcess_h
0052 #define G4VEnergyLossProcess_h 1
0053 
0054 #include "G4VContinuousDiscreteProcess.hh"
0055 #include "globals.hh"
0056 #include "G4Material.hh"
0057 #include "G4MaterialCutsCouple.hh"
0058 #include "G4Track.hh"
0059 #include "G4EmModelManager.hh"
0060 #include "G4ParticleChangeForLoss.hh"
0061 #include "G4EmTableType.hh"
0062 #include "G4EmSecondaryParticleType.hh"
0063 #include "G4PhysicsTable.hh"
0064 #include "G4PhysicsVector.hh"
0065 
0066 class G4Step;
0067 class G4ParticleDefinition;
0068 class G4EmParameters;
0069 class G4VEmModel;
0070 class G4VEmFluctuationModel;
0071 class G4DataVector;
0072 class G4Region;
0073 class G4SafetyHelper;
0074 class G4VAtomDeexcitation;
0075 class G4VSubCutProducer;
0076 class G4EmBiasingManager;
0077 class G4LossTableManager;
0078 class G4EmDataHandler;
0079 
0080 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0081 
0082 class G4VEnergyLossProcess : public G4VContinuousDiscreteProcess
0083 {
0084 public:
0085 
0086   G4VEnergyLossProcess(const G4String& name = "EnergyLoss",
0087                        G4ProcessType type = fElectromagnetic);
0088 
0089   ~G4VEnergyLossProcess() override;
0090 
0091   //------------------------------------------------------------------------
0092   // Virtual methods to be implemented in concrete processes
0093   //------------------------------------------------------------------------
0094 
0095 protected:
0096 
0097   // description of specific process parameters
0098   virtual void StreamProcessInfo(std::ostream&) const {};
0099 
0100   virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition*,
0101                                            const G4ParticleDefinition*) = 0;
0102 
0103 public:
0104 
0105   // used as low energy limit LambdaTable
0106   virtual G4double MinPrimaryEnergy(const G4ParticleDefinition*,
0107                                     const G4Material*, G4double cut);
0108 
0109   // print documentation in html format
0110   void ProcessDescription(std::ostream& outFile) const override;
0111 
0112   // prepare all tables
0113   void PreparePhysicsTable(const G4ParticleDefinition&) override;
0114 
0115   // build all tables
0116   void BuildPhysicsTable(const G4ParticleDefinition&) override;
0117 
0118   // build a table
0119   G4PhysicsTable* BuildDEDXTable(G4EmTableType tType = fRestricted);
0120 
0121   // build a table
0122   G4PhysicsTable* BuildLambdaTable(G4EmTableType tType = fRestricted);
0123 
0124   // Called before tracking of each new G4Track
0125   void StartTracking(G4Track*) override;
0126 
0127   // Step limit from AlongStep 
0128   G4double AlongStepGetPhysicalInteractionLength(
0129                                   const G4Track&,
0130                                   G4double  previousStepSize,
0131                                   G4double  currentMinimumStep,
0132                                   G4double& currentSafety,
0133                                   G4GPILSelection* selection) override;
0134 
0135   // Step limit from cross section
0136   G4double PostStepGetPhysicalInteractionLength(
0137                                   const G4Track& track,
0138                                   G4double previousStepSize,
0139                                   G4ForceCondition* condition) override;
0140 
0141   // AlongStep computations
0142   G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&) override;
0143 
0144   // PostStep sampling of secondaries
0145   G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&) override;
0146 
0147   // Store all PhysicsTable in files.
0148   // Return false in case of any fatal failure at I/O  
0149   G4bool StorePhysicsTable(const G4ParticleDefinition*,
0150                            const G4String& directory,
0151                            G4bool ascii = false) override;
0152 
0153   // Retrieve all Physics from a files.
0154   // Return true if all the Physics Table are built.
0155   // Return false if any fatal failure. 
0156   G4bool RetrievePhysicsTable(const G4ParticleDefinition*,
0157                               const G4String& directory,
0158                               G4bool ascii) override;
0159 
0160 private:
0161 
0162   // summary printout after initialisation
0163   void StreamInfo(std::ostream& out, const G4ParticleDefinition& part,
0164                   G4bool rst=false) const;
0165 
0166   //------------------------------------------------------------------------
0167   // Public interface to cross section, mfp and sampling of fluctuations
0168   // These methods are not used in run time
0169   //------------------------------------------------------------------------
0170 
0171 public:
0172 
0173   // access to dispersion of restricted energy loss
0174   G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple,
0175                              const G4DynamicParticle* dp,
0176                              G4double length);
0177 
0178   // Access to cross section table
0179   G4double CrossSectionPerVolume(G4double kineticEnergy,
0180                                  const G4MaterialCutsCouple* couple);
0181   G4double CrossSectionPerVolume(G4double kineticEnergy,
0182                                  const G4MaterialCutsCouple* couple,
0183                                  G4double logKineticEnergy);
0184 
0185   // access to cross section
0186   G4double MeanFreePath(const G4Track& track);
0187 
0188   // access to step limit
0189   G4double ContinuousStepLimit(const G4Track& track,
0190                                G4double previousStepSize,
0191                                G4double currentMinimumStep,
0192                                G4double& currentSafety);
0193 
0194 protected:
0195 
0196   // implementation of the pure virtual method
0197   G4double GetMeanFreePath(const G4Track& track,
0198                            G4double previousStepSize,
0199                            G4ForceCondition* condition) override;
0200 
0201   // implementation of the pure virtual method
0202   G4double GetContinuousStepLimit(const G4Track& track,
0203                                   G4double previousStepSize,
0204                                   G4double currentMinimumStep,
0205                                   G4double& currentSafety) override;
0206 
0207   // creation of an empty vector for cross sections for derived processes
0208   G4PhysicsVector* LambdaPhysicsVector(const G4MaterialCutsCouple*, 
0209                                        G4double cut);
0210 
0211   inline std::size_t CurrentMaterialCutsCoupleIndex() const;
0212 
0213   //------------------------------------------------------------------------
0214   // Specific methods to set, access, modify models
0215   //------------------------------------------------------------------------
0216 
0217   // Select model in run time
0218   inline void SelectModel(G4double kinEnergy);
0219 
0220 public:
0221   // Select model by energy and couple index
0222   // Not for run time processing
0223   inline G4VEmModel* SelectModelForMaterial(G4double kinEnergy, 
0224                                             std::size_t& idxCouple) const;
0225 
0226   // Add EM model coupled with fluctuation model for region, smaller value 
0227   // of order defines which pair of models will be selected for a given 
0228   // energy interval  
0229   void AddEmModel(G4int, G4VEmModel*, 
0230                   G4VEmFluctuationModel* fluc = nullptr,
0231                   const G4Region* region = nullptr);
0232 
0233   // Assign a model to a process local list, to enable the list in run time 
0234   // the derived process should execute AddEmModel(..) for all such models
0235   void SetEmModel(G4VEmModel*, G4int index=0);
0236 
0237   // Access to models
0238   inline std::size_t NumberOfModels() const;
0239   
0240   // Return a model from the local list
0241   inline G4VEmModel* EmModel(std::size_t index=0) const;
0242   
0243   // Access to models from G4EmModelManager list
0244   inline G4VEmModel* GetModelByIndex(std::size_t idx = 0, G4bool ver = false) const;
0245 
0246   // Assign a fluctuation model to a process
0247   inline void SetFluctModel(G4VEmFluctuationModel*);
0248   
0249   // Return the assigned fluctuation model
0250   inline G4VEmFluctuationModel* FluctModel() const;
0251     
0252   //------------------------------------------------------------------------
0253   // Define and access particle type 
0254   //------------------------------------------------------------------------
0255 
0256 protected:
0257   inline void SetParticle(const G4ParticleDefinition* p);
0258   inline void SetSecondaryParticle(const G4ParticleDefinition* p);
0259 
0260 public:
0261   inline void SetBaseParticle(const G4ParticleDefinition* p);
0262   inline const G4ParticleDefinition* Particle() const;
0263   inline const G4ParticleDefinition* BaseParticle() const;
0264   inline const G4ParticleDefinition* SecondaryParticle() const;
0265 
0266   // hide  assignment operator
0267   G4VEnergyLossProcess(G4VEnergyLossProcess &) = delete;
0268   G4VEnergyLossProcess & operator=(const G4VEnergyLossProcess &right) = delete;
0269 
0270   //------------------------------------------------------------------------
0271   // Get/set parameters to configure the process at initialisation time
0272   //------------------------------------------------------------------------
0273 
0274   // Add subcut processor for the region
0275   void ActivateSubCutoff(const G4Region* region);
0276 
0277   // Activate biasing
0278   void SetCrossSectionBiasingFactor(G4double f, G4bool flag = true);
0279 
0280   void ActivateForcedInteraction(G4double length, 
0281                                  const G4String& region,
0282                                  G4bool flag = true);
0283 
0284   void ActivateSecondaryBiasing(const G4String& region, G4double factor,
0285                                 G4double energyLimit);
0286 
0287   inline void SetLossFluctuations(G4bool val);
0288 
0289   inline void SetSpline(G4bool val);
0290   inline void SetCrossSectionType(G4CrossSectionType val);
0291   inline G4CrossSectionType CrossSectionType() const;
0292 
0293   // Set/Get flag "isIonisation"
0294   void SetIonisation(G4bool val);
0295   inline G4bool IsIonisationProcess() const;
0296 
0297   // Redefine parameteters for stepping control
0298   void SetLinearLossLimit(G4double val);
0299   void SetStepFunction(G4double v1, G4double v2);
0300   void SetLowestEnergyLimit(G4double);
0301 
0302   inline G4int NumberOfSubCutoffRegions() const;
0303 
0304   //------------------------------------------------------------------------
0305   // Specific methods to path Physics Tables to the process
0306   //------------------------------------------------------------------------
0307 
0308   void SetDEDXTable(G4PhysicsTable* p, G4EmTableType tType);
0309   void SetCSDARangeTable(G4PhysicsTable* pRange);
0310   void SetRangeTableForLoss(G4PhysicsTable* p);
0311   void SetInverseRangeTable(G4PhysicsTable* p);
0312   void SetLambdaTable(G4PhysicsTable* p);
0313 
0314   void SetTwoPeaksXS(std::vector<G4TwoPeaksXS*>*);
0315   void SetEnergyOfCrossSectionMax(std::vector<G4double>*);
0316 
0317   //------------------------------------------------------------------------
0318   // Specific methods to define custom Physics Tables to the process
0319   //------------------------------------------------------------------------
0320 
0321   // Binning for dEdx, range, inverse range and lambda tables
0322   void SetDEDXBinning(G4int nbins);
0323 
0324   // Min kinetic energy for tables
0325   void SetMinKinEnergy(G4double e);
0326   inline G4double MinKinEnergy() const;
0327 
0328   // Max kinetic energy for tables
0329   void SetMaxKinEnergy(G4double e);
0330   inline G4double MaxKinEnergy() const;
0331 
0332   // Biasing parameters
0333   inline G4double CrossSectionBiasingFactor() const;
0334 
0335   // Return values for given G4MaterialCutsCouple
0336   inline G4double GetDEDX(G4double kineticEnergy, const G4MaterialCutsCouple*);
0337   inline G4double GetCSDADEDX(G4double kineticEnergy, 
0338                               const G4MaterialCutsCouple*);
0339   inline G4double GetDEDX(G4double kineticEnergy, const G4MaterialCutsCouple*,
0340                           G4double logKineticEnergy);
0341   inline G4double GetRange(G4double kineticEnergy, const G4MaterialCutsCouple*);
0342   inline G4double GetRange(G4double kineticEnergy, const G4MaterialCutsCouple*,
0343                            G4double logKineticEnergy);
0344   inline G4double GetCSDARange(G4double kineticEnergy, 
0345                                const G4MaterialCutsCouple*);
0346   inline G4double GetKineticEnergy(G4double range, 
0347                                    const G4MaterialCutsCouple*);
0348   inline G4double GetLambda(G4double kineticEnergy,const G4MaterialCutsCouple*);
0349   inline G4double GetLambda(G4double kineticEnergy,const G4MaterialCutsCouple*,
0350                             G4double logKineticEnergy);
0351 
0352   inline G4bool TablesAreBuilt() const;
0353 
0354   // Access to specific tables
0355   inline G4PhysicsTable* DEDXTable() const;
0356   inline G4PhysicsTable* DEDXunRestrictedTable() const;
0357   inline G4PhysicsTable* IonisationTable() const;
0358   inline G4PhysicsTable* CSDARangeTable() const;
0359   inline G4PhysicsTable* RangeTableForLoss() const;
0360   inline G4PhysicsTable* InverseRangeTable() const;
0361   inline G4PhysicsTable* LambdaTable() const;
0362   inline std::vector<G4TwoPeaksXS*>* TwoPeaksXS() const;
0363   inline std::vector<G4double>* EnergyOfCrossSectionMax() const;
0364 
0365   inline G4bool UseBaseMaterial() const;
0366 
0367   //------------------------------------------------------------------------
0368   // Run time method for simulation of ionisation
0369   //------------------------------------------------------------------------
0370 
0371   // access atom on which interaction happens
0372   const G4Element* GetCurrentElement() const;
0373 
0374   // Set scaling parameters for ions is needed to G4EmCalculator
0375   void SetDynamicMassCharge(G4double massratio, G4double charge2ratio);
0376 
0377 private:
0378 
0379   void FillSecondariesAlongStep(G4double weight);
0380 
0381   void PrintWarning(const G4String&, G4double val) const;
0382 
0383   // define material and indexes
0384   inline void DefineMaterial(const G4MaterialCutsCouple* couple);
0385 
0386   //------------------------------------------------------------------------
0387   // Compute values using scaling relation, mass and charge of based particle
0388   //------------------------------------------------------------------------
0389   inline G4double GetDEDXForScaledEnergy(G4double scaledKinE);
0390   inline G4double GetDEDXForScaledEnergy(G4double scaledKinE,
0391                                          G4double logScaledKinE);
0392   inline G4double GetIonisationForScaledEnergy(G4double scaledKinE);
0393   inline G4double GetScaledRangeForScaledEnergy(G4double scaledKinE);
0394   inline G4double GetScaledRangeForScaledEnergy(G4double scaledKinE,
0395                                                 G4double logScaledKinE);
0396 
0397   inline G4double GetLimitScaledRangeForScaledEnergy(G4double scaledKinE);
0398   inline G4double GetLimitScaledRangeForScaledEnergy(G4double scaledKinE,
0399                                                      G4double logScaledKinE);
0400 
0401   inline G4double ScaledKinEnergyForLoss(G4double range);
0402   inline G4double GetLambdaForScaledEnergy(G4double scaledKinE);
0403   inline G4double GetLambdaForScaledEnergy(G4double scaledKinE, 
0404                                            G4double logScaledKinE);
0405 
0406   inline G4double LogScaledEkin(const G4Track& aTrack);
0407   
0408   void ComputeLambdaForScaledEnergy(G4double scaledKinE,
0409                                     const G4Track& aTrack);
0410 
0411   G4bool IsRegionForCubcutProcessor(const G4Track& aTrack);
0412 
0413 protected:
0414 
0415   G4ParticleChangeForLoss     fParticleChange;
0416   const G4Material*           currentMaterial = nullptr;
0417   const G4MaterialCutsCouple* currentCouple = nullptr;
0418 
0419 private:
0420 
0421   G4LossTableManager*         lManager;
0422   G4EmModelManager*           modelManager;
0423   G4VEmModel*                 currentModel = nullptr;
0424   G4EmBiasingManager*         biasManager = nullptr;
0425   G4SafetyHelper*             safetyHelper;
0426   G4EmParameters*             theParameters;  
0427   G4VEmFluctuationModel*      fluctModel = nullptr;
0428   G4VAtomDeexcitation*        atomDeexcitation = nullptr;
0429   G4VSubCutProducer*          subcutProducer = nullptr;
0430 
0431   const G4ParticleDefinition* particle = nullptr;
0432   const G4ParticleDefinition* baseParticle = nullptr;
0433   const G4ParticleDefinition* secondaryParticle = nullptr;
0434   G4EmDataHandler* theData = nullptr;
0435 
0436   G4PhysicsTable* theDEDXTable = nullptr;
0437   G4PhysicsTable* theDEDXunRestrictedTable = nullptr;
0438   G4PhysicsTable* theIonisationTable = nullptr;
0439   G4PhysicsTable* theRangeTableForLoss = nullptr;
0440   G4PhysicsTable* theCSDARangeTable = nullptr;
0441   G4PhysicsTable* theInverseRangeTable = nullptr;
0442   G4PhysicsTable* theLambdaTable = nullptr;
0443 
0444   std::vector<const G4Region*>* scoffRegions = nullptr;
0445   std::vector<G4VEmModel*>*     emModels = nullptr;
0446   const std::vector<G4int>*     theDensityIdx = nullptr;
0447   const std::vector<G4double>*  theDensityFactor = nullptr;
0448   const G4DataVector*           theCuts = nullptr;
0449 
0450   std::vector<G4double>* theEnergyOfCrossSectionMax = nullptr;
0451   std::vector<G4TwoPeaksXS*>* fXSpeaks = nullptr;
0452 
0453   G4double lowestKinEnergy;
0454   G4double minKinEnergy;
0455   G4double maxKinEnergy;
0456   G4double maxKinEnergyCSDA;
0457 
0458   G4double linLossLimit = 0.01;
0459   G4double dRoverRange = 0.2;
0460   G4double finalRange;
0461   G4double lambdaFactor = 0.8;
0462   G4double invLambdaFactor;
0463   G4double biasFactor = 1.0;
0464 
0465   G4double massRatio = 1.0;
0466   G4double logMassRatio = 0.0;
0467   G4double fFactor = 1.0;
0468   G4double reduceFactor = 1.0;
0469   G4double chargeSqRatio = 1.0;
0470   G4double fRange = 0.0;
0471   G4double fRangeEnergy = 0.0;
0472 
0473 protected:
0474 
0475   G4double preStepLambda = 0.0;
0476   G4double preStepKinEnergy = 0.0;
0477   G4double preStepScaledEnergy = 0.0;
0478   G4double mfpKinEnergy = 0.0;
0479 
0480   std::size_t currentCoupleIndex = 0;
0481 
0482 private:
0483 
0484   G4int nBins;
0485   G4int nBinsCSDA;
0486   G4int numberOfModels = 0;
0487   G4int nSCoffRegions = 0;
0488   G4int secID = _DeltaElectron;
0489   G4int tripletID = _TripletElectron;
0490   G4int biasID = _DeltaEBelowCut;
0491   G4int mainSecondaries = 1;
0492 
0493   std::size_t basedCoupleIndex = 0;
0494   std::size_t coupleIdxRange = 0;
0495   std::size_t idxDEDX = 0;
0496   std::size_t idxDEDXunRestricted = 0;
0497   std::size_t idxIonisation = 0;
0498   std::size_t idxRange = 0;
0499   std::size_t idxCSDA = 0;
0500   std::size_t idxSecRange = 0;
0501   std::size_t idxInverseRange = 0;
0502   std::size_t idxLambda = 0;
0503 
0504   G4GPILSelection aGPILSelection;
0505   G4CrossSectionType fXSType = fEmOnePeak;
0506 
0507   G4bool lossFluctuationFlag = true;
0508   G4bool useCutAsFinalRange = false;
0509   G4bool tablesAreBuilt = false;
0510   G4bool spline = true;
0511   G4bool isIon = false;
0512   G4bool isIonisation = true;
0513   G4bool useDeexcitation = false;
0514   G4bool biasFlag = false;
0515   G4bool weightFlag = false;
0516   G4bool isMaster = true;
0517   G4bool baseMat = false;
0518   G4bool actLinLossLimit = false;
0519   G4bool actLossFluc = false;
0520   G4bool actBinning = false;
0521   G4bool actMinKinEnergy = false;
0522   G4bool actMaxKinEnergy = false;
0523 
0524   std::vector<G4DynamicParticle*> secParticles;
0525   std::vector<G4Track*> scTracks;
0526 };
0527 
0528 // ======== Run time inline methods ================
0529 
0530 inline std::size_t G4VEnergyLossProcess::CurrentMaterialCutsCoupleIndex() const 
0531 {
0532   return currentCoupleIndex;
0533 }
0534 
0535 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0536 
0537 inline void G4VEnergyLossProcess::SelectModel(G4double kinEnergy)
0538 {
0539   currentModel = modelManager->SelectModel(kinEnergy, currentCoupleIndex);
0540   currentModel->SetCurrentCouple(currentCouple);
0541 }
0542 
0543 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0544 
0545 inline G4VEmModel* G4VEnergyLossProcess::SelectModelForMaterial(
0546                    G4double kinEnergy, std::size_t& idx) const
0547 {
0548   return modelManager->SelectModel(kinEnergy, idx);
0549 }
0550 
0551 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0552 
0553 inline void 
0554 G4VEnergyLossProcess::DefineMaterial(const G4MaterialCutsCouple* couple)
0555 {
0556   if(couple != currentCouple) {
0557     currentCouple = couple;
0558     currentMaterial = couple->GetMaterial();
0559     basedCoupleIndex = currentCoupleIndex = couple->GetIndex();
0560     fFactor = chargeSqRatio*biasFactor;
0561     mfpKinEnergy = DBL_MAX;
0562     idxLambda = 0;
0563     if(baseMat) {
0564       basedCoupleIndex = (*theDensityIdx)[currentCoupleIndex];
0565       fFactor *= (*theDensityFactor)[currentCoupleIndex];
0566     }
0567     reduceFactor = 1.0/(fFactor*massRatio);
0568   }
0569 }
0570 
0571 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0572 
0573 inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e)
0574 {
0575   /*
0576   G4cout << "G4VEnergyLossProcess::GetDEDX: Idx= " 
0577            << basedCoupleIndex << " E(MeV)= " << e 
0578          << " Emin= " << minKinEnergy << "  Factor= " << fFactor 
0579          << "  " << theDEDXTable << G4endl; */
0580   G4double x = fFactor*(*theDEDXTable)[basedCoupleIndex]->Value(e, idxDEDX);
0581   if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
0582   return x;
0583 }
0584 
0585 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0586 
0587 inline
0588 G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e, G4double loge)
0589 {
0590   /*
0591   G4cout << "G4VEnergyLossProcess::GetDEDX: Idx= " 
0592            << basedCoupleIndex << " E(MeV)= " << e 
0593          << " Emin= " << minKinEnergy << "  Factor= " << fFactor 
0594          << "  " << theDEDXTable << G4endl; */
0595   G4double x = fFactor*(*theDEDXTable)[basedCoupleIndex]->LogVectorValue(e,loge);
0596   if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
0597   return x;
0598 }
0599 
0600 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0601 
0602 inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(G4double e)
0603 {
0604   G4double x = 
0605     fFactor*(*theIonisationTable)[basedCoupleIndex]->Value(e, idxIonisation);
0606   if(e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
0607   return x;
0608 }
0609 
0610 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0611 
0612 inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e)
0613 {
0614   //G4cout << "G4VEnergyLossProcess::GetScaledRange: Idx= " 
0615   //         << basedCoupleIndex << " E(MeV)= " << e 
0616   //         << " lastIdx= " << lastIdx << "  " << theRangeTableForLoss << G4endl; 
0617   if(currentCoupleIndex != coupleIdxRange || fRangeEnergy != e) {
0618     coupleIdxRange = currentCoupleIndex;
0619     fRangeEnergy = e;
0620     fRange = reduceFactor*((*theRangeTableForLoss)[basedCoupleIndex])->Value(e, idxRange);
0621     if (fRange < 0.0) { fRange = 0.0; }
0622     else if (e < minKinEnergy) { fRange *= std::sqrt(e/minKinEnergy); }
0623   }
0624   //G4cout << "G4VEnergyLossProcess::GetScaledRange: Idx= " 
0625   //         << basedCoupleIndex << " E(MeV)= " << e 
0626   //         << " R=  " << computedRange << "  " << theRangeTableForLoss << G4endl;
0627   return fRange;
0628 }
0629 
0630 inline G4double
0631 G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e, G4double loge)
0632 {
0633   //G4cout << "G4VEnergyLossProcess::GetScaledRange: Idx= " 
0634   //         << basedCoupleIndex << " E(MeV)= " << e 
0635   //         << " lastIdx= " << lastIdx << "  " << theRangeTableForLoss << G4endl; 
0636   if(currentCoupleIndex != coupleIdxRange || fRangeEnergy != e) {
0637     coupleIdxRange = currentCoupleIndex;
0638     fRangeEnergy = e;
0639     fRange = reduceFactor*((*theRangeTableForLoss)[basedCoupleIndex])->LogVectorValue(e, loge);
0640     if (fRange < 0.0) { fRange = 0.0; }
0641     else if (e < minKinEnergy) { fRange *= std::sqrt(e/minKinEnergy); }
0642   }
0643   //G4cout << "G4VEnergyLossProcess::GetScaledRange: Idx= " 
0644   //         << basedCoupleIndex << " E(MeV)= " << e 
0645   //         << " R=  " << fRange << "  " << theRangeTableForLoss << G4endl;
0646   return fRange;
0647 }
0648 
0649 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0650 
0651 inline G4double 
0652 G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(G4double e)
0653 {
0654   G4double x = ((*theCSDARangeTable)[basedCoupleIndex])->Value(e, idxCSDA);
0655   if (x < 0.0) { x = 0.0; }
0656   else if (e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
0657   return x;
0658 }
0659 
0660 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0661 
0662 inline G4double 
0663 G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy(G4double e,
0664                                                          G4double loge)
0665 {
0666   G4double x = ((*theCSDARangeTable)[basedCoupleIndex])->LogVectorValue(e, loge);
0667   if (x < 0.0) { x = 0.0; }
0668   else if (e < minKinEnergy) { x *= std::sqrt(e/minKinEnergy); }
0669   return x;
0670 }
0671 
0672 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0673 
0674 inline G4double G4VEnergyLossProcess::ScaledKinEnergyForLoss(G4double r)
0675 {
0676   //G4cout << "G4VEnergyLossProcess::GetEnergy: Idx= " 
0677   //         << basedCoupleIndex << " R(mm)= " << r << "  " 
0678   //         << theInverseRangeTable << G4endl; 
0679   G4PhysicsVector* v = (*theInverseRangeTable)[basedCoupleIndex];
0680   G4double rmin = v->Energy(0);
0681   G4double e = 0.0; 
0682   if(r >= rmin) { e = v->Value(r, idxInverseRange); }
0683   else if(r > 0.0) {
0684     G4double x = r/rmin;
0685     e = minKinEnergy*x*x;
0686   }
0687   return e;
0688 }
0689 
0690 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0691 
0692 inline G4double G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e)
0693 {
0694   return fFactor*((*theLambdaTable)[basedCoupleIndex])->Value(e, idxLambda);
0695 }
0696 
0697 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0698 
0699 inline G4double
0700 G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e, G4double loge)
0701 {
0702   return fFactor*((*theLambdaTable)[basedCoupleIndex])->LogVectorValue(e, loge);
0703 }
0704 
0705 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0706 
0707 inline G4double G4VEnergyLossProcess::LogScaledEkin(const G4Track& track)
0708 {
0709   return track.GetDynamicParticle()->GetLogKineticEnergy() + logMassRatio;
0710 }
0711 
0712 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0713 
0714 inline G4double 
0715 G4VEnergyLossProcess::GetDEDX(G4double kinEnergy,
0716                               const G4MaterialCutsCouple* couple)
0717 {
0718   DefineMaterial(couple);
0719   return GetDEDXForScaledEnergy(kinEnergy*massRatio);
0720 }
0721 
0722 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0723 
0724 inline G4double 
0725 G4VEnergyLossProcess::GetDEDX(G4double kinEnergy,
0726                               const G4MaterialCutsCouple* couple,
0727                               G4double logKinEnergy)
0728 {
0729   DefineMaterial(couple);
0730   return GetDEDXForScaledEnergy(kinEnergy*massRatio, logKinEnergy+logMassRatio);
0731 }
0732 
0733 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0734 
0735 inline G4double 
0736 G4VEnergyLossProcess::GetRange(G4double kinEnergy,
0737                                const G4MaterialCutsCouple* couple)
0738 {
0739   DefineMaterial(couple);
0740   return GetScaledRangeForScaledEnergy(kinEnergy*massRatio);
0741 }
0742 
0743 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0744 
0745 inline G4double 
0746 G4VEnergyLossProcess::GetRange(G4double kinEnergy,
0747                                const G4MaterialCutsCouple* couple,
0748                                G4double logKinEnergy)
0749 {
0750   DefineMaterial(couple);
0751   return GetScaledRangeForScaledEnergy(kinEnergy*massRatio, logKinEnergy+logMassRatio);
0752 }
0753 
0754 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0755 
0756 inline G4double 
0757 G4VEnergyLossProcess::GetCSDARange(G4double kineticEnergy, 
0758                                    const G4MaterialCutsCouple* couple)
0759 {
0760   DefineMaterial(couple);
0761   return (nullptr == theCSDARangeTable) ? DBL_MAX : 
0762     GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor;
0763 }
0764 
0765 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0766 
0767 inline G4double 
0768 G4VEnergyLossProcess::GetKineticEnergy(G4double range,
0769                                        const G4MaterialCutsCouple* couple)
0770 {
0771   DefineMaterial(couple);
0772   return ScaledKinEnergyForLoss(range/reduceFactor)/massRatio;
0773 }
0774 
0775 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0776 
0777 inline G4double 
0778 G4VEnergyLossProcess::GetLambda(G4double kinEnergy,
0779                                 const G4MaterialCutsCouple* couple)
0780 {
0781   DefineMaterial(couple);
0782   return (nullptr != theLambdaTable) ? 
0783     GetLambdaForScaledEnergy(kinEnergy*massRatio) : 0.0;
0784 }
0785 
0786 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0787 
0788 inline G4double 
0789 G4VEnergyLossProcess::GetLambda(G4double kinEnergy,
0790                                 const G4MaterialCutsCouple* couple,
0791                                 G4double logKinEnergy)
0792 {
0793   DefineMaterial(couple);
0794   return (nullptr != theLambdaTable) ?
0795     GetLambdaForScaledEnergy(kinEnergy*massRatio, logKinEnergy+logMassRatio) 
0796     :  0.0;
0797 }
0798 
0799 // ======== Get/Set inline methods used at initialisation ================
0800 
0801 inline void G4VEnergyLossProcess::SetFluctModel(G4VEmFluctuationModel* p)
0802 {
0803   fluctModel = p;
0804 }
0805 
0806 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0807 
0808 inline G4VEmFluctuationModel* G4VEnergyLossProcess::FluctModel() const
0809 {
0810   return fluctModel;
0811 }
0812 
0813 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0814 
0815 inline void G4VEnergyLossProcess::SetParticle(const G4ParticleDefinition* p)
0816 {
0817   particle = p;
0818 }
0819 
0820 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0821 
0822 inline void 
0823 G4VEnergyLossProcess::SetSecondaryParticle(const G4ParticleDefinition* p)
0824 {
0825   secondaryParticle = p;
0826 }
0827 
0828 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0829 
0830 inline void 
0831 G4VEnergyLossProcess::SetBaseParticle(const G4ParticleDefinition* p)
0832 {
0833   baseParticle = p;
0834 }
0835 
0836 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0837 
0838 inline const G4ParticleDefinition* G4VEnergyLossProcess::Particle() const
0839 {
0840   return particle;
0841 }
0842 
0843 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0844 
0845 inline const G4ParticleDefinition* G4VEnergyLossProcess::BaseParticle() const
0846 {
0847   return baseParticle;
0848 }
0849 
0850 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0851 
0852 inline const G4ParticleDefinition* 
0853 G4VEnergyLossProcess::SecondaryParticle() const
0854 {
0855   return secondaryParticle;
0856 }
0857 
0858 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0859 
0860 inline void G4VEnergyLossProcess::SetLossFluctuations(G4bool val)
0861 {
0862   lossFluctuationFlag = val;
0863   actLossFluc = true;
0864 }
0865 
0866 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0867 
0868 inline void G4VEnergyLossProcess::SetSpline(G4bool val)
0869 {
0870   spline = val;
0871 }
0872 
0873 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0874 
0875 inline void G4VEnergyLossProcess::SetCrossSectionType(G4CrossSectionType val)
0876 {
0877   fXSType = val;
0878 }
0879 
0880 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0881   
0882 inline G4CrossSectionType G4VEnergyLossProcess::CrossSectionType() const 
0883 {
0884   return fXSType;
0885 }
0886 
0887 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0888 
0889 inline G4bool G4VEnergyLossProcess::IsIonisationProcess() const
0890 {
0891   return isIonisation;
0892 }
0893 
0894 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0895 
0896 inline G4int G4VEnergyLossProcess::NumberOfSubCutoffRegions() const
0897 {
0898   return nSCoffRegions;
0899 }
0900 
0901 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0902 
0903 inline G4double G4VEnergyLossProcess::MinKinEnergy() const
0904 {
0905   return minKinEnergy;
0906 }
0907 
0908 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0909 
0910 inline G4double G4VEnergyLossProcess::MaxKinEnergy() const
0911 {
0912   return maxKinEnergy;
0913 }
0914 
0915 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0916 
0917 inline G4double G4VEnergyLossProcess::CrossSectionBiasingFactor() const
0918 {
0919   return biasFactor;
0920 }
0921 
0922 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0923 
0924 inline G4bool G4VEnergyLossProcess::TablesAreBuilt() const
0925 {
0926   return tablesAreBuilt;
0927 }
0928 
0929 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0930 
0931 inline G4PhysicsTable* G4VEnergyLossProcess::DEDXTable() const
0932 {
0933   return theDEDXTable;
0934 }
0935 
0936 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0937 
0938 inline G4PhysicsTable* G4VEnergyLossProcess::DEDXunRestrictedTable() const
0939 {
0940   return theDEDXunRestrictedTable;
0941 }
0942 
0943 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0944 
0945 inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTable() const
0946 {
0947   return theIonisationTable;
0948 }
0949 
0950 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0951 
0952 inline G4PhysicsTable* G4VEnergyLossProcess::CSDARangeTable() const
0953 {
0954   return theCSDARangeTable;
0955 }
0956 
0957 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0958 
0959 inline G4PhysicsTable* G4VEnergyLossProcess::RangeTableForLoss() const
0960 {
0961   return theRangeTableForLoss;
0962 }
0963 
0964 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0965 
0966 inline G4PhysicsTable* G4VEnergyLossProcess::InverseRangeTable() const
0967 {
0968   return theInverseRangeTable;
0969 }
0970 
0971 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0972 
0973 inline G4PhysicsTable* G4VEnergyLossProcess::LambdaTable() const
0974 {
0975   return theLambdaTable;
0976 }
0977 
0978 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0979 
0980 inline G4bool G4VEnergyLossProcess::UseBaseMaterial() const
0981 {
0982   return baseMat;
0983 }
0984 
0985 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0986 
0987 inline std::vector<G4double>* 
0988 G4VEnergyLossProcess::EnergyOfCrossSectionMax() const
0989 {
0990   return theEnergyOfCrossSectionMax;
0991 }
0992 
0993 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0994 
0995 inline std::vector<G4TwoPeaksXS*>* G4VEnergyLossProcess::TwoPeaksXS() const
0996 {
0997   return fXSpeaks;
0998 }
0999 
1000 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1001 
1002 inline std::size_t G4VEnergyLossProcess::NumberOfModels() const
1003 {
1004   return numberOfModels;
1005 }
1006 
1007 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1008 
1009 inline G4VEmModel* G4VEnergyLossProcess::EmModel(std::size_t index) const
1010 {
1011   return (index < emModels->size()) ? (*emModels)[index] : nullptr;
1012 }
1013 
1014 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1015 
1016 inline G4VEmModel* 
1017 G4VEnergyLossProcess::GetModelByIndex(std::size_t idx, G4bool ver) const
1018 {
1019   return modelManager->GetModel((G4int)idx, ver);
1020 }
1021 
1022 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1023 
1024 #endif