1// ********************************************************************
 
    2// * License and Disclaimer                                           *
 
    4// * The  Geant4 software  is  copyright of the Copyright Holders  of *
 
    5// * the Geant4 Collaboration.  It is provided  under  the terms  and *
 
    6// * conditions of the Geant4 Software License,  included in the file *
 
    7// * LICENSE and available at  http://cern.ch/geant4/license .  These *
 
    8// * include a list of copyright holders.                             *
 
   10// * Neither the authors of this software system, nor their employing *
 
   11// * institutes,nor the agencies providing financial support for this *
 
   12// * work  make  any representation or  warranty, express or implied, *
 
   13// * regarding  this  software system or assume any liability for its *
 
   14// * use.  Please see the license in the file  LICENSE  and URL above *
 
   15// * for the full disclaimer and the limitation of liability.         *
 
   17// * This  code  implementation is the result of  the  scientific and *
 
   18// * technical work of the GEANT4 collaboration.                      *
 
   19// * By using,  copying,  modifying or  distributing the software (or *
 
   20// * any work based  on the software)  you  agree  to acknowledge its *
 
   21// * use  in  resulting  scientific  publications,  and indicate your *
 
   22// * acceptance of all terms of the Geant4 Software license.          *
 
   23// ********************************************************************
 
   25// Helper namespace field_utils inline implementation
 
   27// Author: Dmitry Sorokin, Google Summer of Code 2017
 
   28// Supervision: John Apostolakis, CERN
 
   29// --------------------------------------------------------------------
 
   31namespace field_utils {
 
   36  size_t getFirstIndex(const T& value)
 
   38    return static_cast<size_t>(value);
 
   42template <typename ArrayType>
 
   43inline G4double getValue(const ArrayType& array, Value1D value)
 
   45    const auto begin = internal::getFirstIndex(value);
 
   49template <typename ArrayType>
 
   50G4double getValue2(const ArrayType& array, Value1D value)
 
   52    return sqr(getValue(array, value));
 
   55template <typename ArrayType>
 
   56G4double getValue(const ArrayType& array, Value3D value)
 
   58    return std::sqrt(getValue2(array, value));
 
   61template <typename ArrayType>
 
   62G4double getValue2(const ArrayType& array, const Value3D value)
 
   64    const auto begin = internal::getFirstIndex(value);
 
   65    return sqr(array[begin]) + sqr(array[begin+1]) + sqr(array[begin+2]);
 
   68template <typename ArrayType>
 
   69G4ThreeVector makeVector(const ArrayType& array, Value3D value)
 
   71    const auto begin = internal::getFirstIndex(value);
 
   72    return G4ThreeVector(array[begin], array[begin + 1], array[begin + 2]);
 
   75template <typename SourceArray, typename TargetArray>
 
   76void setValue(const SourceArray& src, Value1D value, TargetArray& trg)
 
   78    const auto begin = internal::getFirstIndex(value);
 
   79    trg[begin] = src[begin];
 
   82template <typename SourceArray, typename TargetArray, typename ...TargetArrays>
 
   83void setValue(const SourceArray& src, Value1D value,
 
   84              TargetArray& trg, TargetArrays&... trgs)
 
   86    const auto begin = internal::getFirstIndex(value);
 
   87    trg[begin] = src[begin];
 
   88    setValue(src, value, trgs...);
 
   92T clamp(T value, T lo, T hi)
 
   94    return std::min(std::max(lo, value), hi);