Real ElementVectorL2Error::computeQpIntegral() { RealVectorValue sol_val(0.0,0.0,0.0); RealVectorValue func_val(0.0,0.0,0.0); sol_val(0) = _u[_qp]; // required variable func_val(0) = _funcx.value(_t, _q_point[_qp]); // required function sol_val(1) = _v[_qp]; sol_val(2) = _w[_qp]; func_val(1) = _funcy.value(_t, _q_point[_qp]); func_val(2) = _funcz.value(_t, _q_point[_qp]); return (sol_val - func_val).size_sq(); // dot product of difference vector }
int eval_function_at_nodes(FMMData *fmm_data, void (*func)(double* coord, int n, double* out), std::vector<double> &func_vec){ FMM_Tree_t* tree=fmm_data->tree ; const MPI_Comm& comm=*tree->Comm(); PetscInt m,n,M,N; m=fmm_data->m; n=fmm_data->n; M=fmm_data->M; N=fmm_data->N; { // Evaluate func at Chebyshev node points. // std::vector<double> func_vec; 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]); } } } int cheb_deg=fmm_data->fmm_mat->ChebDeg(); size_t n_nodes3=(cheb_deg+1)*(cheb_deg+1)*(cheb_deg+1); func_vec.resize(n_nodes3*nlist.size()); std::vector<double> cheb_node_coord3=pvfmm::cheb_nodes<double>(cheb_deg, 3); int omp_p=omp_get_max_threads(); #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; std::vector<double> cheb_node_coord3_(n_nodes3*3); std::vector<double> func_val(n_nodes3); for(size_t i=i_start;i<i_end;i++){ // Shift Cheb node points and evaluate func double* coord=nlist[i]->Coord(); double s=pow(0.5,nlist[i]->Depth()); for(size_t j=0;j<n_nodes3;j++){ cheb_node_coord3_[j*3+0]=cheb_node_coord3[j*3+0]*s+coord[0]; cheb_node_coord3_[j*3+1]=cheb_node_coord3[j*3+1]*s+coord[1]; cheb_node_coord3_[j*3+2]=cheb_node_coord3[j*3+2]*s+coord[2]; } func(&cheb_node_coord3_[0], n_nodes3, &func_val[0]); size_t vec_offset=i*n_nodes3; for(size_t j=0;j<n_nodes3;j++){ func_vec[vec_offset+j]=func_val[j]; } } } } return 1; }