diff --git a/src/DCPSE/DCPSE_op/DCPSE_surface_op.hpp b/src/DCPSE/DCPSE_op/DCPSE_surface_op.hpp index 030c78730c006aa59fa6d2dd8dd27994cbe31e9b..eed13a17b1e8be32ffad5351f7886efaff1f2490 100644 --- a/src/DCPSE/DCPSE_op/DCPSE_surface_op.hpp +++ b/src/DCPSE/DCPSE_op/DCPSE_surface_op.hpp @@ -62,6 +62,27 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } + /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -131,6 +152,27 @@ public: } + + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -201,6 +243,26 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -273,6 +335,26 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -343,6 +425,26 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -414,6 +516,26 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -484,6 +606,26 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -556,6 +698,26 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -628,6 +790,26 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * @@ -700,6 +882,113 @@ public: } + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } + /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. + * + * + * \param parts particle set + */ + template<typename particles_type> + void update(particles_type &particles) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->createNormalParticles<NORMAL_ID>(particles); + dcpse_temp->initializeUpdate(particles); + dcpse_temp->accumulateAndDeleteNormalParticles(particles); + + } +}; + +template<unsigned int NORMAL_ID> +class SurfaceDerivative_G { + + void *dcpse; + +public: + /*! \brief Class for Creating the DCPSE Operator Dxx and objects and computs DCPSE Kernels. + * + * + * \param parts particle set + * \param ord order of convergence of the operator + * \param rCut Argument for cell list construction + * \param oversampling_factor multiplier to the minimum no. of particles required by the operator in support + * \param support_options default:N_particles, Radius can be used to select all particles inside rCut. Overrides oversampling. + * + * \return Operator Dxx which is a function on Vector_dist_Expressions + * + */ + template<typename particles_type> + SurfaceDerivative_G(particles_type &parts, unsigned int ord, typename particles_type::stype rCut,typename particles_type::stype nSpacing, + const Point<particles_type::dims, unsigned int> &p,support_options opt = support_options::RADIUS) { + + dcpse = new Dcpse<particles_type::dims, particles_type>(parts, p, ord, rCut,nSpacing,value_t<NORMAL_ID>(), opt); + } + + template<typename particles_type> + void deallocate(particles_type &parts) { + delete (Dcpse<particles_type::dims, particles_type> *) dcpse; + } + + template<typename operand_type> + vector_dist_expression_op<operand_type, Dcpse<operand_type::vtype::dims, typename operand_type::vtype>, VECT_DCPSE> + operator()(operand_type arg) { + typedef Dcpse<operand_type::vtype::dims, typename operand_type::vtype> dcpse_type; + + return vector_dist_expression_op<operand_type, dcpse_type, VECT_DCPSE>(arg, *(dcpse_type *) dcpse); + } + + template<typename particles_type> + void checkMomenta(particles_type &particles) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->checkMomenta(particles); + + } + + template<unsigned int prp, typename particles_type> + void DrawKernel(particles_type &particles, int k) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->template DrawKernel<prp>(particles, k); + + } + + /*! \brief Method for Saving the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be saved. + */ + template<typename particles_type> + void save(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->save(file); + } + /*! \brief Method for Loading the DCPSE Operator. + * + * \param parts particle set + * \param file name for data to be loaded from. + */ + template<typename particles_type> + void load(particles_type &particles, const std::string &file) { + auto dcpse_temp = (Dcpse<particles_type::dims, particles_type> *) dcpse; + dcpse_temp->load(file); + } /*! \brief Method for Updating the DCPSE Operator by recomputing DCPSE Kernels. * * diff --git a/src/DCPSE/DCPSE_op/tests/DCPSE_op_Surface_tests.cpp b/src/DCPSE/DCPSE_op/tests/DCPSE_op_Surface_tests.cpp index ed225ee05dc2345f1e918bf2067e3944520e8052..3664e8627074a4b2c4380c00f39c0a5480aa32c8 100644 --- a/src/DCPSE/DCPSE_op/tests/DCPSE_op_Surface_tests.cpp +++ b/src/DCPSE/DCPSE_op/tests/DCPSE_op_Surface_tests.cpp @@ -645,6 +645,250 @@ BOOST_AUTO_TEST_CASE(dcpse_surface_sphere_old) { vector_dist<3, double, aggregate<double,double,double,double,double,double,double[3]>> domain(0, box, bc, ghost); + //Init_DCPSE(domain) + BOOST_TEST_MESSAGE("Init domain..."); + + auto it = domain.getGridIterator(sz); + while (it.isNext()) { + domain.add(); + + auto key = it.get(); + double x = key.get(0) * it.getSpacing(0); + domain.getLastPos()[0] = x; + double y = key.get(1) * it.getSpacing(1); + domain.getLastPos()[1] = y; + + domain.getLastPos()[2] = 0; + + ++it; + } + + // Add multi res patch 1 + + { + const size_t sz2[3] = {40,40,1}; + Box<3,double> bx({0.25 + it.getSpacing(0)/4.0,0.25 + it.getSpacing(0)/4.0,-0.5},{sz2[0]*it.getSpacing(0)/2.0 + 0.25 + it.getSpacing(0)/4.0, sz2[1]*it.getSpacing(0)/2.0 + 0.25 + it.getSpacing(0)/4.0,0.5}); + openfpm::vector<size_t> rem; + + auto it = domain.getDomainIterator(); + + while (it.isNext()) + { + auto k = it.get(); + + Point<3,double> xp = domain.getPos(k); + + if (bx.isInside(xp) == true) + { + rem.add(k.getKey()); + } + + ++it; + } + + domain.remove(rem); + + auto it2 = domain.getGridIterator(sz2); + while (it2.isNext()) { + domain.add(); + + auto key = it2.get(); + double x = key.get(0) * spacing/2.0 + 0.25 + spacing/4.0; + domain.getLastPos()[0] = x; + double y = key.get(1) * spacing/2.0 + 0.25 + spacing/4.0; + domain.getLastPos()[1] = y; + domain.getLastPos()[2] = 0; + + ++it2; + } + } + + // Add multi res patch 2 + + { + const size_t sz2[3] = {40,40,1}; + Box<3,double> bx({0.25 + 21.0*spacing/8.0,0.25 + 21.0*spacing/8.0,-5},{sz2[0]*spacing/4.0 + 0.25 + 21.0*spacing/8.0, sz2[1]*spacing/4.0 + 0.25 + 21*spacing/8.0,5}); + openfpm::vector<size_t> rem; + + auto it = domain.getDomainIterator(); + + while (it.isNext()) + { + auto k = it.get(); + + Point<3,double> xp = domain.getPos(k); + + if (bx.isInside(xp) == true) + { + rem.add(k.getKey()); + } + + ++it; + } + + domain.remove(rem); + + auto it2 = domain.getGridIterator(sz2); + while (it2.isNext()) { + domain.add(); + auto key = it2.get(); + double x = key.get(0) * spacing/4.0 + 0.25 + 21*spacing/8.0; + domain.getLastPos()[0] = x; + double y = key.get(1) * spacing/4.0 + 0.25 + 21*spacing/8.0; + domain.getLastPos()[1] = y; + domain.getLastPos()[2] = 0; + + ++it2; + } + } + + /////////////////////// + + BOOST_TEST_MESSAGE("Sync domain across processors..."); + + domain.map(); + domain.ghost_get<0>(); + + openfpm::vector<aggregate<int>> bulk; + openfpm::vector<aggregate<int>> up_p; + openfpm::vector<aggregate<int>> dw_p; + openfpm::vector<aggregate<int>> l_p; + openfpm::vector<aggregate<int>> r_p; + openfpm::vector<aggregate<int>> ref_p; + + auto v = getV<0>(domain); + auto RHS=getV<1>(domain); + auto sol = getV<2>(domain); + auto anasol = getV<3>(domain); + auto err = getV<4>(domain); + auto DCPSE_sol=getV<5>(domain); + + // Here fill me + + Box<3, double> up({box.getLow(0) - spacing / 2.0, box.getHigh(1) - spacing / 2.0,-5}, + {box.getHigh(0) + spacing / 2.0, box.getHigh(1) + spacing / 2.0,5}); + + Box<3, double> down({box.getLow(0) - spacing / 2.0, box.getLow(1) - spacing / 2.0,-5}, + {box.getHigh(0) + spacing / 2.0, box.getLow(1) + spacing / 2.0,5}); + + Box<3, double> left({box.getLow(0) - spacing / 2.0, box.getLow(1) + spacing / 2.0,-5}, + {box.getLow(0) + spacing / 2.0, box.getHigh(1) - spacing / 2.0,5}); + + Box<3, double> right({box.getHigh(0) - spacing / 2.0, box.getLow(1) + spacing / 2.0,-5}, + {box.getHigh(0) + spacing / 2.0, box.getHigh(1) - spacing / 2.0,5}); + + openfpm::vector<Box<3, double>> boxes; + boxes.add(up); + boxes.add(down); + boxes.add(left); + boxes.add(right); + + // Create a writer and write + VTKWriter<openfpm::vector<Box<3, double>>, VECTOR_BOX> vtk_box; + vtk_box.add(boxes); + //vtk_box.write("vtk_box.vtk"); + + auto it2 = domain.getDomainIterator(); + + while (it2.isNext()) { + auto p = it2.get(); + Point<3, double> xp = domain.getPos(p); + if (up.isInside(xp) == true) { + up_p.add(); + up_p.last().get<0>() = p.getKey(); + domain.getProp<1>(p) = -2*M_PI*M_PI*sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + domain.getProp<3>(p) = sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + } else if (down.isInside(xp) == true) { + dw_p.add(); + dw_p.last().get<0>() = p.getKey(); + domain.getProp<1>(p) = -2*M_PI*M_PI*sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + domain.getProp<3>(p) = sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + + } else if (left.isInside(xp) == true) { + l_p.add(); + l_p.last().get<0>() = p.getKey(); + domain.getProp<1>(p) = -2*M_PI*M_PI*sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + domain.getProp<3>(p) = sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + + } else if (right.isInside(xp) == true) { + r_p.add(); + r_p.last().get<0>() = p.getKey(); + domain.getProp<1>(p) = -2*M_PI*M_PI*sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + domain.getProp<3>(p) = sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + + } else { + bulk.add(); + bulk.last().get<0>() = p.getKey(); + domain.getProp<1>(p) = -2*M_PI*M_PI*sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + domain.getProp<3>(p) = sin(M_PI*xp.get(0))*sin(M_PI*xp.get(1)); + } + domain.getProp<6>(p)[0] = 0; + domain.getProp<6>(p)[1] = 0; + domain.getProp<6>(p)[2] = 1; + + ++it2; + } + + domain.ghost_get<1,2,3>(); + SurfaceDerivative_xx<6> Dxx(domain, 2, rCut,1.0,support_options::ADAPTIVE_SURFACE); + +/* v=0; + auto itNNN=domain.getDomainIterator(); + while(itNNN.isNext()){ + auto p=itNNN.get().getKey(); + Dxx.DrawKernel<0,decltype(domain)>(domain,p); + domain.write_frame("Kernel",p); + v=0; + ++itNNN; + } + +*/ + //Dxx.DrawKernel<5,decltype(domain)>(domain,6161); + //domain.write_frame("Kernel",6161); + + SurfaceDerivative_yy<6> Dyy(domain, 2, rCut,1.0,support_options::ADAPTIVE_SURFACE); + SurfaceDerivative_zz<6> Dzz(domain, 2, rCut,1.0,support_options::ADAPTIVE_SURFACE); + + Dxx.save(domain,"Sdxx_test"); + Dyy.save(domain,"Sdyy_test"); + Dzz.save(domain,"Sdzz_test"); + + domain.ghost_get<2>(); + sol=Dxx(anasol)+Dyy(anasol)+Dzz(anasol); + domain.ghost_get<5>(); + + double worst1 = 0.0; + + for(int j=0;j<bulk.size();j++) + { auto p=bulk.get<0>(j); + if (fabs(domain.getProp<1>(p) - domain.getProp<2>(p)) >= worst1) { + worst1 = fabs(domain.getProp<1>(p) - domain.getProp<2>(p)); + } + domain.getProp<4>(p) = fabs(domain.getProp<1>(p) - domain.getProp<2>(p)); + + } + //std::cout << "Maximum Analytic Error: " << worst1 << std::endl; + //domain.ghost_get<4>(); + //domain.write("Robin_anasol"); + BOOST_REQUIRE(worst1 < 0.03); + + } + + + BOOST_AUTO_TEST_CASE(dcpse_surface_adaptive_load) { +// int rank; +// MPI_Comm_rank(MPI_COMM_WORLD, &rank); + const size_t sz[3] = {81,81,1}; + Box<3, double> box({0, 0,-5}, {0.5, 0.5,5}); + size_t bc[3] = {NON_PERIODIC, NON_PERIODIC,NON_PERIODIC}; + double spacing = box.getHigh(0) / (sz[0] - 1); + Ghost<3, double> ghost(spacing * 3.1); + double rCut = 3.1 * spacing; + BOOST_TEST_MESSAGE("Init vector_dist..."); + + vector_dist<3, double, aggregate<double,double,double,double,double,double,double[3]>> domain(0, box, bc, ghost); + + //Init_DCPSE(domain) BOOST_TEST_MESSAGE("Init domain..."); @@ -832,10 +1076,12 @@ BOOST_AUTO_TEST_CASE(dcpse_surface_sphere_old) { } domain.ghost_get<1,2,3>(); - SurfaceDerivative_xx<6> Dxx(domain, 2, rCut,6.0,support_options::ADAPTIVE_SURFACE); - SurfaceDerivative_yy<6> Dyy(domain, 2, rCut,6.0,support_options::ADAPTIVE_SURFACE); - SurfaceDerivative_zz<6> Dzz(domain, 2, rCut,6.0,support_options::ADAPTIVE_SURFACE); - + SurfaceDerivative_xx<6> Dxx(domain, 2, rCut,1.0,support_options::LOAD); + SurfaceDerivative_yy<6> Dyy(domain, 2, rCut,1.0,support_options::LOAD); + SurfaceDerivative_zz<6> Dzz(domain, 2, rCut,1.0,support_options::LOAD); + Dxx.load(domain,"Sdxx_test"); + Dyy.load(domain,"Sdyy_test"); + Dzz.load(domain,"Sdzz_test"); domain.ghost_get<2>(); sol=Dxx(anasol)+Dyy(anasol)+Dzz(anasol); @@ -854,10 +1100,12 @@ BOOST_AUTO_TEST_CASE(dcpse_surface_sphere_old) { //std::cout << "Maximum Analytic Error: " << worst1 << std::endl; //domain.ghost_get<4>(); - domain.write("Robin_anasol"); + //domain.write("Robin_anasol"); BOOST_REQUIRE(worst1 < 0.03); } + + BOOST_AUTO_TEST_SUITE_END() #endif diff --git a/src/DCPSE/Dcpse.hpp b/src/DCPSE/Dcpse.hpp index bc30fb3a05803e8a70de415b4441eacf7bfb5b4d..c7ca10234ac2d1b1225a0d72d65bdfb600b766a9 100644 --- a/src/DCPSE/Dcpse.hpp +++ b/src/DCPSE/Dcpse.hpp @@ -213,7 +213,6 @@ public: particles.ghost_get_subset(); // This communicates which ghost particles to be excluded from support if(opt==support_options::ADAPTIVE_SURFACE) { - supportSizeFactor=nSpacing; if(dim==2){ nCount=3; } @@ -226,18 +225,22 @@ public: auto it = particlesTo.getDomainAndGhostIterator(); while (it.isNext()) { auto key_o = particlesTo.getOriginKey(it.get()); - Support support = supportBuilder.getSupport(it,1,opt); + Support support = supportBuilder.getSupport(it,nSpacing,opt); nSpacings.add(supportBuilder.getLastAvgspacing()); ++it; } } - createNormalParticles<NORMAL_ID>(particles); + if(opt!=support_options::LOAD) { + createNormalParticles<NORMAL_ID>(particles); #ifdef SE_CLASS1 - particles.write("WithNormalParticlesQC"); + particles.write("WithNormalParticlesQC"); #endif + } initializeStaticSize(particles, particles, convergenceOrder, rCut, supportSizeFactor); - accumulateAndDeleteNormalParticles(particles); + if(opt!=support_options::LOAD) { + accumulateAndDeleteNormalParticles(particles); + } } Dcpse(vector_type &particles, @@ -728,61 +731,6 @@ public: } - /** - * Computes the value of the Surface differential operator for one particle for o1 representing a scalar - * - * \param key particle - * \param o1 source property - * \return the selected derivative - * - */ - template<typename op_type> - auto computeSurfaceDifferentialOperator(const vect_dist_key_dx &key, - op_type &o1) -> decltype(is_scalar<std::is_fundamental<decltype(o1.value( - key))>::value>::analyze(key, o1)) { - - typedef decltype(is_scalar<std::is_fundamental<decltype(o1.value(key))>::value>::analyze(key, o1)) expr_type; - - T sign = 1.0; - if (differentialOrder % 2 == 0) { - sign = -1; - } - - double eps = localEps.get(key.getKey()); - double epsInvPow = localEpsInvPow.get(key.getKey()); - - auto &particles = o1.getVector(); - -#ifdef SE_CLASS1 - if(particles.getMapCtr()!=this->getUpdateCtr()) - { - std::cerr<<__FILE__<<":"<<__LINE__<<" Error: You forgot a DCPSE operator update after map."<<std::endl; - } -#endif - - expr_type Dfxp = 0; - Support support = localSupports.get(key.getKey()); - size_t xpK = support.getReferencePointKey(); - //Point<dim, T> xp = particles.getPos(xpK); - expr_type fxp = sign * o1.value(key); - size_t kerOff = kerOffsets.get(xpK); - auto & keys = support.getKeys(); - for (int i = 0 ; i < keys.size() ; i++) - { - size_t xqK = keys.get(i); - expr_type fxq = o1.value(vect_dist_key_dx(xqK)); - Dfxp = Dfxp + (fxq + fxp) * calcKernels.get(kerOff+i); - } - //additional contribution of particles normal to reference Particle - Dfxp = Dfxp + (o1.value(key)+fxp) * calcKernels.get(kerOff+keys.size()); - Dfxp = Dfxp * epsInvPow; - // - //T trueDfxp = particles.template getProp<2>(xpK); - // Store Dfxp in the right position - return Dfxp; - } - - void initializeUpdate(vector_type &particlesFrom,vector_type2 &particlesTo) { #ifdef SE_CLASS1 diff --git a/src/DCPSE/SupportBuilder.hpp b/src/DCPSE/SupportBuilder.hpp index 10e75fb397c5ff5fba7dac3bb506a9b9bb8a8bd5..404ea3afa566ca13e693b73da61fdd04af4dd418 100644 --- a/src/DCPSE/SupportBuilder.hpp +++ b/src/DCPSE/SupportBuilder.hpp @@ -24,54 +24,56 @@ enum support_options template<typename vector_type,typename vector_type2> -class SupportBuilder -{ +class SupportBuilder { private: vector_type &domainFrom; vector_type2 &domainTo; decltype(std::declval<vector_type>().getCellList(0.0)) cellList; const Point<vector_type::dims, unsigned int> differentialSignature; - typename vector_type::stype rCut,AvgSpacing; + typename vector_type::stype rCut, AvgSpacing; bool is_interpolation; public: - SupportBuilder(vector_type &domainFrom,vector_type2 &domainTo, const Point<vector_type::dims, unsigned int> differentialSignature, - typename vector_type::stype rCut, - bool is_interpolation) - :domainFrom(domainFrom), - domainTo(domainTo), - differentialSignature(differentialSignature), - rCut(rCut),is_interpolation(is_interpolation) - { + SupportBuilder(vector_type &domainFrom, vector_type2 &domainTo, + const Point<vector_type::dims, unsigned int> differentialSignature, + typename vector_type::stype rCut, + bool is_interpolation) + : domainFrom(domainFrom), + domainTo(domainTo), + differentialSignature(differentialSignature), + rCut(rCut), is_interpolation(is_interpolation) { cellList = domainFrom.getCellList(rCut); } - SupportBuilder(vector_type &domainFrom,vector_type2 &domainTo, unsigned int differentialSignature[vector_type::dims], typename vector_type::stype rCut, bool is_interpolation) - : SupportBuilder(domainFrom,domainTo, Point<vector_type::dims, unsigned int>(differentialSignature), rCut) {} + SupportBuilder(vector_type &domainFrom, vector_type2 &domainTo, + unsigned int differentialSignature[vector_type::dims], typename vector_type::stype rCut, + bool is_interpolation) + : SupportBuilder(domainFrom, domainTo, Point<vector_type::dims, unsigned int>(differentialSignature), + rCut) {} template<typename iterator_type> - Support getSupport(iterator_type itPoint, unsigned int requiredSize, support_options opt) - { + Support getSupport(iterator_type itPoint, unsigned int requiredSize, support_options opt) { // Get spatial position from point iterator vect_dist_key_dx p = itPoint.get(); vect_dist_key_dx pOrig = itPoint.getOrig(); Point<vector_type::dims, typename vector_type::stype> pos = domainTo.getPos(p.getKey()); // Get cell containing current point and add it to the set of cell keys - grid_key_dx<vector_type::dims> curCellKey = cellList.getCellGrid(pos); // Here get the key of the cell where the current point is + grid_key_dx<vector_type::dims> curCellKey = cellList.getCellGrid( + pos); // Here get the key of the cell where the current point is std::set<grid_key_dx<vector_type::dims>> supportCells; supportCells.insert(curCellKey); // Make sure to consider a set of cells providing enough points for the support - enlargeSetOfCellsUntilSize(supportCells, requiredSize + 1,opt); // NOTE: this +1 is because we then remove the point itself + enlargeSetOfCellsUntilSize(supportCells, requiredSize + 1, + opt); // NOTE: this +1 is because we then remove the point itself // Now return all the points from the support into a vector - std::vector<size_t> supportKeys = getPointsInSetOfCells(supportCells,p,pOrig,requiredSize,opt); + std::vector<size_t> supportKeys = getPointsInSetOfCells(supportCells, p, pOrig, requiredSize, opt); - if (is_interpolation == false) - { + if (is_interpolation == false) { auto p_o = domainFrom.getOriginKey(p.getKey()); std::remove(supportKeys.begin(), supportKeys.end(), p_o.getKey()); } @@ -80,78 +82,65 @@ public: return Support(p_o.getKey(), openfpm::vector_std<size_t>(supportKeys.begin(), supportKeys.end())); } - typename vector_type::stype getLastAvgspacing() - { + typename vector_type::stype getLastAvgspacing() { return this->AvgSpacing; } private: - size_t getCellLinId(const grid_key_dx<vector_type::dims> &cellKey) - { + size_t getCellLinId(const grid_key_dx<vector_type::dims> &cellKey) { mem_id id = cellList.getGrid().LinId(cellKey); return static_cast<size_t>(id); } - size_t getNumElementsInCell(const grid_key_dx<vector_type::dims> &cellKey) - { + size_t getNumElementsInCell(const grid_key_dx<vector_type::dims> &cellKey) { const size_t curCellId = getCellLinId(cellKey); size_t numElements = cellList.getNelements(curCellId); return numElements; } - size_t getNumElementsInSetOfCells(const std::set<grid_key_dx<vector_type::dims>> &set) - { + size_t getNumElementsInSetOfCells(const std::set<grid_key_dx<vector_type::dims>> &set) { size_t tot = 0; - for (const auto cell : set) - { + for (const auto cell: set) { tot += getNumElementsInCell(cell); } return tot; } void enlargeSetOfCellsUntilSize(std::set<grid_key_dx<vector_type::dims>> &set, unsigned int requiredSize, - support_options opt) - { - if (opt==support_options::RADIUS){ - auto cell=*set.begin(); + support_options opt) { + if (opt == support_options::RADIUS || opt == support_options::ADAPTIVE_SURFACE) { + auto cell = *set.begin(); grid_key_dx<vector_type::dims> middle; - int n=std::ceil(rCut/cellList.getCellBox().getHigh(0)); + int n = std::ceil(rCut / cellList.getCellBox().getHigh(0)); size_t sz[vector_type::dims]; - for (int i=0;i<vector_type::dims;i++) - { - sz[i]=2*n+1; - middle.set_d(i,n); + for (int i = 0; i < vector_type::dims; i++) { + sz[i] = 2 * n + 1; + middle.set_d(i, n); } - grid_sm<vector_type::dims,void> g(sz); + grid_sm<vector_type::dims, void> g(sz); grid_key_dx_iterator<vector_type::dims> g_k(g); - while(g_k.isNext()) - { - auto key=g_k.get(); - key=cell+key-middle; - if (isCellKeyInBounds(key)) - { + while (g_k.isNext()) { + auto key = g_k.get(); + key = cell + key - middle; + if (isCellKeyInBounds(key)) { set.insert(key); } ++g_k; } - } - else{ - while (getNumElementsInSetOfCells(set) < 5.0*requiredSize) //Why 5*requiredSize? Becasue it can help with adaptive resolutions. + } else { + while (getNumElementsInSetOfCells(set) < + 5.0 * requiredSize) //Why 5*requiredSize? Becasue it can help with adaptive resolutions. { auto tmpSet = set; - for (const auto el : tmpSet) - { - for (unsigned int i = 0; i < vector_type::dims; ++i) - { + for (const auto el: tmpSet) { + for (unsigned int i = 0; i < vector_type::dims; ++i) { const auto pOneEl = el.move(i, +1); const auto mOneEl = el.move(i, -1); - if (isCellKeyInBounds(pOneEl)) - { + if (isCellKeyInBounds(pOneEl)) { set.insert(pOneEl); } - if (isCellKeyInBounds(mOneEl)) - { + if (isCellKeyInBounds(mOneEl)) { set.insert(mOneEl); } } @@ -162,77 +151,73 @@ private: } std::vector<size_t> getPointsInSetOfCells(std::set<grid_key_dx<vector_type::dims>> set, - vect_dist_key_dx & p, - vect_dist_key_dx & pOrig, - size_t requiredSupportSize, - support_options opt) - { - struct reord - { + vect_dist_key_dx &p, + vect_dist_key_dx &pOrig, + size_t requiredSupportSize, + support_options opt) { + struct reord { typename vector_type::stype dist; size_t offset; - bool operator<(const reord & p) const - {return this->dist < p.dist;} + bool operator<(const reord &p) const { return this->dist < p.dist; } }; openfpm::vector<reord> rp; std::vector<size_t> points; - Point<vector_type::dims,typename vector_type::stype> xp = domainTo.getPos(p); - for (const auto cellKey : set) - { + Point<vector_type::dims, typename vector_type::stype> xp = domainTo.getPos(p); + for (const auto cellKey: set) { const size_t cellLinId = getCellLinId(cellKey); const size_t elemsInCell = getNumElementsInCell(cellKey); - for (size_t k = 0; k < elemsInCell; ++k) - { + for (size_t k = 0; k < elemsInCell; ++k) { size_t el = cellList.get(cellLinId, k); - if (pOrig.getKey() == el && is_interpolation == false) {continue;} + if (pOrig.getKey() == el && is_interpolation == false) { continue; } - Point<vector_type::dims,typename vector_type::stype> xq = domainFrom.getPosOrig(el); + Point<vector_type::dims, typename vector_type::stype> xq = domainFrom.getPosOrig(el); //points.push_back(el); reord pr; pr.dist = xp.distance(xq); pr.offset = el; - rp.add(pr); } } - if (opt == support_options::RADIUS) - { - for (int i = 0 ; i < rp.size() ; i++) - { - if (rp.get(i).dist < rCut) - { + if (opt == support_options::RADIUS) { + for (int i = 0; i < rp.size(); i++) { + if (rp.get(i).dist < rCut) { points.push_back(rp.get(i).offset); } } - /* #ifdef SE_CLASS1 - if (points.size()<requiredSupportSize) - { - std::cerr<<__FILE__<<":"<<__LINE__<<"Note that the DCPSE neighbourhood doesn't have asked no. particles (Increase the rCut or reduce the over_sampling factor)"; - std::cout<<"Particels asked (minimum*oversampling_factor): "<<requiredSupportSize<<". Particles Possible with given options:"<<points.size()<<"."<<std::endl; - } - #endif*/ + /* #ifdef SE_CLASS1 + if (points.size()<requiredSupportSize) + { + std::cerr<<__FILE__<<":"<<__LINE__<<"Note that the DCPSE neighbourhood doesn't have asked no. particles (Increase the rCut or reduce the over_sampling factor)"; + std::cout<<"Particels asked (minimum*oversampling_factor): "<<requiredSupportSize<<". Particles Possible with given options:"<<points.size()<<"."<<std::endl; + } + #endif*/ } - else - { rp.sort(); - AvgSpacing=rp.get(1).dist; - for (int i = 0 ; i < requiredSupportSize ; i++) - { - if(opt==support_options::ADAPTIVE_SURFACE && rp.get(i).dist > rCut) - {} - else{ - points.push_back(rp.get(i).offset); + else if(opt == support_options::ADAPTIVE_SURFACE) { + AvgSpacing = std::numeric_limits<double>::max(); + for (int i = 0; i < rp.size(); i++) { + if (AvgSpacing > rp.get(i).dist && rp.get(i).dist != 0) { + AvgSpacing = rp.get(i).dist; + } + } + for (int i = 0; i < rp.size(); i++) { + if (rp.get(i).dist < 3.9 * AvgSpacing) { + points.push_back(rp.get(i).offset); } - //AvgSpacing+=rp.get(i).dist; } - //AvgSpacing=AvgSpacing/requiredSupportSize; } - + else { + rp.sort(); + for (int i = 0; i < requiredSupportSize; i++) { + points.push_back(rp.get(i).offset); + } + } + //AvgSpacing=AvgSpacing/requiredSupportSize return points; }