1 #ifndef CELLCONTACTDETECTION
2 #define CELLCONTACTDETECTION
6 #include <boost/random.hpp>
32 template <
class Archive>
47 int init_cells (std::vector<
Boundary<d>> &boundaries, std::vector<double> & r) {
double ds = 2.1*(*std::max_element(r.begin(), r.end())) ;
return (
init_cells(boundaries, ds)) ; }
55 ContactList<d> & CLnew, std::vector<std::vector<double>>
const & X, std::vector<double>
const &r,
double LE_displacement) ;
57 ContactList<d> & CLnew, std::vector<std::vector<double>>
const & X, std::vector<double>
const &r,
double LE_displacement) ;
60 std::vector<double>
const &r,
cp<d> & tmpcp ) ;
62 ContactList<d> & CLnew, std::vector<std::vector<double>>
const & X, std::vector<double>
const &r,
double LE_displacement,
cp<d> & tmpcp ) ;
67 int x2id (
const std::vector<int>&v)
70 for (
int dd=0; dd<
d ; dd++)
72 if (v[dd] < 0 || v[dd]>=
n_cell[dd]) { fflush(stdout) ;
return -1 ; }
78 std::vector<int>
id2x (
int id)
80 std::vector<int> ids (
d,0) ;
81 for (
int dd=0 ; dd<
d ; dd++)
83 ids[dd] =
id %
n_cell[dd] ;
95 printf(
"ERROR %d\n", i) ;
102 double dsqr (std::vector<double> &X1, std::vector<double> &X2)
105 for (
int k=0 ; k<
d ; k++)
106 sum += (X1[k]-X2[k])*(X1[k]-X2[k]) ;
114 if (considered < offset)
117 if ((ghost>>1)&1 && (ghostdir&1))
129 if ((ghost>>1)&1 && !(ghostdir&1))
145 template <
class Archive>
167 std::vector<std::vector<double>> res (
d, std::vector<double>(2,0)) ;
169 for (
size_t i=0 ; i<boundaries.size() ; i++)
171 switch (boundaries[i].
Type)
175 res[i][0] = boundaries[i].xmin ;
176 res[i][1] = boundaries[i].xmax ;
178 Delta[i] = boundaries[i].delta ;
182 printf(
"ERR: this type of boundary is incompatible with cell contacts\n") ;
185 res[i][0] = boundaries[i].xmin ;
186 res[i][1] = boundaries[i].xmax ;
190 for (
int dd=0 ; dd<
d ; dd++)
192 res[dd][0] = boundaries[i].center[dd]-boundaries[i].radius ;
193 res[dd][1] = boundaries[i].center[dd]+boundaries[i].radius ;
197 for (
int dd=0 ; dd<
d ; dd++)
199 res[dd][0] = boundaries[i].center[dd]-boundaries[i].radius ;
200 if (dd != boundaries[i].axis)
201 res[dd][1] = boundaries[i].center[dd]+boundaries[i].radius ;
205 for (
int dd=0 ; dd<
d ; dd++)
207 if (dd==boundaries[i].axis) continue ;
208 res[dd][0] = boundaries[i].radius ;
209 res[dd][1] = boundaries[i].radius ;
213 printf(
"ERR: unknown boundary condition for cell building.\n") ;
225 for (
int i=0 ; i<
d ; i++)
227 n_cell[i] = n_cell_super[i]*2 ;
228 delta[i] = delta_super[i]/2. ;
231 init_finalise(bounds) ;
238 printf(
"CELL SIZE: %g\n", ds) ;
242 auto boundaries = boundary_handler(bounds) ;
243 for (
int i=0 ; i<
d ; i++)
245 n_cell[i] = floor((boundaries[i][1]-boundaries[i][0])/ds) ;
246 delta[i] = (boundaries[i][1]-boundaries[i][0])/n_cell[i] ;
249 init_finalise(bounds) ;
257 cum_n_cell.resize(
d+1,0) ;
265 auto boundaries = boundary_handler(bounds) ;
267 for (
int i=0 ; i<
d ; i++)
270 cum_n_cell[i] = cum_n_cell[i-1]*n_cell[i-1] ;
271 origin[i] = boundaries[i][0] ;
273 cum_n_cell[
d] = cum_n_cell[
d-1]*n_cell[
d-1] ;
274 planesize = cum_n_cell[2] ;
276 cells.resize(cum_n_cell[
d]) ;
277 for (
auto &v: n_cell) printf(
"%d ", v) ;
279 for (
auto &v: cum_n_cell) printf(
"%d ", v) ;
281 for (
int i=0 ; i<
d ; i++)
282 printf(
"%g ", delta[i]) ;
285 for (
size_t i=0 ; i<cells.size() ; i++)
287 auto x_base = id2x(i) ;
297 cells[i].neighbours.reserve(pow(3,
d)) ;
303 for ( ; t<pow(3,
d) ; t++)
306 int pbc_le_crossing = 0;
309 bitdim ghost = 0, ghostdir = 0 ;
310 for (
int dd=0 ; dd<
d ; dd++)
314 if (pbc_le_crossing != 0 )
315 x[dd] += t[dd] * pbc_le_crossing ;
326 pbc_le_crossing = 1 ;
329 x[dd] += n_cell[dd] ;
335 x[dd] += n_cell[dd] ;
343 else if (x[dd]>=n_cell[dd])
347 pbc_le_crossing = -1 ;
349 x[dd] -= n_cell[dd] ;
354 x[dd] -= n_cell[dd] ;
367 unsigned int id = x2id(x) ;
372 cells[i].neigh_ghosts.push_back(
id) ;
373 cells[i].neigh_ghosts_dim.push_back(ghost) ;
374 cells[i].neigh_ghosts_dir.push_back(ghostdir) ;
381 cells[i].neigh_ghosts.push_back(
id) ;
382 cells[i].neigh_ghosts_dim.push_back(ghost) ;
383 cells[i].neigh_ghosts_dir.push_back(ghostdir) ;
387 cells[i].neigh_ghosts_full.push_back(
id) ;
388 cells[i].neigh_ghosts_full_dim.push_back(ghost) ;
389 cells[i].neigh_ghosts_full_dir.push_back(ghostdir) ;
394 cells[i].neighbours.push_back(x2id(x)) ;
398 sort( cells[i].neighbours.begin(), cells[i].neighbours.end() );
399 int bef = cells[i].neighbours.size() ;
400 cells[i].neighbours.erase(
unique( cells[i].neighbours.begin(), cells[i].neighbours.end() ), cells[i].neighbours.end() );
401 int aft = cells[i].neighbours.size() ;
402 if (bef-aft != 0) printf(
"ERR: no duplication of cells should happen with the algorithm.\n") ;
404 cells[i].neighbours_full = cells[i].neighbours ;
405 cells[i].neighbours.erase(std::remove_if(cells[i].neighbours.begin(), cells[i].neighbours.end(),
406 [=](
size_t x) { return x<=i ; }), cells[i].neighbours.end());
407 cells[i].neighbours_full.erase(std::remove_if(cells[i].neighbours_full.begin(), cells[i].neighbours_full.end(),
408 [=](
size_t x) { return x>=i ; }), cells[i].neighbours_full.end());
434 std::vector<int> v (
d,0) ;
438 for (
size_t i=0 ; i<X.size() ; i++)
440 for (
int dd=0 ; dd<
d ; dd++)
441 v[dd] = floor((X[i][dd]-origin[dd])/delta[dd]) ;
444 cells[id].incell.push_back(i) ;
458 for (
size_t i=0 ; i<cells.size() ; i++)
459 cells[i].incell.clear() ;
466 std::vector<int> v (
d,0) ;
468 for (
int dd=0 ; dd<
d ; dd++)
469 v[dd] = floor((X[dd]-origin[dd])/delta[dd]) ;
472 cells[id].incell.push_back(grainid) ;
484 std::vector<std::vector<double>>
const & X, std::vector<double>
const &r,
double LE_displacement)
486 auto [cell_first, cell_last] = bounds ;
491 for (
int c=cell_first ; c<cell_last ; c++)
493 if (cells[c].incell.size()==0) continue ;
495 for (
size_t ii=0 ; ii<cells[c].incell.size() ; ii++)
496 for (
size_t jj=ii+1 ; jj<cells[c].incell.size() ; jj++)
499 int i = cells[c].incell[ii] ;
500 int j = cells[c].incell[jj] ;
501 for (
int k=0 ; sum<(r[i]+r[j])*(r[i]+r[j]) && k<
d ; k++)
502 sum+= (X[i][k]-X[j][k])*(X[i][k]-X[j][k]) ;
503 if (sum<(r[i]+r[j])*(r[i]+r[j]))
506 if (i<j) {tmpcp.
i = i ; tmpcp.
j=j ;}
507 else { tmpcp.
i = j ; tmpcp.
j=i ;}
509 if (!cell_contact_insert(ID, CLp_it, tmpcp))
511 CLnew.
v.push_back(tmpcp) ;
517 for (
size_t cc=0 ; cc<cells[c].neighbours.size() ; cc++)
519 int c2 = cells[c].neighbours[cc] ;
520 for (
size_t ii=0 ; ii<cells[c].incell.size() ; ii++)
521 for (
size_t jj=0 ; jj<cells[c2].incell.size() ; jj++)
524 int i = cells[c].incell[ii] ;
525 int j = cells[c2].incell[jj] ;
526 for (
int k=0 ; sum<(r[i]+r[j])*(r[i]+r[j]) && k<
d ; k++)
527 sum+= (X[i][k]-X[j][k])*(X[i][k]-X[j][k]) ;
528 if (sum<(r[i]+r[j])*(r[i]+r[j]))
531 if (i<j) {tmpcp.
i = i ; tmpcp.
j=j ;}
532 else { tmpcp.
i = j ; tmpcp.
j=i ;}
534 if (!cell_contact_insert(ID, CLp_it, tmpcp)) CLnew.
v.push_back(tmpcp) ;
541 for (
size_t cc=0 ; cc<cells[c].neigh_ghosts.size() ; cc++)
543 int c2 = cells[c].neigh_ghosts[cc] ;
544 bitdim ghost=cells[c].neigh_ghosts_dim[cc], ghostdir=cells[c].neigh_ghosts_dir[cc] ;
546 if (LE_displacement && cells[c].neigh_ghosts_dim[cc]&1)
548 int newc2 = c2-floor(LE_displacement*(cells[c].neigh_ghosts_dir[cc]&1?-1:1)/delta[1]) * cum_n_cell[1] ;
549 c2 = clip_LEmoved_cell(c2, newc2, ghost, ghostdir) ;
555 for (
size_t ii=0 ; ii<cells[c].incell.size() ; ii++)
556 for (
size_t jj=0 ; jj<cells[c2].incell.size() ; jj++)
559 int i = cells[c].incell[ii] ;
560 int j = cells[c2].incell[jj] ;
561 for (
int k=0 ; sum<(r[i]+r[j])*(r[i]+r[j]) && k<
d ; k++)
563 double additionaldelta=0 ;
565 additionaldelta = LE_displacement * (ghostdir&1?-1:1) ;
566 sum+= pow(( X[i][k]-X[j][k] - Delta[k]*(ghost>>k & 1)*((ghostdir>>k & 1)?-1:1) - additionaldelta),2) ;
574 if (sum<(r[i]+r[j])*(r[i]+r[j]))
578 if (i<j) {tmpcp.
i = i ; tmpcp.
j=j ; tmpcp.
ghostdir = ghostdir ;}
579 else { tmpcp.
i = j ; tmpcp.
j=i ; tmpcp.
ghostdir = (~ghostdir)&ghost ;}
581 if (!cell_contact_insert(ID, CLp_it, tmpcp)) CLnew.
v.push_back(tmpcp) ;
603 it->contactlength=
a.contactlength ;
605 it->ghostdir=
a.ghostdir ;
606 it->persisting = true ;
617 std::vector<std::vector<double>>
const & X, std::vector<double>
const &r,
cp<d> & tmpcp)
620 for (
size_t ii=0 ; ii<c1.
incell.size() ; ii++)
621 for (
size_t jj=0 ; jj<c2.
incell.size() ; jj++)
626 for (
int k=0 ; sum<(r[i]+r[j])*(r[i]+r[j]) && k<
d ; k++)
627 sum+= (X[i][k]-X[j][k])*(X[i][k]-X[j][k]) ;
628 if (sum<(r[i]+r[j])*(r[i]+r[j]))
630 if (i<j) {tmpcp.
i = i ; tmpcp.
j=j ;}
631 else { tmpcp.
i = j ; tmpcp.
j=i ;}
633 if (!cell_contact_insert(ID, CLp_it, tmpcp)) CLnew.
v.push_back(tmpcp) ;
641 ContactList<d> & CLnew, std::vector<std::vector<double>>
const & X, std::vector<double>
const &r,
double LE_displacement,
cp<d> & tmpcp)
644 for (
size_t ii=0 ; ii<c1.
incell.size() ; ii++)
645 for (
size_t jj=0 ; jj<c2.
incell.size() ; jj++)
650 for (
int k=0 ; sum<(r[i]+r[j])*(r[i]+r[j]) && k<
d ; k++)
652 double additionaldelta=0 ;
653 if (k==1 && ghost&1) additionaldelta = LE_displacement * (ghostdir&1?-1:1) ;
654 sum+= pow(( X[i][k]-X[j][k] - Delta[k]*(ghost>>k & 1)*((ghostdir>>k & 1)?-1:1) - additionaldelta),2) ;
657 if (sum<(r[i]+r[j])*(r[i]+r[j]))
659 if (i<j) {tmpcp.
i = i ; tmpcp.
j=j ; tmpcp.
ghostdir = ghostdir ;}
660 else { tmpcp.
i = j ; tmpcp.
j=i ; tmpcp.
ghostdir = (~ghostdir)&ghost ;}
662 if (!cell_contact_insert(ID, CLp_it, tmpcp)) CLnew.
v.push_back(tmpcp) ;
670 ContactList<d> & CLnew, std::vector<std::vector<double>>
const & X, std::vector<double>
const &r,
double LE_displacement)
672 auto [cell_first, cell_last] = bounds ;
675 for (
int c=cell_first ; c<cell_last ; c++)
677 if (cells[c].incell.size()==0) continue ;
679 auto xloc = id2x(c) ;
680 for (
auto &v:xloc) v /= pow(2, delta_lvl) ;
681 int oid = ocell.
x2id(xloc) ;
684 contacts_cell_cell(ID, cells[c], ocell.
cells[oid], CLp_it, CLnew, X, r, tmpcp) ;
686 for (
size_t cc=0 ; cc<ocell.
cells[oid].neighbours.size() ; cc++)
687 contacts_cell_cell(ID, cells[c], ocell.
cells[ocell.
cells[oid].neighbours[cc]], CLp_it, CLnew, X, r, tmpcp) ;
688 for (
size_t cc=0 ; cc<ocell.
cells[oid].neighbours_full.size() ; cc++)
689 contacts_cell_cell(ID, cells[c], ocell.
cells[ocell.
cells[oid].neighbours_full[cc]], CLp_it, CLnew, X, r, tmpcp) ;
692 for (
size_t cc=0 ; cc<ocell.
cells[oid].neigh_ghosts.size() ; cc++)
694 int c2 = ocell.
cells[oid].neigh_ghosts[cc] ;
695 bitdim ghost=ocell.
cells[oid].neigh_ghosts_dim[cc], ghostdir=ocell.
cells[oid].neigh_ghosts_dir[cc] ;
703 contacts_cell_ghostcell(ID, cells[c], ocell.
cells[c2], ghost, ghostdir, CLp_it, CLnew, X, r, LE_displacement, tmpcp) ;
706 for (
size_t cc=0 ; cc<ocell.
cells[oid].neigh_ghosts_full.size() ; cc++)
708 int c2 = ocell.
cells[oid].neigh_ghosts_full[cc] ;
709 bitdim ghost=ocell.
cells[oid].neigh_ghosts_full_dim[cc], ghostdir=ocell.
cells[oid].neigh_ghosts_full_dir[cc] ;
717 contacts_cell_ghostcell(ID, cells[c], ocell.
cells[c2], ghost, ghostdir, CLp_it, CLnew, X, r, LE_displacement, tmpcp) ;
#define CEREAL_NVP(T)
Creates a name value pair for the variable T with the same name as the variable.
Definition: cereal.hpp:72
Definition: Boundaries.h:8
Individual cell for contact detection.
Definition: Cells.h:19
std::vector< int > neigh_ghosts
list of the ghost cells through the PBC
Definition: Cells.h:23
void serialize(Archive &ar)
Definition: Cells.h:33
std::vector< bitdim > neigh_ghosts_dir
Ghost cell directions going through PBC (1 is negative delta)
Definition: Cells.h:25
std::vector< int > incell
list of particles in the cell
Definition: Cells.h:21
std::vector< int > neighbours
list of cell neighbours to the current cell
Definition: Cells.h:22
std::vector< int > neighbours_full
list of cell neighbours to the current cell
Definition: Cells.h:27
std::vector< int > neigh_ghosts_full
list of the ghost cells through the PBC
Definition: Cells.h:28
std::vector< bitdim > neigh_ghosts_full_dim
Ghost cell dimensions going through PBC.
Definition: Cells.h:29
std::vector< bitdim > neigh_ghosts_full_dir
Ghost cell directions going through PBC (1 is negative delta)
Definition: Cells.h:30
std::vector< bitdim > neigh_ghosts_dim
Ghost cell dimensions going through PBC.
Definition: Cells.h:24
All the cells making the space, with related function for creating the cell array,...
Definition: Cells.h:44
std::vector< double > origin
Definition: Cells.h:139
int contacts_external(int ID, Cells< d > &ocell, int delta_lvl, std::pair< int, int > bounds, CLp_it_t< d > &CLp_it, ContactList< d > &CLnew, std::vector< std::vector< double >> const &X, std::vector< double > const &r, double LE_displacement)
Definition: Cells.h:669
int init_allocate()
Definition: Cells.h:254
int clear_all()
Definition: Cells.h:455
int init_finalise(std::vector< Boundary< d >> &bounds)
Definition: Cells.h:263
int contacts(int ID, std::pair< int, int > bounds, CLp_it_t< d > &CLp_it, ContactList< d > &CLnew, std::vector< std::vector< double >> const &X, std::vector< double > const &r, double LE_displacement)
Definition: Cells.h:482
int contacts_cell_ghostcell(int ID, Cell &c1, Cell &c2, bitdim ghost, bitdim ghostdir, CLp_it_t< d > &CLp_it, ContactList< d > &CLnew, std::vector< std::vector< double >> const &X, std::vector< double > const &r, double LE_displacement, cp< d > &tmpcp)
Definition: Cells.h:640
int allocate_single(std::vector< double > &X, int grainid)
Definition: Cells.h:464
int init_subcells(std::vector< Boundary< d >> &bounds, double delta_super[], const std::vector< int > &n_cell_super)
Definition: Cells.h:222
int allocate_to_cells(std::vector< std::vector< double >> &X)
Definition: Cells.h:432
int planesize
Definition: Cells.h:143
int init_cells(std::vector< Boundary< d >> &boundaries, std::vector< double > &r)
Definition: Cells.h:47
double delta[d]
Definition: Cells.h:142
int contacts_cell_cell(int ID, Cell &c1, Cell &c2, CLp_it_t< d > &CLp_it, ContactList< d > &CLnew, std::vector< std::vector< double >> const &X, std::vector< double > const &r, cp< d > &tmpcp)
Definition: Cells.h:615
int clip_LEmoved_cell(int original, int considered, bitdim &ghost, bitdim &ghostdir)
Definition: Cells.h:110
std::vector< int > id2x(int id)
Definition: Cells.h:78
void serialize(Archive &ar)
Definition: Cells.h:146
double dsqr(std::vector< double > &X1, std::vector< double > &X2)
Definition: Cells.h:102
std::vector< Cell > cells
Definition: Cells.h:141
std::vector< int > n_cell
Definition: Cells.h:138
std::vector< double > Delta
Definition: Cells.h:140
int x2id(const std::vector< int > &v)
Definition: Cells.h:67
std::vector< int > cum_n_cell
Definition: Cells.h:138
std::vector< std::vector< double > > boundary_handler(std::vector< Boundary< d >> &boundaries)
Definition: Cells.h:165
int init_cells(std::vector< Boundary< d >> &boundaries, double ds)
Definition: Cells.h:236
bool cell_contact_insert(int ID, CLp_it_t< d > &CLp_it, const cp< d > &a)
Definition: Cells.h:595
bool test_idempotent()
Definition: Cells.h:89
Contact properties class.
Definition: ContactList.h:69
double contactlength
Length of the contact.
Definition: ContactList.h:115
int j
Index of second contacting particle or wall. If this is a wall contact, j=2*walldimension + (0 or 1 i...
Definition: ContactList.h:114
bool persisting
True if the contact is still maintained for the current ts.
Definition: ContactList.h:121
int i
Index of contacting particle.
Definition: ContactList.h:113
uint32_t ghost
Contain ghost information about ghost contact, cf detailed description.
Definition: ContactList.h:116
uint32_t ghostdir
Contain ghost information about ghost direction, cf detailed description.
Definition: ContactList.h:117
void set_quat_bit(int n)
Definition: ternary.h:91
unsigned int bitdim
Definition: Typedefs.h:17
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1181
PUGI_IMPL_FN void sort(I begin, I end, const Pred &pred)
Definition: pugixml.cpp:7707
PUGI_IMPL_FN I unique(I begin, I end)
Definition: pugixml.cpp:7621
Type
Type of JSON value.
Definition: rapidjson.h:644
Simple packing structure for the iterators to the contact list regions per particle.
Definition: Multiproc.h:23
std::vector< typename list< cp< d > >::iterator > it_array_beg
Contains iterator related to each particle contacts.
Definition: Multiproc.h:49
ContactList< d > null_list
Empty list, effectively providing a null iterator.
Definition: Multiproc.h:51
std::vector< typename list< cp< d > >::iterator > it_ends
Definition: Multiproc.h:50