Import Geant4 9.3.0 source tree
This commit is contained in:
@@ -24,8 +24,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4PhysicsVector.cc,v 1.27 2008/10/16 12:14:36 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
// $Id: G4PhysicsVector.cc,v 1.41 2009/12/07 09:21:27 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -42,6 +42,12 @@
|
||||
// 18 Jan. 2001, H.Kurashige : removed ptrNextTable
|
||||
// 09 Mar. 2001, H.Kurashige : added G4PhysicsVector type
|
||||
// 05 Sep. 2008, V.Ivanchenko : added protections for zero-length vector
|
||||
// 11 May 2009, A.Bagulya : added new implementation of methods
|
||||
// ComputeSecondDerivatives - first derivatives at edge points
|
||||
// should be provided by a user
|
||||
// FillSecondDerivatives - default computation base on "not-a-knot"
|
||||
// algorithm
|
||||
// 19 Jun. 2009, V.Ivanchenko : removed hidden bin
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4PhysicsVector.hh"
|
||||
@@ -51,17 +57,14 @@
|
||||
|
||||
G4PhysicsVector::G4PhysicsVector(G4bool spline)
|
||||
: type(T_G4PhysicsVector),
|
||||
edgeMin(0.), edgeMax(0.), numberOfBin(0),
|
||||
lastEnergy(0.), lastValue(0.), lastBin(0),
|
||||
secDerivative(0), useSpline(spline)
|
||||
edgeMin(0.), edgeMax(0.), numberOfNodes(0),
|
||||
lastEnergy(-DBL_MAX), lastValue(0.), lastBin(0), useSpline(spline)
|
||||
{}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
G4PhysicsVector::~G4PhysicsVector()
|
||||
{
|
||||
DeleteData();
|
||||
}
|
||||
{}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -77,7 +80,7 @@ G4PhysicsVector& G4PhysicsVector::operator=(const G4PhysicsVector& right)
|
||||
if (&right==this) { return *this; }
|
||||
if (type != right.type) { return *this; }
|
||||
|
||||
DeleteData();
|
||||
//DeleteData();
|
||||
CopyData(right);
|
||||
|
||||
return *this;
|
||||
@@ -101,8 +104,7 @@ G4int G4PhysicsVector::operator!=(const G4PhysicsVector &right) const
|
||||
|
||||
void G4PhysicsVector::DeleteData()
|
||||
{
|
||||
delete [] secDerivative;
|
||||
secDerivative = 0;
|
||||
secDerivative.clear();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -112,7 +114,7 @@ void G4PhysicsVector::CopyData(const G4PhysicsVector& vec)
|
||||
type = vec.type;
|
||||
edgeMin = vec.edgeMin;
|
||||
edgeMax = vec.edgeMax;
|
||||
numberOfBin = vec.numberOfBin;
|
||||
numberOfNodes = vec.numberOfNodes;
|
||||
lastEnergy = vec.lastEnergy;
|
||||
lastValue = vec.lastValue;
|
||||
lastBin = vec.lastBin;
|
||||
@@ -120,18 +122,7 @@ void G4PhysicsVector::CopyData(const G4PhysicsVector& vec)
|
||||
binVector = vec.binVector;
|
||||
useSpline = vec.useSpline;
|
||||
comment = vec.comment;
|
||||
if (vec.secDerivative)
|
||||
{
|
||||
secDerivative = new G4double [numberOfBin];
|
||||
for (size_t i=0; i<numberOfBin; i++)
|
||||
{
|
||||
secDerivative[i] = vec.secDerivative[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
secDerivative = 0;
|
||||
}
|
||||
secDerivative = vec.secDerivative;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -156,14 +147,14 @@ G4bool G4PhysicsVector::Store(std::ofstream& fOut, G4bool ascii)
|
||||
// binning
|
||||
fOut.write((char*)(&edgeMin), sizeof edgeMin);
|
||||
fOut.write((char*)(&edgeMax), sizeof edgeMax);
|
||||
fOut.write((char*)(&numberOfBin), sizeof numberOfBin);
|
||||
fOut.write((char*)(&numberOfNodes), sizeof numberOfNodes);
|
||||
|
||||
// contents
|
||||
size_t size = dataVector.size();
|
||||
fOut.write((char*)(&size), sizeof size);
|
||||
|
||||
G4double* value = new G4double[2*size];
|
||||
for(size_t i = 0; i < size; i++)
|
||||
for(size_t i = 0; i < size; ++i)
|
||||
{
|
||||
value[2*i] = binVector[i];
|
||||
value[2*i+1]= dataVector[i];
|
||||
@@ -179,18 +170,19 @@ G4bool G4PhysicsVector::Store(std::ofstream& fOut, G4bool ascii)
|
||||
G4bool G4PhysicsVector::Retrieve(std::ifstream& fIn, G4bool ascii)
|
||||
{
|
||||
// clear properties;
|
||||
lastEnergy=0.;
|
||||
lastEnergy=-DBL_MAX;
|
||||
lastValue =0.;
|
||||
lastBin =0;
|
||||
dataVector.clear();
|
||||
binVector.clear();
|
||||
secDerivative.clear();
|
||||
comment = "";
|
||||
|
||||
// retrieve in ascii mode
|
||||
if (ascii)
|
||||
{
|
||||
// binning
|
||||
fIn >> edgeMin >> edgeMax >> numberOfBin;
|
||||
fIn >> edgeMin >> edgeMax >> numberOfNodes;
|
||||
if (fIn.fail()) { return false; }
|
||||
// contents
|
||||
size_t size=0;
|
||||
@@ -217,7 +209,7 @@ G4bool G4PhysicsVector::Retrieve(std::ifstream& fIn, G4bool ascii)
|
||||
// binning
|
||||
fIn.read((char*)(&edgeMin), sizeof edgeMin);
|
||||
fIn.read((char*)(&edgeMax), sizeof edgeMax);
|
||||
fIn.read((char*)(&numberOfBin), sizeof numberOfBin );
|
||||
fIn.read((char*)(&numberOfNodes), sizeof numberOfNodes );
|
||||
|
||||
// contents
|
||||
size_t size;
|
||||
@@ -233,7 +225,7 @@ G4bool G4PhysicsVector::Retrieve(std::ifstream& fIn, G4bool ascii)
|
||||
|
||||
binVector.reserve(size);
|
||||
dataVector.reserve(size);
|
||||
for(size_t i = 0; i < size; i++)
|
||||
for(size_t i = 0; i < size; ++i)
|
||||
{
|
||||
binVector.push_back(value[2*i]);
|
||||
dataVector.push_back(value[2*i+1]);
|
||||
@@ -244,23 +236,181 @@ G4bool G4PhysicsVector::Retrieve(std::ifstream& fIn, G4bool ascii)
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
void G4PhysicsVector::FillSecondDerivatives()
|
||||
{
|
||||
secDerivative = new G4double [numberOfBin];
|
||||
void
|
||||
G4PhysicsVector::ScaleVector(G4double factorE, G4double factorV)
|
||||
{
|
||||
size_t n = dataVector.size();
|
||||
size_t i;
|
||||
if(n > 0) {
|
||||
for(i=0; i<n; ++i) {
|
||||
binVector[i] *= factorE;
|
||||
dataVector[i] *= factorV;
|
||||
}
|
||||
}
|
||||
n = secDerivative.size();
|
||||
if(n > 0) { for(i=0; i<n; ++i) { secDerivative[i] *= factorV; } }
|
||||
|
||||
size_t n = numberOfBin-1;
|
||||
edgeMin *= factorE;
|
||||
edgeMax *= factorE;
|
||||
lastEnergy *= factorE;
|
||||
lastValue *= factorV;
|
||||
}
|
||||
|
||||
// cannot compute derivatives for less than 3 points
|
||||
if(3 > numberOfBin)
|
||||
// --------------------------------------------------------------
|
||||
|
||||
void
|
||||
G4PhysicsVector::ComputeSecondDerivatives(G4double firstPointDerivative,
|
||||
G4double endPointDerivative)
|
||||
// A standard method of computation of second derivatives
|
||||
// First derivatives at the first and the last point should be provided
|
||||
// See for example W.H. Press et al. "Numerical reciptes and C"
|
||||
// Cambridge University Press, 1997.
|
||||
{
|
||||
if(4 > numberOfNodes) // cannot compute derivatives for less than 4 bins
|
||||
{
|
||||
secDerivative[0] = 0.0;
|
||||
secDerivative[n] = 0.0;
|
||||
ComputeSecDerivatives();
|
||||
return;
|
||||
}
|
||||
|
||||
for(size_t i=1; i<n; i++)
|
||||
if(!SplinePossible()) { return; }
|
||||
|
||||
G4int n = numberOfNodes-1;
|
||||
|
||||
G4double* u = new G4double [n];
|
||||
|
||||
G4double p, sig, un;
|
||||
|
||||
u[0] = (6.0/(binVector[1]-binVector[0]))
|
||||
* ((dataVector[1]-dataVector[0])/(binVector[1]-binVector[0])
|
||||
- firstPointDerivative);
|
||||
|
||||
secDerivative[0] = - 0.5;
|
||||
|
||||
// Decomposition loop for tridiagonal algorithm. secDerivative[i]
|
||||
// and u[i] are used for temporary storage of the decomposed factors.
|
||||
|
||||
for(G4int i=1; i<n; ++i)
|
||||
{
|
||||
secDerivative[i] =
|
||||
sig = (binVector[i]-binVector[i-1]) / (binVector[i+1]-binVector[i-1]);
|
||||
p = sig*secDerivative[i-1] + 2.0;
|
||||
secDerivative[i] = (sig - 1.0)/p;
|
||||
u[i] = (dataVector[i+1]-dataVector[i])/(binVector[i+1]-binVector[i])
|
||||
- (dataVector[i]-dataVector[i-1])/(binVector[i]-binVector[i-1]);
|
||||
u[i] = 6.0*u[i]/(binVector[i+1]-binVector[i-1]) - sig*u[i-1]/p;
|
||||
}
|
||||
|
||||
sig = (binVector[n-1]-binVector[n-2]) / (binVector[n]-binVector[n-2]);
|
||||
p = sig*secDerivative[n-2] + 2.0;
|
||||
un = (6.0/(binVector[n]-binVector[n-1]))
|
||||
*(endPointDerivative -
|
||||
(dataVector[n]-dataVector[n-1])/(binVector[n]-binVector[n-1])) - u[n-1]/p;
|
||||
secDerivative[n] = un/(secDerivative[n-1] + 2.0);
|
||||
|
||||
// The back-substitution loop for the triagonal algorithm of solving
|
||||
// a linear system of equations.
|
||||
|
||||
for(G4int k=n-1; k>0; --k)
|
||||
{
|
||||
secDerivative[k] *=
|
||||
(secDerivative[k+1] -
|
||||
u[k]*(binVector[k+1]-binVector[k-1])/(binVector[k+1]-binVector[k]));
|
||||
}
|
||||
secDerivative[0] = 0.5*(u[0] - secDerivative[1]);
|
||||
|
||||
delete [] u;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
void G4PhysicsVector::FillSecondDerivatives()
|
||||
// Computation of second derivatives using "Not-a-knot" endpoint conditions
|
||||
// B.I. Kvasov "Methods of shape-preserving spline approximation"
|
||||
// World Scientific, 2000
|
||||
{
|
||||
if(5 > numberOfNodes) // cannot compute derivatives for less than 4 points
|
||||
{
|
||||
ComputeSecDerivatives();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!SplinePossible()) { return; }
|
||||
|
||||
G4int n = numberOfNodes-1;
|
||||
|
||||
//G4cout << "G4PhysicsVector::FillSecondDerivatives() n= " << n << G4endl;
|
||||
// G4cout << *this << G4endl;
|
||||
|
||||
G4double* u = new G4double [n];
|
||||
|
||||
G4double p, sig;
|
||||
|
||||
u[1] = ((dataVector[2]-dataVector[1])/(binVector[2]-binVector[1]) -
|
||||
(dataVector[1]-dataVector[0])/(binVector[1]-binVector[0]));
|
||||
u[1] = 6.0*u[1]*(binVector[2]-binVector[1])
|
||||
/ ((binVector[2]-binVector[0])*(binVector[2]-binVector[0]));
|
||||
|
||||
// Decomposition loop for tridiagonal algorithm. secDerivative[i]
|
||||
// and u[i] are used for temporary storage of the decomposed factors.
|
||||
|
||||
secDerivative[1] = (2.0*binVector[1]-binVector[0]-binVector[2])
|
||||
/ (2.0*binVector[2]-binVector[0]-binVector[1]);
|
||||
|
||||
for(G4int i=2; i<n-1; ++i)
|
||||
{
|
||||
sig = (binVector[i]-binVector[i-1]) / (binVector[i+1]-binVector[i-1]);
|
||||
p = sig*secDerivative[i-1] + 2.0;
|
||||
secDerivative[i] = (sig - 1.0)/p;
|
||||
u[i] = (dataVector[i+1]-dataVector[i])/(binVector[i+1]-binVector[i])
|
||||
- (dataVector[i]-dataVector[i-1])/(binVector[i]-binVector[i-1]);
|
||||
u[i] = (6.0*u[i]/(binVector[i+1]-binVector[i-1])) - sig*u[i-1]/p;
|
||||
}
|
||||
|
||||
sig = (binVector[n-1]-binVector[n-2]) / (binVector[n]-binVector[n-2]);
|
||||
p = sig*secDerivative[n-3] + 2.0;
|
||||
u[n-1] = (dataVector[n]-dataVector[n-1])/(binVector[n]-binVector[n-1])
|
||||
- (dataVector[n-1]-dataVector[n-2])/(binVector[n-1]-binVector[n-2]);
|
||||
u[n-1] = 6.0*sig*u[n-1]/(binVector[n]-binVector[n-2])
|
||||
- (2.0*sig - 1.0)*u[n-2]/p;
|
||||
|
||||
p = (1.0+sig) + (2.0*sig-1.0)*secDerivative[n-2];
|
||||
secDerivative[n-1] = u[n-1]/p;
|
||||
|
||||
// The back-substitution loop for the triagonal algorithm of solving
|
||||
// a linear system of equations.
|
||||
|
||||
for(G4int k=n-2; k>1; --k)
|
||||
{
|
||||
secDerivative[k] *=
|
||||
(secDerivative[k+1] -
|
||||
u[k]*(binVector[k+1]-binVector[k-1])/(binVector[k+1]-binVector[k]));
|
||||
}
|
||||
secDerivative[n] = (secDerivative[n-1] - (1.0-sig)*secDerivative[n-2])/sig;
|
||||
sig = 1.0 - ((binVector[2]-binVector[1])/(binVector[2]-binVector[0]));
|
||||
secDerivative[1] *= (secDerivative[2] - u[1]/(1.0-sig));
|
||||
secDerivative[0] = (secDerivative[1] - sig*secDerivative[2])/(1.0-sig);
|
||||
|
||||
delete [] u;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
void
|
||||
G4PhysicsVector::ComputeSecDerivatives()
|
||||
// A simplified method of computation of second derivatives
|
||||
{
|
||||
if(!SplinePossible()) { return; }
|
||||
|
||||
if(3 > numberOfNodes) // cannot compute derivatives for less than 4 bins
|
||||
{
|
||||
useSpline = false;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t n = numberOfNodes-1;
|
||||
|
||||
for(size_t i=1; i<n; ++i)
|
||||
{
|
||||
secDerivative[i] =
|
||||
3.0*((dataVector[i+1]-dataVector[i])/(binVector[i+1]-binVector[i]) -
|
||||
(dataVector[i]-dataVector[i-1])/(binVector[i]-binVector[i-1]))
|
||||
/(binVector[i+1]-binVector[i-1]);
|
||||
@@ -268,6 +418,26 @@ void G4PhysicsVector::FillSecondDerivatives()
|
||||
secDerivative[n] = secDerivative[n-1];
|
||||
secDerivative[0] = secDerivative[1];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
G4bool G4PhysicsVector::SplinePossible()
|
||||
// Initialise second derivative array. If neighbor energy coincide
|
||||
// or not ordered than spline cannot be applied
|
||||
{
|
||||
if(!useSpline) return useSpline;
|
||||
secDerivative.clear();
|
||||
secDerivative.reserve(numberOfNodes);
|
||||
for(size_t j=0; j<numberOfNodes; ++j)
|
||||
{
|
||||
secDerivative.push_back(0.0);
|
||||
if(j > 0)
|
||||
{
|
||||
if(binVector[j]-binVector[j-1] <= 0.) { useSpline = false; }
|
||||
}
|
||||
}
|
||||
return useSpline;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -275,7 +445,7 @@ std::ostream& operator<<(std::ostream& out, const G4PhysicsVector& pv)
|
||||
{
|
||||
// binning
|
||||
out << std::setprecision(12) << pv.edgeMin;
|
||||
out <<" " << pv.edgeMax <<" " << pv.numberOfBin << G4endl;
|
||||
out <<" " << pv.edgeMax <<" " << pv.numberOfNodes << G4endl;
|
||||
|
||||
// contents
|
||||
out << pv.dataVector.size() << G4endl;
|
||||
|
||||
Reference in New Issue
Block a user