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