Commit c3556b53 authored by Pietro Incardona's avatar Pietro Incardona

Ghost put working

parent d9335a87
......@@ -29,7 +29,6 @@ int main(int argc, char* argv[])
//
// Get the vcluster object and the number of processor
//
Vcluster & v_cl = create_vcluster();
long int N_prc = v_cl.getProcessingUnits();
......@@ -37,7 +36,7 @@ int main(int argc, char* argv[])
// ### WIKI 3 ###
//
// We find the maximum of the processors rank, that should be the Number of
// processora minus one, only processor 0 print on terminal
// processor minus one, only processor 0 print on terminal
//
long int id = v_cl.getProcessUnitID();
......
......@@ -344,7 +344,7 @@ int main(int argc, char* argv[])
/*!
* \page Vector_0_simple Vector 0 simple
*
* ## Finalize ## {#finalize}
* ## Finalize ## {#finalize_e0_sim}
*
* At the very end of the program we have always to de-initialize the library
*
......@@ -361,7 +361,7 @@ int main(int argc, char* argv[])
/*!
* \page Vector_0_simple Vector 0 simple
*
* # Full code # {#code}
* ## Full code ## {#code_e0_sim}
*
* \include Vector/0_simple/main.cpp
*
......
......@@ -12,7 +12,7 @@ OBJ_VL_SYM = main_vl_sym.o
all: md_dyn md_dyn_expr md_dyn_vl md_dyn_vl_sym
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
$(CC) -O3 -g -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
md_dyn: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
......@@ -27,7 +27,7 @@ md_dyn_vl_sym: $(OBJ_VL_SYM)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
run: all
source $$HOME/openfpm_vars; mpirun -np 3 ./md_dyn; mpirun -np 3 ./md_dyn_expr; mpirun -np 3 ./md_dyn_vl; mpirun -np 3 ./md_dyn_vl_sym
source $$HOME/openfpm_vars; mpirun -np 3 ./md_dyn; mpirun -np 3 ./md_dyn_expr; mpirun -np 3 ./md_dyn_vl; mpirun -np 3 ./md_dyn_vl_sym;
.PHONY: clean all run
......
/*! \page Vector_3_md Vector 3 molecular dynamic
*
* \subpage Vector_3_md_dyn
* \subpage Vector_3_md_vl
*
*/
#include "Vector/vector_dist.hpp"
#include "Decomposition/CartDecomposition.hpp"
#include "data_type/aggregate.hpp"
......@@ -6,7 +13,7 @@
#include "timer.hpp"
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* [TOC]
*
......@@ -31,7 +38,7 @@ constexpr int force = 1;
/*!
*
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* ## Calculate forces ## {#e3_md_cf}
*
......@@ -54,7 +61,7 @@ void calc_forces(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, Ce
//! \cond [calc forces] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* This function in called several time and require neighborhood of each particle. In order to speed-up the
* Cell-list construction we can use updateCellList function to reuse the memory of the previous cell-list.
......@@ -74,7 +81,7 @@ void calc_forces(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, Ce
/*!
*
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md Vector 3 molecular dynamic with cell-list
*
* Get an iterator over the particles and get its position. For each particle p iterate in its neighborhood q
* and calculate the force based on the Lennard-Jhones potential given by
......@@ -155,7 +162,7 @@ void calc_forces(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, Ce
//! \cond [calc forces2] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* ## Calculate energy ## {#e3_md_ce}
*
......@@ -176,7 +183,7 @@ double calc_energy(vector_dist<3,double, aggregate<double[3],double[3]> > & vd,
//! \cond [calc energy] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* Reset the counter for the energy counter and
* update the cell list from the actual particle configuration
......@@ -196,7 +203,7 @@ double calc_energy(vector_dist<3,double, aggregate<double[3],double[3]> > & vd,
/*!
*
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* First we get an iterator over the particles and get its position. For each particle p iterate in its neighborhood q
* and calculate the energy based on the Lennard-Jhones potential given by
......@@ -273,7 +280,7 @@ double calc_energy(vector_dist<3,double, aggregate<double[3],double[3]> > & vd,
int main(int argc, char* argv[])
{
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* ## Initialization ## {#e3_md_init}
*
......@@ -282,11 +289,11 @@ int main(int argc, char* argv[])
* size of the box, and cut-off radius of the interaction. We also define 2 vectors
* x and y (they are like std::vector) used for statistic
*
* \snippet Vector/3_molecular_dynamic/main.cpp constants
* \snippet Vector/3_molecular_dynamic/main.cpp constants run
*
*/
//! \cond [constants] \endcond
//! \cond [constants run] \endcond
double dt = 0.0005;
double sigma = 0.1;
......@@ -297,10 +304,10 @@ int main(int argc, char* argv[])
openfpm::vector<double> x;
openfpm::vector<openfpm::vector<double>> y;
//! \cond [constants] \endcond
//! \cond [constants run] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* Here we Initialize the library, we create a Box that define our domain, boundary conditions and ghost
*
......@@ -330,7 +337,7 @@ int main(int argc, char* argv[])
//! \cond [init] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* Than we define a distributed vector in 3D, containing 2 vectorial properties the
* first is the actual velocity of the particle the other is the force
......@@ -348,7 +355,7 @@ int main(int argc, char* argv[])
//! \cond [vect create] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* ## Particles on a grid like position ## {#e3_md_gl}
*
......@@ -389,7 +396,7 @@ int main(int argc, char* argv[])
//! \cond [vect grid] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* ## Molecular dynamic steps ## {#e3_md_vi}
*
......@@ -397,16 +404,16 @@ int main(int argc, char* argv[])
*
* The verlet integration stepping look like this
*
* $$ \vec{v}(t_{n+1/2}) = \vec{v}_p(t_n) + \frac{1}{2} \delta t \vec{a}(t_n) $$ // Step 1
* $$ \vec{x}(t_{n}) = \vec{x}_p(t_n) + \delta t \vec{v}(t_n+1/2) $$ // Step 1
* \f[ \vec{v}(t_{n+1/2}) = \vec{v}_p(t_n) + \frac{1}{2} \delta t \vec{a}(t_n) \f]
* \f[ \vec{x}(t_{n}) = \vec{x}_p(t_n) + \delta t \vec{v}(t_n+1/2) \f]
*
* calculate the forces $$ \vec{a} (t_{n}) $$ from $$ \vec{x} (t_{n}) $$ // Step 2
* calculate the forces from \f$ \vec{a} (t_{n}) \f$ finally
*
* $$ \vec{v}(t_{n+1}) = \vec{v}_p(t_n+1/2) + \frac{1}{2} \delta t \vec{a}(t_n+1) $$ // Step 3
* \f[ \vec{v}(t_{n+1}) = \vec{v}_p(t_n+1/2) + \frac{1}{2} \delta t \vec{a}(t_n+1) \f]
*
* The cell-list structure is required to calculate forces
*
* Inside this cycle we are using several features that has been explained before in particuilar
* Inside this cycle we are using several features that has been explained before in particular
*
* \see \ref e0_s_assign_pos
*
......@@ -516,7 +523,7 @@ int main(int argc, char* argv[])
std::cout << "Time: " << tsim.getwct() << std::endl;
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* ## Plotting graphs ## {#e3_md_pg}
*
......@@ -560,13 +567,13 @@ int main(int argc, char* argv[])
//! \cond [google chart] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* ## Finalize ## {#finalize}
* ## Finalize ## {#finalize_v_e3_md}
*
* At the very end of the program we have always to de-initialize the library
*
* \snippet Vector/1_celllist/main.cpp finalize
* \snippet Vector/3_molecular_dynamic/main.cpp finalize
*
*/
......@@ -577,18 +584,18 @@ int main(int argc, char* argv[])
//! \cond [finalize] \endcond
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* # Full code # {#code}
* ## Full code ## {#code_v_e3_md}
*
* \include Vector/3_molecular_dynamic/main.cpp
*
*/
/*!
* \page Vector_3_md Vector 3 molecular dynamic
* \page Vector_3_md_dyn Vector 3 molecular dynamic with cell-list
*
* # Code with expression # {#code}
* ## Code with expression ## {#code_v_e3_md_expr}
*
* Here we also show how we can simplify the example using expressions
*
......
openfpm_data @ 36003173
Subproject commit 9301fe459ca2ef81115c642ee7a54c983ddfd6f1
Subproject commit 360031739584423b20497b1364d2c3bcf26c5143
......@@ -844,6 +844,18 @@ public:
this->template ghost_get_<prp...>(v_pos,v_prp,g_m,opt);
}
/*! \brief It synchronize the properties and position of the ghost particles
*
* \tparam op which kind of operation to apply
* \tparam prp list of properties to get synchronize
*
*
*/
template<template<typename,typename> class op, int ... prp> inline void ghost_put()
{
this->template ghost_put_<op,prp...>(v_pos,v_prp,g_m);
}
/*! \brief Remove a set of elements from the distributed vector
*
* \warning keys must be sorted
......
......@@ -407,7 +407,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_sym_cell_list_test )
auto q = NpSym.get();
// if p == q skip this particle
if (q == p.getKey()) {++NpSym; continue;};
if (q == p.getKey() ) {++NpSym; continue;};
// Get position of the particle q
Point<3,double> xq = vd.getPos(q);
......@@ -664,262 +664,5 @@ BOOST_AUTO_TEST_CASE( vector_dist_sym_verlet_list_test )
}
}
struct couple_contrib
{
size_t i;
size_t j;
size_t ir;
size_t jr;
double E;
bool operator<(couple_contrib & ct)
{
return E < ct.E;
}
};
BOOST_AUTO_TEST_CASE( vector_dist_sym_tot_red_computation )
{
if (create_vcluster().getProcessingUnits() > 12)
return;
long int k = 4096*create_vcluster().getProcessingUnits();
size_t base = create_vcluster().getProcessUnitID() * 4096;
long int big_step = k / 30;
big_step = (big_step == 0)?1:big_step;
long int small_step = 21;
print_test( "Testing vector symmetric verlet-list k<=",k);
openfpm::vector<couple_contrib> cct;
openfpm::vector<couple_contrib> cct2;
// 3D test
/* for ( ; k > 8*big_step ; k-= (k > 2*big_step)?big_step:small_step )
{*/
double r_cut = 0.05;
// domain
Box<3,double> box({0.0,0.0,0.0},{1.0,1.0,1.0});
// Boundary conditions
size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
// ghost, big enough to contain the interaction radius
Ghost<3,float> ghost(r_cut);
vector_dist<3,double, aggregate<size_t> > vd(k,box,bc,ghost);
{
auto it = vd.getDomainIterator();
while (it.isNext())
{
auto p = it.get();
vd.getPos(p)[0] = (double)rand()/RAND_MAX;
vd.getPos(p)[1] = (double)rand()/RAND_MAX;
vd.getPos(p)[2] = (double)rand()/RAND_MAX;
vd.getProp<0>(p) = p.getKey() + base;
++it;
}
}
vd.map();
vd.ghost_get<0>();
// Get the Cell list structure
auto NN = vd.getVerlet(r_cut,VL_SYMMETRIC_RED);
auto NNc = vd.getVerlet(r_cut);
// Get an iterator over particles
auto it2 = vd.getDomainAndGhostIterator();
/////////// SYMMETRIC CASE VERLET-LIST REDUCTION ////////
{
auto it2 = vd.getDomainAndGhostIterator();
// DEBUG
// For each particle ...
while (it2.isNext())
{
// ... p
auto p = it2.get();
if( vd.getProp<0>(p) == 2524 || vd.getProp<0>(p) == 4135 )
{
Vcluster & v_cl = create_vcluster();
Point<3,double> xp = vd.getPos(p);
std::cout << "Particle " << p.getKey() << " " << xp.toString() << " " << v_cl.getProcessUnitID() << std::endl;
}
++it2;
}
}
openfpm::vector<couple_contrib> ctt;
double tot_sym = 0.0;
size_t tot_n_sym = 0;
// For each particle ...
while (it2.isNext())
{
// ... p
auto p = it2.get();
// Get the position of the particle p
Point<3,double> xp = vd.getPos(p);
// Get an iterator over the neighborhood of the particle p symmetric
auto NpSym = NN.template getNNIterator<NO_CHECK>(p.getKey());
// For each neighborhood of the particle p
while (NpSym.isNext())
{
// Neighborhood particle q
auto q = NpSym.get();
// if p == q skip this particle
if (q == p.getKey()) {++NpSym; continue;};
// Get position of the particle q
Point<3,double> xq = vd.getPos(q);
// take the normalized direction
double rn = norm2(xp - xq);
////// debug ////////////
couple_contrib cc;
cc.i = vd.getProp<0>(p);
cc.j = vd.getProp<0>(q);
cc.ir = p.getKey();
cc.jr = q;
cc.E = rn;
cct.add(cc);
/////////////////////////
// potential energy (using pow is slower)
tot_sym += rn;
tot_n_sym++;
// Next neighborhood
++NpSym;
}
// Next Particle
++it2;
}
/////////////// NON SYMMETRIC CASE VERLET-LIST ////////////////////////
double tot = 0.0;
size_t tot_n = 0;
auto it = vd.getDomainIterator();
// For each particle ...
while (it.isNext())
{
// ... p
auto p = it.get();
// Get the position of the particle p
Point<3,double> xp = vd.getPos(p);
// Get an iterator over the neighborhood of the particle p
auto Np = NNc.template getNNIterator<NO_CHECK>(p.getKey());
// For each neighborhood of the particle p
while (Np.isNext())
{
// Neighborhood particle q
auto q = Np.get();
// if p == q skip this particle
if (q == p.getKey()) {++Np; continue;};
// Get position of the particle q
Point<3,double> xq = vd.getPos(q);
// take the normalized direction
double rn = norm2(xp - xq);
// potential energy (using pow is slower)
tot += rn/2.0;
tot_n++;
////// debug ////////////
couple_contrib cc;
cc.i = vd.getProp<0>(p);
cc.j = vd.getProp<0>(q);
cc.E = rn;
cct2.add(cc);
/////////////////////////
// Next neighborhood
++Np;
}
// Next Particle
++it;
}
Vcluster & v_cl = create_vcluster();
v_cl.sum(tot_n);
v_cl.sum(tot_n_sym);
v_cl.sum(tot);
v_cl.sum(tot_sym);
v_cl.execute();
openfpm::vector<couple_contrib> cc_collect;
openfpm::vector<couple_contrib> cc_collect2;
v_cl.SGather(cct,cc_collect,0);
v_cl.SGather(cct2,cc_collect2,0);
if (v_cl.getProcessUnitID() == 0)
{
cc_collect.sort();
cc_collect2.sort();
for (size_t i = 0 ; i < cc_collect2.size() ; i++)
{
if (i % 10000 == 0)
std::cout << i << " " << cc_collect2.size() << std::endl;
for (size_t k = i+1 ; k < i+2 && k < cc_collect2.size() ; k++)
{
if (cc_collect2.get(i).i == cc_collect2.get(k).j && cc_collect2.get(i).j == cc_collect2.get(k).i)
{
cc_collect2.remove(k);
}
}
}
for (size_t i = 0 ; i < cc_collect.size() && i < cc_collect2.size() ; i++)
std::cout << "E1: " << cc_collect.get(i).E << " " << cc_collect.get(i).i << "(" << cc_collect.get(i).ir << ")" << " " << cc_collect.get(i).j << "(" << cc_collect.get(i).jr << ")" << " E2: " << cc_collect2.get(i).E << " " << cc_collect2.get(i).i << " " << cc_collect2.get(i).j << std::endl;
}
// BOOST_REQUIRE_EQUAL(2*tot_n_sym,tot_n);
// BOOST_REQUIRE_CLOSE(tot,tot_sym,0.00001);
/* }*/
}
#endif /* SRC_VECTOR_VECTOR_DIST_CELL_LIST_TESTS_HPP_ */
......@@ -39,7 +39,7 @@ class vector_dist_comm
//! It map the processor id with the communication request into map procedure
openfpm::vector<size_t> p_map_req;
//! For each near processor, outgoing particle id and shift vector
//! For each near processor, outgoing particle id
openfpm::vector<openfpm::vector<size_t>> opart;
//! For each near processor, particle shift vector
......@@ -54,15 +54,31 @@ class vector_dist_comm
//! Sending buffer for the ghost particles position
BHeapMemory g_pos_mem;
//! For each adjacent processor it store from which processor come from
openfpm::vector<size_t> prc_recv;
//! the same as prc_recv but for put
openfpm::vector<size_t> prc_recv_put;
//! Number of received elements
openfpm::vector<size_t> n_recv_ele;
//! For each adjacent processor it store the size of the receiving message in byte
openfpm::vector<size_t> recv_sz;
//! The same as recv_sz but for put
openfpm::vector<size_t> recv_sz_put;
//! For each adjacent processor it store the received message for ghost get
openfpm::vector<BHeapMemory> recv_mem_gg;
//! For each processor it store the received message for global map
openfpm::vector<BHeapMemory> recv_mem_gm;
//! Local ghost marker (across the ghost particles it mark from where we have the)
//! replicated ghost particles that are local
size_t lg_m;
/*! \brief It store for each processor the position and properties vector of the particles
*
* This structure is used in the map function
......@@ -93,26 +109,25 @@ class vector_dist_comm
//! definition of the send vector for position
typedef openfpm::vector<Point<dim, St>, ExtPreAlloc<Memory>, typename memory_traits_lin<Point<dim, St>>::type, memory_traits_lin , openfpm::grow_policy_identity> send_pos_vector;
//! Flags that indicate that the function createShiftBox() has been called
bool is_shift_box_created = false;
// this map is used to check if a combination is already present
//! this map is used to check if a combination is already present
std::unordered_map<size_t, size_t> map_cmb;
// The boxes touching the border of the domain are divided in groups (first vector)
// each group contain internal ghost coming from sub-domains of the same section
//! The boxes touching the border of the domain are divided in groups (first vector)
//! each group contain internal ghost coming from sub-domains of the same section
openfpm::vector_std<openfpm::vector_std<Box<dim, St>>>box_f;
// Store the sector for each group (previous vector)
//! Store the sector for each group (previous vector)
openfpm::vector_std<comb<dim>> box_cmb;
//
//! Id of the local particle to replicate for ghost_get
openfpm::vector<aggregate<size_t,size_t>> o_part_loc;
/*! \brief For every internal ghost box we create a structure that order such internal local ghost box in
* shift vectors
*
* \param shifts vectors
*
*/
void createShiftBox()
{
......@@ -156,10 +171,14 @@ class vector_dist_comm
/*! \brief Local ghost from labeled particles
*
* \param v_pos vector of particle positions
* \param v_prp vector of particles properties
*
*/
void local_ghost_from_opart(openfpm::vector<Point<dim, St>> & v_pos, openfpm::vector<prop> & v_prp)
{
lg_m = v_prp.size();
// get the shift vectors
const openfpm::vector<Point<dim, St>> & shifts = dec.getShiftVectors();
......@@ -183,7 +202,7 @@ class vector_dist_comm
*
* \param v_pos vector of particle positions
* \param v_prp vector of particle properties
* \g_m ghost marker
* \param g_m ghost marker
*
*/
void local_ghost_from_dec(openfpm::vector<Point<dim, St>> & v_pos, openfpm::vector<prop> & v_prp, size_t g_m)
......@@ -292,6 +311,8 @@ class vector_dist_comm
// Create the shift boxes
createShiftBox();
lg_m = v_prp.size();
if (box_f.size() == 0)
return;
else
......@@ -338,6 +359,55 @@ class vector_dist_comm
}
}
/*! \brief This function fill the send buffer for ghost_put
*
* \tparam send_vector type used to send data
* \tparam prp_object object containing only the properties to send
* \tparam prp set of properties to send
*
* \param v_prp vector of particle properties
* \param g_send_prp Send buffer to fill
* \param prAlloc_prp Memory object for the send buffer
* \param g_m ghost marker
*
*/
template<typename send_vector, typename prp_object, int ... prp> void fill_send_ghost_put_prp_buf(openfpm::vector<prop> & v_prp, openfpm::vector<send_vector> & g_send_prp, ExtPreAlloc<Memory> * prAlloc_prp, size_t & g_m)
{
// create a number of send buffers equal to the near processors
// from which we received
g_send_prp.resize(prc_recv.size());
for (size_t i = 0; i < g_send_prp.size(); i++)
{
// set the preallocated memory to ensure contiguity
g_send_prp.get(i).setMemory(*prAlloc_prp);
// resize the sending vector (No allocation is produced)
g_send_prp.get(i).resize(n_recv_ele.get(i));
}
size_t accum = g_m;
// Fill the send buffer
for (size_t i = 0; i < prc_recv.size(); i++)
{
size_t j2 = 0;
for (size_t j = accum; j < accum + n_recv_ele.get(i); j++)
{
// source object type
typedef encapc<1, prop, typename openfpm::vector<prop>::layout_type> encap_src;
// destination object type
typedef encapc<1, prp_object, typename openfpm::vector<prp_object>::layout_type> encap_dst;
// Copy only the selected properties
object_si_d<encap_src, encap_dst, OBJ_ENCAP, prp...>(v_prp.get(j), g_send_prp.get(i).get(j2));
j2++;
}
accum = accum + n_recv_ele.get(i);
}
}
/*! \brief This function fill the send buffer for properties after the particles has been label with labelParticles
*
* \tparam send_vector type used to send data
......@@ -530,8 +600,8 @@ class vector_dist_comm
{
if ((long int) p_id != -1)
{
prc_sz.get(p_id)++;lbl_p
.get(p_id).add(key);
prc_sz.get(p_id)++;
lbl_p.get(p_id).add(key);
opart.add(key);
}
else
......@@ -546,7 +616,7 @@ class vector_dist_comm
}
}
/*! \brief This function process the receiced data for the properties and populate the ghost
/*! \brief This function process the received data for the properties and populate the ghost
*
* \tparam send_vector type used to send data
* \tparam prp_object object containing only the properties to send
......@@ -558,6 +628,8 @@ class vector_dist_comm
*/
template<typename send_vector, typename prp_object, int ... prp> void process_received_ghost_prp(openfpm::vector<prop> & v_prp, size_t & g_m)
{
n_recv_ele.resize(recv_mem_gg.size());
// Mark the ghost part
g_m = v_prp.size();
......@@ -575,14 +647,74 @@ class vector_dist_comm
v2.setMemory(*ptr1);
// resize with the number of elements