Ignore:
Timestamp:
Apr 6, 2009, 12:21:12 PM (15 years ago)
Author:
garnier
Message:

update processes

Location:
trunk/source/processes/electromagnetic/utils/src
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/processes/electromagnetic/utils/src/G4DummyModel.cc

    r819 r961  
    2525//
    2626// $Id: G4DummyModel.cc,v 1.3 2007/05/22 17:31:58 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
  • trunk/source/processes/electromagnetic/utils/src/G4EmCalculator.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmCalculator.cc,v 1.37 2007/08/16 15:55:42 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4EmCalculator.cc,v 1.46 2009/02/24 09:56:03 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5555//            10 keV to 1 keV (V. Ivanchenko)
    5656// 15.03.2007 Add ComputeEnergyCutFromRangeCut methods (V.Ivanchenko)
     57// 21.04.2008 Updated computations for ions (V.Ivanchenko)
    5758//
    5859// Class Description:
     
    126127  if(couple && UpdateParticle(p, kinEnergy) ) {
    127128    res = manager->GetDEDX(p, kinEnergy, couple);
     129    if(isIon) {
     130      G4double eth = 2.0*MeV/massRatio;
     131      if(kinEnergy > eth) {
     132        G4double x1 = corr->ComputeIonCorrections(p,mat,kinEnergy);
     133        G4double x2 = corr->ComputeIonCorrections(p,mat,eth);
     134        res += x1 - x2*eth/kinEnergy;
     135        /*     
     136        G4cout << "### GetDEDX: E= " << kinEnergy << " res= " << res
     137               << " x1= " << x1 << " x2= " << x2
     138               << " del= " << x1 - x2*eth/kinEnergy << G4endl;;
     139        */
     140      }
     141    }
     142
    128143    if(verbose>0) {
    129144      G4cout << "G4EmCalculator::GetDEDX: E(MeV)= " << kinEnergy/MeV
     
    406421        res = currentModel->ComputeDEDXPerVolume(
    407422              mat, baseParticle, escaled, cut) * chargeSquare;
    408         if(verbose > 1)
     423        if(verbose > 1) {
    409424          G4cout <<  baseParticle->GetParticleName()
    410425                 << " Escaled(MeV)= " << escaled;
     426        }
    411427      } else {
    412428        res = currentModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cut);
    413429        if(verbose > 1) G4cout <<  " no basePart E(MeV)= " << kinEnergy;
    414430      }
    415       if(verbose > 1)
     431      if(verbose > 1) {
    416432        G4cout << " DEDX(MeV/mm)= " << res*mm/MeV
    417433               << " DEDX(MeV*cm^2/g)= "
    418434               << res*gram/(MeV*cm2*mat->GetDensity())
    419435               << G4endl;
    420 
    421       if(isIon) {
    422         if(currentModel->HighEnergyLimit() > 100.*MeV)
    423           res += corr->HighOrderCorrections(p,mat,kinEnergy);
    424         else
    425           res *= corr->EffectiveChargeCorrection(p,mat,kinEnergy);
    426         if(verbose > 1)
    427           G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV
    428                  << " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
    429                  << G4endl;
    430       }
    431 
    432      
     436      }
     437
    433438      // emulate boundary region for different parameterisations
    434439      G4double eth = currentModel->LowEnergyLimit();
     
    447452          res0 = loweModel->ComputeDEDXPerVolume(mat, p, eth, cut);
    448453        }
    449         if(verbose > 1)
     454        if(verbose > 1) {
    450455          G4cout << "At boundary energy(MeV)= " << eth/MeV
    451456                 << " DEDX(MeV/mm)= " << res1*mm/MeV
    452457                 << G4endl;
    453         if(isIon) res1 += corr->HighOrderCorrections(p,mat,eth/massRatio);
    454         //G4cout << "eth= " << eth << " escaled= " << escaled
    455         //  << " res0= " << res0 << " res1= "
    456         //       << res1 <<  "  q2= " << chargeSquare << G4endl;
     458        }
     459        /*
     460        G4cout << "eth= " << eth << " escaled= " << escaled
     461               << " res0= " << res0 << " res1= "
     462               << res1 <<  "  q2= " << chargeSquare << G4endl;
     463        */
    457464        res *= (1.0 + (res0/res1 - 1.0)*eth/escaled);
     465
     466        if(isIon) {
     467          G4double ethscaled = eth/massRatio;
     468          if(kinEnergy > ethscaled) {
     469            G4double x1 = corr->ComputeIonCorrections(p,mat,kinEnergy);
     470            G4double x2 = corr->ComputeIonCorrections(p,mat,ethscaled);
     471            res += x1 - x2*ethscaled/kinEnergy;
     472          }
     473       
     474          if(verbose > 1) {
     475            G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV
     476                   << " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
     477                   << G4endl;
     478          }
     479        }
    458480      }
    459481     
     
    507529//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    508530
    509 G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4ParticleDefinition* part,
    510                                           const G4Material* mat, G4double cut)
     531G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy,
     532                                          const G4ParticleDefinition* part,
     533                                          const G4Material* mat,
     534                                          G4double cut)
    511535{
    512536  G4double dedx = ComputeElectronicDEDX(kinEnergy,part,mat,cut);
     
    517541//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    518542
    519 G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4String& part,
    520                                           const G4String& mat, G4double cut)
     543G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy,
     544                                          const G4String& part,
     545                                          const G4String& mat,
     546                                          G4double cut)
    521547{
    522548  return ComputeTotalDEDX(kinEnergy,FindParticle(part),FindMaterial(mat),cut);
     
    729755    if(currentProcess) currentProcessName = currentProcess->GetProcessName();
    730756
    731     if(p->GetParticleType() == "nucleus" &&
    732        currentParticleName  != "deuteron" && currentParticleName != "triton") {
     757    if(p->GetParticleType() == "nucleus"
     758       && currentParticleName != "deuteron" 
     759       && currentParticleName != "triton"
     760       && currentParticleName != "alpha+"
     761       && currentParticleName != "helium"
     762       && currentParticleName != "hydrogen"
     763      ) {
    733764      baseParticle = theGenericIon;
    734765      massRatio = baseParticle->GetPDGMass()/p->GetPDGMass();
     
    755786  if(isIon) {
    756787    chargeSquare =
    757      ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy);
    758     if(currentProcess)
     788     ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy)
     789      * corr->EffectiveChargeCorrection(p,currentMaterial,kinEnergy);
     790    if(currentProcess) {
    759791      currentProcess->SetDynamicMassCharge(massRatio,chargeSquare);
    760     // G4cout << "massR= " << massRatio << "   q2= " << chargeSquare << G4endl;
     792      //G4cout << "NewP: massR= " << massRatio << "   q2= " << chargeSquare << G4endl;
     793    }
    761794  }
    762795  return true;
  • trunk/source/processes/electromagnetic/utils/src/G4EmCorrections.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmCorrections.cc,v 1.23.2.1 2008/04/22 15:28:13 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4EmCorrections.cc,v 1.51 2008/12/18 13:01:44 gunter Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4444// 08.05.2007 V.Ivanchenko Use G4IonTable for ion mass instead of NistTable to avoid
    4545//                         division by zero
     46// 29.02.2008 V.Ivanchenko use expantions for log and power function
     47// 21.04.2008 Updated computations for ions (V.Ivanchenko)
     48// 20.05.2008 Removed Finite Size correction (V.Ivanchenko)
    4649//
    4750//
     
    5659#include "G4EmCorrections.hh"
    5760#include "Randomize.hh"
    58 #include "G4NistManager.hh"
    5961#include "G4ParticleTable.hh"
    6062#include "G4IonTable.hh"
    6163#include "G4VEmModel.hh"
    6264#include "G4Proton.hh"
     65#include "G4GenericIon.hh"
    6366#include "G4LPhysicsFreeVector.hh"
     67#include "G4PhysicsLogVector.hh"
     68#include "G4ProductionCutsTable.hh"
     69#include "G4MaterialCutsCouple.hh"
    6470
    6571//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    6773G4EmCorrections::G4EmCorrections()
    6874{
    69   Initialise();
    7075  particle   = 0;
    7176  curParticle= 0;
     
    7479  curVector  = 0;
    7580  kinEnergy  = 0.0;
    76   ionModel   = 0;
     81  ionLEModel = 0;
     82  ionHEModel = 0;
    7783  nIons      = 0;
    7884  verbose    = 1;
     85  ncouples   = 0;
    7986  massFactor = 1.0;
     87  eth        = 2.0*MeV;
     88  nbinCorr   = 20;
     89  eCorrMin   = 25.*keV;
     90  eCorrMax   = 250.*MeV;
    8091  nist = G4NistManager::Instance();
    8192  ionTable = G4ParticleTable::GetParticleTable()->GetIonTable();
     93  Initialise();
    8294}
    8395
     
    93105G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
    94106                                               const G4Material* mat,
    95                                                G4double e)
     107                                               G4double e, G4double)
    96108{
    97109// . Z^3 Barkas effect in the stopping power of matter for charged particles
     
    108120  G4double Bloch  = BlochCorrection (p, mat, e);
    109121  G4double Mott   = MottCorrection (p, mat, e);
    110   G4double FSize  = FiniteSizeCorrection (p, mat, e);
    111 
    112   G4double sum = (2.0*(Barkas + Bloch) + FSize + Mott);
     122
     123  G4double sum = (2.0*(Barkas + Bloch) + Mott);
    113124
    114125  if(verbose > 1)
    115126    G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas
    116            << " Bloch= " << Bloch << " Mott= " << Mott << " Fsize= " << FSize
     127           << " Bloch= " << Bloch << " Mott= " << Mott
    117128           << " Sum= " << sum << G4endl;
    118129
    119130  sum *= material->GetElectronDensity() * q2 *  twopi_mc2_rcl2 /beta2;
     131  return sum;
     132}
     133
     134//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     135
     136G4double G4EmCorrections::IonBarkasCorrection(const G4ParticleDefinition* p,
     137                                              const G4Material* mat,
     138                                              G4double e)
     139{
     140// . Z^3 Barkas effect in the stopping power of matter for charged particles
     141//   J.C Ashley and R.H.Ritchie
     142//   Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
     143//   and ICRU49 report
     144//   valid for kineticEnergy < 0.5 MeV
     145
     146  SetupKinematics(p, mat, e);
     147  G4double res = 0.0;
     148  if(tau > 0.0)
     149    res = 2.0*BarkasCorrection(p, mat, e)*
     150      material->GetElectronDensity() * q2 *  twopi_mc2_rcl2 /beta2;
     151  return res;
     152}
     153
     154//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     155
     156G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p,
     157                                                const G4Material* mat,
     158                                                G4double e)
     159{
     160// . Z^3 Barkas effect in the stopping power of matter for charged particles
     161//   J.C Ashley and R.H.Ritchie
     162//   Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
     163//   and ICRU49 report
     164//   valid for kineticEnergy < 0.5 MeV
     165//   Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
     166  SetupKinematics(p, mat, e);
     167  if(tau <= 0.0) return 0.0;
     168
     169  G4double Barkas = BarkasCorrection (p, mat, e);
     170  G4double Bloch  = BlochCorrection (p, mat, e);
     171  G4double Mott   = MottCorrection (p, mat, e);
     172
     173  G4double sum = 2.0*(Barkas*(charge - 1.0)/charge + Bloch) + Mott;
     174
     175  if(verbose > 1) {
     176    G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas
     177           << " Bloch= " << Bloch << " Mott= " << Mott
     178           << " Sum= " << sum << G4endl;
     179  }
     180  sum *= material->GetElectronDensity() * q2 *  twopi_mc2_rcl2 /beta2;
     181
     182  if(verbose > 1) G4cout << " Sum= " << sum << G4endl;
     183  return sum;
     184}
     185
     186//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     187
     188G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p,
     189                                                  const G4MaterialCutsCouple* couple,
     190                                                  G4double e)
     191{
     192// . Z^3 Barkas effect in the stopping power of matter for charged particles
     193//   J.C Ashley and R.H.Ritchie
     194//   Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
     195//   and ICRU49 report
     196//   valid for kineticEnergy < 0.5 MeV
     197//   Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
     198
     199  G4double sum = 0.0;
     200
     201  if(ionHEModel) {
     202    G4int Z = G4int(p->GetPDGCharge()/eplus + 0.5);
     203    if(Z >= 100)   Z = 99;
     204    else if(Z < 1) Z = 1;
     205
     206    // fill vector
     207    if(thcorr[Z].size() == 0) {
     208      thcorr[Z].resize(ncouples);
     209      G4double ethscaled = eth*p->GetPDGMass()/proton_mass_c2;
     210
     211      for(size_t i=0; i<ncouples; i++) {
     212        (thcorr[Z])[i] = ethscaled*ComputeIonCorrections(p, currmat[i], ethscaled);
     213        //G4cout << i << ". ethscaled= " << ethscaled
     214        //<< " corr= " << (thcorr[Z])[i]/ethscaled << G4endl;
     215      }
     216    }
     217    G4double rest = (thcorr[Z])[couple->GetIndex()];
     218
     219    sum = ComputeIonCorrections(p,couple->GetMaterial(),e) - rest/e;
     220
     221    if(verbose > 1) G4cout << " Sum= " << sum << " dSum= " << rest/e << G4endl;
     222  }
    120223  return sum;
    121224}
     
    226329    G4int ieta = Index(y, Eta, nEtaK);
    227330    corr = Value2(x, y, TheK[itet], TheK[itet+1], Eta[ieta], Eta[ieta+1],
    228                   CK[itet][ieta], CK[itet+1][ieta], CK[itet][ieta+1], CK[itet+1][ieta+1]);
     331                  CK[itet][ieta], CK[itet+1][ieta],
     332                  CK[itet][ieta+1], CK[itet+1][ieta+1]);
    229333    //G4cout << "   x= " <<x<<" y= "<<y<<" tet= " <<TheK[itet]
    230334    //<<" "<< TheK[itet+1]<<" eta= "<< Eta[ieta]<<" "<< Eta[ieta+1]
     
    439543    else {
    440544      G4int iw = Index(W, engBarkas, 47);
    441       val = Value(W, engBarkas[iw], engBarkas[iw+1], corBarkas[iw], corBarkas[iw+1]);
     545      val = Value(W, engBarkas[iw], engBarkas[iw+1],
     546                  corBarkas[iw], corBarkas[iw+1]);
    442547    }
    443548    //    G4cout << "i= " << i << " b= " << b << " W= " << W
     
    479584{
    480585  SetupKinematics(p, mat, e);
    481   G4double mterm = pi*fine_structure_const*beta*charge;
    482   /*
    483   G4double mterm = 0.0;
    484   if(beta > 0.0) {
    485 
    486     // Estimation of mean square root of the ionisation potential
    487     G4double Zeff = 0.0;
    488     G4double norm = 0.0;
    489 
    490     for (G4int i = 0; i<numberOfElements; i++) {
    491       G4double Z = (*theElementVector)[i]->GetZ();
    492       Zeff += Z*atomDensity[i];
    493       norm += atomDensity[i];
    494     }
    495     Zeff *= (2.0/norm);
    496     G4double ze1 = std::log(Zeff);
    497     G4double eexc= material->GetIonisation()->GetMeanExcitationEnergy()*ze1*ze1/Zeff;
    498 
    499     G4double invbeta = 1.0/beta;
    500     G4double invbeta2= invbeta*invbeta;
    501     G4double za  = charge*fine_structure_const;
    502     G4double za2 = za*za;
    503     G4double za3 = za2*za;
    504     G4double x   = za*invbeta;
    505     G4double cosx;
    506     if(x < COSEB[13]) {
    507       G4int i = Index(x,COSEB,14);
    508       cosx    = Value(x,COSEB[i], COSEB[i+1],COSXI[i],COSXI[i+1]);
    509     } else {
    510       cosx = COSXI[13]*COSEB[13]/x;
    511     }
    512 
    513     mterm =
    514       za*beta*(1.725 + pi*cosx*(0.52 - 2.0*std::sqrt(eexc/(2.0*electron_mass_c2*bg2))));
    515       + za2*(3.246 - 0.451*beta2)
    516       + za3*(1.522*beta + 0.987*invbeta)
    517       + za2*za2*(4.569 - 0.494*beta2 - 2.696*invbeta2)
    518       + za3*za2*(1.254*beta + 0.222*invbeta - 1.17*invbeta*invbeta2);
    519   }
    520 */ 
     586  G4double mterm = CLHEP::pi*fine_structure_const*beta*charge;
    521587  return mterm;
    522 }
    523 
    524 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    525 
    526 G4double G4EmCorrections::FiniteSizeCorrection(const G4ParticleDefinition* p,
    527                                                const G4Material* mat,
    528                                                G4double e)
    529   // Finite size corrections are parameterized according to
    530   // J.D.Jackson Phys. Rev. D59 (1998) 017301
    531 {
    532   if(p) return 0.0;
    533   SetupKinematics(p, mat, e);
    534   G4double term = 0.0;
    535   G4double numlim = 0.2;
    536 
    537   //Leptons
    538   if(p->GetLeptonNumber() != 0) {
    539     G4double x =  tmax/(e + mass);
    540     term = x*x;
    541 
    542     // Pions and Kaons
    543   } else if(p->GetPDGSpin() == 0.0 && q2 < 1.5) {
    544     G4double xpi = 0.736*GeV;
    545     G4double x   = 2.0*electron_mass_c2*tmax0/(xpi*xpi);
    546     if(x <= numlim) term = -x*(1.0 - 0.5*x);
    547     else            term = -std::log(1.0 + x);
    548 
    549     // Protons and baryons
    550   } else if(q2 < 1.5) {
    551     G4double xp = 0.8426*GeV;
    552     G4double x  = 2.0*electron_mass_c2*tmax0/(xp*xp);
    553     G4double ksi2 = 2.79285*2.79285;
    554     if(x <= numlim) term = -x*((1.0 + 5.0*x/6.0)/((1.0 + x)*(1 + x)) + 0.5*x);
    555     else term = -x*(1.0 + 5.0*x/6.0)/((1.0 + x)*(1 + x)) - std::log(1.0 + x);
    556     G4double b  = xp*0.5/mass;
    557     G4double c  = xp*mass/(electron_mass_c2*(mass + e));
    558     G4double lb = b*b;
    559     G4double lb2= lb*lb;
    560     G4double nu = 0.5*c*c;
    561     G4double x1 = 1.0 + x;
    562     G4double x2 = x1*x1;
    563     G4double l1 = 1.0 - lb;
    564     G4double l2 = l1*l1;
    565     G4double lx = 1.0 + lb*x;
    566     G4double ia = lb2*(lx*std::log(lx/x1)/x + l1 -
    567                        0.5*x*l2/(lb*x1) +
    568                        x*(3.0 + 2.0*x)*l2*l1/(6.0*x2*lb2))/(l2*l2);
    569     G4double ib = x*x*(3.0 + x)/(6.0*x2*x1);
    570     term += lb*((ksi2 - 1.0)*ia + nu*ksi2*ib);
    571     // G4cout << "Proton F= " << term << " ia= " << ia << " ib= " << ib << " lb= " << lb<< G4endl;
    572    
    573     //ions
    574   } else {
    575     G4double xp = 0.8426*GeV/std::pow(mass/proton_mass_c2,-0.33333333);
    576     G4double x  = 2.0*electron_mass_c2*tmax0/(xp*xp);
    577     if(x <= numlim) term = -x*(1.0 - 0.5*x);
    578     else            term = -std::log(1.0 + x);
    579     //G4cout << "Ion F= " << term << G4endl;
    580   }
    581 
    582   return term;
    583588}
    584589
     
    629634  if (er >= ed[0])       nloss = a[0];
    630635  else {
     636    // the table is inverse in energy
    631637    for (G4int i=102; i>=0; i--)
    632638    {
     
    657663//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    658664
    659 G4ionEffectiveCharge* G4EmCorrections::GetIonEffectiveCharge(G4VEmModel* m)
    660 {
    661   if(m) ionModel = m;
    662   return &effCharge;
    663 }
    664 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    665 
    666 G4int G4EmCorrections::GetNumberOfStoppingVectors()
    667 {
    668   return nIons;
    669 }
    670 
    671 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    672 
    673665G4double G4EmCorrections::EffectiveChargeCorrection(const G4ParticleDefinition* p,
    674666                                                    const G4Material* mat,
     
    676668{
    677669  G4double factor = 1.0;
    678   if(p->GetPDGCharge() <= 2.5*eplus) return factor;
    679   if(verbose > 1)
    680     G4cout << "EffectiveChargeCorrection: " << p->GetParticleName() << " in " << mat->GetName()
     670  if(p->GetPDGCharge() <= 2.5*eplus || nIons <= 0) return factor;
     671  /*
     672  if(verbose > 1) {
     673    G4cout << "EffectiveChargeCorrection: " << p->GetParticleName()
     674           << " in " << mat->GetName()
    681675           << " ekin(MeV)= " << ekin/MeV << G4endl;
     676  }
     677  */
    682678  if(p != curParticle || mat != curMaterial) {
    683679    curParticle = p;
    684     curMaterial = 0;
     680    curMaterial = mat;
    685681    curVector   = 0;
    686     G4int Z = p->GetAtomicNumber();
    687     G4int A = p->GetAtomicMass();
    688     if(verbose > 1) G4cout << "Zion= " << Z << " Aion= " << A << G4endl;
    689     massFactor = proton_mass_c2/ionTable->GetIonMass(Z,A);
    690     idx = 0;
    691     for(; idx<nIons; idx++) {
    692       if(Z == Zion[idx] && A == Aion[idx]) {
    693         if(materialList[idx] == mat) {
    694           curMaterial = mat;
    695           curVector = stopData[idx];
    696           break;
    697         } else if(materialList[idx] == 0) {
    698           if(materialName[idx] == mat->GetName())
    699             curVector = InitialiseMaterial(mat);
    700         }
     682    currentZ = p->GetAtomicNumber();
     683    if(verbose > 1) {
     684      G4cout << "G4EmCorrections::EffectiveChargeCorrection: Zion= "
     685             << currentZ << " Aion= " << p->GetPDGMass()/amu_c2 << G4endl;
     686    }
     687    massFactor = proton_mass_c2/p->GetPDGMass();
     688    idx = -1;
     689    G4int dz = 1000;
     690
     691    for(G4int i=0; i<nIons; i++) {
     692      if(materialList[i] == mat) {
     693        G4int delz = currentZ - Zion[i];
     694        if(delz < 0) delz = -delz;
     695        if(delz < dz) {
     696          idx = i;
     697          dz = delz;
     698          if(0 == delz) break;
     699        }
    701700      }
     701    }
     702    //    G4cout << " idx= " << idx << " dz= " << dz << G4endl;
     703    if(idx > 0) {
     704      if(!ionList[idx]) BuildCorrectionVector();
     705      if(ionList[idx])  curVector = stopData[idx];
    702706    }
    703707  }
     
    705709    G4bool b;
    706710    factor = curVector->GetValue(ekin*massFactor,b);
    707   }
    708   if(verbose > 1) G4cout << "  factor= " << factor << G4endl;
     711    if(verbose > 1) {
     712      G4cout << "E= " << ekin << " factor= " << factor << " massfactor= "
     713             << massFactor << G4endl;
     714    }
     715  }
    709716  return factor;
    710717}
     
    714721void G4EmCorrections::AddStoppingData(G4int Z, G4int A,
    715722                                      const G4String& mname,
    716                                       G4PhysicsVector& dVector)
    717 {
    718   idx = 0;
    719   for(; idx<nIons; idx++) {
    720     if(Z == Zion[idx] && A == Aion[idx] && mname == materialName[idx])
    721       break;
    722   }
    723   if(idx == nIons) {
     723                                      G4PhysicsVector* dVector)
     724{
     725  G4int i = 0;
     726  for(; i<nIons; i++) {
     727    if(Z == Zion[i] && A == Aion[i] && mname == materialName[i]) break;
     728  }
     729  if(i == nIons) {
    724730    Zion.push_back(Z);
    725731    Aion.push_back(A);
    726732    materialName.push_back(mname);
    727733    materialList.push_back(0);
    728     stopData.push_back(0);
     734    ionList.push_back(0);
     735    stopData.push_back(dVector);
    729736    nIons++;
    730   } else {
    731     if(stopData[idx]) delete stopData[idx];
    732   }
    733   size_t nbins = dVector.GetVectorLength();
    734   size_t n = 0;
    735   for(; n<nbins; n++) {
    736     if(dVector.GetLowEdgeEnergy(n) > 2.0*MeV) break;
    737   }
    738   if(n < nbins) nbins = n + 1;
    739   G4LPhysicsFreeVector* v =
    740     new G4LPhysicsFreeVector(nbins,
    741                              dVector.GetLowEdgeEnergy(0),
    742                              dVector.GetLowEdgeEnergy(nbins-1));
     737    if(verbose>1) {
     738      G4cout << "AddStoppingData Z= " << Z << " A= " << A << " " << mname
     739             << "  idx= " << i << G4endl;
     740    }
     741  }
     742}
     743
     744//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     745
     746void G4EmCorrections::BuildCorrectionVector()
     747{
     748  if(!ionLEModel || !ionHEModel) {
     749    return;
     750  }
     751
     752  const G4ParticleDefinition* ion = curParticle;
     753  G4int Z = Zion[idx];
     754  if(currentZ != Z) {
     755    ion = G4ParticleTable::GetParticleTable()->FindIon(Z, Aion[idx], 0, Z);
     756  }
     757  //G4cout << "BuildCorrectionVector: idx= " << idx << " Z= " << Z
     758  //     << " curZ= " << currentZ << G4endl;
     759
     760  // G4double A = nist->GetAtomicMassAmu(Z);
     761  G4double A = G4double(ion->GetBaryonNumber());
     762  G4PhysicsVector* v = stopData[idx];
     763   
     764  const G4ParticleDefinition* p = G4GenericIon::GenericIon();
     765  G4double massRatio = proton_mass_c2/ion->GetPDGMass();
     766
     767  if(verbose>1) {
     768    G4cout << "BuildCorrectionVector: Stopping for "
     769           << curParticle->GetParticleName() << " in "
     770           << materialName[idx] << " Ion Z= " << Z << " A= " << A
     771           << " massRatio= " << massRatio << G4endl;
     772  }
    743773  G4bool b;
    744   for(size_t i=0; i<nbins; i++) {
    745     G4double e = dVector.GetLowEdgeEnergy(i);
    746     G4double dedx = dVector.GetValue(e, b);
    747     v->PutValues(i, e, dedx);
    748   }
    749   //  G4cout << *v << G4endl;
    750   stopData[idx] = v;
    751 }
    752 
    753 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    754 
    755 G4PhysicsVector* G4EmCorrections::InitialiseMaterial(const G4Material* mat)
    756 {
    757   G4PhysicsVector* v = 0;
    758   const G4Material* m = nist->FindOrBuildMaterial(materialName[idx],false);
    759   if(m) {
    760     materialList[idx] = m;
    761     curMaterial = mat;
    762     v = stopData[idx];
    763     size_t nbins = v->GetVectorLength();
    764     const G4ParticleDefinition* p = G4Proton::Proton();
    765     if(verbose>1) G4cout << "G4ionIonisation::InitialiseMaterial Stooping data for "
    766                          << materialName[idx] << G4endl;
    767     G4bool b;
    768     for(size_t i=0; i<nbins; i++) {
    769       G4double e = v->GetLowEdgeEnergy(i);
    770       G4double dedx = v->GetValue(e, b);
    771       G4double dedx1= ionModel->ComputeDEDXPerVolume(mat, p, e, e)*
    772         effCharge.EffectiveChargeSquareRatio(curParticle,mat,e/massFactor);
    773       v->PutValue(i, dedx/dedx1);
    774       if(verbose>1) G4cout << "  E(meV)= " << e/MeV << "   Correction= " << dedx/dedx1
    775                            << "   "  << dedx << " " << dedx1 << G4endl;
    776     }
    777   }
    778   return v;
     774
     775  G4PhysicsLogVector* vv =
     776    new G4PhysicsLogVector(eCorrMin,eCorrMax,nbinCorr);
     777  vv->SetSpline(true);
     778  G4double e, eion, dedx, dedx1;
     779  G4double eth0 = v->GetLowEdgeEnergy(0);
     780  G4double escal = eth/massRatio;
     781  G4double qe =
     782    effCharge.EffectiveChargeSquareRatio(ion, curMaterial, escal);
     783  G4double dedxt =
     784    ionLEModel->ComputeDEDXPerVolume(curMaterial, p, eth, eth)*qe;
     785  G4double dedx1t =
     786    ionHEModel->ComputeDEDXPerVolume(curMaterial, p, eth, eth)*qe
     787    + ComputeIonCorrections(curParticle, curMaterial, escal);
     788  G4double rest = escal*(dedxt - dedx1t);
     789  //G4cout << "Escal(MeV)= "<<escal<<" dedxt0= " <<dedxt
     790  //     << " dedxt1= " << dedx1t << G4endl;   
     791
     792  for(G4int i=0; i<nbinCorr; i++) {
     793    e = vv->GetLowEdgeEnergy(i);
     794    escal = e/massRatio;
     795    eion  = escal/A;
     796    if(eion <= eth0) {
     797      dedx = v->GetValue(eth0, b)*std::sqrt(eion/eth0);
     798    } else {
     799      dedx = v->GetValue(eion, b);
     800    }
     801    qe = effCharge.EffectiveChargeSquareRatio(curParticle,curMaterial,escal);
     802    if(e <= eth) {
     803      dedx1 = ionLEModel->ComputeDEDXPerVolume(curMaterial, p, e, e)*qe;
     804    } else {
     805      dedx1 = ionHEModel->ComputeDEDXPerVolume(curMaterial, p, e, e)*qe +
     806        ComputeIonCorrections(curParticle, curMaterial, escal) + rest/escal;
     807    }
     808    vv->PutValue(i, dedx/dedx1);
     809    if(verbose>1) {
     810      G4cout << "  E(meV)= " << e/MeV << "   Correction= " << dedx/dedx1
     811             << "   "  << dedx << " " << dedx1
     812             << "  massF= " << massFactor << G4endl;
     813    }
     814  }
     815  delete v;
     816  ionList[idx]  = ion;
     817  stopData[idx] = vv;
     818  if(verbose>1) G4cout << "End data set " << G4endl;
     819}
     820
     821//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     822
     823void G4EmCorrections::InitialiseForNewRun()
     824{
     825  G4ProductionCutsTable* tb = G4ProductionCutsTable::GetProductionCutsTable();
     826  ncouples = tb->GetTableSize();
     827  if(currmat.size() != ncouples) {
     828    currmat.resize(ncouples);
     829    size_t i;
     830    for(i=0; i<100; i++) {thcorr[i].clear();}
     831    for(i=0; i<ncouples; i++) {
     832      currmat[i] = tb->GetMaterialCutsCouple(i)->GetMaterial();
     833      G4String nam = currmat[i]->GetName();
     834      for(G4int j=0; j<nIons; j++) {
     835        if(nam == materialName[j]) { materialList[j] = currmat[i]; }
     836      }
     837    }
     838  }
    779839}
    780840
  • trunk/source/processes/electromagnetic/utils/src/G4EmModelManager.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmModelManager.cc,v 1.40 2007/11/09 11:35:54 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     26// $Id: G4EmModelManager.cc,v 1.46 2008/10/13 14:56:56 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    7878//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    7979
    80 G4RegionModels::G4RegionModels(G4int nMod, std::vector<G4int>& list, G4DataVector& lowE)
     80G4RegionModels::G4RegionModels(G4int nMod, std::vector<G4int>& indx,
     81                               G4DataVector& lowE, const G4Region* reg)
    8182{
    8283  nModelsForRegion      = nMod;
    8384  theListOfModelIndexes = new G4int [nModelsForRegion];
    84   lowKineticEnergy      = new G4double [nModelsForRegion];
     85  lowKineticEnergy      = new G4double [nModelsForRegion+1];
    8586  for (G4int i=0; i<nModelsForRegion; i++) {
    86     theListOfModelIndexes[i] = list[i];
     87    theListOfModelIndexes[i] = indx[i];
    8788    lowKineticEnergy[i] = lowE[i];
    8889  }
     90  lowKineticEnergy[nModelsForRegion] = lowE[nModelsForRegion];
     91  theRegion = reg;
    8992}
    9093
     
    99102//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    100103
    101 #include "G4LossTableManager.hh"
    102104#include "G4Step.hh"
    103105#include "G4ParticleDefinition.hh"
     
    107109#include "G4MaterialCutsCouple.hh"
    108110#include "G4ProductionCutsTable.hh"
    109 #include "G4Region.hh"
    110111#include "G4RegionStore.hh"
    111112#include "G4Gamma.hh"
    112113#include "G4Positron.hh"
     114#include "G4UnitsTable.hh"
    113115
    114116//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    128130  regions.clear();
    129131  orderOfModels.clear();
    130   upperEkin.clear();
    131132  maxCutInRange    = 12.*cm;
    132133  maxSubCutInRange = 0.7*mm;
     
    139140G4EmModelManager::~G4EmModelManager()
    140141{
    141   G4int i,j;
    142142  Clear();
     143}
     144
     145//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     146
     147void G4EmModelManager::Clear()
     148{
    143149  if(1 < verboseLevel) {
    144     G4cout << "G4EmModelManager:: delete models ";
    145     if(particle) G4cout << " for " << particle->GetParticleName();
    146     G4cout << " nModels=" << nEmModels <<G4endl;
    147   }
    148 
    149   for(i = 0; i<nEmModels; i++) {
    150     orderOfModels[i] = 1;
    151   }
    152   for(i = 0; i<nEmModels; i++) {
    153     if (orderOfModels[i]) {
    154       orderOfModels[i] = 0;
    155       for(j = i+1; j<nEmModels; j++) {
    156         if(models[i] == models[j]) orderOfModels[j] = 0;
    157       }
    158       G4String nam = models[i]->GetName();
    159       if(nam != "PAI" && nam != "PAIModel" ) delete models[i];
    160     }
    161   }
    162   for(i = 0; i<nEmModels; i++) {
    163     orderOfModels[i] = 1;
    164   }
    165   for(i = 0; i<nEmModels; i++) {
    166     if (orderOfModels[i]) {
    167       orderOfModels[i] = 0;
    168       for(j = i+1; j<nEmModels; j++) {
    169         if(flucModels[i] == flucModels[j]) orderOfModels[j] = 0;
    170       }
    171       delete flucModels[i];
    172     }
    173   }
    174   if(1 < verboseLevel)
    175     G4cout << "G4EmModelManager:: models are deleted!" << G4endl;
    176 }
    177 
    178 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    179 
    180 void G4EmModelManager::Clear()
    181 {
    182   if(1 < verboseLevel) {
    183     G4cout << "G4EmModelManager::Clear()";
    184     if(particle) G4cout << " for " << particle->GetParticleName();
    185     G4cout << G4endl;
     150    G4cout << "G4EmModelManager::Clear()" << G4endl;
    186151  }
    187152
    188153  theCuts.clear();
    189154  theSubCuts.clear();
    190   upperEkin.clear();
    191155  if(idxOfRegionModels) delete [] idxOfRegionModels;
    192156  if(setOfRegionModels && nRegions) {
     
    215179  orderOfModels.push_back(num);
    216180  p->DefineForRegion(r);
    217   if (nEmModels>0) {
    218     G4int idx = nEmModels;
    219     do {idx--;} while (idx && num < orderOfModels[idx]);
    220     if (num >= orderOfModels[idx] && num <= orderOfModels[idx+1]) idx++;
    221     if (idx < nEmModels) {
    222       models[nEmModels] = models[idx];
    223       flucModels[nEmModels] = flucModels[idx];
    224       regions[nEmModels] = regions[idx];
    225       orderOfModels[nEmModels] = orderOfModels[idx];
    226       models[idx] = p;
    227       flucModels[idx] = fm;
    228       regions[idx] = r;
    229       orderOfModels[idx] = num;
    230     }
    231   }
    232181  nEmModels++;
    233182}
     
    254203//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    255204
    256 G4VEmModel* G4EmModelManager::GetModel(G4int i)
     205G4VEmModel* G4EmModelManager::GetModel(G4int i, G4bool ver)
    257206{
    258207  G4VEmModel* m = 0;
    259   if(i >= 0 && i < nEmModels) m = models[i];
    260   else if(verboseLevel > 0)
     208  if(i >= 0 && i < nEmModels) {m = models[i];}
     209  else if(verboseLevel > 0 && ver) {
    261210    G4cout << "G4EmModelManager::GetModel WARNING: "
    262211           << "index " << i << " is wrong Nmodels= "
    263            << nEmModels << G4endl;
     212           << nEmModels;
     213    if(particle) G4cout << " for " << particle->GetParticleName();
     214    G4cout<< G4endl;
     215  }
    264216  return m;
    265217}
     
    269221const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
    270222                                                 const G4ParticleDefinition* sp,
    271                                                        G4double theMinSubRange,
    272                                                       G4int val)
     223                                                 G4double theMinSubRange,
     224                                                G4int val)
    273225{
    274226  verboseLevel = val;
     
    293245  // Identify the list of regions with different set of models
    294246  nRegions = 1;
    295   std::vector<const G4Region*> set;
    296   set.push_back(world);
     247  std::vector<const G4Region*> setr;
     248  setr.push_back(world);
    297249  G4bool isWorld = false;
    298250
     
    306258      if (nRegions>1) {
    307259        for (G4int j=1; j<nRegions; j++) {
    308           if ( r == set[j] ) newRegion = false;
     260          if ( r == setr[j] ) newRegion = false;
    309261        }
    310262      }
    311263      if (newRegion) {
    312         set.push_back(r);
     264        setr.push_back(r);
    313265        nRegions++;
    314266      }
     
    322274  idxOfRegionModels[numOfCouples] = 0;
    323275  setOfRegionModels = new G4RegionModels*[nRegions];
    324   upperEkin.resize(nEmModels);
     276
     277  std::vector<G4int>    modelAtRegion(nEmModels);
     278  std::vector<G4int>    modelOrd(nEmModels);
     279  G4DataVector          eLow(nEmModels);
     280  G4DataVector          eHigh(nEmModels);
     281  G4int nmax = nEmModels;
    325282
    326283  // Order models for regions
    327284  for (G4int reg=0; reg<nRegions; reg++) {
    328     const G4Region* region = set[reg];
    329 
     285    const G4Region* region = setr[reg];
    330286    G4int n = 0;
    331 
    332     std::vector<G4int>    modelAtRegion;
    333     G4DataVector            eLow;
    334     G4DataVector            eHigh;
    335     modelAtRegion.clear();
    336     eLow.clear();
    337     eHigh.clear();
    338287
    339288    if(isWorld || 0 < reg) {
     
    346295          G4double tmin = model->LowEnergyLimit();
    347296          G4double tmax = model->HighEnergyLimit();
    348           if (n>0) tmin = std::max(tmin, eHigh[n-1]);
     297          G4int  ord    = orderOfModels[ii];
     298          G4bool push   = true;
     299          G4bool insert = false;
     300          G4int  idx    = n;
    349301
    350302          if(1 < verboseLevel) {
     
    355307                 << " tmin(MeV)= " << tmin/MeV
    356308                 << "; tmax(MeV)= " << tmax/MeV
    357                  << "; order= " << orderOfModels[ii]
     309                 << "; order= " << ord
    358310                 << G4endl;
    359311          }
    360 
    361           if (tmin < tmax) {
    362             modelAtRegion.push_back(ii);
    363             eLow.push_back(tmin);
    364             eHigh.push_back(tmax);
    365             upperEkin[ii] = tmax;
    366             n++;
     312       
     313          if (n == 0) n++;
     314          else {
     315            tmin = std::min(tmin, eHigh[n-1]);
     316            if(tmin >= tmax) push = false;
     317            else {
     318
     319              // high energy model
     320              if(tmin == eHigh[n-1] && tmax > eHigh[n-1]) n++;
     321              else if (tmax > eHigh[n-1]) {
     322
     323                // compare order of models
     324                for(G4int k = n-1; k>=0; k--) {
     325       
     326                  if (ord >= modelOrd[k]) {
     327                    tmin = std::max(tmin, eHigh[k]);           
     328                    if(k < n-1) n = k + 2;
     329                    break;
     330                  } else if (tmin > eLow[k]) {
     331                    eHigh[k] = tmin;
     332                    n = k + 2;
     333                    break;
     334                  } else if (tmin == eLow[k]) {
     335                    n = k + 1;
     336                    break;
     337                  }
     338                }
     339                if(tmin < eLow[0]) n = 1;
     340                idx = n - 1;
     341
     342                // low energy model
     343              } else {
     344
     345                tmax = std::max(tmax, eLow[0]);
     346                insert = true;
     347                push = false;
     348                idx = 0;
     349                if(tmax <= eLow[0]) tmax = eLow[0];
     350                else {
     351
     352                  for(G4int k=0; k<n; k++) {
     353       
     354                    if (ord >= modelOrd[k]) {
     355                      if(k == 0) {
     356                        if(tmin < eLow[0]) tmax = eLow[0];
     357                        else insert = false;
     358                        break;
     359                      } else {
     360                        insert = false;
     361                        break;
     362                      }
     363                    } else if(tmax < eHigh[k]) {
     364                      idx = k;
     365                      if(k > 0) tmin = eLow[k];
     366                      eLow[k] = tmax;               
     367                      break;
     368                    } else if(tmax == eHigh[k]) {           
     369                      insert = false;
     370                      push = true;
     371                      idx = k;
     372                      if(k > 0) tmin = eLow[k];
     373                      else tmin = std::min(tmin,eLow[0]);
     374                      break;
     375                    } else {
     376                      modelAtRegion[k] = ii;
     377                      modelOrd[k] = ord;
     378                      if(k == 0) eLow[idx] = std::min(tmin,eLow[0]);
     379                    }
     380                  }
     381                }
     382                if(insert && idx < n) n++;
     383                else insert = false;
     384              }
     385            }
     386          }
     387          if(n > nmax) {
     388            nmax = n;
     389            modelAtRegion.resize(nmax);
     390            modelOrd.resize(nmax);
     391            eLow.resize(nmax);
     392            eHigh.resize(nmax);
     393          }
     394          if(insert) {
     395            for(G4int k=n-2; k>=idx; k--) {           
     396              modelAtRegion[k+1] = modelAtRegion[k];
     397              modelOrd[k+1] = modelOrd[k];
     398              eLow[k+1]  = eLow[k];
     399              eHigh[k+1] = eHigh[k];
     400            }
     401          }
     402          if (push || insert) {
     403            modelAtRegion[idx] = ii;
     404            modelOrd[idx] = ord;
     405            eLow[idx]  = tmin;
     406            eHigh[idx] = tmax;
    367407          }
    368408        }
     
    374414      eLow.push_back(0.0);
    375415      eHigh.push_back(DBL_MAX);
    376       upperEkin.push_back(DBL_MAX);
    377416    }
    378417    eLow[0] = 0.0;
     418    if(n >= nmax) eLow.resize(nmax+1);
     419    eLow[n] = eHigh[n-1];
    379420
    380421    if(1 < verboseLevel) {
     
    382423      if (region) G4cout << region->GetName();
    383424      G4cout << ">  Elow(MeV)= ";
    384       for(G4int ii=0; ii<n; ii++) {G4cout << eLow[ii]/MeV << " ";}
     425      for(G4int ii=0; ii<=n; ii++) {G4cout << eLow[ii]/MeV << " ";}
    385426      G4cout << G4endl;
    386427    }
    387     G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow);
     428    G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow, region);
    388429    setOfRegionModels[reg] = rm;
    389430  }
     
    399440 
    400441    G4int reg = nRegions;
    401     do {reg--;} while (reg>0 && pcuts != (set[reg]->GetProductionCuts()));
     442    do {reg--;} while (reg>0 && pcuts != (setr[reg]->GetProductionCuts()));
    402443    idxOfRegionModels[i] = reg;
    403444
     
    474515{
    475516
    476   // vectors to provide continues dE/dx
    477   G4DataVector factor;
    478   G4DataVector dedxLow;
    479   G4DataVector dedxHigh;
    480 
    481517  G4double e;
    482518
     
    491527    G4cout << "G4EmModelManager::FillDEDXVector() for "
    492528           << couple->GetMaterial()->GetName()
    493            << "  Ecut(MeV)= " << cut
    494            << "  Esubcut(MeV)= " << subcut
     529           << "  cut(MeV)= " << cut
     530           << "  subcut(MeV)= " << subcut
    495531           << "  Type " << tType
    496532           << "  for " << particle->GetParticleName()
     
    501537  const G4RegionModels* regModels = setOfRegionModels[reg];
    502538  G4int nmod = regModels->NumberOfModels();
    503   factor.resize(nmod);
    504   dedxLow.resize(nmod);
    505   dedxHigh.resize(nmod);
     539
     540  // vectors to provide continues dE/dx
     541  G4DataVector factor(nmod);
     542  G4DataVector eLow(nmod+1);
     543  G4DataVector dedxLow(nmod);
     544  G4DataVector dedxHigh(nmod);
    506545
    507546  if(1 < verboseLevel) {
     
    512551  }
    513552
    514 
    515553  // calculate factors to provide continuity of energy loss
     554
     555
    516556  factor[0] = 1.0;
    517557  G4int j;
     
    519559  G4int totBinsLoss = aVector->GetVectorLength();
    520560
    521   dedxLow[0]  = 0.0;
    522 
    523   e = upperEkin[regModels->ModelIndex(0)];
     561  dedxLow[0] = 0.0;
     562  eLow[0]    = 0.0;
     563
     564  e = regModels->LowEdgeEnergy(1);
     565  eLow[1]    = e;
    524566  G4VEmModel* model = models[regModels->ModelIndex(0)];
    525567  dedxHigh[0] = 0.0;
    526568  if(model && cut > subcut) {
    527569    dedxHigh[0] = model->ComputeDEDX(couple,particle,e,cut);
    528     if(subcut > 0.0)
     570    if(subcut > 0.0) {
    529571      dedxHigh[0] -= model->ComputeDEDX(couple,particle,e,subcut);
     572    }
    530573  }
    531574  if(nmod > 1) {
    532575    for(j=1; j<nmod; j++) {
    533576
    534       e = upperEkin[regModels->ModelIndex(j-1)];
     577      e = regModels->LowEdgeEnergy(j);
     578      eLow[j]   = e;
    535579      G4int idx = regModels->ModelIndex(j);
    536580
    537581      dedxLow[j] = models[idx]->ComputeDEDX(couple,particle,e,cut);
    538       if(subcut > 0.0)
     582      if(subcut > 0.0) {
    539583        dedxLow[j] -= models[idx]->ComputeDEDX(couple,particle,e,subcut);
     584      }
    540585      if(subcut == cut) dedxLow[j] = 0.0;
    541586
    542       e = upperEkin[idx];
     587      e = regModels->LowEdgeEnergy(j+1);
     588      eLow[j+1] = e;
    543589      dedxHigh[j] = models[idx]->ComputeDEDX(couple,particle,e,cut);
    544       if(subcut > 0.0)
     590      if(subcut > 0.0) {
    545591        dedxHigh[j] -= models[idx]->ComputeDEDX(couple,particle,e,subcut);
     592      }
    546593      if(subcut == cut) dedxHigh[j] = 0.0;
    547594    }
     595    if(1 < verboseLevel) {
     596      G4cout << " model #0" 
     597             << "  dedx(" << eLow[0] << ")=  " << dedxLow[0]
     598             << "  dedx(" << eLow[1] << ")=  " << dedxHigh[0]
     599             << G4endl;
     600    }
    548601
    549602    for(j=1; j<nmod; j++) {
    550       if(dedxLow[j] > 0.0) factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0);
    551       else                 factor[j] = 0.0;
     603      if(dedxLow[j] > 0.0) {
     604        factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0)*eLow[j];
     605      } else  factor[j] = 0.0;
     606      if(1 < verboseLevel) {
     607        G4cout << " model #" << j
     608               << "  dedx(" << eLow[j] << ")=  " << dedxLow[j]
     609               << "  dedx(" << eLow[j+1] << ")=  " << dedxHigh[j]
     610               << "  factor= " << factor[j]/eLow[j]
     611               << G4endl;
     612      }
    552613    }
    553614
     
    565626      // Choose a model of energy losses
    566627    G4int k = 0;
    567     if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
     628    if (nmod > 1 && e > eLow[1]) {
    568629      do {
    569630        k++;
    570         fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
    571       } while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
     631        fac *= (1.0 + factor[k]/e);
     632      } while (k+1 < nmod && e > eLow[k+1]);
    572633    }
    573634
     
    602663                                        G4EmTableType tType)
    603664{
    604   // vectors to provide continues cross section
    605   G4DataVector factor;
    606   G4DataVector sigmaLow;
    607   G4DataVector sigmaHigh;
    608 
    609665  G4double e;
    610666
     
    630686  const G4RegionModels* regModels = setOfRegionModels[reg];
    631687  G4int nmod = regModels->NumberOfModels();
    632   factor.resize(nmod);
    633   sigmaLow.resize(nmod);
    634   sigmaHigh.resize(nmod);
     688
     689  // vectors to provide continues dE/dx
     690  G4DataVector factor(nmod);
     691  G4DataVector eLow(nmod+1);
     692  G4DataVector sigmaLow(nmod);
     693  G4DataVector sigmaHigh(nmod);
    635694
    636695  if(2 < verboseLevel) {
     
    644703  G4int totBinsLambda = aVector->GetVectorLength();
    645704
    646   sigmaLow[0]  = 0.0;
    647 
    648   e = upperEkin[regModels->ModelIndex(0)];
     705  sigmaLow[0] = 0.0;
     706  eLow[0]     = 0.0;
     707
     708  e = regModels->LowEdgeEnergy(1);
     709  eLow[1]     = e;
    649710  G4VEmModel* model = models[regModels->ModelIndex(0)];
    650711  sigmaHigh[0] = 0.0;
     
    668729    for(j=1; j<nmod; j++) {
    669730
    670       e  = upperEkin[regModels->ModelIndex(j-1)];
    671       sigmaLow[j] =
    672         models[regModels->ModelIndex(j)]->CrossSection(couple,particle,e,cut,tmax);
    673       e  = upperEkin[regModels->ModelIndex(j)];
    674       sigmaHigh[j] =
    675         models[regModels->ModelIndex(j)]->CrossSection(couple,particle,e,cut,tmax);
     731      e  = regModels->LowEdgeEnergy(j);
     732      eLow[j]   = e;
     733      G4int idx = regModels->ModelIndex(j);
     734
     735      sigmaLow[j] = models[idx]->CrossSection(couple,particle,e,cut,tmax);
     736      e  = regModels->LowEdgeEnergy(j+1);
     737      eLow[j+1] = e;
     738      sigmaHigh[j] = models[idx]->CrossSection(couple,particle,e,cut,tmax);
     739    }
     740    if(1 < verboseLevel) {
     741      G4cout << " model #0" 
     742             << "  sigma(" << eLow[0] << ")=  " << sigmaLow[0]
     743             << "  sigma(" << eLow[1] << ")=  " << sigmaHigh[0]
     744             << G4endl;
     745    }
     746    for(j=1; j<nmod; j++) {
     747      if(sigmaLow[j] > 0.0) {
     748        factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0)*eLow[j];
     749      } else  factor[j] = 0.0;
    676750      if(1 < verboseLevel) {
    677         G4cout << " model #" << j << "   eUp= " << e
    678                << "  sigmaUp= " << sigmaHigh[j]
    679                << "  sigmaDown= " << sigmaLow[j]
     751        G4cout << " model #" << j
     752               << "  sigma(" << eLow[j] << ")=  " << sigmaLow[j]
     753               << "  sigma(" << eLow[j+1] << ")=  " << sigmaHigh[j]
     754               << "  factor= " << factor[j]/eLow[j]
    680755               << G4endl;
    681756      }
    682     }
    683     for(j=1; j<nmod; j++) {
    684       if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
    685       else                  factor[j] = 0.0;
    686757    }
    687758  }
     
    695766    G4int k = 0;
    696767    G4double fac = 1.0;
    697     if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
     768    if (nmod > 1 && e > eLow[1]) {
    698769      do {
    699770        k++;
    700         fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
    701       } while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
     771        fac *= (1.0 + factor[k]/e);
     772      } while ( k+1 < nmod && e > eLow[k+1] );
    702773    }
    703774
     
    721792
    722793//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     794
     795void G4EmModelManager::DumpModelList(G4int verb)
     796{
     797  if(verb == 0) return;
     798  for(G4int i=0; i<nRegions; i++) {
     799    G4RegionModels* r = setOfRegionModels[i];
     800    const G4Region* reg = r->Region();
     801    if(verb > 1 || nRegions > 1) {
     802    }
     803    G4int n = r->NumberOfModels(); 
     804    if(verb > 1 || n > 0) {
     805      G4cout << "      ===== EM models for the G4Region  " << reg->GetName()
     806             << " ======" << G4endl;;
     807      for(G4int j=0; j<n; j++) {
     808        const G4VEmModel* m = models[r->ModelIndex(j)];
     809        G4cout << std::setw(20);
     810        G4cout << m->GetName() << " :     Emin= "
     811               << std::setw(10) << G4BestUnit(r->LowEdgeEnergy(j),"Energy")
     812               << "        Emax=   "
     813               << G4BestUnit(r->LowEdgeEnergy(j+1),"Energy")
     814               << G4endl;
     815      } 
     816    }
     817  }
     818}
     819
     820//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
  • trunk/source/processes/electromagnetic/utils/src/G4EmMultiModel.cc

    r819 r961  
    2525//
    2626// $Id: G4EmMultiModel.cc,v 1.6 2007/05/22 17:31:58 vnivanch Exp $
    27 // GEANT4 tag $Name: $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
  • trunk/source/processes/electromagnetic/utils/src/G4EmProcessOptions.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4EmProcessOptions.cc,v 1.22 2007/11/07 18:38:49 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4EmProcessOptions.cc,v 1.26 2009/02/18 14:43:27 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5959#include "G4VMultipleScattering.hh"
    6060#include "G4Region.hh"
     61#include "G4RegionStore.hh"
    6162
    6263//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    392393//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    393394
    394 void G4EmProcessOptions::ActivateDeexcitation(G4bool val, const G4Region* r)
    395 {
    396   const std::vector<G4VEnergyLossProcess*>& v =
    397         theManager->GetEnergyLossProcessVector();
    398   std::vector<G4VEnergyLossProcess*>::const_iterator itr;
    399   for(itr = v.begin(); itr != v.end(); itr++) {
    400     G4VEnergyLossProcess* p = *itr;
    401     if(p) p->ActivateDeexcitation(val,r);
    402   }
    403   const std::vector<G4VEmProcess*>& w =
    404         theManager->GetEmProcessVector();
    405   std::vector<G4VEmProcess*>::const_iterator itp;
    406   for(itp = w.begin(); itp != w.end(); itp++) {
    407     G4VEmProcess* q = *itp;
    408     if(q) q->ActivateDeexcitation(val,r);
     395void G4EmProcessOptions::ActivateDeexcitation(const G4String& pname,
     396                                              G4bool val,
     397                                              const G4String& reg)
     398{
     399  G4RegionStore* regionStore = G4RegionStore::GetInstance();
     400  const G4Region* r = 0;
     401  if(reg == "" || reg == "World") {
     402    r = regionStore->GetRegion("DefaultRegionForTheWorld", false);
     403  } else {
     404    r = regionStore->GetRegion(reg, false);
     405  }
     406  if(!r) {
     407    G4cout << "G4EmProcessOptions::ActivateDeexcitation ERROR: G4Region <"
     408           << reg << "> not found, the command ignored" << G4endl;
     409    return;
     410  }
     411
     412  const std::vector<G4VEnergyLossProcess*>& v =
     413        theManager->GetEnergyLossProcessVector();
     414  std::vector<G4VEnergyLossProcess*>::const_iterator itr;
     415  for(itr = v.begin(); itr != v.end(); itr++) {
     416    G4VEnergyLossProcess* p = *itr;
     417    if(p) {
     418      if(pname == p->GetProcessName()) p->ActivateDeexcitation(val,r);
     419    }
     420  }
     421  const std::vector<G4VEmProcess*>& w =
     422        theManager->GetEmProcessVector();
     423  std::vector<G4VEmProcess*>::const_iterator itp;
     424  for(itp = w.begin(); itp != w.end(); itp++) {
     425    G4VEmProcess* q = *itp;
     426    if(q) {
     427      if(pname == q->GetProcessName()) q->ActivateDeexcitation(val,r);
     428    }
    409429  }
    410430}
     
    477497//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    478498
     499void G4EmProcessOptions::SetPolarAngleLimit(G4double val)
     500{
     501  const std::vector<G4VMultipleScattering*>& u =
     502        theManager->GetMultipleScatteringVector();
     503  std::vector<G4VMultipleScattering*>::const_iterator itm;
     504  for(itm = u.begin(); itm != u.end(); itm++) {
     505    if(*itm) (*itm)->SetPolarAngleLimit(val);
     506  }
     507  const std::vector<G4VEmProcess*>& w =
     508        theManager->GetEmProcessVector();
     509  std::vector<G4VEmProcess*>::const_iterator itp;
     510  for(itp = w.begin(); itp != w.end(); itp++) {
     511    G4VEmProcess* q = *itp;
     512    if(q) q->SetPolarAngleLimit(val);
     513  }
     514}
     515
     516//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     517
    479518void G4EmProcessOptions::SetLPMFlag(G4bool val)
    480519{
     
    484523//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    485524
     525void G4EmProcessOptions::SetSplineFlag(G4bool val)
     526{
     527  theManager->SetSplineFlag(val);
     528}
     529
     530//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     531
    486532void G4EmProcessOptions::SetLinearLossLimit(G4double val)
    487533{
  • trunk/source/processes/electromagnetic/utils/src/G4EnergyLossMessenger.cc

    r819 r961  
    2525//
    2626//
    27 // $Id: G4EnergyLossMessenger.cc,v 1.29 2007/06/11 14:56:51 vnivanch Exp $
    28 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     27// $Id: G4EnergyLossMessenger.cc,v 1.37 2009/02/18 14:43:27 vnivanch Exp $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030// -------------------------------------------------------------------
     
    4949// 16-03-07 modify /process/eLoss/minsubsec command (V.Ivanchenko)
    5050// 18-05-07 add /process/msc directory and commands (V.Ivanchenko)
     51// 11-03-08 add /process/em directory and commands (V.Ivanchenko)
    5152//
    5253// -------------------------------------------------------------------
     
    8485  mscDirectory = new G4UIdirectory("/process/msc/");
    8586  mscDirectory->SetGuidance("Commands for EM scattering processes.");
     87  emDirectory = new G4UIdirectory("/process/em/");
     88  emDirectory->SetGuidance("General commands for EM processes.");
    8689
    8790  RndmStepCmd = new G4UIcmdWithABool("/process/eLoss/rndmStep",this);
     
    146149
    147150  IntegCmd = new G4UIcmdWithABool("/process/eLoss/integral",this);
    148   IntegCmd->SetGuidance("Switch true/false the integration of cross section over step.");
     151  IntegCmd->SetGuidance("Switch true/false the integral option");
    149152  IntegCmd->SetParameterName("integ",true);
    150153  IntegCmd->SetDefaultValue(true);
     
    152155
    153156  rangeCmd = new G4UIcmdWithABool("/process/eLoss/CSDARange",this);
    154   rangeCmd->SetGuidance("Switch true/false the precise range calculation.");
     157  rangeCmd->SetGuidance("Switch true/false the CSDA range calculation");
    155158  rangeCmd->SetParameterName("range",true);
    156159  rangeCmd->SetDefaultValue(true);
     
    158161
    159162  lpmCmd = new G4UIcmdWithABool("/process/eLoss/LPM",this);
    160   lpmCmd->SetGuidance("Switch true/false the LPM effect calculation.");
     163  lpmCmd->SetGuidance("The flag of the LPM effect calculation");
    161164  lpmCmd->SetParameterName("lpm",true);
    162165  lpmCmd->SetDefaultValue(true);
    163166  lpmCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    164167
     168  splCmd = new G4UIcmdWithABool("/process/em/spline",this);
     169  splCmd->SetGuidance("The flag of usage spline for Physics Vectors");
     170  splCmd->SetParameterName("spl",true);
     171  splCmd->SetDefaultValue(false);
     172  splCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
     173
     174  aplCmd = new G4UIcmdWithABool("/process/em/applyCuts",this);
     175  aplCmd->SetGuidance("The flag to Apply Cuts for gamma processes");
     176  aplCmd->SetParameterName("apl",true);
     177  aplCmd->SetDefaultValue(false);
     178  aplCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
     179
     180  deexCmd = new G4UIcommand("/process/em/deexcitation",this);
     181  deexCmd->SetGuidance("Set deexcitation flag per process and G4Region.");
     182  deexCmd->SetGuidance("  procName  : process name");
     183  deexCmd->SetGuidance("  flag      : flag");
     184  deexCmd->SetGuidance("  regName   : G4Region name");
     185
     186  G4UIparameter* pName = new G4UIparameter("pName",'s',false);
     187  deexCmd->SetParameter(pName);
     188
     189  G4UIparameter* flag = new G4UIparameter("flag",'s',false);
     190  deexCmd->SetParameter(flag);
     191
     192  G4UIparameter* regName = new G4UIparameter("regName",'s',false);
     193  deexCmd->SetParameter(regName);
     194
    165195  dedxCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsDEDX",this);
    166   dedxCmd->SetGuidance("Set number of bins for DEDX tables.");
     196  dedxCmd->SetGuidance("Set number of bins for DEDX tables");
    167197  dedxCmd->SetParameterName("binsDEDX",true);
    168198  dedxCmd->SetDefaultValue(120);
     
    170200
    171201  lamCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsLambda",this);
    172   lamCmd->SetGuidance("Set number of bins for Lambda tables.");
     202  lamCmd->SetGuidance("Set number of bins for Lambda tables");
    173203  lamCmd->SetParameterName("binsL",true);
    174204  lamCmd->SetDefaultValue(120);
     
    176206
    177207  verCmd = new G4UIcmdWithAnInteger("/process/eLoss/verbose",this);
    178   verCmd->SetGuidance("Set verbose level for EM physics.");
     208  verCmd->SetGuidance("Set verbose level for EM physics");
    179209  verCmd->SetParameterName("verb",true);
    180210  verCmd->SetDefaultValue(1);
    181211  verCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    182212
     213  ver1Cmd = new G4UIcmdWithAnInteger("/process/em/verbose",this);
     214  ver1Cmd->SetGuidance("Set verbose level for EM physics");
     215  ver1Cmd->SetParameterName("verb1",true);
     216  ver1Cmd->SetDefaultValue(1);
     217  ver1Cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
     218
    183219  lllCmd = new G4UIcmdWithADouble("/process/eLoss/linLossLimit",this);
    184   lllCmd->SetGuidance("Set linearLossLimit parameter.");
     220  lllCmd->SetGuidance("Set linearLossLimit parameter");
    185221  lllCmd->SetParameterName("linlim",true);
    186222  lllCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    187223
    188   labCmd = new G4UIcmdWithADouble("/process/eLoss/lambdaFactor",this);
    189   labCmd->SetGuidance("Set lambdaFactor parameter.");
     224  labCmd = new G4UIcmdWithADouble("/process/eLoss/LambdaFactor",this);
     225  labCmd->SetGuidance("Set lambdaFactor parameter for integral option");
    190226  labCmd->SetParameterName("Fl",true);
    191227  labCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    192228
    193229  mscCmd = new G4UIcmdWithAString("/process/msc/StepLimit",this);
    194   mscCmd->SetGuidance("Set msc step limitation type.");
     230  mscCmd->SetGuidance("Set msc step limitation type");
    195231  mscCmd->SetParameterName("StepLim",true);
    196232  mscCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    197233
    198234  latCmd = new G4UIcmdWithABool("/process/msc/LateralDisplacement",this);
    199   latCmd->SetGuidance("Switch true/false sampling of latra dislacent.");
     235  latCmd->SetGuidance("Set flag of sampling of lateral displacement");
    200236  latCmd->SetParameterName("lat",true);
    201237  latCmd->SetDefaultValue(true);
     
    203239
    204240  frCmd = new G4UIcmdWithADouble("/process/msc/RangeFactor",this);
    205   frCmd->SetGuidance("Set RangeFactor parameter for msc process.");
     241  frCmd->SetGuidance("Set RangeFactor parameter for msc processes");
    206242  frCmd->SetParameterName("Fr",true);
    207243  frCmd->SetRange("Fr>0");
     
    210246
    211247  fgCmd = new G4UIcmdWithADouble("/process/msc/GeomFactor",this);
    212   fgCmd->SetGuidance("Set GeomFactor parameter for msc process.");
     248  fgCmd->SetGuidance("Set GeomFactor parameter for msc processes");
    213249  fgCmd->SetParameterName("Fg",true);
    214250  fgCmd->SetRange("Fg>0");
     
    217253
    218254  skinCmd = new G4UIcmdWithADouble("/process/msc/Skin",this);
    219   skinCmd->SetGuidance("Set skin parameter for multiple scattering.");
     255  skinCmd->SetGuidance("Set skin parameter for msc processes");
    220256  skinCmd->SetParameterName("skin",true);
    221257  skinCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    222258
     259  angCmd = new G4UIcmdWithADoubleAndUnit("/process/msc/ThetaLimit",this);
     260  angCmd->SetGuidance("Set the limit on the polar angle");
     261  angCmd->SetParameterName("theta",true);
     262  angCmd->SetUnitCategory("Angle");
     263  angCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    223264}
    224265
     
    233274  delete MinSubSecCmd;
    234275  delete StepFuncCmd;
     276  delete deexCmd;
    235277  delete eLossDirectory;
    236278  delete mscDirectory;
     279  delete emDirectory;
    237280  delete MinEnCmd;
    238281  delete MaxEnCmd;
     
    240283  delete rangeCmd;
    241284  delete lpmCmd;
     285  delete splCmd;
     286  delete aplCmd;
    242287  delete latCmd;
    243288  delete verCmd;
     289  delete ver1Cmd;
    244290  delete mscCmd;
    245291  delete dedxCmd;
     
    250296  delete labCmd;
    251297  delete skinCmd;
     298  delete angCmd;
    252299}
    253300
     
    289336  }
    290337
     338  if (command == deexCmd) {
     339    G4String s1 (""), s2(""), s3("");
     340    G4bool b = false;
     341    std::istringstream is(newValue);
     342    is >> s1 >> s2 >> s3;
     343    if(s2 == "true") b = true;
     344    opt->ActivateDeexcitation(s1,b,s3);
     345  }
     346
    291347  if (command == mscCmd) {
    292348    if(newValue == "Minimal")
     
    317373  } 
    318374
    319   if (command == IntegCmd)
     375  if (command == IntegCmd) {
    320376    opt->SetIntegral(IntegCmd->GetNewBoolValue(newValue));
    321  
     377  }
    322378  if (command == rangeCmd) {
    323379    opt->SetBuildCSDARange(rangeCmd->GetNewBoolValue(newValue));
     
    330386  }
    331387
     388  if (command == splCmd) {
     389    opt->SetSplineFlag(splCmd->GetNewBoolValue(newValue));
     390    G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
     391  }
     392
     393  if (command == aplCmd) {
     394    opt->SetApplyCuts(aplCmd->GetNewBoolValue(newValue));
     395  }
     396
    332397  if (command == latCmd) {
    333398    opt->SetMscLateralDisplacement(latCmd->GetNewBoolValue(newValue));
     
    335400  }
    336401
    337   if (command == verCmd)
     402  if (command == verCmd) {
    338403    opt->SetVerbose(verCmd->GetNewIntValue(newValue));
    339 
    340   if (command == lllCmd)
     404  }
     405  if (command == ver1Cmd) {
     406    opt->SetVerbose(ver1Cmd->GetNewIntValue(newValue));
     407  }
     408  if (command == lllCmd) {
    341409    opt->SetLinearLossLimit(lllCmd->GetNewDoubleValue(newValue));
    342 
    343   if (command == labCmd)
     410  }
     411  if (command == labCmd) {
    344412    opt->SetLambdaFactor(labCmd->GetNewDoubleValue(newValue));
    345  
     413  }
    346414  if (command == skinCmd) {
    347415    opt->SetSkin(skinCmd->GetNewDoubleValue(newValue));
     
    364432    G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
    365433  }
     434  if (command == angCmd) {
     435    opt->SetPolarAngleLimit(angCmd->GetNewDoubleValue(newValue));
     436    G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified");
     437  } 
    366438}
    367439
  • trunk/source/processes/electromagnetic/utils/src/G4EnergyLossTables.cc

    r819 r961  
    2525//
    2626//
    27 // $Id: G4EnergyLossTables.cc,v 1.33 2006/06/29 19:55:09 gunter Exp $
    28 // GEANT4 tag $Name: $
     27// $Id: G4EnergyLossTables.cc,v 1.34 2008/07/08 10:57:22 vnivanch Exp $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030// -------------------------------------------------------------------
     
    998998//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    999999
    1000 void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle, const G4String& q)
    1001 {
    1002   G4String s = "G4EnergyLossTables:: " + q + " table not found for "
    1003              + aParticle->GetParticleName() + "!";
    1004   G4Exception(s);
    1005   exit(1);
    1006 }
    1007 
    1008 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     1000void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle,
     1001                                            const G4String& q)
     1002{
     1003  G4String s = " " + q + " table not found for "
     1004             + aParticle->GetParticleName() + " !";
     1005  G4Exception("G4EnergyLossTables::ParticleHaveNoLoss", "EM01",
     1006              FatalException, s);
     1007}
     1008
     1009//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
  • trunk/source/processes/electromagnetic/utils/src/G4LossTableBuilder.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4LossTableBuilder.cc,v 1.24 2007/02/16 11:59:35 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4LossTableBuilder.cc,v 1.28 2009/02/18 16:24:47 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    6464
    6565G4LossTableBuilder::G4LossTableBuilder()
    66 {}
     66{
     67  splineFlag = true;
     68}
    6769
    6870//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    7375//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    7476
    75 void G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
    76                                   const std::vector<G4PhysicsTable*>& list)
     77void
     78G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable,
     79                                   const std::vector<G4PhysicsTable*>& list)
    7780{
    7881  size_t n_processes = list.size();
     
    9194
    9295    pv = new G4PhysicsLogVector(elow, ehigh, nbins);
     96    pv->SetSpline(splineFlag);
    9397    for (size_t j=0; j<nbins; j++) {
    9498      G4double dedx = 0.0;
     
    128132      G4double dedx1  = pv->GetValue(elow, b);
    129133
     134      //G4cout << "nbins= " << nbins << " dedx1= " << dedx1 << G4endl;
     135
     136      // protection for specific cases dedx=0
    130137      if(dedx1 == 0.0) {
    131         for (size_t k=1; k<nbins; k++) {
     138        for (size_t k=1; k<nbins-1; k++) {
    132139          bin0++;
    133140          elow  = pv->GetLowEdgeEnergy(k);
     
    138145      }
    139146
     147      //G4cout << "nbins= " << nbins << " elow= " << elow << " ehigh= " << ehigh << G4endl;
     148      // initialisation of a new vector
    140149      G4PhysicsLogVector* v = new G4PhysicsLogVector(elow, ehigh, nbins);
    141 
     150      // dedx is exect zero
     151      if(nbins <= 2) {
     152        v->PutValue(0,1000.);
     153        v->PutValue(1,2000.);
     154        G4PhysicsTableHelper::SetPhysicsVector(rangeTable, i, v);
     155        return;
     156      }
     157      v->SetSpline(splineFlag);
     158
     159      // assumed dedx proportional to beta
    142160      G4double range  = 2.*elow/dedx1;
    143       //G4double range  = elow/dedx1;
    144161      v->PutValue(0,range);
    145162      G4double energy1 = elow;
     
    148165
    149166        G4double energy2 = pv->GetLowEdgeEnergy(j+bin0);
    150         G4double dedx2   = pv->GetValue(energy2, b);
    151167        G4double de      = (energy2 - energy1) * del;
    152         G4double energy  = energy1 - de*0.5;
    153 
    154         G4bool   yes     = true;
    155         //G4bool   yes     = false;
    156         if(dedx1 < DBL_MIN || dedx2 < DBL_MIN) yes = false;   
    157 
    158         G4double fac, f;
    159 
    160         if(yes) fac = std::log(dedx2/dedx1)/std::log(energy2/energy1);
    161         else    fac = (dedx2 - dedx1)/(energy2 - energy1);
    162 
     168        G4double energy  = energy2 + de*0.5;
    163169        for (size_t k=0; k<n; k++) {
    164           energy += de;
    165           if(yes) f = dedx1*std::exp(fac*std::log(energy/energy1));
    166           else    f = dedx1 + fac*(energy - energy1);
    167           if(f > DBL_MIN) range  += de/f;
    168         }
     170          energy -= de;
     171          dedx1 = pv->GetValue(energy, b);
     172          if(dedx1 > 0.0) range += de/dedx1;
     173        }
     174
    169175        //      G4cout << "Range i= " <<i << " j= " << j << G4endl;
    170176        v->PutValue(j,range);
    171177        energy1 = energy2;
    172         dedx1   = dedx2;
    173178      }
    174179      G4PhysicsTableHelper::SetPhysicsVector(rangeTable, i, v);
     
    197202      G4double rlow  = pv->GetValue(elow, b);
    198203      G4double rhigh = pv->GetValue(ehigh, b);
    199 
    200       rhigh *= std::exp(std::log(rhigh/rlow)/((G4double)(nbins-1)));
    201 
    202204     
    203205      G4LPhysicsFreeVector* v = new G4LPhysicsFreeVector(nbins,rlow,rhigh);
     206      v->SetSpline(splineFlag);
     207
    204208      for (size_t j=0; j<nbins; j++) {
    205209        G4double e  = pv->GetLowEdgeEnergy(j);
     
    207211        v->PutValues(j,r,e);
    208212      }
     213      v->PutValues(nbins,rhigh+rlow,ehigh);
    209214
    210215      G4PhysicsTableHelper::SetPhysicsVector(invRangeTable, i, v);
  • trunk/source/processes/electromagnetic/utils/src/G4LossTableManager.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4LossTableManager.cc,v 1.84 2007/06/14 07:28:48 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4LossTableManager.cc,v 1.95 2008/11/13 18:23:39 schaelic Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    7070// 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko)
    7171// 18-06-07 Move definition of msc parameters to G4EmProcessOptions (V.Ivanchenko)
     72// 21-02-08 Add G4EmSaturation (V.Ivanchenko)
    7273//
    7374// Class Description:
     
    9192#include "G4PhysicsTableHelper.hh"
    9293#include "G4EmCorrections.hh"
     94#include "G4EmSaturation.hh"
    9395#include "G4EmTableType.hh"
    9496#include "G4LossTableBuilder.hh"
     
    116118  size_t msc = msc_vector.size();
    117119  for (size_t j=0; j<msc; j++) {
    118     if(msc_vector[j] ) delete msc_vector[j];
     120    if( msc_vector[j] ) delete msc_vector[j];
    119121  }
    120122  size_t emp = emp_vector.size();
    121123  for (size_t k=0; k<emp; k++) {
    122     if(emp_vector[k] ) delete emp_vector[k];
     124    if( emp_vector[k] ) delete emp_vector[k];
     125  }
     126  size_t mod = mod_vector.size();
     127  for (size_t a=0; a<mod; a++) {
     128    if( mod_vector[a] ) delete mod_vector[a];
     129  }
     130  size_t fmod = fmod_vector.size();
     131  for (size_t b=0; b<fmod; b++) {
     132    if( fmod_vector[b] ) delete fmod_vector[b];
    123133  }
    124134  Clear();
     
    126136  delete tableBuilder;
    127137  delete emCorrections;
     138  delete emSaturation;
    128139}
    129140
     
    152163  tableBuilder = new G4LossTableBuilder();
    153164  emCorrections= new G4EmCorrections();
     165  emSaturation = new G4EmSaturation();
    154166  integral = true;
    155167  integralActive = false;
     
    160172  stepFunctionActive = false;
    161173  flagLPM = true;
     174  splineFlag = true;
    162175  bremsTh = DBL_MAX;
    163176  verbose = 1;
     177  tableBuilder->SetSplineFlag(splineFlag);
    164178}
    165179
     
    226240{
    227241  msc_vector.push_back(p);
    228   if(verbose > 1)
     242  if(verbose > 1) {
    229243    G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
    230244           << p->GetProcessName() << G4endl;
     245  }
    231246}
    232247
     
    246261{
    247262  emp_vector.push_back(p);
    248   if(verbose > 1)
     263  if(verbose > 1) {
    249264    G4cout << "G4LossTableManager::Register G4VEmProcess : "
    250265           << p->GetProcessName() << G4endl;
     266  }
    251267}
    252268
     
    258274  for (size_t i=0; i<emp; i++) {
    259275    if(emp_vector[i] == p) emp_vector[i] = 0;
     276  }
     277}
     278
     279//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     280
     281void G4LossTableManager::Register(G4VEmModel* p)
     282{
     283  mod_vector.push_back(p);
     284  if(verbose > 1) {
     285    G4cout << "G4LossTableManager::Register G4VEmModel : "
     286           << p->GetName() << G4endl;
     287  }
     288}
     289
     290//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     291
     292void G4LossTableManager::DeRegister(G4VEmModel* p)
     293{
     294  size_t n = mod_vector.size();
     295  for (size_t i=0; i<n; i++) {
     296    if(mod_vector[i] == p) mod_vector[i] = 0;
     297  }
     298}
     299
     300//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     301
     302void G4LossTableManager::Register(G4VEmFluctuationModel* p)
     303{
     304  fmod_vector.push_back(p);
     305  if(verbose > 1) {
     306    G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
     307           << p->GetName() << G4endl;
     308  }
     309}
     310
     311//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     312
     313void G4LossTableManager::DeRegister(G4VEmFluctuationModel* p)
     314{
     315  size_t n = fmod_vector.size();
     316  for (size_t i=0; i<n; i++) {
     317    if(fmod_vector[i] == p) fmod_vector[i] = 0;
    260318  }
    261319}
     
    364422     const G4ParticleDefinition* aParticle)
    365423{
    366   G4String s = "G4LossTableManager:: dE/dx table not found for "
    367              + aParticle->GetParticleName() + "!";
    368   G4Exception(s);
    369   exit(1);
     424  G4String s = " dE/dx table not found for "
     425             + aParticle->GetParticleName() + " !";
     426  G4Exception("G4LossTableManager::ParticleHaveNoLoss", "EM01",
     427              FatalException, s);
     428
    370429}
    371430
     
    476535    p = loss_vector[i];
    477536    if (p && aParticle == part_vector[i] && !tables_are_built[i]) {
    478       if (p->IsIonisationProcess() && isActive[i] || !em || (em && !isActive[iem]) ) {
     537      if ((p->IsIonisationProcess() && isActive[i]) ||
     538          !em || (em && !isActive[iem]) ) {
    479539        em = p;
    480540        iem= i;
     
    509569  dedx = em->IonisationTable();
    510570  if (1 < n_dedx) {
    511     em->SetDEDXTable(dedx, fIonisation);
     571    em->SetDEDXTable(dedx, fIsIonisation);
    512572    dedx = 0;
    513573    dedx  = G4PhysicsTableHelper::PreparePhysicsTable(dedx);
     
    560620    G4PhysicsTable* dedxSub = em->IonisationTableForSubsec();
    561621    if (1 < listSub.size()) {
    562       em->SetDEDXTable(dedxSub, fSubIonisation);
     622      em->SetDEDXTable(dedxSub, fIsSubIonisation);
    563623      dedxSub = 0;
    564624      dedxSub = G4PhysicsTableHelper::PreparePhysicsTable(dedxSub);
     
    829889}
    830890
     891//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     892
     893void G4LossTableManager::SetSplineFlag(G4bool val)
     894{
     895  splineFlag = val;
     896  tableBuilder->SetSplineFlag(splineFlag);
     897}
     898
     899//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     900
     901G4bool G4LossTableManager::SplineFlag() const
     902{
     903  return splineFlag;
     904}
     905
    831906//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    832907
     
    843918}
    844919
     920//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     921
     922G4EmCorrections* G4LossTableManager::EmCorrections()
     923{
     924  return emCorrections;
     925}
     926
     927//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     928
     929G4EmSaturation* G4LossTableManager::EmSaturation()
     930{
     931  return emSaturation;
     932}
     933
    845934//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
  • trunk/source/processes/electromagnetic/utils/src/G4VEmFluctuationModel.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmFluctuationModel.cc,v 1.2 2006/06/29 19:55:15 gunter Exp $
    27 // GEANT4 tag $Name: $
     26// $Id: G4VEmFluctuationModel.cc,v 1.4 2009/02/19 11:25:50 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4949
    5050#include "G4VEmFluctuationModel.hh"
    51 
     51#include "G4LossTableManager.hh"
    5252
    5353//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    5656G4VEmFluctuationModel::G4VEmFluctuationModel(const G4String& nam)
    5757  : name(nam)
     58{
     59  G4LossTableManager::Instance()->Register(this);
     60}
     61
     62G4VEmFluctuationModel::~G4VEmFluctuationModel()
     63{
     64  G4LossTableManager::Instance()->DeRegister(this);
     65}
     66
     67void G4VEmFluctuationModel::InitialiseMe(const G4ParticleDefinition*)
    5868{}
    5969
    60 G4VEmFluctuationModel::~G4VEmFluctuationModel()
     70void G4VEmFluctuationModel::SetParticleAndCharge(const G4ParticleDefinition*,
     71                                                 G4double)
    6172{}
    6273
  • trunk/source/processes/electromagnetic/utils/src/G4VEmModel.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmModel.cc,v 1.8 2007/09/25 10:19:07 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VEmModel.cc,v 1.25 2009/02/19 09:57:36 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4141// 25.10.2005 Set default highLimit=100.TeV (V.Ivanchenko)
    4242// 06.02.2006 add method ComputeMeanFreePath() (mma)
     43// 16.02.2009 Move implementations of virtual methods to source (VI)
    4344//
    4445//
     
    5152
    5253#include "G4VEmModel.hh"
     54#include "G4LossTableManager.hh"
     55#include "G4ProductionCutsTable.hh"
    5356
    5457//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     
    5659
    5760G4VEmModel::G4VEmModel(const G4String& nam):
    58  lowLimit(0.1*keV), highLimit(100.0*TeV), fluc(0), name(nam), pParticleChange(0)
    59 {}
     61  fluc(0), name(nam), lowLimit(0.1*keV), highLimit(100.0*TeV),
     62  polarAngleLimit(0.0),secondaryThreshold(DBL_MAX),theLPMflag(false),
     63  pParticleChange(0),nuclearStopping(false),
     64  currentCouple(0),currentElement(0),
     65  nsec(5),flagDeexcitation(false)
     66{
     67  xsec.resize(nsec);
     68  nSelectors = 0;
     69  G4LossTableManager::Instance()->Register(this);
     70}
    6071
    6172//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    6273
    6374G4VEmModel::~G4VEmModel()
    64 {}
     75{
     76  G4LossTableManager::Instance()->DeRegister(this);
     77  G4int n = elmSelectors.size();
     78  if(n > 0) {
     79    for(G4int i=0; i<n; i++) {
     80      delete elmSelectors[i];
     81    }
     82  }
     83}
     84
     85//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     86
     87void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* p,
     88                                            const G4DataVector& cuts)
     89{
     90  // initialise before run
     91  flagDeexcitation = false;
     92
     93  G4int nbins = G4int(std::log10(highLimit/lowLimit) + 0.5);
     94  if(nbins < 3) nbins = 3;
     95  G4bool spline = G4LossTableManager::Instance()->SplineFlag();
     96
     97  G4ProductionCutsTable* theCoupleTable=
     98    G4ProductionCutsTable::GetProductionCutsTable();
     99  G4int numOfCouples = theCoupleTable->GetTableSize();
     100
     101  // prepare vector
     102  if(numOfCouples > nSelectors) {
     103    elmSelectors.resize(numOfCouples);
     104    nSelectors = numOfCouples;
     105  }
     106
     107  // initialise vector
     108  for(G4int i=0; i<numOfCouples; i++) {
     109    const G4MaterialCutsCouple* couple =
     110      theCoupleTable->GetMaterialCutsCouple(i);
     111    const G4Material* material = couple->GetMaterial();
     112    G4int idx = couple->GetIndex();
     113
     114    // selector already exist check if should be deleted
     115    G4bool create = true;
     116    if(elmSelectors[i]) {
     117      if(material == elmSelectors[i]->GetMaterial()) create = false;
     118      else delete elmSelectors[i];
     119    }
     120    if(create) {
     121      elmSelectors[i] = new G4EmElementSelector(this,material,nbins,
     122                                                lowLimit,highLimit,spline);
     123    }
     124    elmSelectors[i]->Initialise(p, cuts[idx]);
     125    //elmSelectors[i]->Dump(p);
     126  }
     127}
     128
     129//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     130
     131G4double G4VEmModel::ComputeDEDXPerVolume(const G4Material*,
     132                                          const G4ParticleDefinition*,
     133                                          G4double,G4double)
     134{
     135  return 0.0;
     136}
    65137
    66138//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     
    68140G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material,
    69141                                           const G4ParticleDefinition* p,
    70                                                  G4double ekin,
    71                                                  G4double emin,
    72                                                  G4double emax)
    73 {
     142                                           G4double ekin,
     143                                           G4double emin,
     144                                           G4double emax)
     145{
     146  SetupForMaterial(p, material, ekin);
    74147  G4double cross = 0.0;
    75148  const G4ElementVector* theElementVector = material->GetElementVector();
    76149  const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
    77   size_t nelm = material->GetNumberOfElements();
    78   for (size_t i=0; i<nelm; i++) {
    79     const G4Element* elm = (*theElementVector)[i];
     150  G4int nelm = material->GetNumberOfElements();
     151  if(nelm > nsec) {
     152    xsec.resize(nelm);
     153    nsec = nelm;
     154  }
     155  for (G4int i=0; i<nelm; i++) {
    80156    cross += theAtomNumDensityVector[i]*
    81       ComputeCrossSectionPerAtom(p,ekin,elm->GetZ(),elm->GetN(),emin,emax);
     157      ComputeCrossSectionPerAtom(p,(*theElementVector)[i],ekin,emin,emax);
    82158    xsec[i] = cross;
    83159  }
     
    87163//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    88164
    89 G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p,
    90                                                G4double ekin,
    91                                          const G4Material* material,     
    92                                                G4double emin,
    93                                                G4double emax)
    94 {
    95   G4double mfp = DBL_MAX;
    96   G4double cross = CrossSectionPerVolume(material,p,ekin,emin,emax);
    97   if (cross > DBL_MIN) mfp = 1./cross;
    98   return mfp;
    99 }
    100 
    101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    102 
    103 
     165G4double G4VEmModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
     166                                                G4double, G4double, G4double,
     167                                                G4double, G4double)
     168{
     169  return 0.0;
     170}
     171
     172//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     173
     174G4double G4VEmModel::MinEnergyCut(const G4ParticleDefinition*,
     175                                  const G4MaterialCutsCouple*)
     176{
     177  return 0.0;
     178}
     179
     180//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     181
     182G4double G4VEmModel::GetChargeSquareRatio(const G4ParticleDefinition* p,
     183                                          const G4Material*, G4double)
     184{
     185  G4double q = p->GetPDGCharge()/CLHEP::eplus;
     186  return q*q;
     187}
     188
     189//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     190
     191G4double G4VEmModel::GetParticleCharge(const G4ParticleDefinition* p,
     192                                       const G4Material*, G4double)
     193{
     194  return p->GetPDGCharge();
     195}
     196
     197//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     198
     199void G4VEmModel::CorrectionsAlongStep(const G4MaterialCutsCouple*,
     200                                      const G4DynamicParticle*,
     201                                      G4double&,G4double&,G4double)
     202{}
     203
     204//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     205
     206void G4VEmModel::SampleDeexcitationAlongStep(const G4Material*,
     207                                             const G4Track&,
     208                                             G4double& )
     209{}
     210
     211//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     212
     213G4double G4VEmModel::MaxSecondaryEnergy(const G4ParticleDefinition*,
     214                                        G4double kineticEnergy)
     215{
     216  return kineticEnergy;
     217}
     218
     219//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     220
     221void G4VEmModel::SampleScattering(const G4DynamicParticle*, G4double)
     222{}
     223
     224//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     225
     226G4double G4VEmModel::ComputeTruePathLengthLimit(const G4Track&,
     227                                                G4PhysicsTable*,
     228                                                G4double)
     229{
     230  return DBL_MAX;
     231}
     232
     233//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     234
     235G4double G4VEmModel::ComputeGeomPathLength(G4double truePathLength)
     236{
     237  return truePathLength;
     238}
     239
     240//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     241
     242G4double G4VEmModel::ComputeTrueStepLength(G4double geomPathLength)
     243{
     244  return geomPathLength;
     245}
     246
     247//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     248
     249void G4VEmModel::DefineForRegion(const G4Region*)
     250{}
     251
     252//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     253
     254void G4VEmModel::SetupForMaterial(const G4ParticleDefinition*,
     255                                  const G4Material*, G4double)
     256{}
     257
     258//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
  • trunk/source/processes/electromagnetic/utils/src/G4VEmProcess.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEmProcess.cc,v 1.48 2007/10/29 08:38:58 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VEmProcess.cc,v 1.62 2009/02/19 09:57:36 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    8282
    8383G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
    84                       G4VDiscreteProcess(name, type),
    85   selectedModel(0),                   
     84  G4VDiscreteProcess(name, type),
     85  secondaryParticle(0),
     86  buildLambdaTable(true),
    8687  theLambdaTable(0),
    8788  theEnergyOfCrossSectionMax(0),
    8889  theCrossSectionMax(0),
    89   particle(0),
    90   secondaryParticle(0),
    91   nLambdaBins(90),
    92   lambdaFactor(0.8),
    93   currentCouple(0),
    9490  integral(false),
    95   buildLambdaTable(true),
    9691  applyCuts(false),
    9792  startFromNull(true),
    98   nRegions(0)
     93  useDeexcitation(false),
     94  nDERegions(0),
     95  idxDERegions(0),
     96  currentModel(0),
     97  particle(0),
     98  currentCouple(0)
    9999{
    100100  SetVerboseLevel(1);
     101
     102  // Size of tables assuming spline
    101103  minKinEnergy = 0.1*keV;
    102   maxKinEnergy = 100.0*GeV;
     104  maxKinEnergy = 100.0*TeV;
     105  nLambdaBins  = 84;
     106
     107  // default lambda factor
     108  lambdaFactor  = 0.8;
     109
     110  // default limit on polar angle
     111  polarAngleLimit = 0.0;
     112
     113  // particle types
    103114  theGamma     = G4Gamma::Gamma();
    104115  theElectron  = G4Electron::Electron();
     
    126137  delete modelManager;
    127138  (G4LossTableManager::Instance())->DeRegister(this);
     139}
     140
     141//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     142
     143void G4VEmProcess::Clear()
     144{
     145  delete [] theEnergyOfCrossSectionMax;
     146  delete [] theCrossSectionMax;
     147  delete [] idxDERegions;
     148  theEnergyOfCrossSectionMax = 0;
     149  theCrossSectionMax = 0;
     150  idxDERegions = 0;
     151  currentCouple = 0;
     152  preStepLambda = 0.0;
     153  mfpKinEnergy  = DBL_MAX;
     154  deRegions.clear();
     155  nDERegions = 0;
    128156}
    129157
     
    153181      theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
    154182  }
    155 }
    156 
    157 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    158 
    159 void G4VEmProcess::Clear()
    160 {
    161   if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax;
    162   if(theCrossSectionMax) delete [] theCrossSectionMax;
    163   theEnergyOfCrossSectionMax = 0;
    164   theCrossSectionMax = 0;
    165   currentCouple = 0;
    166   preStepLambda = 0.0;
    167   mfpKinEnergy  = DBL_MAX;
     183  // Sub Cutoff and Deexcitation
     184  if (nDERegions>0) {
     185
     186    const G4ProductionCutsTable* theCoupleTable=
     187          G4ProductionCutsTable::GetProductionCutsTable();
     188    size_t numOfCouples = theCoupleTable->GetTableSize();
     189
     190    idxDERegions = new G4bool[numOfCouples];
     191
     192    for (size_t j=0; j<numOfCouples; j++) {
     193
     194      const G4MaterialCutsCouple* couple =
     195        theCoupleTable->GetMaterialCutsCouple(j);
     196      const G4ProductionCuts* pcuts = couple->GetProductionCuts();
     197      G4bool reg = false;
     198      for(G4int i=0; i<nDERegions; i++) {
     199        if(deRegions[i]) {
     200          if(pcuts == deRegions[i]->GetProductionCuts()) reg = true;
     201        }
     202      }
     203      idxDERegions[j] = reg;
     204    }
     205  }
     206  if (1 < verboseLevel && nDERegions>0) {
     207    G4cout << " Deexcitation is activated for regions: " << G4endl;
     208    for (G4int i=0; i<nDERegions; i++) {
     209      const G4Region* r = deRegions[i];
     210      G4cout << "           " << r->GetName() << G4endl;
     211    }
     212  }
    168213}
    169214
     
    228273      G4cout << *theLambdaTable << G4endl;
    229274    }
     275  }
     276}
     277
     278//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     279
     280void G4VEmProcess::PrintInfoDefinition()
     281{
     282  if(verboseLevel > 0) {
     283    G4cout << G4endl << GetProcessName() << ":   for  "
     284           << particle->GetParticleName();
     285    if(integral) G4cout << ", integral: 1 ";
     286    if(applyCuts) G4cout << ", applyCuts: 1 ";
     287    G4cout << "    SubType= " << GetProcessSubType() << G4endl;
     288    if(buildLambdaTable) {
     289      G4cout << "      Lambda tables from "
     290             << G4BestUnit(minKinEnergy,"Energy")
     291             << " to "
     292             << G4BestUnit(maxKinEnergy,"Energy")
     293             << " in " << nLambdaBins << " bins, spline: "
     294             << (G4LossTableManager::Instance())->SplineFlag()
     295             << G4endl;
     296    }
     297    PrintInfo();
     298    modelManager->DumpModelList(verboseLevel);
     299  }
     300
     301  if(verboseLevel > 2 && buildLambdaTable) {
     302    G4cout << "      LambdaTable address= " << theLambdaTable << G4endl;
     303    if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
    230304  }
    231305}
     
    295369//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    296370
    297 G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,
    298                                        G4double,
    299                                        G4ForceCondition* condition)
    300 {
    301   *condition = NotForced;
    302   return G4VEmProcess::MeanFreePath(track);
    303 }
    304 
    305 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    306 
    307371G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
    308372                                              const G4Step&)
     
    333397  }
    334398
    335   G4VEmModel* currentModel = SelectModel(finalT);
    336 
     399  SelectModel(finalT);
     400  if(useDeexcitation) {
     401    currentModel->SetDeexcitationFlag(idxDERegions[currentMaterialIndex]);
     402  }
    337403  /* 
    338404  if(0 < verboseLevel) {
     
    373439
    374440        } else if (p == thePositron) {
    375           if (e < (*theCutsPositron)[currentMaterialIndex]) {
     441          if (electron_mass_c2 < (*theCutsGamma)[currentMaterialIndex] &&
     442              e < (*theCutsPositron)[currentMaterialIndex]) {
    376443            good = false;
    377444            e += 2.0*electron_mass_c2;
     
    394461//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    395462
    396 void G4VEmProcess::PrintInfoDefinition()
    397 {
    398   if(verboseLevel > 0) {
    399     G4cout << G4endl << GetProcessName() << ": " ;
    400     PrintInfo();
    401     if(integral) {
    402       G4cout << "      Integral mode is used  "<< G4endl;
    403     }
    404   }
    405 
    406   if (!buildLambdaTable)  return;
    407  
    408   if(verboseLevel > 0) {
    409     G4cout << "      tables are built for  "
    410            << particle->GetParticleName()
    411            << G4endl
    412            << "      Lambda tables from "
    413            << G4BestUnit(minKinEnergy,"Energy")
    414            << " to "
    415            << G4BestUnit(maxKinEnergy,"Energy")
    416            << " in " << nLambdaBins << " bins."
    417            << G4endl;
    418   }
    419 
    420   if(verboseLevel > 1) {
    421     G4cout << "Tables are built for " << particle->GetParticleName()
    422            << G4endl;
    423 
    424   if(verboseLevel > 2) {
    425     G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
    426     if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
    427     }
    428   }
    429 }
    430 
    431 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    432 
    433 G4double G4VEmProcess::MicroscopicCrossSection(G4double kineticEnergy,
    434                                          const G4MaterialCutsCouple* couple)
    435 {
    436   // Cross section per atom is calculated
    437   DefineMaterial(couple);
    438   G4double cross = 0.0;
    439   G4bool b;
    440   if(theLambdaTable) {
    441     cross = (((*theLambdaTable)[currentMaterialIndex])->
    442                            GetValue(kineticEnergy, b));
    443 
    444     cross /= currentMaterial->GetTotNbOfAtomsPerVolume();
    445   } else {
    446     G4VEmModel* model = SelectModel(kineticEnergy);
    447     cross =
    448       model->CrossSectionPerVolume(currentMaterial,particle,kineticEnergy);
    449   }
    450 
    451   return cross;
    452 }
    453 
    454 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    455 
    456463G4bool G4VEmProcess::StorePhysicsTable(const G4ParticleDefinition* part,
    457464                                       const G4String& directory,
     
    508515             << G4endl;
    509516    }
     517    if((G4LossTableManager::Instance())->SplineFlag()) {
     518      size_t n = theLambdaTable->length();
     519      for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);}
     520    }
    510521  } else {
    511522    if (1 < verboseLevel) {
     
    517528
    518529  return yes;
     530}
     531
     532//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     533
     534void G4VEmProcess::ActivateDeexcitation(G4bool val, const G4Region* r)
     535{
     536  G4RegionStore* regionStore = G4RegionStore::GetInstance();
     537  const G4Region* reg = r;
     538  if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);}
     539
     540  // the region is in the list
     541  if (nDERegions) {
     542    for (G4int i=0; i<nDERegions; i++) {
     543      if (reg == deRegions[i]) {
     544        if(!val) deRegions[i] = 0;
     545        return;
     546      }
     547    }
     548  }
     549
     550  // new region
     551  if(val) {
     552    useDeexcitation = true;
     553    deRegions.push_back(reg);
     554    nDERegions++;
     555  } else {
     556    useDeexcitation = false;
     557  }
     558}
     559
     560//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     561
     562G4double G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy,
     563                                             const G4MaterialCutsCouple* couple)
     564{
     565  // Cross section per atom is calculated
     566  DefineMaterial(couple);
     567  G4double cross = 0.0;
     568  G4bool b;
     569  if(theLambdaTable) {
     570    cross = (((*theLambdaTable)[currentMaterialIndex])->
     571                           GetValue(kineticEnergy, b));
     572  } else {
     573    SelectModel(kineticEnergy);
     574    cross = currentModel->CrossSectionPerVolume(currentMaterial,
     575                                                particle,kineticEnergy);
     576  }
     577
     578  return cross;
     579}
     580
     581//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     582
     583G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,
     584                                       G4double,
     585                                       G4ForceCondition* condition)
     586{
     587  *condition = NotForced;
     588  return G4VEmProcess::MeanFreePath(track);
    519589}
    520590
     
    568638  G4PhysicsVector* v =
    569639    new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
     640  v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
    570641  return v;
    571642}
  • trunk/source/processes/electromagnetic/utils/src/G4VEnergyLoss.cc

    r819 r961  
    2626//
    2727// $Id: G4VEnergyLoss.cc,v 1.46 2006/06/29 19:55:21 gunter Exp $
    28 // GEANT4 tag $Name: $
     28// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2929//
    3030
  • trunk/source/processes/electromagnetic/utils/src/G4VEnergyLossProcess.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VEnergyLossProcess.cc,v 1.123 2008/01/11 19:55:29 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VEnergyLossProcess.cc,v 1.146 2009/02/19 11:25:50 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    146146
    147147G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name,
    148   G4ProcessType type): G4VContinuousDiscreteProcess(name, type),
     148                                           G4ProcessType type):
     149  G4VContinuousDiscreteProcess(name, type),
     150  secondaryParticle(0),
    149151  nSCoffRegions(0),
     152  nDERegions(0),
    150153  idxSCoffRegions(0),
     154  idxDERegions(0),
    151155  nProcesses(0),
    152156  theDEDXTable(0),
     
    165169  theEnergyOfCrossSectionMax(0),
    166170  theCrossSectionMax(0),
    167   particle(0),
    168171  baseParticle(0),
    169   secondaryParticle(0),
    170   currentCouple(0),
    171   nBins(120),
    172   nBinsCSDA(70),
    173   nWarnings(0),
    174   linLossLimit(0.05),
    175172  minSubRange(0.1),
    176   lambdaFactor(0.8),
    177   mfpKinEnergy(0.0),
    178173  lossFluctuationFlag(true),
    179174  rndmStepFlag(false),
    180175  tablesAreBuilt(false),
    181176  integral(true),
     177  isIon(false),
    182178  isIonisation(true),
    183   useSubCutoff(false)
     179  useSubCutoff(false),
     180  useDeexcitation(false),
     181  particle(0),
     182  currentCouple(0),
     183  nWarnings(0),
     184  mfpKinEnergy(0.0)
    184185{
    185186  SetVerboseLevel(1);
    186187
    187   // Size of tables
     188  // low energy limit
    188189  lowestKinEnergy  = 1.*eV;
     190
     191  // Size of tables assuming spline
    189192  minKinEnergy     = 0.1*keV;
    190193  maxKinEnergy     = 100.0*TeV;
     194  nBins            = 84;
    191195  maxKinEnergyCSDA = 1.0*GeV;
     196  nBinsCSDA        = 35;
     197
     198  // default linear loss limit for spline
     199  linLossLimit  = 0.01;
    192200
    193201  // default dRoverRange and finalRange
    194202  SetStepFunction(0.2, 1.0*mm);
    195203
    196   theElectron = G4Electron::Electron();
    197   thePositron = G4Positron::Positron();
     204  // default lambda factor
     205  lambdaFactor  = 0.8;
     206
     207  // particle types
     208  theElectron   = G4Electron::Electron();
     209  thePositron   = G4Positron::Positron();
     210  theGenericIon = 0;
    198211
    199212  // run time objects
     
    208221  fluctModel = 0;
    209222
    210   scoffRegions.clear();
    211   scProcesses.clear();
    212223  scTracks.reserve(5);
    213224  secParticles.reserve(5);
     
    215226  // Data for stragling of ranges from ICRU'37 report
    216227  const G4int nrbins = 7;
    217   vstrag = new G4PhysicsLogVector(keV, GeV, nrbins);
     228  vstrag = new G4PhysicsLogVector(keV, GeV, nrbins-1);
     229  vstrag->SetSpline(true);
    218230  G4double s[nrbins] = {-0.2, -0.85, -1.3, -1.578, -1.76, -1.85, -1.9};
    219231  for(G4int i=0; i<nrbins; i++) {vstrag->PutValue(i, s[i]);}
     
    228240           << G4endl;
    229241  delete vstrag;
    230   Clear();
     242  Clean();
    231243
    232244  if ( !baseParticle ) {
     
    282294//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    283295
    284 void G4VEnergyLossProcess::Clear()
    285 {
    286   if(1 < verboseLevel)
     296void G4VEnergyLossProcess::Clean()
     297{
     298  if(1 < verboseLevel) {
    287299    G4cout << "G4VEnergyLossProcess::Clear() for " << GetProcessName()
    288     << G4endl;
    289 
     300           << G4endl;
     301  }
    290302  delete [] theDEDXAtMaxEnergy;
    291303  delete [] theRangeAtMaxEnergy;
     
    293305  delete [] theCrossSectionMax;
    294306  delete [] idxSCoffRegions;
     307  delete [] idxDERegions;
    295308
    296309  theDEDXAtMaxEnergy = 0;
     
    300313  tablesAreBuilt = false;
    301314
    302   scTracks.clear();
     315  //scTracks.clear();
    303316  scProcesses.clear();
    304 }
    305 
    306 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    307 
    308 void G4VEnergyLossProcess::PreparePhysicsTable(
    309      const G4ParticleDefinition& part)
    310 {
    311 
    312   // Are particle defined?
    313   if( !particle ) {
    314     if(part.GetParticleType() == "nucleus" &&
    315        part.GetParticleSubType() == "generic")
    316          particle = G4GenericIon::GenericIon();
    317     else particle = &part;
    318   }
    319 
     317  nProcesses = 0;
     318}
     319
     320//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     321
     322G4double G4VEnergyLossProcess::MinPrimaryEnergy(const G4ParticleDefinition*,
     323                                                const G4Material*,
     324                                                G4double cut)
     325{
     326  return cut;
     327}
     328
     329//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     330
     331void
     332G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
     333{
    320334  if(1 < verboseLevel) {
    321335    G4cout << "G4VEnergyLossProcess::PreparePhysicsTable for "
    322336           << GetProcessName()
    323337           << " for " << part.GetParticleName()
    324            << " local: " << particle->GetParticleName()
    325338           << G4endl;
    326339  }
    327 
    328   G4LossTableManager* lManager = G4LossTableManager::Instance();
    329 
    330   if(&part != particle) {
    331     if(part.GetParticleType() == "nucleus") lManager->RegisterIon(&part, this);
    332     else                          lManager->RegisterExtraParticle(&part, this);
    333     return;
    334   }
    335 
    336   Clear();
    337340
    338341  currentCouple = 0;
     
    341344  fRange        = DBL_MAX;
    342345  preStepKinEnergy = 0.0;
     346  chargeSqRatio = 1.0;
     347  massRatio = 1.0;
     348  reduceFactor = 1.0;
     349
     350  G4LossTableManager* lManager = G4LossTableManager::Instance();
     351
     352  // Are particle defined?
     353  if( !particle ) {
     354    particle = &part;
     355    if(part.GetParticleType() == "nucleus") {
     356      if(!theGenericIon) theGenericIon = G4GenericIon::GenericIon();
     357      if(particle == theGenericIon) { isIon = true; }
     358      else if(part.GetPDGCharge() > eplus) {
     359        isIon = true;
     360
     361        // generic ions created on-fly
     362        if(part.GetPDGCharge() > 2.5*eplus) {
     363          particle = theGenericIon;
     364        }
     365      }
     366    }
     367  }
     368
     369  if( particle != &part) {
     370    if(part.GetParticleType() == "nucleus") {
     371      isIon = true;
     372      lManager->RegisterIon(&part, this);
     373    } else {
     374      lManager->RegisterExtraParticle(&part, this);
     375    }
     376    return;
     377  }
     378
     379  Clean();
    343380
    344381  // Base particle and set of models can be defined here
     
    372409  G4double initialCharge = particle->GetPDGCharge();
    373410  G4double initialMass   = particle->GetPDGMass();
    374   chargeSquare = initialCharge*initialCharge/(eplus*eplus);
    375   chargeSqRatio = 1.0;
    376   massRatio = 1.0;
    377   reduceFactor = 1.0;
    378411
    379412  if (baseParticle) {
     
    387420                                     minSubRange, verboseLevel);
    388421
    389   // Sub Cutoff Regime
    390   scProcesses.clear();
    391   nProcesses = 0;
    392  
    393   if (nSCoffRegions>0) {
     422  // Sub Cutoff and Deexcitation
     423  if (nSCoffRegions>0 || nDERegions>0) {
    394424    theSubCuts = modelManager->SubCutoff();
    395425
     
    397427          G4ProductionCutsTable::GetProductionCutsTable();
    398428    size_t numOfCouples = theCoupleTable->GetTableSize();
    399     idxSCoffRegions = new G4int[numOfCouples];
     429
     430    if(nSCoffRegions>0) idxSCoffRegions = new G4bool[numOfCouples];
     431    if(nDERegions>0) idxDERegions = new G4bool[numOfCouples];
    400432 
    401433    for (size_t j=0; j<numOfCouples; j++) {
     
    404436        theCoupleTable->GetMaterialCutsCouple(j);
    405437      const G4ProductionCuts* pcuts = couple->GetProductionCuts();
    406       G4int reg = 0;
    407       for(G4int i=0; i<nSCoffRegions; i++) {
    408         if( pcuts == scoffRegions[i]->GetProductionCuts()) reg = 1;
    409       }
    410       idxSCoffRegions[j] = reg;
     438     
     439      if(nSCoffRegions>0) {
     440        G4bool reg = false;
     441        for(G4int i=0; i<nSCoffRegions; i++) {
     442          if( pcuts == scoffRegions[i]->GetProductionCuts()) reg = true;
     443        }
     444        idxSCoffRegions[j] = reg;
     445      }
     446      if(nDERegions>0) {
     447        G4bool reg = false;
     448        for(G4int i=0; i<nDERegions; i++) {
     449          if( pcuts == deRegions[i]->GetProductionCuts()) reg = true;
     450        }
     451        idxDERegions[j] = reg;
     452      }
    411453    }
    412454  }
     
    416458  if (1 < verboseLevel) {
    417459    G4cout << "G4VEnergyLossProcess::Initialise() is done "
     460           << " for local " << particle->GetParticleName()
     461           << " isIon= " << isIon
    418462           << " chargeSqRatio= " << chargeSqRatio
    419463           << " massRatio= " << massRatio
     
    426470      }
    427471    }
     472    if (nDERegions) {
     473      G4cout << " Deexcitation is ON for regions: " << G4endl;
     474      for (G4int i=0; i<nDERegions; i++) {
     475        const G4Region* r = deRegions[i];
     476        G4cout << "           " << r->GetName() << G4endl;
     477      }
     478    }
    428479  }
    429480}
     
    442493  }
    443494
    444   if(!tablesAreBuilt && &part == particle)
    445     G4LossTableManager::Instance()->BuildPhysicsTable(particle, this);
    446 
    447   if(0 < verboseLevel && (&part == particle) && !baseParticle) {
    448     PrintInfoDefinition();
    449     safetyHelper->InitialiseHelper();
     495  if(&part == particle) {
     496    if(!tablesAreBuilt) {
     497      G4LossTableManager::Instance()->BuildPhysicsTable(particle, this);
     498    }
     499    if(!baseParticle) {
     500      if(0 < verboseLevel) PrintInfoDefinition();
     501   
     502      // needs to be done only once
     503      safetyHelper->InitialiseHelper();
     504    }
    450505  }
    451506
     
    456511    if(isIonisation) G4cout << "  isIonisation  flag = 1";
    457512    G4cout << G4endl;
    458   }
    459 }
    460 
    461 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    462 
    463 void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r)
    464 {
    465   G4RegionStore* regionStore = G4RegionStore::GetInstance();
    466   if(val) {
    467     useSubCutoff = true;
    468     if (!r) r = regionStore->GetRegion("DefaultRegionForTheWorld", false);
    469     if (nSCoffRegions) {
    470       for (G4int i=0; i<nSCoffRegions; i++) {
    471         if (r == scoffRegions[i]) return;
    472       }
    473     }
    474     scoffRegions.push_back(r);
    475     nSCoffRegions++;
    476   } else {
    477     useSubCutoff = false;
    478513  }
    479514}
     
    528563  for(size_t i=0; i<numOfCouples; i++) {
    529564
    530     if(1 < verboseLevel)
     565    if(1 < verboseLevel) {
    531566      G4cout << "G4VEnergyLossProcess::BuildDEDXVector flag=  "
    532567             << table->GetFlag(i) << G4endl;
    533 
     568    }
    534569    if (table->GetFlag(i)) {
    535570
     
    538573        theCoupleTable->GetMaterialCutsCouple(i);
    539574      G4PhysicsVector* aVector = new G4PhysicsLogVector(emin, emax, bin);
     575      aVector->SetSpline((G4LossTableManager::Instance())->SplineFlag());
     576
    540577      modelManager->FillDEDXVector(aVector, couple, tType);
    541578
     
    580617           << G4endl;
    581618  }
    582   if(!table) return table;
     619  if(!table) {return table;}
    583620
    584621  // Access to materials
     
    615652//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    616653
    617 G4double G4VEnergyLossProcess::GetContinuousStepLimit(
    618                 const G4Track&,
    619                 G4double, G4double, G4double&)
    620 {
    621   return DBL_MAX;
     654void G4VEnergyLossProcess::PrintInfoDefinition()
     655{
     656  if(0 < verboseLevel) {
     657    G4cout << G4endl << GetProcessName() << ":   for  "
     658           << particle->GetParticleName()
     659           << "    SubType= " << GetProcessSubType()
     660           << G4endl
     661           << "      dE/dx and range tables from "
     662           << G4BestUnit(minKinEnergy,"Energy")
     663           << " to " << G4BestUnit(maxKinEnergy,"Energy")
     664           << " in " << nBins << " bins" << G4endl
     665           << "      Lambda tables from threshold to "
     666           << G4BestUnit(maxKinEnergy,"Energy")
     667           << " in " << nBins << " bins, spline: "
     668           << (G4LossTableManager::Instance())->SplineFlag()
     669           << G4endl;
     670    if(theRangeTableForLoss && isIonisation) {
     671      G4cout << "      finalRange(mm)= " << finalRange/mm
     672             << ", dRoverRange= " << dRoverRange
     673             << ", integral: " << integral
     674             << ", fluct: " << lossFluctuationFlag
     675             << ", linLossLimit= " << linLossLimit
     676             << G4endl;
     677    }
     678    PrintInfo();
     679    modelManager->DumpModelList(verboseLevel);
     680    if(theCSDARangeTable && isIonisation) {
     681      G4cout << "      CSDA range table up"
     682             << " to " << G4BestUnit(maxKinEnergyCSDA,"Energy")
     683             << " in " << nBinsCSDA << " bins" << G4endl;
     684    }
     685    if(nSCoffRegions>0 && isIonisation) {
     686      G4cout << "      Subcutoff sampling in " << nSCoffRegions
     687             << " regions" << G4endl;
     688    }
     689    if(2 < verboseLevel) {
     690      G4cout << "      DEDXTable address= " << theDEDXTable << G4endl;
     691      if(theDEDXTable && isIonisation) G4cout << (*theDEDXTable) << G4endl;
     692      G4cout << "non restricted DEDXTable address= "
     693             << theDEDXunRestrictedTable << G4endl;
     694      if(theDEDXunRestrictedTable && isIonisation) {
     695           G4cout << (*theDEDXunRestrictedTable) << G4endl;
     696      }
     697      if(theDEDXSubTable && isIonisation) {
     698        G4cout << (*theDEDXSubTable) << G4endl;
     699      }
     700      G4cout << "      CSDARangeTable address= " << theCSDARangeTable
     701             << G4endl;
     702      if(theCSDARangeTable && isIonisation) {
     703        G4cout << (*theCSDARangeTable) << G4endl;
     704      }
     705      G4cout << "      RangeTableForLoss address= " << theRangeTableForLoss
     706             << G4endl;
     707      if(theRangeTableForLoss && isIonisation) {
     708             G4cout << (*theRangeTableForLoss) << G4endl;
     709      }
     710      G4cout << "      InverseRangeTable address= " << theInverseRangeTable
     711             << G4endl;
     712      if(theInverseRangeTable && isIonisation) {
     713             G4cout << (*theInverseRangeTable) << G4endl;
     714      }
     715      G4cout << "      LambdaTable address= " << theLambdaTable << G4endl;
     716      if(theLambdaTable && isIonisation) {
     717        G4cout << (*theLambdaTable) << G4endl;
     718      }
     719      G4cout << "      SubLambdaTable address= " << theSubLambdaTable << G4endl;
     720      if(theSubLambdaTable && isIonisation) {
     721        G4cout << (*theSubLambdaTable) << G4endl;
     722      }
     723    }
     724  }
     725}
     726
     727//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     728
     729void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r)
     730{
     731  G4RegionStore* regionStore = G4RegionStore::GetInstance();
     732  const G4Region* reg = r;
     733  if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);}
     734
     735  // the region is in the list
     736  if (nSCoffRegions) {
     737    for (G4int i=0; i<nSCoffRegions; i++) {
     738      if (reg == scoffRegions[i]) {
     739        if(!val) deRegions[i] = 0;
     740        return;
     741      }
     742    }
     743  }
     744
     745  // new region
     746  if(val) {
     747    useSubCutoff = true;
     748    scoffRegions.push_back(reg);
     749    nSCoffRegions++;
     750  } else {
     751    useSubCutoff = false;
     752  }
     753}
     754
     755//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     756
     757void G4VEnergyLossProcess::ActivateDeexcitation(G4bool val, const G4Region* r)
     758{
     759  G4RegionStore* regionStore = G4RegionStore::GetInstance();
     760  const G4Region* reg = r;
     761  if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);}
     762
     763  // the region is in the list
     764  if (nDERegions) {
     765    for (G4int i=0; i<nDERegions; i++) {
     766      if (reg == deRegions[i]) {
     767        if(!val) deRegions[i] = 0;
     768        return;
     769      }
     770    }
     771  }
     772
     773  // new region
     774  if(val) {
     775    useDeexcitation = true;
     776    deRegions.push_back(reg);
     777    nDERegions++;
     778  } else {
     779    useDeexcitation = false;
     780  }
    622781}
    623782
     
    641800    if(x > finalRange && y < currentMinStep) {
    642801      x = y + finalRange*(1.0 - dRoverRange)*(2.0 - finalRange/fRange);
    643     } else if (rndmStepFlag) x = SampleRange();
    644     //    G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
    645     //    <<" range= "<<fRange <<" cMinSt="<<currentMinStep
    646     //    <<" safety= " << safety<< " limit= " << x <<G4endl;
    647   }
    648   //  G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
     802    } else if (rndmStepFlag) {x = SampleRange();}
     803    //G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
     804    //  <<" range= "<<fRange <<" cMinSt="<<currentMinStep
     805    //  << " limit= " << x <<G4endl;
     806  }
     807  //G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
    649808  //  <<" stepLimit= "<<x<<G4endl;
    650809  return x;
    651 }
    652 
    653 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    654 
    655 G4double G4VEnergyLossProcess::GetMeanFreePath(
    656                              const G4Track& track,
    657                              G4double,
    658                              G4ForceCondition* condition)
    659 
    660 {
    661   *condition = NotForced;
    662   return MeanFreePath(track);
    663810}
    664811
     
    673820  *condition = NotForced;
    674821  G4double x = DBL_MAX;
     822
     823  // initialisation of material, mass, charge, model at the beginning of the step
     824  DefineMaterial(track.GetMaterialCutsCouple());
     825
     826  const G4ParticleDefinition* currPart = track.GetDefinition();
     827  if(theGenericIon == particle) {
     828    massRatio = proton_mass_c2/currPart->GetPDGMass();
     829  } 
     830  preStepKinEnergy    = track.GetKineticEnergy();
     831  preStepScaledEnergy = preStepKinEnergy*massRatio;
     832  SelectModel(preStepScaledEnergy);
     833
     834  if(isIon) {
     835    chargeSqRatio =
     836      currentModel->GetChargeSquareRatio(currPart,currentMaterial,preStepKinEnergy);
     837    reduceFactor  = 1.0/(chargeSqRatio*massRatio);
     838  }
     839  //G4cout << "q2= " << chargeSqRatio << " massRatio= " << massRatio << G4endl;
     840  // initialisation for sampling of the interaction length
    675841  if(previousStepSize <= DBL_MIN) theNumberOfInteractionLengthLeft = -1.0;
    676   InitialiseStep(track);
    677 
     842  if(theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX;
     843
     844  // compute mean free path
    678845  if(preStepScaledEnergy < mfpKinEnergy) {
    679846    if (integral) ComputeLambdaForScaledEnergy(preStepScaledEnergy);
     
    686853    if (theNumberOfInteractionLengthLeft < 0.0) {
    687854      // beggining of tracking (or just after DoIt of this process)
     855      //G4cout<<"G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength Reset"<<G4endl;
    688856      ResetNumberOfInteractionLengthLeft();
    689857    } else if(currentInteractionLength < DBL_MAX) {
     
    702870      G4cout << "G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength ";
    703871      G4cout << "[ " << GetProcessName() << "]" << G4endl;
    704       G4cout << " for " << particle->GetParticleName()
     872      G4cout << " for " << currPart->GetParticleName()
    705873             << " in Material  " <<  currentMaterial->GetName()
    706874             << " Ekin(MeV)= " << preStepKinEnergy/MeV
     
    710878    }
    711879#endif
    712 
    713880    // zero cross section case
    714881  } else {
     
    738905  if(length <= DBL_MIN) return &fParticleChange;
    739906  G4double eloss  = 0.0;
    740 
    741   /*
     907  G4double esecdep = 0.0;
     908 
     909  /* 
    742910  if(-1 < verboseLevel) {
    743911    const G4ParticleDefinition* d = track.GetDefinition();
     
    755923  */
    756924
     925  const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
     926
    757927  // stopping
    758928  if (length >= fRange) {
     929    eloss = preStepKinEnergy;
     930    if (useDeexcitation) {
     931      if(idxDERegions[currentMaterialIndex]) {
     932        currentModel->SampleDeexcitationAlongStep(currentMaterial, track, eloss);
     933        if(eloss < 0.0) eloss = 0.0;
     934      }
     935    }
    759936    fParticleChange.SetProposedKineticEnergy(0.0);
    760     fParticleChange.ProposeLocalEnergyDeposit(preStepKinEnergy);
     937    fParticleChange.ProposeLocalEnergyDeposit(eloss);
    761938    return &fParticleChange;
    762939  }
     
    772949      GetScaledRangeForScaledEnergy(preStepScaledEnergy) - length/reduceFactor;
    773950    eloss = preStepKinEnergy - ScaledKinEnergyForLoss(x)/massRatio;
     951   
    774952    /*
    775953    if(-1 < verboseLevel)
     
    781959             << " eloss0(MeV)= "
    782960             << GetDEDXForScaledEnergy(preStepScaledEnergy)*length/MeV
     961             << " lim(MeV)= " << preStepKinEnergy*linLossLimit/MeV
    783962             << G4endl;
    784963    */
    785964  }
    786965
    787   const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
    788   G4VEmModel* currentModel = SelectModel(preStepScaledEnergy);
    789   /*   
     966  /*   
    790967  G4double eloss0 = eloss;
    791968  if(-1 < verboseLevel ) {
     
    801978  G4double cut  = (*theCuts)[currentMaterialIndex];
    802979  G4double esec = 0.0;
    803   G4double esecdep = 0.0;
    804980
    805981  // SubCutOff
     
    807983    if(idxSCoffRegions[currentMaterialIndex]) {
    808984
    809       G4double currentMinSafety = 0.0;
     985      G4bool yes = false;
    810986      G4StepPoint* prePoint  = step.GetPreStepPoint();
    811       G4StepPoint* postPoint = step.GetPostStepPoint();
    812       G4double preSafety  = prePoint->GetSafety();
    813       G4double postSafety = preSafety - length;
    814       G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(1);
    815 
    816       // recompute safety
    817       if(prePoint->GetStepStatus() != fGeomBoundary &&
    818          postPoint->GetStepStatus() != fGeomBoundary) {
    819 
    820         /*
    821         //      G4bool yes = (track.GetTrackID() == 5512);
    822         G4bool yes = false;
    823         if(yes)
    824           G4cout << "G4VEnergyLoss: presafety= " << preSafety
    825                  << " rcut= " << rcut << "  length= " << length
    826                  << " dir " << track.GetMomentumDirection()
    827                  << G4endl;
    828         */
    829 
    830         if(preSafety < rcut)
     987
     988      // Check boundary
     989      if(prePoint->GetStepStatus() == fGeomBoundary) yes = true;
     990
     991      // Check PrePoint
     992      else {
     993        G4double preSafety  = prePoint->GetSafety();
     994        G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(1);
     995
     996        // recompute presafety
     997        if(preSafety < rcut) {
    831998          preSafety = safetyHelper->ComputeSafety(prePoint->GetPosition());
    832 
    833         //if(yes) {
    834         //  G4cout << "G4VEnergyLoss: newsafety= " << preSafety << G4endl;
    835           //       if(preSafety==0.0 && track.GetTrackID() == 5512 ) exit(1);
    836         //}
    837         if(postSafety < rcut)
    838           postSafety = safetyHelper->ComputeSafety(postPoint->GetPosition());
    839         /*     
    840           if(-1 < verboseLevel)
    841           G4cout << "Subcutoff: presafety(mm)= " << preSafety/mm
    842                  << " postsafety(mm)= " << postSafety/mm
    843                  << " rcut(mm)= " << rcut/mm
    844                  << G4endl;
    845         */
    846         currentMinSafety = std::min(preSafety,postSafety);
    847       }
    848 
     999        }
     1000
     1001        if(preSafety < rcut) yes = true;
     1002
     1003        // Check PostPoint
     1004        else {
     1005          G4double postSafety = preSafety - length;
     1006          if(postSafety < rcut) {
     1007            postSafety =
     1008              safetyHelper->ComputeSafety(step.GetPostStepPoint()->GetPosition());
     1009            if(postSafety < rcut) yes = true;
     1010          }
     1011        }
     1012      }
     1013 
    8491014      // Decide to start subcut sampling
    850       if(currentMinSafety < rcut) {
     1015      if(yes) {
    8511016
    8521017        cut = (*theSubCuts)[currentMaterialIndex];
     
    8561021                                currentModel,currentMaterialIndex,
    8571022                                esecdep);
     1023        // add bremsstrahlung sampling
    8581024        /*
    8591025        if(nProcesses > 0) {
     
    8761042            esec += e;
    8771043            pParticleChange->AddSecondary(t);
    878             //  mom -= t->GetMomentum();
    8791044          }     
    880           //        fParticleChange.SetProposedMomentum(mom);           
    8811045        }
    8821046      }
     
    8851049
    8861050  // Corrections, which cannot be tabulated
    887   CorrectionsAlongStep(currentCouple, dynParticle, eloss, length);
     1051  currentModel->CorrectionsAlongStep(currentCouple, dynParticle,
     1052                                     eloss, esecdep, length);
    8881053
    8891054  // Sample fluctuations
     
    8951060      G4double tmax =
    8961061        std::min(currentModel->MaxSecondaryKinEnergy(dynParticle),cut);
     1062      G4double emean = eloss;
    8971063      eloss = fluc->SampleFluctuations(currentMaterial,dynParticle,
    898                                        tmax,length,eloss);
    899       /*           
     1064                                       tmax,length,emean);
     1065      /*                            
    9001066      if(-1 < verboseLevel)
    9011067      G4cout << "After fluct: eloss(MeV)= " << eloss/MeV
    9021068             << " fluc= " << (eloss-eloss0)/MeV
    903              << " currentChargeSquare= " << chargeSquare
     1069             << " ChargeSqRatio= " << chargeSqRatio
    9041070             << " massRatio= " << massRatio
    9051071             << " tmax= " << tmax
     
    9111077  eloss += esecdep;
    9121078  if(eloss < 0.0) eloss = 0.0;
     1079
     1080  // deexcitation
     1081  else if (useDeexcitation) {
     1082    if(idxDERegions[currentMaterialIndex]) {
     1083      currentModel->SampleDeexcitationAlongStep(currentMaterial, track, eloss);
     1084      if(eloss < 0.0) eloss = 0.0;
     1085    }
     1086  }
    9131087
    9141088  // Energy balanse
     
    9171091    eloss  = preStepKinEnergy - esec;
    9181092    finalT = 0.0;
     1093  } else if(isIon) {
     1094    fParticleChange.SetProposedCharge(
     1095      currentModel->GetParticleCharge(track.GetDefinition(),currentMaterial,finalT));
    9191096  }
    9201097
     
    9221099  fParticleChange.ProposeLocalEnergyDeposit(eloss);
    9231100
    924   /*
     1101  /* 
    9251102  if(-1 < verboseLevel) {
    9261103    G4cout << "Final value eloss(MeV)= " << eloss/MeV
     
    9311108           << G4endl;
    9321109  }
    933   */
     1110  */ 
    9341111
    9351112  return &fParticleChange;
     
    9431120       G4VEmModel* model,
    9441121       G4int idx,
    945        G4double& extraEdep)
     1122       G4double& /*extraEdep*/)
    9461123{
    9471124  // Fast check weather subcutoff can work
     
    9521129  const G4Track* track = step.GetTrack();
    9531130  const G4DynamicParticle* dp = track->GetDynamicParticle();
     1131  G4double e = dp->GetKineticEnergy()*massRatio;
    9541132  G4bool b;
    955   G4double cross =
    956     chargeSqRatio*(((*theSubLambdaTable)[idx])->GetValue(dp->GetKineticEnergy(),b));
     1133  G4double cross = chargeSqRatio*(((*theSubLambdaTable)[idx])->GetValue(e,b));
    9571134  G4double length = step.GetStepLength();
    9581135
    9591136  // negligible probability to get any interaction
    9601137  if(length*cross < perMillion) return;
    961   /*   
     1138  /*     
    9621139  if(-1 < verboseLevel)
    9631140    G4cout << "<<< Subcutoff for " << GetProcessName()
     
    9701147  // Sample subcutoff secondaries
    9711148  G4StepPoint* preStepPoint = step.GetPreStepPoint();
     1149  G4StepPoint* postStepPoint = step.GetPostStepPoint();
    9721150  G4ThreeVector prepoint = preStepPoint->GetPosition();
    973   G4ThreeVector dr = step.GetPostStepPoint()->GetPosition() - prepoint;
     1151  G4ThreeVector dr = postStepPoint->GetPosition() - prepoint;
    9741152  G4double pretime = preStepPoint->GetGlobalTime();
    975   //  G4double dt = length/preStepPoint->GetVelocity();
     1153  G4double dt = postStepPoint->GetGlobalTime() - pretime;
     1154  //G4double dt = length/preStepPoint->GetVelocity();
    9761155  G4double fragment = 0.0;
    9771156
     
    9921171
    9931172      G4bool addSec = true;
     1173      /*
    9941174      // do not track very low-energy delta-electrons
    9951175      if(theSecondaryRangeTable && (*it)->GetDefinition() == theElectron) {
     
    10041184        }
    10051185      }
     1186      */
    10061187      if(addSec) {
    1007         //      G4Track* t = new G4Track((*it), pretime + fragment*dt, r);
    1008         G4Track* t = new G4Track((*it), pretime, r);
     1188        G4Track* t = new G4Track((*it), pretime + fragment*dt, r);
     1189        //G4Track* t = new G4Track((*it), pretime, r);
    10091190        t->SetTouchableHandle(track->GetTouchableHandle());
    10101191        tracks.push_back(t);
    10111192
    1012         /*
    1013           if(-1 < verboseLevel)
    1014           G4cout << "New track " << p->GetDefinition()->GetParticleName()
    1015           << " e(keV)= " << p->GetKineticEnergy()/keV
    1016           << " fragment= " << fragment
    1017           << G4endl;
     1193        /*     
     1194        if(-1 < verboseLevel)
     1195          G4cout << "New track " << t->GetDefinition()->GetParticleName()
     1196                 << " e(keV)= " << t->GetKineticEnergy()/keV
     1197                << " fragment= " << fragment
     1198                << G4endl;
    10181199        */
    10191200      }
     
    10591240  }
    10601241
    1061   G4VEmModel* currentModel = SelectModel(postStepScaledEnergy);
     1242  SelectModel(postStepScaledEnergy);
     1243  if(useDeexcitation) {
     1244    currentModel->SetDeexcitationFlag(idxDERegions[currentMaterialIndex]);
     1245  }
     1246
    10621247  const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
    10631248  G4double tcut = (*theCuts)[currentMaterialIndex];
     
    10941279//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    10951280
    1096 void G4VEnergyLossProcess::PrintInfoDefinition()
    1097 {
    1098   if(0 < verboseLevel) {
    1099     G4cout << G4endl << GetProcessName() << ":   tables are built for  "
    1100            << particle->GetParticleName()
    1101            << G4endl
    1102            << "      dE/dx and range tables from "
    1103            << G4BestUnit(minKinEnergy,"Energy")
    1104            << " to " << G4BestUnit(maxKinEnergy,"Energy")
    1105            << " in " << nBins << " bins." << G4endl
    1106            << "      Lambda tables from threshold to "
    1107            << G4BestUnit(maxKinEnergy,"Energy")
    1108            << " in " << nBins << " bins."
     1281G4bool G4VEnergyLossProcess::StorePhysicsTable(
     1282       const G4ParticleDefinition* part, const G4String& directory,
     1283       G4bool ascii)
     1284{
     1285  G4bool res = true;
     1286  if ( baseParticle || part != particle ) return res;
     1287
     1288  if(!StoreTable(part,theDEDXTable,ascii,directory,"DEDX"))
     1289    {res = false;}
     1290
     1291  if(!StoreTable(part,theDEDXunRestrictedTable,ascii,directory,"DEDXnr"))
     1292    {res = false;}
     1293
     1294  if(!StoreTable(part,theDEDXSubTable,ascii,directory,"SubDEDX"))
     1295    {res = false;}
     1296
     1297  if(!StoreTable(part,theIonisationTable,ascii,directory,"Ionisation"))
     1298    {res = false;}
     1299
     1300  if(!StoreTable(part,theIonisationSubTable,ascii,directory,"SubIonisation"))
     1301    {res = false;}
     1302
     1303  if(isIonisation &&
     1304     !StoreTable(part,theCSDARangeTable,ascii,directory,"CSDARange"))
     1305    {res = false;}
     1306
     1307  if(isIonisation &&
     1308     !StoreTable(part,theRangeTableForLoss,ascii,directory,"Range"))
     1309    {res = false;}
     1310 
     1311  if(isIonisation &&
     1312     !StoreTable(part,theInverseRangeTable,ascii,directory,"InverseRange"))
     1313    {res = false;}
     1314 
     1315  if(!StoreTable(part,theLambdaTable,ascii,directory,"Lambda"))
     1316    {res = false;}
     1317
     1318  if(!StoreTable(part,theSubLambdaTable,ascii,directory,"SubLambda"))
     1319    {res = false;}
     1320
     1321  if ( res ) {
     1322    if(0 < verboseLevel) {
     1323      G4cout << "Physics tables are stored for " << particle->GetParticleName()
     1324             << " and process " << GetProcessName()
     1325             << " in the directory <" << directory
     1326             << "> " << G4endl;
     1327    }
     1328  } else {
     1329    G4cout << "Fail to store Physics Tables for "
     1330           << particle->GetParticleName()
     1331           << " and process " << GetProcessName()
     1332           << " in the directory <" << directory
     1333           << "> " << G4endl;
     1334  }
     1335  return res;
     1336}
     1337
     1338//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     1339
     1340G4bool G4VEnergyLossProcess::RetrievePhysicsTable(
     1341       const G4ParticleDefinition* part, const G4String& directory,
     1342       G4bool ascii)
     1343{
     1344  G4bool res = true;
     1345  const G4String particleName = part->GetParticleName();
     1346
     1347  if(1 < verboseLevel) {
     1348    G4cout << "G4VEnergyLossProcess::RetrievePhysicsTable() for "
     1349           << particleName << " and process " << GetProcessName()
     1350           << "; tables_are_built= " << tablesAreBuilt
    11091351           << G4endl;
    1110     PrintInfo();
    1111     if(theRangeTableForLoss && isIonisation)
    1112       G4cout << "      Step function: finalRange(mm)= " << finalRange/mm
    1113              << ", dRoverRange= " << dRoverRange
    1114              << ", integral: " << integral
    1115              << ", fluct: " << lossFluctuationFlag
    1116              << G4endl;
    1117    
    1118     if(theCSDARangeTable && isIonisation)
    1119       G4cout << "      CSDA range table up"
    1120              << " to " << G4BestUnit(maxKinEnergyCSDA,"Energy")
    1121              << " in " << nBinsCSDA << " bins." << G4endl;
    1122    
    1123     if(nSCoffRegions>0)
    1124       G4cout << "      Subcutoff sampling in " << nSCoffRegions
    1125              << " regions" << G4endl;
    1126 
    1127     if(2 < verboseLevel) {
    1128       G4cout << "DEDXTable address= " << theDEDXTable << G4endl;
    1129       if(theDEDXTable && isIonisation) G4cout << (*theDEDXTable) << G4endl;
    1130       G4cout << "non restricted DEDXTable address= "
    1131              << theDEDXunRestrictedTable << G4endl;
    1132       if(theDEDXunRestrictedTable && isIonisation)
    1133            G4cout << (*theDEDXunRestrictedTable) << G4endl;
    1134       if(theDEDXSubTable && isIonisation) G4cout << (*theDEDXSubTable)
    1135                                                  << G4endl;
    1136       G4cout << "CSDARangeTable address= " << theCSDARangeTable
     1352  }
     1353  if(particle == part) {
     1354
     1355    //    G4bool yes = true;
     1356    if ( !baseParticle ) {
     1357
     1358      G4bool fpi = true;
     1359      if(!RetrieveTable(part,theDEDXTable,ascii,directory,"DEDX",fpi))
     1360        {fpi = false;}
     1361
     1362      if(!RetrieveTable(part,theIonisationTable,ascii,directory,"Ionisation",false))
     1363        {fpi = false;}
     1364
     1365      if(!RetrieveTable(part,theRangeTableForLoss,ascii,directory,"Range",fpi))
     1366        {res = false;}
     1367
     1368      if(!RetrieveTable(part,theDEDXunRestrictedTable,ascii,directory,"DEDXnr",false))
     1369        {res = false;}
     1370
     1371      if(!RetrieveTable(part,theCSDARangeTable,ascii,directory,"CSDARange",false))
     1372        {res = false;}
     1373
     1374      if(!RetrieveTable(part,theInverseRangeTable,ascii,directory,"InverseRange",fpi))
     1375        {res = false;}
     1376
     1377      if(!RetrieveTable(part,theLambdaTable,ascii,directory,"Lambda",true))
     1378        {res = false;}
     1379
     1380      G4bool yes = false;
     1381      if(nSCoffRegions > 0) {yes = true;}
     1382
     1383      if(!RetrieveTable(part,theDEDXSubTable,ascii,directory,"SubDEDX",yes))
     1384        {res = false;}
     1385
     1386      if(!RetrieveTable(part,theSubLambdaTable,ascii,directory,"SubLambda",yes))
     1387        {res = false;}
     1388
     1389      if(!fpi) yes = false;
     1390      if(!RetrieveTable(part,theIonisationSubTable,ascii,directory,"SubIonisation",yes))
     1391        {res = false;}
     1392    }
     1393  }
     1394
     1395  return res;
     1396}
     1397
     1398//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     1399
     1400G4bool G4VEnergyLossProcess::StoreTable(const G4ParticleDefinition* part,
     1401                                        G4PhysicsTable* aTable, G4bool ascii,
     1402                                        const G4String& directory,
     1403                                        const G4String& tname)
     1404{
     1405  G4bool res = true;
     1406  if ( aTable ) {
     1407    const G4String name = GetPhysicsTableFileName(part,directory,tname,ascii);
     1408    if( !aTable->StorePhysicsTable(name,ascii)) res = false;
     1409  }
     1410  return res;
     1411}
     1412
     1413//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
     1414
     1415G4bool G4VEnergyLossProcess::RetrieveTable(const G4ParticleDefinition* part,
     1416                                           G4PhysicsTable* aTable, G4bool ascii,
     1417                                           const G4String& directory,
     1418                                           const G4String& tname,
     1419                                           G4bool mandatory)
     1420{
     1421  G4bool res = true;
     1422  G4String filename = GetPhysicsTableFileName(part,directory,tname,ascii);
     1423  G4bool yes = aTable->ExistPhysicsTable(filename);
     1424  if(yes) {
     1425    yes = G4PhysicsTableHelper::RetrievePhysicsTable(aTable,filename,ascii);
     1426    if((G4LossTableManager::Instance())->SplineFlag()) {
     1427      size_t n = aTable->length();
     1428      for(size_t i=0; i<n; i++) {(*aTable)[i]->SetSpline(true);}
     1429    }
     1430  }
     1431  if(yes) {
     1432    if (0 < verboseLevel) {
     1433      G4cout << tname << " table for " << part->GetParticleName()
     1434             << " is Retrieved from <" << filename << ">"
    11371435             << G4endl;
    1138       if(theCSDARangeTable && isIonisation) G4cout << (*theCSDARangeTable)
    1139             << G4endl;
    1140       G4cout << "RangeTableForLoss address= " << theRangeTableForLoss
     1436    }
     1437  } else {
     1438    if(mandatory) res = false;
     1439    if(mandatory || 1 < verboseLevel) {
     1440      G4cout << tname << " table for " << part->GetParticleName()
     1441             << " from file <"
     1442             << filename << "> is not Retrieved"
    11411443             << G4endl;
    1142       if(theRangeTableForLoss && isIonisation)
    1143              G4cout << (*theRangeTableForLoss) << G4endl;
    1144       G4cout << "InverseRangeTable address= " << theInverseRangeTable
    1145              << G4endl;
    1146       if(theInverseRangeTable && isIonisation)
    1147              G4cout << (*theInverseRangeTable) << G4endl;
    1148       G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
    1149       if(theLambdaTable && isIonisation) G4cout << (*theLambdaTable) << G4endl;
    1150       G4cout << "SubLambdaTable address= " << theSubLambdaTable << G4endl;
    1151       if(theSubLambdaTable && isIonisation) G4cout << (*theSubLambdaTable)
    1152              << G4endl;
     1444    }
     1445  }
     1446  return res;
     1447}
     1448
     1449//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1450
     1451G4double G4VEnergyLossProcess::GetDEDXDispersion(
     1452                                  const G4MaterialCutsCouple *couple,
     1453                                  const G4DynamicParticle* dp,
     1454                                        G4double length)
     1455{
     1456  DefineMaterial(couple);
     1457  G4double ekin = dp->GetKineticEnergy();
     1458  SelectModel(ekin*massRatio);
     1459  G4double tmax = currentModel->MaxSecondaryKinEnergy(dp);
     1460  tmax = std::min(tmax,(*theCuts)[currentMaterialIndex]);
     1461  G4double d = 0.0;
     1462  G4VEmFluctuationModel* fm = currentModel->GetModelOfFluctuations();
     1463  if(fm) d = fm->Dispersion(currentMaterial,dp,tmax,length);
     1464  return d;
     1465}
     1466
     1467//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1468
     1469G4double G4VEnergyLossProcess::CrossSectionPerVolume(
     1470         G4double kineticEnergy, const G4MaterialCutsCouple* couple)
     1471{
     1472  // Cross section per volume is calculated
     1473  DefineMaterial(couple);
     1474  G4double cross = 0.0;
     1475  G4bool b;
     1476  if(theLambdaTable) {
     1477    cross =
     1478      ((*theLambdaTable)[currentMaterialIndex])->GetValue(kineticEnergy, b);
     1479  } else {
     1480    SelectModel(kineticEnergy);
     1481    cross =
     1482      currentModel->CrossSectionPerVolume(currentMaterial,
     1483                                          particle, kineticEnergy,
     1484                                          (*theCuts)[currentMaterialIndex]);
     1485  }
     1486
     1487  return cross;
     1488}
     1489
     1490//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1491
     1492G4double G4VEnergyLossProcess::MeanFreePath(const G4Track& track)
     1493{
     1494  DefineMaterial(track.GetMaterialCutsCouple());
     1495  preStepLambda = GetLambdaForScaledEnergy(track.GetKineticEnergy()*massRatio);
     1496  G4double x = DBL_MAX;
     1497  if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda;
     1498  return x;
     1499}
     1500
     1501//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1502
     1503G4double G4VEnergyLossProcess::ContinuousStepLimit(const G4Track& track,
     1504                                                   G4double x, G4double y,
     1505                                                   G4double& z)
     1506{
     1507  G4GPILSelection sel;
     1508  return AlongStepGetPhysicalInteractionLength(track, x, y, z, &sel);
     1509}
     1510
     1511//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1512
     1513G4double G4VEnergyLossProcess::GetMeanFreePath(
     1514                             const G4Track& track,
     1515                             G4double,
     1516                             G4ForceCondition* condition)
     1517
     1518{
     1519  *condition = NotForced;
     1520  return MeanFreePath(track);
     1521}
     1522
     1523//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1524
     1525G4double G4VEnergyLossProcess::GetContinuousStepLimit(
     1526                const G4Track&,
     1527                G4double, G4double, G4double&)
     1528{
     1529  return DBL_MAX;
     1530}
     1531
     1532//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1533
     1534G4PhysicsVector* G4VEnergyLossProcess::LambdaPhysicsVector(
     1535                 const G4MaterialCutsCouple* couple, G4double cut)
     1536{
     1537  //  G4double cut  = (*theCuts)[couple->GetIndex()];
     1538  //  G4int nbins = nLambdaBins;
     1539  G4double tmin =
     1540    std::max(MinPrimaryEnergy(particle, couple->GetMaterial(), cut),
     1541             minKinEnergy);
     1542  if(tmin >= maxKinEnergy) tmin = 0.5*maxKinEnergy;
     1543  G4PhysicsVector* v = new G4PhysicsLogVector(tmin, maxKinEnergy, nBins);
     1544  v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
     1545
     1546  return v;
     1547}
     1548
     1549//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     1550 
     1551void G4VEnergyLossProcess::AddCollaborativeProcess(
     1552            G4VEnergyLossProcess* p)
     1553{
     1554  G4bool add = true;
     1555  if(p->GetProcessName() != "eBrem") add = false;
     1556  if(add && nProcesses > 0) {
     1557    for(G4int i=0; i<nProcesses; i++) {
     1558      if(p == scProcesses[i]) {
     1559        add = false;
     1560        break;
     1561      }
     1562    }
     1563  }
     1564  if(add) {
     1565    scProcesses.push_back(p);
     1566    nProcesses++;
     1567    if (1 < verboseLevel) {
     1568      G4cout << "### The process " << p->GetProcessName()
     1569             << " is added to the list of collaborative processes of "
     1570             << GetProcessName() << G4endl;
    11531571    }
    11541572  }
     
    11821600  } else if(fSubRestricted == tType) {   
    11831601    theDEDXSubTable = p;
    1184   } else if(fIonisation == tType && theIonisationTable != p) {   
     1602  } else if(fIsIonisation == tType && theIonisationTable != p) {   
    11851603    if(theIonisationTable) theIonisationTable->clearAndDestroy();
    11861604    theIonisationTable = p;
    1187   } else if(fSubIonisation == tType && theIonisationSubTable != p) {   
     1605  } else if(fIsSubIonisation == tType && theIonisationSubTable != p) {   
    11881606    if(theIonisationSubTable) theIonisationSubTable->clearAndDestroy();
    11891607    theIonisationSubTable = p;
     
    13191737//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    13201738
    1321 G4PhysicsVector* G4VEnergyLossProcess::LambdaPhysicsVector(
    1322                  const G4MaterialCutsCouple* couple, G4double cut)
    1323 {
    1324   //  G4double cut  = (*theCuts)[couple->GetIndex()];
    1325   //  G4int nbins = nLambdaBins;
    1326   G4double tmin =
    1327     std::max(MinPrimaryEnergy(particle, couple->GetMaterial(), cut),
    1328              minKinEnergy);
    1329   if(tmin >= maxKinEnergy) tmin = 0.5*maxKinEnergy;
    1330   G4PhysicsVector* v = new G4PhysicsLogVector(tmin, maxKinEnergy, nBins);
    1331   return v;
    1332 }
    1333 
    1334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1335 
    1336 G4double G4VEnergyLossProcess::MicroscopicCrossSection(
    1337          G4double kineticEnergy, const G4MaterialCutsCouple* couple)
    1338 {
    1339   // Cross section per atom is calculated
    1340   DefineMaterial(couple);
    1341   G4double cross = 0.0;
    1342   G4bool b;
    1343   if(theLambdaTable)
    1344     cross =
    1345       ((*theLambdaTable)[currentMaterialIndex])->GetValue(kineticEnergy, b)/
    1346       currentMaterial->GetTotNbOfAtomsPerVolume();
    1347 
    1348   return cross;
    1349 }
    1350 
    1351 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1352 
    1353 G4bool G4VEnergyLossProcess::StorePhysicsTable(
    1354        const G4ParticleDefinition* part, const G4String& directory,
    1355        G4bool ascii)
    1356 {
    1357   G4bool res = true;
    1358   if ( baseParticle || part != particle ) return res;
    1359 
    1360   if ( theDEDXTable ) {
    1361     const G4String name = GetPhysicsTableFileName(part,directory,"DEDX",ascii);
    1362     if( !theDEDXTable->StorePhysicsTable(name,ascii)) res = false;
    1363   }
    1364 
    1365   if ( theDEDXunRestrictedTable ) {
    1366     const G4String name =
    1367       GetPhysicsTableFileName(part,directory,"DEDXnr",ascii);
    1368     if( !theDEDXTable->StorePhysicsTable(name,ascii)) res = false;
    1369   }
    1370 
    1371   if ( theDEDXSubTable ) {
    1372     const G4String name =
    1373       GetPhysicsTableFileName(part,directory,"SubDEDX",ascii);
    1374     if( !theDEDXSubTable->StorePhysicsTable(name,ascii)) res = false;
    1375   }
    1376 
    1377   if ( theIonisationTable ) {
    1378     const G4String name =
    1379       GetPhysicsTableFileName(part,directory,"Ionisation",ascii);
    1380     if( !theIonisationTable->StorePhysicsTable(name,ascii)) res = false;
    1381   }
    1382 
    1383   if ( theIonisationSubTable ) {
    1384     const G4String name =
    1385       GetPhysicsTableFileName(part,directory,"SubIonisation",ascii);
    1386     if( !theIonisationSubTable->StorePhysicsTable(name,ascii)) res = false;
    1387   }
    1388 
    1389   if ( theCSDARangeTable && isIonisation ) {
    1390     const G4String name =
    1391       GetPhysicsTableFileName(part,directory,"CSDARange",ascii);
    1392     if( !theCSDARangeTable->StorePhysicsTable(name,ascii)) res = false;
    1393   }
    1394 
    1395   if ( theRangeTableForLoss && isIonisation ) {
    1396     const G4String name =
    1397       GetPhysicsTableFileName(part,directory,"Range",ascii);
    1398     if( !theRangeTableForLoss->StorePhysicsTable(name,ascii)) res = false;
    1399   }
    1400 
    1401   if ( theInverseRangeTable && isIonisation ) {
    1402     const G4String name =
    1403       GetPhysicsTableFileName(part,directory,"InverseRange",ascii);
    1404     if( !theInverseRangeTable->StorePhysicsTable(name,ascii)) res = false;
    1405   }
    1406 
    1407   if ( theLambdaTable  && isIonisation) {
    1408     const G4String name =
    1409       GetPhysicsTableFileName(part,directory,"Lambda",ascii);
    1410     if( !theLambdaTable->StorePhysicsTable(name,ascii)) res = false;
    1411   }
    1412 
    1413   if ( theSubLambdaTable  && isIonisation) {
    1414     const G4String name =
    1415       GetPhysicsTableFileName(part,directory,"SubLambda",ascii);
    1416     if( !theSubLambdaTable->StorePhysicsTable(name,ascii)) res = false;
    1417   }
    1418   if ( res ) {
    1419     if(0 < verboseLevel) {
    1420       G4cout << "Physics tables are stored for " << particle->GetParticleName()
    1421              << " and process " << GetProcessName()
    1422              << " in the directory <" << directory
    1423              << "> " << G4endl;
    1424     }
    1425   } else {
    1426     G4cout << "Fail to store Physics Tables for "
    1427            << particle->GetParticleName()
    1428            << " and process " << GetProcessName()
    1429            << " in the directory <" << directory
    1430            << "> " << G4endl;
    1431   }
    1432   return res;
    1433 }
    1434 
    1435 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
    1436 
    1437 G4bool G4VEnergyLossProcess::RetrievePhysicsTable(
    1438        const G4ParticleDefinition* part, const G4String& directory,
    1439        G4bool ascii)
    1440 {
    1441   G4bool res = true;
    1442   const G4String particleName = part->GetParticleName();
    1443 
    1444   if(1 < verboseLevel) {
    1445     G4cout << "G4VEnergyLossProcess::RetrievePhysicsTable() for "
    1446            << particleName << " and process " << GetProcessName()
    1447            << "; tables_are_built= " << tablesAreBuilt
    1448            << G4endl;
    1449   }
    1450   if(particle == part) {
    1451 
    1452     G4bool yes = true;
    1453     G4bool fpi = true;
    1454     if ( !baseParticle ) {
    1455       G4String filename;
    1456 
    1457       filename = GetPhysicsTableFileName(part,directory,"DEDX",ascii);
    1458       yes = theDEDXTable->ExistPhysicsTable(filename);
    1459       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1460                     theDEDXTable,filename,ascii);
    1461       if(yes) {
    1462         if (0 < verboseLevel) {
    1463           G4cout << "DEDX table for " << particleName
    1464                  << " is Retrieved from <"
    1465                  << filename << ">"
    1466                  << G4endl;
    1467         }
    1468       } else {
    1469         fpi = false;
    1470         if (1 < verboseLevel) {
    1471           G4cout << "DEDX table for " << particleName << " from file <"
    1472                  << filename << "> is not Retrieved"
    1473                  << G4endl;
    1474         }
    1475       }
    1476 
    1477       filename = GetPhysicsTableFileName(part,directory,"Range",ascii);
    1478       yes = theRangeTableForLoss->ExistPhysicsTable(filename);
    1479       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1480                     theRangeTableForLoss,filename,ascii);
    1481       if(yes) {
    1482         if (0 < verboseLevel) {
    1483           G4cout << "Range table for loss for " << particleName
    1484                  << " is Retrieved from <"
    1485                  << filename << ">"
    1486                  << G4endl;
    1487         }
    1488       } else {
    1489         if(fpi) {
    1490           res = false;
    1491           G4cout << "Range table for loss for " << particleName
    1492                  << " from file <"
    1493                  << filename << "> is not Retrieved"
    1494                  << G4endl;
    1495         }
    1496       }
    1497 
    1498       filename = GetPhysicsTableFileName(part,directory,"DEDXnr",ascii);
    1499       yes = theDEDXunRestrictedTable->ExistPhysicsTable(filename);
    1500       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1501                     theDEDXunRestrictedTable,filename,ascii);
    1502       if(yes) {
    1503         if (0 < verboseLevel) {
    1504           G4cout << "Non-restricted DEDX table for " << particleName
    1505                  << " is Retrieved from <"
    1506                  << filename << ">"
    1507                  << G4endl;
    1508         }
    1509       } else {
    1510         if (1 < verboseLevel) {
    1511           G4cout << "Non-restricted DEDX table for " << particleName
    1512                  << " from file <"
    1513                  << filename << "> is not Retrieved"
    1514                  << G4endl;
    1515         }
    1516       }
    1517 
    1518       filename = GetPhysicsTableFileName(part,directory,"CSDARange",ascii);
    1519       yes = theCSDARangeTable->ExistPhysicsTable(filename);
    1520       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1521                     theCSDARangeTable,filename,ascii);
    1522       if(yes) {
    1523         if (0 < verboseLevel) {
    1524           G4cout << "CSDA Range table for " << particleName
    1525                  << " is Retrieved from <"
    1526                  << filename << ">"
    1527                  << G4endl;
    1528         }
    1529       } else {
    1530         G4cout << "CSDA Range table for loss for " << particleName
    1531                << " does not exist"
    1532                << G4endl;
    1533       }
    1534 
    1535       filename = GetPhysicsTableFileName(part,directory,"InverseRange",ascii);
    1536       yes = theInverseRangeTable->ExistPhysicsTable(filename);
    1537       if(yes)  yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1538                      theInverseRangeTable,filename,ascii);
    1539       if(yes) {
    1540         if (0 < verboseLevel) {
    1541           G4cout << "InverseRange table for " << particleName
    1542                  << " is Retrieved from <"
    1543                  << filename << ">"
    1544                  << G4endl;
    1545         }
    1546       } else {
    1547         if(fpi) {
    1548           res = false;
    1549           G4cout << "InverseRange table for " << particleName
    1550                  << " from file <"
    1551                  << filename << "> is not Retrieved"
    1552                  << G4endl;
    1553 
    1554         }
    1555       }
    1556 
    1557       filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
    1558       yes = theLambdaTable->ExistPhysicsTable(filename);
    1559       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1560                     theLambdaTable,filename,ascii);
    1561       if(yes) {
    1562         if (0 < verboseLevel) {
    1563           G4cout << "Lambda table for " << particleName
    1564                  << " is Retrieved from <"
    1565                  << filename << ">"
    1566                  << G4endl;
    1567         }
    1568       } else {
    1569         if(fpi) {
    1570           res = false;
    1571           G4cout << "Lambda table for " << particleName << " from file <"
    1572                  << filename << "> is not Retrieved"
    1573                  << G4endl;
    1574         }
    1575       }
    1576 
    1577       filename = GetPhysicsTableFileName(part,directory,"SubDEDX",ascii);
    1578       yes = theDEDXSubTable->ExistPhysicsTable(filename);
    1579       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1580                     theDEDXSubTable,filename,ascii);
    1581       if(yes) {
    1582         if (0 < verboseLevel) {
    1583           G4cout << "SubDEDX table for " << particleName
    1584                  << " is Retrieved from <"
    1585                  << filename << ">"
    1586                  << G4endl;
    1587         }
    1588       } else {
    1589         if(nSCoffRegions) {
    1590           res=false;
    1591           G4cout << "SubDEDX table for " << particleName << " from file <"
    1592                  << filename << "> is not Retrieved"
    1593                  << G4endl;
    1594         }
    1595       }
    1596 
    1597       filename = GetPhysicsTableFileName(part,directory,"SubLambda",ascii);
    1598       yes = theSubLambdaTable->ExistPhysicsTable(filename);
    1599       if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1600                     theSubLambdaTable,filename,ascii);
    1601       if(yes) {
    1602         if (0 < verboseLevel) {
    1603           G4cout << "SubLambda table for " << particleName
    1604                  << " is Retrieved from <"
    1605                  << filename << ">"
    1606                  << G4endl;
    1607         }
    1608       } else {
    1609         if(nSCoffRegions) {
    1610           res=false;
    1611           G4cout << "SubLambda table for " << particleName << " from file <"
    1612                  << filename << "> is not Retrieved"
    1613                  << G4endl;
    1614         }
    1615       }
    1616 
    1617       filename = GetPhysicsTableFileName(part,directory,"Ionisation",ascii);
    1618       yes = theIonisationTable->ExistPhysicsTable(filename);
    1619       if(yes) {
    1620         theIonisationTable =
    1621           G4PhysicsTableHelper::PreparePhysicsTable(theIonisationTable);
    1622        
    1623         yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1624                     theIonisationTable,filename,ascii);
    1625       }
    1626       if(yes) {
    1627         if (0 < verboseLevel) {
    1628           G4cout << "Ionisation table for " << particleName
    1629                  << " is Retrieved from <"
    1630                  << filename << ">"
    1631                  << G4endl;
    1632         }
    1633       }
    1634 
    1635       filename = GetPhysicsTableFileName(part,directory,"SubIonisation",ascii);
    1636       yes = theIonisationSubTable->ExistPhysicsTable(filename);
    1637       if(yes) {
    1638         theIonisationSubTable =
    1639           G4PhysicsTableHelper::PreparePhysicsTable(theIonisationSubTable);
    1640         yes = G4PhysicsTableHelper::RetrievePhysicsTable(
    1641                     theIonisationSubTable,filename,ascii);
    1642       }
    1643       if(yes) {
    1644         if (0 < verboseLevel) {
    1645           G4cout << "SubIonisation table for " << particleName
    1646                  << " is Retrieved from <"
    1647                  << filename << ">"
    1648                  << G4endl;
    1649         }
    1650       }
    1651     }
    1652   }
    1653 
    1654   return res;
    1655 }
    1656 
    1657 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1658  
    1659 void G4VEnergyLossProcess::AddCollaborativeProcess(
    1660             G4VEnergyLossProcess* p)
    1661 {
    1662   G4bool add = true;
    1663   if(nProcesses > 0) {
    1664     for(G4int i=0; i<nProcesses; i++) {
    1665       if(p == scProcesses[i]) {
    1666         add = false;
    1667         break;
    1668       }
    1669     }
    1670   }
    1671   if(add) {
    1672     scProcesses.push_back(p);
    1673     nProcesses++;
    1674     if (0 < verboseLevel)
    1675       G4cout << "### The process " << p->GetProcessName()
    1676              << " is added to the list of collaborative processes of "
    1677              << GetProcessName() << G4endl;
    1678   }
    1679 }
    1680 
    1681 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1682 
    1683 G4double G4VEnergyLossProcess::GetDEDXDispersion(
    1684                                   const G4MaterialCutsCouple *couple,
    1685                                   const G4DynamicParticle* dp,
    1686                                         G4double length)
    1687 {
    1688   DefineMaterial(couple);
    1689   G4double ekin = dp->GetKineticEnergy();
    1690   G4VEmModel* currentModel = SelectModel(ekin*massRatio);
    1691   G4double tmax = currentModel->MaxSecondaryKinEnergy(dp);
    1692   tmax = std::min(tmax,(*theCuts)[currentMaterialIndex]);
    1693   G4double d = 0.0;
    1694   G4VEmFluctuationModel* fm = currentModel->GetModelOfFluctuations();
    1695   if(fm) d = fm->Dispersion(currentMaterial,dp,tmax,length);
    1696   return d;
    1697 }
    1698 
    1699 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1700 
    1701 void G4VEnergyLossProcess::ActivateDeexcitation(G4bool, const G4Region*)
    1702 {}
    1703 
    1704 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    1705 
  • trunk/source/processes/electromagnetic/utils/src/G4VMultipleScattering.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4VMultipleScattering.cc,v 1.47 2007/11/09 11:35:54 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4VMultipleScattering.cc,v 1.60 2008/11/20 20:32:40 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5555// 12-04-07 Add verbosity at destruction (V.Ivanchenko)
    5656// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
     57// 11-03-08 Set skin value does not effect step limit type (V.Ivanchenko)
    5758//
    5859// Class Description:
     
    8586//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    8687
    87 G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType type):
    88                  G4VContinuousDiscreteProcess(name, type),
     88G4VMultipleScattering::G4VMultipleScattering(const G4String& name,
     89                                             G4ProcessType type):
     90  G4VContinuousDiscreteProcess(name, type),
     91  buildLambdaTable(true),
    8992  theLambdaTable(0),
    9093  firstParticle(0),
    91   currentParticle(0),
    92   currentCouple(0),
    93   nBins(120),
    9494  stepLimit(fUseSafety),
    95   skin(0.0),
     95  skin(3.0),
    9696  facrange(0.02),
    9797  facgeom(2.5),
    9898  latDisplasment(true),
    99   buildLambdaTable(true)
    100 {
     99  currentParticle(0),
     100  currentCouple(0)
     101{
     102  SetVerboseLevel(1);
     103  SetProcessSubType(fMultipleScattering);
     104
     105  // Size of tables assuming spline
    101106  minKinEnergy = 0.1*keV;
    102107  maxKinEnergy = 100.0*TeV;
    103   SetVerboseLevel(1);
     108  nBins        = 84;
     109
     110  // default limit on polar angle
     111  polarAngleLimit = 0.0;
    104112
    105113  pParticleChange = &fParticleChange;
     
    114122G4VMultipleScattering::~G4VMultipleScattering()
    115123{
    116   if(1 < verboseLevel)
     124  if(1 < verboseLevel) {
    117125    G4cout << "G4VMultipleScattering destruct " << GetProcessName()
    118126           << G4endl;
     127  }
    119128  delete modelManager;
    120129  if (theLambdaTable) {
     
    131140  G4String num = part.GetParticleName();
    132141  if(1 < verboseLevel) {
    133     //    G4cout << "========================================================" << G4endl;
    134142    G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for "
    135143           << GetProcessName()
     
    148156      if (theLambdaTable->GetFlag(i)) {
    149157        // create physics vector and fill it
    150         const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
     158        const G4MaterialCutsCouple* couple =
     159          theCoupleTable->GetMaterialCutsCouple(i);
    151160        G4PhysicsVector* aVector = PhysicsVector(couple);
    152161        modelManager->FillLambdaVector(aVector, couple, false);
     
    162171  }
    163172  if(verboseLevel>0 && ( num == "e-" || num == "mu+" || 
    164                          num == "proton" || num == "pi-" || num == "GenericIon")) {
     173                         num == "proton" || num == "pi-" ||
     174                         num == "GenericIon")) {
    165175    PrintInfoDefinition();
    166176    if(2 < verboseLevel && theLambdaTable) G4cout << *theLambdaTable << G4endl;
     
    182192    currentCouple = 0;
    183193    if(part.GetParticleType() == "nucleus" &&
    184        part.GetParticleSubType() == "generic")
    185          firstParticle = G4GenericIon::GenericIon();
    186     else firstParticle = &part;
     194       part.GetParticleSubType() == "generic") {
     195      firstParticle = G4GenericIon::GenericIon();
     196    } else {
     197      firstParticle = &part;
     198    }
     199
    187200    currentParticle = &part;
    188201  }
    189202
    190203  if(1 < verboseLevel) {
    191     //    G4cout << "========================================================" << G4endl;
    192204    G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
    193205           << GetProcessName()
     
    217229{
    218230  if (0 < verboseLevel) {
    219     G4cout << G4endl << GetProcessName() << ":  Model variant of multiple scattering "
    220            << "for " << firstParticle->GetParticleName()
     231    G4cout << G4endl << GetProcessName()
     232           << ":   for " << firstParticle->GetParticleName()
     233           << "    SubType= " << GetProcessSubType()
    221234           << G4endl;
    222235    if (theLambdaTable) {
     
    225238             << " to "
    226239             << G4BestUnit(MaxKinEnergy(),"Energy")
    227              << " in " << nBins << " bins."
     240             << " in " << nBins << " bins, spline: "
     241             << (G4LossTableManager::Instance())->SplineFlag()
    228242             << G4endl;
    229243    }
    230     G4cout << "      LateralDisplacementFlag=  " << latDisplasment
    231            << "   Skin= " << skin << G4endl;
    232244    PrintInfo();
     245    modelManager->DumpModelList(verboseLevel);
    233246    if (2 < verboseLevel) {
    234247      G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
     
    242255G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength(
    243256                             const G4Track& track,
    244                              G4double previousStepSize,
     257                             G4double,
    245258                             G4double currentMinimalStep,
    246259                             G4double& currentSafety,
     
    249262  // get Step limit proposed by the process
    250263  valueGPILSelectionMSC = NotCandidateForSelection;
    251   G4double steplength = GetMscContinuousStepLimit(track,previousStepSize,
    252                                               currentMinimalStep,currentSafety);
     264  G4double steplength = GetMscContinuousStepLimit(track,
     265                                                  track.GetKineticEnergy(),
     266                                                  currentMinimalStep,
     267                                                  currentSafety);
    253268  // G4cout << "StepLimit= " << steplength << G4endl;
    254269  // set return value for G4GPILSelection
     
    315330  if( couple->IsUsed() ) nbins = nBins;
    316331  G4PhysicsVector* v = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nbins);
     332  v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
    317333  return v;
    318334}
     
    372388               << G4endl;
    373389    }
     390    if((G4LossTableManager::Instance())->SplineFlag()) {
     391      size_t n = theLambdaTable->length();
     392      for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);}
     393    }
    374394  } else {
    375395    if (1 < verboseLevel) {
  • trunk/source/processes/electromagnetic/utils/src/G4ionEffectiveCharge.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4ionEffectiveCharge.cc,v 1.17.2.1 2008/04/22 15:28:13 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4ionEffectiveCharge.cc,v 1.24 2008/12/18 13:01:46 gunter Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    5454#include "G4ionEffectiveCharge.hh"
    5555#include "G4UnitsTable.hh"
    56 #include "G4ParticleDefinition.hh"
    5756#include "G4Material.hh"
     57#include "G4NistManager.hh"
    5858
    5959//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    6262{
    6363  chargeCorrection = 1.0;
    64   energyHighLimit  = 10.0*MeV;
     64  energyHighLimit  = 20.0*MeV;
    6565  energyLowLimit   = 1.0*keV;
    6666  energyBohr       = 25.*keV;
    6767  massFactor       = amu_c2/(proton_mass_c2*keV);
    68   minCharge        = 0.1;
     68  minCharge        = 1.0;
     69  lastPart         = 0;
     70  lastMat          = 0;
     71  lastKinEnergy    = 0.0;
     72  effCharge        = eplus;
     73  nist = G4NistManager::Instance();
    6974}
    7075
     
    7883G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p,
    7984                                               const G4Material* material,
    80                                                      G4double kineticEnergy)
     85                                               G4double kineticEnergy)
    8186{
     87  if(p == lastPart && material == lastMat && kineticEnergy == lastKinEnergy)
     88    return effCharge;
     89
     90  lastPart      = p;
     91  lastMat       = material;
     92  lastKinEnergy = kineticEnergy;
     93
    8294  G4double mass   = p->GetPDGMass();
    8395  G4double charge = p->GetPDGCharge();
     
    8597
    8698  chargeCorrection = 1.0;
     99  effCharge = charge;
    87100
    88101  // The aproximation of ion effective charge from:
     
    94107  if( reducedEnergy > Zi*energyHighLimit || Zi < 1.5 || !material) return charge;
    95108
    96   static G4double c[6] = {0.2865,  0.1266, -0.001429,
    97                           0.02402,-0.01135, 0.001475} ;
    98 
    99109  G4double z    = material->GetIonisation()->GetZeffective();
    100   reducedEnergy = std::max(reducedEnergy,energyLowLimit);
    101   G4double q;
     110  //  reducedEnergy = std::max(reducedEnergy,energyLowLimit);
    102111
    103112  // Helium ion case
    104113  if( Zi < 2.5 ) {
     114
     115    static G4double c[6] = {0.2865,  0.1266, -0.001429,
     116                            0.02402,-0.01135, 0.001475} ;
    105117
    106118    G4double Q = std::max(0.0,std::log(reducedEnergy*massFactor));
     
    120132    if(tq2 < 0.2) tt *= (1.0 - tq2 + 0.5*tq2*tq2);
    121133    else          tt *= std::exp(-tq2);
    122     q = (1.0 + tt) * std::sqrt(ex);
     134
     135    effCharge = charge*(1.0 + tt) * std::sqrt(ex);
    123136
    124137    // Heavy ion case
    125138  } else {
    126139   
    127     G4double z23  = std::pow(z, 0.666666);
    128     G4double zi13 = std::pow(Zi, 0.333333);
     140    G4double y;
     141    //    = nist->GetZ13(z);
     142    //G4double z23  = y*y;
     143    G4double zi13 = nist->GetZ13(Zi);
    129144    G4double zi23 = zi13*zi13;
    130     G4double e = std::max(reducedEnergy,energyBohr/z23);
     145    //    G4double e = std::max(reducedEnergy,energyBohr/z23);
     146    //G4double e = reducedEnergy;
    131147
    132148    // v1 is ion velocity in vF unit
    133149    G4double eF   = material->GetIonisation()->GetFermiEnergy();
    134     G4double v1sq = e/eF;
     150    G4double v1sq = reducedEnergy/eF;
    135151    G4double vFsq = eF/energyBohr;
    136     G4double vF   = std::sqrt(vFsq);
    137 
    138     G4double y ;
     152    G4double vF   = std::sqrt(eF/energyBohr);
    139153
    140154    // Faster than Fermi velocity
     
    147161    }
    148162
     163    G4double q;
    149164    G4double y3 = std::pow(y, 0.3) ;
    150     //    G4cout << "y= " << y << " y3= " << y3 << " v1= " << v1 << " vF= " << vF << G4endl;
     165    // G4cout<<"y= "<<y<<" y3= "<<y3<<" v1= "<<v1<<" vF= "<<vF<<G4endl;
    151166    q = 1.0 - std::exp( 0.803*y3 - 1.3167*y3*y3 - 0.38157*y - 0.008983*y*y ) ;
    152 
    153     //    q = 1.0 - std::exp(-0.95*std::sqrt(reducedEnergy/energyBohr)/zi23);
     167   
     168    //y *= 0.77;
     169    //y *= (0.75 + 0.52/Zi);
     170
     171    //if( y < 0.2 ) q = y*(1.0 - 0.5*y);
     172    //else          q = 1.0 - std::exp(-y);
    154173
    155174    G4double qmin = minCharge/Zi;
    156 
    157175    if(q < qmin) q = qmin;
     176 
     177    effCharge = q*charge;
     178
     179    /*
     180    G4double x1 = 1.0*effCharge*(1.0 - 0.132*std::log(y))/(y*std::sqrt(z));
     181    G4double x2 = 0.1*effCharge*effCharge*energyBohr/reducedEnergy;
     182
     183    chargeCorrection = 1.0 + x1 - x2;
     184
     185    G4cout << "x1= "<<x1<<" x2= "<< x2<<" corr= "<<chargeCorrection<<G4endl;
     186    */
    158187   
    159188    G4double tq = 7.6 - std::log(reducedEnergy/keV);
     
    170199
    171200    G4double lambda = 10.0 * vF / (zi13 * (6.0 + q));
    172     if(q < 0.2) lambda *= (1.0 - 0.666666*q - q*q/9.0);
     201    if(q < 0.2) lambda *= (1.0 - 0.66666667*q - q*q/9.0);
    173202    else        lambda *= std::pow(1.0-q, 0.666666);
    174203
     
    180209
    181210    chargeCorrection = sq * (1.0 + xx);
     211   
    182212  }
    183213  //  G4cout << "G4ionEffectiveCharge: charge= " << charge << " q= " << q
    184214  //         << " chargeCor= " << chargeCorrection
    185215  //       << " e(MeV)= " << kineticEnergy/MeV << G4endl;
    186   return q*charge;
     216  return effCharge;
    187217}
    188218
Note: See TracChangeset for help on using the changeset viewer.