1 |
francois |
979 |
#include "poly_voro.h" |
2 |
|
|
#include "poly_point.h" |
3 |
|
|
#include "poly_noeud.h" |
4 |
|
|
#include "poly_face.h" |
5 |
|
|
#include "poly_cellule.h" |
6 |
|
|
|
7 |
|
|
#include <iostream> |
8 |
|
|
#include <algorithm> |
9 |
|
|
|
10 |
|
|
#include "../voro++-0.4.6/src/voro++.hh" |
11 |
|
|
|
12 |
|
|
Poly_Voro::Poly_Voro(std::vector<Poly_Point*> list_pnts): list_points(list_pnts) |
13 |
|
|
{ |
14 |
|
|
// Géométrie du conteneur |
15 |
|
|
double x_min= list_points[0]->get_x(), x_max= list_points[6]->get_x(); |
16 |
|
|
double y_min= list_points[0]->get_y(), y_max= list_points[6]->get_y(); |
17 |
|
|
double z_min= list_points[0]->get_z(), z_max= list_points[6]->get_z(); |
18 |
|
|
double cvol = (x_max - x_min) * (y_max - y_min) * (x_max - x_min); |
19 |
|
|
|
20 |
|
|
// Nombre de blocs qui divise le container (blocs calculatoires) |
21 |
|
|
int n_x= 6, n_y= 6, n_z= 6; |
22 |
|
|
|
23 |
|
|
// Cré un container avec la géométrie données |
24 |
|
|
voro::container con(x_min, x_max, y_min, y_max, z_min, z_max, n_x, n_y, n_z, false, false, false, 8); |
25 |
|
|
|
26 |
|
|
// Ajoute les particules au container, on n'insère pas les 8 coins du cube |
27 |
|
|
double x,y,z; |
28 |
|
|
for(int i=8; i < list_points.size(); i++) { |
29 |
|
|
x = list_points[i]->get_x(); |
30 |
|
|
y = list_points[i]->get_y(); |
31 |
|
|
z = list_points[i]->get_z(); |
32 |
|
|
con.put(i, x, y, z); |
33 |
|
|
} |
34 |
|
|
|
35 |
|
|
// Additionne les volumes et vérifi que ça concorde avec le volume du container |
36 |
|
|
double vvol = con.sum_cell_volumes(); |
37 |
|
|
std::cout << "Container volume: " << cvol << std::endl; |
38 |
|
|
std::cout << "Voronoi volume: " << vvol << std::endl; |
39 |
|
|
std::cout << "Difference: " << vvol-cvol << std::endl; |
40 |
|
|
|
41 |
|
|
voro::voronoicell voro_cell; |
42 |
|
|
voro::c_loop_all loop(con); |
43 |
|
|
|
44 |
|
|
// loop a travers les cellules |
45 |
|
|
if(loop.start()) do if(con.compute_cell(voro_cell,loop)) |
46 |
|
|
{ |
47 |
|
|
Poly_Cellule* cell = new Poly_Cellule; |
48 |
|
|
add_cell(cell); |
49 |
|
|
loop.pos(x,y,z); // position globale de la particule en cours |
50 |
|
|
|
51 |
|
|
// récupération des noeuds |
52 |
|
|
std::vector< double > vert_xyz; |
53 |
|
|
voro_cell.vertices(x, y, z, vert_xyz); // récupère tous les vertex de la cellule dans le système global |
54 |
|
|
|
55 |
|
|
for(int i=0; i < vert_xyz.size(); i+=3) |
56 |
|
|
{ |
57 |
|
|
Poly_Noeud* nd = new Poly_Noeud(i, vert_xyz[i], vert_xyz[i+1], vert_xyz[i+2]); |
58 |
|
|
cell->add_noeud(nd); |
59 |
|
|
} |
60 |
|
|
|
61 |
|
|
// récupération des faces |
62 |
|
|
std::vector< int > face_vert; |
63 |
|
|
voro_cell.face_vertices(face_vert); // liste de vertex pour chaque face |
64 |
|
|
|
65 |
|
|
for(int i=0; i < face_vert.size(); i++) |
66 |
|
|
{ |
67 |
|
|
Poly_Face* face = new Poly_Face; |
68 |
|
|
int nbVert = face_vert[i]; // première valeur = le nombre de vertex de la face |
69 |
|
|
for(int j=i+1; j < i+nbVert+1; j++) |
70 |
|
|
{ |
71 |
|
|
face->add_noeud(face_vert[j]); |
72 |
|
|
} |
73 |
|
|
cell->add_face(face); |
74 |
|
|
i += nbVert; |
75 |
|
|
} |
76 |
|
|
} while (loop.inc()); |
77 |
|
|
} |
78 |
|
|
|
79 |
|
|
// destructor |
80 |
|
|
Poly_Voro::~Poly_Voro() |
81 |
|
|
{ |
82 |
|
|
for (int i=0; i<get_nb_cell(); i++) |
83 |
|
|
{ |
84 |
|
|
Poly_Cellule* c = list_cellules[i]; |
85 |
|
|
delete c; |
86 |
|
|
} |
87 |
|
|
} |
88 |
|
|
|
89 |
|
|
void Poly_Voro::fusion_noeuds(void) |
90 |
|
|
{ |
91 |
|
|
double eps = 10e-17; |
92 |
|
|
|
93 |
|
|
// cré une liste contenant {(x, y, z), (num_cellule, num_noeud)} |
94 |
|
|
std::vector< std::pair< std::vector<double>, std::vector<int> > > list_noeud; |
95 |
|
|
|
96 |
|
|
for(int i=0; i < get_nb_cell(); i++) |
97 |
|
|
{ |
98 |
|
|
Poly_Cellule* c = get_cell(i); |
99 |
|
|
for(int j=0; j < c->get_nb_noeud(); j++) |
100 |
|
|
{ |
101 |
|
|
double x = c->get_noeud(j)->get_x(); |
102 |
|
|
double y = c->get_noeud(j)->get_y(); |
103 |
|
|
double z = c->get_noeud(j)->get_z(); |
104 |
|
|
std::vector<double> coord = {x, y, z}; |
105 |
|
|
std::vector<int> id = {i, j}; |
106 |
|
|
list_noeud.push_back(std::make_pair(coord,id)); |
107 |
|
|
} |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
// sort les noeud dans l'ordre croissant de leur coordonnée |
111 |
|
|
std::sort(list_noeud.begin(), list_noeud.end()); |
112 |
|
|
|
113 |
|
|
// comparaison de la distance entre un noeud et le suivant |
114 |
|
|
for(int i=0; i < list_noeud.size()-1; i++) |
115 |
|
|
{ |
116 |
|
|
Poly_Noeud* curr = get_cell(list_noeud[i].second[0])->get_noeud(list_noeud[i].second[1]); |
117 |
|
|
Poly_Noeud* next = get_cell(list_noeud[i+1].second[0])->get_noeud(list_noeud[i+1].second[1]); |
118 |
|
|
|
119 |
|
|
double dist_x = fabs(curr->get_x() - next->get_x()); |
120 |
|
|
double dist_y = fabs(curr->get_y() - next->get_y()); |
121 |
|
|
double dist_z = fabs(curr->get_z() - next->get_z()); |
122 |
|
|
|
123 |
|
|
if(dist_x < eps && dist_y < eps && dist_z < eps) |
124 |
|
|
{ |
125 |
|
|
// le noeud est le même, donc on égale la coordonnée |
126 |
|
|
next->set_x(curr->get_x()); |
127 |
|
|
next->set_y(curr->get_y()); |
128 |
|
|
next->set_z(curr->get_z()); |
129 |
|
|
} |
130 |
|
|
} |
131 |
|
|
} |
132 |
|
|
|
133 |
|
|
|
134 |
|
|
// |
135 |
|
|
// Accessor et modifier |
136 |
|
|
// |
137 |
|
|
|
138 |
|
|
void Poly_Voro::add_cell(Poly_Cellule* element) |
139 |
|
|
{ |
140 |
|
|
list_cellules.push_back(element); |
141 |
|
|
} |
142 |
|
|
|
143 |
|
|
Poly_Point* Poly_Voro::get_point(int num) |
144 |
|
|
{ |
145 |
|
|
return list_points[num]; |
146 |
|
|
} |
147 |
|
|
|
148 |
|
|
Poly_Cellule* Poly_Voro::get_cell(int num) |
149 |
|
|
{ |
150 |
|
|
return list_cellules[num]; |
151 |
|
|
} |
152 |
|
|
|
153 |
|
|
int Poly_Voro::get_nb_cell(void) |
154 |
|
|
{ |
155 |
|
|
return list_cellules.size(); |
156 |
|
|
} |