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