/** * \file kernel.hpp * \author Dhairya Malhotra, dhairya.malhotra@gmail.com * \date 12-20-2011 * \brief This file contains the definition of the struct Kernel and also the * implementation of various kernels for FMM. */ #include #include #include #include #ifndef _PVFMM_FMM_KERNEL_HPP_ #define _PVFMM_FMM_KERNEL_HPP_ namespace pvfmm{ template struct Kernel{ public: /** * \brief Evaluate potential due to source points at target coordinates. * \param[in] r_src Coordinates of source points. * \param[in] src_cnt Number of source points. * \param[in] v_src Strength of source points. * \param[in] r_trg Coordinates of target points. * \param[in] trg_cnt Number of target points. * \param[out] k_out Output array with potential values. */ typedef void (*Ker_t)(T* r_src, int src_cnt, T* v_src, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); /** * \brief Constructor. */ Kernel(); /** * \brief Constructor. */ Kernel(Ker_t poten, Ker_t dbl_poten, const char* name, int dim_, std::pair k_dim, bool homogen_=false, T ker_scale=0, size_t dev_poten=(size_t)NULL, size_t dev_dbl_poten=(size_t)NULL); /** * \brief Compute the transformation matrix (on the source strength vector) * to get potential at target coordinates due to sources at the given * coordinates. * \param[in] r_src Coordinates of source points. * \param[in] src_cnt Number of source points. * \param[in] r_trg Coordinates of target points. * \param[in] trg_cnt Number of target points. * \param[out] k_out Output array with potential values. */ void BuildMatrix(T* r_src, int src_cnt, T* r_trg, int trg_cnt, T* k_out); int dim; int ker_dim[2]; Ker_t ker_poten; Ker_t dbl_layer_poten; size_t dev_ker_poten; size_t dev_dbl_layer_poten; bool homogen; T poten_scale; std::string ker_name; }; template Kernel BuildKernel(const char* name, int dim, std::pair k_dim, bool homogen=false, T ker_scale=0){ size_t dev_ker_poten ; size_t dev_dbl_layer_poten; #ifdef __INTEL_OFFLOAD #pragma offload target(mic:0) #endif { dev_ker_poten =(size_t)((typename Kernel::Ker_t)A); dev_dbl_layer_poten=(size_t)((typename Kernel::Ker_t)B); } return Kernel(A, B, name, dim, k_dim, homogen, ker_scale, dev_ker_poten, dev_dbl_layer_poten); } template Kernel BuildKernel(const char* name, int dim, std::pair k_dim, bool homogen=false, T ker_scale=0){ size_t dev_ker_poten ; #ifdef __INTEL_OFFLOAD #pragma offload target(mic:0) #endif { dev_ker_poten =(size_t)((typename Kernel::Ker_t)A); } return Kernel(A, NULL, name, dim, k_dim, homogen, ker_scale, dev_ker_poten, (size_t)NULL); } }//end namespace #ifdef __INTEL_OFFLOAD #pragma offload_attribute(push,target(mic)) #endif namespace pvfmm{ // Predefined Kernel-functions //////////////////////////////////////////////////////////////////////////////// //////// LAPLACE KERNEL //////// //////////////////////////////////////////////////////////////////////////////// /** * \brief Green's function for the Poisson's equation. Kernel tensor * dimension = 1x1. */ template void laplace_poten(T* r_src, int src_cnt, T* v_src, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); // Laplace double layer potential. template void laplace_dbl_poten(T* r_src, int src_cnt, T* v_src, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); // Laplace grdient kernel. template void laplace_grad(T* r_src, int src_cnt, T* v_src, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); #ifdef QuadReal_t const Kernel laplace_potn_q=BuildKernel("laplace" , 3, std::pair(1,1), true, 1.0); const Kernel laplace_grad_q=BuildKernel("laplace_grad", 3, std::pair(1,3), true, 2.0); #endif const Kernel laplace_potn_d=BuildKernel("laplace" , 3, std::pair(1,1), true, 1.0); const Kernel laplace_grad_d=BuildKernel("laplace_grad", 3, std::pair(1,3), true, 2.0); const Kernel laplace_potn_f=BuildKernel("laplace" , 3, std::pair(1,1), true, 1.0); const Kernel laplace_grad_f=BuildKernel("laplace_grad", 3, std::pair(1,3), true, 2.0); template struct LaplaceKernel{ inline static const Kernel& potn_ker(); inline static const Kernel& grad_ker(); }; #ifdef QuadReal_t template<> const Kernel& LaplaceKernel::potn_ker(){ return laplace_potn_q; }; template<> const Kernel& LaplaceKernel::grad_ker(){ return laplace_grad_q; }; #endif template<> const Kernel& LaplaceKernel::potn_ker(){ return laplace_potn_d; }; template<> const Kernel& LaplaceKernel::grad_ker(){ return laplace_grad_d; }; template<> const Kernel& LaplaceKernel::potn_ker(){ return laplace_potn_f; }; template<> const Kernel& LaplaceKernel::grad_ker(){ return laplace_grad_f; }; //////////////////////////////////////////////////////////////////////////////// //////// STOKES KERNEL //////// //////////////////////////////////////////////////////////////////////////////// /** * \brief Green's function for the Stokes's equation. Kernel tensor * dimension = 3x3. */ template void stokes_vel(T* r_src, int src_cnt, T* v_src_, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); template void stokes_sym_dip(T* r_src, int src_cnt, T* v_src, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); template void stokes_press(T* r_src, int src_cnt, T* v_src_, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); template void stokes_stress(T* r_src, int src_cnt, T* v_src_, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); template void stokes_grad(T* r_src, int src_cnt, T* v_src_, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); const Kernel ker_stokes_vel =BuildKernel("stokes_vel" , 3, std::pair(3,3),true,1.0); const Kernel ker_stokes_press =BuildKernel("stokes_press" , 3, std::pair(3,1),true,2.0); const Kernel ker_stokes_stress=BuildKernel("stokes_stress", 3, std::pair(3,9),true,2.0); const Kernel ker_stokes_grad =BuildKernel("stokes_grad" , 3, std::pair(3,9),true,2.0); //////////////////////////////////////////////////////////////////////////////// //////// BIOT-SAVART KERNEL //////// //////////////////////////////////////////////////////////////////////////////// template void biot_savart(T* r_src, int src_cnt, T* v_src_, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); const Kernel ker_biot_savart=BuildKernel("biot_savart", 3, std::pair(3,3),true,2.0); //////////////////////////////////////////////////////////////////////////////// //////// HELMHOLTZ KERNEL //////// //////////////////////////////////////////////////////////////////////////////// /** * \brief Green's function for the Helmholtz's equation. Kernel tensor * dimension = 2x2. */ template void helmholtz_poten(T* r_src, int src_cnt, T* v_src, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); template void helmholtz_grad(T* r_src, int src_cnt, T* v_src, int dof, T* r_trg, int trg_cnt, T* k_out, mem::MemoryManager* mem_mgr); const Kernel ker_helmholtz =BuildKernel("helmholtz" , 3, std::pair(2,2)); const Kernel ker_helmholtz_grad=BuildKernel("helmholtz_grad", 3, std::pair(2,6)); }//end namespace #ifdef __INTEL_OFFLOAD #pragma offload_attribute(pop) #endif #include #endif //_PVFMM_FMM_KERNEL_HPP_