Statistiques
| Révision :

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
}