Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // >> 23 // $Id: G4VEnergyLossProcess.hh,v 1.9 2004/03/11 14:43:14 vnivanch Exp $ >> 24 // GEANT4 tag $Name: geant4-06-01 $ 26 // 25 // 27 // ------------------------------------------- 26 // ------------------------------------------------------------------- 28 // 27 // 29 // GEANT4 Class header file 28 // GEANT4 Class header file 30 // 29 // 31 // 30 // 32 // File name: G4VEnergyLossProcess 31 // File name: G4VEnergyLossProcess 33 // 32 // 34 // Author: Vladimir Ivanchenko on base 33 // Author: Vladimir Ivanchenko on base of Laszlo Urban code 35 // 34 // 36 // Creation date: 03.01.2002 35 // Creation date: 03.01.2002 37 // 36 // 38 // Modifications: Vladimir Ivanchenko << 37 // Modifications: >> 38 // >> 39 // 26-12-02 Secondary production moved to derived classes (V.Ivanchenko) >> 40 // 20-01-03 Migrade to cut per region (V.Ivanchenko) >> 41 // 24-01-03 Make models region aware (V.Ivanchenko) >> 42 // 05-02-03 Fix compilation warnings (V.Ivanchenko) >> 43 // 13-02-03 SubCutoffProcessors defined for regions (V.Ivanchenko) >> 44 // 17-02-03 Fix problem of store/restore tables (V.Ivanchenko) >> 45 // 26-02-03 Region dependent step limit (V.Ivanchenko) >> 46 // 26-03-03 Add GetDEDXDispersion (V.Ivanchenko) >> 47 // 09-04-03 Fix problem of negative range limit for non integral (V.Ivanchenko) >> 48 // 13-05-03 Add calculation of precise range (V.Ivanchenko) >> 49 // 21-07-03 Add UpdateEmModel method (V.Ivanchenko) >> 50 // 12-11-03 G4EnergyLossSTD -> G4EnergyLossProcess (V.Ivanchenko) >> 51 // 14-01-04 Activate precise range calculation (V.Ivanchenko) >> 52 // 10-03-04 Fix problem of step limit calculation (V.Ivanchenko) 39 // 53 // 40 // Class Description: 54 // Class Description: 41 // 55 // 42 // It is the unified energy loss process it ca 56 // It is the unified energy loss process it calculates the continuous 43 // energy loss for charged particles using a s 57 // energy loss for charged particles using a set of Energy Loss 44 // models valid for different energy regions. 58 // models valid for different energy regions. There are a possibility 45 // to create and access to dE/dx and range tab 59 // to create and access to dE/dx and range tables, or to calculate 46 // that information on fly. 60 // that information on fly. 47 61 48 // ------------------------------------------- 62 // ------------------------------------------------------------------- 49 // 63 // 50 64 51 #ifndef G4VEnergyLossProcess_h 65 #ifndef G4VEnergyLossProcess_h 52 #define G4VEnergyLossProcess_h 1 66 #define G4VEnergyLossProcess_h 1 53 67 54 #include "G4VContinuousDiscreteProcess.hh" 68 #include "G4VContinuousDiscreteProcess.hh" 55 #include "globals.hh" 69 #include "globals.hh" 56 #include "G4Material.hh" 70 #include "G4Material.hh" 57 #include "G4MaterialCutsCouple.hh" 71 #include "G4MaterialCutsCouple.hh" 58 #include "G4Track.hh" 72 #include "G4Track.hh" 59 #include "G4EmModelManager.hh" 73 #include "G4EmModelManager.hh" >> 74 #include "G4UnitsTable.hh" 60 #include "G4ParticleChangeForLoss.hh" 75 #include "G4ParticleChangeForLoss.hh" 61 #include "G4EmTableType.hh" << 62 #include "G4EmSecondaryParticleType.hh" << 63 #include "G4PhysicsTable.hh" << 64 #include "G4PhysicsVector.hh" << 65 76 66 class G4Step; 77 class G4Step; 67 class G4ParticleDefinition; 78 class G4ParticleDefinition; 68 class G4EmParameters; << 69 class G4VEmModel; 79 class G4VEmModel; 70 class G4VEmFluctuationModel; 80 class G4VEmFluctuationModel; 71 class G4DataVector; 81 class G4DataVector; >> 82 //class G4VParticleChange; >> 83 class G4PhysicsTable; >> 84 class G4PhysicsVector; >> 85 class G4VSubCutoffProcessor; 72 class G4Region; 86 class G4Region; 73 class G4SafetyHelper; << 74 class G4VAtomDeexcitation; << 75 class G4VSubCutProducer; << 76 class G4EmBiasingManager; << 77 class G4LossTableManager; << 78 class G4EmDataHandler; << 79 87 80 //....oooOO0OOooo........oooOO0OOooo........oo 88 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 81 89 82 class G4VEnergyLossProcess : public G4VContinu 90 class G4VEnergyLossProcess : public G4VContinuousDiscreteProcess 83 { 91 { 84 public: 92 public: 85 93 86 G4VEnergyLossProcess(const G4String& name = 94 G4VEnergyLossProcess(const G4String& name = "EnergyLoss", 87 G4ProcessType type = fE << 95 G4ProcessType type = fElectromagnetic); 88 96 89 ~G4VEnergyLossProcess() override; << 97 ~G4VEnergyLossProcess(); 90 98 91 //------------------------------------------ << 99 void Initialise(); 92 // Virtual methods to be implemented in conc << 93 //------------------------------------------ << 94 100 95 protected: << 101 G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&); 96 102 97 // description of specific process parameter << 103 G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&); 98 virtual void StreamProcessInfo(std::ostream& << 99 104 100 virtual void InitialiseEnergyLossProcess(con << 105 virtual std::vector<G4Track*>* SecondariesAlongStep( 101 con << 106 const G4Step&, >> 107 G4double& tmax, >> 108 G4double& eloss, >> 109 G4double& kinEnergy) = 0; 102 110 103 public: << 111 virtual void SecondariesPostStep( >> 112 G4VEmModel*, >> 113 const G4MaterialCutsCouple*, >> 114 const G4DynamicParticle*, >> 115 G4double& tcut, >> 116 G4double& kinEnergy) = 0; 104 117 105 // used as low energy limit LambdaTable << 118 virtual G4bool IsApplicable(const G4ParticleDefinition& p) = 0; 106 virtual G4double MinPrimaryEnergy(const G4Pa << 119 // True for all charged particles 107 const G4Ma << 108 120 109 // print documentation in html format << 121 virtual 110 void ProcessDescription(std::ostream& outFil << 122 void BuildPhysicsTable(const G4ParticleDefinition&); >> 123 // Build physics table during initialisation 111 124 112 // prepare all tables << 125 virtual void PrintInfoDefinition(); 113 void PreparePhysicsTable(const G4ParticleDef << 114 126 115 // build all tables << 127 // Print out of the class parameters 116 void BuildPhysicsTable(const G4ParticleDefin << 117 << 118 // build a table << 119 G4PhysicsTable* BuildDEDXTable(G4EmTableType << 120 << 121 // build a table << 122 G4PhysicsTable* BuildLambdaTable(G4EmTableTy << 123 << 124 // Called before tracking of each new G4Trac << 125 void StartTracking(G4Track*) override; << 126 << 127 // Step limit from AlongStep << 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 << 141 // AlongStep computations << 142 G4VParticleChange* AlongStepDoIt(const G4Tra << 143 << 144 // PostStep sampling of secondaries << 145 G4VParticleChange* PostStepDoIt(const G4Trac << 146 << 147 // Store all PhysicsTable in files. << 148 // Return false in case of any fatal failure << 149 G4bool StorePhysicsTable(const G4ParticleDef << 150 const G4String& dir << 151 G4bool ascii = fals << 152 << 153 // Retrieve all Physics from a files. << 154 // Return true if all the Physics Table are << 155 // Return false if any fatal failure. << 156 G4bool RetrievePhysicsTable(const G4Particle << 157 const G4String& << 158 G4bool ascii) ov << 159 128 160 private: << 129 G4PhysicsTable* BuildDEDXTable(); 161 130 162 // summary printout after initialisation << 131 G4PhysicsTable* BuildDEDXTableForPreciseRange(); 163 void StreamInfo(std::ostream& out, const G4P << 164 G4bool rst=false) const; << 165 << 166 //------------------------------------------ << 167 // Public interface to cross section, mfp an << 168 // These methods are not used in run time << 169 //------------------------------------------ << 170 132 171 public: << 133 G4PhysicsTable* BuildLambdaTable(); 172 134 173 // access to dispersion of restricted energy << 135 G4PhysicsTable* BuildLambdaSubTable(); 174 G4double GetDEDXDispersion(const G4MaterialC << 175 const G4DynamicPa << 176 G4double length); << 177 136 178 // Access to cross section table << 137 void SetParticles(const G4ParticleDefinition*, 179 G4double CrossSectionPerVolume(G4double kine << 138 const G4ParticleDefinition*); 180 const G4Mater << 181 G4double CrossSectionPerVolume(G4double kine << 182 const G4Mater << 183 G4double logK << 184 139 185 // access to cross section << 140 void SetParticle(const G4ParticleDefinition* p); 186 G4double MeanFreePath(const G4Track& track); << 141 void SetBaseParticle(const G4ParticleDefinition* p); >> 142 void SetSecondaryParticle(const G4ParticleDefinition* p); 187 143 188 // access to step limit << 144 const G4ParticleDefinition* Particle() const; 189 G4double ContinuousStepLimit(const G4Track& << 145 const G4ParticleDefinition* BaseParticle() const; 190 G4double previo << 146 const G4ParticleDefinition* SecondaryParticle() const; 191 G4double curren << 147 // Particle definition 192 G4double& curre << 193 148 194 protected: << 149 void SetDEDXBinning(G4int nbins); >> 150 // Binning for dEdx, range, and inverse range tables 195 151 196 // implementation of the pure virtual method << 152 void SetDEDXBinningForPreciseRange(G4int nbins); 197 G4double GetMeanFreePath(const G4Track& trac << 153 // Binning for dEdx, range, and inverse range tables 198 G4double previousSt << 199 G4ForceCondition* c << 200 154 201 // implementation of the pure virtual method << 155 void SetLambdaBinning(G4int nbins); 202 G4double GetContinuousStepLimit(const G4Trac << 156 // Binning for lambda table 203 G4double pre << 204 G4double cur << 205 G4double& cu << 206 << 207 // creation of an empty vector for cross sec << 208 G4PhysicsVector* LambdaPhysicsVector(const G << 209 G4doubl << 210 << 211 inline std::size_t CurrentMaterialCutsCouple << 212 << 213 //------------------------------------------ << 214 // Specific methods to set, access, modify m << 215 //------------------------------------------ << 216 157 217 // Select model in run time << 158 void SetMinKinEnergy(G4double e); 218 inline void SelectModel(G4double kinEnergy); << 159 G4double MinKinEnergy() const; >> 160 // Min kinetic energy for tables 219 161 220 public: << 162 void SetMaxKinEnergy(G4double e); 221 // Select model by energy and couple index << 163 G4double MaxKinEnergy() const; 222 // Not for run time processing << 164 // Max kinetic energy for tables 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 << 237 // Access to models << 238 inline std::size_t NumberOfModels() const; << 239 << 240 // Return a model from the local list << 241 inline G4VEmModel* EmModel(std::size_t index << 242 << 243 // Access to models from G4EmModelManager li << 244 inline G4VEmModel* GetModelByIndex(std::size << 245 << 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 //------------------------------------------ << 253 // Define and access particle type << 254 //------------------------------------------ << 255 165 256 protected: << 166 void SetMaxKinEnergyForPreciseRange(G4double e); 257 inline void SetParticle(const G4ParticleDefi << 167 // Max kinetic energy for tables 258 inline void SetSecondaryParticle(const G4Par << 259 168 260 public: << 169 G4bool StorePhysicsTable(G4ParticleDefinition*, 261 inline void SetBaseParticle(const G4Particle << 170 const G4String& directory, 262 inline const G4ParticleDefinition* Particle( << 171 G4bool ascii = false); 263 inline const G4ParticleDefinition* BaseParti << 172 // Store PhysicsTable in a file. 264 inline const G4ParticleDefinition* Secondary << 173 // Return false in case of failure at I/O >> 174 >> 175 G4bool RetrievePhysicsTable(G4ParticleDefinition*, >> 176 const G4String& directory, >> 177 G4bool ascii); >> 178 // Retrieve Physics from a file. >> 179 // (return true if the Physics Table can be build by using file) >> 180 // (return false if the process has no functionality or in case of failure) >> 181 // File name should is constructed as processName+particleName and the >> 182 // should be placed under the directory specifed by the argument. >> 183 >> 184 void AddEmModel(G4int, G4VEmModel*, G4VEmFluctuationModel* fluc = 0, >> 185 const G4Region* region = 0); >> 186 // Add EM model coupled with fluctuation model for the region >> 187 >> 188 void UpdateEmModel(const G4String&, G4double, G4double); >> 189 // Define new energy range for thhe model identified by the name >> 190 >> 191 void AddSubCutoffProcessor(G4VSubCutoffProcessor*, const G4Region* region = 0); >> 192 // Add subcutoff processor for the region 265 193 266 // hide assignment operator << 194 virtual void SetSubCutoff(G4bool) {}; 267 G4VEnergyLossProcess(G4VEnergyLossProcess &) << 268 G4VEnergyLossProcess & operator=(const G4VEn << 269 195 270 //------------------------------------------ << 196 void SetDEDXTable(G4PhysicsTable* p); 271 // Get/set parameters to configure the proce << 197 G4PhysicsTable* DEDXTable() const {return theDEDXTable;}; 272 //------------------------------------------ << 273 198 274 // Add subcut processor for the region << 199 void SetRangeTable(G4PhysicsTable* pRange); 275 void ActivateSubCutoff(const G4Region* regio << 200 G4PhysicsTable* RangeTable() const {return thePreciseRangeTable;}; 276 201 277 // Activate biasing << 202 void SetRangeTableForLoss(G4PhysicsTable* p); 278 void SetCrossSectionBiasingFactor(G4double f << 203 G4PhysicsTable* RangeTableForLoss() const {return theRangeTableForLoss;}; 279 204 280 void ActivateForcedInteraction(G4double leng << 205 void SetInverseRangeTable(G4PhysicsTable* p); 281 const G4Strin << 206 G4PhysicsTable* InverseRangeTable() const {return theInverseRangeTable;}; 282 G4bool flag = << 283 207 284 void ActivateSecondaryBiasing(const G4String << 208 void SetSecondaryRangeTable(G4PhysicsTable* p); 285 G4double energ << 286 209 287 inline void SetLossFluctuations(G4bool val); << 210 void SetLambdaTable(G4PhysicsTable* p); >> 211 G4PhysicsTable* LambdaTable() {return theLambdaTable;}; 288 212 289 inline void SetSpline(G4bool val); << 213 void SetSubLambdaTable(G4PhysicsTable* p); 290 inline void SetCrossSectionType(G4CrossSecti << 214 G4PhysicsTable* SubLambdaTable() {return theSubLambdaTable;}; 291 inline G4CrossSectionType CrossSectionType() << 292 215 293 // Set/Get flag "isIonisation" << 216 G4double GetDEDX(G4double& kineticEnergy, const G4MaterialCutsCouple* couple); 294 void SetIonisation(G4bool val); << 295 inline G4bool IsIonisationProcess() const; << 296 217 297 // Redefine parameteters for stepping contro << 218 G4double GetRange(G4double& kineticEnergy, const G4MaterialCutsCouple* couple); 298 void SetLinearLossLimit(G4double val); << 299 void SetStepFunction(G4double v1, G4double v << 300 void SetLowestEnergyLimit(G4double); << 301 219 302 inline G4int NumberOfSubCutoffRegions() cons << 220 G4double GetKineticEnergy(G4double& range, const G4MaterialCutsCouple* couple); 303 221 304 //------------------------------------------ << 222 G4double GetLambda(G4double kineticEnergy, const G4MaterialCutsCouple* couple); 305 // Specific methods to path Physics Tables t << 223 // It returns the MeanFreePath of the process 306 //------------------------------------------ << 307 224 308 void SetDEDXTable(G4PhysicsTable* p, G4EmTab << 225 G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple, 309 void SetCSDARangeTable(G4PhysicsTable* pRang << 226 const G4DynamicParticle* dp, 310 void SetRangeTableForLoss(G4PhysicsTable* p) << 227 G4double& length); 311 void SetInverseRangeTable(G4PhysicsTable* p) << 312 void SetLambdaTable(G4PhysicsTable* p); << 313 228 314 void SetTwoPeaksXS(std::vector<G4TwoPeaksXS* << 229 G4double MicroscopicCrossSection(G4double kineticEnergy, 315 void SetEnergyOfCrossSectionMax(std::vector< << 230 const G4MaterialCutsCouple* couple); >> 231 // It returns the MeanFreePath of the process for a (energy, material) 316 232 317 //------------------------------------------ << 233 void SetLinearLossLimit(G4double val) {linLossLimit = val;}; 318 // Specific methods to define custom Physics << 319 //------------------------------------------ << 320 234 321 // Binning for dEdx, range, inverse range an << 235 void SetLossFluctuations(G4bool val) {lossFluctuationFlag = val;}; 322 void SetDEDXBinning(G4int nbins); << 323 236 324 // Min kinetic energy for tables << 237 void SetIntegral(G4bool val); 325 void SetMinKinEnergy(G4double e); << 238 G4bool IsIntegral() const {return integral;} 326 inline G4double MinKinEnergy() const; << 327 239 328 // Max kinetic energy for tables << 240 void SetRandomStep(G4bool val) {rndmStepFlag = val;}; 329 void SetMaxKinEnergy(G4double e); << 330 inline G4double MaxKinEnergy() const; << 331 241 332 // Biasing parameters << 242 void SetMinSubRange(G4double val) {minSubRange = val;}; 333 inline G4double CrossSectionBiasingFactor() << 334 243 335 // Return values for given G4MaterialCutsCou << 244 void SetStepLimits(G4double v1, G4double v2); 336 inline G4double GetDEDX(G4double kineticEner << 245 void SetStepFunction(G4double v1, G4double v2); 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 << 352 inline G4bool TablesAreBuilt() const; << 353 << 354 // Access to specific tables << 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 << 365 inline G4bool UseBaseMaterial() const; << 366 << 367 //------------------------------------------ << 368 // Run time method for simulation of ionisat << 369 //------------------------------------------ << 370 246 371 // access atom on which interaction happens << 247 G4bool TablesAreBuilt() const {return tablesAreBuilt;}; 372 const G4Element* GetCurrentElement() const; << 373 248 374 // Set scaling parameters for ions is needed << 249 G4int NumberOfSubCutoffRegions() const {return nSCoffRegions;}; 375 void SetDynamicMassCharge(G4double massratio << 376 250 377 private: << 251 G4double MeanFreePath(const G4Track& track, >> 252 G4double previousStepSize, >> 253 G4ForceCondition* condition); 378 254 379 void FillSecondariesAlongStep(G4double weigh << 255 G4double ContinuousStepLimit(const G4Track& track, >> 256 G4double previousStepSize, >> 257 G4double currentMinimumStep, >> 258 G4double& currentSafety); 380 259 381 void PrintWarning(const G4String&, G4double << 260 void ResetNumberOfInteractionLengthLeft(); >> 261 // reset (determine the value of)NumberOfInteractionLengthLeft 382 262 383 // define material and indexes << 263 protected: 384 inline void DefineMaterial(const G4MaterialC << 385 264 386 //------------------------------------------ << 265 virtual 387 // Compute values using scaling relation, ma << 266 G4double GetMeanFreePath(const G4Track& track, 388 //------------------------------------------ << 267 G4double previousStepSize, 389 inline G4double GetDEDXForScaledEnergy(G4dou << 268 G4ForceCondition* condition); 390 inline G4double GetDEDXForScaledEnergy(G4dou << 391 G4dou << 392 inline G4double GetIonisationForScaledEnergy << 393 inline G4double GetScaledRangeForScaledEnerg << 394 inline G4double GetScaledRangeForScaledEnerg << 395 << 396 << 397 inline G4double GetLimitScaledRangeForScaled << 398 inline G4double GetLimitScaledRangeForScaled << 399 << 400 << 401 inline G4double ScaledKinEnergyForLoss(G4dou << 402 inline G4double GetLambdaForScaledEnergy(G4d << 403 inline G4double GetLambdaForScaledEnergy(G4d << 404 G4d << 405 << 406 inline G4double LogScaledEkin(const G4Track& << 407 << 408 void ComputeLambdaForScaledEnergy(G4double s << 409 const G4Tr << 410 269 411 G4bool IsRegionForCubcutProcessor(const G4Tr << 270 virtual >> 271 G4double GetContinuousStepLimit(const G4Track& track, >> 272 G4double previousStepSize, >> 273 G4double currentMinimumStep, >> 274 G4double& currentSafety); 412 275 413 protected: << 276 virtual >> 277 const G4ParticleDefinition* DefineBaseParticle( >> 278 const G4ParticleDefinition*) {return 0;}; 414 279 415 G4ParticleChangeForLoss fParticleChange; << 280 virtual 416 const G4Material* currentMaterial << 281 G4PhysicsVector* DEDXPhysicsVector(const G4MaterialCutsCouple*); 417 const G4MaterialCutsCouple* currentCouple = << 418 282 419 private: << 283 virtual >> 284 G4PhysicsVector* DEDXPhysicsVectorForPreciseRange(const G4MaterialCutsCouple*); 420 285 421 G4LossTableManager* lManager; << 286 virtual 422 G4EmModelManager* modelManager; << 287 G4PhysicsVector* LambdaPhysicsVector(const G4MaterialCutsCouple*); 423 G4VEmModel* currentModel = n << 424 G4EmBiasingManager* biasManager = nu << 425 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 288 450 std::vector<G4double>* theEnergyOfCrossSecti << 289 virtual 451 std::vector<G4TwoPeaksXS*>* fXSpeaks = nullp << 290 G4PhysicsVector* SubLambdaPhysicsVector(const G4MaterialCutsCouple*); 452 291 453 G4double lowestKinEnergy; << 292 virtual G4double MinPrimaryEnergy(const G4ParticleDefinition*, 454 G4double minKinEnergy; << 293 const G4Material*, G4double cut) = 0; 455 G4double maxKinEnergy; << 456 G4double maxKinEnergyCSDA; << 457 294 458 G4double linLossLimit = 0.01; << 295 virtual G4double MaxSecondaryEnergy(const G4DynamicParticle* dp) = 0; 459 G4double dRoverRange = 0.2; << 460 G4double finalRange; << 461 G4double lambdaFactor = 0.8; << 462 G4double invLambdaFactor; << 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 296 473 protected: << 297 G4VEmModel* SelectModel(G4double& kinEnergy); 474 298 475 G4double preStepLambda = 0.0; << 299 G4VSubCutoffProcessor* SubCutoffProcessor(size_t index); 476 G4double preStepKinEnergy = 0.0; << 477 G4double preStepScaledEnergy = 0.0; << 478 G4double mfpKinEnergy = 0.0; << 479 300 480 std::size_t currentCoupleIndex = 0; << 301 size_t CurrentMaterialCutsCoupleIndex() const {return currentMaterialIndex;}; 481 302 482 private: << 303 void SetMassRatio(G4double val) {massRatio = val;}; 483 304 484 G4int nBins; << 305 void SetReduceFactor(G4double val) {reduceFactor = val;}; 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 306 526 std::vector<G4DynamicParticle*> secParticles << 307 void SetChargeSquare(G4double val) {chargeSquare = val;}; 527 std::vector<G4Track*> scTracks; << 528 }; << 529 308 530 // ======== Run time inline methods ========== << 309 void SetChargeSquareRatio(G4double val) {chargeSqRatio = val;}; 531 310 532 inline std::size_t G4VEnergyLossProcess::Curre << 311 private: 533 { << 534 return currentCoupleIndex; << 535 } << 536 312 537 //....oooOO0OOooo........oooOO0OOooo........oo << 313 void Clear(); 538 314 539 inline void G4VEnergyLossProcess::SelectModel( << 315 void DefineMaterial(const G4MaterialCutsCouple* couple); 540 { << 541 currentModel = modelManager->SelectModel(kin << 542 currentModel->SetCurrentCouple(currentCouple << 543 } << 544 316 545 //....oooOO0OOooo........oooOO0OOooo........oo << 317 G4double GetDEDXForLoss(G4double kineticEnergy); 546 318 547 inline G4VEmModel* G4VEnergyLossProcess::Selec << 319 G4double GetRangeForLoss(G4double kineticEnergy); 548 G4double kinEnergy, std::si << 549 { << 550 return modelManager->SelectModel(kinEnergy, << 551 } << 552 320 553 //....oooOO0OOooo........oooOO0OOooo........oo << 321 G4double GetPreciseRange(G4double kineticEnergy); 554 322 555 inline void << 323 G4double GetKineticEnergyForLoss(G4double range); 556 G4VEnergyLossProcess::DefineMaterial(const G4M << 557 { << 558 if(couple != currentCouple) { << 559 currentCouple = couple; << 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 } << 572 324 573 //....oooOO0OOooo........oooOO0OOooo........oo << 325 // hide assignment operator 574 326 575 inline G4double G4VEnergyLossProcess::GetDEDXF << 327 G4VEnergyLossProcess(G4VEnergyLossProcess &); 576 { << 328 G4VEnergyLossProcess & operator=(const G4VEnergyLossProcess &right); 577 /* << 578 G4cout << "G4VEnergyLossProcess::GetDEDX: Id << 579 << basedCoupleIndex << " E(MeV)= " << 580 << " Emin= " << minKinEnergy << " Fa << 581 << " " << theDEDXTable << G4endl; */ << 582 G4double x = fFactor*(*theDEDXTable)[basedCo << 583 if(e < minKinEnergy) { x *= std::sqrt(e/minK << 584 return x; << 585 } << 586 329 587 //....oooOO0OOooo........oooOO0OOooo........oo << 330 // ===================================================================== 588 331 589 inline << 332 protected: 590 G4double G4VEnergyLossProcess::GetDEDXForScale << 591 { << 592 /* << 593 G4cout << "G4VEnergyLossProcess::GetDEDX: Id << 594 << basedCoupleIndex << " E(MeV)= " << 595 << " Emin= " << minKinEnergy << " Fa << 596 << " " << theDEDXTable << G4endl; */ << 597 G4double x = fFactor*(*theDEDXTable)[basedCo << 598 if(e < minKinEnergy) { x *= std::sqrt(e/minK << 599 return x; << 600 } << 601 333 602 //....oooOO0OOooo........oooOO0OOooo........oo << 334 G4ParticleChangeForLoss fParticleChange; 603 335 604 inline G4double G4VEnergyLossProcess::GetIonis << 336 private: 605 { << 606 G4double x = << 607 fFactor*(*theIonisationTable)[basedCoupleI << 608 if(e < minKinEnergy) { x *= std::sqrt(e/minK << 609 return x; << 610 } << 611 337 612 //....oooOO0OOooo........oooOO0OOooo........oo << 338 G4EmModelManager* modelManager; >> 339 std::vector<G4VSubCutoffProcessor*> scoffProcessors; >> 340 std::vector<const G4Region*> scoffRegions; >> 341 G4int nSCoffRegions; >> 342 std::vector<G4int> idxSCoffRegions; >> 343 >> 344 // tables and vectors >> 345 G4PhysicsTable* theDEDXTable; >> 346 G4PhysicsTable* theRangeTableForLoss; >> 347 G4PhysicsTable* thePreciseRangeTable; >> 348 G4PhysicsTable* theSecondaryRangeTable; >> 349 G4PhysicsTable* theInverseRangeTable; >> 350 G4PhysicsTable* theLambdaTable; >> 351 G4PhysicsTable* theSubLambdaTable; >> 352 G4double* theDEDXAtMaxEnergy; >> 353 G4double* theRangeAtMaxEnergy; >> 354 >> 355 const G4DataVector* theCuts; >> 356 >> 357 const G4ParticleDefinition* particle; >> 358 const G4ParticleDefinition* baseParticle; >> 359 const G4ParticleDefinition* secondaryParticle; >> 360 >> 361 // cash >> 362 const G4Material* currentMaterial; >> 363 const G4MaterialCutsCouple* currentCouple; >> 364 size_t currentMaterialIndex; >> 365 G4double minStepLimit; >> 366 >> 367 G4int nDEDXBins; >> 368 G4int nDEDXBinsForRange; >> 369 G4int nLambdaBins; 613 370 614 inline G4double G4VEnergyLossProcess::GetScale << 371 G4double lowestKinEnergy; 615 { << 372 G4double minKinEnergy; 616 //G4cout << "G4VEnergyLossProcess::GetScaled << 373 G4double maxKinEnergy; 617 // << basedCoupleIndex << " E(MeV)= << 374 G4double maxKinEnergyForRange; 618 // << " lastIdx= " << lastIdx << " << 619 if(currentCoupleIndex != coupleIdxRange || f << 620 coupleIdxRange = currentCoupleIndex; << 621 fRangeEnergy = e; << 622 fRange = reduceFactor*((*theRangeTableForL << 623 if (fRange < 0.0) { fRange = 0.0; } << 624 else if (e < minKinEnergy) { fRange *= std << 625 } << 626 //G4cout << "G4VEnergyLossProcess::GetScaled << 627 // << basedCoupleIndex << " E(MeV)= << 628 // << " R= " << computedRange << " << 629 return fRange; << 630 } << 631 << 632 inline G4double << 633 G4VEnergyLossProcess::GetScaledRangeForScaledE << 634 { << 635 //G4cout << "G4VEnergyLossProcess::GetScaled << 636 // << basedCoupleIndex << " E(MeV)= << 637 // << " lastIdx= " << lastIdx << " << 638 if(currentCoupleIndex != coupleIdxRange || f << 639 coupleIdxRange = currentCoupleIndex; << 640 fRangeEnergy = e; << 641 fRange = reduceFactor*((*theRangeTableForL << 642 if (fRange < 0.0) { fRange = 0.0; } << 643 else if (e < minKinEnergy) { fRange *= std << 644 } << 645 //G4cout << "G4VEnergyLossProcess::GetScaled << 646 // << basedCoupleIndex << " E(MeV)= << 647 // << " R= " << fRange << " " << t << 648 return fRange; << 649 } << 650 375 651 //....oooOO0OOooo........oooOO0OOooo........oo << 376 G4double massRatio; >> 377 G4double reduceFactor; >> 378 G4double chargeSquare; >> 379 G4double chargeSqRatio; >> 380 >> 381 G4double preStepLambda; >> 382 G4double fRange; >> 383 G4double preStepKinEnergy; >> 384 G4double preStepScaledEnergy; >> 385 G4double linLossLimit; >> 386 G4double minSubRange; >> 387 G4double dRoverRange; >> 388 G4double finalRange; >> 389 G4double defaultRoverRange; >> 390 G4double defaultIntegralRange; 652 391 653 inline G4double << 392 G4bool lossFluctuationFlag; 654 G4VEnergyLossProcess::GetLimitScaledRangeForSc << 393 G4bool rndmStepFlag; 655 { << 394 G4bool hasRestProcess; 656 G4double x = ((*theCSDARangeTable)[basedCoup << 395 G4bool tablesAreBuilt; 657 if (x < 0.0) { x = 0.0; } << 396 G4bool integral; 658 else if (e < minKinEnergy) { x *= std::sqrt( << 397 G4bool meanFreePath; 659 return x; << 398 }; 660 } << 661 399 662 //....oooOO0OOooo........oooOO0OOooo........oo 400 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 663 << 664 inline G4double << 665 G4VEnergyLossProcess::GetLimitScaledRangeForSc << 666 << 667 { << 668 G4double x = ((*theCSDARangeTable)[basedCoup << 669 if (x < 0.0) { x = 0.0; } << 670 else if (e < minKinEnergy) { x *= std::sqrt( << 671 return x; << 672 } << 673 << 674 //....oooOO0OOooo........oooOO0OOooo........oo 401 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 675 402 676 inline G4double G4VEnergyLossProcess::ScaledKi << 403 inline void G4VEnergyLossProcess::DefineMaterial(const G4MaterialCutsCouple* couple) 677 { 404 { 678 //G4cout << "G4VEnergyLossProcess::GetEnergy << 405 if(couple != currentCouple) { 679 // << basedCoupleIndex << " R(mm)= " << 406 currentCouple = couple; 680 // << theInverseRangeTable << G4endl << 407 currentMaterial = couple->GetMaterial(); 681 G4PhysicsVector* v = (*theInverseRangeTable) << 408 currentMaterialIndex = couple->GetIndex(); 682 G4double rmin = v->Energy(0); << 409 minStepLimit = std::min(finalRange, 683 G4double e = 0.0; << 410 currentCouple->GetProductionCuts()->GetProductionCut(idxG4ElectronCut)); 684 if(r >= rmin) { e = v->Value(r, idxInverseRa << 411 if(integral && !meanFreePath) ResetNumberOfInteractionLengthLeft(); 685 else if(r > 0.0) { << 686 G4double x = r/rmin; << 687 e = minKinEnergy*x*x; << 688 } 412 } 689 return e; << 690 } << 691 << 692 //....oooOO0OOooo........oooOO0OOooo........oo << 693 << 694 inline G4double G4VEnergyLossProcess::GetLambd << 695 { << 696 return fFactor*((*theLambdaTable)[basedCoupl << 697 } 413 } 698 414 699 //....oooOO0OOooo........oooOO0OOooo........oo 415 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 700 416 701 inline G4double << 417 inline G4double G4VEnergyLossProcess::GetDEDX(G4double& kineticEnergy, 702 G4VEnergyLossProcess::GetLambdaForScaledEnergy << 418 const G4MaterialCutsCouple* couple) 703 { 419 { 704 return fFactor*((*theLambdaTable)[basedCoupl << 420 DefineMaterial(couple); >> 421 G4bool b; >> 422 G4double e = kineticEnergy*massRatio; >> 423 G4double x = ((*theDEDXTable)[currentMaterialIndex]->GetValue(e, b))*chargeSqRatio; >> 424 if(e < minKinEnergy) x *= sqrt(e/minKinEnergy); >> 425 return x; 705 } 426 } 706 427 707 //....oooOO0OOooo........oooOO0OOooo........oo 428 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 708 429 709 inline G4double G4VEnergyLossProcess::LogScale << 430 inline G4double G4VEnergyLossProcess::GetDEDXForLoss(G4double kineticEnergy) 710 { 431 { 711 return track.GetDynamicParticle()->GetLogKin << 432 G4bool b; >> 433 G4double e = kineticEnergy*massRatio; >> 434 G4double x = ((*theDEDXTable)[currentMaterialIndex]->GetValue(e, b))*chargeSqRatio; >> 435 if(e < minKinEnergy) x *= sqrt(e/minKinEnergy); >> 436 return x; 712 } 437 } 713 438 714 //....oooOO0OOooo........oooOO0OOooo........oo 439 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 715 440 716 inline G4double << 441 inline G4double G4VEnergyLossProcess::GetRange(G4double& kineticEnergy, 717 G4VEnergyLossProcess::GetDEDX(G4double kinEner << 442 const G4MaterialCutsCouple* couple) 718 const G4Material << 719 { 443 { 720 DefineMaterial(couple); 444 DefineMaterial(couple); 721 return GetDEDXForScaledEnergy(kinEnergy*mass << 445 G4double x = DBL_MAX; >> 446 if(thePreciseRangeTable) x = GetPreciseRange(kineticEnergy); >> 447 else if(theRangeTableForLoss) x = GetRangeForLoss(kineticEnergy); >> 448 return x; 722 } 449 } 723 450 724 //....oooOO0OOooo........oooOO0OOooo........oo 451 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 725 452 726 inline G4double << 453 inline G4double G4VEnergyLossProcess::GetPreciseRange(G4double kineticEnergy) 727 G4VEnergyLossProcess::GetDEDX(G4double kinEner << 728 const G4Material << 729 G4double logKinE << 730 { 454 { 731 DefineMaterial(couple); << 455 G4bool b; 732 return GetDEDXForScaledEnergy(kinEnergy*mass << 456 G4double x; >> 457 G4double e = kineticEnergy*massRatio; >> 458 >> 459 if (e < maxKinEnergyForRange) { >> 460 x = ((*thePreciseRangeTable)[currentMaterialIndex])->GetValue(e, b); >> 461 if(e < minKinEnergy) x *= sqrt(e/minKinEnergy); >> 462 >> 463 } else { >> 464 x = theRangeAtMaxEnergy[currentMaterialIndex] + >> 465 (e - maxKinEnergyForRange)/theDEDXAtMaxEnergy[currentMaterialIndex]; >> 466 } >> 467 return x*reduceFactor; 733 } 468 } 734 469 735 //....oooOO0OOooo........oooOO0OOooo........oo 470 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 736 471 737 inline G4double << 472 inline G4double G4VEnergyLossProcess::GetRangeForLoss(G4double kineticEnergy) 738 G4VEnergyLossProcess::GetRange(G4double kinEne << 739 const G4Materia << 740 { 473 { 741 DefineMaterial(couple); << 474 G4bool b; 742 return GetScaledRangeForScaledEnergy(kinEner << 475 G4double e = kineticEnergy*massRatio; >> 476 G4double x = ((*theRangeTableForLoss)[currentMaterialIndex])->GetValue(e, b); >> 477 if(e < minKinEnergy) x *= sqrt(e/minKinEnergy); >> 478 return x*reduceFactor; 743 } 479 } 744 480 745 //....oooOO0OOooo........oooOO0OOooo........oo 481 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 746 482 747 inline G4double << 483 inline G4double G4VEnergyLossProcess::GetKineticEnergy(G4double& range, 748 G4VEnergyLossProcess::GetRange(G4double kinEne << 484 const G4MaterialCutsCouple* couple) 749 const G4Materia << 750 G4double logKin << 751 { 485 { 752 DefineMaterial(couple); << 486 G4double del = fRange - range; 753 return GetScaledRangeForScaledEnergy(kinEner << 487 G4double e = minKinEnergy; >> 488 if(couple == currentCouple && del > 0.0 && del < fRange*linLossLimit) { >> 489 e = preStepKinEnergy - del*GetDEDXForLoss(preStepKinEnergy); >> 490 if(e < 0.0) e = 0.0; >> 491 } else { >> 492 DefineMaterial(couple); >> 493 G4double r = range/reduceFactor; >> 494 G4PhysicsVector* v = (*theInverseRangeTable)[currentMaterialIndex]; >> 495 G4double rmin = v->GetLowEdgeEnergy(0); >> 496 if(r <= rmin) { >> 497 r /= rmin; >> 498 e *= r*r; >> 499 } else { >> 500 G4bool b; >> 501 e = v->GetValue(r, b); >> 502 } >> 503 e /= massRatio; >> 504 } >> 505 return e; 754 } 506 } 755 507 756 //....oooOO0OOooo........oooOO0OOooo........oo 508 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 757 509 758 inline G4double << 510 inline G4double G4VEnergyLossProcess::GetKineticEnergyForLoss(G4double range) 759 G4VEnergyLossProcess::GetCSDARange(G4double ki << 760 const G4Mat << 761 { 511 { 762 DefineMaterial(couple); << 512 G4double r = range/reduceFactor; 763 return (nullptr == theCSDARangeTable) ? DBL_ << 513 G4PhysicsVector* v = (*theInverseRangeTable)[currentMaterialIndex]; 764 GetLimitScaledRangeForScaledEnergy(kinetic << 514 G4double rmin = v->GetLowEdgeEnergy(0); >> 515 G4double e = minKinEnergy; >> 516 if(r <= rmin) { >> 517 r /= rmin; >> 518 e *= r*r; >> 519 } else { >> 520 G4bool b; >> 521 e = v->GetValue(r, b); >> 522 } >> 523 return e/massRatio; 765 } 524 } 766 525 767 //....oooOO0OOooo........oooOO0OOooo........oo 526 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 768 527 769 inline G4double << 528 inline G4double G4VEnergyLossProcess::GetDEDXDispersion( 770 G4VEnergyLossProcess::GetKineticEnergy(G4doubl << 529 const G4MaterialCutsCouple *couple, 771 const G << 530 const G4DynamicParticle* dp, >> 531 G4double& length) 772 { 532 { 773 DefineMaterial(couple); 533 DefineMaterial(couple); 774 return ScaledKinEnergyForLoss(range/reduceFa << 534 G4double tmax = MaxSecondaryEnergy(dp); >> 535 tmax = std::min(tmax,(*theCuts)[currentMaterialIndex]); >> 536 return modelManager->GetDEDXDispersion(currentMaterial, dp, tmax, length, >> 537 currentMaterialIndex); 775 } 538 } 776 539 777 //....oooOO0OOooo........oooOO0OOooo........oo 540 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 778 541 779 inline G4double << 542 inline G4double G4VEnergyLossProcess::GetMeanFreePath(const G4Track& track, 780 G4VEnergyLossProcess::GetLambda(G4double kinEn << 543 G4double, G4ForceCondition*) 781 const G4Materi << 782 { 544 { 783 DefineMaterial(couple); << 545 DefineMaterial(track.GetMaterialCutsCouple()); 784 return (nullptr != theLambdaTable) ? << 546 preStepKinEnergy = track.GetKineticEnergy(); 785 GetLambdaForScaledEnergy(kinEnergy*massRat << 547 preStepScaledEnergy = preStepKinEnergy*massRatio; >> 548 if (meanFreePath) { >> 549 G4bool b; >> 550 preStepLambda = (((*theLambdaTable)[currentMaterialIndex])-> >> 551 GetValue(preStepScaledEnergy, b)) * chargeSqRatio; >> 552 if (integral) meanFreePath = false; >> 553 } >> 554 G4double x = DBL_MAX; >> 555 if(0.0 < preStepLambda) x = 1.0/preStepLambda; >> 556 // G4cout << GetProcessName() << ": e= " << preStepKinEnergy << " mfp= " << x << G4endl; >> 557 return x; 786 } 558 } 787 559 788 //....oooOO0OOooo........oooOO0OOooo........oo 560 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 789 561 790 inline G4double << 562 inline G4double G4VEnergyLossProcess::GetContinuousStepLimit(const G4Track&, 791 G4VEnergyLossProcess::GetLambda(G4double kinEn << 563 G4double, G4double currentMinStep, G4double&) 792 const G4Materi << 793 G4double logKi << 794 { 564 { 795 DefineMaterial(couple); << 565 G4double x = DBL_MAX; 796 return (nullptr != theLambdaTable) ? << 566 if(theRangeTableForLoss) { 797 GetLambdaForScaledEnergy(kinEnergy*massRat << 567 fRange = GetRange(preStepKinEnergy, currentCouple); 798 : 0.0; << 799 } << 800 << 801 // ======== Get/Set inline methods used at ini << 802 568 803 inline void G4VEnergyLossProcess::SetFluctMode << 569 x = fRange; 804 { << 570 G4double y = x*dRoverRange; 805 fluctModel = p; << 806 } << 807 571 808 //....oooOO0OOooo........oooOO0OOooo........oo << 572 if(x > minStepLimit && y < currentMinStep ) { 809 573 810 inline G4VEmFluctuationModel* G4VEnergyLossPro << 574 x = y + minStepLimit*(1.0 - dRoverRange)*(2.0 - minStepLimit/fRange); 811 { << 575 if(x >fRange || x<minStepLimit) G4cout << "!!! StepLimit problem!!!" << G4endl; 812 return fluctModel; << 576 if(rndmStepFlag) x = minStepLimit + G4UniformRand()*(x-minStepLimit); >> 577 } >> 578 } >> 579 return x; 813 } 580 } 814 581 815 //....oooOO0OOooo........oooOO0OOooo........oo 582 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 816 583 817 inline void G4VEnergyLossProcess::SetParticle( << 584 inline void G4VEnergyLossProcess::ResetNumberOfInteractionLengthLeft() 818 { 585 { 819 particle = p; << 586 meanFreePath = true; >> 587 G4VProcess::ResetNumberOfInteractionLengthLeft(); 820 } 588 } 821 589 822 //....oooOO0OOooo........oooOO0OOooo........oo << 823 << 824 inline void << 825 G4VEnergyLossProcess::SetSecondaryParticle(con << 826 { << 827 secondaryParticle = p; << 828 } << 829 590 830 //....oooOO0OOooo........oooOO0OOooo........oo 591 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 831 592 832 inline void << 593 inline G4VEmModel* G4VEnergyLossProcess::SelectModel(G4double& kinEnergy) 833 G4VEnergyLossProcess::SetBaseParticle(const G4 << 834 { 594 { 835 baseParticle = p; << 595 return modelManager->SelectModel(kinEnergy, currentMaterialIndex); 836 } 596 } 837 597 838 //....oooOO0OOooo........oooOO0OOooo........oo 598 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 839 599 840 inline const G4ParticleDefinition* G4VEnergyLo 600 inline const G4ParticleDefinition* G4VEnergyLossProcess::Particle() const 841 { 601 { 842 return particle; 602 return particle; 843 } 603 } 844 604 845 //....oooOO0OOooo........oooOO0OOooo........oo 605 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 846 606 847 inline const G4ParticleDefinition* G4VEnergyLo 607 inline const G4ParticleDefinition* G4VEnergyLossProcess::BaseParticle() const 848 { 608 { 849 return baseParticle; 609 return baseParticle; 850 } 610 } 851 611 852 //....oooOO0OOooo........oooOO0OOooo........oo 612 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 853 613 854 inline const G4ParticleDefinition* << 614 inline const G4ParticleDefinition* G4VEnergyLossProcess::SecondaryParticle() const 855 G4VEnergyLossProcess::SecondaryParticle() cons << 856 { 615 { 857 return secondaryParticle; 616 return secondaryParticle; 858 } 617 } 859 618 860 //....oooOO0OOooo........oooOO0OOooo........oo 619 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 861 620 862 inline void G4VEnergyLossProcess::SetLossFluct << 621 inline void G4VEnergyLossProcess::SetDEDXBinning(G4int nbins) 863 { << 864 lossFluctuationFlag = val; << 865 actLossFluc = true; << 866 } << 867 << 868 //....oooOO0OOooo........oooOO0OOooo........oo << 869 << 870 inline void G4VEnergyLossProcess::SetSpline(G4 << 871 { << 872 spline = val; << 873 } << 874 << 875 //....oooOO0OOooo........oooOO0OOooo........oo << 876 << 877 inline void G4VEnergyLossProcess::SetCrossSect << 878 { 622 { 879 fXSType = val; << 623 nDEDXBins = nbins; 880 } 624 } 881 625 882 //....oooOO0OOooo........oooOO0OOooo........oo 626 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 883 << 884 inline G4CrossSectionType G4VEnergyLossProcess << 885 { << 886 return fXSType; << 887 } << 888 627 889 //....oooOO0OOooo........oooOO0OOooo........oo << 628 inline void G4VEnergyLossProcess::SetDEDXBinningForPreciseRange(G4int nbins) 890 << 891 inline G4bool G4VEnergyLossProcess::IsIonisati << 892 { 629 { 893 return isIonisation; << 630 nDEDXBinsForRange = nbins; 894 } 631 } 895 632 896 //....oooOO0OOooo........oooOO0OOooo........oo 633 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 897 634 898 inline G4int G4VEnergyLossProcess::NumberOfSub << 635 inline void G4VEnergyLossProcess::SetLambdaBinning(G4int nbins) 899 { 636 { 900 return nSCoffRegions; << 637 nLambdaBins = nbins; 901 } 638 } 902 639 903 //....oooOO0OOooo........oooOO0OOooo........oo 640 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 904 641 905 inline G4double G4VEnergyLossProcess::MinKinEn 642 inline G4double G4VEnergyLossProcess::MinKinEnergy() const 906 { 643 { 907 return minKinEnergy; 644 return minKinEnergy; 908 } 645 } 909 646 910 //....oooOO0OOooo........oooOO0OOooo........oo 647 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 911 648 912 inline G4double G4VEnergyLossProcess::MaxKinEn << 649 inline void G4VEnergyLossProcess::SetMinKinEnergy(G4double e) 913 { 650 { 914 return maxKinEnergy; << 651 minKinEnergy = e; 915 } 652 } 916 653 917 //....oooOO0OOooo........oooOO0OOooo........oo 654 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 918 655 919 inline G4double G4VEnergyLossProcess::CrossSec << 656 inline void G4VEnergyLossProcess::SetMaxKinEnergy(G4double e) 920 { 657 { 921 return biasFactor; << 658 maxKinEnergy = e; >> 659 if(e < maxKinEnergyForRange) maxKinEnergyForRange = e; 922 } 660 } 923 661 924 //....oooOO0OOooo........oooOO0OOooo........oo 662 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 925 663 926 inline G4bool G4VEnergyLossProcess::TablesAreB << 664 inline void G4VEnergyLossProcess::SetMaxKinEnergyForPreciseRange(G4double e) 927 { 665 { 928 return tablesAreBuilt; << 666 maxKinEnergyForRange = e; 929 } 667 } 930 668 931 //....oooOO0OOooo........oooOO0OOooo........oo 669 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 932 670 933 inline G4PhysicsTable* G4VEnergyLossProcess::D << 671 inline G4double G4VEnergyLossProcess::MaxKinEnergy() const 934 { << 935 return theDEDXTable; << 936 } << 937 << 938 //....oooOO0OOooo........oooOO0OOooo........oo << 939 << 940 inline G4PhysicsTable* G4VEnergyLossProcess::D << 941 { << 942 return theDEDXunRestrictedTable; << 943 } << 944 << 945 //....oooOO0OOooo........oooOO0OOooo........oo << 946 << 947 inline G4PhysicsTable* G4VEnergyLossProcess::I << 948 { << 949 return theIonisationTable; << 950 } << 951 << 952 //....oooOO0OOooo........oooOO0OOooo........oo << 953 << 954 inline G4PhysicsTable* G4VEnergyLossProcess::C << 955 { << 956 return theCSDARangeTable; << 957 } << 958 << 959 //....oooOO0OOooo........oooOO0OOooo........oo << 960 << 961 inline G4PhysicsTable* G4VEnergyLossProcess::R << 962 { << 963 return theRangeTableForLoss; << 964 } << 965 << 966 //....oooOO0OOooo........oooOO0OOooo........oo << 967 << 968 inline G4PhysicsTable* G4VEnergyLossProcess::I << 969 { << 970 return theInverseRangeTable; << 971 } << 972 << 973 //....oooOO0OOooo........oooOO0OOooo........oo << 974 << 975 inline G4PhysicsTable* G4VEnergyLossProcess::L << 976 { << 977 return theLambdaTable; << 978 } << 979 << 980 //....oooOO0OOooo........oooOO0OOooo........oo << 981 << 982 inline G4bool G4VEnergyLossProcess::UseBaseMat << 983 { << 984 return baseMat; << 985 } << 986 << 987 //....oooOO0OOooo........oooOO0OOooo........oo << 988 << 989 inline std::vector<G4double>* << 990 G4VEnergyLossProcess::EnergyOfCrossSectionMax( << 991 { << 992 return theEnergyOfCrossSectionMax; << 993 } << 994 << 995 //....oooOO0OOooo........oooOO0OOooo........oo << 996 << 997 inline std::vector<G4TwoPeaksXS*>* G4VEnergyLo << 998 { << 999 return fXSpeaks; << 1000 } << 1001 << 1002 //....oooOO0OOooo........oooOO0OOooo........o << 1003 << 1004 inline std::size_t G4VEnergyLossProcess::Numb << 1005 { 672 { 1006 return numberOfModels; << 673 return maxKinEnergy; 1007 } 674 } 1008 675 1009 //....oooOO0OOooo........oooOO0OOooo........o 676 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1010 677 1011 inline G4VEmModel* G4VEnergyLossProcess::EmMo << 678 inline G4double G4VEnergyLossProcess::GetLambda(G4double kineticEnergy, >> 679 const G4MaterialCutsCouple* couple) 1012 { 680 { 1013 return (index < emModels->size()) ? (*emMod << 681 DefineMaterial(couple); >> 682 G4double x = DBL_MAX; >> 683 G4bool b; >> 684 if(theLambdaTable) { >> 685 G4double y = (((*theLambdaTable)[currentMaterialIndex])-> >> 686 GetValue(kineticEnergy*massRatio, b)); >> 687 if(y > 0.0) x = 1.0/y; >> 688 } >> 689 return x; 1014 } 690 } 1015 691 1016 //....oooOO0OOooo........oooOO0OOooo........o 692 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1017 693 1018 inline G4VEmModel* << 694 inline G4VSubCutoffProcessor* G4VEnergyLossProcess::SubCutoffProcessor(size_t index) 1019 G4VEnergyLossProcess::GetModelByIndex(std::si << 1020 { 695 { 1021 return modelManager->GetModel((G4int)idx, v << 696 G4VSubCutoffProcessor* p = 0; >> 697 if( nSCoffRegions ) p = scoffProcessors[idxSCoffRegions[index]]; >> 698 return p; 1022 } 699 } 1023 700 1024 //....oooOO0OOooo........oooOO0OOooo........o 701 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1025 702 1026 #endif 703 #endif 1027 704