Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/management/src/G4PhysicsVector.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 /global/management/src/G4PhysicsVector.cc (Version 11.3.0) and /global/management/src/G4PhysicsVector.cc (Version 11.1.1)


  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 // G4PhysicsVector class implementation            26 // G4PhysicsVector class implementation
 27 //                                                 27 //
 28 // Authors:                                        28 // Authors:
 29 // - 02 Dec. 1995, G.Cosmo: Structure created      29 // - 02 Dec. 1995, G.Cosmo: Structure created based on object model
 30 // - 03 Mar. 1996, K.Amako: Implemented the 1s     30 // - 03 Mar. 1996, K.Amako: Implemented the 1st version
 31 // Revisions:                                      31 // Revisions:
 32 // - 11 Nov. 2000, H.Kurashige: Use STL vector     32 // - 11 Nov. 2000, H.Kurashige: Use STL vector for dataVector and binVector
 33 // -------------------------------------------     33 // --------------------------------------------------------------------
 34                                                    34 
 35 #include "G4PhysicsVector.hh"                      35 #include "G4PhysicsVector.hh"
 36 #include <iomanip>                                 36 #include <iomanip>
 37                                                    37 
 38 // -------------------------------------------     38 // --------------------------------------------------------------
 39 G4PhysicsVector::G4PhysicsVector(G4bool val)       39 G4PhysicsVector::G4PhysicsVector(G4bool val)
 40   : useSpline(val)                                 40   : useSpline(val)
 41 {}                                                 41 {}
 42                                                    42 
 43 // -------------------------------------------     43 // --------------------------------------------------------------------
 44 void G4PhysicsVector::Initialise()                 44 void G4PhysicsVector::Initialise()
 45 {                                                  45 {
 46   if (1 < numberOfNodes)                       <<  46   idxmax = numberOfNodes - 2;
                                                   >>  47   if(0 < numberOfNodes)
 47   {                                                48   {
 48     idxmax = numberOfNodes - 2;                << 
 49     edgeMin = binVector[0];                        49     edgeMin = binVector[0];
 50     edgeMax = binVector[idxmax + 1];           <<  50     edgeMax = binVector[numberOfNodes - 1];
 51   }                                                51   }
 52 }                                                  52 }
 53                                                    53 
 54 // -------------------------------------------     54 // --------------------------------------------------------------
 55 G4bool G4PhysicsVector::Store(std::ofstream& f     55 G4bool G4PhysicsVector::Store(std::ofstream& fOut, G4bool ascii) const
 56 {                                                  56 {
 57   // Ascii mode                                    57   // Ascii mode
 58   if (ascii)                                   <<  58   if(ascii)
 59   {                                                59   {
 60     fOut << *this;                                 60     fOut << *this;
 61     return true;                                   61     return true;
 62   }                                                62   }
 63   // Binary Mode                                   63   // Binary Mode
 64                                                    64 
 65   // binning                                       65   // binning
 66   fOut.write((char*) (&edgeMin), sizeof edgeMi     66   fOut.write((char*) (&edgeMin), sizeof edgeMin);
 67   fOut.write((char*) (&edgeMax), sizeof edgeMa     67   fOut.write((char*) (&edgeMax), sizeof edgeMax);
 68   fOut.write((char*) (&numberOfNodes), sizeof      68   fOut.write((char*) (&numberOfNodes), sizeof numberOfNodes);
 69                                                    69 
 70   // contents                                      70   // contents
 71   std::size_t size = dataVector.size();            71   std::size_t size = dataVector.size();
 72   fOut.write((char*) (&size), sizeof size);        72   fOut.write((char*) (&size), sizeof size);
 73                                                    73 
 74   auto value = new G4double[2 * size];         <<  74   G4double* value = new G4double[2 * size];
 75   for (std::size_t i = 0; i < size; ++i)       <<  75   for(std::size_t i = 0; i < size; ++i)
 76   {                                                76   {
 77     value[2 * i]     = binVector[i];               77     value[2 * i]     = binVector[i];
 78     value[2 * i + 1] = dataVector[i];              78     value[2 * i + 1] = dataVector[i];
 79   }                                                79   }
 80   fOut.write((char*) (value), 2 * size * (size     80   fOut.write((char*) (value), 2 * size * (sizeof(G4double)));
 81   delete[] value;                                  81   delete[] value;
 82                                                    82 
 83   return true;                                     83   return true;
 84 }                                                  84 }
 85                                                    85 
 86 // -------------------------------------------     86 // --------------------------------------------------------------
 87 G4bool G4PhysicsVector::Retrieve(std::ifstream     87 G4bool G4PhysicsVector::Retrieve(std::ifstream& fIn, G4bool ascii)
 88 {                                                  88 {
 89   // clear properties;                             89   // clear properties;
 90   dataVector.clear();                              90   dataVector.clear();
 91   binVector.clear();                               91   binVector.clear();
 92   secDerivative.clear();                           92   secDerivative.clear();
 93                                                    93 
 94   // retrieve in ascii mode                        94   // retrieve in ascii mode
 95   if (ascii)                                   <<  95   if(ascii)
 96   {                                                96   {
 97     // binning                                     97     // binning
 98     fIn >> edgeMin >> edgeMax >> numberOfNodes     98     fIn >> edgeMin >> edgeMax >> numberOfNodes;
 99     if (fIn.fail() || numberOfNodes < 2)       <<  99     if(fIn.fail() || numberOfNodes < 2)
100     {                                             100     {
101       return false;                               101       return false;
102     }                                             102     }
103     // contents                                   103     // contents
104     G4int siz0 = 0;                            << 104     G4int siz = 0;
105     fIn >> siz0;                               << 105     fIn >> siz;
106     if (siz0 < 2) { return false; }            << 106     if(fIn.fail() || siz != G4int(numberOfNodes))
107     auto siz = static_cast<std::size_t>(siz0); << 
108     if (fIn.fail() || siz != numberOfNodes)    << 
109     {                                             107     {
110       return false;                               108       return false;
111     }                                             109     }
112                                                   110 
113     binVector.reserve(siz);                       111     binVector.reserve(siz);
114     dataVector.reserve(siz);                      112     dataVector.reserve(siz);
115     G4double vBin, vData;                         113     G4double vBin, vData;
116                                                   114 
117     for (std::size_t i = 0; i < siz; ++i)      << 115     for(G4int i = 0; i < siz; ++i)
118     {                                             116     {
119       vBin  = 0.;                                 117       vBin  = 0.;
120       vData = 0.;                                 118       vData = 0.;
121       fIn >> vBin >> vData;                       119       fIn >> vBin >> vData;
122       if (fIn.fail())                          << 120       if(fIn.fail())
123       {                                           121       {
124         return false;                             122         return false;
125       }                                           123       }
126       binVector.push_back(vBin);                  124       binVector.push_back(vBin);
127       dataVector.push_back(vData);                125       dataVector.push_back(vData);
128     }                                             126     }
129     Initialise();                                 127     Initialise();
130     return true;                                  128     return true;
131   }                                               129   }
132                                                   130 
133   // retrieve in binary mode                      131   // retrieve in binary mode
134   // binning                                      132   // binning
135   fIn.read((char*) (&edgeMin), sizeof edgeMin)    133   fIn.read((char*) (&edgeMin), sizeof edgeMin);
136   fIn.read((char*) (&edgeMax), sizeof edgeMax)    134   fIn.read((char*) (&edgeMax), sizeof edgeMax);
137   fIn.read((char*) (&numberOfNodes), sizeof nu    135   fIn.read((char*) (&numberOfNodes), sizeof numberOfNodes);
138                                                   136 
139   // contents                                     137   // contents
140   std::size_t size;                               138   std::size_t size;
141   fIn.read((char*) (&size), sizeof size);         139   fIn.read((char*) (&size), sizeof size);
142                                                   140 
143   auto value = new G4double[2 * size];         << 141   G4double* value = new G4double[2 * size];
144   fIn.read((char*) (value), 2 * size * (sizeof    142   fIn.read((char*) (value), 2 * size * (sizeof(G4double)));
145   if (static_cast<G4int>(fIn.gcount()) != stat << 143   if(G4int(fIn.gcount()) != G4int(2 * size * (sizeof(G4double))))
146   {                                               144   {
147     delete[] value;                               145     delete[] value;
148     return false;                                 146     return false;
149   }                                               147   }
150                                                   148 
151   binVector.reserve(size);                        149   binVector.reserve(size);
152   dataVector.reserve(size);                       150   dataVector.reserve(size);
153   for (std::size_t i = 0; i < size; ++i)       << 151   for(std::size_t i = 0; i < size; ++i)
154   {                                               152   {
155     binVector.push_back(value[2 * i]);            153     binVector.push_back(value[2 * i]);
156     dataVector.push_back(value[2 * i + 1]);       154     dataVector.push_back(value[2 * i + 1]);
157   }                                               155   }
158   delete[] value;                                 156   delete[] value;
159                                                   157 
160   Initialise();                                   158   Initialise();
161   return true;                                    159   return true;
162 }                                                 160 }
163                                                   161 
164 // -------------------------------------------    162 // --------------------------------------------------------------
165 void G4PhysicsVector::DumpValues(G4double unit    163 void G4PhysicsVector::DumpValues(G4double unitE, G4double unitV) const
166 {                                                 164 {
167   for (std::size_t i = 0; i < numberOfNodes; + << 165   for(std::size_t i = 0; i < numberOfNodes; ++i)
168   {                                               166   {
169     G4cout << binVector[i] / unitE << "   " <<    167     G4cout << binVector[i] / unitE << "   " << dataVector[i] / unitV 
170            << G4endl;                             168            << G4endl;
171   }                                               169   }
172 }                                                 170 }
173                                                   171 
174 // -------------------------------------------    172 // --------------------------------------------------------------------
175 std::size_t G4PhysicsVector::FindBin(const G4d    173 std::size_t G4PhysicsVector::FindBin(const G4double energy, 
176                                      std::size    174                                      std::size_t idx) const
177 {                                                 175 {
178   if (idx + 1 < numberOfNodes &&               << 176   if(idx + 1 < numberOfNodes && 
179       energy >= binVector[idx] && energy <= bi << 177      energy >= binVector[idx] && energy <= binVector[idx])
180   {                                               178   {
181     return idx;                                   179     return idx;
182   }                                               180   } 
183   if (energy <= binVector[1])                  << 181   if(energy <= binVector[1])
184   {                                               182   {
185     return 0;                                     183     return 0;
186   }                                               184   }
187   if (energy >= binVector[idxmax])             << 185   if(energy >= binVector[idxmax])
188   {                                               186   {
189     return idxmax;                                187     return idxmax;
190   }                                               188   }
191   return GetBin(energy);                          189   return GetBin(energy); 
192 }                                                 190 }
193                                                   191 
194 // -------------------------------------------    192 // --------------------------------------------------------------------
195 void G4PhysicsVector::ScaleVector(const G4doub    193 void G4PhysicsVector::ScaleVector(const G4double factorE, 
196                                   const G4doub    194                                   const G4double factorV)
197 {                                                 195 {
198   for (std::size_t i = 0; i < numberOfNodes; + << 196   for(std::size_t i = 0; i < numberOfNodes; ++i)
199   {                                               197   {
200     binVector[i] *= factorE;                      198     binVector[i] *= factorE;
201     dataVector[i] *= factorV;                     199     dataVector[i] *= factorV;
202   }                                               200   }
203   Initialise();                                   201   Initialise();
204 }                                                 202 }
205                                                   203 
206 // -------------------------------------------    204 // --------------------------------------------------------------------
207 void G4PhysicsVector::FillSecondDerivatives(co    205 void G4PhysicsVector::FillSecondDerivatives(const G4SplineType stype,
208               const G4double dir1,                206               const G4double dir1,
209               const G4double dir2)                207               const G4double dir2)
210 {                                                 208 {
211   if (!useSpline) { return; }                  << 209   if(!useSpline) { return; }
212   // cannot compute derivatives for less than     210   // cannot compute derivatives for less than 5 points
213   const std::size_t nmin = (stype == G4SplineT    211   const std::size_t nmin = (stype == G4SplineType::Base) ? 5 : 4;
214   if (nmin > numberOfNodes)                    << 212   if(nmin > numberOfNodes) 
215   {                                               213   {
216     if (0 < verboseLevel)                      << 214     if(0 < verboseLevel)
217     {                                             215     { 
218       G4cout << "### G4PhysicsVector: spline c    216       G4cout << "### G4PhysicsVector: spline cannot be used for "
219        << numberOfNodes << " points - spline d    217        << numberOfNodes << " points - spline disabled" 
220        << G4endl;                                 218        << G4endl;
221       DumpValues();                               219       DumpValues();
222     }                                             220     }
223     useSpline = false;                            221     useSpline = false;
224     return;                                       222     return;
225   }                                               223   }
226   // check energies of free vector                224   // check energies of free vector
227   if (type == T_G4PhysicsFreeVector)           << 225   if(type == T_G4PhysicsFreeVector)
228   {                                               226   {
229     for (std::size_t i=0; i<=idxmax; ++i)      << 227     for(std::size_t i=0; i<=idxmax; ++i) 
230     {                                             228     {
231       if (binVector[i + 1] <= binVector[i])    << 229       if(binVector[i + 1] <= binVector[i])
232       {                                           230       {
233         if (0 < verboseLevel)                  << 231         if(0 < verboseLevel) 
234         {                                         232         {
235     G4cout << "### G4PhysicsVector: spline can    233     G4cout << "### G4PhysicsVector: spline cannot be used, because "
236      << " E[" << i << "]=" << binVector[i]        234      << " E[" << i << "]=" << binVector[i]
237      << " >= E[" << i+1 << "]=" << binVector[i    235      << " >= E[" << i+1 << "]=" << binVector[i + 1]
238      << G4endl;                                   236      << G4endl;
239     DumpValues();                                 237     DumpValues();
240         }                                         238         }
241         useSpline = false;                        239         useSpline = false;
242         return;                                   240         return;
243       }                                           241       }
244     }                                             242     }
245   }                                               243   }
246                                                   244 
247   // spline is possible                           245   // spline is possible
248   Initialise();                                   246   Initialise();
249   secDerivative.resize(numberOfNodes);            247   secDerivative.resize(numberOfNodes);
250                                                   248 
251   if (1 < verboseLevel)                        << 249   if(1 < verboseLevel)
252   {                                               250   {
253     G4cout << "### G4PhysicsVector:: FillSecon    251     G4cout << "### G4PhysicsVector:: FillSecondDerivatives N=" 
254            << numberOfNodes << G4endl;            252            << numberOfNodes << G4endl;
255     DumpValues();                                 253     DumpValues();
256   }                                               254   }
257                                                   255 
258   switch(stype)                                   256   switch(stype) 
259   {                                               257   {
260     case G4SplineType::Base:                      258     case G4SplineType::Base:
261       ComputeSecDerivative1();                    259       ComputeSecDerivative1();
262       break;                                      260       break;
263                                                   261 
264     case G4SplineType::FixedEdges:                262     case G4SplineType::FixedEdges:
265       ComputeSecDerivative2(dir1, dir2);          263       ComputeSecDerivative2(dir1, dir2);
266       break;                                      264       break;
267                                                   265 
268     default:                                      266     default:
269       ComputeSecDerivative0();                    267       ComputeSecDerivative0();
270   }                                               268   }
271 }                                                 269 }
272                                                   270 
273 // -------------------------------------------    271 // --------------------------------------------------------------
274 void G4PhysicsVector::ComputeSecDerivative0()     272 void G4PhysicsVector::ComputeSecDerivative0()
275 //  A simplified method of computation of seco    273 //  A simplified method of computation of second derivatives
276 {                                                 274 {
277   std::size_t n = numberOfNodes - 1;              275   std::size_t n = numberOfNodes - 1;
278                                                   276 
279   for (std::size_t i = 1; i < n; ++i)          << 277   for(std::size_t i = 1; i < n; ++i)
280   {                                               278   {
281     secDerivative[i] = 3.0 *                      279     secDerivative[i] = 3.0 *
282       ((dataVector[i + 1] - dataVector[i]) / (    280       ((dataVector[i + 1] - dataVector[i]) / (binVector[i + 1] - binVector[i]) -
283        (dataVector[i] - dataVector[i - 1]) /      281        (dataVector[i] - dataVector[i - 1]) /
284          (binVector[i] - binVector[i - 1])) /     282          (binVector[i] - binVector[i - 1])) /
285       (binVector[i + 1] - binVector[i - 1]);      283       (binVector[i + 1] - binVector[i - 1]);
286   }                                               284   }
287   secDerivative[n] = secDerivative[n - 1];        285   secDerivative[n] = secDerivative[n - 1];
288   secDerivative[0] = secDerivative[1];            286   secDerivative[0] = secDerivative[1];
289 }                                                 287 }
290                                                   288 
291 // -------------------------------------------    289 // --------------------------------------------------------------
292 void G4PhysicsVector::ComputeSecDerivative1()     290 void G4PhysicsVector::ComputeSecDerivative1()
293 // Computation of second derivatives using "No    291 // Computation of second derivatives using "Not-a-knot" endpoint conditions
294 // B.I. Kvasov "Methods of shape-preserving sp    292 // B.I. Kvasov "Methods of shape-preserving spline approximation"
295 // World Scientific, 2000                         293 // World Scientific, 2000
296 {                                                 294 {
297   std::size_t n = numberOfNodes - 1;              295   std::size_t n = numberOfNodes - 1;
298   auto u = new G4double[n];                    << 296   G4double* u = new G4double[n];
299   G4double p, sig;                                297   G4double p, sig;
300                                                   298 
301   u[1] = ((dataVector[2] - dataVector[1]) / (b    299   u[1] = ((dataVector[2] - dataVector[1]) / (binVector[2] - binVector[1]) -
302           (dataVector[1] - dataVector[0]) / (b    300           (dataVector[1] - dataVector[0]) / (binVector[1] - binVector[0]));
303   u[1] = 6.0 * u[1] * (binVector[2] - binVecto    301   u[1] = 6.0 * u[1] * (binVector[2] - binVector[1]) /
304          ((binVector[2] - binVector[0]) * (bin    302          ((binVector[2] - binVector[0]) * (binVector[2] - binVector[0]));
305                                                   303 
306   // Decomposition loop for tridiagonal algori    304   // Decomposition loop for tridiagonal algorithm. secDerivative[i]
307   // and u[i] are used for temporary storage o    305   // and u[i] are used for temporary storage of the decomposed factors.
308                                                   306 
309   secDerivative[1] = (2.0 * binVector[1] - bin    307   secDerivative[1] = (2.0 * binVector[1] - binVector[0] - binVector[2]) /
310                      (2.0 * binVector[2] - bin    308                      (2.0 * binVector[2] - binVector[0] - binVector[1]);
311                                                   309 
312   for(std::size_t i = 2; i < n - 1; ++i)          310   for(std::size_t i = 2; i < n - 1; ++i)
313   {                                               311   {
314     sig =                                         312     sig =
315       (binVector[i] - binVector[i - 1]) / (bin    313       (binVector[i] - binVector[i - 1]) / (binVector[i + 1] - binVector[i - 1]);
316     p                = sig * secDerivative[i -    314     p                = sig * secDerivative[i - 1] + 2.0;
317     secDerivative[i] = (sig - 1.0) / p;           315     secDerivative[i] = (sig - 1.0) / p;
318     u[i] =                                        316     u[i] =
319       (dataVector[i + 1] - dataVector[i]) / (b    317       (dataVector[i + 1] - dataVector[i]) / (binVector[i + 1] - binVector[i]) -
320       (dataVector[i] - dataVector[i - 1]) / (b    318       (dataVector[i] - dataVector[i - 1]) / (binVector[i] - binVector[i - 1]);
321     u[i] =                                        319     u[i] =
322       (6.0 * u[i] / (binVector[i + 1] - binVec    320       (6.0 * u[i] / (binVector[i + 1] - binVector[i - 1])) - sig * u[i - 1] / p;
323   }                                               321   }
324                                                   322 
325   sig =                                           323   sig =
326     (binVector[n - 1] - binVector[n - 2]) / (b    324     (binVector[n - 1] - binVector[n - 2]) / (binVector[n] - binVector[n - 2]);
327   p = sig * secDerivative[n - 3] + 2.0;           325   p = sig * secDerivative[n - 3] + 2.0;
328   u[n - 1] =                                      326   u[n - 1] =
329     (dataVector[n] - dataVector[n - 1]) / (bin    327     (dataVector[n] - dataVector[n - 1]) / (binVector[n] - binVector[n - 1]) -
330     (dataVector[n - 1] - dataVector[n - 2]) /     328     (dataVector[n - 1] - dataVector[n - 2]) /
331       (binVector[n - 1] - binVector[n - 2]);      329       (binVector[n - 1] - binVector[n - 2]);
332   u[n - 1] = 6.0 * sig * u[n - 1] / (binVector    330   u[n - 1] = 6.0 * sig * u[n - 1] / (binVector[n] - binVector[n - 2]) -
333              (2.0 * sig - 1.0) * u[n - 2] / p;    331              (2.0 * sig - 1.0) * u[n - 2] / p;
334                                                   332 
335   p = (1.0 + sig) + (2.0 * sig - 1.0) * secDer    333   p = (1.0 + sig) + (2.0 * sig - 1.0) * secDerivative[n - 2];
336   secDerivative[n - 1] = u[n - 1] / p;            334   secDerivative[n - 1] = u[n - 1] / p;
337                                                   335 
338   // The back-substitution loop for the triago    336   // The back-substitution loop for the triagonal algorithm of solving
339   // a linear system of equations.                337   // a linear system of equations.
340                                                   338 
341   for (std::size_t k = n - 2; k > 1; --k)      << 339   for(std::size_t k = n - 2; k > 1; --k)
342   {                                               340   {
343     secDerivative[k] *=                           341     secDerivative[k] *=
344       (secDerivative[k + 1] - u[k] * (binVecto    342       (secDerivative[k + 1] - u[k] * (binVector[k + 1] - binVector[k - 1]) /
345                                 (binVector[k +    343                                 (binVector[k + 1] - binVector[k]));
346   }                                               344   }
347   secDerivative[n] =                              345   secDerivative[n] =
348     (secDerivative[n - 1] - (1.0 - sig) * secD    346     (secDerivative[n - 1] - (1.0 - sig) * secDerivative[n - 2]) / sig;
349   sig = 1.0 - ((binVector[2] - binVector[1]) /    347   sig = 1.0 - ((binVector[2] - binVector[1]) / (binVector[2] - binVector[0]));
350   secDerivative[1] *= (secDerivative[2] - u[1]    348   secDerivative[1] *= (secDerivative[2] - u[1] / (1.0 - sig));
351   secDerivative[0] = (secDerivative[1] - sig *    349   secDerivative[0] = (secDerivative[1] - sig * secDerivative[2]) / (1.0 - sig);
352                                                   350 
353   delete[] u;                                     351   delete[] u;
354 }                                                 352 }
355                                                   353 
356 // -------------------------------------------    354 // --------------------------------------------------------------
357 void G4PhysicsVector::ComputeSecDerivative2(G4    355 void G4PhysicsVector::ComputeSecDerivative2(G4double firstPointDerivative,
358                                             G4    356                                             G4double endPointDerivative)
359 // A standard method of computation of second     357 // A standard method of computation of second derivatives
360 // First derivatives at the first and the last    358 // First derivatives at the first and the last point should be provided
361 // See for example W.H. Press et al. "Numerica    359 // See for example W.H. Press et al. "Numerical recipes in C"
362 // Cambridge University Press, 1997.              360 // Cambridge University Press, 1997.
363 {                                                 361 {
364   std::size_t n = numberOfNodes - 1;              362   std::size_t n = numberOfNodes - 1;
365   auto u = new G4double[n];                    << 363   G4double* u = new G4double[n];
366   G4double p, sig, un;                            364   G4double p, sig, un;
367                                                   365 
368   u[0] = (6.0 / (binVector[1] - binVector[0]))    366   u[0] = (6.0 / (binVector[1] - binVector[0])) *
369          ((dataVector[1] - dataVector[0]) / (b    367          ((dataVector[1] - dataVector[0]) / (binVector[1] - binVector[0]) -
370           firstPointDerivative);                  368           firstPointDerivative);
371                                                   369 
372   secDerivative[0] = -0.5;                        370   secDerivative[0] = -0.5;
373                                                   371 
374   // Decomposition loop for tridiagonal algori    372   // Decomposition loop for tridiagonal algorithm. secDerivative[i]
375   // and u[i] are used for temporary storage o    373   // and u[i] are used for temporary storage of the decomposed factors.
376                                                   374 
377   for (std::size_t i = 1; i < n; ++i)          << 375   for(std::size_t i = 1; i < n; ++i)
378   {                                               376   {
379     sig =                                         377     sig =
380       (binVector[i] - binVector[i - 1]) / (bin    378       (binVector[i] - binVector[i - 1]) / (binVector[i + 1] - binVector[i - 1]);
381     p                = sig * (secDerivative[i     379     p                = sig * (secDerivative[i - 1]) + 2.0;
382     secDerivative[i] = (sig - 1.0) / p;           380     secDerivative[i] = (sig - 1.0) / p;
383     u[i] =                                        381     u[i] =
384       (dataVector[i + 1] - dataVector[i]) / (b    382       (dataVector[i + 1] - dataVector[i]) / (binVector[i + 1] - binVector[i]) -
385       (dataVector[i] - dataVector[i - 1]) / (b    383       (dataVector[i] - dataVector[i - 1]) / (binVector[i] - binVector[i - 1]);
386     u[i] =                                        384     u[i] =
387       6.0 * u[i] / (binVector[i + 1] - binVect    385       6.0 * u[i] / (binVector[i + 1] - binVector[i - 1]) - sig * u[i - 1] / p;
388   }                                               386   }
389                                                   387 
390   sig =                                           388   sig =
391     (binVector[n - 1] - binVector[n - 2]) / (b    389     (binVector[n - 1] - binVector[n - 2]) / (binVector[n] - binVector[n - 2]);
392   p  = sig * secDerivative[n - 2] + 2.0;          390   p  = sig * secDerivative[n - 2] + 2.0;
393   un = (6.0 / (binVector[n] - binVector[n - 1]    391   un = (6.0 / (binVector[n] - binVector[n - 1])) *
394          (endPointDerivative - (dataVector[n]     392          (endPointDerivative - (dataVector[n] - dataVector[n - 1]) /
395                                  (binVector[n]    393                                  (binVector[n] - binVector[n - 1])) -
396        u[n - 1] / p;                              394        u[n - 1] / p;
397   secDerivative[n] = un / (secDerivative[n - 1    395   secDerivative[n] = un / (secDerivative[n - 1] + 2.0);
398                                                   396 
399   // The back-substitution loop for the triago    397   // The back-substitution loop for the triagonal algorithm of solving
400   // a linear system of equations.                398   // a linear system of equations.
401                                                   399 
402   for (std::size_t k = n - 1; k > 0; --k)      << 400   for(std::size_t k = n - 1; k > 0; --k)
403   {                                               401   {
404     secDerivative[k] *=                           402     secDerivative[k] *=
405       (secDerivative[k + 1] - u[k] * (binVecto    403       (secDerivative[k + 1] - u[k] * (binVector[k + 1] - binVector[k - 1]) /
406                                 (binVector[k +    404                                 (binVector[k + 1] - binVector[k]));
407   }                                               405   }
408   secDerivative[0] = 0.5 * (u[0] - secDerivati    406   secDerivative[0] = 0.5 * (u[0] - secDerivative[1]);
409                                                   407 
410   delete[] u;                                     408   delete[] u;
411 }                                                 409 }
412                                                   410 
413 // -------------------------------------------    411 // --------------------------------------------------------------
414 std::ostream& operator<<(std::ostream& out, co    412 std::ostream& operator<<(std::ostream& out, const G4PhysicsVector& pv)
415 {                                                 413 {
416   // binning                                      414   // binning
417   G4long prec = out.precision();                  415   G4long prec = out.precision();
418   out << std::setprecision(12) << pv.edgeMin <    416   out << std::setprecision(12) << pv.edgeMin << " " << pv.edgeMax << " "
419       << pv.numberOfNodes << G4endl;              417       << pv.numberOfNodes << G4endl;
420                                                   418 
421   // contents                                     419   // contents
422   out << pv.dataVector.size() << G4endl;          420   out << pv.dataVector.size() << G4endl;
423   for (std::size_t i = 0; i < pv.dataVector.si << 421   for(std::size_t i = 0; i < pv.dataVector.size(); ++i)
424   {                                               422   {
425     out << pv.binVector[i] << "  " << pv.dataV    423     out << pv.binVector[i] << "  " << pv.dataVector[i] << G4endl;
426   }                                               424   }
427   out.precision(prec);                            425   out.precision(prec);
428                                                   426 
429   return out;                                     427   return out;
430 }                                                 428 }
431                                                   429 
432 //--------------------------------------------    430 //---------------------------------------------------------------
433 G4double G4PhysicsVector::GetEnergy(const G4do    431 G4double G4PhysicsVector::GetEnergy(const G4double val) const
434 {                                                 432 {
435   if (0 == numberOfNodes)                      << 433   if(0 == numberOfNodes)
436   {                                               434   {
437     return 0.0;                                   435     return 0.0;
438   }                                               436   }
439   if (1 == numberOfNodes || val <= dataVector[ << 437   if(1 == numberOfNodes || val <= dataVector[0])
440   {                                               438   {
441     return edgeMin;                               439     return edgeMin;
442   }                                               440   }
443   if (val >= dataVector[numberOfNodes - 1])    << 441   if(val >= dataVector[numberOfNodes - 1])
444   {                                               442   {
445     return edgeMax;                               443     return edgeMax;
446   }                                               444   }
447   std::size_t bin = std::lower_bound(dataVecto    445   std::size_t bin = std::lower_bound(dataVector.cbegin(), dataVector.cend(), val)
448                   - dataVector.cbegin() - 1;      446                   - dataVector.cbegin() - 1;
449   if (bin > idxmax) { bin = idxmax; }          << 447   if(bin > idxmax) { bin = idxmax; } 
450   G4double res = binVector[bin];                  448   G4double res = binVector[bin];
451   G4double del = dataVector[bin + 1] - dataVec    449   G4double del = dataVector[bin + 1] - dataVector[bin];
452   if (del > 0.0)                               << 450   if(del > 0.0)
453   {                                               451   {
454     res += (val - dataVector[bin]) * (binVecto    452     res += (val - dataVector[bin]) * (binVector[bin + 1] - res) / del;
455   }                                               453   }
456   return res;                                     454   return res;
457 }                                                 455 }
458                                                   456 
459 //--------------------------------------------    457 //---------------------------------------------------------------
460 void G4PhysicsVector::PrintPutValueError(std::    458 void G4PhysicsVector::PrintPutValueError(std::size_t index, 
461                                          G4dou    459                                          G4double val, 
462                                          const    460                                          const G4String& text)
463 {                                                 461 {
464   G4ExceptionDescription ed;                      462   G4ExceptionDescription ed;
465   ed << "Vector type: " << type << " length= "    463   ed << "Vector type: " << type << " length= " << numberOfNodes
466      << "; an attempt to put data at index= "     464      << "; an attempt to put data at index= " << index
467      << " value= " << val << " in " << text;      465      << " value= " << val << " in " << text;
468   G4Exception("G4PhysicsVector:", "gl0005",       466   G4Exception("G4PhysicsVector:", "gl0005", 
469               FatalException, ed, "Wrong opera    467               FatalException, ed, "Wrong operation");
470 }                                                 468 }
471                                                   469 
472 //--------------------------------------------    470 //---------------------------------------------------------------
473                                                   471