int kmparticle_ptr(particle_t* p) { HASH_DEL(particles, p); remove_body(p->body); free(p); return 0; }
int kmparticle_id(int id) { particle_t* p = particle(id); if(p == NULL) { return -1; } HASH_DEL(particles, p); remove_body(p->body); free(p); return 0; }
int QuadTree::_update(Body ** removed_bodies) { int index = 0; if(!has_children()) { for(size_t i=0; i<bodies->size(); ++i) { if(!boundary.containsPoint((*bodies)[i]->position)) { remove_body((*bodies)[i]); removed_bodies[index++] = (*bodies)[i]; bodies->erase(bodies->begin() + i); } } } else if(northWest != NULL) { int empty = 0; for(QuadTree * t : children) { index += t->_update(removed_bodies + index); if(t->empty()) ++empty; } if(empty == 4) { /* All childrens are empty, delete them, so that we also become empty */ for(QuadTree * &t : children) { delete t; t = nullptr; } } for(int i=0;i<index;++i) { remove_body(removed_bodies[i]); } } else { printf("Derp\n"); abort(); } return index; }
void MultisphereParallel::exchange() { int i,m,nsend,nrecv,nrecv1,nrecv2; double lo,hi,value; double x[3]; double *sublo,*subhi,*buf; MPI_Request request; MPI_Status status; // subbox bounds for orthogonal // triclinic not implemented sublo = domain->sublo; subhi = domain->subhi; // loop over dimensions for (int dim = 0; dim < 3; dim++) { // fill buffer with atoms leaving my box, using < and >= // when atom is deleted, fill it in with last atom lo = sublo[dim]; hi = subhi[dim]; i = nsend = 0; while (i < nbody_) { MathExtraLiggghts::local_coosys_to_cartesian(x,xcm_to_xbound_(i),ex_space_(i),ey_space_(i),ez_space_(i)); vectorAdd3D(xcm_(i),x,x); if (x[dim] < lo || x[dim] >= hi) { if (nsend > maxsend_) grow_send(nsend,1); nsend += pack_exchange_rigid(i,&buf_send_[nsend]); remove_body(i); } else i++; } // send/recv atoms in both directions // if 1 proc in dimension, no send/recv, set recv buf to send buf // if 2 procs in dimension, single send/recv // if more than 2 procs in dimension, send/recv to both neighbors int procneigh[3][2]; for(int i = 0; i < 3; i++) for(int j = 0; j < 2; j++) procneigh[i][j] = comm->procneigh[i][j]; int *procgrid = comm->procgrid; if (procgrid[dim] == 1) { nrecv = nsend; buf = buf_send_; } else { MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0,&nrecv1,1,MPI_INT,procneigh[dim][1],0,world,&status); nrecv = nrecv1; if (procgrid[dim] > 2) { MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0,&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,&status); nrecv += nrecv2; } if (nrecv > maxrecv_) grow_recv(nrecv); MPI_Irecv(buf_recv_,nrecv1,MPI_DOUBLE,procneigh[dim][1],0,world,&request); MPI_Send(buf_send_,nsend,MPI_DOUBLE,procneigh[dim][0],0,world); MPI_Wait(&request,&status); if (procgrid[dim] > 2) { MPI_Irecv(&buf_recv_[nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,world,&request); MPI_Send(buf_send_,nsend,MPI_DOUBLE,procneigh[dim][1],0,world); MPI_Wait(&request,&status); } buf = buf_recv_; } // check incoming atoms to see if they are in my box // if so, add to my list m = 0; while (m < nrecv) { value = buf[m+dim+1]; if (value >= lo && value < hi) m += unpack_exchange_rigid(&buf[m]); else m += static_cast<int> (buf[m]); } } }