Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:10:55

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/field/RZMapField.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cmath>
0010 
0011 #include "corecel/Macros.hh"
0012 #include "corecel/Types.hh"
0013 #include "corecel/grid/FindInterp.hh"
0014 #include "corecel/grid/UniformGrid.hh"
0015 #include "corecel/math/Algorithms.hh"
0016 #include "celeritas/Types.hh"
0017 #include "celeritas/Units.hh"
0018 
0019 #include "RZMapFieldData.hh"
0020 
0021 namespace celeritas
0022 {
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * Evaluate the value of magnetic field based on a volume-based RZ field map.
0026  */
0027 class RZMapField
0028 {
0029   public:
0030     //!@{
0031     //! \name Type aliases
0032     using Real3 = Array<real_type, 3>;
0033     using FieldParamsRef = NativeCRef<RZMapFieldParamsData>;
0034     //!@}
0035 
0036   public:
0037     // Construct with the shared map data
0038     inline CELER_FUNCTION explicit RZMapField(FieldParamsRef const& shared);
0039 
0040     // Evaluate the magnetic field value for the given position
0041     CELER_FUNCTION
0042     inline Real3 operator()(Real3 const& pos) const;
0043 
0044   private:
0045     // Shared constant field map
0046     FieldParamsRef const& params_;
0047 
0048     UniformGrid const grid_r_;
0049     UniformGrid const grid_z_;
0050 };
0051 
0052 //---------------------------------------------------------------------------//
0053 // INLINE DEFINITIONS
0054 //---------------------------------------------------------------------------//
0055 /*!
0056  * Construct with the shared magnetic field map data.
0057  */
0058 CELER_FUNCTION
0059 RZMapField::RZMapField(FieldParamsRef const& params)
0060     : params_(params)
0061     , grid_r_(params_.grids.data_r)
0062     , grid_z_(params_.grids.data_z)
0063 {
0064 }
0065 
0066 //---------------------------------------------------------------------------//
0067 /*!
0068  * Calculate the magnetic field vector for the given position.
0069  *
0070  * This does a 2-D interpolation on the input grid and reconstructs the
0071  * magnetic field vector from the stored R and Z components of the field. The
0072  * result is in the native Celeritas unit system.
0073  */
0074 CELER_FUNCTION auto RZMapField::operator()(Real3 const& pos) const -> Real3
0075 {
0076     CELER_ENSURE(params_);
0077 
0078     Real3 value{0, 0, 0};
0079 
0080     real_type r = hypot(pos[0], pos[1]);
0081 
0082     if (!params_.valid(pos[2], r))
0083         return value;
0084 
0085     // Find interpolation points for given r and z
0086     FindInterp<real_type> interp_r = find_interp<UniformGrid>(grid_r_, r);
0087     FindInterp<real_type> interp_z = find_interp<UniformGrid>(grid_z_, pos[2]);
0088 
0089     size_type ir = interp_r.index;
0090     size_type iz = interp_z.index;
0091 
0092     // z component
0093     real_type low = params_.fieldmap[params_.id(iz, ir)].value_z;
0094     real_type high = params_.fieldmap[params_.id(iz + 1, ir)].value_z;
0095     value[2] = low + (high - low) * interp_z.fraction;
0096 
0097     // x and y components
0098     low = params_.fieldmap[params_.id(iz, ir)].value_r;
0099     high = params_.fieldmap[params_.id(iz, ir + 1)].value_r;
0100     real_type tmp = (r != 0) ? (low + (high - low) * interp_r.fraction) / r
0101                              : low;
0102     value[0] = tmp * pos[0];
0103     value[1] = tmp * pos[1];
0104 
0105     return value;
0106 }
0107 
0108 //---------------------------------------------------------------------------//
0109 }  // namespace celeritas