void RS_Spline::rbsplinu(size_t npts, size_t k, size_t p1, const std::vector<RS_Vector>& b, const std::vector<double>& h, std::vector<RS_Vector>& p) const{ size_t const nplusc = npts + k; /* generate the periodic knot vector */ std::vector<double> const x = knotu(npts, k); /* calculate the points on the rational B-spline curve */ double t = k-1; double const step = double(npts - k + 1)/(p1 - 1); for (auto& vp: p) { if (x[nplusc-1] - t < 5e-6) t = x[nplusc-1]; /* generate the basis function for this value of t */ auto const nbasis = rbasis(k, t, npts, x, h); /* generate a point on the curve, for x, y, z */ for (size_t i = 0; i < npts; i++) vp += b[i] * nbasis[i]; t += step; } }
/** * Generates a rational B-spline curve using a uniform open knot vector. */ void RS_Spline::rbspline(size_t npts, size_t k, size_t p1, const std::vector<RS_Vector>& b, const std::vector<double>& h, std::vector<RS_Vector>& p) const{ size_t const nplusc = npts + k; // generate the open knot vector auto const x = knot(npts, k); // calculate the points on the rational B-spline curve double t = 0; double const step = x[nplusc-1]/(p1-1); for (auto& vp: p) { if (x[nplusc-1] - t < 5e-6) t = x[nplusc-1]; // generate the basis function for this value of t auto const nbasis = rbasis(k, t, npts, x, h); // generate a point on the curve for (size_t i = 0; i < npts; i++) vp += b[i] * nbasis[i]; t += step; } }
/** * Generates a rational B-spline curve using a uniform open knot vector. */ void RS_Spline::rbspline(size_t npts, size_t k, size_t p1, const std::vector<double>& b, const std::vector<double>& h, std::vector<double>& p) { size_t i,j,icount,jcount; size_t i1; //int x[30]; /* allows for 20 data points with basis function of order 5 */ int nplusc; double step; double t; //double nbasis[20]; // double temp; nplusc = npts + k; std::vector<int> x(nplusc+1, 0); std::vector<double> nbasis(npts+1, 0.); // generate the uniform open knot vector knot(npts,k,x); icount = 0; // calculate the points on the rational B-spline curve t = 0; step = ((double)x[nplusc])/((double)(p1-1)); for (i1 = 1; i1<= p1; i1++) { if ((double)x[nplusc] - t < 5e-6) { t = (double)x[nplusc]; } // generate the basis function for this value of t rbasis(k,t,npts,x,h,nbasis); // generate a point on the curve for (j = 1; j <= 3; j++) { jcount = j; p[icount+j] = 0.; // Do local matrix multiplication for (i = 1; i <= npts; i++) { // temp = nbasis[i]*b[jcount]; // p[icount + j] = p[icount + j] + temp; p[icount + j] += nbasis[i]*b[jcount]; jcount = jcount + 3; } } icount = icount + 3; t = t + step; } }
void rbspline2( int npts,int k,int p1,double b[],double h[], bool bCalculateKnots, double knots[], double p[] ) { const int nplusc = npts + k; std::vector<double> nbasis; nbasis.resize( npts+1 ); /* generate the uniform open knot vector */ if( bCalculateKnots == true ) knot(npts, k, knots); int icount = 0; /* calculate the points on the rational B-spline curve */ double t = 0.0; const double step = ((double)knots[nplusc])/((double)(p1-1)); for( int i1 = 1; i1<= p1; i1++ ) { if( (double)knots[nplusc] - t < 5e-6 ) { t = (double)knots[nplusc]; } /* generate the basis function for this value of t */ rbasis(k, t, npts, knots, h, &(nbasis[0])); for( int j = 1; j <= 3; j++ ) { /* generate a point on the curve */ int jcount = j; p[icount+j] = 0.; for( int i = 1; i <= npts; i++ ) { /* Do local matrix multiplication */ const double temp = nbasis[i]*b[jcount]; p[icount + j] = p[icount + j] + temp; jcount = jcount + 3; } } icount = icount + 3; t = t + step; } }
void rbsplinu(int npts,int k,int p1,double b[],double h[], double p[]) { int i,j,icount,jcount; int i1; int nplusc; double step; double t; double temp; std::vector<double> nbasis; std::vector<int> x; nplusc = npts + k; x.resize( nplusc+1); nbasis.resize(npts+1); /* zero and redimension the knot vector and the basis array */ for(i = 0; i <= npts; i++){ nbasis[i] = 0.; } for(i = 0; i <= nplusc; i++){ x[i] = 0; } /* generate the uniform periodic knot vector */ knotu(npts,k,&(x[0])); /* printf("The knot vector is "); for (i = 1; i <= nplusc; i++){ printf(" %d ", x[i]); } printf("\n"); printf("The usable parameter range is "); for (i = k; i <= npts+1; i++){ printf(" %d ", x[i]); } printf("\n"); */ icount = 0; /* calculate the points on the rational B-spline curve */ t = k-1; step = ((double)((npts)-(k-1)))/((double)(p1-1)); for (i1 = 1; i1<= p1; i1++){ if ((double)x[nplusc] - t < 5e-6){ t = (double)x[nplusc]; } rbasis(k,t,npts,&(x[0]),h,&(nbasis[0])); /* generate the basis function for this value of t */ /* printf("t = %f \n",t); printf("nbasis = "); for (i = 1; i <= npts; i++){ printf("%f ",nbasis[i]); } printf("\n"); */ for (j = 1; j <= 3; j++){ /* generate a point on the curve */ jcount = j; p[icount+j] = 0.; for (i = 1; i <= npts; i++){ /* Do local matrix multiplication */ temp = nbasis[i]*b[jcount]; p[icount + j] = p[icount + j] + temp; /* printf("jcount,nbasis,b,nbasis*b,p = %d %f %f %f %f\n",jcount,nbasis[i],b[jcount],temp,p[icount+j]); */ jcount = jcount + 3; } } /* printf("icount, p %d %f %f %f \n",icount,p[icount+1],p[icount+2],p[icount+3]); */ icount = icount + 3; t = t + step; } }
void RS_Spline::rbsplinu(int npts, int k, int p1, const std::vector<double>& b, const std::vector<double>& h, std::vector<double>& p) { int i,j,icount,jcount; int i1; //int x[30]; /* allows for 20 data points with basis function of order 5 */ int nplusc; double step; double t; //double nbasis[20]; // double temp; nplusc = npts + k; std::vector<int> x(nplusc+1, 0); std::vector<double> nbasis(npts+1, 0.); /* generate the uniform periodic knot vector */ knotu(npts,k,x); /* printf("The knot vector is "); for (i = 1; i <= nplusc; i++){ printf(" %d ", x[i]); } printf("\n"); printf("The usable parameter range is "); for (i = k; i <= npts+1; i++){ printf(" %d ", x[i]); } printf("\n"); */ icount = 0; /* calculate the points on the rational B-spline curve */ t = k-1; step = ((double)((npts)-(k-1)))/((double)(p1-1)); for (i1 = 1; i1<= p1; i1++) { if ((double)x[nplusc] - t < 5e-6) { t = (double)x[nplusc]; } rbasis(k,t,npts,x,h,nbasis); /* generate the basis function for this value of t */ /* printf("t = %f \n",t); printf("nbasis = "); for (i = 1; i <= npts; i++){ printf("%f ",nbasis[i]); } printf("\n"); */ for (j = 1; j <= 3; j++) { /* generate a point on the curve */ jcount = j; p[icount+j] = 0.; for (i = 1; i <= npts; i++) { /* Do local matrix multiplication */ // temp = nbasis[i]*b[jcount]; // p[icount + j] = p[icount + j] + temp; p[icount + j] += nbasis[i]*b[jcount]; /* printf("jcount,nbasis,b,nbasis*b,p = %d %f %f %f %f\n",jcount,nbasis[i],b[jcount],temp,p[icount+j]); */ jcount = jcount + 3; } } /* printf("icount, p %d %f %f %f \n",icount,p[icount+1],p[icount+2],p[icount+3]); */ icount = icount + 3; t = t + step; } }
int main( int argc, char * argv[ ] ) { // start timer const double t_0 = omp_get_wtime( ); const unsigned int dim = 3; const unsigned int order = DFMM_ORDER; const double eps = DFMM_EPSILON; typedef DimTraits<dim>::point_type point_type; typedef Dof<dim> particle_type; // required command line arguments #ifdef DFMM_USE_OMP if (argc != 5) { #else if (argc != 4) { #endif std::cerr << "Wrong number of command line arguments" << std::endl; exit(-1); } const std::string filename( argv[1]); const unsigned long N = atoi(argv[2]); const unsigned int lmax = atoi(argv[3]); #ifdef DFMM_USE_OMP const unsigned int nthreads = atoi(argv[4]); omp_set_num_threads(nthreads); std::cout << "Using " << omp_get_max_threads() << " threads." << std::endl; #endif particle_type *const particles = new particle_type [N]; unsigned int *const pindices = new unsigned int [N]; ReadParticles(filename, N, particles); // fill pindices for (unsigned int p=0; p<N; ++p) pindices[p] = particles[p].getId(); // plot particles //Plot<particle_type> plotter(particles, N); //plotter.plot(); // get bounding box of root cluster const std::pair<point_type,point_type> bbx = GetBoundingBox(particles, N); // storage: setup and stores level infos, stores kernel wrapper, etc. typedef Storage<dim> storage_type; storage_type storage(bbx, lmax); // setup root cluster typedef Cluster<dim> cluster_type; cluster_type* cl = new cluster_type(N, storage.getRootClusterCenter()); // subdivide root cluster, then generated level based cluster lists std::vector<std::vector<cluster_type*> > all_cluster_vectors; const unsigned int ncl = cl->subdivide(storage.getLevels(), all_cluster_vectors, particles, pindices, lmax); std::cout << "\n- Number of clusters " << ncl << std::endl; // check if particles are in correct cluster AreParticlesInCluster<particle_type> areThey(particles,pindices); bool all_particles_are_in_cluster = true; BOOST_FOREACH(const cluster_type *const lcl, all_cluster_vectors.back()) if (!areThey(lcl, storage.getLevels().at(lcl->getNlevel()))) { std::cout << "Particles are not in cluster they belong to." << std::endl; all_particles_are_in_cluster = false; } assert(all_particles_are_in_cluster); // LAPLACE typedef KernelFunction<LAPLACE3D> kernel_type; typedef kernel_type::value_type value_type; kernel_type kernel; storage.initLevels(); //typedef M2LHandlerSArcmp<dim,order,value_type> m2l_handler_type; //typedef M2LHandlerNA<dim,order,value_type> m2l_handler_type; //typedef M2LHandlerNAsym<dim,order,value_type> m2l_handler_type; //typedef M2LHandlerNAblk<dim,order,value_type> m2l_handler_type; //typedef M2LHandlerIA<dim,order,value_type> m2l_handler_type; typedef M2LHandlerIAsym<dim,order,value_type> m2l_handler_type; //typedef M2LHandlerIAblk<dim,order,value_type> m2l_handler_type; // init m2l handler typedef std::vector<m2l_handler_type> m2l_handler_type_vector; m2l_handler_type_vector all_m2l_handler; storage.initialize(all_m2l_handler); m2l_handler_type::getInfo(); // cluster bases typedef ClusterBasis<dim,order,value_type> clusterbasis_type; std::vector<clusterbasis_type> rbasis(ncl), cbasis(ncl); // cluster expansions typedef ExpansionHandler<dim,order,value_type> expansion_type; std::vector<expansion_type> rexph(ncl), cexph(ncl); // cluster relations typedef Relations<dim> relations_type; std::vector<relations_type> relations(ncl); // setup multilevel relations SetupClusterRelations(all_cluster_vectors, rexph, all_cluster_vectors, cexph, relations, storage.getLevels(), all_m2l_handler); // write out info storage.writeInfo(all_m2l_handler); //////////////////////////////////////////////////////////////////// // draw cross section through cluster oct-tree at "loc" in direction "dir" point_type loc; for (unsigned int i=0; i<dim; ++i) loc[i] = (bbx.first[i]+bbx.second[i]) / 2; std::cout << "\n- Center of particles at " << loc << std::endl; std::cout << " - a = " << bbx.first << "\tb = " << bbx.second << std::endl; // std::cout << "\n- Origin of PS pictures at " << loc << std::endl; //const unsigned int dir0 = 0; //drawCrossSection(filename, loc, dir0, // storage.getRootClusterCenter(), // storage.getRootClusterExtension(), // all_cluster_vectors, storage.getLevels(), all_m2l_handler); // //const unsigned int dir1 = 1; //drawCrossSection(filename, loc, dir1, // storage.getRootClusterCenter(), // storage.getRootClusterExtension(), // all_cluster_vectors, storage.getLevels(), all_m2l_handler); // //const unsigned int dir2 = 2; //drawCrossSection(filename, loc, dir2, // storage.getRootClusterCenter(), // storage.getRootClusterExtension(), // all_cluster_vectors, storage.getLevels(), all_m2l_handler); ////////////////////////////////////////////////////////////////////// // compute m2l operators ComputeM2Loperators(all_m2l_handler, kernel, eps); // l2l/m2m operators std::cout << "\n- Evaluating interpolation operators " << std::flush; const double t_io = omp_get_wtime(); setIO(all_cluster_vectors, rbasis, all_m2l_handler, pindices, particles); setIO(all_cluster_vectors, cbasis, all_m2l_handler, pindices, particles); std::cout << " took " << omp_get_wtime() - t_io << " s" << std::endl; // densities and potentials value_type *const y = new value_type [N]; for (unsigned int n=0; n<N; ++n) y[n] = (double)rand()/(double)RAND_MAX; value_type *const x = new value_type [N]; for (unsigned int n=0; n<N; ++n) x[n] = 0.; // m2m std::cout << "\n- Applying M2M operators\n" << std::flush; const double t_m2m = omp_get_wtime(); ApplyM2Moperators(all_cluster_vectors, cbasis, cexph, all_m2l_handler, y); std::cout << " - overall " << omp_get_wtime() - t_m2m << " s" << std::endl; // m2l std::cout << "\n- Applying M2L operators\n" << std::flush; const double t_m2l = omp_get_wtime(); ApplyM2Loperators(all_cluster_vectors, rexph, cexph, relations, all_m2l_handler); std::cout << " - overall " << omp_get_wtime() - t_m2l << " s" << std::endl; // l2l std::cout << "\n- Applying L2L operators\n" << std::flush; const double t_l2l = omp_get_wtime(); ApplyL2Loperators(all_cluster_vectors, rbasis, rexph, all_m2l_handler, x); std::cout << " - overall " << omp_get_wtime() - t_l2l << " s" << std::endl; // apply near field on the fly typedef NFadder<cluster_type,particle_type,relations_type,kernel_type> nfc_type; ApplyNearField(all_cluster_vectors.back(), nfc_type(kernel, relations, pindices, particles, pindices, particles, x, y)); // std::cout << "\n- Size of value_type is " << sizeof(value_type) // << " byte." << std::endl; // // // direct calculation // const long size = ndofs*ndofs; // const long size_in_bytes = size * sizeof(value_type); // const double mem_dns = (long)size_in_bytes / (1024.*1024.); // std::cout << "\n- Direct calculation of " << ndofs << " times " << ndofs // << " particles requires " // << (long)size_in_bytes / (1024.*1024.) // << " Mb."<< std::endl; // const double t_direct = omp_get_wtime(); // value_type *const x0 = new value_type [ndofs]; // blas::setzero(ndofs, x0); // std::cout << " - Memory allocation " << std::flush; // const double t_alloc = omp_get_wtime(); // value_type *const K = new value_type [ndofs * ndofs]; // const double t_calc = omp_get_wtime(); // std::cout << "took " << t_calc - t_alloc << " s" << std::endl; // std::cout << " - Matrix evaluation " << std::flush; // storage.getFundSol().compute(ndofs, dofs, ndofs, dofs, K); // const double t_matvec = omp_get_wtime(); // std::cout << "took " << t_matvec - t_calc << " s" << std::endl; // // matrix vector product // std::cout << " - Matrix vector multiplication " << std::flush; // blas::gemva(ndofs, ndofs, 1., K, y, x0); // std::cout << "took " << omp_get_wtime() - t_matvec << " s" << std::endl; // std::cout << " took " << omp_get_wtime() - t_direct << " s" << std::endl; // exact clusterX std::cout << "\n- Exact evaluation of cluster X " << std::flush; const double t_ex = omp_get_wtime(); cluster_type *const clx = all_cluster_vectors.back().front(); assert(clx->getNbeg() == 0); const unsigned int nx = clx->getSize(); const unsigned int ny = N; value_type *const x0 = new value_type [nx]; blas::setzero(nx, x0); for (unsigned int i=0; i<nx; ++i) for (unsigned int j=nx; j<ny; ++j) x0[i] += kernel(particles[pindices[i]].getPoint(), particles[pindices[j]].getPoint()) * y[j]; std::cout << "took " << omp_get_wtime() - t_ex << " s" << std::endl; // value_type sum_x = 0; // value_type sum_x0 = 0; // for (unsigned int n=0; n<nx; ++n) { // sum_x += x[ n]; // sum_x0 += x0[n]; // } // std::cout << "\nSize of cluster X = " << nx // << "\tsumx = " << sum_x // << "\tsumx0 = " << sum_x0 << std::endl; // for (unsigned int n=0; n<(10<nx?10:nx); ++n) // std::cout << x[n] << "\t" << x0[n] << "\t" << x[n]-x0[n] << std::endl; std::cout << "\n- L2 error " << computeL2norm( nx, x0, x) << std::endl; std::cout << "- Inf error " << computeINFnorm(nx, x0, x) << std::endl; std::cout << "\n- INTERPOLATION_ORDER = " << order << "\n- EPSILON = " << eps << std::endl; // clear memory delete [] x; delete [] y; delete [] x0; delete cl; delete [] particles; delete [] pindices; //////////////////////////////////////////////////// std::cout << "\n- Overall time " << omp_get_wtime( ) - t_0 << " s" << std::endl; //////////////////////////////////////////////////// return 0; }
/** * Generates a rational B-spline curve using a uniform open knot vector. */ void RS_Spline::rbspline(int npts, int k, int p1, double b[], double h[], double p[]) { int i,j,icount,jcount; int i1; //int x[30]; /* allows for 20 data points with basis function of order 5 */ int nplusc; double step; double t; //double nbasis[20]; // double temp; nplusc = npts + k; int* x = new int[nplusc+1]; double* nbasis = new double[npts+1]; // zero and redimension the knot vector and the basis array for(i = 0; i <= npts; i++) { nbasis[i] = 0.0; } for(i = 0; i <= nplusc; i++) { x[i] = 0; } // generate the uniform open knot vector knot(npts,k,x); icount = 0; // calculate the points on the rational B-spline curve t = 0; step = ((double)x[nplusc])/((double)(p1-1)); for (i1 = 1; i1<= p1; i1++) { if ((double)x[nplusc] - t < 5e-6) { t = (double)x[nplusc]; } // generate the basis function for this value of t rbasis(k,t,npts,x,h,nbasis); // generate a point on the curve for (j = 1; j <= 3; j++) { jcount = j; p[icount+j] = 0.; // Do local matrix multiplication for (i = 1; i <= npts; i++) { // temp = nbasis[i]*b[jcount]; // p[icount + j] = p[icount + j] + temp; p[icount + j] += nbasis[i]*b[jcount]; jcount = jcount + 3; } } icount = icount + 3; t = t + step; } delete[] x; delete[] nbasis; }
void rbsplinu(int npts,int k,int p1,double b[],double h[], double p[]) { int i,j,icount,jcount; int i1; int nplusc; double step; double t; double temp; std::vector<double> nbasis; std::vector<double> x; nplusc = npts + k; x.resize( nplusc+1); nbasis.resize(npts+1); /* zero and redimension the knot vector and the basis array */ for(i = 0; i <= npts; i++){ nbasis[i] = 0.; } for(i = 0; i <= nplusc; i++){ x[i] = 0; } /* generate the uniform periodic knot vector */ knotu(npts,k,&(x[0])); icount = 0; /* calculate the points on the rational B-spline curve */ t = k-1; step = ((double)((npts)-(k-1)))/((double)(p1-1)); for (i1 = 1; i1<= p1; i1++){ if (x[nplusc] - t < 5e-6){ t = x[nplusc]; } rbasis(k,t,npts,&(x[0]),h,&(nbasis[0])); /* generate the basis function for this value of t */ for (j = 1; j <= 3; j++){ /* generate a point on the curve */ jcount = j; p[icount+j] = 0.; for (i = 1; i <= npts; i++){ /* Do local matrix multiplication */ temp = nbasis[i]*b[jcount]; p[icount + j] = p[icount + j] + temp; jcount = jcount + 3; } } icount = icount + 3; t = t + step; } }