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