#ifndef _SCTL_FMM_WRAPPER_HPP_ #define _SCTL_FMM_WRAPPER_HPP_ #include #include SCTL_INCLUDE(comm.hpp) #include SCTL_INCLUDE(mem_mgr.hpp) #include #include #ifdef SCTL_HAVE_PVFMM namespace pvfmm { template struct Kernel; template class MPI_Node; template class FMM_Node; template class FMM_Pts; template class FMM_Tree; template using PtFMM_Node = FMM_Node>; template using PtFMM = FMM_Pts>; template using PtFMM_Tree = FMM_Tree>; } #endif namespace SCTL_NAMESPACE { template class Vector; template class ParticleFMM { public: ParticleFMM(const ParticleFMM&) = delete; ParticleFMM& operator= (const ParticleFMM&) = delete; ParticleFMM(const Comm& comm = Comm::Self()); ~ParticleFMM(); void SetComm(const Comm& comm); void SetAccuracy(Integer digits); template void SetKernels(const KerM2M& ker_m2m, const KerM2L& ker_m2l, const KerL2L& ker_l2l); template void AddSrc(const std::string& name, const KerS2M& ker_s2m, const KerS2L& ker_s2l); template void AddTrg(const std::string& name, const KerM2T& ker_m2t, const KerL2T& ker_l2t); template void SetKernelS2T(const std::string& src_name, const std::string& trg_name, const KerS2T& ker_s2t); void DeleteSrc(const std::string& name); void DeleteTrg(const std::string& name); void SetSrcCoord(const std::string& name, const Vector& src_coord, const Vector& src_normal = Vector()); void SetSrcDensity(const std::string& name, const Vector& src_density); void SetTrgCoord(const std::string& name, const Vector& trg_coord); void Eval(Vector& U, const std::string& trg_name) const; void EvalDirect(Vector& U, const std::string& trg_name) const; static void test(const Comm& comm); private: struct FMMKernels { Iterator ker_m2m, ker_m2l, ker_l2l; Integer dim_mul_ch, dim_mul_eq; Integer dim_loc_ch, dim_loc_eq; void (*ker_m2m_eval)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*ker_m2l_eval)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*ker_l2l_eval)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*delete_ker_m2m)(Iterator ker); void (*delete_ker_m2l)(Iterator ker); void (*delete_ker_l2l)(Iterator ker); #ifdef SCTL_HAVE_PVFMM pvfmm::Kernel pvfmm_ker_m2m; pvfmm::Kernel pvfmm_ker_m2l; pvfmm::Kernel pvfmm_ker_l2l; #endif }; struct SrcData { Vector X, Xn, F; Iterator ker_s2m, ker_s2l; Integer dim_src, dim_mul_ch, dim_loc_ch, dim_normal; void (*ker_s2m_eval)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*ker_s2l_eval)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*delete_ker_s2m)(Iterator ker); void (*delete_ker_s2l)(Iterator ker); #ifdef SCTL_HAVE_PVFMM pvfmm::Kernel pvfmm_ker_s2m; pvfmm::Kernel pvfmm_ker_s2l; StaticArray bbox; #endif }; struct TrgData { Vector X, U; Iterator ker_m2t, ker_l2t; Integer dim_mul_eq, dim_loc_eq, dim_trg; void (*ker_m2t_eval)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*ker_l2t_eval)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*delete_ker_m2t)(Iterator ker); void (*delete_ker_l2t)(Iterator ker); #ifdef SCTL_HAVE_PVFMM pvfmm::Kernel pvfmm_ker_m2t; pvfmm::Kernel pvfmm_ker_l2t; StaticArray bbox; #endif }; struct S2TData { Iterator ker_s2t; Integer dim_src, dim_trg, dim_normal; void (*ker_s2t_eval)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*ker_s2t_eval_omp)(Vector& v_trg, const Vector& r_trg, const Vector& r_src, const Vector& n_src, const Vector& v_src, Integer digits, ConstIterator self); void (*delete_ker_s2t)(Iterator ker); #ifdef SCTL_HAVE_PVFMM mutable Real bbox_scale; mutable StaticArray bbox_offset; mutable Vector src_scal_exp, trg_scal_exp; mutable Vector src_scal, trg_scal; mutable pvfmm::Kernel pvfmm_ker_s2t; mutable pvfmm::PtFMM_Tree* tree_ptr; mutable pvfmm::PtFMM fmm_ctx; mutable bool setup_tree; mutable bool setup_ker; #endif }; static void BuildSrcTrgScal(const S2TData& s2t_data, bool verbose); template static void DeleteKer(Iterator ker); void CheckKernelDims() const; void DeleteS2T(const std::string& src_name, const std::string& trg_name); #ifdef SCTL_HAVE_PVFMM template struct PVFMMKernelFn; // construct PVFMMKernel from SCTLKernel void EvalPVFMM(Vector& U, const std::string& trg_name) const; #endif FMMKernels fmm_ker; std::map src_map; std::map trg_map; std::map, S2TData> s2t_map; Comm comm_; Integer digits_; }; } // end namespace #include SCTL_INCLUDE(fmm-wrapper.txx) #endif //_SCTL_FMM_WRAPPER_HPP_