int FMM_Init(MPI_Comm& comm, FMMData *fmm_data){ int myrank, np; MPI_Comm_rank(comm, &myrank); MPI_Comm_size(comm,&np); FMM_Mat_t *fmm_mat=new FMM_Mat_t; FMM_Tree_t* tree=new FMM_Tree_t(comm); //Kernel function const pvfmm::Kernel<double>* kernel; if(INPUT_DOF==1) kernel=pvfmm::LaplaceKernel<double>::potn_ker; else if(INPUT_DOF==2) kernel=&pvfmm::ker_helmholtz; else if(INPUT_DOF==3) kernel=&pvfmm::ker_stokes_vel; //Setup FMM data structure. int mult_order=MUL_ORDER; int cheb_deg=CHEB_DEG; bool adap=true; double tol=TOL; pvfmm::BoundaryType bndry=pvfmm::FreeSpace; if(PERIODIC==PETSC_TRUE) bndry=pvfmm::Periodic; typename FMMNode_t::NodeData tree_data; { // Tree Construction (eta). FMM_Tree_t* tree=new FMM_Tree_t(comm); //Various parameters. tree_data.dim=COORD_DIM; tree_data.max_depth=MAXDEPTH; tree_data.cheb_deg=cheb_deg; //Set input function pointer tree_data.input_fn=eta; tree_data.data_dof=1; tree_data.tol=tol*fabs(eta_); std::vector<double> pt_coord; { //Set source coordinates. size_t NN=ceil(pow((double)np,1.0/3.0)); NN=std::max<size_t>(NN,pow(2.0,MINDEPTH)); size_t N_total=NN*NN*NN; size_t start= myrank *N_total/np; size_t end =(myrank+1)*N_total/np; for(size_t i=start;i<end;i++){ pt_coord.push_back(((double)((i/ 1 )%NN)+0.5)/NN); pt_coord.push_back(((double)((i/ NN )%NN)+0.5)/NN); pt_coord.push_back(((double)((i/(NN*NN))%NN)+0.5)/NN); } tree_data.pt_coord=pt_coord; } tree_data.max_pts=1; // Points per octant. //Create Tree and initialize with input data. tree->Initialize(&tree_data); tree->InitFMM_Tree(adap,bndry); // this is getting the center coordinates of each of the nodes of the octree? pt_coord.clear(); std::vector<FMMNode_t*> nlist=tree->GetNodeList(); for(size_t i=0;i<nlist.size();i++){ if(nlist[i]->IsLeaf() && !nlist[i]->IsGhost()){ double s=pow(0.5,nlist[i]->Depth()+1); double* c=nlist[i]->Coord(); pt_coord.push_back(c[0]+s); pt_coord.push_back(c[1]+s); pt_coord.push_back(c[2]+s); } } tree_data.pt_coord=pt_coord; tree->Write2File("results/eta",VTK_ORDER); FMM_Tree_t* eta_tree = tree; fmm_data->eta_tree = eta_tree; //delete tree; } //new // typename FMMNode_t::NodeData tree_data; //Various parameters. // tree_data.dim=COORD_DIM; // tree_data.max_depth=MAXDEPTH; // tree_data.cheb_deg=cheb_deg; { // Tree Construction. bool adap=true; // Manually setting the coordinates where we evaluate the function? std::vector<double> pt_coord; { //Set source coordinates. size_t NN=ceil(pow((double)np,1.0/3.0)); NN=std::max<size_t>(NN,pow(2.0,MINDEPTH)); size_t N_total=NN*NN*NN; size_t start= myrank *N_total/np; size_t end =(myrank+1)*N_total/np; for(size_t i=start;i<end;i++){ pt_coord.push_back(((double)((i/ 1 )%NN)+0.5)/NN); pt_coord.push_back(((double)((i/ NN )%NN)+0.5)/NN); pt_coord.push_back(((double)((i/(NN*NN))%NN)+0.5)/NN); } tree_data.pt_coord=pt_coord; } tree_data.max_pts=1; // Points per octant. //old // //Set input function pointer tree_data.input_fn=fn_input; tree_data.data_dof=kernel->ker_dim[0]; tree_data.tol=tol*f_max; //Create Tree and initialize with input data. tree->Initialize(&tree_data); tree->InitFMM_Tree(adap,bndry); //std::vector<double> pt_coord; Again getting the point coordinates of the centers of the nodes of the octree? pt_coord.clear(); std::vector<FMMNode_t*> nlist=tree->GetNodeList(); for(size_t i=0;i<nlist.size();i++){ if(nlist[i]->IsLeaf() && !nlist[i]->IsGhost()){ double s=pow(0.5,nlist[i]->Depth()+1); double* c=nlist[i]->Coord(); pt_coord.push_back(c[0]+s); pt_coord.push_back(c[1]+s); pt_coord.push_back(c[2]+s); } } tree_data.pt_coord=pt_coord; { //Output max tree depth. std::vector<size_t> all_nodes(MAXDEPTH+1,0); std::vector<size_t> leaf_nodes(MAXDEPTH+1,0); std::vector<FMMNode_t*>& nodes=tree->GetNodeList(); for(size_t i=0;i<nodes.size();i++){ FMMNode_t* n=nodes[i]; if(!n->IsGhost()) all_nodes[n->Depth()]++; if(!n->IsGhost() && n->IsLeaf()) leaf_nodes[n->Depth()]++; } if(!myrank) std::cout<<"All Nodes: "; for(int i=0;i<MAXDEPTH;i++){ int local_size=all_nodes[i]; int global_size; MPI_Allreduce(&local_size, &global_size, 1, MPI_INT, MPI_SUM, comm); if(global_size==0) MAXDEPTH=i; if(!myrank) std::cout<<global_size<<' '; } if(!myrank) std::cout<<'\n'; if(!myrank) std::cout<<"Leaf Nodes: "; for(int i=0;i<MAXDEPTH;i++){ int local_size=leaf_nodes[i]; int global_size; MPI_Allreduce(&local_size, &global_size, 1, MPI_INT, MPI_SUM, comm); if(!myrank) std::cout<<global_size<<' '; } if(!myrank) std::cout<<'\n'; } } size_t n_coeff3=(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3)/6; size_t n_nodes3=(cheb_deg+1)*(cheb_deg+1)*(cheb_deg+1); PetscInt m=0,n=0,M=0,N=0,l=0,L=0; { // Get local and global size long long loc_size=0, glb_size=0; long long loc_nodes=0, glb_nodes=0; std::vector<FMMNode_t*> nlist=tree->GetNodeList(); for(size_t i=0;i<nlist.size();i++){ if(nlist[i]->IsLeaf() && !nlist[i]->IsGhost()){ loc_size+=n_coeff3; //nlist[i]->ChebData().Dim(); loc_nodes+=n_nodes3; } } MPI_Allreduce(&loc_size, &glb_size, 1, MPI_LONG_LONG , MPI_SUM, comm); MPI_Allreduce(&loc_nodes, &glb_nodes, 1, MPI_LONG_LONG, MPI_SUM, comm); n=loc_size*kernel->ker_dim[0]; N=glb_size*kernel->ker_dim[0]; m=loc_size*kernel->ker_dim[1]; M=glb_size*kernel->ker_dim[1]; l=loc_nodes*kernel->ker_dim[0]; L=glb_nodes*kernel->ker_dim[0]; std::cout << L << std::endl; num_oct=glb_size/n_coeff3; } if(TREE_ONLY) return 0; //Initialize FMM_Mat. fmm_mat->Initialize(mult_order,cheb_deg,comm,kernel); fmm_data->kernel =kernel ; fmm_data->fmm_mat=fmm_mat; fmm_data->tree =tree ; fmm_data->bndry =bndry ; fmm_data->m=m; fmm_data->n=n; fmm_data->M=M; fmm_data->N=N; fmm_data->l=l; fmm_data->L=L; return 0; }
int main() { int n,i,value=0; //number of nodes scanf("%d",&n); int a[n]; for(i=1;i<=n;i++){ scanf("%d",&a[i]); } char str[20]; scanf("%s",str); while(strcmp(str,"exit")!=0){ if(strcmp(str,"parent")==0){ scanf("%d",&i); value=parent(n,a,i); if(value!=-1) printf("%d",a[value]); } else if(strcmp(str,"left")==0){ scanf("%d",&i); value=left(n,a,i); if(value!=-1) printf("%d",a[value]); } else if(strcmp(str,"right")==0){ scanf("%d",&i); value=right(n,a,i); if(value!=-1) printf("%d",a[value]); } else if(strcmp(str,"minimum")==0){ value=minimum(n,a); printf("%d",value); } else if(strcmp(str,"minimum")==0){ value=maximum(n,a); printf("%d",value); } else if(strcmp(str,"leaf_nodes")==0){ leaf_nodes(n,a); } else if(strcmp(str,"buildheap_max")==0){ buildheap_max(n,a); for(i=1;i<=n;i++){ printf("%d ",a[i]); } } else if(strcmp(str,"heapsort")==0){ heapsort(n,a); } else if(strcmp(str,"extract_max")==0){ value=extract_max(n,a); printf("%d",value); } else if(strcmp(str,"extract_min")==0){ value=extract_min(n,a); printf("%d",value); } else if(strcmp(str,"increase_key")==0){ scanf("%d%d",&i,&value); increase_key(n,a,i,value); } else if(strcmp(str,"decrease_key")==0){ scanf("%d%d",&i,&value); decrease_key(n,a,i,value); } else if(strcmp(str,"buildheap_min")==0){ buildheap_min(n,a); for(i=1;i<=n;i++){ printf("%d ",a[i]); } } scanf("%s",str); } return 0; }