300 lines
8.6 KiB
Plaintext
300 lines
8.6 KiB
Plaintext
//
|
|
// ********************************************************************
|
|
// * License and Disclaimer *
|
|
// * *
|
|
// * The Geant4 software is copyright of the Copyright Holders of *
|
|
// * the Geant4 Collaboration. It is provided under the terms and *
|
|
// * conditions of the Geant4 Software License, included in the file *
|
|
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
|
// * include a list of copyright holders. *
|
|
// * *
|
|
// * Neither the authors of this software system, nor their employing *
|
|
// * institutes,nor the agencies providing financial support for this *
|
|
// * work make any representation or warranty, express or implied, *
|
|
// * regarding this software system or assume any liability for its *
|
|
// * use. Please see the license in the file LICENSE and URL above *
|
|
// * for the full disclaimer and the limitation of liability. *
|
|
// * *
|
|
// * This code implementation is the result of the scientific and *
|
|
// * technical work of the GEANT4 collaboration. *
|
|
// * By using, copying, modifying or distributing the software (or *
|
|
// * any work based on the software) you agree to acknowledge its *
|
|
// * use in resulting scientific publications, and indicate your *
|
|
// * acceptance of all terms of the Geant4 Software license. *
|
|
// ********************************************************************
|
|
//
|
|
// G4PhysicsVector inline methods implementation
|
|
//
|
|
// Authors:
|
|
// - 02 Dec. 1995, G.Cosmo: Structure created based on object model
|
|
// - 03 Mar. 1996, K.Amako: Implemented the 1st version
|
|
// --------------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::operator[](const std::size_t index) const
|
|
{
|
|
return dataVector[index];
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::operator()(const std::size_t index) const
|
|
{
|
|
return dataVector[index];
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::Energy(const std::size_t index) const
|
|
{
|
|
return binVector[index];
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double
|
|
G4PhysicsVector::GetLowEdgeEnergy(const std::size_t index) const
|
|
{
|
|
return binVector[index];
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::GetMinEnergy() const
|
|
{
|
|
return edgeMin;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::GetMaxEnergy() const
|
|
{
|
|
return edgeMax;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::GetMinValue() const
|
|
{
|
|
return (numberOfNodes > 0) ? dataVector[0] : 0.0;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::GetMaxValue() const
|
|
{
|
|
return (numberOfNodes > 0) ? dataVector[numberOfNodes - 1] : 0.0;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline std::size_t G4PhysicsVector::GetVectorLength() const
|
|
{
|
|
return numberOfNodes;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline void G4PhysicsVector::PutValue(std::size_t index, G4double theValue)
|
|
{
|
|
if(index >= numberOfNodes)
|
|
{
|
|
PrintPutValueError(index, theValue, "PutValue(..) ");
|
|
}
|
|
else
|
|
{
|
|
dataVector[index] = theValue;
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4PhysicsVectorType G4PhysicsVector::GetType() const
|
|
{
|
|
return type;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4bool G4PhysicsVector::GetSpline() const
|
|
{
|
|
return useSpline;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline void G4PhysicsVector::SetVerboseLevel(G4int value)
|
|
{
|
|
verboseLevel = value;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double
|
|
G4PhysicsVector::FindLinearEnergy(const G4double rand) const
|
|
{
|
|
return GetEnergy(rand*dataVector[numberOfNodes - 1]);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::Interpolation(const std::size_t idx,
|
|
const G4double e) const
|
|
{
|
|
// perform the interpolation
|
|
const G4double x1 = binVector[idx];
|
|
const G4double dl = binVector[idx + 1] - x1;
|
|
|
|
const G4double y1 = dataVector[idx];
|
|
const G4double dy = dataVector[idx + 1] - y1;
|
|
|
|
// note: all corner cases of the previous methods are covered and eventually
|
|
// gives b=0/1 that results in y=y0\y_{N-1} if e<=x[0]/e>=x[N-1] or
|
|
// y=y_i/y_{i+1} if e<x[i]/e>=x[i+1] due to small numerical errors
|
|
const G4double b = (e - x1) / dl;
|
|
|
|
G4double res = y1 + b * dy;
|
|
|
|
if (useSpline) // spline interpolation
|
|
{
|
|
const G4double c0 = (2.0 - b) * secDerivative[idx];
|
|
const G4double c1 = (1.0 + b) * secDerivative[idx + 1];
|
|
res += (b * (b - 1.0)) * (c0 + c1) * (dl * dl * (1.0/6.0));
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline std::size_t G4PhysicsVector::ComputeLogVectorBin(
|
|
const G4double loge) const
|
|
{
|
|
return static_cast<std::size_t>( std::min( static_cast<G4int>((loge - logemin) * invdBin),
|
|
static_cast<G4int>(idxmax) ) );
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline std::size_t
|
|
G4PhysicsVector::LogBin(const G4double e, const G4double loge) const
|
|
{
|
|
std::size_t idx =
|
|
scale[std::min( static_cast<G4int>((loge - lmin1) * iBin1),
|
|
static_cast<G4int>(imax1) )];
|
|
for (; idx <= idxmax; ++idx)
|
|
{
|
|
if (e >= binVector[idx] && e <= binVector[idx + 1]) { break; }
|
|
}
|
|
return idx;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline std::size_t G4PhysicsVector::BinaryBin(const G4double e) const
|
|
{
|
|
// Bin location proposed by K.Genser (FNAL)
|
|
return std::lower_bound(binVector.cbegin(), binVector.cend(), e) -
|
|
binVector.cbegin() - 1;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline std::size_t G4PhysicsVector::GetBin(const G4double e) const
|
|
{
|
|
std::size_t bin;
|
|
switch(type)
|
|
{
|
|
case T_G4PhysicsLogVector:
|
|
bin = ComputeLogVectorBin(G4Log(e));
|
|
break;
|
|
|
|
case T_G4PhysicsLinearVector:
|
|
bin = static_cast<std::size_t>( std::min( static_cast<G4int>((e - edgeMin) * invdBin),
|
|
static_cast<G4int>(idxmax) ) );
|
|
break;
|
|
|
|
default:
|
|
bin = (nLogNodes > 0) ? LogBin(e, G4Log(e)) : BinaryBin(e);
|
|
}
|
|
return bin;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double
|
|
G4PhysicsVector::Value(const G4double e, std::size_t& idx) const
|
|
{
|
|
G4double res;
|
|
if (idx + 1 < numberOfNodes &&
|
|
e >= binVector[idx] && e <= binVector[idx+1])
|
|
{
|
|
res = Interpolation(idx, e);
|
|
}
|
|
else if (e > edgeMin && e < edgeMax)
|
|
{
|
|
idx = GetBin(e);
|
|
res = Interpolation(idx, e);
|
|
}
|
|
else if(e <= edgeMin)
|
|
{
|
|
res = dataVector[0];
|
|
idx = 0;
|
|
}
|
|
else
|
|
{
|
|
res = dataVector[idxmax + 1];
|
|
idx = idxmax;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::Value(G4double e) const
|
|
{
|
|
G4double res;
|
|
if (e > edgeMin && e < edgeMax)
|
|
{
|
|
const std::size_t idx = GetBin(e);
|
|
res = Interpolation(idx, e);
|
|
}
|
|
else if(e <= edgeMin)
|
|
{
|
|
res = dataVector[0];
|
|
}
|
|
else
|
|
{
|
|
res = dataVector[idxmax + 1];
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double G4PhysicsVector::GetValue(G4double e, G4bool&) const
|
|
{
|
|
return Value(e);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double
|
|
G4PhysicsVector::LogVectorValue(const G4double e, const G4double loge) const
|
|
{
|
|
G4double res;
|
|
if (e > edgeMin && e < edgeMax)
|
|
{
|
|
const std::size_t idx = ComputeLogVectorBin(loge);
|
|
res = Interpolation(idx, e);
|
|
}
|
|
else if (e <= edgeMin)
|
|
{
|
|
res = dataVector[0];
|
|
}
|
|
else
|
|
{
|
|
res = dataVector[idxmax - 1];
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
inline G4double
|
|
G4PhysicsVector::LogFreeVectorValue(const G4double e, const G4double loge) const
|
|
{
|
|
G4double res;
|
|
if (e > edgeMin && e < edgeMax)
|
|
{
|
|
const std::size_t idx = LogBin(e, loge);
|
|
res = Interpolation(idx, e);
|
|
}
|
|
else if (e <= edgeMin)
|
|
{
|
|
res = dataVector[0];
|
|
}
|
|
else
|
|
{
|
|
res = dataVector[idxmax + 1];
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|