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 10.0.p4)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4PhysicsVector class implementation        << 
 27 //                                                 26 //
 28 // Authors:                                    <<  27 // $Id: G4PhysicsVector.cc 74256 2013-10-02 14:24:02Z gcosmo $
 29 // - 02 Dec. 1995, G.Cosmo: Structure created  <<  28 //
 30 // - 03 Mar. 1996, K.Amako: Implemented the 1s <<  29 // 
 31 // Revisions:                                  <<  30 // --------------------------------------------------------------
 32 // - 11 Nov. 2000, H.Kurashige: Use STL vector <<  31 //      GEANT 4 class implementation file
 33 // ------------------------------------------- <<  32 //
                                                   >>  33 //  G4PhysicsVector.cc
                                                   >>  34 //
                                                   >>  35 //  History:
                                                   >>  36 //    02 Dec. 1995, G.Cosmo : Structure created based on object model
                                                   >>  37 //    03 Mar. 1996, K.Amako : Implemented the 1st version
                                                   >>  38 //    01 Jul. 1996, K.Amako : Hidden bin from the user introduced
                                                   >>  39 //    12 Nov. 1998, K.Amako : A bug in GetVectorLength() fixed
                                                   >>  40 //    11 Nov. 2000, H.Kurashige : use STL vector for dataVector and binVector
                                                   >>  41 //    18 Jan. 2001, H.Kurashige : removed ptrNextTable
                                                   >>  42 //    09 Mar. 2001, H.Kurashige : added G4PhysicsVector type 
                                                   >>  43 //    05 Sep. 2008, V.Ivanchenko : added protections for zero-length vector
                                                   >>  44 //    11 May  2009, A.Bagulya : added new implementation of methods 
                                                   >>  45 //            ComputeSecondDerivatives - first derivatives at edge points 
                                                   >>  46 //                                       should be provided by a user
                                                   >>  47 //            FillSecondDerivatives - default computation base on "not-a-knot"
                                                   >>  48 //                                    algorithm
                                                   >>  49 //    19 Jun. 2009, V.Ivanchenko : removed hidden bin 
                                                   >>  50 //    17 Nov. 2009, H.Kurashige   : use pointer for DataVector
                                                   >>  51 //    04 May  2010  H.Kurashige   : use G4PhyscisVectorCache
                                                   >>  52 //    28 May  2010  H.Kurashige  : Stop using  pointers to G4PVDataVector
                                                   >>  53 //    16 Aug. 2011  H.Kurashige  : Add dBin, baseBin and verboseLevel
                                                   >>  54 // --------------------------------------------------------------
 34                                                    55 
 35 #include "G4PhysicsVector.hh"                  << 
 36 #include <iomanip>                                 56 #include <iomanip>
                                                   >>  57 #include "G4PhysicsVector.hh"
                                                   >>  58 
                                                   >>  59 G4ThreadLocal G4Allocator<G4PhysicsVector> *fpPVAllocator = 0;
 37                                                    60 
 38 // -------------------------------------------     61 // --------------------------------------------------------------
 39 G4PhysicsVector::G4PhysicsVector(G4bool val)   << 
 40   : useSpline(val)                             << 
 41 {}                                             << 
 42                                                    62 
 43 // ------------------------------------------- <<  63 G4PhysicsVector::G4PhysicsVector(G4bool)
 44 void G4PhysicsVector::Initialise()             <<  64  : type(T_G4PhysicsVector),
                                                   >>  65    edgeMin(0.), edgeMax(0.), numberOfNodes(0),
                                                   >>  66    useSpline(false), 
                                                   >>  67    dBin(0.), baseBin(0.),
                                                   >>  68    verboseLevel(0)
 45 {                                                  69 {
 46   if (1 < numberOfNodes)                       <<  70   if (!fpPVAllocator) fpPVAllocator = new G4Allocator<G4PhysicsVector>;
 47   {                                            <<  71   // g4pow = G4Pow::GetInstance();
 48     idxmax = numberOfNodes - 2;                <<  72 }
 49     edgeMin = binVector[0];                    <<  73 
 50     edgeMax = binVector[idxmax + 1];           <<  74 // --------------------------------------------------------------
                                                   >>  75 
                                                   >>  76 G4PhysicsVector::~G4PhysicsVector() 
                                                   >>  77 {
                                                   >>  78 }
                                                   >>  79 
                                                   >>  80 // --------------------------------------------------------------
                                                   >>  81 
                                                   >>  82 G4PhysicsVector::G4PhysicsVector(const G4PhysicsVector& right)
                                                   >>  83 {
                                                   >>  84   //  g4pow = G4Pow::GetInstance();
                                                   >>  85 
                                                   >>  86   dBin         = right.dBin;
                                                   >>  87   baseBin      = right.baseBin;
                                                   >>  88   verboseLevel = right.verboseLevel;
                                                   >>  89 
                                                   >>  90   DeleteData();
                                                   >>  91   CopyData(right);
                                                   >>  92 }
                                                   >>  93 
                                                   >>  94 // --------------------------------------------------------------
                                                   >>  95 
                                                   >>  96 G4PhysicsVector& G4PhysicsVector::operator=(const G4PhysicsVector& right)
                                                   >>  97 {
                                                   >>  98   if (&right==this)  { return *this; }
                                                   >>  99   dBin         = right.dBin;
                                                   >> 100   baseBin      = right.baseBin;
                                                   >> 101   verboseLevel = right.verboseLevel;
                                                   >> 102 
                                                   >> 103   DeleteData();
                                                   >> 104   CopyData(right);
                                                   >> 105   return *this;
                                                   >> 106 }
                                                   >> 107 
                                                   >> 108 // --------------------------------------------------------------
                                                   >> 109 
                                                   >> 110 G4int G4PhysicsVector::operator==(const G4PhysicsVector &right) const
                                                   >> 111 {
                                                   >> 112   return (this == &right);
                                                   >> 113 }
                                                   >> 114 
                                                   >> 115 // --------------------------------------------------------------
                                                   >> 116 
                                                   >> 117 G4int G4PhysicsVector::operator!=(const G4PhysicsVector &right) const
                                                   >> 118 {
                                                   >> 119   return (this != &right);
                                                   >> 120 }
                                                   >> 121 
                                                   >> 122 // --------------------------------------------------------------
                                                   >> 123 
                                                   >> 124 void G4PhysicsVector::DeleteData()
                                                   >> 125 {
                                                   >> 126   useSpline = false;
                                                   >> 127   secDerivative.clear();
                                                   >> 128 }
                                                   >> 129 
                                                   >> 130 // --------------------------------------------------------------
                                                   >> 131 
                                                   >> 132 void G4PhysicsVector::CopyData(const G4PhysicsVector& vec)
                                                   >> 133 {
                                                   >> 134   type = vec.type;
                                                   >> 135   edgeMin = vec.edgeMin;
                                                   >> 136   edgeMax = vec.edgeMax;
                                                   >> 137   numberOfNodes = vec.numberOfNodes;
                                                   >> 138   useSpline = vec.useSpline;
                                                   >> 139 
                                                   >> 140   size_t i;
                                                   >> 141   dataVector.clear();
                                                   >> 142   for(i=0; i<(vec.dataVector).size(); i++){ 
                                                   >> 143     dataVector.push_back( (vec.dataVector)[i] );
                                                   >> 144   }
                                                   >> 145   binVector.clear();
                                                   >> 146   for(i=0; i<(vec.binVector).size(); i++){ 
                                                   >> 147     binVector.push_back( (vec.binVector)[i] );
                                                   >> 148   }
                                                   >> 149   secDerivative.clear();
                                                   >> 150   for(i=0; i<(vec.secDerivative).size(); i++){ 
                                                   >> 151     secDerivative.push_back( (vec.secDerivative)[i] );
 51   }                                               152   }
 52 }                                                 153 }
 53                                                   154 
 54 // -------------------------------------------    155 // --------------------------------------------------------------
 55 G4bool G4PhysicsVector::Store(std::ofstream& f << 156 
                                                   >> 157 G4double G4PhysicsVector::GetLowEdgeEnergy(size_t binNumber) const
                                                   >> 158 {
                                                   >> 159   return binVector[binNumber];
                                                   >> 160 }
                                                   >> 161 
                                                   >> 162 // --------------------------------------------------------------
                                                   >> 163 
                                                   >> 164 G4bool G4PhysicsVector::Store(std::ofstream& fOut, G4bool ascii)
 56 {                                                 165 {
 57   // Ascii mode                                   166   // Ascii mode
 58   if (ascii)                                      167   if (ascii)
 59   {                                               168   {
 60     fOut << *this;                                169     fOut << *this;
 61     return true;                                  170     return true;
 62   }                                            << 171   } 
 63   // Binary Mode                                  172   // Binary Mode
 64                                                   173 
 65   // binning                                      174   // binning
 66   fOut.write((char*) (&edgeMin), sizeof edgeMi << 175   fOut.write((char*)(&edgeMin), sizeof edgeMin);
 67   fOut.write((char*) (&edgeMax), sizeof edgeMa << 176   fOut.write((char*)(&edgeMax), sizeof edgeMax);
 68   fOut.write((char*) (&numberOfNodes), sizeof  << 177   fOut.write((char*)(&numberOfNodes), sizeof numberOfNodes);
 69                                                   178 
 70   // contents                                     179   // contents
 71   std::size_t size = dataVector.size();        << 180   size_t size = dataVector.size(); 
 72   fOut.write((char*) (&size), sizeof size);    << 181   fOut.write((char*)(&size), sizeof size);
 73                                                   182 
 74   auto value = new G4double[2 * size];         << 183   G4double* value = new G4double[2*size];
 75   for (std::size_t i = 0; i < size; ++i)       << 184   for(size_t i = 0; i < size; ++i)
 76   {                                               185   {
 77     value[2 * i]     = binVector[i];           << 186     value[2*i]  =  binVector[i];
 78     value[2 * i + 1] = dataVector[i];          << 187     value[2*i+1]=  dataVector[i];
 79   }                                               188   }
 80   fOut.write((char*) (value), 2 * size * (size << 189   fOut.write((char*)(value), 2*size*(sizeof (G4double)));
 81   delete[] value;                              << 190   delete [] value;
 82                                                   191 
 83   return true;                                    192   return true;
 84 }                                                 193 }
 85                                                   194 
 86 // -------------------------------------------    195 // --------------------------------------------------------------
                                                   >> 196 
 87 G4bool G4PhysicsVector::Retrieve(std::ifstream    197 G4bool G4PhysicsVector::Retrieve(std::ifstream& fIn, G4bool ascii)
 88 {                                                 198 {
 89   // clear properties;                            199   // clear properties;
 90   dataVector.clear();                             200   dataVector.clear();
 91   binVector.clear();                              201   binVector.clear();
 92   secDerivative.clear();                          202   secDerivative.clear();
 93                                                   203 
 94   // retrieve in ascii mode                       204   // retrieve in ascii mode
 95   if (ascii)                                   << 205   if (ascii){
 96   {                                            << 
 97     // binning                                    206     // binning
 98     fIn >> edgeMin >> edgeMax >> numberOfNodes << 207     fIn >> edgeMin >> edgeMax >> numberOfNodes; 
 99     if (fIn.fail() || numberOfNodes < 2)       << 208     if (fIn.fail())  { return false; }
100     {                                          << 
101       return false;                            << 
102     }                                          << 
103     // contents                                   209     // contents
104     G4int siz0 = 0;                            << 210     G4int siz=0;
105     fIn >> siz0;                               << 211     fIn >> siz;
106     if (siz0 < 2) { return false; }            << 212     if (fIn.fail())  { return false; }
107     auto siz = static_cast<std::size_t>(siz0); << 213     if (siz<=0)
108     if (fIn.fail() || siz != numberOfNodes)    << 
109     {                                             214     {
                                                   >> 215 #ifdef G4VERBOSE  
                                                   >> 216       G4cerr << "G4PhysicsVector::Retrieve():";
                                                   >> 217       G4cerr << " Invalid vector size: " << siz << G4endl;
                                                   >> 218 #endif
110       return false;                               219       return false;
111     }                                             220     }
112                                                   221 
113     binVector.reserve(siz);                       222     binVector.reserve(siz);
114     dataVector.reserve(siz);                      223     dataVector.reserve(siz);
115     G4double vBin, vData;                         224     G4double vBin, vData;
116                                                   225 
117     for (std::size_t i = 0; i < siz; ++i)      << 226     for(G4int i = 0; i < siz ; i++)
118     {                                             227     {
119       vBin  = 0.;                              << 228       vBin = 0.;
120       vData = 0.;                              << 229       vData= 0.;
121       fIn >> vBin >> vData;                       230       fIn >> vBin >> vData;
122       if (fIn.fail())                          << 231       if (fIn.fail())  { return false; }
123       {                                        << 
124         return false;                          << 
125       }                                        << 
126       binVector.push_back(vBin);                  232       binVector.push_back(vBin);
127       dataVector.push_back(vData);                233       dataVector.push_back(vData);
128     }                                             234     }
129     Initialise();                              << 235 
130     return true;                               << 236     // to remove any inconsistency 
                                                   >> 237     numberOfNodes = siz;
                                                   >> 238     edgeMin = binVector[0];
                                                   >> 239     edgeMax = binVector[numberOfNodes-1];
                                                   >> 240     return true ;
131   }                                               241   }
132                                                   242 
133   // retrieve in binary mode                      243   // retrieve in binary mode
134   // binning                                      244   // binning
135   fIn.read((char*) (&edgeMin), sizeof edgeMin) << 245   fIn.read((char*)(&edgeMin), sizeof edgeMin);
136   fIn.read((char*) (&edgeMax), sizeof edgeMax) << 246   fIn.read((char*)(&edgeMax), sizeof edgeMax);
137   fIn.read((char*) (&numberOfNodes), sizeof nu << 247   fIn.read((char*)(&numberOfNodes), sizeof numberOfNodes ); 
138                                                << 248  
139   // contents                                     249   // contents
140   std::size_t size;                            << 250   size_t size;
141   fIn.read((char*) (&size), sizeof size);      << 251   fIn.read((char*)(&size), sizeof size); 
142                                                << 252  
143   auto value = new G4double[2 * size];         << 253   G4double* value = new G4double[2*size];
144   fIn.read((char*) (value), 2 * size * (sizeof << 254   fIn.read((char*)(value),  2*size*(sizeof(G4double)) );
145   if (static_cast<G4int>(fIn.gcount()) != stat << 255   if (G4int(fIn.gcount()) != G4int(2*size*(sizeof(G4double))) )
146   {                                               256   {
147     delete[] value;                            << 257     delete [] value;
148     return false;                                 258     return false;
149   }                                               259   }
150                                                   260 
151   binVector.reserve(size);                        261   binVector.reserve(size);
152   dataVector.reserve(size);                       262   dataVector.reserve(size);
153   for (std::size_t i = 0; i < size; ++i)       << 263   for(size_t i = 0; i < size; ++i)
154   {                                               264   {
155     binVector.push_back(value[2 * i]);         << 265     binVector.push_back(value[2*i]);
156     dataVector.push_back(value[2 * i + 1]);    << 266     dataVector.push_back(value[2*i+1]);
157   }                                               267   }
158   delete[] value;                              << 268   delete [] value;
                                                   >> 269 
                                                   >> 270   // to remove any inconsistency 
                                                   >> 271   numberOfNodes = size;
                                                   >> 272   edgeMin = binVector[0];
                                                   >> 273   edgeMax = binVector[numberOfNodes-1];
159                                                   274 
160   Initialise();                                << 
161   return true;                                    275   return true;
162 }                                                 276 }
163                                                   277 
164 // -------------------------------------------    278 // --------------------------------------------------------------
165 void G4PhysicsVector::DumpValues(G4double unit << 
166 {                                              << 
167   for (std::size_t i = 0; i < numberOfNodes; + << 
168   {                                            << 
169     G4cout << binVector[i] / unitE << "   " << << 
170            << G4endl;                          << 
171   }                                            << 
172 }                                              << 
173                                                   279 
174 // ------------------------------------------- << 280 void 
175 std::size_t G4PhysicsVector::FindBin(const G4d << 281 G4PhysicsVector::ScaleVector(G4double factorE, G4double factorV)
176                                      std::size << 
177 {                                                 282 {
178   if (idx + 1 < numberOfNodes &&               << 283   size_t n = dataVector.size();
179       energy >= binVector[idx] && energy <= bi << 284   size_t i;
180   {                                            << 285   if(n > 0) { 
181     return idx;                                << 286     for(i=0; i<n; ++i) {
182   }                                            << 287       binVector[i]  *= factorE;
183   if (energy <= binVector[1])                  << 288       dataVector[i] *= factorV;
184   {                                            << 289     } 
185     return 0;                                  << 
186   }                                            << 
187   if (energy >= binVector[idxmax])             << 
188   {                                            << 
189     return idxmax;                             << 
190   }                                               290   }
191   return GetBin(energy);                       << 291   //  n = secDerivative.size();
192 }                                              << 292   // if(n > 0) { for(i=0; i<n; ++i) { secDerivative[i] *= factorV; } }
                                                   >> 293   secDerivative.clear();
193                                                   294 
194 // ------------------------------------------- << 295   edgeMin *= factorE;
195 void G4PhysicsVector::ScaleVector(const G4doub << 296   edgeMax *= factorE;
196                                   const G4doub << 
197 {                                              << 
198   for (std::size_t i = 0; i < numberOfNodes; + << 
199   {                                            << 
200     binVector[i] *= factorE;                   << 
201     dataVector[i] *= factorV;                  << 
202   }                                            << 
203   Initialise();                                << 
204 }                                                 297 }
205                                                   298 
206 // ------------------------------------------- << 299 // --------------------------------------------------------------
207 void G4PhysicsVector::FillSecondDerivatives(co << 300 
208               const G4double dir1,             << 301 void 
209               const G4double dir2)             << 302 G4PhysicsVector::ComputeSecondDerivatives(G4double firstPointDerivative, 
                                                   >> 303                                           G4double endPointDerivative)
                                                   >> 304   //  A standard method of computation of second derivatives 
                                                   >> 305   //  First derivatives at the first and the last point should be provided
                                                   >> 306   //  See for example W.H. Press et al. "Numerical recipes in C"
                                                   >> 307   //  Cambridge University Press, 1997.
210 {                                                 308 {
211   if (!useSpline) { return; }                  << 309   if(4 > numberOfNodes)   // cannot compute derivatives for less than 4 bins
212   // cannot compute derivatives for less than  << 
213   const std::size_t nmin = (stype == G4SplineT << 
214   if (nmin > numberOfNodes)                    << 
215   {                                               310   {
216     if (0 < verboseLevel)                      << 311     ComputeSecDerivatives();
217     {                                          << 
218       G4cout << "### G4PhysicsVector: spline c << 
219        << numberOfNodes << " points - spline d << 
220        << G4endl;                              << 
221       DumpValues();                            << 
222     }                                          << 
223     useSpline = false;                         << 
224     return;                                       312     return;
225   }                                               313   }
226   // check energies of free vector             << 
227   if (type == T_G4PhysicsFreeVector)           << 
228   {                                            << 
229     for (std::size_t i=0; i<=idxmax; ++i)      << 
230     {                                          << 
231       if (binVector[i + 1] <= binVector[i])    << 
232       {                                        << 
233         if (0 < verboseLevel)                  << 
234         {                                      << 
235     G4cout << "### G4PhysicsVector: spline can << 
236      << " E[" << i << "]=" << binVector[i]     << 
237      << " >= E[" << i+1 << "]=" << binVector[i << 
238      << G4endl;                                << 
239     DumpValues();                              << 
240         }                                      << 
241         useSpline = false;                     << 
242         return;                                << 
243       }                                        << 
244     }                                          << 
245   }                                            << 
246                                                   314 
247   // spline is possible                        << 315   if(!SplinePossible()) { return; }
248   Initialise();                                << 
249   secDerivative.resize(numberOfNodes);         << 
250                                                   316 
251   if (1 < verboseLevel)                        << 317   useSpline = true;
252   {                                            << 
253     G4cout << "### G4PhysicsVector:: FillSecon << 
254            << numberOfNodes << G4endl;         << 
255     DumpValues();                              << 
256   }                                            << 
257                                                   318 
258   switch(stype)                                << 319   G4int n = numberOfNodes-1;
259   {                                            << 
260     case G4SplineType::Base:                   << 
261       ComputeSecDerivative1();                 << 
262       break;                                   << 
263                                                   320 
264     case G4SplineType::FixedEdges:             << 321   G4double* u = new G4double [n];
265       ComputeSecDerivative2(dir1, dir2);       << 322   
266       break;                                   << 323   G4double p, sig, un;
267                                                   324 
268     default:                                   << 325   u[0] = (6.0/(binVector[1]-binVector[0]))
269       ComputeSecDerivative0();                 << 326     * ((dataVector[1]-dataVector[0])/(binVector[1]-binVector[0])
270   }                                            << 327        - firstPointDerivative);
271 }                                              << 328  
                                                   >> 329   secDerivative[0] = - 0.5;
272                                                   330 
273 // ------------------------------------------- << 331   // Decomposition loop for tridiagonal algorithm. secDerivative[i]
274 void G4PhysicsVector::ComputeSecDerivative0()  << 332   // and u[i] are used for temporary storage of the decomposed factors.
275 //  A simplified method of computation of seco << 333 
276 {                                              << 334   for(G4int i=1; i<n; ++i)
277   std::size_t n = numberOfNodes - 1;           << 335   {
                                                   >> 336     sig = (binVector[i]-binVector[i-1]) / (binVector[i+1]-binVector[i-1]);
                                                   >> 337     p = sig*(secDerivative[i-1]) + 2.0;
                                                   >> 338     secDerivative[i] = (sig - 1.0)/p;
                                                   >> 339     u[i] = (dataVector[i+1]-dataVector[i])/(binVector[i+1]-binVector[i])
                                                   >> 340          - (dataVector[i]-dataVector[i-1])/(binVector[i]-binVector[i-1]);
                                                   >> 341     u[i] = 6.0*u[i]/(binVector[i+1]-binVector[i-1]) - sig*u[i-1]/p;
                                                   >> 342   }
                                                   >> 343 
                                                   >> 344   sig = (binVector[n-1]-binVector[n-2]) / (binVector[n]-binVector[n-2]);
                                                   >> 345   p = sig*secDerivative[n-2] + 2.0;
                                                   >> 346   un = (6.0/(binVector[n]-binVector[n-1]))
                                                   >> 347     *(endPointDerivative - 
                                                   >> 348       (dataVector[n]-dataVector[n-1])/(binVector[n]-binVector[n-1])) - u[n-1]/p;
                                                   >> 349   secDerivative[n] = un/(secDerivative[n-1] + 2.0);
278                                                   350 
279   for (std::size_t i = 1; i < n; ++i)          << 351   // The back-substitution loop for the triagonal algorithm of solving
                                                   >> 352   // a linear system of equations.
                                                   >> 353    
                                                   >> 354   for(G4int k=n-1; k>0; --k)
280   {                                               355   {
281     secDerivative[i] = 3.0 *                   << 356     secDerivative[k] *= 
282       ((dataVector[i + 1] - dataVector[i]) / ( << 357       (secDerivative[k+1] - 
283        (dataVector[i] - dataVector[i - 1]) /   << 358        u[k]*(binVector[k+1]-binVector[k-1])/(binVector[k+1]-binVector[k]));
284          (binVector[i] - binVector[i - 1])) /  << 
285       (binVector[i + 1] - binVector[i - 1]);   << 
286   }                                               359   }
287   secDerivative[n] = secDerivative[n - 1];     << 360   secDerivative[0] = 0.5*(u[0] - secDerivative[1]);
288   secDerivative[0] = secDerivative[1];         << 361 
                                                   >> 362   delete [] u;
289 }                                                 363 }
290                                                   364 
291 // -------------------------------------------    365 // --------------------------------------------------------------
292 void G4PhysicsVector::ComputeSecDerivative1()  << 366 
293 // Computation of second derivatives using "No << 367 void G4PhysicsVector::FillSecondDerivatives()
294 // B.I. Kvasov "Methods of shape-preserving sp << 368   // Computation of second derivatives using "Not-a-knot" endpoint conditions
295 // World Scientific, 2000                      << 369   // B.I. Kvasov "Methods of shape-preserving spline approximation"
                                                   >> 370   // World Scientific, 2000
296 {                                                 371 {
297   std::size_t n = numberOfNodes - 1;           << 372   if(5 > numberOfNodes)  // cannot compute derivatives for less than 4 points
298   auto u = new G4double[n];                    << 373   {
299   G4double p, sig;                             << 374     ComputeSecDerivatives();
                                                   >> 375     return;
                                                   >> 376   }
                                                   >> 377 
                                                   >> 378   if(!SplinePossible()) { return; }
300                                                   379 
301   u[1] = ((dataVector[2] - dataVector[1]) / (b << 380   useSpline = true;
302           (dataVector[1] - dataVector[0]) / (b << 381  
303   u[1] = 6.0 * u[1] * (binVector[2] - binVecto << 382   G4int n = numberOfNodes-1;
304          ((binVector[2] - binVector[0]) * (bin << 383 
                                                   >> 384   G4double* u = new G4double [n];
                                                   >> 385   
                                                   >> 386   G4double p, sig;
305                                                   387 
                                                   >> 388   u[1] = ((dataVector[2]-dataVector[1])/(binVector[2]-binVector[1]) -
                                                   >> 389           (dataVector[1]-dataVector[0])/(binVector[1]-binVector[0]));
                                                   >> 390   u[1] = 6.0*u[1]*(binVector[2]-binVector[1])
                                                   >> 391     / ((binVector[2]-binVector[0])*(binVector[2]-binVector[0]));
                                                   >> 392  
306   // Decomposition loop for tridiagonal algori    393   // Decomposition loop for tridiagonal algorithm. secDerivative[i]
307   // and u[i] are used for temporary storage o    394   // and u[i] are used for temporary storage of the decomposed factors.
308                                                   395 
309   secDerivative[1] = (2.0 * binVector[1] - bin << 396   secDerivative[1] = (2.0*binVector[1]-binVector[0]-binVector[2])
310                      (2.0 * binVector[2] - bin << 397     / (2.0*binVector[2]-binVector[0]-binVector[1]);
311                                                   398 
312   for(std::size_t i = 2; i < n - 1; ++i)       << 399   for(G4int i=2; i<n-1; ++i)
313   {                                               400   {
314     sig =                                      << 401     sig = (binVector[i]-binVector[i-1]) / (binVector[i+1]-binVector[i-1]);
315       (binVector[i] - binVector[i - 1]) / (bin << 402     p = sig*secDerivative[i-1] + 2.0;
316     p                = sig * secDerivative[i - << 403     secDerivative[i] = (sig - 1.0)/p;
317     secDerivative[i] = (sig - 1.0) / p;        << 404     u[i] = (dataVector[i+1]-dataVector[i])/(binVector[i+1]-binVector[i])
318     u[i] =                                     << 405          - (dataVector[i]-dataVector[i-1])/(binVector[i]-binVector[i-1]);
319       (dataVector[i + 1] - dataVector[i]) / (b << 406     u[i] = (6.0*u[i]/(binVector[i+1]-binVector[i-1])) - sig*u[i-1]/p;
320       (dataVector[i] - dataVector[i - 1]) / (b << 407   }
321     u[i] =                                     << 408 
322       (6.0 * u[i] / (binVector[i + 1] - binVec << 409   sig = (binVector[n-1]-binVector[n-2]) / (binVector[n]-binVector[n-2]);
323   }                                            << 410   p = sig*secDerivative[n-3] + 2.0;
324                                                << 411   u[n-1] = (dataVector[n]-dataVector[n-1])/(binVector[n]-binVector[n-1])
325   sig =                                        << 412     - (dataVector[n-1]-dataVector[n-2])/(binVector[n-1]-binVector[n-2]);
326     (binVector[n - 1] - binVector[n - 2]) / (b << 413   u[n-1] = 6.0*sig*u[n-1]/(binVector[n]-binVector[n-2])
327   p = sig * secDerivative[n - 3] + 2.0;        << 414     - (2.0*sig - 1.0)*u[n-2]/p;  
328   u[n - 1] =                                   << 
329     (dataVector[n] - dataVector[n - 1]) / (bin << 
330     (dataVector[n - 1] - dataVector[n - 2]) /  << 
331       (binVector[n - 1] - binVector[n - 2]);   << 
332   u[n - 1] = 6.0 * sig * u[n - 1] / (binVector << 
333              (2.0 * sig - 1.0) * u[n - 2] / p; << 
334                                                   415 
335   p = (1.0 + sig) + (2.0 * sig - 1.0) * secDer << 416   p = (1.0+sig) + (2.0*sig-1.0)*secDerivative[n-2];
336   secDerivative[n - 1] = u[n - 1] / p;         << 417   secDerivative[n-1] = u[n-1]/p;
337                                                   418 
338   // The back-substitution loop for the triago    419   // The back-substitution loop for the triagonal algorithm of solving
339   // a linear system of equations.                420   // a linear system of equations.
340                                                << 421    
341   for (std::size_t k = n - 2; k > 1; --k)      << 422   for(G4int k=n-2; k>1; --k)
342   {                                               423   {
343     secDerivative[k] *=                        << 424     secDerivative[k] *= 
344       (secDerivative[k + 1] - u[k] * (binVecto << 425       (secDerivative[k+1] - 
345                                 (binVector[k + << 426        u[k]*(binVector[k+1]-binVector[k-1])/(binVector[k+1]-binVector[k]));
346   }                                            << 427   }
347   secDerivative[n] =                           << 428   secDerivative[n] = (secDerivative[n-1] - (1.0-sig)*secDerivative[n-2])/sig;
348     (secDerivative[n - 1] - (1.0 - sig) * secD << 429   sig = 1.0 - ((binVector[2]-binVector[1])/(binVector[2]-binVector[0]));
349   sig = 1.0 - ((binVector[2] - binVector[1]) / << 430   secDerivative[1] *= (secDerivative[2] - u[1]/(1.0-sig));
350   secDerivative[1] *= (secDerivative[2] - u[1] << 431   secDerivative[0]  = (secDerivative[1] - sig*secDerivative[2])/(1.0-sig);
351   secDerivative[0] = (secDerivative[1] - sig * << 
352                                                   432 
353   delete[] u;                                  << 433   delete [] u;
354 }                                                 434 }
355                                                   435 
356 // -------------------------------------------    436 // --------------------------------------------------------------
357 void G4PhysicsVector::ComputeSecDerivative2(G4 << 437 
358                                             G4 << 438 void 
359 // A standard method of computation of second  << 439 G4PhysicsVector::ComputeSecDerivatives()
360 // First derivatives at the first and the last << 440   //  A simplified method of computation of second derivatives 
361 // See for example W.H. Press et al. "Numerica << 
362 // Cambridge University Press, 1997.           << 
363 {                                                 441 {
364   std::size_t n = numberOfNodes - 1;           << 442   if(3 > numberOfNodes)  // cannot compute derivatives for less than 4 bins
365   auto u = new G4double[n];                    << 443   {
366   G4double p, sig, un;                         << 444     useSpline = false;
                                                   >> 445     return;
                                                   >> 446   }
367                                                   447 
368   u[0] = (6.0 / (binVector[1] - binVector[0])) << 448   if(!SplinePossible())  { return; }
369          ((dataVector[1] - dataVector[0]) / (b << 
370           firstPointDerivative);               << 
371                                                   449 
372   secDerivative[0] = -0.5;                     << 450   useSpline = true;
373                                                   451 
374   // Decomposition loop for tridiagonal algori << 452   size_t n = numberOfNodes-1;
375   // and u[i] are used for temporary storage o << 
376                                                   453 
377   for (std::size_t i = 1; i < n; ++i)          << 454   for(size_t i=1; i<n; ++i)
378   {                                               455   {
379     sig =                                      << 456     secDerivative[i] =
380       (binVector[i] - binVector[i - 1]) / (bin << 457       3.0*((dataVector[i+1]-dataVector[i])/(binVector[i+1]-binVector[i]) -
381     p                = sig * (secDerivative[i  << 458            (dataVector[i]-dataVector[i-1])/(binVector[i]-binVector[i-1]))
382     secDerivative[i] = (sig - 1.0) / p;        << 459       /(binVector[i+1]-binVector[i-1]);
383     u[i] =                                     << 460   }
384       (dataVector[i + 1] - dataVector[i]) / (b << 461   secDerivative[n] = secDerivative[n-1];
385       (dataVector[i] - dataVector[i - 1]) / (b << 462   secDerivative[0] = secDerivative[1];
386     u[i] =                                     << 463 }
387       6.0 * u[i] / (binVector[i + 1] - binVect << 
388   }                                            << 
389                                                << 
390   sig =                                        << 
391     (binVector[n - 1] - binVector[n - 2]) / (b << 
392   p  = sig * secDerivative[n - 2] + 2.0;       << 
393   un = (6.0 / (binVector[n] - binVector[n - 1] << 
394          (endPointDerivative - (dataVector[n]  << 
395                                  (binVector[n] << 
396        u[n - 1] / p;                           << 
397   secDerivative[n] = un / (secDerivative[n - 1 << 
398                                                   464 
399   // The back-substitution loop for the triago << 465 // --------------------------------------------------------------
400   // a linear system of equations.             << 
401                                                   466 
402   for (std::size_t k = n - 1; k > 0; --k)      << 467 G4bool G4PhysicsVector::SplinePossible()
                                                   >> 468   // Initialise second derivative array. If neighbor energy coincide 
                                                   >> 469   // or not ordered than spline cannot be applied
                                                   >> 470 {
                                                   >> 471   G4bool result = true;
                                                   >> 472   secDerivative.clear();
                                                   >> 473   secDerivative.reserve(numberOfNodes);
                                                   >> 474   for(size_t j=0; j<numberOfNodes; ++j)
403   {                                               475   {
404     secDerivative[k] *=                        << 476     secDerivative.push_back(0.0);
405       (secDerivative[k + 1] - u[k] * (binVecto << 477     if(j > 0)
406                                 (binVector[k + << 478     {
407   }                                            << 479       if(binVector[j]-binVector[j-1] <= 0.)  { 
408   secDerivative[0] = 0.5 * (u[0] - secDerivati << 480   result = false; 
409                                                << 481   secDerivative.clear();
410   delete[] u;                                  << 482   break;
                                                   >> 483       }
                                                   >> 484     }
                                                   >> 485   }  
                                                   >> 486   return result;
411 }                                                 487 }
412                                                << 488    
413 // -------------------------------------------    489 // --------------------------------------------------------------
                                                   >> 490 
414 std::ostream& operator<<(std::ostream& out, co    491 std::ostream& operator<<(std::ostream& out, const G4PhysicsVector& pv)
415 {                                                 492 {
416   // binning                                      493   // binning
417   G4long prec = out.precision();               << 494   out << std::setprecision(12) << pv.edgeMin << " "
418   out << std::setprecision(12) << pv.edgeMin < << 495       << pv.edgeMax << " " << pv.numberOfNodes << G4endl; 
419       << pv.numberOfNodes << G4endl;           << 
420                                                   496 
421   // contents                                     497   // contents
422   out << pv.dataVector.size() << G4endl;       << 498   out << pv.dataVector.size() << G4endl; 
423   for (std::size_t i = 0; i < pv.dataVector.si << 499   for(size_t i = 0; i < pv.dataVector.size(); i++)
424   {                                               500   {
425     out << pv.binVector[i] << "  " << pv.dataV    501     out << pv.binVector[i] << "  " << pv.dataVector[i] << G4endl;
426   }                                               502   }
427   out.precision(prec);                         << 503   out << std::setprecision(6);
428                                                   504 
429   return out;                                     505   return out;
430 }                                                 506 }
431                                                   507 
432 //--------------------------------------------    508 //---------------------------------------------------------------
433 G4double G4PhysicsVector::GetEnergy(const G4do << 509 
                                                   >> 510 G4double 
                                                   >> 511 G4PhysicsVector::Value(G4double theEnergy, size_t& lastIdx) const
434 {                                                 512 {
435   if (0 == numberOfNodes)                      << 513   G4double y;
436   {                                            << 514   if(theEnergy <= edgeMin) {
437     return 0.0;                                << 515     lastIdx = 0; 
438   }                                            << 516     y = dataVector[0]; 
439   if (1 == numberOfNodes || val <= dataVector[ << 517   } else if(theEnergy >= edgeMax) { 
440   {                                            << 518     lastIdx = numberOfNodes-1; 
441     return edgeMin;                            << 519     y = dataVector[lastIdx]; 
442   }                                            << 520   } else {
443   if (val >= dataVector[numberOfNodes - 1])    << 521     lastIdx = FindBin(theEnergy, lastIdx);
444   {                                            << 522     y = Interpolation(lastIdx, theEnergy);
445     return edgeMax;                            << 
446   }                                            << 
447   std::size_t bin = std::lower_bound(dataVecto << 
448                   - dataVector.cbegin() - 1;   << 
449   if (bin > idxmax) { bin = idxmax; }          << 
450   G4double res = binVector[bin];               << 
451   G4double del = dataVector[bin + 1] - dataVec << 
452   if (del > 0.0)                               << 
453   {                                            << 
454     res += (val - dataVector[bin]) * (binVecto << 
455   }                                               523   }
456   return res;                                  << 524   return y;
457 }                                                 525 }
458                                                   526 
459 //--------------------------------------------    527 //---------------------------------------------------------------
460 void G4PhysicsVector::PrintPutValueError(std:: << 528 
461                                          G4dou << 529 G4double G4PhysicsVector::FindLinearEnergy(G4double rand) const
462                                          const << 530 {
463 {                                              << 531   if(1 >= numberOfNodes) { return 0.0; }
464   G4ExceptionDescription ed;                   << 532   size_t n1 = 0;
465   ed << "Vector type: " << type << " length= " << 533   size_t n2 = numberOfNodes/2;
466      << "; an attempt to put data at index= "  << 534   size_t n3 = numberOfNodes - 1;
467      << " value= " << val << " in " << text;   << 535   G4double y = rand*dataVector[n3];
468   G4Exception("G4PhysicsVector:", "gl0005",    << 536   while (n1 + 1 != n3)
469               FatalException, ed, "Wrong opera << 537     {
                                                   >> 538       if (y > dataVector[n2])
                                                   >> 539   { n1 = n2; }
                                                   >> 540       else
                                                   >> 541   { n3 = n2; }
                                                   >> 542       n2 = (n3 + n1 + 1)/2;
                                                   >> 543     }
                                                   >> 544   G4double res = binVector[n1];
                                                   >> 545   G4double del = dataVector[n3] - dataVector[n1];
                                                   >> 546   if(del > 0.0) { 
                                                   >> 547     res += (y - dataVector[n1])*(binVector[n3] - res)/del;  
                                                   >> 548   }
                                                   >> 549   return res;
470 }                                                 550 }
471                                                   551 
472 //--------------------------------------------    552 //---------------------------------------------------------------
473                                                   553