Files
geant4/source/global/management/include/G4PhysicsVector.icc
T
2023-12-08 10:43:34 +01:00

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;
}
// ---------------------------------------------------------------