Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id: G4VEnergyLossProcess.hh,v 1.68 2007/06/12 11:29:09 vnivanch Exp $ >> 27 // GEANT4 tag $Name: 26 // 28 // 27 // ------------------------------------------- 29 // ------------------------------------------------------------------- 28 // 30 // 29 // GEANT4 Class header file 31 // GEANT4 Class header file 30 // 32 // 31 // 33 // 32 // File name: G4VEnergyLossProcess 34 // File name: G4VEnergyLossProcess 33 // 35 // 34 // Author: Vladimir Ivanchenko on base 36 // Author: Vladimir Ivanchenko on base of Laszlo Urban code 35 // 37 // 36 // Creation date: 03.01.2002 38 // Creation date: 03.01.2002 37 // 39 // 38 // Modifications: Vladimir Ivanchenko << 40 // Modifications: >> 41 // >> 42 // 26-12-02 Secondary production moved to derived classes (V.Ivanchenko) >> 43 // 20-01-03 Migrade to cut per region (V.Ivanchenko) >> 44 // 24-01-03 Make models region aware (V.Ivanchenko) >> 45 // 05-02-03 Fix compilation warnings (V.Ivanchenko) >> 46 // 13-02-03 SubCutoffProcessors defined for regions (V.Ivanchenko) >> 47 // 17-02-03 Fix problem of store/restore tables (V.Ivanchenko) >> 48 // 26-02-03 Region dependent step limit (V.Ivanchenko) >> 49 // 26-03-03 Add GetDEDXDispersion (V.Ivanchenko) >> 50 // 09-04-03 Fix problem of negative range limit for non integral (V.Ivanchenko) >> 51 // 13-05-03 Add calculation of precise range (V.Ivanchenko) >> 52 // 21-07-03 Add UpdateEmModel method (V.Ivanchenko) >> 53 // 12-11-03 G4EnergyLossSTD -> G4EnergyLossProcess (V.Ivanchenko) >> 54 // 14-01-04 Activate precise range calculation (V.Ivanchenko) >> 55 // 10-03-04 Fix problem of step limit calculation (V.Ivanchenko) >> 56 // 30-06-04 make destructor virtual (V.Ivanchenko) >> 57 // 05-07-04 fix problem of GenericIons seen at small cuts (V.Ivanchenko) >> 58 // 03-08-04 Add DEDX table to all processes for control on integral range(VI) >> 59 // 06-08-04 Clear up names of member functions (V.Ivanchenko) >> 60 // 27-08-04 Add NeedBuildTables method (V.Ivanchneko) >> 61 // 09-09-04 Bug fix for the integral mode with 2 peaks (V.Ivanchneko) >> 62 // 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivanchenko) >> 63 // 08-04-05 Major optimisation of internal interfaces (V.Ivanchenko) >> 64 // 11-04-05 Use MaxSecondaryEnergy from a model (V.Ivanchenko) >> 65 // 10-01-05 Remove SetStepLimits (V.Ivanchenko) >> 66 // 10-01-06 PreciseRange -> CSDARange (V.Ivantchenko) >> 67 // 13-01-06 Remove AddSubCutSecondaries and cleanup (V.Ivantchenko) >> 68 // 20-01-06 Introduce G4EmTableType and reducing number of methods (VI) >> 69 // 26-01-06 Add public method GetCSDARange (V.Ivanchenko) >> 70 // 22-03-06 Add SetDynamicMassCharge (V.Ivanchenko) >> 71 // 23-03-06 Use isIonisation flag (V.Ivanchenko) >> 72 // 13-05-06 Add method to access model by index (V.Ivanchenko) >> 73 // 14-01-07 add SetEmModel(index) and SetFluctModel() (mma) >> 74 // 15-01-07 Add separate ionisation tables and reorganise get/set methods for >> 75 // dedx tables (V.Ivanchenko) >> 76 // 13-03-07 use SafetyHelper instead of navigator (V.Ivanchenko) 39 // 77 // 40 // Class Description: 78 // Class Description: 41 // 79 // 42 // It is the unified energy loss process it ca 80 // It is the unified energy loss process it calculates the continuous 43 // energy loss for charged particles using a s 81 // energy loss for charged particles using a set of Energy Loss 44 // models valid for different energy regions. 82 // models valid for different energy regions. There are a possibility 45 // to create and access to dE/dx and range tab 83 // to create and access to dE/dx and range tables, or to calculate 46 // that information on fly. 84 // that information on fly. 47 85 48 // ------------------------------------------- 86 // ------------------------------------------------------------------- 49 // 87 // 50 88 51 #ifndef G4VEnergyLossProcess_h 89 #ifndef G4VEnergyLossProcess_h 52 #define G4VEnergyLossProcess_h 1 90 #define G4VEnergyLossProcess_h 1 53 91 54 #include "G4VContinuousDiscreteProcess.hh" 92 #include "G4VContinuousDiscreteProcess.hh" 55 #include "globals.hh" 93 #include "globals.hh" 56 #include "G4Material.hh" 94 #include "G4Material.hh" 57 #include "G4MaterialCutsCouple.hh" 95 #include "G4MaterialCutsCouple.hh" 58 #include "G4Track.hh" 96 #include "G4Track.hh" 59 #include "G4EmModelManager.hh" 97 #include "G4EmModelManager.hh" >> 98 #include "G4UnitsTable.hh" 60 #include "G4ParticleChangeForLoss.hh" 99 #include "G4ParticleChangeForLoss.hh" 61 #include "G4EmTableType.hh" 100 #include "G4EmTableType.hh" 62 #include "G4EmSecondaryParticleType.hh" << 63 #include "G4PhysicsTable.hh" 101 #include "G4PhysicsTable.hh" 64 #include "G4PhysicsVector.hh" 102 #include "G4PhysicsVector.hh" 65 103 66 class G4Step; 104 class G4Step; 67 class G4ParticleDefinition; 105 class G4ParticleDefinition; 68 class G4EmParameters; << 69 class G4VEmModel; 106 class G4VEmModel; 70 class G4VEmFluctuationModel; 107 class G4VEmFluctuationModel; 71 class G4DataVector; 108 class G4DataVector; 72 class G4Region; 109 class G4Region; 73 class G4SafetyHelper; 110 class G4SafetyHelper; 74 class G4VAtomDeexcitation; << 75 class G4VSubCutProducer; << 76 class G4EmBiasingManager; << 77 class G4LossTableManager; << 78 class G4EmDataHandler; << 79 111 80 //....oooOO0OOooo........oooOO0OOooo........oo 112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 81 113 82 class G4VEnergyLossProcess : public G4VContinu 114 class G4VEnergyLossProcess : public G4VContinuousDiscreteProcess 83 { 115 { 84 public: 116 public: 85 117 86 G4VEnergyLossProcess(const G4String& name = 118 G4VEnergyLossProcess(const G4String& name = "EnergyLoss", 87 G4ProcessType type = fE << 119 G4ProcessType type = fElectromagnetic); 88 120 89 ~G4VEnergyLossProcess() override; << 121 virtual ~G4VEnergyLossProcess(); 90 122 91 //------------------------------------------ 123 //------------------------------------------------------------------------ 92 // Virtual methods to be implemented in conc 124 // Virtual methods to be implemented in concrete processes 93 //------------------------------------------ 125 //------------------------------------------------------------------------ 94 126 95 protected: << 127 virtual G4bool IsApplicable(const G4ParticleDefinition& p) = 0; >> 128 >> 129 virtual void PrintInfo() = 0; 96 130 97 // description of specific process parameter << 131 protected: 98 virtual void StreamProcessInfo(std::ostream& << 99 132 100 virtual void InitialiseEnergyLossProcess(con 133 virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition*, 101 con 134 const G4ParticleDefinition*) = 0; 102 135 103 public: << 136 //------------------------------------------------------------------------ >> 137 // Methods with standard implementation; may be overwritten if needed >> 138 //------------------------------------------------------------------------ >> 139 protected: 104 140 105 // used as low energy limit LambdaTable << 141 inline virtual G4double MinPrimaryEnergy(const G4ParticleDefinition*, 106 virtual G4double MinPrimaryEnergy(const G4Pa << 107 const G4Ma 142 const G4Material*, G4double cut); 108 143 109 // print documentation in html format << 144 inline virtual void CorrectionsAlongStep( 110 void ProcessDescription(std::ostream& outFil << 145 const G4MaterialCutsCouple*, 111 << 146 const G4DynamicParticle*, 112 // prepare all tables << 147 G4double& eloss, 113 void PreparePhysicsTable(const G4ParticleDef << 148 G4double& length); 114 149 115 // build all tables << 150 //------------------------------------------------------------------------ 116 void BuildPhysicsTable(const G4ParticleDefin << 151 // Generic methods common to all ContinuousDiscrete processes 117 << 152 //------------------------------------------------------------------------ 118 // build a table << 153 public: 119 G4PhysicsTable* BuildDEDXTable(G4EmTableType << 120 154 121 // build a table << 155 void PrintInfoDefinition(); 122 G4PhysicsTable* BuildLambdaTable(G4EmTableTy << 123 156 124 // Called before tracking of each new G4Trac << 157 void PreparePhysicsTable(const G4ParticleDefinition&); 125 void StartTracking(G4Track*) override; << 126 158 127 // Step limit from AlongStep << 159 void BuildPhysicsTable(const G4ParticleDefinition&); 128 G4double AlongStepGetPhysicalInteractionLeng << 129 const G4Trac << 130 G4double pr << 131 G4double cu << 132 G4double& cu << 133 G4GPILSelect << 134 << 135 // Step limit from cross section << 136 G4double PostStepGetPhysicalInteractionLengt << 137 const G4Trac << 138 G4double pre << 139 G4ForceCondi << 140 160 141 // AlongStep computations << 161 G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&); 142 G4VParticleChange* AlongStepDoIt(const G4Tra << 143 162 144 // PostStep sampling of secondaries << 163 G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&); 145 G4VParticleChange* PostStepDoIt(const G4Trac << 146 164 147 // Store all PhysicsTable in files. << 165 // Store PhysicsTable in a file. 148 // Return false in case of any fatal failure << 166 // Return false in case of failure at I/O 149 G4bool StorePhysicsTable(const G4ParticleDef 167 G4bool StorePhysicsTable(const G4ParticleDefinition*, 150 const G4String& dir 168 const G4String& directory, 151 G4bool ascii = fals << 169 G4bool ascii = false); 152 170 153 // Retrieve all Physics from a files. << 171 // Retrieve Physics from a file. 154 // Return true if all the Physics Table are << 172 // (return true if the Physics Table can be build by using file) 155 // Return false if any fatal failure. << 173 // (return false if the process has no functionality or in case of failure) >> 174 // File name should is constructed as processName+particleName and the >> 175 // should be placed under the directory specifed by the argument. 156 G4bool RetrievePhysicsTable(const G4Particle 176 G4bool RetrievePhysicsTable(const G4ParticleDefinition*, 157 const G4String& 177 const G4String& directory, 158 G4bool ascii) ov << 178 G4bool ascii); 159 179 160 private: << 180 protected: 161 181 162 // summary printout after initialisation << 182 inline G4double GetMeanFreePath(const G4Track& track, 163 void StreamInfo(std::ostream& out, const G4P << 183 G4double previousStepSize, 164 G4bool rst=false) const; << 184 G4ForceCondition* condition); >> 185 >> 186 inline G4double GetContinuousStepLimit(const G4Track& track, >> 187 G4double previousStepSize, >> 188 G4double currentMinimumStep, >> 189 G4double& currentSafety); 165 190 166 //------------------------------------------ 191 //------------------------------------------------------------------------ 167 // Public interface to cross section, mfp an << 192 // Specific methods for along/post step simulation 168 // These methods are not used in run time << 169 //------------------------------------------ 193 //------------------------------------------------------------------------ 170 194 171 public: 195 public: 172 196 173 // access to dispersion of restricted energy << 197 void AddCollaborativeProcess(G4VEnergyLossProcess*); 174 G4double GetDEDXDispersion(const G4MaterialC << 175 const G4DynamicPa << 176 G4double length); << 177 198 178 // Access to cross section table << 199 void SampleSubCutSecondaries(std::vector<G4Track*>&, const G4Step&, 179 G4double CrossSectionPerVolume(G4double kine << 200 G4VEmModel* model, G4int matIdx, 180 const G4Mater << 201 G4double& extraEdep); 181 G4double CrossSectionPerVolume(G4double kine << 182 const G4Mater << 183 G4double logK << 184 << 185 // access to cross section << 186 G4double MeanFreePath(const G4Track& track); << 187 << 188 // access to step limit << 189 G4double ContinuousStepLimit(const G4Track& << 190 G4double previo << 191 G4double curren << 192 G4double& curre << 193 202 194 protected: << 203 G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple, >> 204 const G4DynamicParticle* dp, >> 205 G4double length); 195 206 196 // implementation of the pure virtual method << 197 G4double GetMeanFreePath(const G4Track& trac << 198 G4double previousSt << 199 G4ForceCondition* c << 200 << 201 // implementation of the pure virtual method << 202 G4double GetContinuousStepLimit(const G4Trac << 203 G4double pre << 204 G4double cur << 205 G4double& cu << 206 207 207 // creation of an empty vector for cross sec << 208 inline G4double AlongStepGetPhysicalInteractionLength( 208 G4PhysicsVector* LambdaPhysicsVector(const G << 209 const G4Track&, 209 G4doubl << 210 G4double previousStepSize, 210 << 211 G4double currentMinimumStep, 211 inline std::size_t CurrentMaterialCutsCouple << 212 G4double& currentSafety, >> 213 G4GPILSelection* selection >> 214 ); >> 215 >> 216 inline G4double PostStepGetPhysicalInteractionLength( >> 217 const G4Track& track, >> 218 G4double previousStepSize, >> 219 G4ForceCondition* condition >> 220 ); 212 221 213 //------------------------------------------ 222 //------------------------------------------------------------------------ 214 // Specific methods to set, access, modify m << 223 // Specific methods to build and access Physics Tables 215 //------------------------------------------ 224 //------------------------------------------------------------------------ 216 225 217 // Select model in run time << 226 G4double MicroscopicCrossSection(G4double kineticEnergy, 218 inline void SelectModel(G4double kinEnergy); << 227 const G4MaterialCutsCouple* couple); 219 228 220 public: << 229 G4PhysicsTable* BuildDEDXTable(G4EmTableType tType = fRestricted); 221 // Select model by energy and couple index << 222 // Not for run time processing << 223 inline G4VEmModel* SelectModelForMaterial(G4 << 224 st << 225 << 226 // Add EM model coupled with fluctuation mod << 227 // of order defines which pair of models wil << 228 // energy interval << 229 void AddEmModel(G4int, G4VEmModel*, << 230 G4VEmFluctuationModel* fluc << 231 const G4Region* region = nul << 232 << 233 // Assign a model to a process local list, t << 234 // the derived process should execute AddEmM << 235 void SetEmModel(G4VEmModel*, G4int index=0); << 236 230 237 // Access to models << 231 G4PhysicsTable* BuildLambdaTable(G4EmTableType tType = fRestricted); 238 inline std::size_t NumberOfModels() const; << 232 239 << 233 void SetDEDXTable(G4PhysicsTable* p, G4EmTableType tType); 240 // Return a model from the local list << 234 void SetCSDARangeTable(G4PhysicsTable* pRange); 241 inline G4VEmModel* EmModel(std::size_t index << 235 void SetRangeTableForLoss(G4PhysicsTable* p); 242 << 236 void SetInverseRangeTable(G4PhysicsTable* p); 243 // Access to models from G4EmModelManager li << 237 void SetSecondaryRangeTable(G4PhysicsTable* p); 244 inline G4VEmModel* GetModelByIndex(std::size << 238 >> 239 void SetLambdaTable(G4PhysicsTable* p); >> 240 void SetSubLambdaTable(G4PhysicsTable* p); >> 241 >> 242 // Binning for dEdx, range, inverse range and labda tables >> 243 inline void SetDEDXBinning(G4int nbins); >> 244 inline void SetLambdaBinning(G4int nbins); >> 245 >> 246 // Binning for dEdx, range, and inverse range tables >> 247 inline void SetDEDXBinningForCSDARange(G4int nbins); >> 248 >> 249 // Min kinetic energy for tables >> 250 inline void SetMinKinEnergy(G4double e); >> 251 inline G4double MinKinEnergy() const; >> 252 >> 253 // Max kinetic energy for tables >> 254 inline void SetMaxKinEnergy(G4double e); >> 255 inline G4double MaxKinEnergy() const; >> 256 >> 257 // Max kinetic energy for tables >> 258 inline void SetMaxKinEnergyForCSDARange(G4double e); >> 259 >> 260 // Access to specific tables >> 261 inline G4PhysicsTable* DEDXTable() const; >> 262 inline G4PhysicsTable* DEDXTableForSubsec() const; >> 263 inline G4PhysicsTable* DEDXunRestrictedTable() const; >> 264 inline G4PhysicsTable* IonisationTable() const; >> 265 inline G4PhysicsTable* IonisationTableForSubsec() const; >> 266 inline G4PhysicsTable* CSDARangeTable() const; >> 267 inline G4PhysicsTable* RangeTableForLoss() const; >> 268 inline G4PhysicsTable* InverseRangeTable() const; >> 269 inline G4PhysicsTable* LambdaTable(); >> 270 inline G4PhysicsTable* SubLambdaTable(); >> 271 >> 272 // Return values for given G4MaterialCutsCouple >> 273 inline G4double GetDEDX(G4double& kineticEnergy, const G4MaterialCutsCouple*); >> 274 inline G4double GetDEDXForSubsec(G4double& kineticEnergy, >> 275 const G4MaterialCutsCouple*); >> 276 inline G4double GetRange(G4double& kineticEnergy, const G4MaterialCutsCouple*); >> 277 inline G4double GetCSDARange(G4double& kineticEnergy, const G4MaterialCutsCouple*); >> 278 inline G4double GetRangeForLoss(G4double& kineticEnergy, const G4MaterialCutsCouple*); >> 279 inline G4double GetKineticEnergy(G4double& range, const G4MaterialCutsCouple*); >> 280 inline G4double GetLambda(G4double& kineticEnergy, const G4MaterialCutsCouple*); >> 281 >> 282 inline G4bool TablesAreBuilt() const; 245 283 246 // Assign a fluctuation model to a process << 247 inline void SetFluctModel(G4VEmFluctuationMo << 248 << 249 // Return the assigned fluctuation model << 250 inline G4VEmFluctuationModel* FluctModel() c << 251 << 252 //------------------------------------------ 284 //------------------------------------------------------------------------ 253 // Define and access particle type 285 // Define and access particle type 254 //------------------------------------------ 286 //------------------------------------------------------------------------ 255 287 256 protected: << 257 inline void SetParticle(const G4ParticleDefi << 258 inline void SetSecondaryParticle(const G4Par << 259 << 260 public: << 261 inline void SetBaseParticle(const G4Particle 288 inline void SetBaseParticle(const G4ParticleDefinition* p); 262 inline const G4ParticleDefinition* Particle( 289 inline const G4ParticleDefinition* Particle() const; 263 inline const G4ParticleDefinition* BaseParti 290 inline const G4ParticleDefinition* BaseParticle() const; 264 inline const G4ParticleDefinition* Secondary 291 inline const G4ParticleDefinition* SecondaryParticle() const; 265 292 266 // hide assignment operator << 267 G4VEnergyLossProcess(G4VEnergyLossProcess &) << 268 G4VEnergyLossProcess & operator=(const G4VEn << 269 << 270 //------------------------------------------ 293 //------------------------------------------------------------------------ 271 // Get/set parameters to configure the proce << 294 // Specific methods to set, access, modify models 272 //------------------------------------------ 295 //------------------------------------------------------------------------ 273 296 274 // Add subcut processor for the region << 297 // Add EM model coupled with fluctuation model for the region 275 void ActivateSubCutoff(const G4Region* regio << 298 inline void AddEmModel(G4int, G4VEmModel*, G4VEmFluctuationModel* fluc = 0, >> 299 const G4Region* region = 0); >> 300 >> 301 // Assign a model to a process >> 302 inline void SetEmModel(G4VEmModel*, G4int index=1); >> 303 >> 304 // return the assigned model >> 305 inline G4VEmModel* EmModel(G4int index=1); >> 306 >> 307 // Assign a fluctuation model to a process >> 308 inline void SetFluctModel(G4VEmFluctuationModel*); >> 309 >> 310 // return the assigned fluctuation model >> 311 inline G4VEmFluctuationModel* FluctModel(); >> 312 >> 313 // Define new energy range for the model identified by the name >> 314 inline void UpdateEmModel(const G4String&, G4double, G4double); 276 315 277 // Activate biasing << 316 // Access to models 278 void SetCrossSectionBiasingFactor(G4double f << 317 inline G4VEmModel* GetModelByIndex(G4int idx = 0); 279 318 280 void ActivateForcedInteraction(G4double leng << 319 inline G4int NumberOfModels(); 281 const G4Strin << 282 G4bool flag = << 283 320 284 void ActivateSecondaryBiasing(const G4String << 321 //------------------------------------------------------------------------ 285 G4double energ << 322 // Get/set parameters used for simulation of energy loss >> 323 //------------------------------------------------------------------------ 286 324 287 inline void SetLossFluctuations(G4bool val); 325 inline void SetLossFluctuations(G4bool val); 288 << 326 inline void SetRandomStep(G4bool val); 289 inline void SetSpline(G4bool val); << 327 inline void SetIntegral(G4bool val); 290 inline void SetCrossSectionType(G4CrossSecti << 328 inline G4bool IsIntegral() const; 291 inline G4CrossSectionType CrossSectionType() << 292 329 293 // Set/Get flag "isIonisation" 330 // Set/Get flag "isIonisation" 294 void SetIonisation(G4bool val); << 331 inline void SetIonisation(G4bool val); 295 inline G4bool IsIonisationProcess() const; 332 inline G4bool IsIonisationProcess() const; 296 333 297 // Redefine parameteters for stepping contro 334 // Redefine parameteters for stepping control 298 void SetLinearLossLimit(G4double val); << 335 // 299 void SetStepFunction(G4double v1, G4double v << 336 inline void SetLinearLossLimit(G4double val); 300 void SetLowestEnergyLimit(G4double); << 337 inline void SetMinSubRange(G4double val); >> 338 inline void SetStepFunction(G4double v1, G4double v2); >> 339 inline void SetLambdaFactor(G4double val); >> 340 >> 341 >> 342 // Add subcutoff option for the region >> 343 void ActivateSubCutoff(G4bool val, const G4Region* region = 0); 301 344 302 inline G4int NumberOfSubCutoffRegions() cons 345 inline G4int NumberOfSubCutoffRegions() const; 303 346 >> 347 // Activate deexcitation code >> 348 virtual void ActivateDeexcitation(G4bool, const G4Region* region = 0); >> 349 304 //------------------------------------------ 350 //------------------------------------------------------------------------ 305 // Specific methods to path Physics Tables t << 351 // Run time method for simulation of ionisation 306 //------------------------------------------ 352 //------------------------------------------------------------------------ 307 353 308 void SetDEDXTable(G4PhysicsTable* p, G4EmTab << 354 inline G4double SampleRange(); 309 void SetCSDARangeTable(G4PhysicsTable* pRang << 310 void SetRangeTableForLoss(G4PhysicsTable* p) << 311 void SetInverseRangeTable(G4PhysicsTable* p) << 312 void SetLambdaTable(G4PhysicsTable* p); << 313 355 314 void SetTwoPeaksXS(std::vector<G4TwoPeaksXS* << 356 inline G4VEmModel* SelectModelForMaterial(G4double kinEnergy, size_t& idx) const; 315 void SetEnergyOfCrossSectionMax(std::vector< << 316 357 317 //------------------------------------------ << 318 // Specific methods to define custom Physics << 319 //------------------------------------------ << 320 358 321 // Binning for dEdx, range, inverse range an << 359 // Set scaling parameters 322 void SetDEDXBinning(G4int nbins); << 360 inline void SetDynamicMassCharge(G4double massratio, G4double charge2ratio); 323 361 324 // Min kinetic energy for tables << 362 // Helper functions 325 void SetMinKinEnergy(G4double e); << 363 inline G4double MeanFreePath(const G4Track& track); 326 inline G4double MinKinEnergy() const; << 327 364 328 // Max kinetic energy for tables << 365 inline G4double ContinuousStepLimit(const G4Track& track, 329 void SetMaxKinEnergy(G4double e); << 366 G4double previousStepSize, 330 inline G4double MaxKinEnergy() const; << 367 G4double currentMinimumStep, >> 368 G4double& currentSafety); 331 369 332 // Biasing parameters << 370 protected: 333 inline G4double CrossSectionBiasingFactor() << 334 371 335 // Return values for given G4MaterialCutsCou << 372 G4PhysicsVector* LambdaPhysicsVector(const G4MaterialCutsCouple*, 336 inline G4double GetDEDX(G4double kineticEner << 373 G4double cut); 337 inline G4double GetCSDADEDX(G4double kinetic << 338 const G4Material << 339 inline G4double GetDEDX(G4double kineticEner << 340 G4double logKineticE << 341 inline G4double GetRange(G4double kineticEne << 342 inline G4double GetRange(G4double kineticEne << 343 G4double logKinetic << 344 inline G4double GetCSDARange(G4double kineti << 345 const G4Materia << 346 inline G4double GetKineticEnergy(G4double ra << 347 const G4Mat << 348 inline G4double GetLambda(G4double kineticEn << 349 inline G4double GetLambda(G4double kineticEn << 350 G4double logKineti << 351 374 352 inline G4bool TablesAreBuilt() const; << 375 inline virtual void InitialiseMassCharge(const G4Track&); 353 376 354 // Access to specific tables << 377 inline void SetParticle(const G4ParticleDefinition* p); 355 inline G4PhysicsTable* DEDXTable() const; << 356 inline G4PhysicsTable* DEDXunRestrictedTable << 357 inline G4PhysicsTable* IonisationTable() con << 358 inline G4PhysicsTable* CSDARangeTable() cons << 359 inline G4PhysicsTable* RangeTableForLoss() c << 360 inline G4PhysicsTable* InverseRangeTable() c << 361 inline G4PhysicsTable* LambdaTable() const; << 362 inline std::vector<G4TwoPeaksXS*>* TwoPeaksX << 363 inline std::vector<G4double>* EnergyOfCrossS << 364 378 365 inline G4bool UseBaseMaterial() const; << 379 inline void SetSecondaryParticle(const G4ParticleDefinition* p); 366 380 367 //------------------------------------------ << 381 inline G4VEmModel* SelectModel(G4double kinEnergy); 368 // Run time method for simulation of ionisat << 369 //------------------------------------------ << 370 382 371 // access atom on which interaction happens << 383 inline size_t CurrentMaterialCutsCoupleIndex() const; 372 const G4Element* GetCurrentElement() const; << 373 384 374 // Set scaling parameters for ions is needed << 385 inline G4double GetCurrentRange() const; 375 void SetDynamicMassCharge(G4double massratio << 376 386 377 private: 387 private: 378 388 379 void FillSecondariesAlongStep(G4double weigh << 389 // Clear tables >> 390 void Clear(); 380 391 381 void PrintWarning(const G4String&, G4double << 392 inline void InitialiseStep(const G4Track&); 382 393 383 // define material and indexes << 384 inline void DefineMaterial(const G4MaterialC 394 inline void DefineMaterial(const G4MaterialCutsCouple* couple); 385 395 386 //------------------------------------------ << 396 // Returnd values for scaled energy and base particles mass 387 // Compute values using scaling relation, ma << 397 // 388 //------------------------------------------ << 398 inline G4double GetDEDXForScaledEnergy(G4double scaledKinEnergy); 389 inline G4double GetDEDXForScaledEnergy(G4dou << 399 inline G4double GetSubDEDXForScaledEnergy(G4double scaledKinEnergy); 390 inline G4double GetDEDXForScaledEnergy(G4dou << 400 inline G4double GetIonisationForScaledEnergy(G4double scaledKinEnergy); 391 G4dou << 401 inline G4double GetSubIonisationForScaledEnergy(G4double scaledKinEnergy); 392 inline G4double GetIonisationForScaledEnergy << 402 inline G4double GetScaledRangeForScaledEnergy(G4double scaledKinEnergy); 393 inline G4double GetScaledRangeForScaledEnerg << 403 inline G4double GetLimitScaledRangeForScaledEnergy(G4double scaledKinEnergy); 394 inline G4double GetScaledRangeForScaledEnerg << 404 inline G4double GetLambdaForScaledEnergy(G4double scaledKinEnergy); 395 << 396 << 397 inline G4double GetLimitScaledRangeForScaled << 398 inline G4double GetLimitScaledRangeForScaled << 399 << 400 << 401 inline G4double ScaledKinEnergyForLoss(G4dou 405 inline G4double ScaledKinEnergyForLoss(G4double range); 402 inline G4double GetLambdaForScaledEnergy(G4d << 406 inline void ComputeLambdaForScaledEnergy(G4double scaledKinEnergy); 403 inline G4double GetLambdaForScaledEnergy(G4d << 404 G4d << 405 407 406 inline G4double LogScaledEkin(const G4Track& << 408 // hide assignment operator 407 << 409 408 void ComputeLambdaForScaledEnergy(G4double s << 410 G4VEnergyLossProcess(G4VEnergyLossProcess &); 409 const G4Tr << 411 G4VEnergyLossProcess & operator=(const G4VEnergyLossProcess &right); 410 412 411 G4bool IsRegionForCubcutProcessor(const G4Tr << 413 // ===================================================================== 412 414 413 protected: 415 protected: 414 416 415 G4ParticleChangeForLoss fParticleChange; << 417 G4ParticleChangeForLoss fParticleChange; 416 const G4Material* currentMaterial << 417 const G4MaterialCutsCouple* currentCouple = << 418 418 419 private: 419 private: 420 420 421 G4LossTableManager* lManager; << 421 G4EmModelManager* modelManager; 422 G4EmModelManager* modelManager; << 422 G4VEmModel* emModel[5]; 423 G4VEmModel* currentModel = n << 423 G4VEmFluctuationModel* fluctModel; 424 G4EmBiasingManager* biasManager = nu << 424 std::vector<const G4Region*> scoffRegions; >> 425 G4int nSCoffRegions; >> 426 G4int* idxSCoffRegions; >> 427 std::vector<G4DynamicParticle*> secParticles; >> 428 std::vector<G4Track*> scTracks; >> 429 std::vector<G4VEnergyLossProcess*> scProcesses; >> 430 G4int nProcesses; >> 431 >> 432 // tables and vectors >> 433 G4PhysicsTable* theDEDXTable; >> 434 G4PhysicsTable* theDEDXSubTable; >> 435 G4PhysicsTable* theDEDXunRestrictedTable; >> 436 G4PhysicsTable* theIonisationTable; >> 437 G4PhysicsTable* theIonisationSubTable; >> 438 G4PhysicsTable* theRangeTableForLoss; >> 439 G4PhysicsTable* theCSDARangeTable; >> 440 G4PhysicsTable* theSecondaryRangeTable; >> 441 G4PhysicsTable* theInverseRangeTable; >> 442 G4PhysicsTable* theLambdaTable; >> 443 G4PhysicsTable* theSubLambdaTable; >> 444 G4double* theDEDXAtMaxEnergy; >> 445 G4double* theRangeAtMaxEnergy; >> 446 G4double* theEnergyOfCrossSectionMax; >> 447 G4double* theCrossSectionMax; >> 448 >> 449 const G4DataVector* theCuts; >> 450 const G4DataVector* theSubCuts; >> 451 425 G4SafetyHelper* safetyHelper; 452 G4SafetyHelper* safetyHelper; 426 G4EmParameters* theParameters; << 427 G4VEmFluctuationModel* fluctModel = nul << 428 G4VAtomDeexcitation* atomDeexcitation << 429 G4VSubCutProducer* subcutProducer = << 430 << 431 const G4ParticleDefinition* particle = nullp << 432 const G4ParticleDefinition* baseParticle = n << 433 const G4ParticleDefinition* secondaryParticl << 434 G4EmDataHandler* theData = nullptr; << 435 << 436 G4PhysicsTable* theDEDXTable = nullptr; << 437 G4PhysicsTable* theDEDXunRestrictedTable = n << 438 G4PhysicsTable* theIonisationTable = nullptr << 439 G4PhysicsTable* theRangeTableForLoss = nullp << 440 G4PhysicsTable* theCSDARangeTable = nullptr; << 441 G4PhysicsTable* theInverseRangeTable = nullp << 442 G4PhysicsTable* theLambdaTable = nullptr; << 443 << 444 std::vector<const G4Region*>* scoffRegions = << 445 std::vector<G4VEmModel*>* emModels = nul << 446 const std::vector<G4int>* theDensityIdx << 447 const std::vector<G4double>* theDensityFact << 448 const G4DataVector* theCuts = null << 449 453 450 std::vector<G4double>* theEnergyOfCrossSecti << 454 const G4ParticleDefinition* particle; 451 std::vector<G4TwoPeaksXS*>* fXSpeaks = nullp << 455 const G4ParticleDefinition* baseParticle; >> 456 const G4ParticleDefinition* secondaryParticle; >> 457 const G4ParticleDefinition* theElectron; >> 458 const G4ParticleDefinition* thePositron; >> 459 >> 460 G4PhysicsVector* vstrag; >> 461 >> 462 // cash >> 463 const G4Material* currentMaterial; >> 464 const G4MaterialCutsCouple* currentCouple; >> 465 size_t currentMaterialIndex; >> 466 >> 467 G4int nBins; >> 468 G4int nBinsCSDA; >> 469 G4int nWarnings; 452 470 453 G4double lowestKinEnergy; 471 G4double lowestKinEnergy; 454 G4double minKinEnergy; 472 G4double minKinEnergy; 455 G4double maxKinEnergy; 473 G4double maxKinEnergy; 456 G4double maxKinEnergyCSDA; 474 G4double maxKinEnergyCSDA; 457 475 458 G4double linLossLimit = 0.01; << 476 G4double massRatio; 459 G4double dRoverRange = 0.2; << 477 G4double reduceFactor; >> 478 G4double chargeSquare; >> 479 G4double chargeSqRatio; >> 480 >> 481 G4double preStepLambda; >> 482 G4double fRange; >> 483 G4double preStepKinEnergy; >> 484 G4double preStepScaledEnergy; >> 485 G4double linLossLimit; >> 486 G4double minSubRange; >> 487 G4double dRoverRange; 460 G4double finalRange; 488 G4double finalRange; 461 G4double lambdaFactor = 0.8; << 489 G4double lambdaFactor; 462 G4double invLambdaFactor; << 490 G4double mfpKinEnergy; 463 G4double biasFactor = 1.0; << 464 << 465 G4double massRatio = 1.0; << 466 G4double logMassRatio = 0.0; << 467 G4double fFactor = 1.0; << 468 G4double reduceFactor = 1.0; << 469 G4double chargeSqRatio = 1.0; << 470 G4double fRange = 0.0; << 471 G4double fRangeEnergy = 0.0; << 472 << 473 protected: << 474 << 475 G4double preStepLambda = 0.0; << 476 G4double preStepKinEnergy = 0.0; << 477 G4double preStepScaledEnergy = 0.0; << 478 G4double mfpKinEnergy = 0.0; << 479 << 480 std::size_t currentCoupleIndex = 0; << 481 491 482 private: << 492 G4GPILSelection aGPILSelection; 483 << 484 G4int nBins; << 485 G4int nBinsCSDA; << 486 G4int numberOfModels = 0; << 487 G4int nSCoffRegions = 0; << 488 G4int secID = _DeltaElectron; << 489 G4int tripletID = _TripletElectron; << 490 G4int biasID = _DeltaEBelowCut; << 491 G4int epixeID = _ePIXE; << 492 G4int gpixeID = _GammaPIXE; << 493 G4int mainSecondaries = 1; << 494 << 495 std::size_t basedCoupleIndex = 0; << 496 std::size_t coupleIdxRange = 0; << 497 std::size_t idxDEDX = 0; << 498 std::size_t idxDEDXunRestricted = 0; << 499 std::size_t idxIonisation = 0; << 500 std::size_t idxRange = 0; << 501 std::size_t idxCSDA = 0; << 502 std::size_t idxSecRange = 0; << 503 std::size_t idxInverseRange = 0; << 504 std::size_t idxLambda = 0; << 505 << 506 G4GPILSelection aGPILSelection; << 507 G4CrossSectionType fXSType = fEmOnePeak; << 508 << 509 G4bool lossFluctuationFlag = true; << 510 G4bool useCutAsFinalRange = false; << 511 G4bool tablesAreBuilt = false; << 512 G4bool spline = true; << 513 G4bool isIon = false; << 514 G4bool isIonisation = false; << 515 G4bool useDeexcitation = false; << 516 G4bool biasFlag = false; << 517 G4bool weightFlag = false; << 518 G4bool isMaster = false; << 519 G4bool baseMat = false; << 520 G4bool actLinLossLimit = false; << 521 G4bool actLossFluc = false; << 522 G4bool actBinning = false; << 523 G4bool actMinKinEnergy = false; << 524 G4bool actMaxKinEnergy = false; << 525 493 526 std::vector<G4DynamicParticle*> secParticles << 494 G4bool lossFluctuationFlag; 527 std::vector<G4Track*> scTracks; << 495 G4bool lossFluctuationArePossible; >> 496 G4bool rndmStepFlag; >> 497 G4bool tablesAreBuilt; >> 498 G4bool integral; >> 499 G4bool isIonisation; >> 500 G4bool useSubCutoff; 528 }; 501 }; 529 502 530 // ======== Run time inline methods ========== << 503 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 504 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 531 505 532 inline std::size_t G4VEnergyLossProcess::Curre << 506 inline void G4VEnergyLossProcess::DefineMaterial( >> 507 const G4MaterialCutsCouple* couple) 533 { 508 { 534 return currentCoupleIndex; << 509 if(couple != currentCouple) { >> 510 currentCouple = couple; >> 511 currentMaterial = couple->GetMaterial(); >> 512 currentMaterialIndex = couple->GetIndex(); >> 513 mfpKinEnergy = DBL_MAX; >> 514 } 535 } 515 } 536 516 537 //....oooOO0OOooo........oooOO0OOooo........oo 517 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 538 518 539 inline void G4VEnergyLossProcess::SelectModel( << 519 inline void G4VEnergyLossProcess::InitialiseStep(const G4Track& track) 540 { 520 { 541 currentModel = modelManager->SelectModel(kin << 521 InitialiseMassCharge(track); 542 currentModel->SetCurrentCouple(currentCouple << 522 preStepKinEnergy = track.GetKineticEnergy(); >> 523 preStepScaledEnergy = preStepKinEnergy*massRatio; >> 524 DefineMaterial(track.GetMaterialCutsCouple()); >> 525 if (theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX; 543 } 526 } 544 527 545 //....oooOO0OOooo........oooOO0OOooo........oo 528 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 546 529 547 inline G4VEmModel* G4VEnergyLossProcess::Selec << 530 inline void G4VEnergyLossProcess::InitialiseMassCharge(const G4Track&) 548 G4double kinEnergy, std::si << 531 {} >> 532 >> 533 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 534 >> 535 inline G4double G4VEnergyLossProcess::GetDEDX(G4double& kineticEnergy, >> 536 const G4MaterialCutsCouple* couple) 549 { 537 { 550 return modelManager->SelectModel(kinEnergy, << 538 DefineMaterial(couple); >> 539 return GetDEDXForScaledEnergy(kineticEnergy*massRatio); 551 } 540 } 552 541 553 //....oooOO0OOooo........oooOO0OOooo........oo 542 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 554 543 555 inline void << 544 inline G4double G4VEnergyLossProcess::GetDEDXForSubsec(G4double& kineticEnergy, 556 G4VEnergyLossProcess::DefineMaterial(const G4M << 545 const G4MaterialCutsCouple* couple) 557 { 546 { 558 if(couple != currentCouple) { << 547 DefineMaterial(couple); 559 currentCouple = couple; << 548 return GetSubDEDXForScaledEnergy(kineticEnergy*massRatio); 560 currentMaterial = couple->GetMaterial(); << 561 basedCoupleIndex = currentCoupleIndex = co << 562 fFactor = chargeSqRatio*biasFactor; << 563 mfpKinEnergy = DBL_MAX; << 564 idxLambda = 0; << 565 if(baseMat) { << 566 basedCoupleIndex = (*theDensityIdx)[curr << 567 fFactor *= (*theDensityFactor)[currentCo << 568 } << 569 reduceFactor = 1.0/(fFactor*massRatio); << 570 } << 571 } 549 } 572 550 573 //....oooOO0OOooo........oooOO0OOooo........oo 551 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 574 552 575 inline G4double G4VEnergyLossProcess::GetDEDXF 553 inline G4double G4VEnergyLossProcess::GetDEDXForScaledEnergy(G4double e) 576 { 554 { 577 /* << 555 G4bool b; 578 G4cout << "G4VEnergyLossProcess::GetDEDX: Id << 556 G4double x = 579 << basedCoupleIndex << " E(MeV)= " << 557 ((*theDEDXTable)[currentMaterialIndex]->GetValue(e, b))*chargeSqRatio; 580 << " Emin= " << minKinEnergy << " Fa << 558 if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy); 581 << " " << theDEDXTable << G4endl; */ << 582 G4double x = fFactor*(*theDEDXTable)[basedCo << 583 if(e < minKinEnergy) { x *= std::sqrt(e/minK << 584 return x; 559 return x; 585 } 560 } 586 561 587 //....oooOO0OOooo........oooOO0OOooo........oo 562 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 588 563 589 inline << 564 inline G4double G4VEnergyLossProcess::GetSubDEDXForScaledEnergy(G4double e) 590 G4double G4VEnergyLossProcess::GetDEDXForScale << 591 { 565 { 592 /* << 566 G4bool b; 593 G4cout << "G4VEnergyLossProcess::GetDEDX: Id << 567 G4double x = 594 << basedCoupleIndex << " E(MeV)= " << 568 ((*theDEDXSubTable)[currentMaterialIndex]->GetValue(e, b))*chargeSqRatio; 595 << " Emin= " << minKinEnergy << " Fa << 569 if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy); 596 << " " << theDEDXTable << G4endl; */ << 597 G4double x = fFactor*(*theDEDXTable)[basedCo << 598 if(e < minKinEnergy) { x *= std::sqrt(e/minK << 599 return x; 570 return x; 600 } 571 } 601 572 602 //....oooOO0OOooo........oooOO0OOooo........oo 573 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 603 574 604 inline G4double G4VEnergyLossProcess::GetIonis 575 inline G4double G4VEnergyLossProcess::GetIonisationForScaledEnergy(G4double e) 605 { 576 { 606 G4double x = << 577 G4bool b; 607 fFactor*(*theIonisationTable)[basedCoupleI << 578 G4double x = 0.0; 608 if(e < minKinEnergy) { x *= std::sqrt(e/minK << 579 // if(theIonisationTable) { >> 580 x = ((*theIonisationTable)[currentMaterialIndex]->GetValue(e, b)) >> 581 *chargeSqRatio; >> 582 if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy); >> 583 //} 609 return x; 584 return x; 610 } 585 } 611 586 612 //....oooOO0OOooo........oooOO0OOooo........oo 587 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 613 588 614 inline G4double G4VEnergyLossProcess::GetScale << 589 inline >> 590 G4double G4VEnergyLossProcess::GetSubIonisationForScaledEnergy(G4double e) 615 { 591 { 616 //G4cout << "G4VEnergyLossProcess::GetScaled << 592 G4bool b; 617 // << basedCoupleIndex << " E(MeV)= << 593 G4double x = 0.0; 618 // << " lastIdx= " << lastIdx << " << 594 //if(theIonisationSubTable) { 619 if(currentCoupleIndex != coupleIdxRange || f << 595 x = ((*theIonisationSubTable)[currentMaterialIndex]->GetValue(e, b)) 620 coupleIdxRange = currentCoupleIndex; << 596 *chargeSqRatio; 621 fRangeEnergy = e; << 597 if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy); 622 fRange = reduceFactor*((*theRangeTableForL << 598 //} 623 if (fRange < 0.0) { fRange = 0.0; } << 599 return x; 624 else if (e < minKinEnergy) { fRange *= std << 600 } >> 601 >> 602 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 603 >> 604 inline G4double G4VEnergyLossProcess::GetRange(G4double& kineticEnergy, >> 605 const G4MaterialCutsCouple* couple) >> 606 { >> 607 G4double x = fRange; >> 608 if(kineticEnergy != preStepKinEnergy || couple != currentCouple) { >> 609 DefineMaterial(couple); >> 610 if(theCSDARangeTable) >> 611 x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio) >> 612 * reduceFactor; >> 613 else if(theRangeTableForLoss) >> 614 x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor; 625 } 615 } 626 //G4cout << "G4VEnergyLossProcess::GetScaled << 616 return x; 627 // << basedCoupleIndex << " E(MeV)= << 628 // << " R= " << computedRange << " << 629 return fRange; << 630 } 617 } 631 618 632 inline G4double << 619 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 633 G4VEnergyLossProcess::GetScaledRangeForScaledE << 620 >> 621 inline G4double G4VEnergyLossProcess::GetCSDARange( >> 622 G4double& kineticEnergy, const G4MaterialCutsCouple* couple) 634 { 623 { 635 //G4cout << "G4VEnergyLossProcess::GetScaled << 624 DefineMaterial(couple); 636 // << basedCoupleIndex << " E(MeV)= << 625 G4double x = DBL_MAX; 637 // << " lastIdx= " << lastIdx << " << 626 if(theCSDARangeTable) 638 if(currentCoupleIndex != coupleIdxRange || f << 627 x = GetLimitScaledRangeForScaledEnergy(kineticEnergy*massRatio) 639 coupleIdxRange = currentCoupleIndex; << 628 * reduceFactor; 640 fRangeEnergy = e; << 629 return x; 641 fRange = reduceFactor*((*theRangeTableForL << 630 } 642 if (fRange < 0.0) { fRange = 0.0; } << 631 643 else if (e < minKinEnergy) { fRange *= std << 632 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 633 >> 634 inline G4double G4VEnergyLossProcess::GetLimitScaledRangeForScaledEnergy( >> 635 G4double e) >> 636 { >> 637 G4bool b; >> 638 G4double x; >> 639 >> 640 if (e < maxKinEnergyCSDA) { >> 641 x = ((*theCSDARangeTable)[currentMaterialIndex])->GetValue(e, b); >> 642 if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy); >> 643 } else { >> 644 x = theRangeAtMaxEnergy[currentMaterialIndex] + >> 645 (e - maxKinEnergyCSDA)/theDEDXAtMaxEnergy[currentMaterialIndex]; 644 } 646 } 645 //G4cout << "G4VEnergyLossProcess::GetScaled << 647 return x; 646 // << basedCoupleIndex << " E(MeV)= << 647 // << " R= " << fRange << " " << t << 648 return fRange; << 649 } 648 } 650 649 651 //....oooOO0OOooo........oooOO0OOooo........oo 650 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 652 651 653 inline G4double << 652 inline G4double G4VEnergyLossProcess::GetRangeForLoss( 654 G4VEnergyLossProcess::GetLimitScaledRangeForSc << 653 G4double& kineticEnergy, >> 654 const G4MaterialCutsCouple* couple) 655 { 655 { 656 G4double x = ((*theCSDARangeTable)[basedCoup << 656 DefineMaterial(couple); 657 if (x < 0.0) { x = 0.0; } << 657 G4double x = DBL_MAX; 658 else if (e < minKinEnergy) { x *= std::sqrt( << 658 if(theRangeTableForLoss) >> 659 x = GetScaledRangeForScaledEnergy(kineticEnergy*massRatio)*reduceFactor; >> 660 // G4cout << "Range from " << GetProcessName() >> 661 // << " e= " << kineticEnergy << " r= " << x << G4endl; 659 return x; 662 return x; 660 } 663 } 661 664 662 //....oooOO0OOooo........oooOO0OOooo........oo 665 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 663 666 664 inline G4double << 667 inline G4double G4VEnergyLossProcess::GetScaledRangeForScaledEnergy(G4double e) 665 G4VEnergyLossProcess::GetLimitScaledRangeForSc << 666 << 667 { 668 { 668 G4double x = ((*theCSDARangeTable)[basedCoup << 669 G4bool b; 669 if (x < 0.0) { x = 0.0; } << 670 G4double x = ((*theRangeTableForLoss)[currentMaterialIndex])->GetValue(e, b); 670 else if (e < minKinEnergy) { x *= std::sqrt( << 671 if(e < minKinEnergy) x *= std::sqrt(e/minKinEnergy); 671 return x; 672 return x; 672 } 673 } 673 674 674 //....oooOO0OOooo........oooOO0OOooo........oo 675 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 675 676 >> 677 inline G4double G4VEnergyLossProcess::GetKineticEnergy( >> 678 G4double& range, >> 679 const G4MaterialCutsCouple* couple) >> 680 { >> 681 DefineMaterial(couple); >> 682 G4double r = range/reduceFactor; >> 683 G4double e = ScaledKinEnergyForLoss(r)/massRatio; >> 684 return e; >> 685 } >> 686 >> 687 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 688 676 inline G4double G4VEnergyLossProcess::ScaledKi 689 inline G4double G4VEnergyLossProcess::ScaledKinEnergyForLoss(G4double r) 677 { 690 { 678 //G4cout << "G4VEnergyLossProcess::GetEnergy << 691 G4PhysicsVector* v = (*theInverseRangeTable)[currentMaterialIndex]; 679 // << basedCoupleIndex << " R(mm)= " << 692 G4double rmin = v->GetLowEdgeEnergy(0); 680 // << theInverseRangeTable << G4endl << 681 G4PhysicsVector* v = (*theInverseRangeTable) << 682 G4double rmin = v->Energy(0); << 683 G4double e = 0.0; 693 G4double e = 0.0; 684 if(r >= rmin) { e = v->Value(r, idxInverseRa << 694 if(r >= rmin) { 685 else if(r > 0.0) { << 695 G4bool b; >> 696 e = v->GetValue(r, b); >> 697 } else if(r > 0.0) { 686 G4double x = r/rmin; 698 G4double x = r/rmin; 687 e = minKinEnergy*x*x; 699 e = minKinEnergy*x*x; 688 } 700 } 689 return e; 701 return e; 690 } 702 } 691 703 692 //....oooOO0OOooo........oooOO0OOooo........oo 704 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 693 705 >> 706 inline G4double G4VEnergyLossProcess::GetLambda(G4double& kineticEnergy, >> 707 const G4MaterialCutsCouple* couple) >> 708 { >> 709 DefineMaterial(couple); >> 710 G4double x = 0.0; >> 711 if(theLambdaTable) x = GetLambdaForScaledEnergy(kineticEnergy*massRatio); >> 712 return x; >> 713 } >> 714 >> 715 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 716 694 inline G4double G4VEnergyLossProcess::GetLambd 717 inline G4double G4VEnergyLossProcess::GetLambdaForScaledEnergy(G4double e) 695 { 718 { 696 return fFactor*((*theLambdaTable)[basedCoupl << 719 G4bool b; >> 720 return >> 721 chargeSqRatio*(((*theLambdaTable)[currentMaterialIndex])->GetValue(e, b)); >> 722 } >> 723 >> 724 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 725 >> 726 inline void G4VEnergyLossProcess::ComputeLambdaForScaledEnergy(G4double e) >> 727 { >> 728 mfpKinEnergy = theEnergyOfCrossSectionMax[currentMaterialIndex]; >> 729 if (e <= mfpKinEnergy) { >> 730 preStepLambda = GetLambdaForScaledEnergy(e); >> 731 // mfpKinEnergy = 0.0; >> 732 } else { >> 733 G4double e1 = e*lambdaFactor; >> 734 if(e1 > mfpKinEnergy) { >> 735 preStepLambda = GetLambdaForScaledEnergy(e); >> 736 G4double preStepLambda1 = GetLambdaForScaledEnergy(e1); >> 737 if(preStepLambda1 > preStepLambda) { >> 738 mfpKinEnergy = e1; >> 739 preStepLambda = preStepLambda1; >> 740 } >> 741 } else { >> 742 preStepLambda = chargeSqRatio*theCrossSectionMax[currentMaterialIndex]; >> 743 } >> 744 } >> 745 // theNumberOfInteractionLengthLeft = -1.; 697 } 746 } 698 747 699 //....oooOO0OOooo........oooOO0OOooo........oo 748 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 700 749 701 inline G4double << 750 inline G4double G4VEnergyLossProcess::ContinuousStepLimit( 702 G4VEnergyLossProcess::GetLambdaForScaledEnergy << 751 const G4Track& track, G4double x, G4double y, G4double& z) 703 { 752 { 704 return fFactor*((*theLambdaTable)[basedCoupl << 753 G4GPILSelection sel; >> 754 return AlongStepGetPhysicalInteractionLength(track, x, y, z, &sel); 705 } 755 } 706 756 707 //....oooOO0OOooo........oooOO0OOooo........oo 757 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 708 758 709 inline G4double G4VEnergyLossProcess::LogScale << 759 inline G4double G4VEnergyLossProcess::GetContinuousStepLimit( >> 760 const G4Track&, >> 761 G4double, G4double, G4double&) 710 { 762 { 711 return track.GetDynamicParticle()->GetLogKin << 763 return DBL_MAX; 712 } 764 } 713 765 714 //....oooOO0OOooo........oooOO0OOooo........oo 766 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 715 767 716 inline G4double << 768 inline G4double G4VEnergyLossProcess::AlongStepGetPhysicalInteractionLength( 717 G4VEnergyLossProcess::GetDEDX(G4double kinEner << 769 const G4Track&, 718 const G4Material << 770 G4double, >> 771 G4double currentMinStep, >> 772 G4double&, >> 773 G4GPILSelection* selection) 719 { 774 { 720 DefineMaterial(couple); << 775 G4double x = DBL_MAX; 721 return GetDEDXForScaledEnergy(kinEnergy*mass << 776 *selection = aGPILSelection; >> 777 if(isIonisation) { >> 778 fRange = GetScaledRangeForScaledEnergy(preStepScaledEnergy)*reduceFactor; >> 779 >> 780 x = fRange; >> 781 G4double y = x*dRoverRange; >> 782 >> 783 // G4double safety = track.GetStep()->GetPreStepPoint()->GetSafety(); >> 784 if(x > finalRange && y < currentMinStep) { // && x > safety) { >> 785 x = y + finalRange*(1.0 - dRoverRange)*(2.0 - finalRange/fRange); >> 786 } else if (rndmStepFlag) x = SampleRange(); >> 787 // G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy >> 788 // <<" range= "<<fRange <<" cMinSt="<<currentMinStep >> 789 // <<" safety= " << safety<< " limit= " << x <<G4endl; >> 790 } >> 791 // G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy >> 792 // <<" stepLimit= "<<x<<G4endl; >> 793 return x; 722 } 794 } 723 795 724 //....oooOO0OOooo........oooOO0OOooo........oo 796 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 725 797 726 inline G4double << 798 inline G4double G4VEnergyLossProcess::SampleRange() 727 G4VEnergyLossProcess::GetDEDX(G4double kinEner << 728 const G4Material << 729 G4double logKinE << 730 { 799 { 731 DefineMaterial(couple); << 800 G4double e = amu_c2*preStepKinEnergy/particle->GetPDGMass(); 732 return GetDEDXForScaledEnergy(kinEnergy*mass << 801 G4bool b; >> 802 G4double s = fRange*std::pow(10.,vstrag->GetValue(e,b)); >> 803 G4double x = fRange + G4RandGauss::shoot(0.0,s); >> 804 if(x > 0.0) fRange = x; >> 805 return fRange; >> 806 } >> 807 >> 808 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 809 >> 810 inline G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength( >> 811 const G4Track& track, >> 812 G4double previousStepSize, >> 813 G4ForceCondition* condition) >> 814 { >> 815 // condition is set to "Not Forced" >> 816 *condition = NotForced; >> 817 G4double x = DBL_MAX; >> 818 if(previousStepSize <= DBL_MIN) theNumberOfInteractionLengthLeft = -1.0; >> 819 InitialiseStep(track); >> 820 >> 821 if(preStepScaledEnergy < mfpKinEnergy) { >> 822 if (integral) ComputeLambdaForScaledEnergy(preStepScaledEnergy); >> 823 else preStepLambda = GetLambdaForScaledEnergy(preStepScaledEnergy); >> 824 if(preStepLambda <= DBL_MIN) mfpKinEnergy = 0.0; >> 825 } >> 826 >> 827 if(preStepLambda > DBL_MIN) { >> 828 >> 829 if (theNumberOfInteractionLengthLeft < 0.0) { >> 830 // beggining of tracking (or just after DoIt of this process) >> 831 ResetNumberOfInteractionLengthLeft(); >> 832 } else if(previousStepSize > DBL_MIN) { >> 833 // subtract NumberOfInteractionLengthLeft >> 834 SubtractNumberOfInteractionLengthLeft(previousStepSize); >> 835 if(theNumberOfInteractionLengthLeft<0.) >> 836 theNumberOfInteractionLengthLeft=perMillion; >> 837 } >> 838 >> 839 // get mean free path >> 840 currentInteractionLength = 1.0/preStepLambda; >> 841 x = theNumberOfInteractionLengthLeft * currentInteractionLength; >> 842 #ifdef G4VERBOSE >> 843 if (verboseLevel>2){ >> 844 G4cout << "G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength "; >> 845 G4cout << "[ " << GetProcessName() << "]" << G4endl; >> 846 G4cout << " for " << particle->GetParticleName() >> 847 << " in Material " << currentMaterial->GetName() >> 848 << " Ekin(MeV)= " << preStepKinEnergy/MeV >> 849 <<G4endl; >> 850 G4cout << "MeanFreePath = " << currentInteractionLength/cm << "[cm]" >> 851 << "InteractionLength= " << x/cm <<"[cm] " <<G4endl; >> 852 } >> 853 #endif >> 854 } >> 855 return x; 733 } 856 } 734 857 735 //....oooOO0OOooo........oooOO0OOooo........oo 858 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 736 859 737 inline G4double << 860 inline G4double G4VEnergyLossProcess::MeanFreePath(const G4Track& track) 738 G4VEnergyLossProcess::GetRange(G4double kinEne << 739 const G4Materia << 740 { 861 { 741 DefineMaterial(couple); << 862 DefineMaterial(track.GetMaterialCutsCouple()); 742 return GetScaledRangeForScaledEnergy(kinEner << 863 preStepLambda = GetLambdaForScaledEnergy(track.GetKineticEnergy()*massRatio); >> 864 G4double x = DBL_MAX; >> 865 if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda; >> 866 return x; 743 } 867 } 744 868 745 //....oooOO0OOooo........oooOO0OOooo........oo 869 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 746 870 747 inline G4double << 871 inline G4double G4VEnergyLossProcess::GetMeanFreePath( 748 G4VEnergyLossProcess::GetRange(G4double kinEne << 872 const G4Track& track, 749 const G4Materia << 873 G4double, 750 G4double logKin << 874 G4ForceCondition* condition) >> 875 751 { 876 { 752 DefineMaterial(couple); << 877 *condition = NotForced; 753 return GetScaledRangeForScaledEnergy(kinEner << 878 return MeanFreePath(track); 754 } 879 } 755 880 756 //....oooOO0OOooo........oooOO0OOooo........oo 881 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 757 882 758 inline G4double << 883 inline G4double G4VEnergyLossProcess::MinPrimaryEnergy( 759 G4VEnergyLossProcess::GetCSDARange(G4double ki << 884 const G4ParticleDefinition*, const G4Material*, G4double cut) 760 const G4Mat << 761 { 885 { 762 DefineMaterial(couple); << 886 return cut; 763 return (nullptr == theCSDARangeTable) ? DBL_ << 764 GetLimitScaledRangeForScaledEnergy(kinetic << 765 } 887 } 766 888 767 //....oooOO0OOooo........oooOO0OOooo........oo 889 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 768 890 769 inline G4double << 891 inline G4VEmModel* G4VEnergyLossProcess::SelectModel(G4double kinEnergy) 770 G4VEnergyLossProcess::GetKineticEnergy(G4doubl << 771 const G << 772 { 892 { 773 DefineMaterial(couple); << 893 return modelManager->SelectModel(kinEnergy, currentMaterialIndex); 774 return ScaledKinEnergyForLoss(range/reduceFa << 775 } 894 } 776 895 777 //....oooOO0OOooo........oooOO0OOooo........oo 896 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 778 897 779 inline G4double << 898 inline G4VEmModel* G4VEnergyLossProcess::SelectModelForMaterial( 780 G4VEnergyLossProcess::GetLambda(G4double kinEn << 899 G4double kinEnergy, size_t& idx) const 781 const G4Materi << 782 { 900 { 783 DefineMaterial(couple); << 901 return modelManager->SelectModel(kinEnergy, idx); 784 return (nullptr != theLambdaTable) ? << 785 GetLambdaForScaledEnergy(kinEnergy*massRat << 786 } 902 } 787 903 788 //....oooOO0OOooo........oooOO0OOooo........oo 904 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 789 905 790 inline G4double << 906 inline const G4ParticleDefinition* G4VEnergyLossProcess::Particle() const 791 G4VEnergyLossProcess::GetLambda(G4double kinEn << 792 const G4Materi << 793 G4double logKi << 794 { 907 { 795 DefineMaterial(couple); << 908 return particle; 796 return (nullptr != theLambdaTable) ? << 797 GetLambdaForScaledEnergy(kinEnergy*massRat << 798 : 0.0; << 799 } 909 } 800 910 801 // ======== Get/Set inline methods used at ini << 911 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 802 912 803 inline void G4VEnergyLossProcess::SetFluctMode << 913 inline const G4ParticleDefinition* G4VEnergyLossProcess::BaseParticle() const 804 { 914 { 805 fluctModel = p; << 915 return baseParticle; 806 } 916 } 807 917 808 //....oooOO0OOooo........oooOO0OOooo........oo 918 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 809 919 810 inline G4VEmFluctuationModel* G4VEnergyLossPro << 920 inline const G4ParticleDefinition* G4VEnergyLossProcess::SecondaryParticle() const 811 { 921 { 812 return fluctModel; << 922 return secondaryParticle; 813 } 923 } 814 924 815 //....oooOO0OOooo........oooOO0OOooo........oo 925 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 816 926 817 inline void G4VEnergyLossProcess::SetParticle( << 927 inline void G4VEnergyLossProcess::CorrectionsAlongStep( >> 928 const G4MaterialCutsCouple*, >> 929 const G4DynamicParticle*, >> 930 G4double&, >> 931 G4double&) >> 932 {} >> 933 >> 934 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 935 >> 936 inline G4PhysicsTable* G4VEnergyLossProcess::DEDXTable() const 818 { 937 { 819 particle = p; << 938 return theDEDXTable; 820 } 939 } 821 940 822 //....oooOO0OOooo........oooOO0OOooo........oo 941 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 823 942 824 inline void << 943 inline G4PhysicsTable* G4VEnergyLossProcess::DEDXTableForSubsec() const 825 G4VEnergyLossProcess::SetSecondaryParticle(con << 826 { 944 { 827 secondaryParticle = p; << 945 return theDEDXSubTable; 828 } 946 } 829 947 830 //....oooOO0OOooo........oooOO0OOooo........oo 948 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 831 949 832 inline void << 950 inline G4PhysicsTable* G4VEnergyLossProcess::DEDXunRestrictedTable() const 833 G4VEnergyLossProcess::SetBaseParticle(const G4 << 834 { 951 { 835 baseParticle = p; << 952 return theDEDXunRestrictedTable; 836 } 953 } 837 954 838 //....oooOO0OOooo........oooOO0OOooo........oo 955 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 839 956 840 inline const G4ParticleDefinition* G4VEnergyLo << 957 inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTable() const 841 { 958 { 842 return particle; << 959 G4PhysicsTable* t = theDEDXTable; >> 960 if(theIonisationTable) t = theIonisationTable; >> 961 return t; 843 } 962 } 844 963 845 //....oooOO0OOooo........oooOO0OOooo........oo 964 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 846 965 847 inline const G4ParticleDefinition* G4VEnergyLo << 966 inline G4PhysicsTable* G4VEnergyLossProcess::IonisationTableForSubsec() const 848 { 967 { 849 return baseParticle; << 968 G4PhysicsTable* t = theDEDXSubTable; >> 969 if(theIonisationSubTable) t = theIonisationSubTable; >> 970 return t; 850 } 971 } 851 972 852 //....oooOO0OOooo........oooOO0OOooo........oo 973 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 853 974 854 inline const G4ParticleDefinition* << 975 inline G4PhysicsTable* G4VEnergyLossProcess::CSDARangeTable() const 855 G4VEnergyLossProcess::SecondaryParticle() cons << 856 { 976 { 857 return secondaryParticle; << 977 return theCSDARangeTable; 858 } 978 } 859 979 860 //....oooOO0OOooo........oooOO0OOooo........oo 980 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 861 981 862 inline void G4VEnergyLossProcess::SetLossFluct << 982 inline G4PhysicsTable* G4VEnergyLossProcess::RangeTableForLoss() const 863 { 983 { 864 lossFluctuationFlag = val; << 984 return theRangeTableForLoss; 865 actLossFluc = true; << 866 } 985 } 867 986 868 //....oooOO0OOooo........oooOO0OOooo........oo 987 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 869 988 870 inline void G4VEnergyLossProcess::SetSpline(G4 << 989 inline G4PhysicsTable* G4VEnergyLossProcess::InverseRangeTable() const 871 { 990 { 872 spline = val; << 991 return theInverseRangeTable; 873 } 992 } 874 993 875 //....oooOO0OOooo........oooOO0OOooo........oo 994 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 876 995 877 inline void G4VEnergyLossProcess::SetCrossSect << 996 inline G4PhysicsTable* G4VEnergyLossProcess::LambdaTable() 878 { 997 { 879 fXSType = val; << 998 return theLambdaTable; >> 999 } >> 1000 >> 1001 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1002 >> 1003 inline G4PhysicsTable* G4VEnergyLossProcess::SubLambdaTable() >> 1004 { >> 1005 return theSubLambdaTable; 880 } 1006 } 881 1007 882 //....oooOO0OOooo........oooOO0OOooo........oo 1008 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 883 1009 884 inline G4CrossSectionType G4VEnergyLossProcess << 1010 inline G4bool G4VEnergyLossProcess::IsIntegral() const 885 { 1011 { 886 return fXSType; << 1012 return integral; 887 } 1013 } 888 1014 889 //....oooOO0OOooo........oooOO0OOooo........oo 1015 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 890 1016 891 inline G4bool G4VEnergyLossProcess::IsIonisati << 1017 inline size_t G4VEnergyLossProcess::CurrentMaterialCutsCoupleIndex() const 892 { 1018 { 893 return isIonisation; << 1019 return currentMaterialIndex; 894 } 1020 } 895 1021 896 //....oooOO0OOooo........oooOO0OOooo........oo 1022 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 897 1023 898 inline G4int G4VEnergyLossProcess::NumberOfSub << 1024 inline void G4VEnergyLossProcess::SetDynamicMassCharge(G4double massratio, >> 1025 G4double charge2ratio) 899 { 1026 { 900 return nSCoffRegions; << 1027 massRatio = massratio; >> 1028 chargeSqRatio = charge2ratio; >> 1029 chargeSquare = charge2ratio*eplus*eplus; >> 1030 if(chargeSqRatio > 0.0) reduceFactor = 1.0/(chargeSqRatio*massRatio); >> 1031 } >> 1032 >> 1033 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1034 >> 1035 inline G4double G4VEnergyLossProcess::GetCurrentRange() const >> 1036 { >> 1037 return fRange; 901 } 1038 } 902 1039 903 //....oooOO0OOooo........oooOO0OOooo........oo 1040 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 904 1041 905 inline G4double G4VEnergyLossProcess::MinKinEn << 1042 void G4VEnergyLossProcess::AddEmModel(G4int order, G4VEmModel* p, >> 1043 G4VEmFluctuationModel* fluc, >> 1044 const G4Region* region) >> 1045 { >> 1046 modelManager->AddEmModel(order, p, fluc, region); >> 1047 if(p) p->SetParticleChange(pParticleChange, fluc); >> 1048 if(!fluc) { >> 1049 lossFluctuationFlag = false; >> 1050 lossFluctuationArePossible = false; >> 1051 } >> 1052 } >> 1053 >> 1054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1055 >> 1056 inline G4VEmModel* G4VEnergyLossProcess::GetModelByIndex(G4int idx) 906 { 1057 { 907 return minKinEnergy; << 1058 return modelManager->GetModel(idx); 908 } 1059 } 909 1060 910 //....oooOO0OOooo........oooOO0OOooo........oo 1061 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 911 1062 912 inline G4double G4VEnergyLossProcess::MaxKinEn << 1063 inline G4int G4VEnergyLossProcess::NumberOfModels() 913 { 1064 { 914 return maxKinEnergy; << 1065 return modelManager->NumberOfModels(); >> 1066 } >> 1067 >> 1068 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1069 >> 1070 inline void G4VEnergyLossProcess::SetEmModel(G4VEmModel* p, G4int index) >> 1071 { >> 1072 emModel[index] = p; >> 1073 } >> 1074 >> 1075 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1076 >> 1077 inline G4VEmModel* G4VEnergyLossProcess::EmModel(G4int index) >> 1078 { >> 1079 return emModel[index]; >> 1080 } >> 1081 >> 1082 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1083 >> 1084 inline void G4VEnergyLossProcess::SetFluctModel(G4VEmFluctuationModel* p) >> 1085 { >> 1086 fluctModel = p; >> 1087 } >> 1088 >> 1089 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1090 >> 1091 inline G4VEmFluctuationModel* G4VEnergyLossProcess::FluctModel() >> 1092 { >> 1093 return fluctModel; >> 1094 } >> 1095 >> 1096 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1097 >> 1098 inline void G4VEnergyLossProcess::UpdateEmModel(const G4String& nam, >> 1099 G4double emin, G4double emax) >> 1100 { >> 1101 modelManager->UpdateEmModel(nam, emin, emax); 915 } 1102 } 916 1103 917 //....oooOO0OOooo........oooOO0OOooo........oo 1104 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 918 1105 919 inline G4double G4VEnergyLossProcess::CrossSec << 1106 inline void G4VEnergyLossProcess::SetIntegral(G4bool val) 920 { 1107 { 921 return biasFactor; << 1108 integral = val; >> 1109 } >> 1110 >> 1111 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1112 >> 1113 inline void G4VEnergyLossProcess::SetParticle(const G4ParticleDefinition* p) >> 1114 { >> 1115 particle = p; >> 1116 } >> 1117 >> 1118 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1119 >> 1120 inline void G4VEnergyLossProcess::SetBaseParticle(const G4ParticleDefinition* p) >> 1121 { >> 1122 baseParticle = p; >> 1123 } >> 1124 >> 1125 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1126 >> 1127 inline void G4VEnergyLossProcess::SetSecondaryParticle(const G4ParticleDefinition* p) >> 1128 { >> 1129 secondaryParticle = p; >> 1130 } >> 1131 >> 1132 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1133 >> 1134 inline void G4VEnergyLossProcess::SetLinearLossLimit(G4double val) >> 1135 { >> 1136 linLossLimit = val; >> 1137 } >> 1138 >> 1139 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1140 >> 1141 inline void G4VEnergyLossProcess::SetLossFluctuations(G4bool val) >> 1142 { >> 1143 if(!val || lossFluctuationArePossible) lossFluctuationFlag = val; >> 1144 } >> 1145 >> 1146 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1147 >> 1148 inline void G4VEnergyLossProcess::SetRandomStep(G4bool val) >> 1149 { >> 1150 rndmStepFlag = val; >> 1151 } >> 1152 >> 1153 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 1154 >> 1155 inline void G4VEnergyLossProcess::SetMinSubRange(G4double val) >> 1156 { >> 1157 minSubRange = val; 922 } 1158 } 923 1159 924 //....oooOO0OOooo........oooOO0OOooo........oo 1160 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 925 1161 926 inline G4bool G4VEnergyLossProcess::TablesAreB 1162 inline G4bool G4VEnergyLossProcess::TablesAreBuilt() const 927 { 1163 { 928 return tablesAreBuilt; << 1164 return tablesAreBuilt; 929 } 1165 } 930 1166 931 //....oooOO0OOooo........oooOO0OOooo........oo 1167 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 932 1168 933 inline G4PhysicsTable* G4VEnergyLossProcess::D << 1169 inline G4int G4VEnergyLossProcess::NumberOfSubCutoffRegions() const 934 { 1170 { 935 return theDEDXTable; << 1171 return nSCoffRegions; 936 } 1172 } 937 1173 938 //....oooOO0OOooo........oooOO0OOooo........oo 1174 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 939 1175 940 inline G4PhysicsTable* G4VEnergyLossProcess::D << 1176 inline void G4VEnergyLossProcess::SetDEDXBinning(G4int nbins) 941 { 1177 { 942 return theDEDXunRestrictedTable; << 1178 nBins = nbins; 943 } 1179 } 944 1180 945 //....oooOO0OOooo........oooOO0OOooo........oo 1181 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 946 1182 947 inline G4PhysicsTable* G4VEnergyLossProcess::I << 1183 inline void G4VEnergyLossProcess::SetLambdaBinning(G4int nbins) 948 { 1184 { 949 return theIonisationTable; << 1185 nBins = nbins; 950 } 1186 } 951 1187 952 //....oooOO0OOooo........oooOO0OOooo........oo 1188 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 953 1189 954 inline G4PhysicsTable* G4VEnergyLossProcess::C << 1190 inline void G4VEnergyLossProcess::SetDEDXBinningForCSDARange(G4int nbins) 955 { 1191 { 956 return theCSDARangeTable; << 1192 nBinsCSDA = nbins; 957 } 1193 } 958 1194 959 //....oooOO0OOooo........oooOO0OOooo........oo 1195 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 960 1196 961 inline G4PhysicsTable* G4VEnergyLossProcess::R << 1197 inline G4double G4VEnergyLossProcess::MinKinEnergy() const 962 { 1198 { 963 return theRangeTableForLoss; << 1199 return minKinEnergy; 964 } 1200 } 965 1201 966 //....oooOO0OOooo........oooOO0OOooo........oo 1202 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 967 1203 968 inline G4PhysicsTable* G4VEnergyLossProcess::I << 1204 inline void G4VEnergyLossProcess::SetMinKinEnergy(G4double e) 969 { 1205 { 970 return theInverseRangeTable; << 1206 minKinEnergy = e; 971 } 1207 } 972 1208 973 //....oooOO0OOooo........oooOO0OOooo........oo 1209 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 974 1210 975 inline G4PhysicsTable* G4VEnergyLossProcess::L << 1211 inline void G4VEnergyLossProcess::SetMaxKinEnergy(G4double e) 976 { 1212 { 977 return theLambdaTable; << 1213 maxKinEnergy = e; >> 1214 if(e < maxKinEnergyCSDA) maxKinEnergyCSDA = e; 978 } 1215 } 979 1216 980 //....oooOO0OOooo........oooOO0OOooo........oo 1217 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 981 1218 982 inline G4bool G4VEnergyLossProcess::UseBaseMat << 1219 inline void G4VEnergyLossProcess::SetMaxKinEnergyForCSDARange(G4double e) 983 { 1220 { 984 return baseMat; << 1221 maxKinEnergyCSDA = e; 985 } 1222 } 986 1223 987 //....oooOO0OOooo........oooOO0OOooo........oo 1224 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 988 1225 989 inline std::vector<G4double>* << 1226 inline G4double G4VEnergyLossProcess::MaxKinEnergy() const 990 G4VEnergyLossProcess::EnergyOfCrossSectionMax( << 991 { 1227 { 992 return theEnergyOfCrossSectionMax; << 1228 return maxKinEnergy; 993 } 1229 } 994 1230 995 //....oooOO0OOooo........oooOO0OOooo........oo 1231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 996 1232 997 inline std::vector<G4TwoPeaksXS*>* G4VEnergyLo << 1233 inline void G4VEnergyLossProcess::SetLambdaFactor(G4double val) 998 { 1234 { 999 return fXSpeaks; << 1235 if(val > 0.0 && val <= 1.0) lambdaFactor = val; 1000 } 1236 } 1001 1237 1002 //....oooOO0OOooo........oooOO0OOooo........o 1238 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1003 1239 1004 inline std::size_t G4VEnergyLossProcess::Numb << 1240 inline void G4VEnergyLossProcess::SetIonisation(G4bool val) 1005 { 1241 { 1006 return numberOfModels; << 1242 isIonisation = val; >> 1243 if(val) aGPILSelection = CandidateForSelection; >> 1244 else aGPILSelection = NotCandidateForSelection; 1007 } 1245 } 1008 1246 1009 //....oooOO0OOooo........oooOO0OOooo........o 1247 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1010 1248 1011 inline G4VEmModel* G4VEnergyLossProcess::EmMo << 1249 inline G4bool G4VEnergyLossProcess::IsIonisationProcess() const 1012 { 1250 { 1013 return (index < emModels->size()) ? (*emMod << 1251 return isIonisation; 1014 } 1252 } 1015 1253 1016 //....oooOO0OOooo........oooOO0OOooo........o 1254 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1017 1255 1018 inline G4VEmModel* << 1256 void G4VEnergyLossProcess::SetStepFunction(G4double v1, G4double v2) 1019 G4VEnergyLossProcess::GetModelByIndex(std::si << 1020 { 1257 { 1021 return modelManager->GetModel((G4int)idx, v << 1258 dRoverRange = v1; >> 1259 finalRange = v2; >> 1260 if (dRoverRange > 0.999) dRoverRange = 1.0; >> 1261 currentCouple = 0; >> 1262 mfpKinEnergy = DBL_MAX; 1022 } 1263 } 1023 1264 1024 //....oooOO0OOooo........oooOO0OOooo........o 1265 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1025 1266 1026 #endif 1267 #endif 1027 1268