root / bin / cell_division.cpp @ 1
Historique | Voir | Annoter | Télécharger (10,25 ko)
1 | 1 | akiss | #include <math.h> |
---|---|---|---|
2 | 1 | akiss | #include "cell_division.h" |
3 | 1 | akiss | #include "constants.h" |
4 | 1 | akiss | #include <stdio.h> |
5 | 1 | akiss | #include <stdlib.h> |
6 | 1 | akiss | #include <omp.h> |
7 | 1 | akiss | |
8 | 1 | akiss | /* this function: finds the division direction
|
9 | 1 | akiss | computes the position of the new vertices
|
10 | 1 | akiss | saves the indices and the vertices of the two daughter cells and of the two walls which are cut by the new one (these data are usefull for cell_division2.cpp) */
|
11 | 1 | akiss | |
12 | 1 | akiss | void cell_division(double *vertices, int vertices_number, int *cells_vertices, int *vertices_number_in_each_cell, int cell_number, |
13 | 1 | akiss | double *barycenters, int dividing_cell, int *boundary, double *stress, double *shapes, |
14 | 1 | akiss | int *adjacent_cells_number, int *adjacent_cell1, int *adjacent_cell2, int *daughter_cells_vertices_number, int *cell1, int *cell2, int *wall1, int *wall2){ |
15 | 1 | akiss | |
16 | 1 | akiss | ///bias division
|
17 | 1 | akiss | //double width=3; double dilation=1.;
|
18 | 1 | akiss | |
19 | 1 | akiss | |
20 | 1 | akiss | int j;
|
21 | 1 | akiss | |
22 | 1 | akiss | /* vector of the division line */
|
23 | 1 | akiss | double division_direction[2]; |
24 | 1 | akiss | /* positions of new vertices */
|
25 | 1 | akiss | double new_vertex1[2]={0}; double new_vertex2[2]={0}; |
26 | 1 | akiss | |
27 | 1 | akiss | double eigenvalue=0; double norm; |
28 | 1 | akiss | if (threshold_division>0.0){ /* probabilistic division: the probability to divide a cell following the vector n is proportionnal to |
29 | 1 | akiss | exp(n^t D n / D0) where D is the deviatoric stress (S-tr(S)/2) and D0 the threshold over which we start felling the stress */
|
30 | 1 | akiss | double anisotropic_stress[2]; |
31 | 1 | akiss | anisotropic_stress[0]=(0.5*stress[3*dividing_cell]-0.5*stress[3*dividing_cell+1])/threshold_division; |
32 | 1 | akiss | anisotropic_stress[1]=0.5*stress[3*dividing_cell+2]/threshold_division; |
33 | 1 | akiss | double probability[20]; |
34 | 1 | akiss | for (int i=0;i<20;i++){ |
35 | 1 | akiss | probability[i]=exp(cos(i*pi/19.0)*anisotropic_stress[0]+sin(i*pi/19.0)*anisotropic_stress[1]); |
36 | 1 | akiss | if (probability[i]==HUGE_VAL){ printf("division_h\n"); goto division_highest_tension;} |
37 | 1 | akiss | } |
38 | 1 | akiss | probability[0]/=2.; probability[19]/=2.; |
39 | 1 | akiss | for (int i=1;i<20;i++){probability[i]+=probability[i-1];} |
40 | 1 | akiss | for (int i=0;i<20;i++){probability[i]/=probability[19];} |
41 | 1 | akiss | double random=(double)rand()/(double)RAND_MAX; //printf("random %f\n",random); |
42 | 1 | akiss | int random2=rand()%2; |
43 | 1 | akiss | if (random<=probability[0]){ //printf("%i\n",0); |
44 | 1 | akiss | division_direction[0]=1; |
45 | 1 | akiss | division_direction[1]=0;} |
46 | 1 | akiss | for (int i=1;i<20;i++){//printf("%f %f\n",probability[i-1],probability[i]); |
47 | 1 | akiss | if (random<=probability[i] && random>probability[i-1]){ |
48 | 1 | akiss | if(random2==0){//printf("%i %i\n",i,0); |
49 | 1 | akiss | division_direction[0]=cos(i*0.5*pi/19.0); |
50 | 1 | akiss | division_direction[1]=sin(i*0.5*pi/19.0);} |
51 | 1 | akiss | if(random2==1){//printf("%i %i\n",i,1); |
52 | 1 | akiss | division_direction[0]=cos(i*0.5*pi/19.0); |
53 | 1 | akiss | division_direction[1]=-sin(i*0.5*pi/19.0);} |
54 | 1 | akiss | } |
55 | 1 | akiss | } |
56 | 1 | akiss | } |
57 | 1 | akiss | |
58 | 1 | akiss | if (threshold_division==0.0){ /* division following the maximal stress = particular case of the previous rule */ |
59 | 1 | akiss | division_highest_tension:; //printf("%f %d %d\n",stress[3*dividing_cell+2],dividing_cell,cell_number); |
60 | 1 | akiss | if (stress[3*dividing_cell+2]!=0){ |
61 | 1 | akiss | eigenvalue=(stress[3*dividing_cell]+stress[3*dividing_cell+1])/2.; |
62 | 1 | akiss | eigenvalue+=0.5*sqrt((stress[3*dividing_cell]-stress[3*dividing_cell+1])*(stress[3*dividing_cell]-stress[3*dividing_cell+1])+ |
63 | 1 | akiss | 4.*stress[3*dividing_cell+2]*stress[3*dividing_cell+2]); |
64 | 1 | akiss | division_direction[0]=stress[3*dividing_cell+2]; |
65 | 1 | akiss | division_direction[1]=-stress[3*dividing_cell]+eigenvalue; |
66 | 1 | akiss | norm=sqrt(division_direction[0]*division_direction[0]+division_direction[1]*division_direction[1]); |
67 | 1 | akiss | division_direction[0]/=norm;
|
68 | 1 | akiss | division_direction[1]/=norm;}
|
69 | 1 | akiss | else if (stress[3*dividing_cell]>stress[3*dividing_cell+1]){ |
70 | 1 | akiss | division_direction[0]=1; |
71 | 1 | akiss | division_direction[1]=0;} |
72 | 1 | akiss | else if (stress[3*dividing_cell]<stress[3*dividing_cell+1]){ |
73 | 1 | akiss | division_direction[0]=0; |
74 | 1 | akiss | division_direction[1]=1;} |
75 | 1 | akiss | else if (stress[3*dividing_cell]==stress[3*dividing_cell+1]){ |
76 | 1 | akiss | division_direction[0]=rand()/(double)RAND_MAX; |
77 | 1 | akiss | division_direction[1]=sqrt(1.-division_direction[0]*division_direction[0]);} |
78 | 1 | akiss | } |
79 | 1 | akiss | |
80 | 1 | akiss | double temp_shape[3]; |
81 | 1 | akiss | temp_shape[0]=shapes[3*dividing_cell]; |
82 | 1 | akiss | temp_shape[1]=shapes[3*dividing_cell+1]; |
83 | 1 | akiss | temp_shape[2]=shapes[3*dividing_cell+2]; |
84 | 1 | akiss | //if ((barycenters[2*dividing_cell]*barycenters[2*dividing_cell])<(width*width)){ temp_shape[0]*=dilation*dilation; temp_shape[2]*=dilation;}
|
85 | 1 | akiss | |
86 | 1 | akiss | if (threshold_division<0.0){ /* geometrical rule: division following the shortest direction */ |
87 | 1 | akiss | double shape_direction[2]; |
88 | 1 | akiss | eigenvalue=(temp_shape[0]+temp_shape[1])/2.; |
89 | 1 | akiss | eigenvalue+=0.5*sqrt((temp_shape[0]-temp_shape[1])*(temp_shape[0]-temp_shape[1])+ |
90 | 1 | akiss | 4.*temp_shape[2]*temp_shape[2]); |
91 | 1 | akiss | shape_direction[0]=temp_shape[2]; |
92 | 1 | akiss | shape_direction[1]=eigenvalue-temp_shape[0]; |
93 | 1 | akiss | norm=sqrt(shape_direction[0]*shape_direction[0]+shape_direction[1]*shape_direction[1]); |
94 | 1 | akiss | shape_direction[0]/=norm;
|
95 | 1 | akiss | shape_direction[1]/=norm;
|
96 | 1 | akiss | division_direction[0]=shape_direction[1]; |
97 | 1 | akiss | division_direction[1]=-shape_direction[0]; |
98 | 1 | akiss | } |
99 | 1 | akiss | |
100 | 1 | akiss | /* computation of the new vertices as the intersection between the walls of the cell and the division direction */
|
101 | 1 | akiss | int l=0,m=0,max=vertices_number_in_each_cell[dividing_cell+1],min=vertices_number_in_each_cell[dividing_cell],previous; |
102 | 1 | akiss | double test;
|
103 | 1 | akiss | |
104 | 1 | akiss | |
105 | 1 | akiss | for (int i=min;i<max;i++){ /* loop over the vertices of the dividing cell */ |
106 | 1 | akiss | previous=i-1; if (i==min){previous=max-1;} |
107 | 1 | akiss | test=-division_direction[1]*(vertices[2*cells_vertices[previous]]-barycenters[2*dividing_cell]); |
108 | 1 | akiss | test+=division_direction[0]*(vertices[2*cells_vertices[previous]+1]-barycenters[2*dividing_cell+1]); |
109 | 1 | akiss | test/=-division_direction[1]*(vertices[2*cells_vertices[previous]]-vertices[2*cells_vertices[i]])+ |
110 | 1 | akiss | division_direction[0]*(vertices[2*cells_vertices[previous]+1]-vertices[2*cells_vertices[i]+1]); |
111 | 1 | akiss | |
112 | 1 | akiss | /* test if the considered point of the wall is on the division direction */
|
113 | 1 | akiss | if ((test<1. && test>=0.) && (m==0 || m==1) && l<2){ |
114 | 1 | akiss | //if (test>0.9){test=0.9;} if (test<0.1){test=0.1;} // if new vertices should not be too closed of the older ones for stability reasons
|
115 | 1 | akiss | l++; |
116 | 1 | akiss | if (l==1){ |
117 | 1 | akiss | new_vertex1[0]=test*(vertices[2*cells_vertices[i]]-vertices[2*cells_vertices[previous]])+vertices[2*cells_vertices[previous]]; |
118 | 1 | akiss | new_vertex1[1]=test*(vertices[2*cells_vertices[i]+1]-vertices[2*cells_vertices[previous]+1])+vertices[2*cells_vertices[previous]+1]; |
119 | 1 | akiss | cell1[daughter_cells_vertices_number[0]]=vertices_number-2; daughter_cells_vertices_number[0]+=1; |
120 | 1 | akiss | cell2[daughter_cells_vertices_number[1]]=vertices_number-2; daughter_cells_vertices_number[1]+=1; |
121 | 1 | akiss | wall1[0]=cells_vertices[i];
|
122 | 1 | akiss | wall1[1]=cells_vertices[previous];}
|
123 | 1 | akiss | if (l==2){ |
124 | 1 | akiss | new_vertex2[0]=test*(vertices[2*cells_vertices[i]]-vertices[2*cells_vertices[previous]])+vertices[2*cells_vertices[previous]]; |
125 | 1 | akiss | new_vertex2[1]=test*(vertices[2*cells_vertices[i]+1]-vertices[2*cells_vertices[previous]+1])+vertices[2*cells_vertices[previous]+1]; |
126 | 1 | akiss | cell1[daughter_cells_vertices_number[0]]=vertices_number-1; daughter_cells_vertices_number[0]+=1; |
127 | 1 | akiss | cell2[daughter_cells_vertices_number[1]]=vertices_number-1; daughter_cells_vertices_number[1]+=1; |
128 | 1 | akiss | wall2[0]=cells_vertices[i];
|
129 | 1 | akiss | wall2[1]=cells_vertices[previous];}
|
130 | 1 | akiss | m=2;
|
131 | 1 | akiss | } |
132 | 1 | akiss | |
133 | 1 | akiss | else if ((test<1. && test>=0.) && (m==0 || m==2) && l<2){ |
134 | 1 | akiss | //if (test>0.9){test=0.9;} if (test<0.1){test=0.1;}
|
135 | 1 | akiss | l++; |
136 | 1 | akiss | if (l==1){ |
137 | 1 | akiss | new_vertex1[0]=test*(vertices[2*cells_vertices[i]]-vertices[2*cells_vertices[previous]])+vertices[2*cells_vertices[previous]]; |
138 | 1 | akiss | new_vertex1[1]=test*(vertices[2*cells_vertices[i]+1]-vertices[2*cells_vertices[previous]+1])+vertices[2*cells_vertices[previous]+1]; |
139 | 1 | akiss | cell1[daughter_cells_vertices_number[0]]=vertices_number-2; daughter_cells_vertices_number[0]+=1; |
140 | 1 | akiss | cell2[daughter_cells_vertices_number[1]]=vertices_number-2; daughter_cells_vertices_number[1]+=1; |
141 | 1 | akiss | wall1[0]=cells_vertices[i];
|
142 | 1 | akiss | wall1[1]=cells_vertices[previous];}
|
143 | 1 | akiss | if (l==2){ |
144 | 1 | akiss | new_vertex2[0]=test*(vertices[2*cells_vertices[i]]-vertices[2*cells_vertices[previous]])+vertices[2*cells_vertices[previous]]; |
145 | 1 | akiss | new_vertex2[1]=test*(vertices[2*cells_vertices[i]+1]-vertices[2*cells_vertices[previous]+1])+vertices[2*cells_vertices[previous]+1]; |
146 | 1 | akiss | cell1[daughter_cells_vertices_number[0]]=vertices_number-1; daughter_cells_vertices_number[0]+=1; |
147 | 1 | akiss | cell2[daughter_cells_vertices_number[1]]=vertices_number-1; daughter_cells_vertices_number[1]+=1; |
148 | 1 | akiss | wall2[0]=cells_vertices[i];
|
149 | 1 | akiss | wall2[1]=cells_vertices[previous];}
|
150 | 1 | akiss | m=1;
|
151 | 1 | akiss | } |
152 | 1 | akiss | |
153 | 1 | akiss | /* write the old vertices in the two daughter cells */
|
154 | 1 | akiss | if (l==0 || l==2){cell1[daughter_cells_vertices_number[0]]=cells_vertices[i]; daughter_cells_vertices_number[0]+=1;} |
155 | 1 | akiss | if (l==1){cell2[daughter_cells_vertices_number[1]]=cells_vertices[i]; daughter_cells_vertices_number[1]+=1;} |
156 | 1 | akiss | } |
157 | 1 | akiss | |
158 | 1 | akiss | /* if l<2, there has been a problem in the computation of the new vertices */
|
159 | 1 | akiss | if (l!=2){printf("\n"); printf("division de %d ok,recherche des voisines\n",dividing_cell); exit(EXIT_FAILURE);} |
160 | 1 | akiss | |
161 | 1 | akiss | /* the new vertices are saved in the list "vertices" */
|
162 | 1 | akiss | vertices[2*(vertices_number-2)]=new_vertex1[0]; vertices[2*(vertices_number-2)+1]=new_vertex1[1]; |
163 | 1 | akiss | vertices[2*(vertices_number-1)]=new_vertex2[0]; vertices[2*(vertices_number-1)+1]=new_vertex2[1]; |
164 | 1 | akiss | |
165 | 1 | akiss | /* find the cells which are adjacent to the dividing one and have to be modified to include the new vertices */
|
166 | 1 | akiss | adjacent_cell1[0]=-1; adjacent_cell2[0]=-1; adjacent_cells_number[0]=0; |
167 | 1 | akiss | for (int i=0;i<cell_number-1;i++){ if (i==dividing_cell){goto nextcell;} |
168 | 1 | akiss | min=vertices_number_in_each_cell[i]; max=vertices_number_in_each_cell[i+1]; previous=max-min-1; |
169 | 1 | akiss | for (j=0;j<max-min;j++){ |
170 | 1 | akiss | if ((cells_vertices[min+j]==wall1[1] && cells_vertices[min+previous]==wall1[0]) |
171 | 1 | akiss | ||(cells_vertices[min+j]==wall2[1] && cells_vertices[min+previous]==wall2[0]) |
172 | 1 | akiss | ){ |
173 | 1 | akiss | |
174 | 1 | akiss | if (adjacent_cells_number[0]==0){adjacent_cell1[0]=i;} |
175 | 1 | akiss | if (adjacent_cells_number[0]==1){adjacent_cell2[0]=i;} |
176 | 1 | akiss | adjacent_cells_number[0]+=1; goto nextcell; |
177 | 1 | akiss | } |
178 | 1 | akiss | previous=j;} |
179 | 1 | akiss | nextcell:;
|
180 | 1 | akiss | } |
181 | 1 | akiss | //printf("%d voisines trouvee(s): %d %d\n",adjacent_cells_number[0],adjacent_cell1[0],adjacent_cell2[0]);
|
182 | 1 | akiss | } |