// // ******************************************************************** // * 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+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::min( static_cast((loge - logemin) * invdBin), static_cast(idxmax) ) ); } // --------------------------------------------------------------- inline std::size_t G4PhysicsVector::LogBin(const G4double e, const G4double loge) const { std::size_t idx = scale[std::min( static_cast((loge - lmin1) * iBin1), static_cast(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::min( static_cast((e - edgeMin) * invdBin), static_cast(idxmax) ) ); break; default: bin = (nLogNodes > 0) ? LogBin(e, G4Log(e)) : BinaryBin(e); } return bin; } // --------------------------------------------------------------- inline G4bool G4PhysicsVector::CheckIndex(const G4double e, std::size_t& idx) const { G4bool interpolation = false; if (idx + 1 < numberOfNodes && e >= binVector[idx] && e <= binVector[idx+1]) { interpolation = true; } else if (e > edgeMin && e < edgeMax) { idx = GetBin(e); interpolation = true; } else if(e <= edgeMin) { idx = 0; } else { idx = idxmax + 1; } return interpolation; } // --------------------------------------------------------------- inline G4double G4PhysicsVector::Value(const G4double e, std::size_t& idx) const { G4bool interpolation = CheckIndex(e, idx); G4double res = dataVector[idx]; if (interpolation) { res = Interpolation(idx, e); } 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; } // ---------------------------------------------------------------