Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id: G4VMultipleScattering.cc 90579 2015-06-04 10:00:26Z gcosmo $ 26 // 27 // 27 // ------------------------------------------- 28 // ------------------------------------------------------------------- 28 // 29 // 29 // GEANT4 Class file 30 // GEANT4 Class file 30 // 31 // 31 // 32 // 32 // File name: G4VMultipleScattering 33 // File name: G4VMultipleScattering 33 // 34 // 34 // Author: Vladimir Ivanchenko on base 35 // Author: Vladimir Ivanchenko on base of Laszlo Urban code 35 // 36 // 36 // Creation date: 25.03.2003 37 // Creation date: 25.03.2003 37 // 38 // 38 // Modifications: 39 // Modifications: 39 // 40 // >> 41 // 13.04.03 Change printout (V.Ivanchenko) >> 42 // 04-06-03 Fix compilation warnings (V.Ivanchenko) 40 // 16-07-03 Use G4VMscModel interface (V.Ivanc 43 // 16-07-03 Use G4VMscModel interface (V.Ivanchenko) 41 // 03-11-03 Fix initialisation problem in Retr 44 // 03-11-03 Fix initialisation problem in RetrievePhysicsTable (V.Ivanchenko) 42 // 04-11-03 Update PrintInfoDefinition (V.Ivan 45 // 04-11-03 Update PrintInfoDefinition (V.Ivanchenko) 43 // 01-03-04 SampleCosineTheta signature change 46 // 01-03-04 SampleCosineTheta signature changed 44 // 22-04-04 SampleCosineTheta signature change 47 // 22-04-04 SampleCosineTheta signature changed back to original 45 // 27-08-04 Add InitialiseForRun method (V.Iva 48 // 27-08-04 Add InitialiseForRun method (V.Ivanchneko) 46 // 08-11-04 Migration to new interface of Stor 49 // 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko) 47 // 11-03-05 Shift verbose level by 1 (V.Ivantc 50 // 11-03-05 Shift verbose level by 1 (V.Ivantchenko) 48 // 15-04-05 optimize internal interface (V.Iva 51 // 15-04-05 optimize internal interface (V.Ivanchenko) 49 // 15-04-05 remove boundary flag (V.Ivanchenko 52 // 15-04-05 remove boundary flag (V.Ivanchenko) 50 // 27-10-05 introduce virtual function MscStep 53 // 27-10-05 introduce virtual function MscStepLimitation() (V.Ivanchenko) 51 // 12-04-07 Add verbosity at destruction (V.Iv 54 // 12-04-07 Add verbosity at destruction (V.Ivanchenko) 52 // 27-10-07 Virtual functions moved to source 55 // 27-10-07 Virtual functions moved to source (V.Ivanchenko) 53 // 11-03-08 Set skin value does not effect ste 56 // 11-03-08 Set skin value does not effect step limit type (V.Ivanchenko) 54 // 24-06-09 Removed hidden bin in G4PhysicsVec 57 // 24-06-09 Removed hidden bin in G4PhysicsVector (V.Ivanchenko) 55 // 04-06-13 Adoptation to MT mode (V.Ivanchenk 58 // 04-06-13 Adoptation to MT mode (V.Ivanchenko) 56 // 59 // >> 60 // Class Description: >> 61 // >> 62 // It is the generic process of multiple scattering it includes common >> 63 // part of calculations for all charged particles 57 64 58 // ------------------------------------------- 65 // ------------------------------------------------------------------- 59 // 66 // 60 //....oooOO0OOooo........oooOO0OOooo........oo 67 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 61 //....oooOO0OOooo........oooOO0OOooo........oo 68 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 62 69 63 #include "G4VMultipleScattering.hh" 70 #include "G4VMultipleScattering.hh" 64 #include "G4PhysicalConstants.hh" 71 #include "G4PhysicalConstants.hh" 65 #include "G4SystemOfUnits.hh" 72 #include "G4SystemOfUnits.hh" 66 #include "G4LossTableManager.hh" 73 #include "G4LossTableManager.hh" 67 #include "G4MaterialCutsCouple.hh" 74 #include "G4MaterialCutsCouple.hh" 68 #include "G4Step.hh" 75 #include "G4Step.hh" 69 #include "G4ParticleDefinition.hh" 76 #include "G4ParticleDefinition.hh" 70 #include "G4VEmFluctuationModel.hh" 77 #include "G4VEmFluctuationModel.hh" 71 #include "G4UnitsTable.hh" 78 #include "G4UnitsTable.hh" 72 #include "G4ProductionCutsTable.hh" 79 #include "G4ProductionCutsTable.hh" 73 #include "G4Electron.hh" 80 #include "G4Electron.hh" 74 #include "G4GenericIon.hh" 81 #include "G4GenericIon.hh" 75 #include "G4TransportationManager.hh" 82 #include "G4TransportationManager.hh" 76 #include "G4SafetyHelper.hh" 83 #include "G4SafetyHelper.hh" 77 #include "G4ParticleTable.hh" 84 #include "G4ParticleTable.hh" 78 #include "G4ProcessVector.hh" 85 #include "G4ProcessVector.hh" 79 #include "G4ProcessManager.hh" 86 #include "G4ProcessManager.hh" 80 #include "G4LossTableBuilder.hh" << 81 #include "G4EmTableUtil.hh" << 82 #include <iostream> << 83 87 84 //....oooOO0OOooo........oooOO0OOooo........oo 88 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 85 89 86 G4VMultipleScattering::G4VMultipleScattering(c << 90 static const G4double minSafety = 1.20*CLHEP::nm; 87 : G4VContinuousDiscreteProcess("msc", fElect << 91 static const G4double geomMin = 0.05*CLHEP::nm; >> 92 static const G4double minDisplacement2 = geomMin*geomMin; >> 93 >> 94 G4VMultipleScattering::G4VMultipleScattering(const G4String& name, >> 95 G4ProcessType): >> 96 G4VContinuousDiscreteProcess("msc", fElectromagnetic), >> 97 numberOfModels(0), >> 98 firstParticle(0), >> 99 currParticle(0), >> 100 stepLimit(fUseSafety), >> 101 facrange(0.04), >> 102 latDisplacement(true), >> 103 isIon(false), 88 fNewPosition(0.,0.,0.), 104 fNewPosition(0.,0.,0.), 89 fNewDirection(0.,0.,1.) << 105 fNewDirection(0.,0.,1.), >> 106 fDispBeyondSafety(false) 90 { 107 { 91 theParameters = G4EmParameters::Instance(); 108 theParameters = G4EmParameters::Instance(); 92 SetVerboseLevel(1); 109 SetVerboseLevel(1); 93 SetProcessSubType(fMultipleScattering); 110 SetProcessSubType(fMultipleScattering); >> 111 if("ionmsc" == name) { firstParticle = G4GenericIon::GenericIon(); } 94 112 95 lowestKinEnergy = 10*CLHEP::eV; 113 lowestKinEnergy = 10*CLHEP::eV; 96 114 97 geomMin = 0.05*CLHEP::nm; << 115 physStepLimit = gPathLength = tPathLength = 0.0; 98 minDisplacement2 = geomMin*geomMin; << 116 fIonisation = 0; 99 117 100 pParticleChange = &fParticleChange; 118 pParticleChange = &fParticleChange; 101 << 119 safetyHelper = 0; >> 120 fPositionChanged = false; >> 121 isActive = false; >> 122 actStepLimit = false; >> 123 actFacRange = false; >> 124 actLatDisp = false; >> 125 >> 126 currentModel = 0; 102 modelManager = new G4EmModelManager(); 127 modelManager = new G4EmModelManager(); 103 emManager = G4LossTableManager::Instance(); 128 emManager = G4LossTableManager::Instance(); 104 mscModels.reserve(2); << 105 emManager->Register(this); 129 emManager->Register(this); 106 } 130 } 107 131 108 //....oooOO0OOooo........oooOO0OOooo........oo 132 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 109 133 110 G4VMultipleScattering::~G4VMultipleScattering( 134 G4VMultipleScattering::~G4VMultipleScattering() 111 { 135 { >> 136 /* >> 137 if(1 < verboseLevel) { >> 138 G4cout << "G4VMultipleScattering destruct " << GetProcessName() >> 139 << G4endl; >> 140 } >> 141 */ 112 delete modelManager; 142 delete modelManager; 113 emManager->DeRegister(this); 143 emManager->DeRegister(this); 114 } 144 } 115 145 116 //....oooOO0OOooo........oooOO0OOooo........oo 146 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 117 147 118 void G4VMultipleScattering::AddEmModel(G4int o << 148 void G4VMultipleScattering::AddEmModel(G4int order, G4VEmModel* p, 119 const G << 149 const G4Region* region) 120 { 150 { 121 if(nullptr == ptr) { return; } << 151 G4VEmFluctuationModel* fm = 0; 122 G4VEmFluctuationModel* fm = nullptr; << 152 modelManager->AddEmModel(order, p, fm, region); 123 modelManager->AddEmModel(order, ptr, fm, reg << 153 if(p) { p->SetParticleChange(pParticleChange); } 124 ptr->SetParticleChange(pParticleChange); << 125 } 154 } 126 155 127 //....oooOO0OOooo........oooOO0OOooo........oo 156 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 128 157 129 void G4VMultipleScattering::SetEmModel(G4VMscM << 158 void G4VMultipleScattering::SetEmModel(G4VMscModel* p, G4int index) 130 { 159 { 131 if(nullptr == ptr) { return; } << 160 G4int n = mscModels.size(); 132 if(!mscModels.empty()) { << 161 if(index >= n) { for(G4int i=n; i<=index; ++i) { mscModels.push_back(0); } } 133 for(auto & msc : mscModels) { if(msc == pt << 162 mscModels[index] = p; 134 } << 163 } 135 mscModels.push_back(ptr); << 164 >> 165 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 166 >> 167 G4VMscModel* G4VMultipleScattering::EmModel(G4int index) const >> 168 { >> 169 G4VMscModel* p = 0; >> 170 if(index >= 0 && index < G4int(mscModels.size())) { p = mscModels[index]; } >> 171 return p; >> 172 } >> 173 >> 174 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 175 >> 176 G4VEmModel* >> 177 G4VMultipleScattering::GetModelByIndex(G4int idx, G4bool ver) const >> 178 { >> 179 return modelManager->GetModel(idx, ver); 136 } 180 } 137 181 138 //....oooOO0OOooo........oooOO0OOooo........oo 182 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 139 183 140 void 184 void 141 G4VMultipleScattering::PreparePhysicsTable(con 185 G4VMultipleScattering::PreparePhysicsTable(const G4ParticleDefinition& part) 142 { 186 { 143 G4bool master = emManager->IsMaster(); << 187 G4bool master = true; 144 if (nullptr == firstParticle) { firstParticl << 188 const G4VMultipleScattering* masterProc = >> 189 static_cast<const G4VMultipleScattering*>(GetMasterProcess()); >> 190 if(masterProc && masterProc != this) { master = false; } >> 191 >> 192 if(!firstParticle) { firstParticle = ∂ } >> 193 if(part.GetParticleType() == "nucleus") { >> 194 SetStepLimitType(fMinimal); >> 195 SetLateralDisplasmentFlag(false); >> 196 SetRangeFactor(0.2); >> 197 G4String pname = part.GetParticleName(); >> 198 if(pname != "deuteron" && pname != "triton" && >> 199 pname != "alpha+" && pname != "helium" && >> 200 pname != "alpha" && pname != "He3" && >> 201 pname != "hydrogen") { >> 202 >> 203 const G4ParticleDefinition* theGenericIon = >> 204 G4ParticleTable::GetParticleTable()->FindParticle("GenericIon"); >> 205 >> 206 if(theGenericIon && firstParticle != theGenericIon) { >> 207 G4ProcessManager* pm = theGenericIon->GetProcessManager(); >> 208 G4ProcessVector* v = pm->GetAlongStepProcessVector(); >> 209 size_t n = v->size(); >> 210 for(size_t j=0; j<n; ++j) { >> 211 if((*v)[j] == this) { >> 212 firstParticle = theGenericIon; >> 213 isIon = true; >> 214 break; >> 215 } >> 216 } >> 217 } >> 218 } >> 219 } 145 220 146 emManager->PreparePhysicsTable(&part, this); << 221 emManager->PreparePhysicsTable(&part, this, master); 147 currParticle = nullptr; << 222 currParticle = 0; >> 223 >> 224 if(1 < verboseLevel) { >> 225 G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for " >> 226 << GetProcessName() >> 227 << " and particle " << part.GetParticleName() >> 228 << " local particle " << firstParticle->GetParticleName() >> 229 << " isIon= " << isIon >> 230 << G4endl; >> 231 } 148 232 149 if(firstParticle == &part) { 233 if(firstParticle == &part) { 150 baseMat = emManager->GetTableBuilder()->Ge << 151 G4EmTableUtil::PrepareMscProcess(this, par << 152 stepLimit, facrange, << 153 latDisplacement, master, << 154 isIon, baseMat); << 155 234 >> 235 // initialise process >> 236 InitialiseProcess(firstParticle); >> 237 if(part.GetPDGMass() > MeV) { >> 238 if(!actStepLimit) { stepLimit = fMinimal; } >> 239 if(!actFacRange) { facrange = 0.2; } >> 240 if(!actLatDisp) { >> 241 latDisplacement = theParameters->MuHadLateralDisplacement(); >> 242 } >> 243 } else { >> 244 if(!actStepLimit) { stepLimit = theParameters->MscStepLimitType(); } >> 245 if(!actFacRange) { facrange = theParameters->MscRangeFactor(); } >> 246 if(!actLatDisp) { >> 247 latDisplacement = theParameters->LateralDisplacement(); >> 248 } >> 249 } >> 250 if(latDisplacement) { >> 251 fDispBeyondSafety = theParameters->LatDisplacementBeyondSafety(); >> 252 } >> 253 if(master) { SetVerboseLevel(theParameters->Verbose()); } >> 254 else { SetVerboseLevel(theParameters->WorkerVerbose()); } >> 255 >> 256 // initialisation of models 156 numberOfModels = modelManager->NumberOfMod 257 numberOfModels = modelManager->NumberOfModels(); 157 currentModel = GetModelByIndex(0); << 258 for(G4int i=0; i<numberOfModels; ++i) { >> 259 G4VMscModel* msc = static_cast<G4VMscModel*>(modelManager->GetModel(i)); >> 260 msc->SetIonisation(0, firstParticle); >> 261 msc->SetMasterThread(master); >> 262 if(0 == i) { currentModel = msc; } >> 263 msc->SetStepLimitType(stepLimit); >> 264 msc->SetLateralDisplasmentFlag(latDisplacement); >> 265 msc->SetSkin(theParameters->MscSkin()); >> 266 msc->SetRangeFactor(facrange); >> 267 msc->SetGeomFactor(theParameters->MscGeomFactor()); >> 268 msc->SetPolarAngleLimit(theParameters->MscThetaLimit()); >> 269 G4double emax = >> 270 std::min(msc->HighEnergyLimit(),theParameters->MaxKinEnergy()); >> 271 msc->SetHighEnergyLimit(emax); >> 272 } 158 273 159 if (nullptr == safetyHelper) { << 274 modelManager->Initialise(firstParticle, G4Electron::Electron(), >> 275 10.0, verboseLevel); >> 276 >> 277 if(!safetyHelper) { 160 safetyHelper = G4TransportationManager:: 278 safetyHelper = G4TransportationManager::GetTransportationManager() 161 ->GetSafetyHelper(); 279 ->GetSafetyHelper(); 162 safetyHelper->InitialiseHelper(); 280 safetyHelper->InitialiseHelper(); 163 } 281 } 164 } 282 } 165 } 283 } 166 284 167 //....oooOO0OOooo........oooOO0OOooo........oo 285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 168 286 169 void G4VMultipleScattering::BuildPhysicsTable( 287 void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part) 170 { 288 { 171 G4bool master = emManager->IsMaster(); << 289 G4String num = part.GetParticleName(); 172 << 290 if(1 < verboseLevel) { 173 if(firstParticle == &part) { << 291 G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for " 174 emManager->BuildPhysicsTable(&part); << 292 << GetProcessName() >> 293 << " and particle " << num >> 294 << " IsMaster= " << G4LossTableManager::Instance()->IsMaster() >> 295 << G4endl; 175 } 296 } 176 const G4VMultipleScattering* ptr = this; << 297 G4bool master = true; 177 if(!master) { << 298 const G4VMultipleScattering* masterProcess = 178 ptr = static_cast<const G4VMultipleScatter << 299 static_cast<const G4VMultipleScattering*>(GetMasterProcess()); >> 300 if(masterProcess && masterProcess != this) { master = false; } >> 301 >> 302 if(firstParticle == &part) { >> 303 /* >> 304 G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for " >> 305 << GetProcessName() >> 306 << " and particle " << num >> 307 << " IsMaster= " << G4LossTableManager::Instance()->IsMaster() >> 308 << " " << this >> 309 << G4endl; >> 310 */ >> 311 emManager->BuildPhysicsTable(firstParticle); >> 312 >> 313 if(!master) { >> 314 // initialisation of models >> 315 G4bool printing = true; >> 316 numberOfModels = modelManager->NumberOfModels(); >> 317 /* >> 318 G4cout << "### G4VMultipleScattering::SlaveBuildPhysicsTable() for " >> 319 << GetProcessName() >> 320 << " and particle " << num >> 321 << " Nmod= " << numberOfModels << " " << this >> 322 << G4endl; >> 323 */ >> 324 for(G4int i=0; i<numberOfModels; ++i) { >> 325 G4VMscModel* msc = >> 326 static_cast<G4VMscModel*>(GetModelByIndex(i, printing)); >> 327 G4VMscModel* msc0= >> 328 static_cast<G4VMscModel*>(masterProcess->GetModelByIndex(i,printing)); >> 329 msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false); >> 330 msc->InitialiseLocal(firstParticle, msc0); >> 331 } >> 332 } 179 } 333 } 180 334 181 G4EmTableUtil::BuildMscProcess(this, ptr, pa << 335 // explicitly defined printout by particle name 182 numberOfModels, master); << 336 if(1 < verboseLevel || >> 337 (0 < verboseLevel && (num == "e-" || >> 338 num == "e+" || num == "mu+" || >> 339 num == "mu-" || num == "proton"|| >> 340 num == "pi+" || num == "pi-" || >> 341 num == "kaon+" || num == "kaon-" || >> 342 num == "alpha" || num == "anti_proton" || >> 343 num == "GenericIon"))) >> 344 { >> 345 G4cout << G4endl << GetProcessName() >> 346 << ": for " << num >> 347 << " SubType= " << GetProcessSubType() >> 348 << G4endl; >> 349 PrintInfo(); >> 350 modelManager->DumpModelList(verboseLevel); >> 351 } >> 352 >> 353 if(1 < verboseLevel) { >> 354 G4cout << "### G4VMultipleScattering::BuildPhysicsTable() done for " >> 355 << GetProcessName() >> 356 << " and particle " << num >> 357 << G4endl; >> 358 } 183 } 359 } 184 360 185 //....oooOO0OOooo........oooOO0OOooo........oo 361 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 186 362 187 void G4VMultipleScattering::StreamInfo(std::os << 363 void G4VMultipleScattering::PrintInfoDefinition() 188 const G4ParticleDefinition& << 189 { 364 { 190 G4String indent = (rst ? " " : ""); << 365 if (0 < verboseLevel) { 191 outFile << G4endl << indent << GetProcessNam << 366 G4cout << G4endl << GetProcessName() 192 if (!rst) outFile << " for " << part.GetPart << 367 << ": for " << firstParticle->GetParticleName() 193 outFile << " SubType= " << GetProcessSubTy << 368 << " SubType= " << GetProcessSubType() 194 modelManager->DumpModelList(outFile, verbose << 369 << G4endl; >> 370 PrintInfo(); >> 371 modelManager->DumpModelList(verboseLevel); >> 372 } 195 } 373 } 196 374 197 //....oooOO0OOooo........oooOO0OOooo........oo 375 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 198 376 199 void G4VMultipleScattering::StartTracking(G4Tr 377 void G4VMultipleScattering::StartTracking(G4Track* track) 200 { 378 { 201 G4VEnergyLossProcess* eloss = nullptr; << 379 G4VEnergyLossProcess* eloss = 0; 202 if(track->GetParticleDefinition() != currPar 380 if(track->GetParticleDefinition() != currParticle) { 203 currParticle = track->GetParticleDefinitio 381 currParticle = track->GetParticleDefinition(); 204 fIonisation = emManager->GetEnergyLossProc 382 fIonisation = emManager->GetEnergyLossProcess(currParticle); 205 eloss = fIonisation; 383 eloss = fIonisation; 206 } 384 } 207 for(G4int i=0; i<numberOfModels; ++i) { << 385 /* 208 G4VMscModel* msc = GetModelByIndex(i); << 386 G4cout << "G4VMultipleScattering::StartTracking Nmod= " << numberOfModels 209 msc->StartTracking(track); << 387 << " " << currParticle->GetParticleName() 210 if(nullptr != eloss) { << 388 << " E(MeV)= " << track->GetKineticEnergy() 211 msc->SetIonisation(eloss, currParticle); << 389 << " Ion= " << eloss << " " << fIonisation << " IsMaster= " >> 390 << G4LossTableManager::Instance()->IsMaster() >> 391 << G4endl; >> 392 */ >> 393 // one model >> 394 if(1 == numberOfModels) { >> 395 currentModel->StartTracking(track); >> 396 if(eloss) { currentModel->SetIonisation(fIonisation, currParticle); } >> 397 >> 398 // many models >> 399 } else { >> 400 for(G4int i=0; i<numberOfModels; ++i) { >> 401 G4VMscModel* msc = static_cast<G4VMscModel*>(GetModelByIndex(i,true)); >> 402 msc->StartTracking(track); >> 403 if(eloss) { msc->SetIonisation(fIonisation, currParticle); } 212 } 404 } 213 } 405 } 214 } << 406 } 215 407 216 //....oooOO0OOooo........oooOO0OOooo........oo 408 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 217 409 218 G4double G4VMultipleScattering::AlongStepGetPh 410 G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength( 219 const G4Track& tr 411 const G4Track& track, 220 G4double, 412 G4double, 221 G4double currentM 413 G4double currentMinimalStep, 222 G4double&, 414 G4double&, 223 G4GPILSelection* 415 G4GPILSelection* selection) 224 { 416 { 225 // get Step limit proposed by the process 417 // get Step limit proposed by the process 226 *selection = NotCandidateForSelection; 418 *selection = NotCandidateForSelection; 227 physStepLimit = gPathLength = tPathLength = 419 physStepLimit = gPathLength = tPathLength = currentMinimalStep; 228 420 229 G4double ekin = track.GetKineticEnergy(); 421 G4double ekin = track.GetKineticEnergy(); 230 /* 422 /* 231 G4cout << "MSC::AlongStepGPIL: Ekin= " << ek 423 G4cout << "MSC::AlongStepGPIL: Ekin= " << ekin 232 << " " << currParticle->GetParticleN 424 << " " << currParticle->GetParticleName() 233 << " currMod " << currentModel << 425 << " currMod " << currentModel 234 << G4endl; << 426 << G4endl; 235 */ 427 */ 236 // isIon flag is used only to select a model 428 // isIon flag is used only to select a model 237 if(isIon) { 429 if(isIon) { 238 ekin *= proton_mass_c2/track.GetParticleDe 430 ekin *= proton_mass_c2/track.GetParticleDefinition()->GetPDGMass(); 239 } 431 } 240 const G4MaterialCutsCouple* couple = track.G << 241 432 242 // select new model, static cast is possible << 433 // select new model 243 if(1 < numberOfModels) { 434 if(1 < numberOfModels) { 244 currentModel = << 435 currentModel = static_cast<G4VMscModel*>( 245 static_cast<G4VMscModel*>(SelectModel(ek << 436 SelectModel(ekin,track.GetMaterialCutsCouple()->GetIndex())); 246 } 437 } 247 currentModel->SetCurrentCouple(couple); << 248 // msc is active is model is active, energy 438 // msc is active is model is active, energy above the limit, 249 // and step size is above the limit; 439 // and step size is above the limit; 250 // if it is active msc may limit the step 440 // if it is active msc may limit the step 251 if(currentModel->IsActive(ekin) && tPathLeng 441 if(currentModel->IsActive(ekin) && tPathLength > geomMin 252 && ekin >= lowestKinEnergy) { 442 && ekin >= lowestKinEnergy) { 253 isActive = true; 443 isActive = true; 254 tPathLength = 444 tPathLength = 255 currentModel->ComputeTruePathLengthLimit 445 currentModel->ComputeTruePathLengthLimit(track, gPathLength); 256 if (tPathLength < physStepLimit) { 446 if (tPathLength < physStepLimit) { 257 *selection = CandidateForSelection; 447 *selection = CandidateForSelection; 258 } 448 } 259 } else { << 449 } else { isActive = false; } 260 isActive = false; << 261 gPathLength = DBL_MAX; << 262 } << 263 450 264 //if(currParticle->GetPDGMass() > GeV) 451 //if(currParticle->GetPDGMass() > GeV) 265 /* 452 /* 266 G4cout << "MSC::AlongStepGPIL: Ekin= " << ek 453 G4cout << "MSC::AlongStepGPIL: Ekin= " << ekin 267 << " " << currParticle->GetParticleN 454 << " " << currParticle->GetParticleName() 268 << " gPathLength= " << gPathLength << 455 << " gPathLength= " << gPathLength 269 << " tPathLength= " << tPathLength << 456 << " tPathLength= " << tPathLength 270 << " currentMinimalStep= " << current << 457 << " currentMinimalStep= " << currentMinimalStep 271 << " isActive " << isActive << G4endl << 458 << " isActive " << isActive << G4endl; 272 */ 459 */ 273 return gPathLength; 460 return gPathLength; 274 } 461 } 275 462 276 //....oooOO0OOooo........oooOO0OOooo........oo 463 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 277 464 278 G4double 465 G4double 279 G4VMultipleScattering::PostStepGetPhysicalInte 466 G4VMultipleScattering::PostStepGetPhysicalInteractionLength( 280 const G4Track&, G4double, G4Forc 467 const G4Track&, G4double, G4ForceCondition* condition) 281 { 468 { 282 *condition = NotForced; << 469 *condition = Forced; >> 470 //*condition = NotForced; 283 return DBL_MAX; 471 return DBL_MAX; 284 } 472 } 285 473 286 //....oooOO0OOooo........oooOO0OOooo........oo 474 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 287 475 288 G4VParticleChange* 476 G4VParticleChange* 289 G4VMultipleScattering::AlongStepDoIt(const G4T 477 G4VMultipleScattering::AlongStepDoIt(const G4Track& track, const G4Step& step) 290 { 478 { 291 fParticleChange.InitialiseMSC(track, step); << 479 fParticleChange.ProposeMomentumDirection( 292 fNewPosition = fParticleChange.GetProposedPo << 480 step.GetPostStepPoint()->GetMomentumDirection()); >> 481 fNewPosition = step.GetPostStepPoint()->GetPosition(); >> 482 fParticleChange.ProposePosition(fNewPosition); 293 fPositionChanged = false; 483 fPositionChanged = false; 294 484 295 G4double geomLength = step.GetStepLength(); 485 G4double geomLength = step.GetStepLength(); 296 486 297 // very small step - no msc 487 // very small step - no msc 298 if(!isActive) { 488 if(!isActive) { 299 tPathLength = geomLength; 489 tPathLength = geomLength; 300 490 301 // sample msc 491 // sample msc 302 } else { 492 } else { 303 G4double range = 493 G4double range = 304 currentModel->GetRange(currParticle,trac 494 currentModel->GetRange(currParticle,track.GetKineticEnergy(), 305 track.GetMaterial << 495 track.GetMaterialCutsCouple()); 306 496 307 tPathLength = currentModel->ComputeTrueSte 497 tPathLength = currentModel->ComputeTrueStepLength(geomLength); 308 498 >> 499 // protection against wrong t->g->t conversion 309 /* 500 /* 310 if(currParticle->GetPDGMass() > 0.9*GeV) 501 if(currParticle->GetPDGMass() > 0.9*GeV) 311 G4cout << "G4VMsc::AlongStepDoIt: GeomLeng 502 G4cout << "G4VMsc::AlongStepDoIt: GeomLength= " 312 << geomLength << 503 << geomLength 313 << " tPathLength= " << tPathLength << 504 << " tPathLength= " << tPathLength 314 << " physStepLimit= " << physStepLi << 505 << " physStepLimit= " << physStepLimit 315 << " dr= " << range - tPathLength << 506 << " dr= " << range - tPathLength 316 << " ekin= " << track.GetKineticEne << 507 << " ekin= " << track.GetKineticEnergy() << G4endl; 317 */ 508 */ 318 // protection against wrong t->g->t conver << 319 tPathLength = std::min(tPathLength, physSt 509 tPathLength = std::min(tPathLength, physStepLimit); 320 510 321 // do not sample scattering at the last or 511 // do not sample scattering at the last or at a small step 322 if(tPathLength < range && tPathLength > ge 512 if(tPathLength < range && tPathLength > geomMin) { 323 513 324 static const G4double minSafety = 1.20*C << 325 static const G4double sFact = 0.99; << 326 << 327 G4ThreeVector displacement = currentMode 514 G4ThreeVector displacement = currentModel->SampleScattering( 328 step.GetPostStepPoint()->GetMomentumDi << 515 step.GetPostStepPoint()->GetMomentumDirection(),minSafety); 329 516 330 G4double r2 = displacement.mag2(); 517 G4double r2 = displacement.mag2(); 331 //G4cout << " R= " << sqrt(r2) << " R 518 //G4cout << " R= " << sqrt(r2) << " Rmin= " << sqrt(minDisplacement2) 332 // << " flag= " << fDispBeyondSafety 519 // << " flag= " << fDispBeyondSafety << G4endl; 333 if(r2 > minDisplacement2) { 520 if(r2 > minDisplacement2) { 334 521 335 fPositionChanged = true; << 522 fPositionChanged = true; 336 G4double dispR = std::sqrt(r2); << 523 const G4double sFact = 0.99; 337 G4double postSafety = << 524 G4double postSafety = 338 sFact*safetyHelper->ComputeSafety(fN << 525 sFact*(step.GetPreStepPoint()->GetSafety() - geomLength); 339 //G4cout<<" R= "<< dispR<<" postSaf << 526 //G4cout<<" R= "<<sqrt(r2)<<" postSafety= "<<postSafety<<G4endl; 340 << 527 341 // far away from geometry boundary << 528 // far away from geometry boundary 342 if(postSafety > 0.0 && dispR <= postSa << 529 if(postSafety > 0.0 && r2 <= postSafety*postSafety) { 343 fNewPosition += displacement; << 530 fNewPosition += displacement; 344 << 531 345 //near the boundary << 532 } else { 346 } else { << 533 G4double dispR = std::sqrt(r2); 347 // displaced point is definitely wit << 534 postSafety = 348 //G4cout<<" R= "<<dispR<<" postSa << 535 sFact*safetyHelper->ComputeSafety(fNewPosition, dispR); 349 if(dispR < postSafety) { << 536 350 fNewPosition += displacement; << 537 // displaced point is definitely within the volume 351 << 538 //G4cout<<" R= "<<dispR<<" postSafety= "<<postSafety<<G4endl; 352 // reduced displacement << 539 if(dispR < postSafety) { 353 } else if(postSafety > geomMin) { << 540 fNewPosition += displacement; 354 fNewPosition += displacement*(post << 541 355 << 542 // optional extra mechanism is applied only if a particle 356 // very small postSafety << 543 // is stopped by the boundary 357 } else { << 544 } else if(fDispBeyondSafety && 0.0 == postSafety) { 358 fPositionChanged = false; << 545 fNewPosition += displacement; 359 } << 546 G4double maxshift = 360 } << 547 std::min(2.0*dispR, physStepLimit-tPathLength); 361 if(fPositionChanged) { << 548 G4double dist = 0.0; 362 safetyHelper->ReLocateWithinVolume(f << 549 G4double safety = postSafety + dispR; 363 fParticleChange.ProposePosition(fNew << 550 fNewDirection = *(fParticleChange.GetMomentumDirection()); 364 } << 551 /* >> 552 G4cout << "##MSC before Recheck maxshift= " << maxshift >> 553 << " postsafety= " << postSafety >> 554 << " Ekin= " << track.GetKineticEnergy() >> 555 << " " << track.GetDefinition()->GetParticleName() >> 556 << G4endl; >> 557 */ >> 558 // check if it is possible to shift to the boundary >> 559 if(safetyHelper->RecheckDistanceToCurrentBoundary(fNewPosition, >> 560 fNewDirection, >> 561 maxshift, >> 562 &dist, >> 563 &safety)) >> 564 { >> 565 /* >> 566 G4cout << "##MSC after Recheck dist= " << dist >> 567 << " postsafety= " << postSafety >> 568 << " t= " << tPathLength >> 569 << " g= " << geomLength >> 570 << " p= " << physStepLimit >> 571 << G4endl; >> 572 */ >> 573 G4double tnew = tPathLength*(1.0 + dist/geomLength); >> 574 if(tnew >= 0.0 && tnew < physStepLimit) { >> 575 tPathLength = tnew; >> 576 fNewPosition += dist*fNewDirection; >> 577 } else { >> 578 fNewPosition += displacement*(postSafety/dispR - 1.0); >> 579 } >> 580 } >> 581 else >> 582 // shift on boundary is not possible >> 583 { >> 584 fNewPosition += displacement*(postSafety/dispR - 1.0); >> 585 } >> 586 // reduced displacement >> 587 } else if(postSafety > geomMin) { >> 588 fNewPosition += displacement*(postSafety/dispR); >> 589 >> 590 // very small postSafety >> 591 } else { >> 592 fPositionChanged = false; >> 593 } >> 594 } >> 595 //safetyHelper->ReLocateWithinVolume(fNewPosition); 365 } 596 } 366 } 597 } 367 } 598 } 368 fParticleChange.ProposeTrueStepLength(tPathL 599 fParticleChange.ProposeTrueStepLength(tPathLength); >> 600 //fParticleChange.ProposePosition(fNewPosition); >> 601 return &fParticleChange; >> 602 } >> 603 >> 604 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 605 >> 606 G4VParticleChange* >> 607 G4VMultipleScattering::PostStepDoIt(const G4Track& track, const G4Step&) >> 608 { >> 609 fParticleChange.Initialize(track); >> 610 >> 611 if(fPositionChanged) { >> 612 safetyHelper->ReLocateWithinVolume(fNewPosition); >> 613 fParticleChange.ProposePosition(fNewPosition); >> 614 } >> 615 369 return &fParticleChange; 616 return &fParticleChange; 370 } 617 } 371 618 372 //....oooOO0OOooo........oooOO0OOooo........oo 619 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 373 620 374 G4double G4VMultipleScattering::GetContinuousS 621 G4double G4VMultipleScattering::GetContinuousStepLimit( 375 const G 622 const G4Track& track, 376 G4doubl 623 G4double previousStepSize, 377 G4doubl 624 G4double currentMinimalStep, 378 G4doubl 625 G4double& currentSafety) 379 { 626 { 380 G4GPILSelection selection = NotCandidateForS 627 G4GPILSelection selection = NotCandidateForSelection; 381 G4double x = AlongStepGetPhysicalInteraction 628 G4double x = AlongStepGetPhysicalInteractionLength(track,previousStepSize, 382 << 629 currentMinimalStep, 383 << 630 currentSafety, 384 << 631 &selection); 385 return x; 632 return x; 386 } 633 } 387 634 388 //....oooOO0OOooo........oooOO0OOooo........oo 635 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 389 636 390 G4double G4VMultipleScattering::ContinuousStep 637 G4double G4VMultipleScattering::ContinuousStepLimit( 391 const G 638 const G4Track& track, 392 G4doubl 639 G4double previousStepSize, 393 G4doubl 640 G4double currentMinimalStep, 394 G4doubl 641 G4double& currentSafety) 395 { 642 { 396 return GetContinuousStepLimit(track,previous 643 return GetContinuousStepLimit(track,previousStepSize,currentMinimalStep, 397 currentSafety) << 644 currentSafety); 398 } 645 } 399 646 400 //....oooOO0OOooo........oooOO0OOooo........oo 647 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 401 648 402 G4double G4VMultipleScattering::GetMeanFreePat 649 G4double G4VMultipleScattering::GetMeanFreePath( 403 const G4Track&, G4double, G4Forc 650 const G4Track&, G4double, G4ForceCondition* condition) 404 { 651 { 405 *condition = Forced; 652 *condition = Forced; 406 return DBL_MAX; 653 return DBL_MAX; 407 } 654 } 408 655 409 //....oooOO0OOooo........oooOO0OOooo........oo 656 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 410 657 411 G4bool 658 G4bool 412 G4VMultipleScattering::StorePhysicsTable(const 659 G4VMultipleScattering::StorePhysicsTable(const G4ParticleDefinition* part, 413 const << 660 const G4String& directory, 414 G4boo << 661 G4bool ascii) 415 { 662 { 416 G4bool yes = true; 663 G4bool yes = true; 417 if(part != firstParticle || !emManager->IsMa << 664 if(part != firstParticle) { return yes; } 418 << 665 const G4VMultipleScattering* masterProcess = 419 return G4EmTableUtil::StoreMscTable(this, pa << 666 static_cast<const G4VMultipleScattering*>(GetMasterProcess()); 420 numberOfModels, verboseLevel, << 667 if(masterProcess && masterProcess != this) { return yes; } 421 ascii); << 668 >> 669 G4int nmod = modelManager->NumberOfModels(); >> 670 static const G4String ss[4] = {"1","2","3","4"}; >> 671 for(G4int i=0; i<nmod; ++i) { >> 672 G4VEmModel* msc = modelManager->GetModel(i); >> 673 yes = true; >> 674 G4PhysicsTable* table = msc->GetCrossSectionTable(); >> 675 if (table) { >> 676 G4int j = std::min(i,3); >> 677 G4String name = >> 678 GetPhysicsTableFileName(part,directory,"LambdaMod"+ss[j],ascii); >> 679 yes = table->StorePhysicsTable(name,ascii); >> 680 >> 681 if ( yes ) { >> 682 if ( verboseLevel>0 ) { >> 683 G4cout << "Physics table are stored for " >> 684 << part->GetParticleName() >> 685 << " and process " << GetProcessName() >> 686 << " with a name <" << name << "> " << G4endl; >> 687 } >> 688 } else { >> 689 G4cout << "Fail to store Physics Table for " >> 690 << part->GetParticleName() >> 691 << " and process " << GetProcessName() >> 692 << " in the directory <" << directory >> 693 << "> " << G4endl; >> 694 } >> 695 } >> 696 } >> 697 return yes; 422 } 698 } 423 699 424 //....oooOO0OOooo........oooOO0OOooo........oo 700 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 425 701 426 G4bool 702 G4bool 427 G4VMultipleScattering::RetrievePhysicsTable(co 703 G4VMultipleScattering::RetrievePhysicsTable(const G4ParticleDefinition*, 428 co << 704 const G4String&, 429 G4 << 705 G4bool) 430 { 706 { 431 return true; 707 return true; 432 } 708 } 433 709 434 //....oooOO0OOooo........oooOO0OOooo........oo 710 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 435 711 436 void G4VMultipleScattering::ProcessDescription << 712 void G4VMultipleScattering::SetIonisation(G4VEnergyLossProcess* p) 437 { 713 { 438 if(nullptr != firstParticle) { << 714 for(G4int i=0; i<numberOfModels; ++i) { 439 StreamInfo(outFile, *firstParticle, true); << 715 G4VMscModel* msc = static_cast<G4VMscModel*>(GetModelByIndex(i, true)); >> 716 msc->SetIonisation(p, firstParticle); 440 } 717 } 441 } 718 } 442 719 443 //....oooOO0OOooo........oooOO0OOooo........oo 720 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 444 721 445 722