Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/standard/src/G4WentzelVIModel.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/electromagnetic/standard/src/G4WentzelVIModel.cc (Version 11.3.0) and /processes/electromagnetic/standard/src/G4WentzelVIModel.cc (Version 10.3.p1)


  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: G4WentzelVIModel.cc 96934 2016-05-18 09:10:41Z gcosmo $
 26 //                                                 27 //
 27 // -------------------------------------------     28 // -------------------------------------------------------------------
 28 //                                                 29 //
 29 // GEANT4 Class file                               30 // GEANT4 Class file
 30 //                                                 31 //
 31 //                                                 32 //
 32 // File name:   G4WentzelVIModel                   33 // File name:   G4WentzelVIModel
 33 //                                                 34 //
 34 // Author:      V.Ivanchenko                       35 // Author:      V.Ivanchenko 
 35 //                                                 36 //
 36 // Creation date: 09.04.2008 from G4MuMscModel     37 // Creation date: 09.04.2008 from G4MuMscModel
 37 //                                                 38 //
 38 // Modifications:                                  39 // Modifications:
 39 // 27-05-2010 V.Ivanchenko added G4WentzelOKan     40 // 27-05-2010 V.Ivanchenko added G4WentzelOKandVIxSection class to
 40 //              compute cross sections and sam     41 //              compute cross sections and sample scattering angle
 41 //                                                 42 //
 42 //                                                 43 //
 43 // Class Description:                              44 // Class Description:
 44 //                                                 45 //
 45 // Implementation of the model of multiple sca     46 // Implementation of the model of multiple scattering based on
 46 // G.Wentzel, Z. Phys. 40 (1927) 590.              47 // G.Wentzel, Z. Phys. 40 (1927) 590.
 47 // H.W.Lewis, Phys Rev 78 (1950) 526.              48 // H.W.Lewis, Phys Rev 78 (1950) 526.
 48 // J.M. Fernandez-Varea et al., NIM B73 (1993)     49 // J.M. Fernandez-Varea et al., NIM B73 (1993) 447.
 49 // L.Urban, CERN-OPEN-2006-077.                    50 // L.Urban, CERN-OPEN-2006-077.
 50                                                    51 
 51 // -------------------------------------------     52 // -------------------------------------------------------------------
 52 //                                                 53 //
 53                                                    54 
 54 //....oooOO0OOooo........oooOO0OOooo........oo     55 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 55 //....oooOO0OOooo........oooOO0OOooo........oo     56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 56                                                    57 
 57 #include "G4WentzelVIModel.hh"                     58 #include "G4WentzelVIModel.hh"
 58 #include "G4PhysicalConstants.hh"                  59 #include "G4PhysicalConstants.hh"
 59 #include "G4SystemOfUnits.hh"                      60 #include "G4SystemOfUnits.hh"
 60 #include "Randomize.hh"                            61 #include "Randomize.hh"
 61 #include "G4ParticleChangeForMSC.hh"               62 #include "G4ParticleChangeForMSC.hh"
 62 #include "G4PhysicsTableHelper.hh"                 63 #include "G4PhysicsTableHelper.hh"
 63 #include "G4ElementVector.hh"                      64 #include "G4ElementVector.hh"
 64 #include "G4ProductionCutsTable.hh"                65 #include "G4ProductionCutsTable.hh"
 65 #include "G4EmParameters.hh"                       66 #include "G4EmParameters.hh"
 66 #include "G4Log.hh"                                67 #include "G4Log.hh"
 67 #include "G4Exp.hh"                                68 #include "G4Exp.hh"
 68                                                    69 
 69 //....oooOO0OOooo........oooOO0OOooo........oo     70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 70                                                    71 
 71 using namespace std;                               72 using namespace std;
 72                                                    73 
 73 const G4double invsqrt12 = 1./std::sqrt(12.);  <<  74 G4WentzelVIModel::G4WentzelVIModel(G4bool combined, const G4String& nam) :
 74 const G4double numlimit = 0.1;                 <<  75   G4VMscModel(nam),
 75 const G4int minNCollisions = 10;               <<  76   ssFactor(1.05),
 76                                                <<  77   invssFactor(1.0),
 77 G4WentzelVIModel::G4WentzelVIModel(G4bool comb <<  78   currentCouple(nullptr),
 78   : G4VMscModel(nam),                          <<  79   singleScatteringMode(false),
 79     singleScatteringMode(false),               <<  80   cosThetaMin(1.0),
 80     isCombined(comb),                          <<  81   cosThetaMax(-1.0),
 81     useSecondMoment(false)                     <<  82   fSecondMoments(nullptr),
                                                   >>  83   idx2(0),
                                                   >>  84   numlimit(0.1),
                                                   >>  85   isCombined(combined),
                                                   >>  86   useSecondMoment(false)
 82 {                                                  87 {
 83   tlimitminfix = 1.e-6*CLHEP::mm;              << 
 84   lowEnergyLimit = 1.0*CLHEP::eV;              << 
 85   SetSingleScatteringFactor(1.25);                 88   SetSingleScatteringFactor(1.25);
 86   wokvi = new G4WentzelOKandVIxSection(isCombi <<  89   invsqrt12 = 1./sqrt(12.);
                                                   >>  90   tlimitminfix = 1.e-6*mm;
                                                   >>  91   lowEnergyLimit = 1.0*eV;
                                                   >>  92   particle = 0;
                                                   >>  93   nelments = 5;
                                                   >>  94   xsecn.resize(nelments);
                                                   >>  95   prob.resize(nelments);
                                                   >>  96   wokvi = new G4WentzelOKandVIxSection(combined);
                                                   >>  97   fixedCut = -1.0;
                                                   >>  98 
                                                   >>  99   minNCollisions = 10;
                                                   >> 100 
                                                   >> 101   preKinEnergy = effKinEnergy = tPathLength = zPathLength = lambdaeff 
                                                   >> 102     = currentRange = xtsec = cosTetMaxNuc = 0.0;
                                                   >> 103   currentMaterialIndex = 0;
                                                   >> 104 
                                                   >> 105   fParticleChange = nullptr;
                                                   >> 106   currentCuts = nullptr;
                                                   >> 107   currentMaterial = nullptr;
 87 }                                                 108 }
 88                                                   109 
 89 //....oooOO0OOooo........oooOO0OOooo........oo    110 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 90                                                   111 
 91 G4WentzelVIModel::~G4WentzelVIModel()             112 G4WentzelVIModel::~G4WentzelVIModel()
 92 {                                                 113 {
 93   delete wokvi;                                   114   delete wokvi;
 94   if(IsMaster()) {                             << 115   if(fSecondMoments && IsMaster()) {
 95     delete fSecondMoments;                        116     delete fSecondMoments;
 96     fSecondMoments = nullptr;                  << 117     fSecondMoments = 0;
 97   }                                               118   }
 98 }                                                 119 }
 99                                                   120 
100 //....oooOO0OOooo........oooOO0OOooo........oo    121 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
101                                                   122 
102 void G4WentzelVIModel::Initialise(const G4Part    123 void G4WentzelVIModel::Initialise(const G4ParticleDefinition* p,
103                                   const G4Data    124                                   const G4DataVector& cuts)
104 {                                                 125 {
105   // reset parameters                             126   // reset parameters
106   SetupParticle(p);                               127   SetupParticle(p);
107   InitialiseParameters(p);                     << 
108   currentRange = 0.0;                             128   currentRange = 0.0;
109                                                   129 
110   if(isCombined) {                                130   if(isCombined) {
111     G4double tet = PolarAngleLimit();             131     G4double tet = PolarAngleLimit();
112     if(tet <= 0.0)           { cosThetaMax = 1    132     if(tet <= 0.0)           { cosThetaMax = 1.0; }
113     else if(tet < CLHEP::pi) { cosThetaMax = c    133     else if(tet < CLHEP::pi) { cosThetaMax = cos(tet); }
114   }                                               134   }
115   //G4cout << "G4WentzelVIModel::Initialise "  << 
116   //   << " " << this << " " << wokvi << G4end << 
117                                                   135 
                                                   >> 136   //G4cout << "G4WentzelVIModel::Initialise " << p->GetParticleName() << G4endl;
118   wokvi->Initialise(p, cosThetaMax);              137   wokvi->Initialise(p, cosThetaMax);
119   /*                                           << 138   /*  
120   G4cout << "G4WentzelVIModel: " << particle->    139   G4cout << "G4WentzelVIModel: " << particle->GetParticleName()
121          << "  1-cos(ThetaLimit)= " << 1 - cos    140          << "  1-cos(ThetaLimit)= " << 1 - cosThetaMax 
122          << " SingScatFactor= " << ssFactor       141          << " SingScatFactor= " << ssFactor
123          << G4endl;                               142          << G4endl;
124   */                                              143   */
125   currentCuts = &cuts;                            144   currentCuts = &cuts;
126                                                   145 
127   // set values of some data members              146   // set values of some data members
128   fParticleChange = GetParticleChangeForMSC(p)    147   fParticleChange = GetParticleChangeForMSC(p);
129                                                   148 
130   // Access to materials                       << 
131   const G4ProductionCutsTable* theCoupleTable  << 
132     G4ProductionCutsTable::GetProductionCutsTa << 
133   G4int numOfCouples = (G4int)theCoupleTable-> << 
134   nelments = 0;                                << 
135   for(G4int i=0; i<numOfCouples; ++i) {        << 
136     G4int nelm = (G4int)theCoupleTable->GetMat << 
137     nelments = std::max(nelments, nelm);       << 
138   }                                            << 
139   xsecn.resize(nelments);                      << 
140   prob.resize(nelments);                       << 
141                                                << 
142   // build second moment table only if transpo    149   // build second moment table only if transport table is build
143   G4PhysicsTable* table = GetCrossSectionTable    150   G4PhysicsTable* table = GetCrossSectionTable();
144   if(useSecondMoment && IsMaster() && nullptr  << 151   if(useSecondMoment && IsMaster() && table) {
145                                                   152 
146     //G4cout << "### G4WentzelVIModel::Initial    153     //G4cout << "### G4WentzelVIModel::Initialise: build 2nd moment table "
147     //           << table << G4endl;              154     //           << table << G4endl;
148     fSecondMoments =                              155     fSecondMoments =  
149       G4PhysicsTableHelper::PreparePhysicsTabl    156       G4PhysicsTableHelper::PreparePhysicsTable(fSecondMoments);
                                                   >> 157     // Access to materials
                                                   >> 158     const G4ProductionCutsTable* theCoupleTable =
                                                   >> 159       G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 160     size_t numOfCouples = theCoupleTable->GetTableSize();
150                                                   161 
151     G4bool splineFlag = true;                     162     G4bool splineFlag = true;
152     G4PhysicsVector* aVector = nullptr;           163     G4PhysicsVector* aVector = nullptr;
153     G4PhysicsVector* bVector = nullptr;           164     G4PhysicsVector* bVector = nullptr;
154     G4double emin = std::max(LowEnergyLimit(),    165     G4double emin = std::max(LowEnergyLimit(), LowEnergyActivationLimit());
155     G4double emax = std::min(HighEnergyLimit()    166     G4double emax = std::min(HighEnergyLimit(), HighEnergyActivationLimit());
156     if(emin < emax) {                             167     if(emin < emax) {
157       std::size_t n = G4EmParameters::Instance << 168       size_t n = G4EmParameters::Instance()->NumberOfBinsPerDecade()
158         *G4lrint(std::log10(emax/emin));          169         *G4lrint(std::log10(emax/emin));
159       if(n < 3) { n = 3; }                        170       if(n < 3) { n = 3; }
160                                                   171 
161       for(G4int i=0; i<numOfCouples; ++i) {    << 172       for(size_t i=0; i<numOfCouples; ++i) {
162                                                   173 
163         //G4cout<< "i= " << i << " Flag=  " <<    174         //G4cout<< "i= " << i << " Flag=  " << fSecondMoments->GetFlag(i) 
164         //      << G4endl;                        175         //      << G4endl;
165         if(fSecondMoments->GetFlag(i)) {          176         if(fSecondMoments->GetFlag(i)) {
166           DefineMaterial(theCoupleTable->GetMa    177           DefineMaterial(theCoupleTable->GetMaterialCutsCouple(i));
167                                                   178        
168           delete (*fSecondMoments)[i];            179           delete (*fSecondMoments)[i];
169           if(nullptr == aVector) {             << 180           if(!aVector) { 
170             aVector = new G4PhysicsLogVector(e << 181             aVector = new G4PhysicsLogVector(emin, emax, n);
171             bVector = aVector;                    182             bVector = aVector;
172           } else {                                183           } else {
173             bVector = new G4PhysicsVector(*aVe    184             bVector = new G4PhysicsVector(*aVector);
174           }                                       185           }
175           for(std::size_t j=0; j<n; ++j) {     << 186           for(size_t j=0; j<n; ++j) {
176             G4double e = bVector->Energy(j);      187             G4double e = bVector->Energy(j); 
177             bVector->PutValue(j, ComputeSecond    188             bVector->PutValue(j, ComputeSecondMoment(p, e)*e*e);
178           }                                       189           }
179           if(splineFlag) { bVector->FillSecond    190           if(splineFlag) { bVector->FillSecondDerivatives(); }
180           (*fSecondMoments)[i] = bVector;         191           (*fSecondMoments)[i] = bVector;  
181         }                                         192         }
182       }                                           193       }
183     }                                             194     } 
184     //G4cout << *fSecondMoments << G4endl;        195     //G4cout << *fSecondMoments << G4endl;
185   }                                               196   }
186 }                                                 197 }
187                                                   198 
188 //....oooOO0OOooo........oooOO0OOooo........oo    199 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
189                                                   200 
190 void G4WentzelVIModel::InitialiseLocal(const G    201 void G4WentzelVIModel::InitialiseLocal(const G4ParticleDefinition*, 
191                                        G4VEmMo    202                                        G4VEmModel* masterModel)
192 {                                                 203 {
193   fSecondMoments = static_cast<G4WentzelVIMode    204   fSecondMoments = static_cast<G4WentzelVIModel*>(masterModel)
194     ->GetSecondMomentTable();                     205     ->GetSecondMomentTable(); 
195 }                                                 206 }
196                                                   207 
197 //....oooOO0OOooo........oooOO0OOooo........oo << 
198                                                << 
199 void G4WentzelVIModel::DefineMaterial(const G4 << 
200 {                                              << 
201   if(cup != currentCouple) {                   << 
202     currentCouple = cup;                       << 
203     SetCurrentCouple(cup);                     << 
204     currentMaterial = cup->GetMaterial();      << 
205     currentMaterialIndex = currentCouple->GetI << 
206   }                                            << 
207 }                                              << 
208                                                << 
209 //....oooOO0OOooo........oooOO0OOooo........oo    208 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
210                                                   209 
211 G4double G4WentzelVIModel::ComputeCrossSection    210 G4double G4WentzelVIModel::ComputeCrossSectionPerAtom( 
212                              const G4ParticleD    211                              const G4ParticleDefinition* p,
213                              G4double kinEnerg    212                              G4double kinEnergy,
214                              G4double Z, G4dou    213                              G4double Z, G4double,
215                              G4double cutEnerg    214                              G4double cutEnergy, G4double)
216 {                                                 215 {
217   G4double cross = 0.0;                           216   G4double cross = 0.0;
218   SetupParticle(p);                            << 217   if(p != particle) { SetupParticle(p); }
219   if(kinEnergy < lowEnergyLimit) { return cros    218   if(kinEnergy < lowEnergyLimit) { return cross; }
220   if(nullptr == CurrentCouple()) {             << 219   if(!CurrentCouple()) {
221     G4Exception("G4WentzelVIModel::ComputeCros    220     G4Exception("G4WentzelVIModel::ComputeCrossSectionPerAtom", "em0011",
222                 FatalException, " G4MaterialCu    221                 FatalException, " G4MaterialCutsCouple is not defined");
223     return 0.0;                                   222     return 0.0;
224   }                                               223   }
225   DefineMaterial(CurrentCouple());                224   DefineMaterial(CurrentCouple());
226   cosTetMaxNuc = wokvi->SetupKinematic(kinEner    225   cosTetMaxNuc = wokvi->SetupKinematic(kinEnergy, currentMaterial);
227   if(cosTetMaxNuc < 1.0) {                        226   if(cosTetMaxNuc < 1.0) {
228     G4double cut  = (0.0 < fixedCut) ? fixedCu << 227     G4double cut = cutEnergy;
                                                   >> 228     if(fixedCut > 0.0) { cut = fixedCut; }
229     G4double cost = wokvi->SetupTarget(G4lrint    229     G4double cost = wokvi->SetupTarget(G4lrint(Z), cut);
230     cross = wokvi->ComputeTransportCrossSectio    230     cross = wokvi->ComputeTransportCrossSectionPerAtom(cost);
231     /*                                            231     /*
232     if(p->GetParticleName() == "e-")              232     if(p->GetParticleName() == "e-")      
233     G4cout << "G4WentzelVIModel::CS: Z= " << G    233     G4cout << "G4WentzelVIModel::CS: Z= " << G4int(Z) << " e(MeV)= "<<kinEnergy 
234            << " 1-cosN= " << 1 - cosTetMaxNuc     234            << " 1-cosN= " << 1 - cosTetMaxNuc << " cross(bn)= " << cross/barn
235            << " " << particle->GetParticleName    235            << " " << particle->GetParticleName() << G4endl;
236     */                                            236     */
237   }                                               237   }
238   return cross;                                   238   return cross;
239 }                                                 239 }
240                                                   240 
241 //....oooOO0OOooo........oooOO0OOooo........oo    241 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
242                                                   242 
243 void G4WentzelVIModel::StartTracking(G4Track*     243 void G4WentzelVIModel::StartTracking(G4Track* track)
244 {                                                 244 {
245   /*                                           << 245   SetupParticle(track->GetDynamicParticle()->GetDefinition());
246   G4cout << "G4WentzelVIModel::StartTracking " << 
247    << track->GetParticleDefinition()->GetParti << 
248    << "   workvi: " << wokvi << G4endl;        << 
249   */                                           << 
250   SetupParticle(track->GetParticleDefinition() << 
251 }                                                 246 }
252                                                   247 
253 //....oooOO0OOooo........oooOO0OOooo........oo    248 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
254                                                   249 
255 G4double G4WentzelVIModel::ComputeTruePathLeng    250 G4double G4WentzelVIModel::ComputeTruePathLengthLimit(
256                              const G4Track& tr    251                              const G4Track& track,
257                              G4double& current    252                              G4double& currentMinimalStep)
258 {                                                 253 {
259   G4double tlimit = currentMinimalStep;           254   G4double tlimit = currentMinimalStep;
260   const G4DynamicParticle* dp = track.GetDynam    255   const G4DynamicParticle* dp = track.GetDynamicParticle();
261   const G4StepPoint* sp = track.GetStep()->Get << 256   G4StepPoint* sp = track.GetStep()->GetPreStepPoint();
262   G4StepStatus stepStatus = sp->GetStepStatus(    257   G4StepStatus stepStatus = sp->GetStepStatus();
263   singleScatteringMode = false;                   258   singleScatteringMode = false;
264                                                   259 
265   //G4cout << "G4WentzelVIModel::ComputeTruePa    260   //G4cout << "G4WentzelVIModel::ComputeTruePathLengthLimit stepStatus= " 
266   //         << stepStatus << "  " << track.Ge    261   //         << stepStatus << "  " << track.GetDefinition()->GetParticleName() 
267   //         << G4endl;                           262   //         << G4endl;
268                                                   263 
269   // initialisation for each step, lambda may     264   // initialisation for each step, lambda may be computed from scratch
270   preKinEnergy = dp->GetKineticEnergy();          265   preKinEnergy = dp->GetKineticEnergy();
271   effKinEnergy = preKinEnergy;                    266   effKinEnergy = preKinEnergy;
272   DefineMaterial(track.GetMaterialCutsCouple()    267   DefineMaterial(track.GetMaterialCutsCouple());
273   const G4double logPreKinEnergy = dp->GetLogK << 268   lambdaeff = GetTransportMeanFreePath(particle,preKinEnergy);
274   lambdaeff = GetTransportMeanFreePath(particl << 269   currentRange = GetRange(particle,preKinEnergy,currentCouple);
275   currentRange = GetRange(particle,preKinEnerg << 
276   cosTetMaxNuc = wokvi->SetupKinematic(preKinE    270   cosTetMaxNuc = wokvi->SetupKinematic(preKinEnergy, currentMaterial);
277                                                   271   
278   //G4cout << "lambdaeff= " << lambdaeff << "     272   //G4cout << "lambdaeff= " << lambdaeff << " Range= " << currentRange
279   // << " tlimit= " << tlimit << " 1-cost= " <    273   // << " tlimit= " << tlimit << " 1-cost= " << 1 - cosTetMaxNuc << G4endl;
280                                                   274   
281   // extra check for abnormal situation           275   // extra check for abnormal situation
282   // this check needed to run MSC with eIoni a    276   // this check needed to run MSC with eIoni and eBrem inactivated
283   if(tlimit > currentRange) { tlimit = current    277   if(tlimit > currentRange) { tlimit = currentRange; }
284                                                   278 
285   // stop here if small range particle            279   // stop here if small range particle
286   if(tlimit < tlimitminfix) {                     280   if(tlimit < tlimitminfix) { 
287     return ConvertTrueToGeom(tlimit, currentMi    281     return ConvertTrueToGeom(tlimit, currentMinimalStep); 
288   }                                               282   }
289                                                   283 
290   // pre step                                     284   // pre step
291   G4double presafety = sp->GetSafety();           285   G4double presafety = sp->GetSafety();
292   // far from geometry boundary                   286   // far from geometry boundary
293   if(currentRange < presafety) {                  287   if(currentRange < presafety) {
294     return ConvertTrueToGeom(tlimit, currentMi    288     return ConvertTrueToGeom(tlimit, currentMinimalStep);
295   }                                               289   }
296                                                   290 
297   // compute presafety again if presafety <= 0    291   // compute presafety again if presafety <= 0 and no boundary
298   // i.e. when it is needed for optimization p    292   // i.e. when it is needed for optimization purposes
299   if(stepStatus != fGeomBoundary && presafety     293   if(stepStatus != fGeomBoundary && presafety < tlimitminfix) {
300     presafety = ComputeSafety(sp->GetPosition(    294     presafety = ComputeSafety(sp->GetPosition(), tlimit); 
301     if(currentRange < presafety) {                295     if(currentRange < presafety) {
302       return ConvertTrueToGeom(tlimit, current    296       return ConvertTrueToGeom(tlimit, currentMinimalStep);
303     }                                             297     }
304   }                                               298   }
305   /*                                              299   /*       
306   G4cout << "e(MeV)= " << preKinEnergy/MeV        300   G4cout << "e(MeV)= " << preKinEnergy/MeV
307          << "  " << particle->GetParticleName(    301          << "  " << particle->GetParticleName() 
308          << " CurLimit(mm)= " << tlimit/mm <<"    302          << " CurLimit(mm)= " << tlimit/mm <<" safety(mm)= " << presafety/mm
309          << " R(mm)= " <<currentRange/mm          303          << " R(mm)= " <<currentRange/mm
310          << " L0(mm^-1)= " << lambdaeff*mm        304          << " L0(mm^-1)= " << lambdaeff*mm 
311          << G4endl;                               305          << G4endl;
312   */                                              306   */
313   // natural limit for high energy                307   // natural limit for high energy
314   G4double rlimit = std::max(facrange*currentR    308   G4double rlimit = std::max(facrange*currentRange, 
315                              (1.0 - cosTetMaxN    309                              (1.0 - cosTetMaxNuc)*lambdaeff*invssFactor);
316                                                   310 
317   // low-energy e-                                311   // low-energy e-
318   if(cosThetaMax > cosTetMaxNuc) {                312   if(cosThetaMax > cosTetMaxNuc) {
319     rlimit = std::min(rlimit, facsafety*presaf    313     rlimit = std::min(rlimit, facsafety*presafety);
320   }                                               314   }
321                                                   315    
322   // cut correction                               316   // cut correction
323   G4double rcut = currentCouple->GetProduction    317   G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(1);
324   //G4cout << "rcut= " << rcut << " rlimit= "     318   //G4cout << "rcut= " << rcut << " rlimit= " << rlimit << " presafety= " 
325   // << presafety << " 1-cosThetaMax= " <<1-co    319   // << presafety << " 1-cosThetaMax= " <<1-cosThetaMax 
326   //<< " 1-cosTetMaxNuc= " << 1-cosTetMaxNuc <    320   //<< " 1-cosTetMaxNuc= " << 1-cosTetMaxNuc << G4endl;
327   if(rcut > rlimit) { rlimit = std::min(rlimit << 321   if(rcut > rlimit) { rlimit = std::min(rlimit, rcut*sqrt(rlimit/rcut)); }
328                                                   322  
329   tlimit = std::min(tlimit, rlimit);              323   tlimit = std::min(tlimit, rlimit);
330   tlimit = std::max(tlimit, tlimitminfix);        324   tlimit = std::max(tlimit, tlimitminfix);
331                                                   325 
332   // step limit in infinite media                 326   // step limit in infinite media
333   tlimit = std::min(tlimit, 50*currentMaterial    327   tlimit = std::min(tlimit, 50*currentMaterial->GetRadlen()/facgeom);
334                                                   328 
335   //compute geomlimit and force few steps with    329   //compute geomlimit and force few steps within a volume
336   if (steppingAlgorithm == fUseDistanceToBound    330   if (steppingAlgorithm == fUseDistanceToBoundary 
337       && stepStatus == fGeomBoundary) {           331       && stepStatus == fGeomBoundary) {
338                                                   332 
339     G4double geomlimit = ComputeGeomLimit(trac    333     G4double geomlimit = ComputeGeomLimit(track, presafety, currentRange);
340     tlimit = std::min(tlimit, geomlimit/facgeo    334     tlimit = std::min(tlimit, geomlimit/facgeom);
341   }                                               335   } 
342   /*                                              336   /*         
343   G4cout << particle->GetParticleName() << " e    337   G4cout << particle->GetParticleName() << " e= " << preKinEnergy
344          << " L0= " << lambdaeff << " R= " <<     338          << " L0= " << lambdaeff << " R= " << currentRange
345          << " tlimit= " << tlimit                 339          << " tlimit= " << tlimit  
346            << " currentMinimalStep= " << curre    340            << " currentMinimalStep= " << currentMinimalStep << G4endl;
347   */                                              341   */
348   return ConvertTrueToGeom(tlimit, currentMini    342   return ConvertTrueToGeom(tlimit, currentMinimalStep);
349 }                                                 343 }
350                                                   344 
351 //....oooOO0OOooo........oooOO0OOooo........oo    345 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
352                                                   346 
353 G4double G4WentzelVIModel::ComputeGeomPathLeng    347 G4double G4WentzelVIModel::ComputeGeomPathLength(G4double truelength)
354 {                                                 348 {
355   zPathLength = tPathLength = truelength;         349   zPathLength = tPathLength = truelength;
356                                                   350 
357   // small step use only single scattering        351   // small step use only single scattering
358   cosThetaMin = 1.0;                              352   cosThetaMin = 1.0;
359   ComputeTransportXSectionPerVolume(cosThetaMi    353   ComputeTransportXSectionPerVolume(cosThetaMin);
360   //G4cout << "xtsec= " << xtsec << "  Nav= "     354   //G4cout << "xtsec= " << xtsec << "  Nav= " 
361   //         << zPathLength*xtsec << G4endl;      355   //         << zPathLength*xtsec << G4endl;
362   if(0.0 >= lambdaeff || G4int(zPathLength*xts    356   if(0.0 >= lambdaeff || G4int(zPathLength*xtsec) < minNCollisions) {
363     singleScatteringMode = true;                  357     singleScatteringMode = true;
364     lambdaeff = DBL_MAX;                          358     lambdaeff = DBL_MAX;
365                                                   359 
366   } else {                                        360   } else {
367     //G4cout << "ComputeGeomPathLength: tLengt    361     //G4cout << "ComputeGeomPathLength: tLength= " << tPathLength
368     //           << " Leff= " << lambdaeff <<     362     //           << " Leff= " << lambdaeff << G4endl; 
369     // small step                                 363     // small step
370     if(tPathLength < numlimit*lambdaeff) {        364     if(tPathLength < numlimit*lambdaeff) {
371       G4double tau = tPathLength/lambdaeff;       365       G4double tau = tPathLength/lambdaeff;
372       zPathLength *= (1.0 - 0.5*tau + tau*tau/    366       zPathLength *= (1.0 - 0.5*tau + tau*tau/6.0);
373                                                   367 
374       // medium step                              368       // medium step
375     } else {                                      369     } else {
376       G4double e1 = 0.0;                          370       G4double e1 = 0.0;
377       if(currentRange > tPathLength) {            371       if(currentRange > tPathLength) {
378         e1 = GetEnergy(particle,currentRange-t    372         e1 = GetEnergy(particle,currentRange-tPathLength,currentCouple);
379       }                                           373       }
380       effKinEnergy = 0.5*(e1 + preKinEnergy);     374       effKinEnergy = 0.5*(e1 + preKinEnergy);
381       cosTetMaxNuc = wokvi->SetupKinematic(eff    375       cosTetMaxNuc = wokvi->SetupKinematic(effKinEnergy, currentMaterial);
382       lambdaeff = GetTransportMeanFreePath(par    376       lambdaeff = GetTransportMeanFreePath(particle, effKinEnergy);
383       //G4cout << " tLength= "<< tPathLength<<    377       //G4cout << " tLength= "<< tPathLength<< " Leff= " << lambdaeff << G4endl;
384       zPathLength = lambdaeff;                    378       zPathLength = lambdaeff;
385       if(tPathLength*numlimit < lambdaeff) {      379       if(tPathLength*numlimit < lambdaeff) {
386         zPathLength *= (1.0 - G4Exp(-tPathLeng    380         zPathLength *= (1.0 - G4Exp(-tPathLength/lambdaeff));
387       }                                           381       }
388     }                                             382     }
389   }                                               383   }
390   //G4cout << "Comp.geom: zLength= "<<zPathLen    384   //G4cout << "Comp.geom: zLength= "<<zPathLength<<" tLength= "
391   //         << tPathLength<< " Leff= " << lam    385   //         << tPathLength<< " Leff= " << lambdaeff << G4endl;
392   return zPathLength;                             386   return zPathLength;
393 }                                                 387 }
394                                                   388 
395 //....oooOO0OOooo........oooOO0OOooo........oo    389 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
396                                                   390 
397 G4double G4WentzelVIModel::ComputeTrueStepLeng    391 G4double G4WentzelVIModel::ComputeTrueStepLength(G4double geomStepLength)
398 {                                                 392 {
399   // initialisation of single scattering x-sec    393   // initialisation of single scattering x-section
400   /*                                              394   /*
401   G4cout << "ComputeTrueStepLength: Step= " <<    395   G4cout << "ComputeTrueStepLength: Step= " << geomStepLength 
402          << "  geomL= " << zPathLength            396          << "  geomL= " << zPathLength
403          << "  Lambda= " <<  lambdaeff            397          << "  Lambda= " <<  lambdaeff 
404            << " 1-cosThetaMaxNuc= " << 1 - cos    398            << " 1-cosThetaMaxNuc= " << 1 - cosTetMaxNuc << G4endl;
405   */                                              399   */
406   if(singleScatteringMode) {                      400   if(singleScatteringMode) {
407     zPathLength = tPathLength = geomStepLength    401     zPathLength = tPathLength = geomStepLength;
408                                                   402 
409   } else {                                        403   } else {
410                                                   404 
411     // step defined by transportation             405     // step defined by transportation
412     // change both geom and true step lengths     406     // change both geom and true step lengths 
413     if(geomStepLength < zPathLength) {            407     if(geomStepLength < zPathLength) { 
414                                                   408 
415       // single scattering                        409       // single scattering
416       if(G4int(geomStepLength*xtsec) < minNCol    410       if(G4int(geomStepLength*xtsec) < minNCollisions) {
417         zPathLength = tPathLength = geomStepLe    411         zPathLength = tPathLength = geomStepLength;
418         lambdaeff = DBL_MAX;                      412         lambdaeff = DBL_MAX;
419         singleScatteringMode = true;              413         singleScatteringMode = true;
420                                                   414 
421         // multiple scattering                    415         // multiple scattering
422       } else {                                    416       } else {
423         // small step                             417         // small step
424         if(geomStepLength < numlimit*lambdaeff    418         if(geomStepLength < numlimit*lambdaeff) {
425           G4double tau = geomStepLength/lambda    419           G4double tau = geomStepLength/lambdaeff;
426           tPathLength = geomStepLength*(1.0 +     420           tPathLength = geomStepLength*(1.0 + 0.5*tau + tau*tau/3.0); 
427                                                   421 
428           // energy correction for a big step     422           // energy correction for a big step
429         } else {                                  423         } else {
430           tPathLength *= geomStepLength/zPathL    424           tPathLength *= geomStepLength/zPathLength;
431           G4double e1 = 0.0;                      425           G4double e1 = 0.0;
432           if(currentRange > tPathLength) {        426           if(currentRange > tPathLength) {
433             e1 = GetEnergy(particle,currentRan    427             e1 = GetEnergy(particle,currentRange-tPathLength,currentCouple);
434           }                                       428           }
435           effKinEnergy = 0.5*(e1 + preKinEnerg    429           effKinEnergy = 0.5*(e1 + preKinEnergy);
436           cosTetMaxNuc = wokvi->SetupKinematic    430           cosTetMaxNuc = wokvi->SetupKinematic(effKinEnergy, currentMaterial);
437           lambdaeff = GetTransportMeanFreePath    431           lambdaeff = GetTransportMeanFreePath(particle, effKinEnergy);
438           G4double tau = geomStepLength/lambda    432           G4double tau = geomStepLength/lambdaeff;
439                                                   433 
440           if(tau < 0.999999) { tPathLength = -    434           if(tau < 0.999999) { tPathLength = -lambdaeff*G4Log(1.0 - tau); } 
441           else               { tPathLength = c    435           else               { tPathLength = currentRange; }
442         }                                         436         }
443         zPathLength = geomStepLength;             437         zPathLength = geomStepLength;
444       }                                           438       }
445     }                                             439     }
446   }                                               440   }
447   // check of step length                         441   // check of step length
448   // define threshold angle between single and    442   // define threshold angle between single and multiple scattering 
449   if(!singleScatteringMode) {                     443   if(!singleScatteringMode) {
450     cosThetaMin -= ssFactor*tPathLength/lambda    444     cosThetaMin -= ssFactor*tPathLength/lambdaeff; 
451     xtsec = 0.0;                                  445     xtsec = 0.0;
452                                                   446 
453     // recompute transport cross section - do     447     // recompute transport cross section - do not change energy
454     // anymore - cannot be applied for big ste    448     // anymore - cannot be applied for big steps
455     if(cosThetaMin > cosTetMaxNuc) {              449     if(cosThetaMin > cosTetMaxNuc) {
456       // new computation                          450       // new computation
457       G4double cross = ComputeTransportXSectio    451       G4double cross = ComputeTransportXSectionPerVolume(cosThetaMin);
458       //G4cout << "%%%% cross= " << cross << "    452       //G4cout << "%%%% cross= " << cross << "  xtsec= " << xtsec 
459       //           << " 1-cosTMin= " << 1.0 -     453       //           << " 1-cosTMin= " << 1.0 - cosThetaMin << G4endl;
460       if(cross <= 0.0) {                          454       if(cross <= 0.0) {
461         singleScatteringMode = true;              455         singleScatteringMode = true;
462         tPathLength = zPathLength;                456         tPathLength = zPathLength; 
463         lambdaeff = DBL_MAX;                      457         lambdaeff = DBL_MAX;
464         cosThetaMin = 1.0;                        458         cosThetaMin = 1.0;
465       } else if(xtsec > 0.0) {                    459       } else if(xtsec > 0.0) {
466                                                   460         
467         lambdaeff = 1./cross;                     461         lambdaeff = 1./cross; 
468         G4double tau = zPathLength*cross;         462         G4double tau = zPathLength*cross;
469         if(tau < numlimit) {                      463         if(tau < numlimit) { 
470           tPathLength = zPathLength*(1.0 + 0.5    464           tPathLength = zPathLength*(1.0 + 0.5*tau + tau*tau/3.0); 
471         } else if(tau < 0.999999) {               465         } else if(tau < 0.999999) { 
472           tPathLength = -lambdaeff*G4Log(1.0 -    466           tPathLength = -lambdaeff*G4Log(1.0 - tau); 
473         } else {                                  467         } else { 
474           tPathLength = currentRange;             468           tPathLength = currentRange;
475         }                                         469         }
476       }                                           470       }
477     }                                             471     } 
478   }                                               472   }
479   tPathLength = std::min(tPathLength, currentR    473   tPathLength = std::min(tPathLength, currentRange);
480   /*                                              474   /*      
481   G4cout <<"Comp.true: zLength= "<<zPathLength    475   G4cout <<"Comp.true: zLength= "<<zPathLength<<" tLength= "<<tPathLength
482          <<" Leff(mm)= "<<lambdaeff/mm<<" sig0    476          <<" Leff(mm)= "<<lambdaeff/mm<<" sig0(1/mm)= " << xtsec <<G4endl;
483   G4cout << particle->GetParticleName() << " 1    477   G4cout << particle->GetParticleName() << " 1-cosThetaMin= " << 1-cosThetaMin
484          << " 1-cosTetMaxNuc= " << 1-cosTetMax    478          << " 1-cosTetMaxNuc= " << 1-cosTetMaxNuc 
485          << " e(MeV)= " << preKinEnergy/MeV <<    479          << " e(MeV)= " << preKinEnergy/MeV << "  "  
486          << " SSmode= " << singleScatteringMod    480          << " SSmode= " << singleScatteringMode << G4endl;
487   */                                              481   */
488   return tPathLength;                             482   return tPathLength;
489 }                                                 483 }
490                                                   484 
491 //....oooOO0OOooo........oooOO0OOooo........oo    485 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
492                                                   486 
493 G4ThreeVector&                                    487 G4ThreeVector& 
494 G4WentzelVIModel::SampleScattering(const G4Thr    488 G4WentzelVIModel::SampleScattering(const G4ThreeVector& oldDirection,
495                                    G4double /*    489                                    G4double /*safety*/)
496 {                                                 490 {
497   fDisplacement.set(0.0,0.0,0.0);                 491   fDisplacement.set(0.0,0.0,0.0);
498   //G4cout << "!##! G4WentzelVIModel::SampleSc    492   //G4cout << "!##! G4WentzelVIModel::SampleScattering for " 
499   //         << particle->GetParticleName() <<    493   //         << particle->GetParticleName() << G4endl;
500                                                   494 
501   // ignore scattering for zero step length an    495   // ignore scattering for zero step length and energy below the limit
502   if(preKinEnergy < lowEnergyLimit || tPathLen    496   if(preKinEnergy < lowEnergyLimit || tPathLength <= 0.0) 
503     { return fDisplacement; }                     497     { return fDisplacement; }
504                                                   498   
505   G4double invlambda = 0.0;                       499   G4double invlambda = 0.0;
506   if(lambdaeff < DBL_MAX) { invlambda = 0.5/la    500   if(lambdaeff < DBL_MAX) { invlambda = 0.5/lambdaeff; }
507                                                   501 
508   // use average kinetic energy over the step     502   // use average kinetic energy over the step
509   G4double cut = (*currentCuts)[currentMateria    503   G4double cut = (*currentCuts)[currentMaterialIndex];
510   if(fixedCut > 0.0) { cut = fixedCut; }          504   if(fixedCut > 0.0) { cut = fixedCut; }
511   /*                                              505   /*  
512   G4cout <<"SampleScat: E0(MeV)= "<< preKinEne    506   G4cout <<"SampleScat: E0(MeV)= "<< preKinEnergy/MeV
513            << " Leff= " << lambdaeff <<" sig0(    507            << " Leff= " << lambdaeff <<" sig0(1/mm)= " << xtsec 
514           << " xmsc= " <<  tPathLength*invlamb    508           << " xmsc= " <<  tPathLength*invlambda 
515          << " safety= " << safety << G4endl;      509          << " safety= " << safety << G4endl;
516   */                                              510   */
517   // step limit due msc                           511   // step limit due msc
518   G4int nMscSteps = 1;                            512   G4int nMscSteps = 1;
519   G4double x0 = tPathLength;                      513   G4double x0 = tPathLength;
520   G4double z0 = x0*invlambda;                     514   G4double z0 = x0*invlambda;
                                                   >> 515   //G4double zzz = 0.0;
521   G4double prob2 = 0.0;                           516   G4double prob2 = 0.0;
522                                                   517 
523   CLHEP::HepRandomEngine* rndmEngine = G4Rando    518   CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
524                                                   519 
525   // large scattering angle case - two step ap    520   // large scattering angle case - two step approach
526   if(!singleScatteringMode) {                     521   if(!singleScatteringMode) {
                                                   >> 522     static const G4double zzmin = 0.05;
527     if(useSecondMoment) {                         523     if(useSecondMoment) { 
528       G4double z1 = invlambda*invlambda;          524       G4double z1 = invlambda*invlambda;
529       G4double z2 = SecondMoment(particle, cur    525       G4double z2 = SecondMoment(particle, currentCouple, effKinEnergy);
530       prob2 = (z2 - z1)/(1.5*z1 - z2);            526       prob2 = (z2 - z1)/(1.5*z1 - z2);
531     }                                             527     }
532     // numerical limitation on step length for << 528     //    if(z0 > zzmin && safety > tlimitminfix) { 
533     if (z0 > 0.05 && z0 < 30.) {               << 529     if(z0 > zzmin) { 
534       x0 *= 0.5;                                  530       x0 *= 0.5; 
535       z0 *= 0.5;                                  531       z0 *= 0.5;
536       nMscSteps = 2;                              532       nMscSteps = 2;
537       G4double zzz = G4Exp(-1.0/z0);           << 533     } 
                                                   >> 534     //if(z0 > zzmin) { zzz = G4Exp(-1.0/z0); }
                                                   >> 535     G4double zzz = 0.0;
                                                   >> 536     if(z0 > zzmin) { 
                                                   >> 537       zzz = G4Exp(-1.0/z0); 
538       z0 += zzz;                                  538       z0 += zzz; 
539       prob2 *= (1.0 + zzz);                    << 539       prob2 *= (1 + zzz);
540     }                                             540     }
541     prob2 /= (1.0 + prob2);                    << 541     prob2 /= (1 + prob2);
542   }                                               542   } 
543                                                   543 
544   // step limit due to single scattering          544   // step limit due to single scattering
545   G4double x1 = 2*tPathLength;                    545   G4double x1 = 2*tPathLength;
546   if(0.0 < xtsec) { x1 = -G4Log(rndmEngine->fl    546   if(0.0 < xtsec) { x1 = -G4Log(rndmEngine->flat())/xtsec; }
547                                                   547 
548   // no scattering case                           548   // no scattering case
549   if(singleScatteringMode && x1 > tPathLength)    549   if(singleScatteringMode && x1 > tPathLength)  
550     { return fDisplacement; }                     550     { return fDisplacement; }
551                                                   551 
552   const G4ElementVector* theElementVector =       552   const G4ElementVector* theElementVector = 
553     currentMaterial->GetElementVector();          553     currentMaterial->GetElementVector();
554   std::size_t nelm = currentMaterial->GetNumbe << 554   G4int nelm = currentMaterial->GetNumberOfElements();
555                                                   555 
556   // geometry                                     556   // geometry
557   G4double sint, cost, phi;                       557   G4double sint, cost, phi;
558   G4ThreeVector temp(0.0,0.0,1.0);                558   G4ThreeVector temp(0.0,0.0,1.0);
559                                                   559 
560   // current position and direction relative t    560   // current position and direction relative to the end point
561   // because of magnetic field geometry is com    561   // because of magnetic field geometry is computed relatively to the 
562   // end point of the step                        562   // end point of the step 
563   G4ThreeVector dir(0.0,0.0,1.0);                 563   G4ThreeVector dir(0.0,0.0,1.0);
564   fDisplacement.set(0.0,0.0,-zPathLength);        564   fDisplacement.set(0.0,0.0,-zPathLength);
565                                                   565 
566   G4double mscfac = zPathLength/tPathLength;      566   G4double mscfac = zPathLength/tPathLength;
567                                                   567 
568   // start a loop                                 568   // start a loop 
569   G4double x2 = x0;                               569   G4double x2 = x0;
570   G4double step, z;                               570   G4double step, z;
571   G4bool singleScat;                              571   G4bool singleScat;
572   /*                                              572   /*   
573     G4cout << "Start of the loop x1(mm)= " <<     573     G4cout << "Start of the loop x1(mm)= " << x1 << "  x2(mm)= " << x2 
574     << " 1-cost1= " << 1 - cosThetaMin << " SS    574     << " 1-cost1= " << 1 - cosThetaMin << " SSmode= " << singleScatteringMode 
575            << " xtsec= " << xtsec << " Nst= "     575            << " xtsec= " << xtsec << " Nst= "  << nMscSteps << G4endl;
576   */                                              576   */
577   do {                                            577   do {
578                                                   578 
579     //G4cout << "# x1(mm)= "<< x1<< " x2(mm)=     579     //G4cout << "# x1(mm)= "<< x1<< " x2(mm)= "<< x2 << G4endl;
580     // single scattering case                     580     // single scattering case
581     if(singleScatteringMode && x1 > x2) {         581     if(singleScatteringMode && x1 > x2) { 
582       fDisplacement += x2*mscfac*dir;             582       fDisplacement += x2*mscfac*dir;
583       break;                                      583       break; 
584     }                                             584     }
585                                                   585 
586     // what is next single of multiple?           586     // what is next single of multiple?
587     if(x1 <= x2) {                                587     if(x1 <= x2) { 
588       step = x1;                                  588       step = x1;
589       singleScat = true;                          589       singleScat = true;
590     } else {                                      590     } else {
591       step = x2;                                  591       step = x2;
592       singleScat = false;                         592       singleScat = false;
593     }                                             593     }
594                                                   594 
595     //G4cout << "# step(mm)= "<< step<< "  sin    595     //G4cout << "# step(mm)= "<< step<< "  singlScat= "<< singleScat << G4endl;
596                                                   596 
597     // new position                               597     // new position
598     fDisplacement += step*mscfac*dir;             598     fDisplacement += step*mscfac*dir;
599                                                   599 
600     if(singleScat) {                              600     if(singleScat) {
601                                                   601 
602       // select element                           602       // select element
603       std::size_t i = 0;                       << 603       G4int i = 0;
604       if(nelm > 1) {                              604       if(nelm > 1) {
605         G4double qsec = rndmEngine->flat()*xts    605         G4double qsec = rndmEngine->flat()*xtsec;
606         for (; i<nelm; ++i) { if(xsecn[i] >= q    606         for (; i<nelm; ++i) { if(xsecn[i] >= qsec) { break; } }
607       }                                           607       }
608       G4double cosTetM =                          608       G4double cosTetM = 
609         wokvi->SetupTarget((*theElementVector)    609         wokvi->SetupTarget((*theElementVector)[i]->GetZasInt(), cut);
610       //G4cout << "!!! " << cosThetaMin << "      610       //G4cout << "!!! " << cosThetaMin << "  " << cosTetM << "  " 
611       //     << prob[i] << G4endl;                611       //     << prob[i] << G4endl;
612       temp = wokvi->SampleSingleScattering(cos    612       temp = wokvi->SampleSingleScattering(cosThetaMin, cosTetM, prob[i]);
613                                                   613 
614       // direction is changed                     614       // direction is changed
615       temp.rotateUz(dir);                         615       temp.rotateUz(dir);
616       dir = temp;                                 616       dir = temp;
617       //G4cout << dir << G4endl;                  617       //G4cout << dir << G4endl;
618                                                   618 
619       // new proposed step length                 619       // new proposed step length
620       x2 -= step;                                 620       x2 -= step; 
621       x1  = -G4Log(rndmEngine->flat())/xtsec;     621       x1  = -G4Log(rndmEngine->flat())/xtsec; 
622                                                   622 
623     // multiple scattering                        623     // multiple scattering
624     } else {                                      624     } else { 
625       --nMscSteps;                                625       --nMscSteps;
626       x1 -= step;                                 626       x1 -= step;
627       x2  = x0;                                   627       x2  = x0;
628                                                   628 
629       // sample z in interval 0 - 1               629       // sample z in interval 0 - 1
630       G4bool isFirst = true;                      630       G4bool isFirst = true;
631       if(prob2 > 0.0 && rndmEngine->flat() < p    631       if(prob2 > 0.0 && rndmEngine->flat() < prob2) { isFirst = false; } 
632       do {                                        632       do {
                                                   >> 633         //z = -z0*G4Log(1.0 - (1.0 - zzz)*rndmEngine->flat());
633         if(isFirst) { z = -G4Log(rndmEngine->f    634         if(isFirst) { z = -G4Log(rndmEngine->flat()); }
634         else        { z = G4RandGamma::shoot(r    635         else        { z = G4RandGamma::shoot(rndmEngine, 2.0, 2.0); }
635         z *= z0;                                  636         z *= z0;
636         // Loop checking, 03-Aug-2015, Vladimi    637         // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
637       } while(z > 1.0);                           638       } while(z > 1.0);
638                                                   639 
639       cost = 1.0 - 2.0*z/*factCM*/;               640       cost = 1.0 - 2.0*z/*factCM*/;
640       if(cost > 1.0)       { cost = 1.0; }        641       if(cost > 1.0)       { cost = 1.0; }
641       else if(cost < -1.0) { cost =-1.0; }        642       else if(cost < -1.0) { cost =-1.0; }
642       sint = sqrt((1.0 - cost)*(1.0 + cost));     643       sint = sqrt((1.0 - cost)*(1.0 + cost));
643       phi  = twopi*rndmEngine->flat();            644       phi  = twopi*rndmEngine->flat();
644       G4double vx1 = sint*std::cos(phi);       << 645       G4double vx1 = sint*cos(phi);
645       G4double vy1 = sint*std::sin(phi);       << 646       G4double vy1 = sint*sin(phi);
646                                                   647 
647       // lateral displacement                     648       // lateral displacement  
648       if (latDisplasment) {                       649       if (latDisplasment) {
649         G4double rms = z0 > 0.0 ? invsqrt12*st << 650         G4double rms = invsqrt12*sqrt(2*z0);
650         G4double r  = x0*mscfac;                  651         G4double r  = x0*mscfac;
651         G4double dx = r*(0.5*vx1 + rms*G4RandG    652         G4double dx = r*(0.5*vx1 + rms*G4RandGauss::shoot(rndmEngine,0.0,1.0));
652         G4double dy = r*(0.5*vy1 + rms*G4RandG    653         G4double dy = r*(0.5*vy1 + rms*G4RandGauss::shoot(rndmEngine,0.0,1.0));
653         G4double d  = r*r - dx*dx - dy*dy;        654         G4double d  = r*r - dx*dx - dy*dy;
654                                                   655 
655         // change position                        656         // change position
656         if(d >= 0.0)  {                           657         if(d >= 0.0)  { 
657           temp.set(dx, dy, std::sqrt(d) - r);  << 658           temp.set(dx,dy,sqrt(d) - r);
658           temp.rotateUz(dir);                     659           temp.rotateUz(dir); 
659           fDisplacement += temp;                  660           fDisplacement += temp;
660         }                                         661         }
661       }                                           662       }
662       // change direction                         663       // change direction
663       temp.set(vx1,vy1,cost);                     664       temp.set(vx1,vy1,cost);
664       temp.rotateUz(dir);                         665       temp.rotateUz(dir);
665       dir = temp;                                 666       dir = temp;
666     }                                             667     }
667     // Loop checking, 03-Aug-2015, Vladimir Iv    668     // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
668   } while (0 < nMscSteps);                        669   } while (0 < nMscSteps);
669                                                   670     
670   dir.rotateUz(oldDirection);                     671   dir.rotateUz(oldDirection);
671                                                   672 
672   //G4cout<<"G4WentzelVIModel sampling is done    673   //G4cout<<"G4WentzelVIModel sampling is done 1-cost= "<< 1.-dir.z()<<G4endl;
673   // end of sampling -------------------------    674   // end of sampling -------------------------------
674                                                   675 
675   fParticleChange->ProposeMomentumDirection(di    676   fParticleChange->ProposeMomentumDirection(dir);
676                                                   677 
677   // lateral displacement                         678   // lateral displacement  
678   fDisplacement.rotateUz(oldDirection);           679   fDisplacement.rotateUz(oldDirection);
679                                                   680 
680   /*                                              681   /*
681          G4cout << " r(mm)= " << fDisplacement    682          G4cout << " r(mm)= " << fDisplacement.mag() 
682                 << " safety= " << safety          683                 << " safety= " << safety
683                 << " trueStep(mm)= " << tPathL    684                 << " trueStep(mm)= " << tPathLength
684                 << " geomStep(mm)= " << zPathL    685                 << " geomStep(mm)= " << zPathLength
685                 << " x= " << fDisplacement.x()    686                 << " x= " << fDisplacement.x() 
686                 << " y= " << fDisplacement.y()    687                 << " y= " << fDisplacement.y() 
687                 << " z= " << fDisplacement.z()    688                 << " z= " << fDisplacement.z()
688                 << G4endl;                        689                 << G4endl;
689   */                                              690   */
690                                                   691 
691   //G4cout<< "G4WentzelVIModel::SampleScatteri    692   //G4cout<< "G4WentzelVIModel::SampleScattering end NewDir= " << dir<< G4endl;
692   return fDisplacement;                           693   return fDisplacement;
693 }                                                 694 }
694                                                   695 
695 //....oooOO0OOooo........oooOO0OOooo........oo    696 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
696                                                   697 
697 G4double G4WentzelVIModel::ComputeTransportXSe    698 G4double G4WentzelVIModel::ComputeTransportXSectionPerVolume(G4double cosTheta)
698 {                                                 699 {
699   // prepare recomputation of x-sections          700   // prepare recomputation of x-sections
700   const G4ElementVector* theElementVector = cu    701   const G4ElementVector* theElementVector = currentMaterial->GetElementVector();
701   const G4double* theAtomNumDensityVector =       702   const G4double* theAtomNumDensityVector = 
702     currentMaterial->GetVecNbOfAtomsPerVolume(    703     currentMaterial->GetVecNbOfAtomsPerVolume();
703   G4int nelm = (G4int)currentMaterial->GetNumb << 704   G4int nelm = currentMaterial->GetNumberOfElements();
704   if(nelm > nelments) {                           705   if(nelm > nelments) {
705     nelments = nelm;                              706     nelments = nelm;
706     xsecn.resize(nelm);                           707     xsecn.resize(nelm);
707     prob.resize(nelm);                            708     prob.resize(nelm);
708   }                                               709   }
709                                                   710 
710   // check consistency                            711   // check consistency
711   xtsec = 0.0;                                    712   xtsec = 0.0;
712   if(cosTetMaxNuc >= cosTheta) { return 0.0; }    713   if(cosTetMaxNuc >= cosTheta) { return 0.0; }
713                                                   714 
714   G4double cut = (*currentCuts)[currentMateria    715   G4double cut = (*currentCuts)[currentMaterialIndex];
715   if(fixedCut > 0.0) { cut = fixedCut; }          716   if(fixedCut > 0.0) { cut = fixedCut; }
716                                                   717 
717   // loop over elements                           718   // loop over elements
718   G4double xs = 0.0;                              719   G4double xs = 0.0;
719   for (G4int i=0; i<nelm; ++i) {                  720   for (G4int i=0; i<nelm; ++i) {
720     G4double costm =                              721     G4double costm = 
721       wokvi->SetupTarget((*theElementVector)[i    722       wokvi->SetupTarget((*theElementVector)[i]->GetZasInt(), cut);
722     G4double density = theAtomNumDensityVector    723     G4double density = theAtomNumDensityVector[i];
723                                                   724 
724     G4double esec = 0.0;                          725     G4double esec = 0.0;
725     if(costm < cosTheta) {                        726     if(costm < cosTheta) {  
726                                                   727 
727       // recompute the transport x-section        728       // recompute the transport x-section
728       if(1.0 > cosTheta) {                        729       if(1.0 > cosTheta) {
729         xs += density*wokvi->ComputeTransportC    730         xs += density*wokvi->ComputeTransportCrossSectionPerAtom(cosTheta);
730       }                                           731       }
731       // recompute the total x-section            732       // recompute the total x-section
732       G4double nucsec = wokvi->ComputeNuclearC    733       G4double nucsec = wokvi->ComputeNuclearCrossSection(cosTheta, costm);
733       esec = wokvi->ComputeElectronCrossSectio    734       esec = wokvi->ComputeElectronCrossSection(cosTheta, costm);
734       nucsec += esec;                             735       nucsec += esec;
735       if(nucsec > 0.0) { esec /= nucsec; }        736       if(nucsec > 0.0) { esec /= nucsec; }
736       xtsec += nucsec*density;                    737       xtsec += nucsec*density;
737     }                                             738     }
738     xsecn[i] = xtsec;                             739     xsecn[i] = xtsec;
739     prob[i]  = esec;                              740     prob[i]  = esec;
740     //G4cout << i << "  xs= " << xs << " xtsec    741     //G4cout << i << "  xs= " << xs << " xtsec= " << xtsec 
741     //       << " 1-cosTheta= " << 1-cosTheta     742     //       << " 1-cosTheta= " << 1-cosTheta 
742     //           << " 1-cosTetMaxNuc2= " <<1-c    743     //           << " 1-cosTetMaxNuc2= " <<1-cosTetMaxNuc2<< G4endl;
743   }                                               744   }
744                                                   745   
745   //G4cout << "ComputeXS result:  xsec(1/mm)=     746   //G4cout << "ComputeXS result:  xsec(1/mm)= " << xs 
746   //         << " txsec(1/mm)= " << xtsec <<G4    747   //         << " txsec(1/mm)= " << xtsec <<G4endl; 
747   return xs;                                      748   return xs;
748 }                                                 749 }
749                                                   750 
750 //....oooOO0OOooo........oooOO0OOooo........oo    751 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
751                                                   752 
752 G4double G4WentzelVIModel::ComputeSecondMoment << 753 G4double G4WentzelVIModel:: ComputeSecondMoment(const G4ParticleDefinition* p,
753                  G4double kinEnergy)           << 754                                                 G4double kinEnergy)
754 {                                                 755 {
755   G4double xs = 0.0;                              756   G4double xs = 0.0;
756                                                   757 
757   SetupParticle(p);                               758   SetupParticle(p);
758   cosTetMaxNuc = wokvi->SetupKinematic(kinEner    759   cosTetMaxNuc = wokvi->SetupKinematic(kinEnergy, currentMaterial);
759                                                   760 
760   if(cosTetMaxNuc >= 1.0) { return xs; }          761   if(cosTetMaxNuc >= 1.0) { return xs; }
761                                                   762 
762   const G4ElementVector* theElementVector = cu    763   const G4ElementVector* theElementVector = currentMaterial->GetElementVector();
763   const G4double* theAtomNumDensityVector =       764   const G4double* theAtomNumDensityVector = 
764     currentMaterial->GetVecNbOfAtomsPerVolume(    765     currentMaterial->GetVecNbOfAtomsPerVolume();
765   std::size_t nelm = currentMaterial->GetNumbe << 766   G4int nelm = currentMaterial->GetNumberOfElements();
766                                                   767 
767   G4double cut = (*currentCuts)[currentMateria    768   G4double cut = (*currentCuts)[currentMaterialIndex];
768   if(fixedCut > 0.0) { cut = fixedCut; }          769   if(fixedCut > 0.0) { cut = fixedCut; }
769                                                   770 
770   // loop over elements                           771   // loop over elements
771   for (std::size_t i=0; i<nelm; ++i) {         << 772   for (G4int i=0; i<nelm; ++i) {
772     G4double costm =                              773     G4double costm = 
773       wokvi->SetupTarget((*theElementVector)[i    774       wokvi->SetupTarget((*theElementVector)[i]->GetZasInt(), cut);
774     xs += theAtomNumDensityVector[i]              775     xs += theAtomNumDensityVector[i]
775       *wokvi->ComputeSecondTransportMoment(cos    776       *wokvi->ComputeSecondTransportMoment(costm);
776   }                                               777   }
777   return xs;                                      778   return xs;
778 }                                                 779 }
779                                                   780 
780 //....oooOO0OOooo........oooOO0OOooo........oo    781 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
781                                                   782 
782 void G4WentzelVIModel::SetSingleScatteringFact    783 void G4WentzelVIModel::SetSingleScatteringFactor(G4double val)
783 {                                                 784 {
784   if(val > 0.05) {                                785   if(val > 0.05) {
785     ssFactor = val;                               786     ssFactor = val;
786     invssFactor = 1.0/(val - 0.05);               787     invssFactor = 1.0/(val - 0.05);
787   }                                               788   }
788 }                                                 789 }
789                                                   790 
790 //....oooOO0OOooo........oooOO0OOooo........oo    791 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
791                                                   792