CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/MagneticField/ParametrizedEngine/plugins/BCyl.h

Go to the documentation of this file.
00001 #ifndef ParametrizedEngine_BCyl_h
00002 #define ParametrizedEngine_BCyl_h
00003 
00019 #include<cmath>
00020 
00021 #include "DataFormats/Math/interface/approx_exp.h"
00022 
00023 namespace magfieldparam {
00024   template<typename T>
00025   struct BCylParam {
00026     //  constexpr BCylParam(std::initializer_list<T> init) :
00027     template<typename ... Args>
00028     constexpr BCylParam(Args... init) :
00029       prm{std::forward<Args>(init)...},
00030     //prm(std::forward<Args>(init)...), 
00031       ap2(4*prm[0]*prm[0]/(prm[1]*prm[1])), 
00032       hb0(0.5*prm[2]*std::sqrt(1.0+ap2)),
00033       hlova(1/std::sqrt(ap2)),
00034       ainv(2*hlova/prm[1]),
00035       coeff(1/(prm[8]*prm[8])){}
00036     
00037     T prm[9];
00038     T ap2, hb0, hlova, ainv,coeff;
00039     
00040     
00041   };
00042   
00043   namespace bcylDetails{
00044     
00045     template<typename T>
00046     inline void ffunkti(T u, T * __restrict__ ff) __attribute__((always_inline));
00047     
00048     template<typename T>
00049     inline void ffunkti(T u, T * __restrict__ ff) {
00050       // Function and its 3 derivatives
00051       T a,b,a2,u2;
00052       u2=u*u; 
00053       a=T(1)/(T(1)+u2);
00054       a2=-T(3)*a*a;
00055       b=std::sqrt(a);
00056       ff[0]=u*b;
00057       ff[1]=a*b;
00058       ff[2]=a2*ff[0];
00059       ff[3]=a2*ff[1]*(T(1)-4*u2);
00060     }
00061     
00062     inline double myExp(double x) { return std::exp(x);}
00063     inline float myExp(float x) { return unsafe_expf<3>(x);}
00064     
00065   }
00066   
00067   
00068   template<typename T>
00069   class BCycl  {
00070   public:
00071     BCycl(BCylParam<T> const & ipar) : pars(ipar) {} 
00072     
00073     void operator()(T r2, T z, T& Br, T& Bz) const {
00074       compute(r2,z,Br,Bz);
00075     }
00076     
00077     
00078   // in meters and T  (Br needs to be multiplied by r)
00079     void compute(T r2, T z, T& Br, T& Bz) const {
00080       using namespace  bcylDetails;
00081       //  if (r<1.15&&fabs(z)<2.8) // NOTE: check omitted, is done already by the wrapper! (NA)
00082       z-=pars.prm[3];                    // max Bz point is shifted in z
00083       T az=std::abs(z);
00084       T zainv=z*pars.ainv;
00085       T u=pars.hlova-zainv;
00086       T v=pars.hlova+zainv;
00087       T fu[4],gv[4];
00088       ffunkti(u,fu);
00089       ffunkti(v,gv);
00090       T rat=T(0.5)*pars.ainv;
00091       T rat2=rat*rat*r2;
00092       Br=pars.hb0*rat*(fu[1]-gv[1]-(fu[3]-gv[3])*rat2*T(0.5));
00093       Bz=pars.hb0*(fu[0]+gv[0]-(fu[2]+gv[2])*rat2);
00094       
00095       T corBr= pars.prm[4]*z*(az-pars.prm[5])*(az-pars.prm[5]);
00096       T corBz=-pars.prm[6]*(
00097                             myExp(-(z-pars.prm[7])*(z-pars.prm[7])*pars.coeff) +
00098                             myExp(-(z+pars.prm[7])*(z+pars.prm[7])*pars.coeff)
00099                             ); // double Gaussian
00100       Br+=corBr;
00101       Bz+=corBz;
00102     }
00103     
00104   private:
00105     BCylParam<T> pars;
00106     
00107   };
00108 }
00109 
00110 #endif