/** * \file pvfmm.hpp * \author Dhairya Malhotra, dhairya.malhotra@gmail.com * \date 1-2-2014 * \brief This file contains wrapper functions for PvFMM. */ #ifndef _PVFMM_HPP_ #define _PVFMM_HPP_ #include #include #include #include #include #include #include namespace pvfmm{ typedef FMM_Node > ChebFMM_Node; typedef FMM_Cheb ChebFMM; typedef FMM_Tree ChebFMM_Tree; typedef ChebFMM_Node::NodeData ChebFMM_Data; typedef void (*ChebFn)(double* , int , double*); ChebFMM_Tree* ChebFMM_CreateTree(int cheb_deg, int data_dim, ChebFn fn_ptr, std::vector& trg_coord, MPI_Comm& comm, double tol=1e-6, int max_pts=100, BoundaryType bndry=FreeSpace, int init_depth=0){ int np, myrank; MPI_Comm_size(comm, &np); MPI_Comm_rank(comm, &myrank); ChebFMM_Data tree_data; tree_data.cheb_deg=cheb_deg; tree_data.data_dof=data_dim; tree_data.input_fn=fn_ptr; tree_data.tol=tol; bool adap=true; tree_data.dim=COORD_DIM; tree_data.max_depth=MAX_DEPTH; tree_data.max_pts=max_pts; { // Set points for initial tree. std::vector coord; size_t N=pow(8.0,init_depth); N=(NInitialize(&tree_data); tree->InitFMM_Tree(adap,bndry); return tree; } void ChebFMM_Evaluate(ChebFMM_Tree* tree, std::vector& trg_val, size_t loc_size=0){ tree->RunFMM(); Vector trg_value; Vector trg_scatter; {// Collect data from each node to trg_value and trg_scatter. std::vector trg_value_; std::vector trg_scatter_; std::vector& nodes=tree->GetNodeList(); for(size_t i=0;iIsLeaf() && !nodes[i]->IsGhost()){ Vector& trg_value=nodes[i]->trg_value; Vector& trg_scatter=nodes[i]->trg_scatter; for(size_t j=0;jComm(),loc_size); trg_val.assign(&trg_value[0],&trg_value[0]+trg_value.Dim());; } typedef FMM_Node > PtFMM_Node; typedef FMM_Pts PtFMM; typedef FMM_Tree PtFMM_Tree; typedef PtFMM_Node::NodeData PtFMM_Data; PtFMM_Tree* PtFMM_CreateTree(std::vector& src_coord, std::vector& src_value, std::vector& surf_coord, std::vector& surf_value, std::vector& trg_coord, MPI_Comm& comm, int max_pts=100, BoundaryType bndry=FreeSpace, int init_depth=0){ int np, myrank; MPI_Comm_size(comm, &np); MPI_Comm_rank(comm, &myrank); PtFMM_Data tree_data; bool adap=true; tree_data.dim=COORD_DIM; tree_data.max_depth=MAX_DEPTH; tree_data.max_pts=max_pts; // Set source points. tree_data. src_coord= src_coord; tree_data. src_value= src_value; tree_data.surf_coord=surf_coord; tree_data.surf_value=surf_value; // Set target points. tree_data.trg_coord=trg_coord; tree_data. pt_coord=trg_coord; PtFMM_Tree* tree=new PtFMM_Tree(comm); tree->Initialize(&tree_data); tree->InitFMM_Tree(adap,bndry); return tree; } PtFMM_Tree* PtFMM_CreateTree(std::vector& src_coord, std::vector& src_value, std::vector& trg_coord, MPI_Comm& comm, int max_pts=100, BoundaryType bndry=FreeSpace, int init_depth=0){ std::vector surf_coord; std::vector surf_value; return PtFMM_CreateTree(src_coord, src_value, surf_coord,surf_value, trg_coord, comm, max_pts, bndry, init_depth); } void PtFMM_Evaluate(PtFMM_Tree* tree, std::vector& trg_val, size_t loc_size=0, std::vector* src_val=NULL, std::vector* surf_val=NULL){ if(src_val){ std::vector src_scatter_; std::vector& nodes=tree->GetNodeList(); for(size_t i=0;iIsLeaf() && !nodes[i]->IsGhost()){ Vector& src_scatter=nodes[i]->src_scatter; for(size_t j=0;j src_value=*src_val; Vector src_scatter=src_scatter_; par::ScatterForward(src_value,src_scatter,*tree->Comm()); size_t indx=0; for(size_t i=0;iIsLeaf() && !nodes[i]->IsGhost()){ Vector& src_value_=nodes[i]->src_value; for(size_t j=0;j surf_scatter_; std::vector& nodes=tree->GetNodeList(); for(size_t i=0;iIsLeaf() && !nodes[i]->IsGhost()){ Vector& surf_scatter=nodes[i]->surf_scatter; for(size_t j=0;j surf_value=*surf_val; Vector surf_scatter=surf_scatter_; par::ScatterForward(surf_value,surf_scatter,*tree->Comm()); size_t indx=0; for(size_t i=0;iIsLeaf() && !nodes[i]->IsGhost()){ Vector& surf_value_=nodes[i]->surf_value; for(size_t j=0;jRunFMM(); Vector trg_value; Vector trg_scatter; { std::vector trg_value_; std::vector trg_scatter_; std::vector& nodes=tree->GetNodeList(); for(size_t i=0;iIsLeaf() && !nodes[i]->IsGhost()){ Vector& trg_value=nodes[i]->trg_value; Vector& trg_scatter=nodes[i]->trg_scatter; for(size_t j=0;jComm(),loc_size); trg_val.assign(&trg_value[0],&trg_value[0]+trg_value.Dim());; } }//end namespace #endif //_PVFMM_HPP_