Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4PenelopeBremsstrahlungModel.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/G4PenelopeBremsstrahlungModel.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4PenelopeBremsstrahlungModel.cc (Version 9.6.p4)


  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$
 26 //                                                 27 //
 27 // Author: Luciano Pandola                         28 // Author: Luciano Pandola
 28 //                                                 29 //
 29 // History:                                        30 // History:
 30 // --------                                        31 // --------
 31 // 23 Nov 2010   L Pandola    First complete i     32 // 23 Nov 2010   L Pandola    First complete implementation, Penelope v2008
 32 // 24 May 2011   L. Pandola   Renamed (make de     33 // 24 May 2011   L. Pandola   Renamed (make default Penelope)
 33 // 13 Mar 2012   L. Pandola   Updated the inte     34 // 13 Mar 2012   L. Pandola   Updated the interface for the angular generator
 34 // 18 Jul 2012   L. Pandola   Migrate to the n <<  35 // 18 Jul 2012   L. Pandola   Migrate to the new interface of the angular generator, which 
 35 //                            now provides the     36 //                            now provides the G4ThreeVector and takes care of rotation
 36 // 02 Oct 2013   L. Pandola   Migrated to MT   << 
 37 // 17 Oct 2013   L. Pandola   Partially revert << 
 38 //                             kept as thread- << 
 39 //                                                 37 //
 40                                                    38 
 41 #include "G4PenelopeBremsstrahlungModel.hh"        39 #include "G4PenelopeBremsstrahlungModel.hh"
 42 #include "G4PhysicalConstants.hh"                  40 #include "G4PhysicalConstants.hh"
 43 #include "G4SystemOfUnits.hh"                      41 #include "G4SystemOfUnits.hh"
 44 #include "G4PenelopeBremsstrahlungFS.hh"           42 #include "G4PenelopeBremsstrahlungFS.hh"
 45 #include "G4PenelopeBremsstrahlungAngular.hh"      43 #include "G4PenelopeBremsstrahlungAngular.hh"
 46 #include "G4ParticleDefinition.hh"                 44 #include "G4ParticleDefinition.hh"
 47 #include "G4MaterialCutsCouple.hh"                 45 #include "G4MaterialCutsCouple.hh"
 48 #include "G4ProductionCutsTable.hh"                46 #include "G4ProductionCutsTable.hh"
 49 #include "G4DynamicParticle.hh"                    47 #include "G4DynamicParticle.hh"
 50 #include "G4Gamma.hh"                              48 #include "G4Gamma.hh"
 51 #include "G4Electron.hh"                           49 #include "G4Electron.hh"
 52 #include "G4Positron.hh"                           50 #include "G4Positron.hh"
 53 #include "G4PenelopeOscillatorManager.hh"          51 #include "G4PenelopeOscillatorManager.hh"
 54 #include "G4PenelopeCrossSection.hh"               52 #include "G4PenelopeCrossSection.hh"
 55 #include "G4PhysicsFreeVector.hh"                  53 #include "G4PhysicsFreeVector.hh"
 56 #include "G4PhysicsLogVector.hh"               <<  54 #include "G4PhysicsLogVector.hh" 
 57 #include "G4PhysicsTable.hh"                       55 #include "G4PhysicsTable.hh"
 58 #include "G4Exp.hh"                            << 
 59                                                    56 
 60 //....oooOO0OOooo........oooOO0OOooo........oo     57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 61 namespace { G4Mutex  PenelopeBremsstrahlungMod <<  58  
 62                                                <<  59 G4PenelopeBremsstrahlungModel::G4PenelopeBremsstrahlungModel(const G4ParticleDefinition*,
 63 G4PenelopeBremsstrahlungModel::G4PenelopeBrems << 
 64                    const G4String& nam)            60                    const G4String& nam)
 65   :G4VEmModel(nam),fParticleChange(nullptr),fP <<  61   :G4VEmModel(nam),fParticleChange(0),isInitialised(false),energyGrid(0),  
 66    fPenelopeFSHelper(nullptr),fPenelopeAngular <<  62    XSTableElectron(0),XSTablePositron(0)
 67    fXSTableElectron(nullptr),fXSTablePositron( <<  63   
 68    fIsInitialised(false),fLocalTable(false)    << 
 69                                                << 
 70 {                                                  64 {
 71   fIntrinsicLowEnergyLimit = 100.0*eV;             65   fIntrinsicLowEnergyLimit = 100.0*eV;
 72   fIntrinsicHighEnergyLimit = 100.0*GeV;           66   fIntrinsicHighEnergyLimit = 100.0*GeV;
 73   nBins = 200;                                     67   nBins = 200;
 74                                                    68 
 75   if (part)                                    << 
 76     SetParticle(part);                         << 
 77                                                << 
 78   SetHighEnergyLimit(fIntrinsicHighEnergyLimit     69   SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
 79   //                                               70   //
 80   fOscManager = G4PenelopeOscillatorManager::G <<  71   oscManager = G4PenelopeOscillatorManager::GetOscillatorManager();
 81   //                                               72   //
 82   fVerboseLevel= 0;                            <<  73   verboseLevel= 0;
                                                   >>  74    
 83   // Verbosity scale:                              75   // Verbosity scale:
 84   // 0 = nothing                                   76   // 0 = nothing
 85   // 1 = warning for energy non-conservation       77   // 1 = warning for energy non-conservation
 86   // 2 = details of energy budget                  78   // 2 = details of energy budget
 87   // 3 = calculation of cross sections, file o     79   // 3 = calculation of cross sections, file openings, sampling of atoms
 88   // 4 = entering in methods                       80   // 4 = entering in methods
 89                                                    81 
                                                   >>  82   fPenelopeFSHelper = new G4PenelopeBremsstrahlungFS();
                                                   >>  83   fPenelopeAngular = new G4PenelopeBremsstrahlungAngular();
                                                   >>  84 
 90   // Atomic deexcitation model activated by de     85   // Atomic deexcitation model activated by default
 91   SetDeexcitationFlag(true);                       86   SetDeexcitationFlag(true);
 92                                                    87 
 93 }                                                  88 }
 94                                                    89 
 95 //....oooOO0OOooo........oooOO0OOooo........oo     90 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 96                                                <<  91  
 97 G4PenelopeBremsstrahlungModel::~G4PenelopeBrem     92 G4PenelopeBremsstrahlungModel::~G4PenelopeBremsstrahlungModel()
 98 {                                                  93 {
 99   if (IsMaster() || fLocalTable)               <<  94   ClearTables();
100     {                                          <<  95   if (fPenelopeFSHelper)
101       ClearTables();                           <<  96     delete fPenelopeFSHelper;
102       if (fPenelopeFSHelper)                   << 
103   delete fPenelopeFSHelper;                    << 
104     }                                          << 
105   // This is thread-local at the moment        << 
106   if (fPenelopeAngular)                            97   if (fPenelopeAngular)
107     delete fPenelopeAngular;                       98     delete fPenelopeAngular;
108 }                                                  99 }
109                                                   100 
110 //....oooOO0OOooo........oooOO0OOooo........oo    101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
111                                                   102 
112 void G4PenelopeBremsstrahlungModel::Initialise << 103 void G4PenelopeBremsstrahlungModel::Initialise(const G4ParticleDefinition*,
113                                              c << 104                                              const G4DataVector&)
114 {                                                 105 {
115   if (fVerboseLevel > 3)                       << 106   if (verboseLevel > 3)
116     G4cout << "Calling G4PenelopeBremsstrahlun    107     G4cout << "Calling G4PenelopeBremsstrahlungModel::Initialise()" << G4endl;
                                                   >> 108  
                                                   >> 109   //Clear and re-build the tables 
                                                   >> 110   ClearTables();
                                                   >> 111   
                                                   >> 112   //forces the cleaning of tables, in this specific case
                                                   >> 113   if (fPenelopeAngular)
                                                   >> 114     fPenelopeAngular->Initialize();
                                                   >> 115     
117                                                   116 
118   SetParticle(part);                           << 117   //Set the number of bins for the tables. 20 points per decade
119                                                << 118   nBins = (size_t) (20*std::log10(HighEnergyLimit()/LowEnergyLimit()));
120   if (IsMaster() && part == fParticle)         << 119   nBins = std::max(nBins,(size_t)100);
121     {                                          << 120   energyGrid = new G4PhysicsLogVector(LowEnergyLimit(),
122       if (!fPenelopeFSHelper)                  << 121                                       HighEnergyLimit(), 
123   fPenelopeFSHelper = new G4PenelopeBremsstrah << 
124       if (!fPenelopeAngular)                   << 
125   fPenelopeAngular = new G4PenelopeBremsstrahl << 
126       //Clear and re-build the tables          << 
127       ClearTables();                           << 
128                                                << 
129       //forces the cleaning of tables, in this << 
130       if (fPenelopeAngular)                    << 
131   fPenelopeAngular->Initialize();              << 
132                                                << 
133       //Set the number of bins for the tables. << 
134       nBins = (std::size_t) (20*std::log10(Hig << 
135       nBins = std::max(nBins,(std::size_t)100) << 
136       fEnergyGrid = new G4PhysicsLogVector(Low << 
137                                       HighEner << 
138                                       nBins-1)    122                                       nBins-1); //one hidden bin is added
                                                   >> 123  
139                                                   124 
140       fXSTableElectron = new                   << 125   XSTableElectron = new 
141   std::map< std::pair<const G4Material*,G4doub << 126     std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>;
142       fXSTablePositron = new                   << 127   XSTablePositron = new 
143   std::map< std::pair<const G4Material*,G4doub << 128     std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>;
144                                                << 129 
145       G4ProductionCutsTable* theCoupleTable =  << 130   if (verboseLevel > 2) {
146   G4ProductionCutsTable::GetProductionCutsTabl << 131     G4cout << "Penelope Bremsstrahlung model v2008 is initialized " << G4endl
147                                                << 132            << "Energy range: "
148       //Build tables for all materials         << 133            << LowEnergyLimit() / keV << " keV - "
149       for (G4int i=0;i<(G4int)theCoupleTable-> << 134            << HighEnergyLimit() / GeV << " GeV." 
150   {                                            << 135            << G4endl;
151     const G4Material* theMat =                 << 136   }
152       theCoupleTable->GetMaterialCutsCouple(i) << 137  
153     //Forces the building of the helper tables << 138   if(isInitialised) return;
154     fPenelopeFSHelper->BuildScaledXSTable(theM << 
155     fPenelopeAngular->PrepareTables(theMat,IsM << 
156     BuildXSTable(theMat,theCuts.at(i));        << 
157                                                << 
158   }                                            << 
159                                                << 
160       if (fVerboseLevel > 2) {                 << 
161   G4cout << "Penelope Bremsstrahlung model v20 << 
162          << "Energy range: "                   << 
163          << LowEnergyLimit() / keV << " keV -  << 
164          << HighEnergyLimit() / GeV << " GeV." << 
165          << G4endl;                            << 
166       }                                        << 
167     }                                          << 
168                                                << 
169   if(fIsInitialised) return;                   << 
170   fParticleChange = GetParticleChangeForLoss()    139   fParticleChange = GetParticleChangeForLoss();
171   fIsInitialised = true;                       << 140   isInitialised = true;
172 }                                              << 
173                                                << 
174 //....oooOO0OOooo........oooOO0OOooo........oo << 
175                                                << 
176 void G4PenelopeBremsstrahlungModel::Initialise << 
177                 G4VEmModel *masterModel)       << 
178 {                                              << 
179   if (fVerboseLevel > 3)                       << 
180     G4cout << "Calling  G4PenelopeBremsstrahlu << 
181   //                                           << 
182   //Check that particle matches: one might hav << 
183   //for e+ and e-).                            << 
184   //                                           << 
185   if (part == fParticle)                       << 
186     {                                          << 
187       //Get the const table pointers from the  << 
188       const G4PenelopeBremsstrahlungModel* the << 
189   static_cast<G4PenelopeBremsstrahlungModel*>  << 
190                                                << 
191       //Copy pointers to the data tables       << 
192       fEnergyGrid = theModel->fEnergyGrid;     << 
193       fXSTableElectron = theModel->fXSTableEle << 
194       fXSTablePositron = theModel->fXSTablePos << 
195       fPenelopeFSHelper = theModel->fPenelopeF << 
196                                                << 
197       //created in each thread and initialized << 
198       if (!fPenelopeAngular)                   << 
199   fPenelopeAngular = new G4PenelopeBremsstrahl << 
200       //forces the cleaning of tables, in this << 
201       if (fPenelopeAngular)                    << 
202   fPenelopeAngular->Initialize();              << 
203                                                << 
204       G4ProductionCutsTable* theCoupleTable =  << 
205   G4ProductionCutsTable::GetProductionCutsTabl << 
206       //Build tables for all materials         << 
207       for (G4int i=0;i<(G4int)theCoupleTable-> << 
208   {                                            << 
209     const G4Material* theMat =                 << 
210       theCoupleTable->GetMaterialCutsCouple(i) << 
211     fPenelopeAngular->PrepareTables(theMat,IsM << 
212   }                                            << 
213                                                << 
214       //copy the data                          << 
215       nBins = theModel->nBins;                 << 
216                                                << 
217       //Same verbosity for all workers, as the << 
218       fVerboseLevel = theModel->fVerboseLevel; << 
219     }                                          << 
220   return;                                      << 
221 }                                                 141 }
222                                                   142 
223 //....oooOO0OOooo........oooOO0OOooo........oo    143 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
224                                                   144 
225 G4double G4PenelopeBremsstrahlungModel::CrossS    145 G4double G4PenelopeBremsstrahlungModel::CrossSectionPerVolume(const G4Material* material,
226                                            con    146                                            const G4ParticleDefinition* theParticle,
227                                            G4d    147                                            G4double energy,
228                                            G4d    148                                            G4double cutEnergy,
229                                            G4d    149                                            G4double)
230 {                                                 150 {
231   //                                              151   //
232   if (fVerboseLevel > 3)                       << 152   if (verboseLevel > 3)
233     G4cout << "Calling CrossSectionPerVolume()    153     G4cout << "Calling CrossSectionPerVolume() of G4PenelopeBremsstrahlungModel" << G4endl;
234                                                << 154  
235   SetupForMaterial(theParticle, material, ener    155   SetupForMaterial(theParticle, material, energy);
                                                   >> 156 
236   G4double crossPerMolecule = 0.;                 157   G4double crossPerMolecule = 0.;
237                                                   158 
238   G4PenelopeCrossSection* theXS = GetCrossSect    159   G4PenelopeCrossSection* theXS = GetCrossSectionTableForCouple(theParticle,material,
239                                                   160                                                                 cutEnergy);
                                                   >> 161 
240   if (theXS)                                      162   if (theXS)
241     crossPerMolecule = theXS->GetHardCrossSect    163     crossPerMolecule = theXS->GetHardCrossSection(energy);
242                                                   164 
243   G4double atomDensity = material->GetTotNbOfA    165   G4double atomDensity = material->GetTotNbOfAtomsPerVolume();
244   G4double atPerMol =  fOscManager->GetAtomsPe << 166   G4double atPerMol =  oscManager->GetAtomsPerMolecule(material);
245                                                << 167  
246   if (fVerboseLevel > 3)                       << 168   if (verboseLevel > 3)
247     G4cout << "Material " << material->GetName    169     G4cout << "Material " << material->GetName() << " has " << atPerMol <<
248       "atoms per molecule" << G4endl;             170       "atoms per molecule" << G4endl;
249                                                   171 
250   G4double moleculeDensity = 0.;               << 172   G4double moleculeDensity = 0.; 
251   if (atPerMol)                                   173   if (atPerMol)
252     moleculeDensity = atomDensity/atPerMol;       174     moleculeDensity = atomDensity/atPerMol;
253                                                << 175  
254   G4double crossPerVolume = crossPerMolecule*m    176   G4double crossPerVolume = crossPerMolecule*moleculeDensity;
255                                                   177 
256   if (fVerboseLevel > 2)                       << 178   if (verboseLevel > 2)
257   {                                               179   {
258     G4cout << "G4PenelopeBremsstrahlungModel "    180     G4cout << "G4PenelopeBremsstrahlungModel " << G4endl;
259     G4cout << "Mean free path for gamma emissi    181     G4cout << "Mean free path for gamma emission > " << cutEnergy/keV << " keV at " <<
260       energy/keV << " keV = " << (1./crossPerV    182       energy/keV << " keV = " << (1./crossPerVolume)/mm << " mm" << G4endl;
261   }                                               183   }
262                                                << 184   
263   return crossPerVolume;                          185   return crossPerVolume;
264 }                                                 186 }
265                                                   187 
266 //....oooOO0OOooo........oooOO0OOooo........oo    188 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
267                                                << 189                                                                                                      
268 //This is a dummy method. Never inkoved by the    190 //This is a dummy method. Never inkoved by the tracking, it just issues
269 //a warning if one tries to get Cross Sections    191 //a warning if one tries to get Cross Sections per Atom via the
270 //G4EmCalculator.                                 192 //G4EmCalculator.
271 G4double G4PenelopeBremsstrahlungModel::Comput    193 G4double G4PenelopeBremsstrahlungModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
272                      G4double,                    194                      G4double,
273                      G4double,                    195                      G4double,
274                      G4double,                    196                      G4double,
275                      G4double,                    197                      G4double,
276                      G4double)                    198                      G4double)
277 {                                                 199 {
278   G4cout << "*** G4PenelopeBremsstrahlungModel    200   G4cout << "*** G4PenelopeBremsstrahlungModel -- WARNING ***" << G4endl;
279   G4cout << "Penelope Bremsstrahlung model v20    201   G4cout << "Penelope Bremsstrahlung model v2008 does not calculate cross section _per atom_ " << G4endl;
280   G4cout << "so the result is always zero. For    202   G4cout << "so the result is always zero. For physics values, please invoke " << G4endl;
281   G4cout << "GetCrossSectionPerVolume() or Get    203   G4cout << "GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" << G4endl;
282   return 0;                                       204   return 0;
283 }                                                 205 }
284                                                   206 
285 //....oooOO0OOooo........oooOO0OOooo........oo    207 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
286                                                   208 
287 G4double G4PenelopeBremsstrahlungModel::Comput    209 G4double G4PenelopeBremsstrahlungModel::ComputeDEDXPerVolume(const G4Material* material,
288                    const G4ParticleDefinition*    210                    const G4ParticleDefinition* theParticle,
289                    G4double kineticEnergy,        211                    G4double kineticEnergy,
290                    G4double cutEnergy)            212                    G4double cutEnergy)
291 {                                                 213 {
292   if (fVerboseLevel > 3)                       << 214   if (verboseLevel > 3)
293     G4cout << "Calling ComputeDEDX() of G4Pene    215     G4cout << "Calling ComputeDEDX() of G4PenelopeBremsstrahlungModel" << G4endl;
294                                                << 216  
295   G4PenelopeCrossSection* theXS = GetCrossSect    217   G4PenelopeCrossSection* theXS = GetCrossSectionTableForCouple(theParticle,material,
296                                                   218                                                                 cutEnergy);
297   G4double sPowerPerMolecule = 0.0;               219   G4double sPowerPerMolecule = 0.0;
298   if (theXS)                                      220   if (theXS)
299     sPowerPerMolecule = theXS->GetSoftStopping    221     sPowerPerMolecule = theXS->GetSoftStoppingPower(kineticEnergy);
300                                                   222 
                                                   >> 223   
301   G4double atomDensity = material->GetTotNbOfA    224   G4double atomDensity = material->GetTotNbOfAtomsPerVolume();
302   G4double atPerMol =  fOscManager->GetAtomsPe << 225   G4double atPerMol =  oscManager->GetAtomsPerMolecule(material);
303                                                << 226                                                                                         
304   G4double moleculeDensity = 0.;               << 227   G4double moleculeDensity = 0.; 
305   if (atPerMol)                                   228   if (atPerMol)
306     moleculeDensity = atomDensity/atPerMol;       229     moleculeDensity = atomDensity/atPerMol;
307                                                << 230  
308   G4double sPowerPerVolume = sPowerPerMolecule    231   G4double sPowerPerVolume = sPowerPerMolecule*moleculeDensity;
309                                                   232 
310   if (fVerboseLevel > 2)                       << 233   if (verboseLevel > 2)
311     {                                             234     {
312       G4cout << "G4PenelopeBremsstrahlungModel    235       G4cout << "G4PenelopeBremsstrahlungModel " << G4endl;
313       G4cout << "Stopping power < " << cutEner    236       G4cout << "Stopping power < " << cutEnergy/keV << " keV at " <<
314         kineticEnergy/keV << " keV = " <<      << 237         kineticEnergy/keV << " keV = " << 
315         sPowerPerVolume/(keV/mm) << " keV/mm"     238         sPowerPerVolume/(keV/mm) << " keV/mm" << G4endl;
316     }                                             239     }
317   return sPowerPerVolume;                         240   return sPowerPerVolume;
318 }                                                 241 }
319                                                   242 
320 //....oooOO0OOooo........oooOO0OOooo........oo    243 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
321                                                   244 
322 void G4PenelopeBremsstrahlungModel::SampleSeco    245 void G4PenelopeBremsstrahlungModel::SampleSecondaries(std::vector<G4DynamicParticle*>*fvect,
323                   const G4MaterialCutsCouple*     246                   const G4MaterialCutsCouple* couple,
324                   const G4DynamicParticle* aDy    247                   const G4DynamicParticle* aDynamicParticle,
325                   G4double cutG,                  248                   G4double cutG,
326                   G4double)                       249                   G4double)
327 {                                                 250 {
328   if (fVerboseLevel > 3)                       << 251   if (verboseLevel > 3)
329     G4cout << "Calling SampleSecondaries() of     252     G4cout << "Calling SampleSecondaries() of G4PenelopeBremsstrahlungModel" << G4endl;
330                                                   253 
331   G4double kineticEnergy = aDynamicParticle->G    254   G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
332   const G4Material* material = couple->GetMate    255   const G4Material* material = couple->GetMaterial();
333                                                   256 
334   if (kineticEnergy <= fIntrinsicLowEnergyLimi    257   if (kineticEnergy <= fIntrinsicLowEnergyLimit)
335    {                                              258    {
336      fParticleChange->SetProposedKineticEnergy    259      fParticleChange->SetProposedKineticEnergy(0.);
337      fParticleChange->ProposeLocalEnergyDeposi    260      fParticleChange->ProposeLocalEnergyDeposit(kineticEnergy);
338      return ;                                     261      return ;
339    }                                              262    }
340                                                   263 
341   G4ParticleMomentum particleDirection0 = aDyn    264   G4ParticleMomentum particleDirection0 = aDynamicParticle->GetMomentumDirection();
342   //This is the momentum                          265   //This is the momentum
343   G4ThreeVector initialMomentum =  aDynamicPar    266   G4ThreeVector initialMomentum =  aDynamicParticle->GetMomentum();
344                                                   267 
345   //Not enough energy to produce a secondary!     268   //Not enough energy to produce a secondary! Return with nothing happened
346   if (kineticEnergy < cutG)                       269   if (kineticEnergy < cutG)
347     return;                                       270     return;
348                                                   271 
349   if (fVerboseLevel > 3)                       << 272   if (verboseLevel > 3)
350     G4cout << "Going to sample gamma energy fo << 273     G4cout << "Going to sample gamma energy for: " <<material->GetName() << " " << 
351       "energy = " << kineticEnergy/keV << ", c    274       "energy = " << kineticEnergy/keV << ", cut = " << cutG/keV << G4endl;
352                                                   275 
353    //Sample gamma's energy according to the sp    276    //Sample gamma's energy according to the spectrum
354   G4double gammaEnergy =                       << 277   G4double gammaEnergy = 
355     fPenelopeFSHelper->SampleGammaEnergy(kinet    278     fPenelopeFSHelper->SampleGammaEnergy(kineticEnergy,material,cutG);
356                                                   279 
357   if (fVerboseLevel > 3)                       << 280   if (verboseLevel > 3)
358     G4cout << "Sampled gamma energy: " << gamm    281     G4cout << "Sampled gamma energy: " << gammaEnergy/keV << " keV" << G4endl;
359                                                << 282   
360   //Now sample the direction for the Gamma. No    283   //Now sample the direction for the Gamma. Notice that the rotation is already done
361   //Z is unused here, I plug 0. The informatio    284   //Z is unused here, I plug 0. The information is in the material pointer
362    G4ThreeVector gammaDirection1 =             << 285    G4ThreeVector gammaDirection1 = 
363      fPenelopeAngular->SampleDirection(aDynami    286      fPenelopeAngular->SampleDirection(aDynamicParticle,gammaEnergy,0,material);
364                                                << 287   
365   if (fVerboseLevel > 3)                       << 288   if (verboseLevel > 3)
366     G4cout << "Sampled cosTheta for e-: " << g    289     G4cout << "Sampled cosTheta for e-: " << gammaDirection1.cosTheta() << G4endl;
367                                                   290 
368   G4double residualPrimaryEnergy = kineticEner    291   G4double residualPrimaryEnergy = kineticEnergy-gammaEnergy;
369   if (residualPrimaryEnergy < 0)                  292   if (residualPrimaryEnergy < 0)
370     {                                             293     {
371       //Ok we have a problem, all energy goes     294       //Ok we have a problem, all energy goes with the gamma
372       gammaEnergy += residualPrimaryEnergy;       295       gammaEnergy += residualPrimaryEnergy;
373       residualPrimaryEnergy = 0.0;                296       residualPrimaryEnergy = 0.0;
374     }                                             297     }
375                                                << 298   
376   //Produce final state according to momentum     299   //Produce final state according to momentum conservation
377   G4ThreeVector particleDirection1 = initialMo    300   G4ThreeVector particleDirection1 = initialMomentum - gammaEnergy*gammaDirection1;
378   particleDirection1 = particleDirection1.unit    301   particleDirection1 = particleDirection1.unit(); //normalize
379                                                   302 
380   //Update the primary particle                   303   //Update the primary particle
381   if (residualPrimaryEnergy > 0.)                 304   if (residualPrimaryEnergy > 0.)
382     {                                             305     {
383       fParticleChange->ProposeMomentumDirectio    306       fParticleChange->ProposeMomentumDirection(particleDirection1);
384       fParticleChange->SetProposedKineticEnerg    307       fParticleChange->SetProposedKineticEnergy(residualPrimaryEnergy);
385     }                                             308     }
386   else                                            309   else
387     {                                             310     {
388       fParticleChange->SetProposedKineticEnerg    311       fParticleChange->SetProposedKineticEnergy(0.);
389     }                                             312     }
390                                                << 313   
391   //Now produce the photon                        314   //Now produce the photon
392   G4DynamicParticle* theGamma = new G4DynamicP    315   G4DynamicParticle* theGamma = new G4DynamicParticle(G4Gamma::Gamma(),
393                                                   316                                                       gammaDirection1,
394                                                   317                                                       gammaEnergy);
395   fvect->push_back(theGamma);                     318   fvect->push_back(theGamma);
396                                                << 319   
397   if (fVerboseLevel > 1)                       << 320   if (verboseLevel > 1)
398     {                                             321     {
399       G4cout << "-----------------------------    322       G4cout << "-----------------------------------------------------------" << G4endl;
400       G4cout << "Energy balance from G4Penelop    323       G4cout << "Energy balance from G4PenelopeBremsstrahlung" << G4endl;
401       G4cout << "Incoming primary energy: " <<    324       G4cout << "Incoming primary energy: " << kineticEnergy/keV << " keV" << G4endl;
402       G4cout << "-----------------------------    325       G4cout << "-----------------------------------------------------------" << G4endl;
403       G4cout << "Outgoing primary energy: " <<    326       G4cout << "Outgoing primary energy: " << residualPrimaryEnergy/keV << " keV" << G4endl;
404       G4cout << "Bremsstrahlung photon " << ga    327       G4cout << "Bremsstrahlung photon " << gammaEnergy/keV << " keV" << G4endl;
405       G4cout << "Total final state: " << (resi << 328       G4cout << "Total final state: " << (residualPrimaryEnergy+gammaEnergy)/keV 
406              << " keV" << G4endl;                 329              << " keV" << G4endl;
407       G4cout << "-----------------------------    330       G4cout << "-----------------------------------------------------------" << G4endl;
408     }                                             331     }
409                                                   332 
410   if (fVerboseLevel > 0)                       << 333   if (verboseLevel > 0)
411     {                                             334     {
412       G4double energyDiff = std::fabs(residual    335       G4double energyDiff = std::fabs(residualPrimaryEnergy+gammaEnergy-kineticEnergy);
413       if (energyDiff > 0.05*keV)                  336       if (energyDiff > 0.05*keV)
414         G4cout << "Warning from G4PenelopeBrem << 337         G4cout << "Warning from G4PenelopeBremsstrahlung: problem with energy conservation: " 
415          <<                                       338          <<
416           (residualPrimaryEnergy+gammaEnergy)/    339           (residualPrimaryEnergy+gammaEnergy)/keV <<
417           " keV (final) vs. " <<                  340           " keV (final) vs. " <<
418           kineticEnergy/keV << " keV (initial)    341           kineticEnergy/keV << " keV (initial)" << G4endl;
419     }                                          << 342     }  
420   return;                                         343   return;
421 }                                                 344 }
422                                                   345 
423 //....oooOO0OOooo........oooOO0OOooo........oo    346 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
424                                                   347 
425 void G4PenelopeBremsstrahlungModel::ClearTable    348 void G4PenelopeBremsstrahlungModel::ClearTables()
426 {                                              << 349 {  
427   if (!IsMaster() && !fLocalTable)             << 350   std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>::iterator i;
428     //Should not be here!                      << 351   if (XSTableElectron)
429     G4Exception("G4PenelopeBremsstrahlungModel << 352     {
430     "em0100",FatalException,"Worker thread in  << 353       for (i=XSTableElectron->begin(); i != XSTableElectron->end(); i++)
431                                                << 354         {
432   if (fXSTableElectron)                        << 355           G4PenelopeCrossSection* tab = i->second;
433     {                                          << 356           delete tab;
434       for (auto& item : (*fXSTableElectron))   << 357         }
435   delete item.second;                          << 358       delete XSTableElectron;
436       delete fXSTableElectron;                 << 359       XSTableElectron = 0;
437       fXSTableElectron = nullptr;              << 360     }
438     }                                          << 361   if (XSTablePositron)
439   if (fXSTablePositron)                        << 362     {
440     {                                          << 363       for (i=XSTablePositron->begin(); i != XSTablePositron->end(); i++)
441       for (auto& item : (*fXSTablePositron))   << 364         {
442   delete item.second;                          << 365           G4PenelopeCrossSection* tab = i->second;
443       delete fXSTablePositron;                 << 366           delete tab;
444       fXSTablePositron = nullptr;              << 367         }
445     }                                          << 368       delete XSTablePositron;
446   /*                                           << 369       XSTablePositron = 0;
447   if (fEnergyGrid)                             << 370     } 
448     delete fEnergyGrid;                        << 371 
449   */                                           << 372   if (energyGrid)
                                                   >> 373     delete energyGrid;
                                                   >> 374 
450   if (fPenelopeFSHelper)                          375   if (fPenelopeFSHelper)
451     fPenelopeFSHelper->ClearTables(IsMaster()) << 376     fPenelopeFSHelper->ClearTables(); 
452                                                   377 
453   if (fVerboseLevel > 2)                       << 378   if (verboseLevel > 2)
454     G4cout << "G4PenelopeBremsstrahlungModel:     379     G4cout << "G4PenelopeBremsstrahlungModel: cleared tables" << G4endl;
455                                                   380 
456  return;                                          381  return;
457 }                                                 382 }
458                                                   383 
459 //....oooOO0OOooo........oooOO0OOooo........oo    384 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
460                                                   385 
461 G4double G4PenelopeBremsstrahlungModel::MinEne    386 G4double G4PenelopeBremsstrahlungModel::MinEnergyCut(const G4ParticleDefinition*,
462                    const G4MaterialCutsCouple*    387                    const G4MaterialCutsCouple*)
463 {                                                 388 {
464   return fIntrinsicLowEnergyLimit;                389   return fIntrinsicLowEnergyLimit;
465 }                                                 390 }
466                                                   391 
467 //....oooOO0OOooo........oooOO0OOooo........oo    392 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
468                                                   393 
469 void G4PenelopeBremsstrahlungModel::BuildXSTab    394 void G4PenelopeBremsstrahlungModel::BuildXSTable(const G4Material* mat,G4double cut)
470 {                                                 395 {
471   if (!IsMaster() && !fLocalTable)             << 396 //
472     //Should not be here!                      << 
473     G4Exception("G4PenelopeBremsstrahlungModel << 
474     "em0100",FatalException,"Worker thread in  << 
475                                                << 
476   //The key of the map                         << 
477   std::pair<const G4Material*,G4double> theKey << 
478                                                << 
479   //The table already exists                   << 
480   if (fXSTableElectron->count(theKey) && fXSTa << 
481     return;                                    << 
482                                                << 
483   //                                           << 
484   //This method fills the G4PenelopeCrossSecti    397   //This method fills the G4PenelopeCrossSection containers for electrons or positrons
485   //and for the given material/cut couple.     << 398   //and for the given material/cut couple. 
486   //Equivalent of subroutines EBRaT and PINaT     399   //Equivalent of subroutines EBRaT and PINaT of Penelope
487   //                                              400   //
488   if (fVerboseLevel > 2)                       << 401   if (verboseLevel > 2)
489     {                                             402     {
490       G4cout << "G4PenelopeBremsstrahlungModel    403       G4cout << "G4PenelopeBremsstrahlungModel: going to build cross section table " << G4endl;
491       G4cout << "for e+/e- in " << mat->GetNam << 404       G4cout << "for e+/e- in " << mat->GetName() << G4endl;
492   cut/keV << " keV " << G4endl;                << 
493     }                                             405     }
494                                                   406 
495   //Tables have been already created (checked     407   //Tables have been already created (checked by GetCrossSectionTableForCouple)
496   if (fEnergyGrid->GetVectorLength() != nBins) << 408   if (energyGrid->GetVectorLength() != nBins) 
497     {                                             409     {
498       G4ExceptionDescription ed;                  410       G4ExceptionDescription ed;
499       ed << "Energy Grid looks not initialized    411       ed << "Energy Grid looks not initialized" << G4endl;
500       ed << nBins << " " << fEnergyGrid->GetVe << 412       ed << nBins << " " << energyGrid->GetVectorLength() << G4endl;
501       G4Exception("G4PenelopeBremsstrahlungMod    413       G4Exception("G4PenelopeBremsstrahlungModel::BuildXSTable()",
502       "em2016",FatalException,ed);                414       "em2016",FatalException,ed);
503     }                                             415     }
504                                                   416 
505   G4PenelopeCrossSection* XSEntry = new G4Pene    417   G4PenelopeCrossSection* XSEntry = new G4PenelopeCrossSection(nBins);
506   G4PenelopeCrossSection* XSEntry2 = new G4Pen    418   G4PenelopeCrossSection* XSEntry2 = new G4PenelopeCrossSection(nBins);
507   const G4PhysicsTable* table = fPenelopeFSHel << 
508                                                   419 
509   //loop on the energy grid                    << 420   G4PhysicsTable* table = fPenelopeFSHelper->GetScaledXSTable(mat,cut);
510   for (std::size_t bin=0;bin<nBins;++bin)      << 421 
                                                   >> 422 
                                                   >> 423   //loop on the energy grid  
                                                   >> 424   for (size_t bin=0;bin<nBins;bin++)
511     {                                             425     {
512        G4double energy = fEnergyGrid->GetLowEd << 426        G4double energy = energyGrid->GetLowEdgeEnergy(bin);
513        G4double XH0=0, XH1=0, XH2=0;              427        G4double XH0=0, XH1=0, XH2=0;
514        G4double XS0=0, XS1=0, XS2=0;              428        G4double XS0=0, XS1=0, XS2=0;
515                                                << 429     
516        //Global xs factor                         430        //Global xs factor
517        G4double fact = fPenelopeFSHelper->GetE    431        G4double fact = fPenelopeFSHelper->GetEffectiveZSquared(mat)*
518    ((energy+electron_mass_c2)*(energy+electron    432    ((energy+electron_mass_c2)*(energy+electron_mass_c2)/
519     (energy*(energy+2.0*electron_mass_c2)));   << 433     (energy*(energy+2.0*electron_mass_c2))); 
520                                                << 434        
521        G4double restrictedCut = cut/energy;       435        G4double restrictedCut = cut/energy;
522                                                << 436    
523        //Now I need the dSigma/dX profile - in << 437        //Now I need the dSigma/dX profile - interpolated on energy - for 
524        //the 32-point x grid. Interpolation is    438        //the 32-point x grid. Interpolation is log-log
525        std::size_t nBinsX = fPenelopeFSHelper- << 439        size_t nBinsX = fPenelopeFSHelper->GetNBinsX();       
526        G4double* tempData = new G4double[nBins << 440        G4double* tempData = new G4double[nBinsX];     
527        G4double logene = G4Log(energy);        << 441        G4double logene = std::log(energy);
528        for (std::size_t ix=0;ix<nBinsX;++ix)   << 442        for (size_t ix=0;ix<nBinsX;ix++) 
529    {                                              443    {
530      //find dSigma/dx for the given E. X belon    444      //find dSigma/dx for the given E. X belongs to the 32-point grid.
531      G4double val = (*table)[ix]->Value(logene << 445      G4double val = (*table)[ix]->Value(logene);     
532      tempData[ix] = G4Exp(val); //back to the  << 446      tempData[ix] = std::exp(val); //back to the real value!
533    }                                           << 447    } 
534                                                << 448        
535        G4double XH0A = 0.;                        449        G4double XH0A = 0.;
536        if (restrictedCut <= 1) //calculate onl    450        if (restrictedCut <= 1) //calculate only if we are above threshold!
537    XH0A = fPenelopeFSHelper->GetMomentumIntegr    451    XH0A = fPenelopeFSHelper->GetMomentumIntegral(tempData,1.0,-1) -
538      fPenelopeFSHelper->GetMomentumIntegral(te    452      fPenelopeFSHelper->GetMomentumIntegral(tempData,restrictedCut,-1);
539        G4double XS1A = fPenelopeFSHelper->GetM    453        G4double XS1A = fPenelopeFSHelper->GetMomentumIntegral(tempData,
540                     restrictedCut,0);          << 454                     restrictedCut,0);       
541        G4double XS2A = fPenelopeFSHelper->GetM    455        G4double XS2A = fPenelopeFSHelper->GetMomentumIntegral(tempData,
542                     restrictedCut,1);             456                     restrictedCut,1);
543        G4double XH1A=0, XH2A=0;                   457        G4double XH1A=0, XH2A=0;
544        if (restrictedCut <=1)                     458        if (restrictedCut <=1)
545    {                                              459    {
546      XH1A = fPenelopeFSHelper->GetMomentumInte    460      XH1A = fPenelopeFSHelper->GetMomentumIntegral(tempData,1.0,0) -
547        XS1A;                                      461        XS1A;
548      XH2A = fPenelopeFSHelper->GetMomentumInte    462      XH2A = fPenelopeFSHelper->GetMomentumIntegral(tempData,1.0,1) -
549        XS2A;                                      463        XS2A;
550    }                                              464    }
551        delete[] tempData;                         465        delete[] tempData;
552                                                   466 
553        XH0 = XH0A*fact;                           467        XH0 = XH0A*fact;
554        XS1 = XS1A*fact*energy;                    468        XS1 = XS1A*fact*energy;
555        XH1 = XH1A*fact*energy;                    469        XH1 = XH1A*fact*energy;
556        XS2 = XS2A*fact*energy*energy;             470        XS2 = XS2A*fact*energy*energy;
557        XH2 = XH2A*fact*energy*energy;             471        XH2 = XH2A*fact*energy*energy;
558                                                   472 
559        XSEntry->AddCrossSectionPoint(bin,energ    473        XSEntry->AddCrossSectionPoint(bin,energy,XH0,XH1,XH2,XS0,XS1,XS2);
560                                                   474 
561        //take care of positrons                   475        //take care of positrons
562        G4double posCorrection = GetPositronXSC    476        G4double posCorrection = GetPositronXSCorrection(mat,energy);
563        XSEntry2->AddCrossSectionPoint(bin,ener    477        XSEntry2->AddCrossSectionPoint(bin,energy,XH0*posCorrection,
564               XH1*posCorrection,                  478               XH1*posCorrection,
565               XH2*posCorrection,                  479               XH2*posCorrection,
566               XS0,                                480               XS0,
567               XS1*posCorrection,                  481               XS1*posCorrection,
568               XS2*posCorrection);                 482               XS2*posCorrection);
569     }                                             483     }
570                                                << 484  
571   //Insert in the appropriate table               485   //Insert in the appropriate table
572   fXSTableElectron->insert(std::make_pair(theK << 486   std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);  
573   fXSTablePositron->insert(std::make_pair(theK << 487   XSTableElectron->insert(std::make_pair(theKey,XSEntry));
574                                                << 488   XSTablePositron->insert(std::make_pair(theKey,XSEntry2));
                                                   >> 489   
575   return;                                         490   return;
576 }                                                 491 }
577                                                   492 
578                                                   493 
579 //....oooOO0OOooo........oooOO0OOooo........oo    494 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
580                                                   495 
581 G4PenelopeCrossSection*                        << 496 G4PenelopeCrossSection* 
582 G4PenelopeBremsstrahlungModel::GetCrossSection    497 G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple(const G4ParticleDefinition* part,
583                    const G4Material* mat,         498                    const G4Material* mat,
584                    G4double cut)                  499                    G4double cut)
585 {                                                 500 {
586   if (part != G4Electron::Electron() && part !    501   if (part != G4Electron::Electron() && part != G4Positron::Positron())
587     {                                             502     {
588       G4ExceptionDescription ed;                  503       G4ExceptionDescription ed;
589       ed << "Invalid particle: " << part->GetP    504       ed << "Invalid particle: " << part->GetParticleName() << G4endl;
590       G4Exception("G4PenelopeBremsstrahlungMod    505       G4Exception("G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
591       "em0001",FatalException,ed);                506       "em0001",FatalException,ed);
592       return nullptr;                          << 507       return NULL;
593     }                                             508     }
594                                                   509 
595   if (part == G4Electron::Electron())             510   if (part == G4Electron::Electron())
596     {                                             511     {
597       //Either Initialize() was not called, or << 512       if (!XSTableElectron)
598       //not invoked                            << 513         {   
599       if (!fXSTableElectron)                   << 
600         {                                      << 
601     //create a **thread-local** version of the << 
602     //Unit Tests                               << 
603           G4String excep = "The Cross Section     514           G4String excep = "The Cross Section Table for e- was not initialized correctly!";
604           G4Exception("G4PenelopeBremsstrahlun    515           G4Exception("G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
605           "em2013",JustWarning,excep);         << 516           "em2013",FatalException,excep);          
606     fLocalTable = true;                        << 517     return NULL;
607     fXSTableElectron = new                     << 
608       std::map< std::pair<const G4Material*,G4 << 
609     if (!fEnergyGrid)                          << 
610       fEnergyGrid = new G4PhysicsLogVector(Low << 
611             HighEnergyLimit(),                 << 
612             nBins-1); //one hidden bin is adde << 
613     if (!fPenelopeFSHelper)                    << 
614       fPenelopeFSHelper = new G4PenelopeBremss << 
615         }                                         518         }
616       std::pair<const G4Material*,G4double> th    519       std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
617       if (fXSTableElectron->count(theKey)) //t << 520       if (XSTableElectron->count(theKey)) //table already built
618         return fXSTableElectron->find(theKey)- << 521         return XSTableElectron->find(theKey)->second;
619       else                                        522       else
620   {                                            << 523         {
621     //If we are here, it means that Initialize << 524           BuildXSTable(mat,cut);
622     //not filled up. This can happen in a Unit << 525           if (XSTableElectron->count(theKey)) //now it should be ok!
623     if (fVerboseLevel > 0)                     << 526             return XSTableElectron->find(theKey)->second;
624       {                                        << 527           else
625         //G4Exception (warning) is issued only << 528             {
626         G4ExceptionDescription ed;                529         G4ExceptionDescription ed;
627         ed << "Unable to find e- table for " < << 530               ed << "Unable to build e- table for " << mat->GetName() << G4endl;
628      << cut/keV << " keV " << G4endl;          << 531               G4Exception("G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
629         ed << "This can happen only in Unit Te << 532         "em2009",FatalException,ed);
630         G4Exception("G4PenelopeBremsstrahlungM << 533             }
631         "em2009",JustWarning,ed);              << 534         }
632       }                                        << 
633     //protect file reading via autolock        << 
634     G4AutoLock lock(&PenelopeBremsstrahlungMod << 
635           fPenelopeFSHelper->BuildScaledXSTabl << 
636     BuildXSTable(mat,cut);                     << 
637     lock.unlock();                             << 
638     //now it should be ok                      << 
639     return fXSTableElectron->find(theKey)->sec << 
640   }                                            << 
641     }                                             535     }
642   if (part == G4Positron::Positron())             536   if (part == G4Positron::Positron())
643     {                                             537     {
644       //Either Initialize() was not called, or << 538       if (!XSTablePositron)
645       //not invoked                            << 
646       if (!fXSTablePositron)                   << 
647         {                                         539         {
648     G4String excep = "The Cross Section Table     540     G4String excep = "The Cross Section Table for e+ was not initialized correctly!";
649           G4Exception("G4PenelopeBremsstrahlun    541           G4Exception("G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
650           "em2013",JustWarning,excep);         << 542           "em2013",FatalException,excep); 
651     fLocalTable = true;                        << 543     return NULL;
652     fXSTablePositron = new                     << 
653       std::map< std::pair<const G4Material*,G4 << 
654     if (!fEnergyGrid)                          << 
655       fEnergyGrid = new G4PhysicsLogVector(Low << 
656             HighEnergyLimit(),                 << 
657             nBins-1); //one hidden bin is adde << 
658     if (!fPenelopeFSHelper)                    << 
659             fPenelopeFSHelper = new G4Penelope << 
660         }                                         544         }
661       std::pair<const G4Material*,G4double> th    545       std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
662       if (fXSTablePositron->count(theKey)) //t << 546       if (XSTablePositron->count(theKey)) //table already built
663         return fXSTablePositron->find(theKey)- << 547         return XSTablePositron->find(theKey)->second;
664       else                                        548       else
665         {                                         549         {
666     //If we are here, it means that Initialize << 550           BuildXSTable(mat,cut);
667     //not filled up. This can happen in a Unit << 551           if (XSTablePositron->count(theKey)) //now it should be ok!
668     if (fVerboseLevel > 0)                     << 552             return XSTablePositron->find(theKey)->second;
669       {                                        << 553           else
670         //Issue a G4Exception (warning) only i << 554             {
671         G4ExceptionDescription ed;                555         G4ExceptionDescription ed;
672         ed << "Unable to find e+ table for " < << 556               ed << "Unable to build e+ table for " << mat->GetName() << G4endl;
673      << cut/keV << " keV " << G4endl;          << 557               G4Exception("G4PenelopeBremsstrahlungModel::GetCrossSectionTableForCouple()",
674         ed << "This can happen only in Unit Te << 558         "em2009",FatalException,ed);
675         G4Exception("G4PenelopeBremsstrahlungM << 559             }
676         "em2009",JustWarning,ed);              << 
677       }                                        << 
678     //protect file reading via autolock        << 
679     G4AutoLock lock(&PenelopeBremsstrahlungMod << 
680           fPenelopeFSHelper->BuildScaledXSTabl << 
681     BuildXSTable(mat,cut);                     << 
682     lock.unlock();                             << 
683     //now it should be ok                      << 
684     return fXSTablePositron->find(theKey)->sec << 
685         }                                         560         }
686     }                                             561     }
687   return nullptr;                              << 562   return NULL;
688 }                                                 563 }
689                                                   564 
                                                   >> 565 
                                                   >> 566 
690 //....oooOO0OOooo........oooOO0OOooo........oo    567 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
691                                                   568 
692 G4double G4PenelopeBremsstrahlungModel::GetPos    569 G4double G4PenelopeBremsstrahlungModel::GetPositronXSCorrection(const G4Material* mat,
693                   G4double energy)                570                   G4double energy)
694 {                                                 571 {
695   //The electron-to-positron correction factor << 572   //The electron-to-positron correction factor is set equal to the ratio of the 
696   //radiative stopping powers for positrons an << 573   //radiative stopping powers for positrons and electrons, which has been calculated 
697   //by Kim et al. (1986) (cf. Berger and Seltz << 574   //by Kim et al. (1986) (cf. Berger and Seltzer, 1982). Here, it is used an 
698   //analytical approximation which reproduces  << 575   //analytical approximation which reproduces the tabulated values with 0.5% 
699   //accuracy                                      576   //accuracy
700   G4double t=G4Log(1.0+1e6*energy/             << 577   G4double t=std::log(1.0+1e6*energy/
701           (electron_mass_c2*fPenelopeFSHelper-    578           (electron_mass_c2*fPenelopeFSHelper->GetEffectiveZSquared(mat)));
702   G4double corr = 1.0-G4Exp(-t*(1.2359e-1-t*(6 << 579   G4double corr = 1.0-std::exp(-t*(1.2359e-1-t*(6.1274e-2-t*
703              (3.1516e-2-t*(7.7446e-3-t*(1.0595    580              (3.1516e-2-t*(7.7446e-3-t*(1.0595e-3-t*
704                       (7.0568e-5-t*               581                       (7.0568e-5-t*
705                        1.8080e-6)))))));          582                        1.8080e-6)))))));
706   return corr;                                    583   return corr;
707 }                                              << 
708                                                << 
709 //....oooOO0OOooo........oooOO0OOooo........oo << 
710                                                << 
711 void G4PenelopeBremsstrahlungModel::SetParticl << 
712 {                                              << 
713   if(!fParticle) {                             << 
714     fParticle = p;                             << 
715   }                                            << 
716 }                                                 584 }
717                                                   585