Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4PenelopeBremsstrahlungAngular.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/G4PenelopeBremsstrahlungAngular.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4PenelopeBremsstrahlungAngular.cc (Version 10.4.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
                                                   >>  26 // $Id: G4PenelopeBremsstrahlungAngular.cc 99415 2016-09-21 09:05:43Z gcosmo $
 26 //                                                 27 //
 27 // -------------------------------------------     28 // --------------------------------------------------------------
 28 //                                                 29 //
 29 // File name:     G4PenelopeBremsstrahlungAngu     30 // File name:     G4PenelopeBremsstrahlungAngular
 30 //                                                 31 //
 31 // Author:        Luciano Pandola                  32 // Author:        Luciano Pandola
 32 //                                                 33 //
 33 // Creation date: November 2010                    34 // Creation date: November 2010
 34 //                                                 35 //
 35 // History:                                        36 // History:
 36 // -----------                                     37 // -----------
 37 // 23 Nov 2010  L. Pandola       1st implement     38 // 23 Nov 2010  L. Pandola       1st implementation
 38 // 24 May 2011  L. Pandola       Renamed (make     39 // 24 May 2011  L. Pandola       Renamed (make v2008 as default Penelope)
 39 // 13 Mar 2012  L. Pandola       Made a derive     40 // 13 Mar 2012  L. Pandola       Made a derived class of G4VEmAngularDistribution
 40 //                               and update th     41 //                               and update the interface accordingly
 41 // 18 Jul 2012  L. Pandola       Migrated to t     42 // 18 Jul 2012  L. Pandola       Migrated to the new basic interface of G4VEmAngularDistribution
 42 //                               Now returns a     43 //                               Now returns a G4ThreeVector and takes care of the rotation
 43 // 03 Oct 2013  L. Pandola       Migrated to M     44 // 03 Oct 2013  L. Pandola       Migrated to MT: only the master model handles tables
 44 // 17 Oct 2013  L. Pandola       Partially rev     45 // 17 Oct 2013  L. Pandola       Partially revert MT migration. The angular generator is kept as
 45 //                                thread-local     46 //                                thread-local, and each worker has full access to it.
 46 //                                                 47 //
 47 //--------------------------------------------     48 //----------------------------------------------------------------
 48                                                    49 
 49 #include "G4PenelopeBremsstrahlungAngular.hh"      50 #include "G4PenelopeBremsstrahlungAngular.hh"
 50                                                    51 
 51 #include "globals.hh"                              52 #include "globals.hh"
 52 #include "G4PhysicalConstants.hh"                  53 #include "G4PhysicalConstants.hh"
 53 #include "G4SystemOfUnits.hh"                      54 #include "G4SystemOfUnits.hh"
 54 #include "G4PhysicsFreeVector.hh"                  55 #include "G4PhysicsFreeVector.hh"
 55 #include "G4PhysicsTable.hh"                       56 #include "G4PhysicsTable.hh"
 56 #include "G4Material.hh"                           57 #include "G4Material.hh"
 57 #include "Randomize.hh"                            58 #include "Randomize.hh"
 58 #include "G4Exp.hh"                                59 #include "G4Exp.hh"
 59                                                    60 
 60 G4PenelopeBremsstrahlungAngular::G4PenelopeBre     61 G4PenelopeBremsstrahlungAngular::G4PenelopeBremsstrahlungAngular() :
 61   G4VEmAngularDistribution("Penelope"), fEffec <<  62   G4VEmAngularDistribution("Penelope"), theEffectiveZSq(0),
 62   fLorentzTables1(nullptr),fLorentzTables2(nul <<  63   theLorentzTables1(0),theLorentzTables2(0)
 63                                                    64 
 64 {                                                  65 {
 65   fDataRead = false;                           <<  66   dataRead = false;
 66   fVerbosityLevel = 0;                         <<  67   verbosityLevel = 0;
 67 }                                                  68 }
 68                                                    69 
 69 //....oooOO0OOooo........oooOO0OOooo........oo     70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 70                                                    71 
 71 G4PenelopeBremsstrahlungAngular::~G4PenelopeBr     72 G4PenelopeBremsstrahlungAngular::~G4PenelopeBremsstrahlungAngular()
 72 {                                                  73 {
 73   ClearTables();                                   74   ClearTables();
 74 }                                                  75 }
 75                                                    76 
 76 //....oooOO0OOooo........oooOO0OOooo........oo     77 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 77                                                    78 
 78 void G4PenelopeBremsstrahlungAngular::Initiali     79 void G4PenelopeBremsstrahlungAngular::Initialize()
 79 {                                                  80 {
 80   ClearTables();                                   81   ClearTables();
 81 }                                                  82 }
 82                                                    83 
 83 //....oooOO0OOooo........oooOO0OOooo........oo     84 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 84                                                    85 
 85 void G4PenelopeBremsstrahlungAngular::ClearTab     86 void G4PenelopeBremsstrahlungAngular::ClearTables()
 86 {                                                  87 {
 87   if (fLorentzTables1)                         <<  88   if (theLorentzTables1)
 88     {                                              89     {
 89       for (auto j=fLorentzTables1->begin(); j  <<  90       for (auto j = theLorentzTables1->begin(); j != theLorentzTables1->end(); j++)
 90         {                                          91         {
 91     G4PhysicsTable* tab = j->second;               92     G4PhysicsTable* tab = j->second;
 92           tab->clearAndDestroy();              <<  93           //tab->clearAndDestroy();
 93           delete tab;                              94           delete tab;
 94         }                                          95         }
 95       fLorentzTables1->clear();                <<  96       delete theLorentzTables1;
 96       delete fLorentzTables1;                  <<  97       theLorentzTables1 = nullptr;
 97       fLorentzTables1 = nullptr;               << 
 98     }                                              98     }
 99                                                    99 
100   if (fLorentzTables2)                         << 100   if (theLorentzTables2)
101     {                                             101     {
102       for (auto j=fLorentzTables2->begin(); j  << 102       for (auto j=theLorentzTables2->begin(); j != theLorentzTables2->end(); j++)
103         {                                         103         {
104     G4PhysicsTable* tab = j->second;              104     G4PhysicsTable* tab = j->second;
105     tab->clearAndDestroy();                    << 105           //tab->clearAndDestroy();
106           delete tab;                             106           delete tab;
107         }                                         107         }
108       fLorentzTables2->clear();                << 108       delete theLorentzTables2;
109       delete fLorentzTables2;                  << 109       theLorentzTables2 = nullptr;
110       fLorentzTables2 = nullptr;               << 
111     }                                             110     }
112   if (fEffectiveZSq)                           << 111   if (theEffectiveZSq)
113     {                                             112     {
114       delete fEffectiveZSq;                    << 113       delete theEffectiveZSq;
115       fEffectiveZSq = nullptr;                 << 114       theEffectiveZSq = nullptr;
116     }                                             115     }
117 }                                                 116 }
118                                                   117 
119 //....oooOO0OOooo........oooOO0OOooo........oo    118 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
120                                                   119 
121 void G4PenelopeBremsstrahlungAngular::ReadData    120 void G4PenelopeBremsstrahlungAngular::ReadDataFile()
122 {                                                 121 {
123    //Read information from DataBase file          122    //Read information from DataBase file
124   const char* path = G4FindDataDir("G4LEDATA") << 123   char* path = getenv("G4LEDATA");
125   if (!path)                                      124   if (!path)
126     {                                             125     {
127       G4String excep =                            126       G4String excep =
128   "G4PenelopeBremsstrahlungAngular - G4LEDATA     127   "G4PenelopeBremsstrahlungAngular - G4LEDATA environment variable not set!";
129       G4Exception("G4PenelopeBremsstrahlungAng    128       G4Exception("G4PenelopeBremsstrahlungAngular::ReadDataFile()",
130       "em0006",FatalException,excep);             129       "em0006",FatalException,excep);
131       return;                                     130       return;
132     }                                             131     }
133   G4String pathString(path);                      132   G4String pathString(path);
134   G4String pathFile = pathString + "/penelope/    133   G4String pathFile = pathString + "/penelope/bremsstrahlung/pdbrang.p08";
135   std::ifstream file(pathFile);                   134   std::ifstream file(pathFile);
136                                                   135 
137   if (!file.is_open())                            136   if (!file.is_open())
138     {                                             137     {
139       G4String excep = "G4PenelopeBremsstrahlu    138       G4String excep = "G4PenelopeBremsstrahlungAngular - data file " + pathFile + " not found!";
140       G4Exception("G4PenelopeBremsstrahlungAng    139       G4Exception("G4PenelopeBremsstrahlungAngular::ReadDataFile()",
141       "em0003",FatalException,excep);             140       "em0003",FatalException,excep);
142       return;                                     141       return;
143     }                                             142     }
144   G4int i=0,j=0,k=0; // i=index for Z, j=index    143   G4int i=0,j=0,k=0; // i=index for Z, j=index for E, k=index for K
145                                                   144 
146   for (k=0;k<fNumberofKPoints;k++)             << 145   for (k=0;k<NumberofKPoints;k++)
147     for (i=0;i<fNumberofZPoints;i++)           << 146     for (i=0;i<NumberofZPoints;i++)
148       for (j=0;j<fNumberofEPoints;j++)         << 147       for (j=0;j<NumberofEPoints;j++)
149   {                                               148   {
150     G4double a1,a2;                               149     G4double a1,a2;
151     G4int ik1,iz1,ie1;                            150     G4int ik1,iz1,ie1;
152     G4double zr,er,kr;                            151     G4double zr,er,kr;
153     file >> iz1 >> ie1 >> ik1 >> zr >> er >> k    152     file >> iz1 >> ie1 >> ik1 >> zr >> er >> kr >> a1 >> a2;
154     //check the data are correct                  153     //check the data are correct
155     if ((iz1-1 == i) && (ik1-1 == k) && (ie1-1    154     if ((iz1-1 == i) && (ik1-1 == k) && (ie1-1 == j))
156       {                                           155       {
157         fQQ1[i][j][k]=a1;                      << 156         QQ1[i][j][k]=a1;
158         fQQ2[i][j][k]=a2;                      << 157         QQ2[i][j][k]=a2;
159       }                                           158       }
160     else                                          159     else
161       {                                           160       {
162         G4ExceptionDescription ed;                161         G4ExceptionDescription ed;
163         ed << "Corrupted data file " << pathFi    162         ed << "Corrupted data file " << pathFile << "?" << G4endl;
164         G4Exception("G4PenelopeBremsstrahlungA    163         G4Exception("G4PenelopeBremsstrahlungAngular::ReadDataFile()",
165       "em0005",FatalException,ed);                164       "em0005",FatalException,ed);
166       }                                           165       }
167   }                                               166   }
168   file.close();                                   167   file.close();
169   fDataRead = true;                            << 168   dataRead = true;
170 }                                                 169 }
171                                                   170 
172 //....oooOO0OOooo........oooOO0OOooo........oo    171 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
173                                                   172 
174 void G4PenelopeBremsstrahlungAngular::PrepareT    173 void G4PenelopeBremsstrahlungAngular::PrepareTables(const G4Material* material,G4bool /*isMaster*/ )
175 {                                                 174 {
176   //Unused at the moment: the G4PenelopeBremss    175   //Unused at the moment: the G4PenelopeBremsstrahlungAngular is thread-local, so each worker
177   //builds its own version of the tables.         176   //builds its own version of the tables.
178                                                << 177   /*
                                                   >> 178     if (!isMaster)
                                                   >> 179     //Should not be here!
                                                   >> 180     G4Exception("G4PenelopeBremsstrahlungAngular::PrepareTables()",
                                                   >> 181     "em0100",FatalException,"Worker thread in this method");
                                                   >> 182   */
                                                   >> 183 
179   //Check if data file has already been read      184   //Check if data file has already been read
180   if (!fDataRead)                              << 185   if (!dataRead)
181     {                                             186     {
182       ReadDataFile();                             187       ReadDataFile();
183       if (!fDataRead)                          << 188       if (!dataRead)
184   G4Exception("G4PenelopeBremsstrahlungAngular    189   G4Exception("G4PenelopeBremsstrahlungAngular::PrepareInterpolationTables()",
185         "em2001",FatalException,"Unable to bui    190         "em2001",FatalException,"Unable to build interpolation table");
186     }                                             191     }
187                                                   192 
188   if (!fLorentzTables1)                        << 193   if (!theLorentzTables1)
189       fLorentzTables1 = new std::map<G4double, << 194       theLorentzTables1 = new std::map<G4double,G4PhysicsTable*>;
190   if (!fLorentzTables2)                        << 195   if (!theLorentzTables2)
191     fLorentzTables2 = new std::map<G4double,G4 << 196     theLorentzTables2 = new std::map<G4double,G4PhysicsTable*>;
192                                                   197 
193   G4double Zmat = CalculateEffectiveZ(material    198   G4double Zmat = CalculateEffectiveZ(material);
194                                                   199 
195   const G4int reducedEnergyGrid=21;               200   const G4int reducedEnergyGrid=21;
196   //Support arrays.                               201   //Support arrays.
197   G4double betas[fNumberofEPoints]; //betas fo << 202   G4double betas[NumberofEPoints]; //betas for interpolation
198   //tables for interpolation                      203   //tables for interpolation
199   G4double Q1[fNumberofEPoints][fNumberofKPoin << 204   G4double Q1[NumberofEPoints][NumberofKPoints];
200   G4double Q2[fNumberofEPoints][fNumberofKPoin << 205   G4double Q2[NumberofEPoints][NumberofKPoints];
201   //expanded tables for interpolation             206   //expanded tables for interpolation
202   G4double Q1E[fNumberofEPoints][reducedEnergy << 207   G4double Q1E[NumberofEPoints][reducedEnergyGrid];
203   G4double Q2E[fNumberofEPoints][reducedEnergy << 208   G4double Q2E[NumberofEPoints][reducedEnergyGrid];
204   G4double pZ[fNumberofZPoints] = {2.0,8.0,13. << 209   G4double pZ[NumberofZPoints] = {2.0,8.0,13.0,47.0,79.0,92.0};
205                                                   210 
206   G4int i=0,j=0,k=0; // i=index for Z, j=index    211   G4int i=0,j=0,k=0; // i=index for Z, j=index for E, k=index for K
207   //Interpolation in Z                            212   //Interpolation in Z
208   for (i=0;i<fNumberofEPoints;i++)             << 213   for (i=0;i<NumberofEPoints;i++)
209     {                                             214     {
210       for (j=0;j<fNumberofKPoints;j++)         << 215       for (j=0;j<NumberofKPoints;j++)
211   {                                               216   {
212     G4PhysicsFreeVector* QQ1vector =           << 217     G4PhysicsFreeVector* QQ1vector = new G4PhysicsFreeVector(NumberofZPoints);
213       new G4PhysicsFreeVector(fNumberofZPoints << 218     G4PhysicsFreeVector* QQ2vector = new G4PhysicsFreeVector(NumberofZPoints);
214     G4PhysicsFreeVector* QQ2vector =           << 
215       new G4PhysicsFreeVector(fNumberofZPoints << 
216                                                   219 
217     //fill vectors                                220     //fill vectors
218     for (k=0;k<fNumberofZPoints;k++)           << 221     for (k=0;k<NumberofZPoints;k++)
219       {                                           222       {
220         QQ1vector->PutValues(k,pZ[k],G4Log(fQQ << 223         QQ1vector->PutValue(k,pZ[k],std::log(QQ1[k][i][j]));
221         QQ2vector->PutValues(k,pZ[k],fQQ2[k][i << 224         QQ2vector->PutValue(k,pZ[k],QQ2[k][i][j]);
222       }                                           225       }
223     //Filled: now calculate derivatives        << 226 
224     QQ1vector->FillSecondDerivatives();        << 227     QQ1vector->SetSpline(true);
225     QQ2vector->FillSecondDerivatives();        << 228     QQ2vector->SetSpline(true);
226                                                   229 
227     Q1[i][j]= G4Exp(QQ1vector->Value(Zmat));      230     Q1[i][j]= G4Exp(QQ1vector->Value(Zmat));
228     Q2[i][j]=QQ2vector->Value(Zmat);              231     Q2[i][j]=QQ2vector->Value(Zmat);
229     delete QQ1vector;                             232     delete QQ1vector;
230     delete QQ2vector;                             233     delete QQ2vector;
231   }                                               234   }
232     }                                             235     }
233   G4double pE[fNumberofEPoints] = {1.0e-03*MeV << 236   G4double pE[NumberofEPoints] = {1.0e-03*MeV,5.0e-03*MeV,1.0e-02*MeV,5.0e-02*MeV,
234           1.0e-01*MeV,5.0e-01*MeV};               237           1.0e-01*MeV,5.0e-01*MeV};
235   G4double pK[fNumberofKPoints] = {0.0,0.6,0.8 << 238   G4double pK[NumberofKPoints] = {0.0,0.6,0.8,0.95};
236   G4double ppK[reducedEnergyGrid];                239   G4double ppK[reducedEnergyGrid];
237                                                   240 
238   for(i=0;i<reducedEnergyGrid;i++)                241   for(i=0;i<reducedEnergyGrid;i++)
239     ppK[i]=((G4double) i) * 0.05;                 242     ppK[i]=((G4double) i) * 0.05;
240                                                   243 
241                                                   244 
242   for(i=0;i<fNumberofEPoints;i++)              << 245   for(i=0;i<NumberofEPoints;i++)
243     betas[i]=std::sqrt(pE[i]*(pE[i]+2*electron    246     betas[i]=std::sqrt(pE[i]*(pE[i]+2*electron_mass_c2))/(pE[i]+electron_mass_c2);
244                                                   247 
245                                                   248 
246   for (i=0;i<fNumberofEPoints;i++)             << 249   for (i=0;i<NumberofEPoints;i++)
247     {                                             250     {
248       for (j=0;j<fNumberofKPoints;j++)         << 251       for (j=0;j<NumberofKPoints;j++)
249   Q1[i][j]=Q1[i][j]/Zmat;                         252   Q1[i][j]=Q1[i][j]/Zmat;
250     }                                             253     }
251                                                   254 
252   //Expanded table of distribution parameters     255   //Expanded table of distribution parameters
253   for (i=0;i<fNumberofEPoints;i++)             << 256   for (i=0;i<NumberofEPoints;i++)
254     {                                             257     {
255       G4PhysicsFreeVector* Q1vector = new G4Ph << 258       G4PhysicsFreeVector* Q1vector = new G4PhysicsFreeVector(NumberofKPoints);
256       G4PhysicsFreeVector* Q2vector = new G4Ph << 259       G4PhysicsFreeVector* Q2vector = new G4PhysicsFreeVector(NumberofKPoints);
257                                                   260 
258       for (j=0;j<fNumberofKPoints;j++)         << 261       for (j=0;j<NumberofKPoints;j++)
259   {                                               262   {
260     Q1vector->PutValues(j,pK[j],G4Log(Q1[i][j] << 263     Q1vector->PutValue(j,pK[j],std::log(Q1[i][j])); //logarithmic
261     Q2vector->PutValues(j,pK[j],Q2[i][j]);     << 264     Q2vector->PutValue(j,pK[j],Q2[i][j]);
262   }                                               265   }
263                                                   266 
264       for (j=0;j<reducedEnergyGrid;j++)           267       for (j=0;j<reducedEnergyGrid;j++)
265   {                                               268   {
266     Q1E[i][j]=Q1vector->Value(ppK[j]);            269     Q1E[i][j]=Q1vector->Value(ppK[j]);
267     Q2E[i][j]=Q2vector->Value(ppK[j]);            270     Q2E[i][j]=Q2vector->Value(ppK[j]);
268   }                                               271   }
269       delete Q1vector;                            272       delete Q1vector;
270       delete Q2vector;                            273       delete Q2vector;
271     }                                             274     }
272   //                                              275   //
273   //TABLES to be stored                           276   //TABLES to be stored
274   //                                              277   //
275   G4PhysicsTable* theTable1 = new G4PhysicsTab    278   G4PhysicsTable* theTable1 = new G4PhysicsTable();
276   G4PhysicsTable* theTable2 = new G4PhysicsTab    279   G4PhysicsTable* theTable2 = new G4PhysicsTable();
277   // the table will contain reducedEnergyGrid     280   // the table will contain reducedEnergyGrid G4PhysicsFreeVectors with different
278   // values of k,                                 281   // values of k,
279   // Each of the G4PhysicsFreeVectors has a pr    282   // Each of the G4PhysicsFreeVectors has a profile of
280   // y vs. E                                      283   // y vs. E
281   //                                              284   //
282   //reserve space of the vectors.                 285   //reserve space of the vectors.
283   for (j=0;j<reducedEnergyGrid;j++)               286   for (j=0;j<reducedEnergyGrid;j++)
284     {                                             287     {
285       G4PhysicsFreeVector* thevec = new G4Phys << 288       G4PhysicsFreeVector* thevec = new G4PhysicsFreeVector(NumberofEPoints);
286       theTable1->push_back(thevec);               289       theTable1->push_back(thevec);
287       G4PhysicsFreeVector* thevec2 = new G4Phy << 290       G4PhysicsFreeVector* thevec2 = new G4PhysicsFreeVector(NumberofEPoints);
288       theTable2->push_back(thevec2);              291       theTable2->push_back(thevec2);
289     }                                             292     }
290                                                   293 
291   for (j=0;j<reducedEnergyGrid;j++)               294   for (j=0;j<reducedEnergyGrid;j++)
292     {                                             295     {
293       G4PhysicsFreeVector* thevec = (G4Physics    296       G4PhysicsFreeVector* thevec = (G4PhysicsFreeVector*) (*theTable1)[j];
294       G4PhysicsFreeVector* thevec2 = (G4Physic    297       G4PhysicsFreeVector* thevec2 = (G4PhysicsFreeVector*) (*theTable2)[j];
295       for (i=0;i<fNumberofEPoints;i++)         << 298       for (i=0;i<NumberofEPoints;i++)
296   {                                               299   {
297     thevec->PutValues(i,betas[i],Q1E[i][j]);   << 300     thevec->PutValue(i,betas[i],Q1E[i][j]);
298     thevec2->PutValues(i,betas[i],Q2E[i][j]);  << 301     thevec2->PutValue(i,betas[i],Q2E[i][j]);
299   }                                               302   }
300       //Vectors are filled: calculate derivati << 303       thevec->SetSpline(true);
301       thevec->FillSecondDerivatives();         << 304       thevec2->SetSpline(true);
302       thevec2->FillSecondDerivatives();        << 
303     }                                             305     }
304                                                   306 
305   if (fLorentzTables1 && fLorentzTables2)      << 307   if (theLorentzTables1 && theLorentzTables2)
306     {                                             308     {
307       fLorentzTables1->insert(std::make_pair(Z << 309       theLorentzTables1->insert(std::make_pair(Zmat,theTable1));
308       fLorentzTables2->insert(std::make_pair(Z << 310       theLorentzTables2->insert(std::make_pair(Zmat,theTable2));
309     }                                             311     }
310   else                                            312   else
311     {                                             313     {
312       G4ExceptionDescription ed;                  314       G4ExceptionDescription ed;
313       ed << "Unable to create tables of Lorent    315       ed << "Unable to create tables of Lorentz coefficients for " << G4endl;
314       ed << "<Z>= "  << Zmat << " in G4Penelop    316       ed << "<Z>= "  << Zmat << " in G4PenelopeBremsstrahlungAngular" << G4endl;
315       delete theTable1;                           317       delete theTable1;
316       delete theTable2;                           318       delete theTable2;
317       G4Exception("G4PenelopeBremsstrahlungAng    319       G4Exception("G4PenelopeBremsstrahlungAngular::PrepareInterpolationTables()",
318       "em2005",FatalException,ed);                320       "em2005",FatalException,ed);
319     }                                             321     }
320                                                   322 
321   return;                                         323   return;
322 }                                                 324 }
323                                                   325 
324 //....oooOO0OOooo........oooOO0OOooo........oo    326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
325                                                   327 
326 G4ThreeVector& G4PenelopeBremsstrahlungAngular    328 G4ThreeVector& G4PenelopeBremsstrahlungAngular::SampleDirection(const G4DynamicParticle* dp,
327                 G4double eGamma,                  329                 G4double eGamma,
328                 G4int,                            330                 G4int,
329                 const G4Material* material)       331                 const G4Material* material)
330 {                                                 332 {
331   if (!material)                                  333   if (!material)
332     {                                             334     {
333       G4Exception("G4PenelopeBremsstrahlungAng    335       G4Exception("G4PenelopeBremsstrahlungAngular::SampleDirection()",
334       "em2040",FatalException,"The pointer to     336       "em2040",FatalException,"The pointer to G4Material* is nullptr");
335       return fLocalDirection;                     337       return fLocalDirection;
336     }                                             338     }
337                                                   339 
338   //Retrieve the effective Z                      340   //Retrieve the effective Z
339   G4double Zmat = 0;                              341   G4double Zmat = 0;
340                                                   342 
341   //The model might be initialized incorrectly << 343   if (!theEffectiveZSq)
342   //G4PenelopeBremsstrahungModel: make sure it << 
343   if (!fEffectiveZSq)                          << 
344     {                                             344     {
345       G4Exception("G4PenelopeBremsstrahlungAng    345       G4Exception("G4PenelopeBremsstrahlungAngular::SampleDirection()",
346       "em2040",JustWarning,"EffectiveZSq table << 346       "em2040",FatalException,"EffectiveZ table not available");
347       PrepareTables(material,false);           << 347       return fLocalDirection;
348       //return fLocalDirection;                << 348     }
349     }                                          << 
350                                                   349 
351   //found in the table: return it                 350   //found in the table: return it
352   if (fEffectiveZSq->count(material))          << 351   if (theEffectiveZSq->count(material))
353     Zmat = fEffectiveZSq->find(material)->seco << 352     Zmat = theEffectiveZSq->find(material)->second;
354   else //this can happen in unit tests or when << 353   else
355     //models other than G4PenelopeBremsstrahun << 354     {
356     {                                          << 
357       G4Exception("G4PenelopeBremsstrahlungAng    355       G4Exception("G4PenelopeBremsstrahlungAngular::SampleDirection()",
358       "em2040",JustWarning,"Material not found << 356       "em2040",FatalException,"Material not found in the effectiveZ table");
359       PrepareTables(material,false);           << 357       return fLocalDirection;
360       Zmat = fEffectiveZSq->find(material)->se << 
361       //      return fLocalDirection;          << 
362     }                                             358     }
363                                                   359 
364   if (fVerbosityLevel > 0)                     << 360   if (verbosityLevel > 0)
365     {                                             361     {
366       G4cout << "Effective <Z> for material :     362       G4cout << "Effective <Z> for material : " << material->GetName() <<
367   " = " << Zmat << G4endl;                        363   " = " << Zmat << G4endl;
368     }                                             364     }
369                                                   365 
370   G4double ePrimary = dp->GetKineticEnergy();     366   G4double ePrimary = dp->GetKineticEnergy();
371                                                   367 
372   G4double beta = std::sqrt(ePrimary*(ePrimary    368   G4double beta = std::sqrt(ePrimary*(ePrimary+2*electron_mass_c2))/
373     (ePrimary+electron_mass_c2);                  369     (ePrimary+electron_mass_c2);
374   G4double cdt = 0;                               370   G4double cdt = 0;
375   G4double sinTheta = 0;                          371   G4double sinTheta = 0;
376   G4double phi = 0;                               372   G4double phi = 0;
377                                                   373 
378   //Use a pure dipole distribution for energy     374   //Use a pure dipole distribution for energy above 500 keV
379   if (ePrimary > 500*keV)                         375   if (ePrimary > 500*keV)
380     {                                             376     {
381       cdt = 2.0*G4UniformRand() - 1.0;            377       cdt = 2.0*G4UniformRand() - 1.0;
382       if (G4UniformRand() > 0.75)                 378       if (G4UniformRand() > 0.75)
383   {                                               379   {
384     if (cdt<0)                                    380     if (cdt<0)
385       cdt = -1.0*std::pow(-cdt,1./3.);            381       cdt = -1.0*std::pow(-cdt,1./3.);
386     else                                          382     else
387       cdt = std::pow(cdt,1./3.);                  383       cdt = std::pow(cdt,1./3.);
388   }                                               384   }
389       cdt = (cdt+beta)/(1.0+beta*cdt);            385       cdt = (cdt+beta)/(1.0+beta*cdt);
390       //Get primary kinematics                    386       //Get primary kinematics
391       sinTheta = std::sqrt(1. - cdt*cdt);         387       sinTheta = std::sqrt(1. - cdt*cdt);
392       phi  = twopi * G4UniformRand();             388       phi  = twopi * G4UniformRand();
393       fLocalDirection.set(sinTheta* std::cos(p    389       fLocalDirection.set(sinTheta* std::cos(phi),
394           sinTheta* std::sin(phi),                390           sinTheta* std::sin(phi),
395           cdt);                                   391           cdt);
396       //rotate                                    392       //rotate
397       fLocalDirection.rotateUz(dp->GetMomentum    393       fLocalDirection.rotateUz(dp->GetMomentumDirection());
398       //return                                    394       //return
399       return fLocalDirection;                     395       return fLocalDirection;
400     }                                             396     }
401                                                   397 
402   if (!(fLorentzTables1->count(Zmat)) || !(fLo << 398   if (!(theLorentzTables1->count(Zmat)) || !(theLorentzTables2->count(Zmat)))
403     {                                             399     {
404       G4ExceptionDescription ed;                  400       G4ExceptionDescription ed;
405       ed << "Unable to retrieve Lorentz tables    401       ed << "Unable to retrieve Lorentz tables for Z= " << Zmat << G4endl;
406       G4Exception("G4PenelopeBremsstrahlungAng    402       G4Exception("G4PenelopeBremsstrahlungAngular::SampleDirection()",
407       "em2006",FatalException,ed);                403       "em2006",FatalException,ed);
408     }                                             404     }
409                                                   405 
410   //retrieve actual tables                        406   //retrieve actual tables
411   const G4PhysicsTable* theTable1 = fLorentzTa << 407   const G4PhysicsTable* theTable1 = theLorentzTables1->find(Zmat)->second;
412   const G4PhysicsTable* theTable2 = fLorentzTa << 408   const G4PhysicsTable* theTable2 = theLorentzTables2->find(Zmat)->second;
413                                                   409 
414   G4double RK=20.0*eGamma/ePrimary;               410   G4double RK=20.0*eGamma/ePrimary;
415   G4int ik=std::min((G4int) RK,19);               411   G4int ik=std::min((G4int) RK,19);
416                                                   412 
417   G4double P10=0,P11=0,P1=0;                      413   G4double P10=0,P11=0,P1=0;
418   G4double P20=0,P21=0,P2=0;                      414   G4double P20=0,P21=0,P2=0;
419                                                   415 
420   //First coefficient                             416   //First coefficient
421   const G4PhysicsFreeVector* v1 = (G4PhysicsFr    417   const G4PhysicsFreeVector* v1 = (G4PhysicsFreeVector*) (*theTable1)[ik];
422   const G4PhysicsFreeVector* v2 = (G4PhysicsFr    418   const G4PhysicsFreeVector* v2 = (G4PhysicsFreeVector*) (*theTable1)[ik+1];
423   P10 = v1->Value(beta);                          419   P10 = v1->Value(beta);
424   P11 = v2->Value(beta);                          420   P11 = v2->Value(beta);
425   P1=P10+(RK-(G4double) ik)*(P11-P10);            421   P1=P10+(RK-(G4double) ik)*(P11-P10);
426                                                   422 
427   //Second coefficient                            423   //Second coefficient
428   const G4PhysicsFreeVector* v3 = (G4PhysicsFr    424   const G4PhysicsFreeVector* v3 = (G4PhysicsFreeVector*) (*theTable2)[ik];
429   const G4PhysicsFreeVector* v4 = (G4PhysicsFr    425   const G4PhysicsFreeVector* v4 = (G4PhysicsFreeVector*) (*theTable2)[ik+1];
430   P20=v3->Value(beta);                            426   P20=v3->Value(beta);
431   P21=v4->Value(beta);                            427   P21=v4->Value(beta);
432   P2=P20+(RK-(G4double) ik)*(P21-P20);            428   P2=P20+(RK-(G4double) ik)*(P21-P20);
433                                                   429 
434   //Sampling from the Lorenz-trasformed dipole    430   //Sampling from the Lorenz-trasformed dipole distributions
435   P1=std::min(G4Exp(P1)/beta,1.0);                431   P1=std::min(G4Exp(P1)/beta,1.0);
436   G4double betap = std::min(std::max(beta*(1.0    432   G4double betap = std::min(std::max(beta*(1.0+P2/beta),0.0),0.9999);
437                                                   433 
438   G4double testf=0;                               434   G4double testf=0;
439                                                   435 
440   if (G4UniformRand() < P1)                       436   if (G4UniformRand() < P1)
441     {                                             437     {
442       do{                                         438       do{
443   cdt = 2.0*G4UniformRand()-1.0;                  439   cdt = 2.0*G4UniformRand()-1.0;
444   testf=2.0*G4UniformRand()-(1.0+cdt*cdt);        440   testf=2.0*G4UniformRand()-(1.0+cdt*cdt);
445       }while(testf>0);                            441       }while(testf>0);
446     }                                             442     }
447   else                                            443   else
448     {                                             444     {
449       do{                                         445       do{
450   cdt = 2.0*G4UniformRand()-1.0;                  446   cdt = 2.0*G4UniformRand()-1.0;
451   testf=G4UniformRand()-(1.0-cdt*cdt);            447   testf=G4UniformRand()-(1.0-cdt*cdt);
452       }while(testf>0);                            448       }while(testf>0);
453     }                                             449     }
454   cdt = (cdt+betap)/(1.0+betap*cdt);              450   cdt = (cdt+betap)/(1.0+betap*cdt);
455                                                   451 
456   //Get primary kinematics                        452   //Get primary kinematics
457   sinTheta = std::sqrt(1. - cdt*cdt);             453   sinTheta = std::sqrt(1. - cdt*cdt);
458   phi  = twopi * G4UniformRand();                 454   phi  = twopi * G4UniformRand();
459   fLocalDirection.set(sinTheta* std::cos(phi),    455   fLocalDirection.set(sinTheta* std::cos(phi),
460           sinTheta* std::sin(phi),                456           sinTheta* std::sin(phi),
461           cdt);                                   457           cdt);
462   //rotate                                        458   //rotate
463   fLocalDirection.rotateUz(dp->GetMomentumDire    459   fLocalDirection.rotateUz(dp->GetMomentumDirection());
464   //return                                        460   //return
465   return fLocalDirection;                         461   return fLocalDirection;
466                                                   462 
467 }                                                 463 }
468                                                   464 
469 //....oooOO0OOooo........oooOO0OOooo........oo    465 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
470                                                   466 
                                                   >> 467 G4double G4PenelopeBremsstrahlungAngular::PolarAngle(const G4double ,
                                                   >> 468                  const G4double ,
                                                   >> 469                  const G4int )
                                                   >> 470 {
                                                   >> 471   G4cout << "WARNING: G4PenelopeBremsstrahlungAngular() does NOT support PolarAngle()" << G4endl;
                                                   >> 472   G4cout << "Please use the alternative interface SampleDirection()" << G4endl;
                                                   >> 473   G4Exception("G4PenelopeBremsstrahlungAngular::PolarAngle()",
                                                   >> 474         "em0005",FatalException,"Unsupported interface");
                                                   >> 475   return 0;
                                                   >> 476 }
                                                   >> 477 
                                                   >> 478 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 479 
471 G4double G4PenelopeBremsstrahlungAngular::Calc    480 G4double G4PenelopeBremsstrahlungAngular::CalculateEffectiveZ(const G4Material* material)
472 {                                                 481 {
473   if (!fEffectiveZSq)                          << 482   if (!theEffectiveZSq)
474     fEffectiveZSq = new std::map<const G4Mater << 483     theEffectiveZSq = new std::map<const G4Material*,G4double>;
475                                                   484 
476   //Already exists: return it                     485   //Already exists: return it
477   if (fEffectiveZSq->count(material))          << 486   if (theEffectiveZSq->count(material))
478     return fEffectiveZSq->find(material)->seco << 487     return theEffectiveZSq->find(material)->second;
479                                                   488 
480   //Helper for the calculation                    489   //Helper for the calculation
481   std::vector<G4double> *StechiometricFactors     490   std::vector<G4double> *StechiometricFactors = new std::vector<G4double>;
482   G4int nElements = (G4int)material->GetNumber << 491   G4int nElements = material->GetNumberOfElements();
483   const G4ElementVector* elementVector = mater    492   const G4ElementVector* elementVector = material->GetElementVector();
484   const G4double* fractionVector = material->G    493   const G4double* fractionVector = material->GetFractionVector();
485   for (G4int i=0;i<nElements;++i)              << 494   for (G4int i=0;i<nElements;i++)
486     {                                             495     {
487       G4double fraction = fractionVector[i];      496       G4double fraction = fractionVector[i];
488       G4double atomicWeigth = (*elementVector)    497       G4double atomicWeigth = (*elementVector)[i]->GetA()/(g/mole);
489       StechiometricFactors->push_back(fraction    498       StechiometricFactors->push_back(fraction/atomicWeigth);
490     }                                             499     }
491   //Find max                                      500   //Find max
492   G4double MaxStechiometricFactor = 0.;           501   G4double MaxStechiometricFactor = 0.;
493   for (G4int i=0;i<nElements;++i)              << 502   for (G4int i=0;i<nElements;i++)
494     {                                             503     {
495       if ((*StechiometricFactors)[i] > MaxStec    504       if ((*StechiometricFactors)[i] > MaxStechiometricFactor)
496         MaxStechiometricFactor = (*Stechiometr    505         MaxStechiometricFactor = (*StechiometricFactors)[i];
497     }                                             506     }
498   //Normalize                                     507   //Normalize
499   for (G4int i=0;i<nElements;++i)              << 508   for (G4int i=0;i<nElements;i++)
500     (*StechiometricFactors)[i] /=  MaxStechiom    509     (*StechiometricFactors)[i] /=  MaxStechiometricFactor;
501                                                   510 
502   G4double sumz2 = 0;                             511   G4double sumz2 = 0;
503   G4double sums = 0;                              512   G4double sums = 0;
504   for (G4int i=0;i<nElements;++i)              << 513   for (G4int i=0;i<nElements;i++)
505     {                                             514     {
506       G4double Z = (*elementVector)[i]->GetZ()    515       G4double Z = (*elementVector)[i]->GetZ();
507       sumz2 += (*StechiometricFactors)[i]*Z*Z;    516       sumz2 += (*StechiometricFactors)[i]*Z*Z;
508       sums  += (*StechiometricFactors)[i];        517       sums  += (*StechiometricFactors)[i];
509     }                                             518     }
510   delete StechiometricFactors;                    519   delete StechiometricFactors;
511                                                   520 
512   G4double ZBR = std::sqrt(sumz2/sums);           521   G4double ZBR = std::sqrt(sumz2/sums);
513   fEffectiveZSq->insert(std::make_pair(materia << 522   theEffectiveZSq->insert(std::make_pair(material,ZBR));
514                                                   523 
515   return ZBR;                                     524   return ZBR;
516 }                                                 525 }
517                                                   526