/*! \brief Create the VTK point definition * */ std::string get_point_list() { //! vertex node output string std::stringstream v_out; //! For each sub-domain for (size_t i = 0 ; i < vg.size() ; i++) { // For each position in the cell for (size_t j = 0 ; j < vg.get(i).g.size() ; j++) { // If there are no grid in this position if (vg.get(i).g.get(j).grids.size() == 0) continue; //! Get the iterator auto it = vg.get(i).g.get(j).grids.get(0)->getIterator(); //! Where the grid is defined Box<pair::first::dims,typename pair::second> dom; // Calculate the offset of the grid considering its cell position Point<pair::first::dims,typename pair::second> middle = vg.get(i).spacing / 2; Point<pair::first::dims,typename pair::second> one; one.one(); one = one + toPoint<pair::first::dims,typename pair::second>::convert(vg.get(i).g.get(j).cmb); Point<pair::first::dims,typename pair::second> offset = pmul(middle,one) + vg.get(i).offset; // if there is the next element while (it.isNext()) { Point<pair::first::dims,typename pair::second> p; p = it.get().toPoint(); p = pmul(p,vg.get(i).spacing) + offset; if (pair::first::dims == 2) v_out << p.toString() << " 0.0" << "\n"; else v_out << p.toString() << "\n"; // increment the iterator ++it; } } } // return the vertex list return v_out.str(); }
EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const { return c + pmul(x,y); }
/*! \brief Test cell structure * * \tparam CellS * */ template<unsigned int dim, typename T, typename CellS> void Test_cell_sM(SpaceBox<dim,T> & box) { //Space where is living the Cell list //SpaceBox<dim,T> box({0.0f,0.0f,0.0f},{1.0f,1.0f,1.0f}); // Subdivisions size_t div[dim] = {16,16,16}; // Origin Point<dim,T> org({0.0,0.0,0.0}); // grid info grid_sm<dim,void> g_info(div); //! [Usage of cell list multi] // CellS = CellListM<dim,T,8> CellS cl1(box,div); // Create a grid iterator grid_key_dx_iterator<dim> g_it(g_info); // Iterate through each element // Add 1 element for each cell // Usefull definition of points Point<dim,T> end = box.getP2() - box.getP1(); Point<dim,T> middle = end / div / 2.0; Point<dim,T> spacing = end / div; Point<dim,T> offset[dim] = {middle,middle,middle}; // Create offset shift vectors for (size_t i = 0 ; i < dim ; i++) { offset[i].get(i) += (1.0 / div[i]) / 8.0; } size_t id = 0; while (g_it.isNext()) { // Add 2 particles on each cell Point<dim,T> key = Point<dim,T>(g_it.get().toPoint()); key = pmul(key,spacing) + offset[0] + box.getP1(); cl1.add(key,id,1); ++id; key = Point<dim,T>(g_it.get().toPoint()); key = pmul(key,spacing) + offset[1] + box.getP1(); cl1.add(key,id,2); ++id; ++g_it; } // check the cell are correctly filled // reset iterator g_it.reset(); while (g_it.isNext()) { // Add 2 particles on each cell Point<dim,T> key = Point<dim,T>(g_it.get().toPoint()); key = pmul(key,spacing) + offset[2] + box.getP1(); size_t cell = cl1.getCell(key); size_t n_ele = cl1.getNelements(cell); size_t p1 = cl1.getP(cell,1); size_t p2 = cl1.getP(cell,0); size_t v1 = cl1.getV(cell,1); size_t v2 = cl1.getV(cell,0); BOOST_REQUIRE_EQUAL(n_ele,2ul); BOOST_REQUIRE_EQUAL((long int)(p1 - p2),1); BOOST_REQUIRE_EQUAL((long int)(v1 - v2),1); ++g_it; } // Create a grid iterator grid_key_dx<dim> p1(1,1,1); grid_key_dx<dim> p2(div[0]-2,div[1]-2,div[2]-2); grid_key_dx_iterator_sub<dim> g_it_s(g_info,p1,p2); while (g_it_s.isNext()) { Point<dim,T> key = Point<dim,T>(g_it_s.get().toPoint()); key = pmul(key,spacing) + offset[0] + box.getP1(); auto NN = cl1.template getNNIterator<NO_CHECK>(cl1.getCell(key)); size_t total1 = 0; size_t total2 = 0; while(NN.isNext()) { // total if (NN.getV() == 1) total1++; else total2++; ++NN; } BOOST_REQUIRE_EQUAL(total1,(size_t)openfpm::math::pow(3,dim)); BOOST_REQUIRE_EQUAL(total2,(size_t)openfpm::math::pow(3,dim)); auto NNSym = cl1.template getNNIteratorSym<NO_CHECK>(cl1.getCell(key)); total1 = 0; total2 = 0; while(NNSym.isNext()) { // total if (NNSym.getV() == 1) total1++; else total2++; ++NNSym; } BOOST_REQUIRE_EQUAL(total1,(size_t)openfpm::math::pow(3,dim) / 2 + 1); BOOST_REQUIRE_EQUAL(total2,(size_t)openfpm::math::pow(3,dim) / 2 + 1); ++g_it_s; } }
/*! \brief Test cell structure * * \tparam CellS * */ template<unsigned int dim, typename T, typename CellS> void Test_cell_s(SpaceBox<dim,T> & box) { //! [Declare a cell list] //Space where is living the Cell list //SpaceBox<dim,T> box({0.0f,0.0f,0.0f},{1.0f,1.0f,1.0f}); // Subdivisions size_t div[dim] = {16,16,16}; // Origin Point<dim,T> org({0.0,0.0,0.0}); // id Cell list CellS cl2(box,div); //! [Declare a cell list] // grid info grid_sm<dim,void> g_info(div); // Test force reallocation in case of Cell list fast for (size_t i = 0 ; i < CELL_REALLOC * 3 ; i++) { cl2.add(org,i); } // Check the elements BOOST_REQUIRE_EQUAL(cl2.getNelements(cl2.getCell(org)),CELL_REALLOC * 3ul); for (size_t i = 0 ; i < CELL_REALLOC * 3 ; i++) { BOOST_REQUIRE_EQUAL(cl2.get(cl2.getCell(org),i),i); } //! [Usage of cell list] // id Cell list CellS cl1(box,div); // Create a grid iterator grid_key_dx_iterator<dim> g_it(g_info); // Iterate through each element // Add 1 element for each cell // Usefull definition of points Point<dim,T> end = box.getP2() - box.getP1(); Point<dim,T> middle = end / div / 2.0; Point<dim,T> spacing = end / div; Point<dim,T> offset[dim] = {middle,middle,middle}; // Create offset shift vectors for (size_t i = 0 ; i < dim ; i++) { offset[i].get(i) += (1.0 / div[i]) / 8.0; } openfpm::vector<Point<dim,T>> pos; size_t id = 0; while (g_it.isNext()) { // Add 2 particles on each cell Point<dim,T> key = Point<dim,T>(g_it.get().toPoint()); key = pmul(key,spacing) + offset[0] + box.getP1(); pos.add(key); cl1.add(key,id); ++id; key = Point<dim,T>(g_it.get().toPoint()); key = pmul(key,spacing) + offset[1] + box.getP1(); pos.add(key); cl1.add(key,id); ++id; ++g_it; } //! [Usage of cell list] // check the cell are correctly filled // reset iterator g_it.reset(); while (g_it.isNext()) { // Check that there are 2 particles on each cell Point<dim,T> key = Point<dim,T>(g_it.get().toPoint()); key = pmul(key,spacing) + offset[2] + box.getP1(); size_t cell = cl1.getCell(key); size_t n_ele = cl1.getNelements(cell); BOOST_REQUIRE_EQUAL(n_ele,2ul); BOOST_REQUIRE_EQUAL((long int)(cl1.get(cell,1) - cl1.get(cell,0)),1); ++g_it; } // reset itarator g_it.reset(); //! [remove one particle from each cell] while (g_it.isNext()) { // remove 1 particle on each cell Point<dim,T> key = Point<dim,T>(g_it.get().toPoint()); key = pmul(key,spacing) + offset[0] + box.getP1(); auto cell = cl1.getCell(key); // Remove the first particle in the cell cl1.remove(cell,0); ++g_it; } //! [remove one particle from each cell] // Check we have 1 object per cell g_it.reset(); while (g_it.isNext()) { // remove 1 particle on each cell Point<dim,T> key = Point<dim,T>(g_it.get().toPoint()); key = pmul(key,spacing) + offset[0] + box.getP1(); auto cell = cl1.getCell(key); size_t n_ele = cl1.getNelements(cell); BOOST_REQUIRE_EQUAL(n_ele,1ul); ++g_it; } // Check we have 1 object per cell // Create a grid iterator grid_key_dx<dim> p1(1,1,1); grid_key_dx<dim> p2(div[0]-2,div[1]-2,div[2]-2); grid_key_dx_iterator_sub<dim> g_it_s(g_info,p1,p2); id = 0; while (g_it_s.isNext()) { // remove 1 particle on each cell //! [Usage of the neighborhood iterator] Point<dim,T> key = Point<dim,T>(g_it_s.get().toPoint()); key = pmul(key,spacing) + offset[0] + box.getP1(); auto NN = cl1.template getNNIterator<NO_CHECK>(cl1.getCell(key)); size_t total = 0; while(NN.isNext()) { // total total++; ++NN; } //! [Usage of the neighborhood iterator] BOOST_REQUIRE_EQUAL(total,(size_t)openfpm::math::pow(3,dim)); id = cl1.get(cl1.getCell(key),0); auto NNSym = cl1.template getNNIteratorSym<NO_CHECK>(cl1.getCell(key),id,pos); total = 0; while(NNSym.isNext()) { // total total++; ++NNSym; } BOOST_REQUIRE_EQUAL(total,(size_t)openfpm::math::pow(3,dim) / 2 + 1); ++g_it_s; } }