Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4PenelopeComptonModel.cc

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

Diff markup

Differences between /processes/electromagnetic/lowenergy/src/G4PenelopeComptonModel.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4PenelopeComptonModel.cc (Version 10.0.p2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
                                                   >>  26 // $Id: G4PenelopeComptonModel.cc 75180 2013-10-29 10:11:24Z gcosmo $
 26 //                                                 27 //
 27 // Author: Luciano Pandola                         28 // Author: Luciano Pandola
 28 //                                                 29 //
 29 // History:                                        30 // History:
 30 // --------                                        31 // --------
 31 // 15 Feb 2010   L Pandola  Implementation         32 // 15 Feb 2010   L Pandola  Implementation
 32 // 18 Mar 2010   L Pandola  Removed GetAtomsPe <<  33 // 18 Mar 2010   L Pandola  Removed GetAtomsPerMolecule(), now demanded 
 33 //                            to G4PenelopeOsc     34 //                            to G4PenelopeOscillatorManager
 34 // 01 Feb 2011   L Pandola  Suppress fake ener <<  35 // 01 Feb 2011   L Pandola  Suppress fake energy-violation warning when Auger is active.
 35 //                            active.          <<  36 //                          Make sure that fluorescence/Auger is generated only if 
 36 //                          Make sure that flu <<  37 //                          above threshold
 37 //                            if above thresho << 
 38 // 24 May 2011   L Pandola  Renamed (make v200     38 // 24 May 2011   L Pandola  Renamed (make v2008 as default Penelope)
 39 // 10 Jun 2011   L Pandola  Migrate atomic dee     39 // 10 Jun 2011   L Pandola  Migrate atomic deexcitation interface
 40 // 09 Oct 2013   L Pandola  Migration to MT        40 // 09 Oct 2013   L Pandola  Migration to MT
 41 // 25 Jul 2023   D Iuso     Fix for possible i << 
 42 //                                                 41 //
 43 #include "G4PenelopeComptonModel.hh"               42 #include "G4PenelopeComptonModel.hh"
 44 #include "G4PhysicalConstants.hh"                  43 #include "G4PhysicalConstants.hh"
 45 #include "G4SystemOfUnits.hh"                      44 #include "G4SystemOfUnits.hh"
 46 #include "G4ParticleDefinition.hh"                 45 #include "G4ParticleDefinition.hh"
 47 #include "G4MaterialCutsCouple.hh"                 46 #include "G4MaterialCutsCouple.hh"
 48 #include "G4DynamicParticle.hh"                    47 #include "G4DynamicParticle.hh"
 49 #include "G4VEMDataSet.hh"                         48 #include "G4VEMDataSet.hh"
 50 #include "G4PhysicsTable.hh"                       49 #include "G4PhysicsTable.hh"
 51 #include "G4PhysicsLogVector.hh"                   50 #include "G4PhysicsLogVector.hh"
 52 #include "G4AtomicTransitionManager.hh"            51 #include "G4AtomicTransitionManager.hh"
 53 #include "G4AtomicShell.hh"                        52 #include "G4AtomicShell.hh"
 54 #include "G4Gamma.hh"                              53 #include "G4Gamma.hh"
 55 #include "G4Electron.hh"                           54 #include "G4Electron.hh"
 56 #include "G4PenelopeOscillatorManager.hh"          55 #include "G4PenelopeOscillatorManager.hh"
 57 #include "G4PenelopeOscillator.hh"                 56 #include "G4PenelopeOscillator.hh"
 58 #include "G4LossTableManager.hh"                   57 #include "G4LossTableManager.hh"
 59 #include "G4Exp.hh"                            << 
 60                                                    58 
 61 //....oooOO0OOooo........oooOO0OOooo........oo     59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 62                                                    60 
                                                   >>  61 
 63 G4PenelopeComptonModel::G4PenelopeComptonModel     62 G4PenelopeComptonModel::G4PenelopeComptonModel(const G4ParticleDefinition* part,
 64                  const G4String& nam)              63                  const G4String& nam)
 65   :G4VEmModel(nam),fParticleChange(nullptr),fP <<  64   :G4VEmModel(nam),fParticleChange(0),fParticle(0),
 66    fAtomDeexcitation(nullptr),                 <<  65    isInitialised(false),fAtomDeexcitation(0),
 67    fOscManager(nullptr),fIsInitialised(false)  <<  66    oscManager(0)
 68 {                                                  67 {
 69   fIntrinsicLowEnergyLimit = 100.0*eV;             68   fIntrinsicLowEnergyLimit = 100.0*eV;
 70   fIntrinsicHighEnergyLimit = 100.0*GeV;           69   fIntrinsicHighEnergyLimit = 100.0*GeV;
                                                   >>  70   //  SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
 71   SetHighEnergyLimit(fIntrinsicHighEnergyLimit     71   SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
 72   //                                               72   //
 73   fOscManager = G4PenelopeOscillatorManager::G <<  73   oscManager = G4PenelopeOscillatorManager::GetOscillatorManager();
 74                                                    74 
 75   if (part)                                        75   if (part)
 76     SetParticle(part);                             76     SetParticle(part);
 77                                                <<  77  
 78   fVerboseLevel= 0;                            <<  78   verboseLevel= 0;
 79   // Verbosity scale:                              79   // Verbosity scale:
 80   // 0 = nothing                               <<  80   // 0 = nothing 
 81   // 1 = warning for energy non-conservation   <<  81   // 1 = warning for energy non-conservation 
 82   // 2 = details of energy budget                  82   // 2 = details of energy budget
 83   // 3 = calculation of cross sections, file o     83   // 3 = calculation of cross sections, file openings, sampling of atoms
 84   // 4 = entering in methods                       84   // 4 = entering in methods
 85                                                    85 
 86   //Mark this model as "applicable" for atomic     86   //Mark this model as "applicable" for atomic deexcitation
 87   SetDeexcitationFlag(true);                       87   SetDeexcitationFlag(true);
 88                                                    88 
 89   fTransitionManager = G4AtomicTransitionManag     89   fTransitionManager = G4AtomicTransitionManager::Instance();
 90 }                                                  90 }
 91                                                    91 
 92 //....oooOO0OOooo........oooOO0OOooo........oo     92 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 93                                                    93 
 94 G4PenelopeComptonModel::~G4PenelopeComptonMode     94 G4PenelopeComptonModel::~G4PenelopeComptonModel()
 95 {;}                                                95 {;}
 96                                                    96 
 97 //....oooOO0OOooo........oooOO0OOooo........oo     97 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 98                                                    98 
 99 void G4PenelopeComptonModel::Initialise(const      99 void G4PenelopeComptonModel::Initialise(const G4ParticleDefinition* part,
100             const G4DataVector&)                  100             const G4DataVector&)
101 {                                                 101 {
102   if (fVerboseLevel > 3)                       << 102   if (verboseLevel > 3)
103     G4cout << "Calling G4PenelopeComptonModel:    103     G4cout << "Calling G4PenelopeComptonModel::Initialise()" << G4endl;
104                                                   104 
105   fAtomDeexcitation = G4LossTableManager::Inst    105   fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
106   //Issue warning if the AtomicDeexcitation ha    106   //Issue warning if the AtomicDeexcitation has not been declared
107   if (!fAtomDeexcitation)                         107   if (!fAtomDeexcitation)
108     {                                             108     {
109       G4cout << G4endl;                           109       G4cout << G4endl;
110       G4cout << "WARNING from G4PenelopeCompto    110       G4cout << "WARNING from G4PenelopeComptonModel " << G4endl;
111       G4cout << "Atomic de-excitation module i    111       G4cout << "Atomic de-excitation module is not instantiated, so there will not be ";
112       G4cout << "any fluorescence/Auger emissi    112       G4cout << "any fluorescence/Auger emission." << G4endl;
113       G4cout << "Please make sure this is inte    113       G4cout << "Please make sure this is intended" << G4endl;
114     }                                             114     }
115                                                   115 
116   SetParticle(part);                              116   SetParticle(part);
117                                                   117 
118   if (IsMaster() && part == fParticle)         << 118   if (IsMaster() && part == fParticle) 
119     {                                             119     {
120                                                   120 
121       if (fVerboseLevel > 0)                   << 121       if (verboseLevel > 0) 
122   {                                               122   {
123     G4cout << "Penelope Compton model v2008 is    123     G4cout << "Penelope Compton model v2008 is initialized " << G4endl
124      << "Energy range: "                          124      << "Energy range: "
125      << LowEnergyLimit() / keV << " keV - "       125      << LowEnergyLimit() / keV << " keV - "
126      << HighEnergyLimit() / GeV << " GeV";     << 126      << HighEnergyLimit() / GeV << " GeV";  
127   }                                            << 
128       //Issue a warning, if the model is going << 
129       //energy which is outside the validity o << 
130       if (LowEnergyLimit() < fIntrinsicLowEner << 
131   {                                            << 
132     G4ExceptionDescription ed;                 << 
133     ed << "Using the Penelope Compton model ou << 
134        << G4endl;                              << 
135     ed << "-> LowEnergyLimit() in process = "  << 
136     ed << "-> Instrinsic low-energy limit = "  << 
137        << G4endl;                              << 
138     ed << "Result of the simulation have to be << 
139     G4Exception("G4PenelopeComptonModel::Initi << 
140           "em2100",JustWarning,ed);            << 
141   }                                               127   }
142     }                                          << 128     }      
143                                                   129 
144   if(fIsInitialised) return;                   << 130   if(isInitialised) return;
145   fParticleChange = GetParticleChangeForGamma(    131   fParticleChange = GetParticleChangeForGamma();
146   fIsInitialised = true;                       << 132   isInitialised = true; 
147                                                   133 
148 }                                                 134 }
149                                                   135 
150 //....oooOO0OOooo........oooOO0OOooo........oo    136 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
151                                                   137 
152 void G4PenelopeComptonModel::InitialiseLocal(c    138 void G4PenelopeComptonModel::InitialiseLocal(const G4ParticleDefinition* part,
153                                                   139                                                      G4VEmModel *masterModel)
154 {                                                 140 {
155   if (fVerboseLevel > 3)                       << 141   if (verboseLevel > 3)
156     G4cout << "Calling  G4PenelopeComptonModel    142     G4cout << "Calling  G4PenelopeComptonModel::InitialiseLocal()" << G4endl;
                                                   >> 143  
157   //                                              144   //
158   //Check that particle matches: one might hav << 145   //Check that particle matches: one might have multiple master models (e.g. 
159   //for e+ and e-).                               146   //for e+ and e-).
160   //                                              147   //
161   if (part == fParticle)                          148   if (part == fParticle)
162     {                                             149     {
163       //Get the const table pointers from the     150       //Get the const table pointers from the master to the workers
164       const G4PenelopeComptonModel* theModel = << 151       const G4PenelopeComptonModel* theModel = 
165         static_cast<G4PenelopeComptonModel*> (    152         static_cast<G4PenelopeComptonModel*> (masterModel);
166                                                << 153       
167       //Same verbosity for all workers, as the    154       //Same verbosity for all workers, as the master
168       fVerboseLevel = theModel->fVerboseLevel; << 155       verboseLevel = theModel->verboseLevel;
169     }                                             156     }
                                                   >> 157 
170   return;                                         158   return;
171 }                                                 159 }
172                                                   160 
173                                                   161 
174 //....oooOO0OOooo........oooOO0OOooo........oo    162 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
175                                                   163 
176 G4double G4PenelopeComptonModel::CrossSectionP    164 G4double G4PenelopeComptonModel::CrossSectionPerVolume(const G4Material* material,
177                                                   165                                                const G4ParticleDefinition* p,
178                                                   166                                                G4double energy,
179                                                   167                                                G4double,
180                                                   168                                                G4double)
181 {                                                 169 {
182   // Penelope model v2008 to calculate the Com    170   // Penelope model v2008 to calculate the Compton scattering cross section:
183   // D. Brusa et al., Nucl. Instrum. Meth. A 3    171   // D. Brusa et al., Nucl. Instrum. Meth. A 379 (1996) 167
184   //                                           << 172   // 
185   // The cross section for Compton scattering  << 173   // The cross section for Compton scattering is calculated according to the Klein-Nishina 
186   // formula for energy > 5 MeV.                  174   // formula for energy > 5 MeV.
187   // For E < 5 MeV it is used a parametrizatio    175   // For E < 5 MeV it is used a parametrization for the differential cross-section dSigma/dOmega,
188   // which is integrated numerically in cos(th    176   // which is integrated numerically in cos(theta), G4PenelopeComptonModel::DifferentialCrossSection().
189   // The parametrization includes the J(p)     << 177   // The parametrization includes the J(p) 
190   // distribution profiles for the atomic shel << 178   // distribution profiles for the atomic shells, that are tabulated from Hartree-Fock calculations 
191   // from F. Biggs et al., At. Data Nucl. Data    179   // from F. Biggs et al., At. Data Nucl. Data Tables 16 (1975) 201
192   //                                              180   //
193   if (fVerboseLevel > 3)                       << 181   if (verboseLevel > 3)
194     G4cout << "Calling CrossSectionPerVolume()    182     G4cout << "Calling CrossSectionPerVolume() of G4PenelopeComptonModel" << G4endl;
195   SetupForMaterial(p, material, energy);          183   SetupForMaterial(p, material, energy);
196                                                   184 
197   G4double cs = 0;                             << 
198   //Force null cross-section if below the low- << 
199   if (energy < LowEnergyLimit())               << 
200     return cs;                                 << 
201                                                << 
202   //Retrieve the oscillator table for this mat    185   //Retrieve the oscillator table for this material
203   G4PenelopeOscillatorTable* theTable = fOscMa << 186   G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material);
                                                   >> 187 
                                                   >> 188   G4double cs = 0;
204                                                   189 
205   if (energy < 5*MeV) //explicit calculation f    190   if (energy < 5*MeV) //explicit calculation for E < 5 MeV
206     {                                             191     {
207       size_t numberOfOscillators = theTable->s    192       size_t numberOfOscillators = theTable->size();
208       for (size_t i=0;i<numberOfOscillators;i+    193       for (size_t i=0;i<numberOfOscillators;i++)
209   {                                               194   {
210     G4PenelopeOscillator* theOsc = (*theTable)    195     G4PenelopeOscillator* theOsc = (*theTable)[i];
211     //sum contributions coming from each oscil    196     //sum contributions coming from each oscillator
212     cs += OscillatorTotalCrossSection(energy,t    197     cs += OscillatorTotalCrossSection(energy,theOsc);
213   }                                               198   }
214     }                                             199     }
215   else //use Klein-Nishina for E>5 MeV            200   else //use Klein-Nishina for E>5 MeV
216     cs = KleinNishinaCrossSection(energy,mater    201     cs = KleinNishinaCrossSection(energy,material);
217                                                << 202        
218   //cross sections are in units of pi*classic_    203   //cross sections are in units of pi*classic_electr_radius^2
219   cs *= pi*classic_electr_radius*classic_elect    204   cs *= pi*classic_electr_radius*classic_electr_radius;
220                                                   205 
221   //Now, cs is the cross section *per molecule << 206   //Now, cs is the cross section *per molecule*, let's calculate the 
222   //cross section per volume                      207   //cross section per volume
                                                   >> 208 
223   G4double atomDensity = material->GetTotNbOfA    209   G4double atomDensity = material->GetTotNbOfAtomsPerVolume();
224   G4double atPerMol =  fOscManager->GetAtomsPe << 210   G4double atPerMol =  oscManager->GetAtomsPerMolecule(material);
225                                                   211 
226   if (fVerboseLevel > 3)                       << 212   if (verboseLevel > 3)
227     G4cout << "Material " << material->GetName << 213     G4cout << "Material " << material->GetName() << " has " << atPerMol << 
228       "atoms per molecule" << G4endl;             214       "atoms per molecule" << G4endl;
229                                                   215 
230   G4double moleculeDensity = 0.;                  216   G4double moleculeDensity = 0.;
231                                                   217 
232   if (atPerMol)                                   218   if (atPerMol)
233     moleculeDensity = atomDensity/atPerMol;       219     moleculeDensity = atomDensity/atPerMol;
234                                                   220 
235   G4double csvolume = cs*moleculeDensity;         221   G4double csvolume = cs*moleculeDensity;
236                                                << 222   
237   if (fVerboseLevel > 2)                       << 223   if (verboseLevel > 2)
238     G4cout << "Compton mean free path at " <<  << 224     G4cout << "Compton mean free path at " << energy/keV << " keV for material " << 
239             material->GetName() << " = " << (1    225             material->GetName() << " = " << (1./csvolume)/mm << " mm" << G4endl;
240   return csvolume;                                226   return csvolume;
241 }                                                 227 }
242                                                   228 
243 //....oooOO0OOooo........oooOO0OOooo........oo    229 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
244                                                   230 
245 //This is a dummy method. Never inkoved by the    231 //This is a dummy method. Never inkoved by the tracking, it just issues
246 //a warning if one tries to get Cross Sections    232 //a warning if one tries to get Cross Sections per Atom via the
247 //G4EmCalculator.                                 233 //G4EmCalculator.
248 G4double G4PenelopeComptonModel::ComputeCrossS    234 G4double G4PenelopeComptonModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
249                                                   235                                                              G4double,
250                                                   236                                                              G4double,
251                                                   237                                                              G4double,
252                                                   238                                                              G4double,
253                                                   239                                                              G4double)
254 {                                                 240 {
255   G4cout << "*** G4PenelopeComptonModel -- WAR    241   G4cout << "*** G4PenelopeComptonModel -- WARNING ***" << G4endl;
256   G4cout << "Penelope Compton model v2008 does    242   G4cout << "Penelope Compton model v2008 does not calculate cross section _per atom_ " << G4endl;
257   G4cout << "so the result is always zero. For    243   G4cout << "so the result is always zero. For physics values, please invoke " << G4endl;
258   G4cout << "GetCrossSectionPerVolume() or Get    244   G4cout << "GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" << G4endl;
259   return 0;                                       245   return 0;
260 }                                                 246 }
261                                                   247 
262 //....oooOO0OOooo........oooOO0OOooo........oo    248 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
263                                                   249 
264 void G4PenelopeComptonModel::SampleSecondaries    250 void G4PenelopeComptonModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
265                  const G4MaterialCutsCouple* c    251                  const G4MaterialCutsCouple* couple,
266                 const G4DynamicParticle* aDyna    252                 const G4DynamicParticle* aDynamicGamma,
267                 G4double,                         253                 G4double,
268                 G4double)                         254                 G4double)
269 {                                                 255 {
                                                   >> 256   
270   // Penelope model v2008 to sample the Compto    257   // Penelope model v2008 to sample the Compton scattering final state.
271   // D. Brusa et al., Nucl. Instrum. Meth. A 3    258   // D. Brusa et al., Nucl. Instrum. Meth. A 379 (1996) 167
272   // The model determines also the original sh << 259   // The model determines also the original shell from which the electron is expelled, 
273   // in order to produce fluorescence de-excit    260   // in order to produce fluorescence de-excitation (from G4DeexcitationManager)
274   //                                           << 261   // 
275   // The final state for Compton scattering is << 262   // The final state for Compton scattering is calculated according to the Klein-Nishina 
276   // formula for energy > 5 MeV. In this case, << 263   // formula for energy > 5 MeV. In this case, the Doppler broadening is negligible and 
277   // one can assume that the target electron i    264   // one can assume that the target electron is at rest.
278   // For E < 5 MeV it is used the parametrizat    265   // For E < 5 MeV it is used the parametrization for the differential cross-section dSigma/dOmega,
279   // to sample the scattering angle and the en << 266   // to sample the scattering angle and the energy of the emerging electron, which is  
280   // G4PenelopeComptonModel::DifferentialCross << 267   // G4PenelopeComptonModel::DifferentialCrossSection(). The rejection method is 
281   // used to sample cos(theta). The efficiency << 268   // used to sample cos(theta). The efficiency increases monotonically with photon energy and is 
282   // nearly independent on the Z; typical valu << 269   // nearly independent on the Z; typical values are 35%, 80% and 95% for 1 keV, 1 MeV and 10 MeV, 
283   // respectively.                                270   // respectively.
284   // The parametrization includes the J(p) dis << 271   // The parametrization includes the J(p) distribution profiles for the atomic shells, that are 
285   // tabulated                                 << 272   // tabulated 
286   // from Hartree-Fock calculations from F. Bi << 273   // from Hartree-Fock calculations from F. Biggs et al., At. Data Nucl. Data Tables 16 (1975) 201. 
287   // Doppler broadening is included.              274   // Doppler broadening is included.
288   //                                              275   //
289                                                   276 
290   if (fVerboseLevel > 3)                       << 277   if (verboseLevel > 3)
291     G4cout << "Calling SampleSecondaries() of     278     G4cout << "Calling SampleSecondaries() of G4PenelopeComptonModel" << G4endl;
292                                                << 279   
293   G4double photonEnergy0 = aDynamicGamma->GetK    280   G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy();
294                                                   281 
295   // do nothing below the threshold            << 282   if (photonEnergy0 <= fIntrinsicLowEnergyLimit)
296   // should never get here because the XS is z << 283     {
297   if(photonEnergy0 < LowEnergyLimit())         << 284       fParticleChange->ProposeTrackStatus(fStopAndKill);
298     return;                                    << 285       fParticleChange->SetProposedKineticEnergy(0.);
                                                   >> 286       fParticleChange->ProposeLocalEnergyDeposit(photonEnergy0);
                                                   >> 287       return ;
                                                   >> 288     }
299                                                   289 
300   G4ParticleMomentum photonDirection0 = aDynam    290   G4ParticleMomentum photonDirection0 = aDynamicGamma->GetMomentumDirection();
301   const G4Material* material = couple->GetMate    291   const G4Material* material = couple->GetMaterial();
302                                                   292 
303   G4PenelopeOscillatorTable* theTable = fOscMa << 293   G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material); 
304                                                   294 
305   const G4int nmax = 64;                          295   const G4int nmax = 64;
306   G4double rn[nmax]={0.0};                        296   G4double rn[nmax]={0.0};
307   G4double pac[nmax]={0.0};                       297   G4double pac[nmax]={0.0};
308                                                << 298   
309   G4double S=0.0;                                 299   G4double S=0.0;
310   G4double epsilon = 0.0;                         300   G4double epsilon = 0.0;
311   G4double cosTheta = 1.0;                        301   G4double cosTheta = 1.0;
312   G4double hartreeFunc = 0.0;                     302   G4double hartreeFunc = 0.0;
313   G4double oscStren = 0.0;                        303   G4double oscStren = 0.0;
314   size_t numberOfOscillators = theTable->size(    304   size_t numberOfOscillators = theTable->size();
315   size_t targetOscillator = 0;                    305   size_t targetOscillator = 0;
316   G4double ionEnergy = 0.0*eV;                    306   G4double ionEnergy = 0.0*eV;
317                                                   307 
318   G4double ek = photonEnergy0/electron_mass_c2    308   G4double ek = photonEnergy0/electron_mass_c2;
319   G4double ek2 = 2.*ek+1.0;                       309   G4double ek2 = 2.*ek+1.0;
320   G4double eks = ek*ek;                           310   G4double eks = ek*ek;
321   G4double ek1 = eks-ek2-1.0;                     311   G4double ek1 = eks-ek2-1.0;
322                                                   312 
323   G4double taumin = 1.0/ek2;                      313   G4double taumin = 1.0/ek2;
324   //This is meant to fix a possible (rare) flo << 314   G4double a1 = std::log(ek2);
325   //causing an infinite loop. The maximum of t << 
326   //be represented (i.e. ~ 1. - 1e-16). Fix by << 
327   static G4double taumax = std::nexttoward(1.0 << 
328   if (fVerboseLevel > 3)                       << 
329     G4cout << "G4PenelopeComptonModel: maximum << 
330   //To here.                                   << 
331   G4double a1 = G4Log(ek2);                    << 
332   G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);     315   G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
333                                                   316 
334   G4double TST = 0;                               317   G4double TST = 0;
335   G4double tau = 0.;                              318   G4double tau = 0.;
336                                                << 319  
337   //If the incoming photon is above 5 MeV, the << 320   //If the incoming photon is above 5 MeV, the quicker approach based on the 
338   //pure Klein-Nishina formula is used            321   //pure Klein-Nishina formula is used
339   if (photonEnergy0 > 5*MeV)                      322   if (photonEnergy0 > 5*MeV)
340     {                                             323     {
341       do{                                         324       do{
342   do{                                             325   do{
343     if ((a2*G4UniformRand()) < a1)                326     if ((a2*G4UniformRand()) < a1)
344       tau = std::pow(taumin,G4UniformRand());  << 327       tau = std::pow(taumin,G4UniformRand());     
345     else                                          328     else
346       tau = std::sqrt(1.0+G4UniformRand()*(tau << 329       tau = std::sqrt(1.0+G4UniformRand()*(taumin*taumin-1.0));     
347     //rejection function                          330     //rejection function
348     TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(e    331     TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
349   }while (G4UniformRand()> TST);                  332   }while (G4UniformRand()> TST);
350   if (tau > taumax) tau = taumax; //prevent FP << 
351   epsilon=tau;                                    333   epsilon=tau;
352   cosTheta = 1.0 - (1.0-tau)/(ek*tau);            334   cosTheta = 1.0 - (1.0-tau)/(ek*tau);
353                                                   335 
354   //Target shell electrons                     << 336   //Target shell electrons  
355   TST = fOscManager->GetTotalZ(material)*G4Uni << 337   TST = oscManager->GetTotalZ(material)*G4UniformRand();
356   targetOscillator = numberOfOscillators-1; //    338   targetOscillator = numberOfOscillators-1; //last level
357   S=0.0;                                          339   S=0.0;
358   G4bool levelFound = false;                      340   G4bool levelFound = false;
359   for (size_t j=0;j<numberOfOscillators && !le    341   for (size_t j=0;j<numberOfOscillators && !levelFound; j++)
360     {                                             342     {
361       S += (*theTable)[j]->GetOscillatorStreng << 343       S += (*theTable)[j]->GetOscillatorStrength();     
362       if (S > TST)                             << 344       if (S > TST) 
363         {                                         345         {
364     targetOscillator = j;                         346     targetOscillator = j;
365     levelFound = true;                            347     levelFound = true;
366         }                                         348         }
367     }                                             349     }
368   //check whether the level is valid              350   //check whether the level is valid
369   ionEnergy = (*theTable)[targetOscillator]->G    351   ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
370       }while((epsilon*photonEnergy0-photonEner    352       }while((epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
371     }                                             353     }
372   else //photonEnergy0 < 5 MeV                    354   else //photonEnergy0 < 5 MeV
373     {                                             355     {
374       //Incoherent scattering function for the    356       //Incoherent scattering function for theta=PI
375       G4double s0=0.0;                            357       G4double s0=0.0;
376       G4double pzomc=0.0;                         358       G4double pzomc=0.0;
377       G4double rni=0.0;                           359       G4double rni=0.0;
378       G4double aux=0.0;                           360       G4double aux=0.0;
379       for (size_t i=0;i<numberOfOscillators;i+    361       for (size_t i=0;i<numberOfOscillators;i++)
380   {                                               362   {
381     ionEnergy = (*theTable)[i]->GetIonisationE    363     ionEnergy = (*theTable)[i]->GetIonisationEnergy();
382     if (photonEnergy0 > ionEnergy)                364     if (photonEnergy0 > ionEnergy)
383       {                                           365       {
384         G4double aux2 = photonEnergy0*(photonE    366         G4double aux2 = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
385         hartreeFunc = (*theTable)[i]->GetHartr << 367         hartreeFunc = (*theTable)[i]->GetHartreeFactor(); 
386         oscStren = (*theTable)[i]->GetOscillat    368         oscStren = (*theTable)[i]->GetOscillatorStrength();
387         pzomc = hartreeFunc*(aux2-electron_mas    369         pzomc = hartreeFunc*(aux2-electron_mass_c2*ionEnergy)/
388     (electron_mass_c2*std::sqrt(2.0*aux2+ionEn    370     (electron_mass_c2*std::sqrt(2.0*aux2+ionEnergy*ionEnergy));
389         if (pzomc > 0)                         << 371         if (pzomc > 0)  
390     rni = 1.0-0.5*G4Exp(0.5-(std::sqrt(0.5)+st << 372     rni = 1.0-0.5*std::exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
391                (std::sqrt(0.5)+std::sqrt(2.0)* << 373                (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));    
392         else                                   << 374         else      
393     rni = 0.5*G4Exp(0.5-(std::sqrt(0.5)-std::s << 375     rni = 0.5*std::exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
394            (std::sqrt(0.5)-std::sqrt(2.0)*pzom << 376            (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));      
395         s0 += oscStren*rni;                       377         s0 += oscStren*rni;
396       }                                           378       }
397   }                                            << 379   }      
398       //Sampling tau                              380       //Sampling tau
399       G4double cdt1 = 0.;                         381       G4double cdt1 = 0.;
400       do                                          382       do
401   {                                               383   {
402     if ((G4UniformRand()*a2) < a1)             << 384     if ((G4UniformRand()*a2) < a1)      
403       tau = std::pow(taumin,G4UniformRand());  << 385       tau = std::pow(taumin,G4UniformRand());     
404     else                                       << 386     else      
405       tau = std::sqrt(1.0+G4UniformRand()*(tau << 387       tau = std::sqrt(1.0+G4UniformRand()*(taumin*taumin-1.0));     
406     if (tau > taumax) tau = taumax; //prevent  << 
407     cdt1 = (1.0-tau)/(ek*tau);                    388     cdt1 = (1.0-tau)/(ek*tau);
408     //Incoherent scattering function              389     //Incoherent scattering function
409     S = 0.;                                       390     S = 0.;
410     for (size_t i=0;i<numberOfOscillators;i++)    391     for (size_t i=0;i<numberOfOscillators;i++)
411       {                                           392       {
412         ionEnergy = (*theTable)[i]->GetIonisat    393         ionEnergy = (*theTable)[i]->GetIonisationEnergy();
413         if (photonEnergy0 > ionEnergy) //sum o    394         if (photonEnergy0 > ionEnergy) //sum only on excitable levels
414     {                                             395     {
415       aux = photonEnergy0*(photonEnergy0-ionEn    396       aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
416       hartreeFunc = (*theTable)[i]->GetHartree << 397       hartreeFunc = (*theTable)[i]->GetHartreeFactor(); 
417       oscStren = (*theTable)[i]->GetOscillator    398       oscStren = (*theTable)[i]->GetOscillatorStrength();
418       pzomc = hartreeFunc*(aux-electron_mass_c    399       pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
419         (electron_mass_c2*std::sqrt(2.0*aux+io    400         (electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
420       if (pzomc > 0)                           << 401       if (pzomc > 0) 
421         rn[i] = 1.0-0.5*G4Exp(0.5-(std::sqrt(0 << 402         rn[i] = 1.0-0.5*std::exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
422                (std::sqrt(0.5)+std::sqrt(2.0)* << 403                (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));        
423       else                                     << 404       else        
424         rn[i] = 0.5*G4Exp(0.5-(std::sqrt(0.5)- << 405         rn[i] = 0.5*std::exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
425            (std::sqrt(0.5)-std::sqrt(2.0)*pzom << 406            (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));        
426       S += oscStren*rn[i];                        407       S += oscStren*rn[i];
427       pac[i] = S;                                 408       pac[i] = S;
428     }                                             409     }
429         else                                      410         else
430     pac[i] = S-1e-6;                           << 411     pac[i] = S-1e-6;    
431       }                                           412       }
432     //Rejection function                          413     //Rejection function
433     TST = S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/ << 414     TST = S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));  
434   }while ((G4UniformRand()*s0) > TST);            415   }while ((G4UniformRand()*s0) > TST);
435                                                   416 
436       cosTheta = 1.0 - cdt1;                      417       cosTheta = 1.0 - cdt1;
437       G4double fpzmax=0.0,fpz=0.0;                418       G4double fpzmax=0.0,fpz=0.0;
438       G4double A=0.0;                             419       G4double A=0.0;
439       //Target electron shell                     420       //Target electron shell
440       do                                          421       do
441   {                                               422   {
442     do                                            423     do
443       {                                           424       {
444         TST = S*G4UniformRand();                  425         TST = S*G4UniformRand();
445         targetOscillator = numberOfOscillators    426         targetOscillator = numberOfOscillators-1; //last level
446         G4bool levelFound = false;                427         G4bool levelFound = false;
447         for (size_t i=0;i<numberOfOscillators     428         for (size_t i=0;i<numberOfOscillators && !levelFound;i++)
448     {                                             429     {
449       if (pac[i]>TST)                          << 430       if (pac[i]>TST) 
450         {                                      << 431         {        
451           targetOscillator = i;                   432           targetOscillator = i;
452           levelFound = true;                      433           levelFound = true;
453         }                                         434         }
454     }                                             435     }
455         A = G4UniformRand()*rn[targetOscillato    436         A = G4UniformRand()*rn[targetOscillator];
456         hartreeFunc = (*theTable)[targetOscill << 437         hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor(); 
457         oscStren = (*theTable)[targetOscillato    438         oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
458         if (A < 0.5)                           << 439         if (A < 0.5) 
459     pzomc = (std::sqrt(0.5)-std::sqrt(0.5-G4Lo << 440     pzomc = (std::sqrt(0.5)-std::sqrt(0.5-std::log(2.0*A)))/
460       (std::sqrt(2.0)*hartreeFunc);            << 441       (std::sqrt(2.0)*hartreeFunc);       
461         else                                   << 442         else    
462     pzomc = (std::sqrt(0.5-G4Log(2.0-2.0*A))-s << 443     pzomc = (std::sqrt(0.5-std::log(2.0-2.0*A))-std::sqrt(0.5))/
463       (std::sqrt(2.0)*hartreeFunc);            << 444       (std::sqrt(2.0)*hartreeFunc); 
464       } while (pzomc < -1);                       445       } while (pzomc < -1);
465                                                   446 
466     // F(EP) rejection                            447     // F(EP) rejection
467     G4double XQC = 1.0+tau*(tau-2.0*cosTheta);    448     G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
468     G4double AF = std::sqrt(XQC)*(1.0+tau*(tau    449     G4double AF = std::sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
469     if (AF > 0)                                << 450     if (AF > 0) 
470       fpzmax = 1.0+AF*0.2;                        451       fpzmax = 1.0+AF*0.2;
471     else                                          452     else
472       fpzmax = 1.0-AF*0.2;                     << 453       fpzmax = 1.0-AF*0.2;      
473     fpz = 1.0+AF*std::max(std::min(pzomc,0.2),    454     fpz = 1.0+AF*std::max(std::min(pzomc,0.2),-0.2);
474   }while ((fpzmax*G4UniformRand())>fpz);          455   }while ((fpzmax*G4UniformRand())>fpz);
475                                                << 456   
476       //Energy of the scattered photon            457       //Energy of the scattered photon
477       G4double T = pzomc*pzomc;                   458       G4double T = pzomc*pzomc;
478       G4double b1 = 1.0-T*tau*tau;                459       G4double b1 = 1.0-T*tau*tau;
479       G4double b2 = 1.0-T*tau*cosTheta;           460       G4double b2 = 1.0-T*tau*cosTheta;
480       if (pzomc > 0.0)                         << 461       if (pzomc > 0.0)  
481   epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2 << 462   epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2*b2-b1*(1.0-T))));  
482       else                                     << 463       else  
483   epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2 << 464   epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2*b2-b1*(1.0-T))));  
484     } //energy < 5 MeV                            465     } //energy < 5 MeV
485                                                << 466   
486   //Ok, the kinematics has been calculated.       467   //Ok, the kinematics has been calculated.
487   G4double sinTheta = std::sqrt(1-cosTheta*cos    468   G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
488   G4double phi = twopi * G4UniformRand() ;        469   G4double phi = twopi * G4UniformRand() ;
489   G4double dirx = sinTheta * std::cos(phi);       470   G4double dirx = sinTheta * std::cos(phi);
490   G4double diry = sinTheta * std::sin(phi);       471   G4double diry = sinTheta * std::sin(phi);
491   G4double dirz = cosTheta ;                      472   G4double dirz = cosTheta ;
492                                                   473 
493   // Update G4VParticleChange for the scattere    474   // Update G4VParticleChange for the scattered photon
494   G4ThreeVector photonDirection1(dirx,diry,dir    475   G4ThreeVector photonDirection1(dirx,diry,dirz);
495   photonDirection1.rotateUz(photonDirection0);    476   photonDirection1.rotateUz(photonDirection0);
496   fParticleChange->ProposeMomentumDirection(ph    477   fParticleChange->ProposeMomentumDirection(photonDirection1) ;
497                                                   478 
498   G4double photonEnergy1 = epsilon * photonEne    479   G4double photonEnergy1 = epsilon * photonEnergy0;
499                                                   480 
500   if (photonEnergy1 > 0.)                      << 481   if (photonEnergy1 > 0.)  
501     fParticleChange->SetProposedKineticEnergy( << 482     fParticleChange->SetProposedKineticEnergy(photonEnergy1) ;  
502   else                                            483   else
503   {                                               484   {
504     fParticleChange->SetProposedKineticEnergy(    485     fParticleChange->SetProposedKineticEnergy(0.) ;
505     fParticleChange->ProposeTrackStatus(fStopA    486     fParticleChange->ProposeTrackStatus(fStopAndKill);
506   }                                               487   }
507                                                << 488   
508   //Create scattered electron                     489   //Create scattered electron
509   G4double diffEnergy = photonEnergy0*(1-epsil    490   G4double diffEnergy = photonEnergy0*(1-epsilon);
510   ionEnergy = (*theTable)[targetOscillator]->G    491   ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
511                                                   492 
512   G4double Q2 =                                << 493   G4double Q2 = 
513     photonEnergy0*photonEnergy0+photonEnergy1*    494     photonEnergy0*photonEnergy0+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
514   G4double cosThetaE = 0.; //scattering angle     495   G4double cosThetaE = 0.; //scattering angle for the electron
515                                                   496 
516   if (Q2 > 1.0e-12)                            << 497   if (Q2 > 1.0e-12)    
517     cosThetaE = (photonEnergy0-photonEnergy1*c << 498     cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/std::sqrt(Q2);    
518   else                                         << 499   else    
519     cosThetaE = 1.0;                           << 500     cosThetaE = 1.0;    
520   G4double sinThetaE = std::sqrt(1-cosThetaE*c    501   G4double sinThetaE = std::sqrt(1-cosThetaE*cosThetaE);
521                                                   502 
522   //Now, try to handle fluorescence               503   //Now, try to handle fluorescence
523   //Notice: merged levels are indicated with Z    504   //Notice: merged levels are indicated with Z=0 and flag=30
524   G4int shFlag = (*theTable)[targetOscillator] << 505   G4int shFlag = (*theTable)[targetOscillator]->GetShellFlag(); 
525   G4int Z = (G4int) (*theTable)[targetOscillat    506   G4int Z = (G4int) (*theTable)[targetOscillator]->GetParentZ();
526                                                   507 
527   //initialize here, then check photons create    508   //initialize here, then check photons created by Atomic-Deexcitation, and the final state e-
528   G4double bindingEnergy = 0.*eV;                 509   G4double bindingEnergy = 0.*eV;
529   const G4AtomicShell* shell = 0;                 510   const G4AtomicShell* shell = 0;
530                                                   511 
531   //Real level                                    512   //Real level
532   if (Z > 0 && shFlag<30)                         513   if (Z > 0 && shFlag<30)
533     {                                             514     {
534       shell = fTransitionManager->Shell(Z,shFl    515       shell = fTransitionManager->Shell(Z,shFlag-1);
535       bindingEnergy = shell->BindingEnergy();  << 516       bindingEnergy = shell->BindingEnergy();    
536     }                                             517     }
537                                                   518 
538   G4double ionEnergyInPenelopeDatabase = ionEn    519   G4double ionEnergyInPenelopeDatabase = ionEnergy;
539   //protection against energy non-conservation    520   //protection against energy non-conservation
540   ionEnergy = std::max(bindingEnergy,ionEnergy << 521   ionEnergy = std::max(bindingEnergy,ionEnergyInPenelopeDatabase);  
541                                                   522 
542   //subtract the excitation energy. If not emi    523   //subtract the excitation energy. If not emitted by fluorescence
543   //the ionization energy is deposited as loca    524   //the ionization energy is deposited as local energy deposition
544   G4double eKineticEnergy = diffEnergy - ionEn << 525   G4double eKineticEnergy = diffEnergy - ionEnergy; 
545   G4double localEnergyDeposit = ionEnergy;     << 526   G4double localEnergyDeposit = ionEnergy; 
546   G4double energyInFluorescence = 0.; //testin    527   G4double energyInFluorescence = 0.; //testing purposes only
547   G4double energyInAuger = 0; //testing purpos    528   G4double energyInAuger = 0; //testing purposes
548                                                   529 
549   if (eKineticEnergy < 0)                      << 530   if (eKineticEnergy < 0) 
550     {                                             531     {
551       //It means that there was some problem/m << 532       //It means that there was some problem/mismatch between the two databases. 
552       //Try to make it work                       533       //Try to make it work
553       //In this case available Energy (diffEne    534       //In this case available Energy (diffEnergy) < ionEnergy
554       //Full residual energy is deposited loca    535       //Full residual energy is deposited locally
555       localEnergyDeposit = diffEnergy;            536       localEnergyDeposit = diffEnergy;
556       eKineticEnergy = 0.0;                       537       eKineticEnergy = 0.0;
557     }                                             538     }
558                                                   539 
559   //the local energy deposit is what remains:     540   //the local energy deposit is what remains: part of this may be spent for fluorescence.
560   //Notice: shell might be nullptr (invalid!)  << 541   //Notice: shell might be NULL (invalid!) if shFlag=30. Must be protected
561   //Now, take care of fluorescence, if require    542   //Now, take care of fluorescence, if required
562   if (fAtomDeexcitation && shell)                 543   if (fAtomDeexcitation && shell)
563     {                                          << 544     {      
564       G4int index = couple->GetIndex();           545       G4int index = couple->GetIndex();
565       if (fAtomDeexcitation->CheckDeexcitation    546       if (fAtomDeexcitation->CheckDeexcitationActiveRegion(index))
566   {                                            << 547   { 
567     size_t nBefore = fvect->size();               548     size_t nBefore = fvect->size();
568     fAtomDeexcitation->GenerateParticles(fvect    549     fAtomDeexcitation->GenerateParticles(fvect,shell,Z,index);
569     size_t nAfter = fvect->size();             << 550     size_t nAfter = fvect->size(); 
570                                                << 551       
571     if (nAfter > nBefore) //actual production     552     if (nAfter > nBefore) //actual production of fluorescence
572       {                                           553       {
573         for (size_t j=nBefore;j<nAfter;j++) //    554         for (size_t j=nBefore;j<nAfter;j++) //loop on products
574     {                                             555     {
575       G4double itsEnergy = ((*fvect)[j])->GetK    556       G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
576       if (itsEnergy < localEnergyDeposit) // v << 557       localEnergyDeposit -= itsEnergy;
577         {                                      << 558       if (((*fvect)[j])->GetParticleDefinition() == G4Gamma::Definition())
578           localEnergyDeposit -= itsEnergy;     << 559         energyInFluorescence += itsEnergy;
579           if (((*fvect)[j])->GetParticleDefini << 560       else if (((*fvect)[j])->GetParticleDefinition() == G4Electron::Definition())
580       energyInFluorescence += itsEnergy;       << 561         energyInAuger += itsEnergy;
581           else if (((*fvect)[j])->GetParticleD << 562       
582              G4Electron::Definition())         << 
583       energyInAuger += itsEnergy;              << 
584         }                                      << 
585       else //invalid secondary: takes more tha << 
586         {                                      << 
587           delete (*fvect)[j];                  << 
588           (*fvect)[j] = nullptr;               << 
589         }                                      << 
590     }                                             563     }
591       }                                           564       }
592                                                << 565 
593   }                                               566   }
594     }                                             567     }
595                                                   568 
596   //Always produce explicitly the electron     << 569 
                                                   >> 570   /*
                                                   >> 571   if(DeexcitationFlag() && Z > 5 && shellId>0) {
                                                   >> 572 
                                                   >> 573     const G4ProductionCutsTable* theCoupleTable=
                                                   >> 574       G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 575 
                                                   >> 576     size_t index = couple->GetIndex();
                                                   >> 577     G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
                                                   >> 578     G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
                                                   >> 579 
                                                   >> 580     // Generation of fluorescence
                                                   >> 581     // Data in EADL are available only for Z > 5
                                                   >> 582     // Protection to avoid generating photons in the unphysical case of
                                                   >> 583     // shell binding energy > photon energy
                                                   >> 584     if (localEnergyDeposit > cutg || localEnergyDeposit > cute)
                                                   >> 585       { 
                                                   >> 586   G4DynamicParticle* aPhoton;
                                                   >> 587   deexcitationManager.SetCutForSecondaryPhotons(cutg);
                                                   >> 588   deexcitationManager.SetCutForAugerElectrons(cute);
                                                   >> 589 
                                                   >> 590   photonVector = deexcitationManager.GenerateParticles(Z,shellId);
                                                   >> 591   if(photonVector) 
                                                   >> 592     {
                                                   >> 593       size_t nPhotons = photonVector->size();
                                                   >> 594       for (size_t k=0; k<nPhotons; k++)
                                                   >> 595         {
                                                   >> 596     aPhoton = (*photonVector)[k];
                                                   >> 597     if (aPhoton)
                                                   >> 598       {
                                                   >> 599         G4double itsEnergy = aPhoton->GetKineticEnergy();
                                                   >> 600         G4bool keepIt = false;
                                                   >> 601         if (itsEnergy <= localEnergyDeposit)
                                                   >> 602           {
                                                   >> 603       //check if good! 
                                                   >> 604       if(aPhoton->GetDefinition() == G4Gamma::Gamma()
                                                   >> 605          && itsEnergy >= cutg)
                                                   >> 606         {
                                                   >> 607           keepIt = true;
                                                   >> 608           energyInFluorescence += itsEnergy;        
                                                   >> 609         }
                                                   >> 610       if (aPhoton->GetDefinition() == G4Electron::Electron() && 
                                                   >> 611           itsEnergy >= cute)
                                                   >> 612         {
                                                   >> 613           energyInAuger += itsEnergy;
                                                   >> 614           keepIt = true;
                                                   >> 615         }
                                                   >> 616           }
                                                   >> 617         //good secondary, register it
                                                   >> 618         if (keepIt)
                                                   >> 619           {
                                                   >> 620       localEnergyDeposit -= itsEnergy;
                                                   >> 621       fvect->push_back(aPhoton);
                                                   >> 622           }       
                                                   >> 623         else
                                                   >> 624           {
                                                   >> 625       delete aPhoton;
                                                   >> 626       (*photonVector)[k] = 0;
                                                   >> 627           }
                                                   >> 628       }
                                                   >> 629         }
                                                   >> 630       delete photonVector;
                                                   >> 631     }
                                                   >> 632       }
                                                   >> 633   }
                                                   >> 634   */
                                                   >> 635 
                                                   >> 636 
                                                   >> 637   //Always produce explicitely the electron 
597   G4DynamicParticle* electron = 0;                638   G4DynamicParticle* electron = 0;
598                                                   639 
599   G4double xEl = sinThetaE * std::cos(phi+pi); << 640   G4double xEl = sinThetaE * std::cos(phi+pi); 
600   G4double yEl = sinThetaE * std::sin(phi+pi);    641   G4double yEl = sinThetaE * std::sin(phi+pi);
601   G4double zEl = cosThetaE;                       642   G4double zEl = cosThetaE;
602   G4ThreeVector eDirection(xEl,yEl,zEl); //ele    643   G4ThreeVector eDirection(xEl,yEl,zEl); //electron direction
603   eDirection.rotateUz(photonDirection0);          644   eDirection.rotateUz(photonDirection0);
604   electron = new G4DynamicParticle (G4Electron    645   electron = new G4DynamicParticle (G4Electron::Electron(),
605             eDirection,eKineticEnergy) ;          646             eDirection,eKineticEnergy) ;
606   fvect->push_back(electron);                     647   fvect->push_back(electron);
                                                   >> 648     
607                                                   649 
608   if (localEnergyDeposit < 0) //Should not be: << 650   if (localEnergyDeposit < 0)
609     {                                             651     {
610       G4Exception("G4PenelopeComptonModel::Sam << 652       G4cout << "WARNING-" 
611        "em2099",JustWarning,"WARNING: Negative << 653        << "G4PenelopeComptonModel::SampleSecondaries - Negative energy deposit"
                                                   >> 654        << G4endl;
612       localEnergyDeposit=0.;                      655       localEnergyDeposit=0.;
613     }                                             656     }
614   fParticleChange->ProposeLocalEnergyDeposit(l    657   fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
615                                                << 658   
616   G4double electronEnergy = 0.;                   659   G4double electronEnergy = 0.;
617   if (electron)                                   660   if (electron)
618     electronEnergy = eKineticEnergy;              661     electronEnergy = eKineticEnergy;
619   if (fVerboseLevel > 1)                       << 662   if (verboseLevel > 1)
620     {                                             663     {
621       G4cout << "-----------------------------    664       G4cout << "-----------------------------------------------------------" << G4endl;
622       G4cout << "Energy balance from G4Penelop    665       G4cout << "Energy balance from G4PenelopeCompton" << G4endl;
623       G4cout << "Incoming photon energy: " <<     666       G4cout << "Incoming photon energy: " << photonEnergy0/keV << " keV" << G4endl;
624       G4cout << "-----------------------------    667       G4cout << "-----------------------------------------------------------" << G4endl;
625       G4cout << "Scattered photon: " << photon    668       G4cout << "Scattered photon: " << photonEnergy1/keV << " keV" << G4endl;
626       G4cout << "Scattered electron " << elect    669       G4cout << "Scattered electron " << electronEnergy/keV << " keV" << G4endl;
627       if (energyInFluorescence)                   670       if (energyInFluorescence)
628   G4cout << "Fluorescence x-rays: " << energyI    671   G4cout << "Fluorescence x-rays: " << energyInFluorescence/keV << " keV" << G4endl;
629       if (energyInAuger)                          672       if (energyInAuger)
630   G4cout << "Auger electrons: " << energyInAug    673   G4cout << "Auger electrons: " << energyInAuger/keV << " keV" << G4endl;
631       G4cout << "Local energy deposit " << loc    674       G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
632       G4cout << "Total final state: " << (phot    675       G4cout << "Total final state: " << (photonEnergy1+electronEnergy+energyInFluorescence+
633             localEnergyDeposit+energyInAuger)/ << 676             localEnergyDeposit+energyInAuger)/keV << 
634   " keV" << G4endl;                               677   " keV" << G4endl;
635       G4cout << "-----------------------------    678       G4cout << "-----------------------------------------------------------" << G4endl;
636     }                                             679     }
637   if (fVerboseLevel > 0)                       << 680   if (verboseLevel > 0)
638     {                                             681     {
639       G4double energyDiff = std::fabs(photonEn    682       G4double energyDiff = std::fabs(photonEnergy1+
640               electronEnergy+energyInFluoresce    683               electronEnergy+energyInFluorescence+
641               localEnergyDeposit+energyInAuger    684               localEnergyDeposit+energyInAuger-photonEnergy0);
642       if (energyDiff > 0.05*keV)                  685       if (energyDiff > 0.05*keV)
643   G4cout << "Warning from G4PenelopeCompton: p << 686   G4cout << "Warning from G4PenelopeCompton: problem with energy conservation: " << 
644     (photonEnergy1+electronEnergy+energyInFluo << 687     (photonEnergy1+electronEnergy+energyInFluorescence+energyInAuger+localEnergyDeposit)/keV << 
645     " keV (final) vs. " <<                     << 688     " keV (final) vs. " << 
646     photonEnergy0/keV << " keV (initial)" << G    689     photonEnergy0/keV << " keV (initial)" << G4endl;
647     }                                          << 690     }    
648 }                                                 691 }
649                                                   692 
650 //....oooOO0OOooo........oooOO0OOooo........oo    693 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
651                                                   694 
652 G4double G4PenelopeComptonModel::DifferentialC    695 G4double G4PenelopeComptonModel::DifferentialCrossSection(G4double cosTheta,G4double energy,
653                   G4PenelopeOscillator* osc)      696                   G4PenelopeOscillator* osc)
654 {                                                 697 {
655   //                                              698   //
656   // Penelope model v2008. Single differential << 699   // Penelope model v2008. Single differential cross section *per electron* 
657   // for photon Compton scattering by          << 700   // for photon Compton scattering by 
658   // electrons in the given atomic oscillator, << 701   // electrons in the given atomic oscillator, differential in the direction of the 
659   // scattering photon. This is in units of pi << 702   // scattering photon. This is in units of pi*classic_electr_radius**2 
660   //                                              703   //
661   // D. Brusa et al., Nucl. Instrum. Meth. A 3    704   // D. Brusa et al., Nucl. Instrum. Meth. A 379 (1996) 167
662   // The parametrization includes the J(p) dis << 705   // The parametrization includes the J(p) distribution profiles for the atomic shells, 
663   // that are tabulated from Hartree-Fock calc << 706   // that are tabulated from Hartree-Fock calculations 
664   // from F. Biggs et al., At. Data Nucl. Data    707   // from F. Biggs et al., At. Data Nucl. Data Tables 16 (1975) 201
665   //                                              708   //
666   G4double ionEnergy = osc->GetIonisationEnerg    709   G4double ionEnergy = osc->GetIonisationEnergy();
667   G4double harFunc = osc->GetHartreeFactor();  << 710   G4double harFunc = osc->GetHartreeFactor(); 
668                                                   711 
669   static const G4double k2 = std::sqrt(2.);       712   static const G4double k2 = std::sqrt(2.);
670   static const G4double k1 = 1./k2;            << 713   static const G4double k1 = 1./k2; 
671                                                   714 
672   if (energy < ionEnergy)                         715   if (energy < ionEnergy)
673     return 0;                                     716     return 0;
674                                                   717 
675   //energy of the Compton line                    718   //energy of the Compton line
676   G4double cdt1 = 1.0-cosTheta;                   719   G4double cdt1 = 1.0-cosTheta;
677   G4double EOEC = 1.0+(energy/electron_mass_c2 << 720   G4double EOEC = 1.0+(energy/electron_mass_c2)*cdt1; 
678   G4double ECOE = 1.0/EOEC;                       721   G4double ECOE = 1.0/EOEC;
679                                                   722 
680   //Incoherent scattering function (analytical    723   //Incoherent scattering function (analytical profile)
681   G4double aux = energy*(energy-ionEnergy)*cdt    724   G4double aux = energy*(energy-ionEnergy)*cdt1;
682   G4double Pzimax =                            << 725   G4double Pzimax = 
683     (aux - electron_mass_c2*ionEnergy)/(electr    726     (aux - electron_mass_c2*ionEnergy)/(electron_mass_c2*std::sqrt(2*aux+ionEnergy*ionEnergy));
684   G4double sia = 0.0;                             727   G4double sia = 0.0;
685   G4double x = harFunc*Pzimax;                    728   G4double x = harFunc*Pzimax;
686   if (x > 0)                                   << 729   if (x > 0) 
687     sia = 1.0-0.5*G4Exp(0.5-(k1+k2*x)*(k1+k2*x << 730     sia = 1.0-0.5*std::exp(0.5-(k1+k2*x)*(k1+k2*x));    
688   else                                         << 731   else    
689     sia = 0.5*G4Exp(0.5-(k1-k2*x)*(k1-k2*x));  << 732     sia = 0.5*std::exp(0.5-(k1-k2*x)*(k1-k2*x));
690                                                << 733    
691   //1st order correction, integral of Pz times    734   //1st order correction, integral of Pz times the Compton profile.
692   //Calculated approximately using a free-elec    735   //Calculated approximately using a free-electron gas profile
693   G4double pf = 3.0/(4.0*harFunc);                736   G4double pf = 3.0/(4.0*harFunc);
694   if (std::fabs(Pzimax) < pf)                     737   if (std::fabs(Pzimax) < pf)
695     {                                             738     {
696       G4double QCOE2 = 1.0+ECOE*ECOE-2.0*ECOE*    739       G4double QCOE2 = 1.0+ECOE*ECOE-2.0*ECOE*cosTheta;
697       G4double p2 = Pzimax*Pzimax;                740       G4double p2 = Pzimax*Pzimax;
698       G4double dspz = std::sqrt(QCOE2)*           741       G4double dspz = std::sqrt(QCOE2)*
699   (1.0+ECOE*(ECOE-cosTheta)/QCOE2)*harFunc        742   (1.0+ECOE*(ECOE-cosTheta)/QCOE2)*harFunc
700   *0.25*(2*p2-(p2*p2)/(pf*pf)-(pf*pf));           743   *0.25*(2*p2-(p2*p2)/(pf*pf)-(pf*pf));
701       sia += std::max(dspz,-1.0*sia);             744       sia += std::max(dspz,-1.0*sia);
702     }                                             745     }
703                                                   746 
704   G4double XKN = EOEC+ECOE-1.0+cosTheta*cosThe    747   G4double XKN = EOEC+ECOE-1.0+cosTheta*cosTheta;
705                                                   748 
706   //Differential cross section (per electron,     749   //Differential cross section (per electron, in units of pi*classic_electr_radius**2)
707   G4double diffCS = ECOE*ECOE*XKN*sia;            750   G4double diffCS = ECOE*ECOE*XKN*sia;
708                                                   751 
709   return diffCS;                                  752   return diffCS;
710 }                                                 753 }
711                                                   754 
712 //....oooOO0OOooo........oooOO0OOooo........oo    755 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
713                                                   756 
714 G4double G4PenelopeComptonModel::OscillatorTot    757 G4double G4PenelopeComptonModel::OscillatorTotalCrossSection(G4double energy,G4PenelopeOscillator* osc)
715 {                                                 758 {
716   //Total cross section (integrated) for the g << 759   //Total cross section (integrated) for the given oscillator in units of 
717   //pi*classic_electr_radius^2                    760   //pi*classic_electr_radius^2
718                                                   761 
719   //Integrate differential cross section for e    762   //Integrate differential cross section for each oscillator
720   G4double stre = osc->GetOscillatorStrength()    763   G4double stre = osc->GetOscillatorStrength();
721                                                << 764   
722   // here one uses the  using the 20-point        765   // here one uses the  using the 20-point
723   // Gauss quadrature method with an adaptive     766   // Gauss quadrature method with an adaptive bipartition scheme
724   const G4int npoints=10;                         767   const G4int npoints=10;
725   const G4int ncallsmax=20000;                    768   const G4int ncallsmax=20000;
726   const G4int nst=256;                            769   const G4int nst=256;
727   static const G4double Abscissas[10] = {7.652    770   static const G4double Abscissas[10] = {7.652651133497334e-02,2.2778585114164508e-01,3.7370608871541956e-01,
728           5.1086700195082710e-01,6.36053680726    771           5.1086700195082710e-01,6.3605368072651503e-01,7.4633190646015079e-01,
729           8.3911697182221882e-01,9.12234428251    772           8.3911697182221882e-01,9.1223442825132591e-01,9.6397192727791379e-01,
730           9.9312859918509492e-01};                773           9.9312859918509492e-01};
731   static const G4double Weights[10] = {1.52753    774   static const G4double Weights[10] = {1.5275338713072585e-01,1.4917298647260375e-01,1.4209610931838205e-01,
732         1.3168863844917663e-01,1.1819453196151    775         1.3168863844917663e-01,1.1819453196151842e-01,1.0193011981724044e-01,
733         8.3276741576704749e-02,6.2672048334109    776         8.3276741576704749e-02,6.2672048334109064e-02,4.0601429800386941e-02,
734         1.7614007139152118e-02};                  777         1.7614007139152118e-02};
735                                                   778 
736   G4double MaxError = 1e-5;                       779   G4double MaxError = 1e-5;
737   //Error control                                 780   //Error control
738   G4double Ctol = std::min(std::max(MaxError,1    781   G4double Ctol = std::min(std::max(MaxError,1e-13),1e-02);
739   G4double Ptol = 0.01*Ctol;                      782   G4double Ptol = 0.01*Ctol;
740   G4double Err=1e35;                              783   G4double Err=1e35;
741                                                   784 
742   //Gauss integration from -1 to 1                785   //Gauss integration from -1 to 1
743   G4double LowPoint = -1.0;                       786   G4double LowPoint = -1.0;
744   G4double HighPoint = 1.0;                       787   G4double HighPoint = 1.0;
745                                                   788 
746   G4double h=HighPoint-LowPoint;                  789   G4double h=HighPoint-LowPoint;
747   G4double sumga=0.0;                             790   G4double sumga=0.0;
748   G4double a=0.5*(HighPoint-LowPoint);            791   G4double a=0.5*(HighPoint-LowPoint);
749   G4double b=0.5*(HighPoint+LowPoint);            792   G4double b=0.5*(HighPoint+LowPoint);
750   G4double c=a*Abscissas[0];                      793   G4double c=a*Abscissas[0];
751   G4double d= Weights[0]*                         794   G4double d= Weights[0]*
752     (DifferentialCrossSection(b+c,energy,osc)+    795     (DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
753   for (G4int i=2;i<=npoints;i++)                  796   for (G4int i=2;i<=npoints;i++)
754     {                                             797     {
755       c=a*Abscissas[i-1];                         798       c=a*Abscissas[i-1];
756       d += Weights[i-1]*                          799       d += Weights[i-1]*
757   (DifferentialCrossSection(b+c,energy,osc)+Di    800   (DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
758     }                                             801     }
759   G4int icall = 2*npoints;                        802   G4int icall = 2*npoints;
760   G4int LH=1;                                     803   G4int LH=1;
761   G4double S[nst],x[nst],sn[nst],xrn[nst];        804   G4double S[nst],x[nst],sn[nst],xrn[nst];
762   S[0]=d*a;                                       805   S[0]=d*a;
763   x[0]=LowPoint;                                  806   x[0]=LowPoint;
764                                                   807 
765   G4bool loopAgain = true;                        808   G4bool loopAgain = true;
766                                                   809 
767   //Adaptive bipartition scheme                   810   //Adaptive bipartition scheme
768   do{                                             811   do{
769     G4double h0=h;                                812     G4double h0=h;
770     h=0.5*h; //bipartition                        813     h=0.5*h; //bipartition
771     G4double sumr=0;                              814     G4double sumr=0;
772     G4int LHN=0;                                  815     G4int LHN=0;
773     G4double si,xa,xb,xc;                         816     G4double si,xa,xb,xc;
774     for (G4int i=1;i<=LH;i++){                    817     for (G4int i=1;i<=LH;i++){
775       si=S[i-1];                                  818       si=S[i-1];
776       xa=x[i-1];                                  819       xa=x[i-1];
777       xb=xa+h;                                    820       xb=xa+h;
778       xc=xa+h0;                                   821       xc=xa+h0;
779       a=0.5*(xb-xa);                              822       a=0.5*(xb-xa);
780       b=0.5*(xb+xa);                              823       b=0.5*(xb+xa);
781       c=a*Abscissas[0];                           824       c=a*Abscissas[0];
782       G4double dLocal = Weights[0]*               825       G4double dLocal = Weights[0]*
783   (DifferentialCrossSection(b+c,energy,osc)+Di    826   (DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
784                                                << 827       
785       for (G4int j=1;j<npoints;j++)               828       for (G4int j=1;j<npoints;j++)
786   {                                               829   {
787     c=a*Abscissas[j];                             830     c=a*Abscissas[j];
788     dLocal += Weights[j]*                         831     dLocal += Weights[j]*
789       (DifferentialCrossSection(b+c,energy,osc    832       (DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
790   }                                            << 833   }    
791       G4double s1=dLocal*a;                       834       G4double s1=dLocal*a;
792       a=0.5*(xc-xb);                              835       a=0.5*(xc-xb);
793       b=0.5*(xc+xb);                              836       b=0.5*(xc+xb);
794       c=a*Abscissas[0];                           837       c=a*Abscissas[0];
795       dLocal=Weights[0]*                          838       dLocal=Weights[0]*
796   (DifferentialCrossSection(b+c,energy,osc)+Di    839   (DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
797                                                << 840       
798       for (G4int j=1;j<npoints;j++)               841       for (G4int j=1;j<npoints;j++)
799   {                                               842   {
800     c=a*Abscissas[j];                             843     c=a*Abscissas[j];
801     dLocal += Weights[j]*                         844     dLocal += Weights[j]*
802       (DifferentialCrossSection(b+c,energy,osc    845       (DifferentialCrossSection(b+c,energy,osc)+DifferentialCrossSection(b-c,energy,osc));
803   }                                            << 846   }    
804       G4double s2=dLocal*a;                       847       G4double s2=dLocal*a;
805       icall=icall+4*npoints;                      848       icall=icall+4*npoints;
806       G4double s12=s1+s2;                         849       G4double s12=s1+s2;
807       if (std::abs(s12-si)<std::max(Ptol*std::    850       if (std::abs(s12-si)<std::max(Ptol*std::abs(s12),1e-35))
808   sumga += s12;                                   851   sumga += s12;
809       else                                        852       else
810   {                                               853   {
811     sumr += s12;                                  854     sumr += s12;
812     LHN += 2;                                     855     LHN += 2;
813     sn[LHN-1]=s2;                                 856     sn[LHN-1]=s2;
814     xrn[LHN-1]=xb;                                857     xrn[LHN-1]=xb;
815     sn[LHN-2]=s1;                                 858     sn[LHN-2]=s1;
816     xrn[LHN-2]=xa;                                859     xrn[LHN-2]=xa;
817   }                                               860   }
818                                                << 861       
819       if (icall>ncallsmax || LHN>nst)             862       if (icall>ncallsmax || LHN>nst)
820   {                                               863   {
821     G4cout << "G4PenelopeComptonModel: " << G4    864     G4cout << "G4PenelopeComptonModel: " << G4endl;
822     G4cout << "LowPoint: " << LowPoint << ", H    865     G4cout << "LowPoint: " << LowPoint << ", High Point: " << HighPoint << G4endl;
823     G4cout << "Tolerance: " << MaxError << G4e    866     G4cout << "Tolerance: " << MaxError << G4endl;
824     G4cout << "Calls: " << icall << ", Integra    867     G4cout << "Calls: " << icall << ", Integral: " << sumga << ", Error: " << Err << G4endl;
825     G4cout << "Number of open subintervals: "     868     G4cout << "Number of open subintervals: " << LHN << G4endl;
826     G4cout << "WARNING: the required accuracy     869     G4cout << "WARNING: the required accuracy has not been attained" << G4endl;
827     loopAgain = false;                            870     loopAgain = false;
828   }                                               871   }
829     }                                             872     }
830     Err=std::abs(sumr)/std::max(std::abs(sumr+    873     Err=std::abs(sumr)/std::max(std::abs(sumr+sumga),1e-35);
831     if (Err < Ctol || LHN == 0)                << 874     if (Err < Ctol || LHN == 0) 
832       loopAgain = false; //end of cycle           875       loopAgain = false; //end of cycle
833     LH=LHN;                                       876     LH=LHN;
834     for (G4int i=0;i<LH;i++)                      877     for (G4int i=0;i<LH;i++)
835       {                                           878       {
836   S[i]=sn[i];                                     879   S[i]=sn[i];
837   x[i]=xrn[i];                                    880   x[i]=xrn[i];
838       }                                           881       }
839   }while(Ctol < 1.0 && loopAgain);             << 882   }while(Ctol < 1.0 && loopAgain); 
                                                   >> 883 
840                                                   884 
841   G4double xs = stre*sumga;                       885   G4double xs = stre*sumga;
842                                                   886 
843   return xs;                                   << 887   return xs; 
844 }                                                 888 }
845                                                   889 
846 //....oooOO0OOooo........oooOO0OOooo........oo    890 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
847                                                   891 
848 G4double G4PenelopeComptonModel::KleinNishinaC    892 G4double G4PenelopeComptonModel::KleinNishinaCrossSection(G4double energy,
849                const G4Material* material)        893                const G4Material* material)
850 {                                                 894 {
851   // use Klein-Nishina formula                    895   // use Klein-Nishina formula
852   // total cross section in units of pi*classi    896   // total cross section in units of pi*classic_electr_radius^2
                                                   >> 897 
853   G4double cs = 0;                                898   G4double cs = 0;
854                                                   899 
855   G4double ek =energy/electron_mass_c2;           900   G4double ek =energy/electron_mass_c2;
856   G4double eks = ek*ek;                           901   G4double eks = ek*ek;
857   G4double ek2 = 1.0+ek+ek;                       902   G4double ek2 = 1.0+ek+ek;
858   G4double ek1 = eks-ek2-1.0;                     903   G4double ek1 = eks-ek2-1.0;
859                                                   904 
860   G4double t0 = 1.0/ek2;                          905   G4double t0 = 1.0/ek2;
861   G4double csl = 0.5*eks*t0*t0+ek2*t0+ek1*G4Lo << 906   G4double csl = 0.5*eks*t0*t0+ek2*t0+ek1*std::log(t0)-(1.0/t0);
862                                                   907 
863   G4PenelopeOscillatorTable* theTable = fOscMa << 908   G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material);
864                                                   909 
865   for (size_t i=0;i<theTable->size();i++)         910   for (size_t i=0;i<theTable->size();i++)
866     {                                             911     {
867       G4PenelopeOscillator* theOsc = (*theTabl    912       G4PenelopeOscillator* theOsc = (*theTable)[i];
868       G4double ionEnergy = theOsc->GetIonisati    913       G4double ionEnergy = theOsc->GetIonisationEnergy();
869       G4double tau=(energy-ionEnergy)/energy;     914       G4double tau=(energy-ionEnergy)/energy;
870       if (tau > t0)                               915       if (tau > t0)
871   {                                               916   {
872     G4double csu = 0.5*eks*tau*tau+ek2*tau+ek1 << 917     G4double csu = 0.5*eks*tau*tau+ek2*tau+ek1*std::log(tau)-(1.0/tau);
873     G4double stre = theOsc->GetOscillatorStren    918     G4double stre = theOsc->GetOscillatorStrength();
874                                                   919 
875     cs += stre*(csu-csl);                         920     cs += stre*(csu-csl);
876   }                                               921   }
877     }                                             922     }
                                                   >> 923 
878   cs /= (ek*eks);                                 924   cs /= (ek*eks);
879                                                   925 
880   return cs;                                      926   return cs;
881                                                   927 
882 }                                                 928 }
883                                                   929 
884 //....oooOO0OOooo........oooOO0OOooo........oo    930 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...
885                                                   931 
886 void G4PenelopeComptonModel::SetParticle(const    932 void G4PenelopeComptonModel::SetParticle(const G4ParticleDefinition* p)
887 {                                                 933 {
888   if(!fParticle) {                                934   if(!fParticle) {
889     fParticle = p;                             << 935     fParticle = p;  
890   }                                               936   }
891 }                                                 937 }
892                                                   938