94 firstParticle(nullptr),
95 currParticle(nullptr),
98 latDisplacement(true),
100 fDispBeyondSafety(false),
101 fNewPosition(0.,0.,0.),
102 fNewDirection(0.,0.,1.)
111 physStepLimit = gPathLength = tPathLength = 0.0;
112 fIonisation =
nullptr;
115 minDisplacement2 = geomMin*geomMin;
118 safetyHelper =
nullptr;
119 fPositionChanged =
false;
122 currentModel =
nullptr;
148 modelManager->
AddEmModel(order, p, fm, region);
156 G4int n = mscModels.size();
157 if(index >= n) {
for(
G4int i=n; i<=index; ++i) { mscModels.push_back(0); } }
158 mscModels[index] =
p;
166 if(index >= 0 && index <
G4int(mscModels.size())) { p = mscModels[index]; }
175 return modelManager->
GetModel(idx, ver);
186 if(masterProc && masterProc !=
this) { master =
false; }
188 if(!firstParticle) { firstParticle = ∂ }
191 latDisplacement =
false;
194 if(pname !=
"deuteron" && pname !=
"triton" &&
195 pname !=
"alpha+" && pname !=
"helium" &&
196 pname !=
"alpha" && pname !=
"He3" &&
197 pname !=
"hydrogen") {
201 if(&part == theGenericIon) { isIon =
true; }
203 if(theGenericIon && firstParticle != theGenericIon) {
206 size_t n = v->
size();
207 for(
size_t j=0; j<
n; ++j) {
208 if((*v)[j] ==
this) {
209 firstParticle = theGenericIon;
222 G4cout <<
"### G4VMultipleScattering::PrepearPhysicsTable() for "
226 <<
" isIon= " << isIon
230 if(firstParticle == &part) {
246 if(latDisplacement) {
262 for(
G4int i=0; i<numberOfModels; ++i) {
266 if(0 == i) { currentModel = msc; }
295 G4cout <<
"### G4VMultipleScattering::BuildPhysicsTable() for "
297 <<
" and particle " << num
304 if(masterProcess && masterProcess !=
this) { master =
false; }
306 if(firstParticle == &part) {
328 for(
G4int i=0; i<numberOfModels; ++i) {
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")))
358 G4cout <<
"### G4VMultipleScattering::BuildPhysicsTable() done for "
360 <<
" and particle " << num
398 if(1 == numberOfModels) {
400 if(eloss) { currentModel->
SetIonisation(fIonisation, currParticle); }
404 for(
G4int i=0; i<numberOfModels; ++i) {
423 physStepLimit = gPathLength = tPathLength = currentMinimalStep;
438 if(1 < numberOfModels) {
445 if(currentModel->
IsActive(ekin) && tPathLength > geomMin
446 && ekin >= lowestKinEnergy) {
450 if (tPathLength < physStepLimit) {
453 }
else { isActive =
false; }
487 fPositionChanged =
false;
493 tPathLength = geomLength;
513 tPathLength =
std::min(tPathLength, physStepLimit);
516 if(tPathLength < range && tPathLength > geomMin) {
527 if(r2 > minDisplacement2) {
529 fPositionChanged =
true;
536 if(postSafety > 0.0 && dispR <= postSafety) {
537 fNewPosition += displacement;
543 if(dispR < postSafety) {
544 fNewPosition += displacement;
548 }
else if(fDispBeyondSafety && 0.0 == postSafety) {
549 fNewPosition += displacement;
551 std::min(2.0*dispR, geomLength*(physStepLimit/tPathLength - 1.0));
553 G4double safety = postSafety + dispR;
565 fNewDirection, maxshift, &dist, &safety)
566 && std::abs(dist) < maxshift) {
577 tPathLength *= (1.0 + dist/geomLength);
578 fNewPosition += dist*fNewDirection;
582 maxshift =
std::min(maxshift, geomLength);
583 if(0.0 < maxshift + dist) {
586 G4double R2 = (postpoint - point).mag2();
589 for(
G4int i=0; i<10; ++i) {
592 point, fNewDirection, maxshift, &dist, &safety)
593 && std::abs(newdist + dist) < maxshift) {
594 point += dist*fNewDirection;
595 G4double R2new = (postpoint - point).mag2();
598 if(dist >= 0.0 || R2new > R2) {
break; }
600 fNewPosition = point;
606 tPathLength *= (1.0 + newdist/geomLength);
609 fNewPosition += displacement*(postSafety/dispR - 1.0);
614 fNewPosition += displacement*(postSafety/dispR - 1.0);
617 }
else if(postSafety > geomMin) {
618 fNewPosition += displacement*(postSafety/dispR);
622 fPositionChanged =
false;
625 if(fPositionChanged) {
690 if(part != firstParticle) {
return yes; }
693 if(masterProcess && masterProcess !=
this) {
return yes; }
696 static const G4String ss[4] = {
"1",
"2",
"3",
"4"};
697 for(
G4int i=0; i<nmod; ++i) {
709 G4cout <<
"Physics table are stored for "
712 <<
" with a name <" << name <<
"> " <<
G4endl;
715 G4cout <<
"Fail to store Physics Table for "
718 <<
" in the directory <" << directory
740 for(
G4int i=0; i<numberOfModels; ++i) {
G4double condition(const G4ErrorSymMatrix &m)
const G4ThreeVector * GetMomentumDirection() const
const G4VProcess * GetMasterProcess() const
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 *)
G4int WorkerVerbose() const
G4double MaxKinEnergy() const
static G4LossTableManager * Instance()
static constexpr double proton_mass_c2
G4double AlongStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4double currentMinimalStep, G4double ¤tSafety, G4GPILSelection *selection) override
G4VEmModel * GetModel(G4int idx, G4bool ver=false)
G4double GetStepLength() const
G4double HighEnergyLimit() const
G4MscStepLimitType MscMuHadStepLimitType() const
void SetParticleChange(G4VParticleChange *, G4VEmFluctuationModel *f=nullptr)
void DeRegister(G4VEnergyLossProcess *p)
G4double MscGeomFactor() const
G4double MscMuHadRangeFactor() const
G4double MscThetaLimit() const
G4bool StorePhysicsTable(const G4ParticleDefinition *, const G4String &directory, G4bool ascii=false) override
virtual void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel)
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
virtual void ProcessDescription(std::ostream &outFile) const
void SetLateralDisplasmentFlag(G4bool val)
void SetEmModel(G4VMscModel *, G4int index=1)
void AddEmModel(G4int, G4VEmModel *, G4VEmFluctuationModel *, const G4Region *)
G4PhysicsTable * GetCrossSectionTable()
virtual ~G4VMultipleScattering()
void SetStepLimitType(G4MscStepLimitType)
G4double GetMeanFreePath(const G4Track &track, G4double, G4ForceCondition *condition) override
const G4String & GetPhysicsTableFileName(const G4ParticleDefinition *, const G4String &directory, const G4String &tableName, G4bool ascii=false)
const G4String & GetParticleName() const
G4bool LatDisplacementBeyondSafety() const
void SetHighEnergyLimit(G4double)
G4VMultipleScattering(const G4String &name="msc", G4ProcessType type=fElectromagnetic)
G4ParticleChangeForMSC fParticleChange
virtual G4double ComputeTrueStepLength(G4double geomPathLength)
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4GLOB_DLL std::ostream G4cout
virtual G4double ComputeTruePathLengthLimit(const G4Track &track, G4double &stepLimit)
G4bool MuHadLateralDisplacement() const
const G4ThreeVector & GetPosition() const
G4double GetRange(const G4ParticleDefinition *part, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
void SetRangeFactor(G4double)
void ProposeTrueStepLength(G4double truePathLength)
G4bool LateralDisplacement() const
const G4ParticleDefinition * GetParticleDefinition() const
void SetProcessSubType(G4int)
const G4String & GetParticleType() const
void SetCrossSectionTable(G4PhysicsTable *, G4bool isLocal)
void Register(G4VEnergyLossProcess *p)
const G4String & GetProcessName() const
G4double GetContinuousStepLimit(const G4Track &track, G4double previousStepSize, G4double currentMinimalStep, G4double ¤tSafety) override
G4bool IsActive(G4double kinEnergy)
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)
G4VEnergyLossProcess * GetEnergyLossProcess(const G4ParticleDefinition *)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
void PreparePhysicsTable(const G4ParticleDefinition &) override
void SetIonisation(G4VEnergyLossProcess *, const G4ParticleDefinition *part)
static G4GenericIon * GenericIon()
G4int NumberOfModels() const
void ProposePosition(const G4ThreeVector &finalPosition)
static constexpr double nm
void BuildPhysicsTable(const G4ParticleDefinition *aParticle)
G4double GetPDGMass() const
static G4ParticleTable * GetParticleTable()
G4ProcessManager * GetProcessManager() const
G4double ContinuousStepLimit(const G4Track &track, G4double previousStepSize, G4double currentMinimalStep, G4double ¤tSafety)
G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &) override
G4StepPoint * GetPostStepPoint() const
static G4EmParameters * Instance()
G4VParticleChange * pParticleChange
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)
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)
static G4Electron * Electron()
static constexpr double MeV
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
void PrintInfoDefinition()
G4ProcessVector * GetAlongStepProcessVector(G4ProcessVectorTypeIndex typ=typeGPIL) const
void BuildPhysicsTable(const G4ParticleDefinition &) override
G4bool RecheckDistanceToCurrentBoundary(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double *prDistance, G4double *prNewSafety=0) const
G4VMscModel * EmModel(G4int index=1) const
G4int GetProcessSubType() const
void StartTracking(G4Track *) override
void SetPolarAngleLimit(G4double)
void SetVerboseLevel(G4int value)
G4VEmModel * GetModelByIndex(G4int idx=0, G4bool ver=false) const
virtual G4ThreeVector & SampleScattering(const G4ThreeVector &, G4double safety)
void SetIonisation(G4VEnergyLossProcess *)