00001 // 00002 // ******************************************************************** 00003 // * License and Disclaimer * 00004 // * * 00005 // * The Geant4 software is copyright of the Copyright Holders of * 00006 // * the Geant4 Collaboration. It is provided under the terms and * 00007 // * conditions of the Geant4 Software License, included in the file * 00008 // * LICENSE and available at http://cern.ch/geant4/license . These * 00009 // * include a list of copyright holders. * 00010 // * * 00011 // * Neither the authors of this software system, nor their employing * 00012 // * institutes,nor the agencies providing financial support for this * 00013 // * work make any representation or warranty, express or implied, * 00014 // * regarding this software system or assume any liability for its * 00015 // * use. Please see the license in the file LICENSE and URL above * 00016 // * for the full disclaimer and the limitation of liability. * 00017 // * * 00018 // * This code implementation is the result of the scientific and * 00019 // * technical work of the GEANT4 collaboration. * 00020 // * By using, copying, modifying or distributing the software (or * 00021 // * any work based on the software) you agree to acknowledge its * 00022 // * use in resulting scientific publications, and indicate your * 00023 // * acceptance of all terms of the Geant4 Software license. * 00024 // ******************************************************************** 00025 // 00026 // 00027 // $Id$ 00028 // 00029 // 00030 //--------------------------------------------------------------- 00031 // GEANT 4 class source file 00032 // 00033 // G4PhysicsVector.icc 00034 // 00035 // Description: 00036 // A physics vector which has values of energy-loss, cross-section, 00037 // and other physics values of a particle in matter in a given 00038 // range of the energy, momentum, etc. 00039 // This class serves as the base class for a vector having various 00040 // energy scale, for example like 'log', 'linear', 'free', etc. 00041 // 00042 //--------------------------------------------------------------- 00043 00044 #if defined G4GLOB_ALLOC_EXPORT 00045 extern G4DLLEXPORT G4Allocator<G4PhysicsVector> aPVAllocator; 00046 #else 00047 extern G4DLLIMPORT G4Allocator<G4PhysicsVector> aPVAllocator; 00048 #endif 00049 00050 inline void* G4PhysicsVector::operator new(size_t) 00051 { 00052 void* aVector; 00053 aVector = (void*)aPVAllocator.MallocSingle(); 00054 return aVector; 00055 } 00056 00057 inline void G4PhysicsVector::operator delete(void* aVector) 00058 { 00059 aPVAllocator.FreeSingle((G4PhysicsVector*)aVector); 00060 } 00061 00062 inline G4double G4PhysicsVector::Value(G4double theEnergy) 00063 { 00064 // Use cache for speed up - check if the value 'theEnergy' is same as the 00065 // last call. If it is same, then use the last value, if not - recompute 00066 00067 if( theEnergy != cache->lastEnergy ) { ComputeValue(theEnergy); } 00068 return cache->lastValue; 00069 } 00070 00071 inline 00072 G4double G4PhysicsVector::GetLastEnergy() const 00073 { 00074 return cache->lastEnergy; 00075 } 00076 00077 inline 00078 G4double G4PhysicsVector::GetLastValue() const 00079 { 00080 return cache->lastValue; 00081 } 00082 00083 inline 00084 size_t G4PhysicsVector::GetLastBin() const 00085 { 00086 return cache->lastBin; 00087 } 00088 00089 inline 00090 G4double G4PhysicsVector::operator[](const size_t binNumber) const 00091 { 00092 return dataVector[binNumber]; 00093 } 00094 00095 //--------------------------------------------------------------- 00096 00097 inline 00098 G4double G4PhysicsVector::operator()(const size_t binNumber) const 00099 { 00100 return dataVector[binNumber]; 00101 } 00102 00103 //--------------------------------------------------------------- 00104 00105 inline 00106 G4double G4PhysicsVector::Energy(const size_t binNumber) const 00107 { 00108 return binVector[binNumber]; 00109 } 00110 00111 //--------------------------------------------------------------- 00112 00113 inline 00114 G4double G4PhysicsVector::GetMaxEnergy() const 00115 { 00116 return edgeMax; 00117 } 00118 00119 //--------------------------------------------------------------- 00120 00121 inline 00122 size_t G4PhysicsVector::GetVectorLength() const 00123 { 00124 return numberOfNodes; 00125 } 00126 00127 //--------------------------------------------------------------- 00128 00129 inline 00130 G4double G4PhysicsVector::GetValue(G4double theEnergy, G4bool&) 00131 { 00132 return Value(theEnergy); 00133 } 00134 00135 //------------------------------------------------ 00136 00137 inline 00138 G4double G4PhysicsVector::LinearInterpolation(G4int lastBin) 00139 { 00140 // Linear interpolation is used to get the value. If the give energy 00141 // is in the highest bin, no interpolation will be Done. Because 00142 // there is an extra bin hidden from a user at locBin=numberOfBin, 00143 // the following interpolation is valid even the current locBin= 00144 // numberOfBin-1. 00145 00146 G4double intplFactor = (cache->lastEnergy-binVector[lastBin]) 00147 / (binVector[lastBin + 1]-binVector[lastBin]); // Interpol. factor 00148 00149 return dataVector[lastBin] + 00150 ( dataVector[lastBin + 1]-dataVector[lastBin] ) * intplFactor; 00151 } 00152 00153 //--------------------------------------------------------------- 00154 00155 inline 00156 G4double G4PhysicsVector::SplineInterpolation(G4int lastBin) 00157 { 00158 // Spline interpolation is used to get the value. If the give energy 00159 // is in the highest bin, no interpolation will be Done. Because 00160 // there is an extra bin hidden from a user at locBin=numberOfBin, 00161 // the following interpolation is valid even the current locBin= 00162 // numberOfBin-1. 00163 00164 if(0 == secDerivative.size() ) { FillSecondDerivatives(); } 00165 00166 // check bin value 00167 G4double x1 = binVector[lastBin]; 00168 G4double x2 = binVector[lastBin + 1]; 00169 G4double delta = x2 - x1; 00170 00171 G4double a = (x2 - cache->lastEnergy)/delta; 00172 G4double b = (cache->lastEnergy - x1)/delta; 00173 00174 // Final evaluation of cubic spline polynomial for return 00175 G4double y1 = dataVector[lastBin]; 00176 G4double y2 = dataVector[lastBin + 1]; 00177 00178 G4double res = a*y1 + b*y2 + 00179 ( (a*a*a - a)*secDerivative[lastBin] + 00180 (b*b*b - b)*secDerivative[lastBin + 1] )*delta*delta/6.0; 00181 00182 return res; 00183 } 00184 00185 //--------------------------------------------------------------- 00186 00187 inline 00188 void G4PhysicsVector::Interpolation(G4int lastBin) 00189 { 00190 if(useSpline) { cache->lastValue = SplineInterpolation(lastBin); } 00191 else { cache->lastValue = LinearInterpolation(lastBin); } 00192 } 00193 00194 //--------------------------------------------------------------- 00195 00196 inline 00197 void G4PhysicsVector::PutValue(size_t binNumber, G4double theValue) 00198 { 00199 dataVector[binNumber] = theValue; 00200 } 00201 00202 //--------------------------------------------------------------- 00203 00204 inline 00205 G4bool G4PhysicsVector::IsFilledVectorExist() const 00206 { 00207 G4bool status=false; 00208 00209 if(numberOfNodes > 0) { status=true; } 00210 return status; 00211 } 00212 00213 //--------------------------------------------------------------- 00214 00215 inline 00216 G4PhysicsVectorType G4PhysicsVector::GetType() const 00217 { 00218 return type; 00219 } 00220 00221 //--------------------------------------------------------------- 00222 00223 inline 00224 void G4PhysicsVector::SetSpline(G4bool val) 00225 { 00226 useSpline = val; 00227 } 00228 00229 //--------------------------------------------------------------- 00230 00231 inline 00232 void G4PhysicsVector::SetVerboseLevel(G4int value) 00233 { 00234 verboseLevel = value; 00235 } 00236 00237 //--------------------------------------------------------------- 00238 00239 inline 00240 G4int G4PhysicsVector::GetVerboseLevel(G4int) 00241 { 00242 return verboseLevel; 00243 } 00244