void main() { clrscr(); vector v1, v2, v3; //vector v4 = {"vec 4", 3.5, 4.4, -2.3}; vector *pv1, *pv2, *pv; pv1 = &v1; val_vec(pv1); clrscr(); printvec1(pv1); getch(); //strcpy(v1.nombre, "vec 1"); //v1 = v4; //strcpy(v2.nombre, "vec 2"); //v2.x = 5.5; //v2.y = 6.4; //v2.z = 0.3; /* printvec(v1); printf("\n"); printvec(v2); getch(); pv1 = &v1; pv2 = &v2; printvec1(pv1); printf("\n"); printvec1(pv2); getch();*/ }//void main()
int CompPhiUsingBorn(Vec &true_sol, FMMData &fmm_data){ // Initialize and get data about the problem PetscErrorCode ierr; PetscInt m,n,l, M,N,L; m=fmm_data.m; // local rows n=fmm_data.n; // local columns M=fmm_data.M; // global rows N=fmm_data.N; // global columns l=fmm_data.l; // local val vec length L=fmm_data.L; // global val vec length FMM_Tree_t *tree=fmm_data.tree; const MPI_Comm comm=*(tree->Comm()); int cheb_deg=fmm_data.fmm_mat->ChebDeg(); int omp_p=omp_get_max_threads(); // Get nodes (I think that these are just the ones local to this compute node) std::vector<FMMNode_t*> nlist; { // Get non-ghost, leaf nodes. std::vector<FMMNode_t*>& nlist_=tree->GetNodeList(); for(size_t i=0;i<nlist_.size();i++){ if(nlist_[i]->IsLeaf() && !nlist_[i]->IsGhost()){ nlist.push_back(nlist_[i]); } } } assert(nlist.size()>0); // Pointwise multiplication of \eta and \phi_0 Vec prod; VecCreateMPI(comm,l,PETSC_DETERMINE,&prod); ierr = VecPointwiseMult(prod, fmm_data.eta_val,fmm_data.phi_0_vec); CHKERRQ(ierr); // Get cheb coeffs from the values and store them in the tree { 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 prod_size; ierr = VecGetLocalSize(prod, &prod_size); int data_dof=prod_size/(n_nodes3*nlist.size()); assert(data_dof*n_nodes3*nlist.size()==prod_size); PetscScalar *prod_ptr; ierr = VecGetArray(prod, &prod_ptr); #pragma omp parallel for for(size_t tid=0;tid<omp_p;tid++){ size_t i_start=(nlist.size()* tid )/omp_p; size_t i_end =(nlist.size()*(tid+1))/omp_p; pvfmm::Vector<double> coeff_vec(n_coeff3*data_dof); pvfmm::Vector<double> val_vec(n_nodes3*data_dof); for(size_t i=i_start;i<i_end;i++){ { // copy values of the product vector into val_vec which contains the values in the current node size_t prod_offset=i*n_nodes3*data_dof; for(size_t j=0;j<n_nodes3*data_dof;j++) val_vec[j]=PetscRealPart(prod_ptr[j+prod_offset]); } { // Compute Chebyshev approx pvfmm::Vector<double>& coeff_vec=nlist[i]->ChebData(); if(coeff_vec.Dim()!=(data_dof*(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3))/6){ coeff_vec.ReInit((data_dof*(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3))/6); } pvfmm::cheb_approx<double,double>(&val_vec[0], cheb_deg, data_dof, &coeff_vec[0]); nlist[i]->DataDOF()=data_dof; } } } } //run fmm tree->ClearFMMData(); tree->RunFMM(); tree->Copy_FMMOutput(); tree2vec(fmm_data,true_sol); VecAXPY(true_sol,1,fmm_data.phi_0); vec2tree(true_sol,fmm_data); return 1; }
int mult(Mat M, Vec U, Vec Y){ PetscErrorCode ierr; FMMData* fmm_data=NULL; MatShellGetContext(M, &fmm_data); FMM_Tree_t* tree=fmm_data->tree; const MPI_Comm* comm=tree->Comm(); int cheb_deg=fmm_data->fmm_mat->ChebDeg(); std::vector<double>& eta_vec=fmm_data->eta; Vec& phi_0_vec=fmm_data->phi_0_vec; int omp_p=omp_get_max_threads(); //int omp_p=1; pvfmm::Profile::Tic("FMM_Mul",comm,true); std::vector<FMMNode_t*> nlist; { // Get non-ghost, leaf nodes. std::vector<FMMNode_t*>& nlist_=tree->GetNodeList(); for(size_t i=0;i<nlist_.size();i++){ if(nlist_[i]->IsLeaf() && !nlist_[i]->IsGhost()){ nlist.push_back(nlist_[i]); } } } assert(nlist.size()>0); // Cheb node points 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); std::vector<double> cheb_node_coord1=pvfmm::cheb_nodes<double>(cheb_deg, 1); #pragma omp parallel for for(size_t i=0;i<cheb_node_coord1.size();i++){ cheb_node_coord1[i]=cheb_node_coord1[i]*2.0-1.0; } // Input Vector ( \phi_0_vec * U ) pvfmm::Profile::Tic("FMM_Input",comm,true); { PetscInt U_size; PetscInt phi_0_size; ierr = VecGetLocalSize(U, &U_size); ierr = VecGetLocalSize(phi_0_vec, &phi_0_size); int data_dof=U_size/(n_coeff3*nlist.size()); assert(data_dof*n_coeff3*nlist.size()==U_size); PetscScalar *U_ptr; PetscScalar* phi_0_ptr; ierr = VecGetArray(U, &U_ptr); ierr = VecGetArray(phi_0_vec, &phi_0_ptr); #pragma omp parallel for for(size_t tid=0;tid<omp_p;tid++){ size_t i_start=(nlist.size()* tid )/omp_p; size_t i_end =(nlist.size()*(tid+1))/omp_p; pvfmm::Vector<double> coeff_vec(n_coeff3*data_dof); pvfmm::Vector<double> val_vec(n_nodes3*data_dof); pvfmm::Vector<double> phi_0_part(n_nodes3*data_dof); for(size_t i=i_start;i<i_end;i++){ double s=std::pow(2.0,COORD_DIM*nlist[i]->Depth()*0.5*SCAL_EXP); { // coeff_vec: Cheb coeff data for this node size_t U_offset=i*n_coeff3*data_dof; size_t phi_0_offset = i*n_nodes3*data_dof; for(size_t j=0;j<n_coeff3*data_dof;j++){ coeff_vec[j]=PetscRealPart(U_ptr[j+U_offset])*s; } for(size_t j=0;j<n_nodes3*data_dof;j++){ phi_0_part[j]=PetscRealPart(phi_0_ptr[j+phi_0_offset]); } } // val_vec: Evaluate coeff_vec at Chebyshev node points cheb_eval(coeff_vec, cheb_deg, cheb_node_coord1, cheb_node_coord1, cheb_node_coord1, val_vec); {// phi_0_part*val_vec for(size_t j0=0;j0<data_dof;j0++){ double* vec=&val_vec[j0*n_nodes3]; double* phi_0=&phi_0_part[j0*n_nodes3]; for(size_t j1=0;j1<n_nodes3;j1++) vec[j1]*=phi_0[j1]; } } { // Compute Chebyshev approx pvfmm::Vector<double>& coeff_vec=nlist[i]->ChebData(); if(coeff_vec.Dim()!=(data_dof*(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3))/6){ coeff_vec.ReInit((data_dof*(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3))/6); } pvfmm::cheb_approx<double,double>(&val_vec[0], cheb_deg, data_dof, &coeff_vec[0]); nlist[i]->DataDOF()=data_dof; } } } } pvfmm::Profile::Toc(); // Run FMM ( Compute: G[ \eta * u ] ) tree->ClearFMMData(); tree->RunFMM(); // Copy data from tree to Y pvfmm::Profile::Tic("tree2vec",comm,true); { PetscInt Y_size; ierr = VecGetLocalSize(Y, &Y_size); int data_dof=Y_size/(n_coeff3*nlist.size()); PetscScalar *Y_ptr; ierr = VecGetArray(Y, &Y_ptr); #pragma omp parallel for for(size_t tid=0;tid<omp_p;tid++){ size_t i_start=(nlist.size()* tid )/omp_p; size_t i_end =(nlist.size()*(tid+1))/omp_p; for(size_t i=i_start;i<i_end;i++){ pvfmm::Vector<double>& coeff_vec=((FMM_Mat_t::FMMData*) nlist[i]->FMMData())->cheb_out; double s=std::pow(0.5,COORD_DIM*nlist[i]->Depth()*0.5*SCAL_EXP); size_t Y_offset=i*n_coeff3*data_dof; for(size_t j=0;j<n_coeff3*data_dof;j++) Y_ptr[j+Y_offset]=coeff_vec[j]*s; } } ierr = VecRestoreArray(Y, &Y_ptr); } pvfmm::Profile::Toc(); // Regularize Vec alpha; PetscScalar sca = (PetscScalar).00001; VecDuplicate(Y,&alpha); VecSet(alpha,sca); ierr = VecPointwiseMult(alpha,alpha,U); ierr = VecAXPY(Y,1,alpha); // Output Vector ( Compute: U + G[ \eta * U ] ) pvfmm::Profile::Tic("FMM_Output",comm,true); ierr = VecAXPY(Y,1,U);CHKERRQ(ierr); pvfmm::Profile::Toc(); ierr = VecDestroy(&alpha); CHKERRQ(ierr); pvfmm::Profile::Toc(); return 0; }