Révision 3
src/initialize.cpp (revision 3) | ||
---|---|---|
1 |
#include "compute_areas.h" |
|
2 |
#include "compute_cell_areas.h" |
|
3 |
#include "compute_barycenters.h" |
|
4 |
#include "compute_shapes.h" |
|
5 |
#include "compute_lengths.h" |
|
6 |
#include "initialize.h" |
|
7 |
#include "constants.h" |
|
8 |
#include <stdio.h> |
|
9 |
#include "compute_cell_walls.h" |
|
10 |
|
|
11 |
/* this function initializes the various lists used in the program */ |
|
12 |
|
|
13 |
void initialize(double *vertices, int vertices_number, int *cells_vertices, int *vertices_number_in_each_cell, int cell_number, int *wall_vertices, int wall_number, int *cell_walls, |
|
14 |
double *barycenters, double *shapes, double *targets, double *lengths, double *target_lengths, double *areas, double *cell_areas, double *forces, double *stress_periclinal, double *stress_anticlinal){ |
|
15 |
|
|
16 |
int i; |
|
17 |
compute_barycenters(vertices,vertices_number,cells_vertices,vertices_number_in_each_cell,cell_number,barycenters); |
|
18 |
compute_shapes(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters, shapes); |
|
19 |
compute_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas); |
|
20 |
compute_cell_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas, cell_areas); |
|
21 |
compute_cell_walls(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, cell_walls, wall_vertices, wall_number); |
|
22 |
compute_lengths(vertices, wall_vertices, wall_number, lengths); |
|
23 |
for (i=0;i<cell_number;i++){ |
|
24 |
targets[3*i]=initial_growth*shapes[3*i]; targets[3*i+1]=initial_growth*shapes[3*i+1]; targets[3*i+2]=initial_growth*shapes[3*i+2]; |
|
25 |
stress_periclinal[3*i]=0.; stress_periclinal[3*i+1]=0.; stress_periclinal[3*i+2]=0.; |
|
26 |
} |
|
27 |
for (i=0;i<wall_number;i++){ |
|
28 |
target_lengths[i]=lengths[i]; stress_anticlinal[3*i]=0.; stress_anticlinal[3*i+1]=0.; stress_anticlinal[3*i+2]=0.; |
|
29 |
} |
|
30 |
} |
src/minimize_steepest_descent.cpp (revision 3) | ||
---|---|---|
1 |
#include "compute_energy_and_forces.h" |
|
2 |
#include "minimize_steepest_descent.h" |
|
3 |
#include <nlopt.h> |
|
4 |
#include <stdio.h> |
|
5 |
#include <stdlib.h> |
|
6 |
#include <cmath> |
|
7 |
|
|
8 |
/* this function minimizes the mechanical energy. It is an alternative to the BFGS algorithm, just for debugging */ |
|
9 |
|
|
10 |
void minimize_steepest_descent(int vertices_number, int cell_number, double *vertices, int *cells_vertices, int *vertices_number_in_each_cell, double *barycenters, double *shapes, double *targets, double *areas, double *cell_areas, double *target_areas, |
|
11 |
int *wall_vertices, int wall_number, double *lengths, double *target_lengths){ |
|
12 |
|
|
13 |
double step_size=1.e-2; |
|
14 |
double precision=1.e-2; |
|
15 |
|
|
16 |
struct parameters_list {int vertices_number; int cell_number; int *cells_vertices; int *vertices_number_in_each_cell; double *barycenters; double *shapes; double *targets; double *areas; double *cell_areas; double *target_areas; |
|
17 |
int *wall_vertices; int wall_number; double *lengths; double *target_lengths;}; |
|
18 |
|
|
19 |
struct parameters_list parameters; |
|
20 |
parameters.vertices_number=vertices_number; |
|
21 |
parameters.cell_number=cell_number; |
|
22 |
parameters.cells_vertices=cells_vertices; |
|
23 |
parameters.vertices_number_in_each_cell=vertices_number_in_each_cell; |
|
24 |
parameters.barycenters=barycenters; |
|
25 |
parameters.shapes=shapes; |
|
26 |
parameters.targets=targets; |
|
27 |
parameters.areas=areas; |
|
28 |
parameters.cell_areas=cell_areas; |
|
29 |
parameters.target_areas=target_areas; |
|
30 |
parameters.wall_vertices=wall_vertices; |
|
31 |
parameters.wall_number=wall_number; |
|
32 |
parameters.lengths=lengths; |
|
33 |
parameters.target_lengths=target_lengths; |
|
34 |
void* pparameters=¶meters; |
|
35 |
|
|
36 |
double forces[2*vertices_number]; |
|
37 |
double energy=compute_energy_and_forces(0, vertices, forces, pparameters); |
|
38 |
double max_step=0.; for (int i=0;i<2*vertices_number;i++){ if (fabs(forces[i])>max_step){ max_step=fabs(forces[i]);}} |
|
39 |
int step_number=0; |
|
40 |
|
|
41 |
while (max_step>precision){ |
|
42 |
step_number++; |
|
43 |
for (int i=0;i<2*vertices_number;i++){ vertices[i]-=step_size*forces[i];} |
|
44 |
energy=compute_energy_and_forces(0, vertices, forces, pparameters); |
|
45 |
max_step=0; |
|
46 |
for (int i=0;i<2*vertices_number;i++){ if (fabs(forces[i])>max_step){ max_step=fabs(forces[i]);}} |
|
47 |
} |
|
48 |
|
|
49 |
printf("opt %f %d\n",energy,step_number); |
|
50 |
|
|
51 |
} |
src/compute_lengths.h (revision 3) | ||
---|---|---|
1 |
#ifndef COMPUTE_LENGTHS_H_INCLUDED |
|
2 |
#define COMPUTE_LENGTHS_H_INCLUDED |
|
3 |
|
|
4 |
void compute_lengths(double *vertices, int *wall_vertices, int wall_number, double *lengths); |
|
5 |
|
|
6 |
#endif // COMPUTE_LENGTHS_H_INCLUDED |
src/compute_energy_and_forces.cpp (revision 3) | ||
---|---|---|
1 |
#include "compute_energy_and_forces.h" |
|
2 |
#include "constants.h" |
|
3 |
#include "compute_areas.h" |
|
4 |
#include "compute_cell_areas.h" |
|
5 |
#include "compute_shapes.h" |
|
6 |
#include "compute_barycenters.h" |
|
7 |
#include "compute_lengths.h" |
|
8 |
#include <math.h> |
|
9 |
#include <stdio.h> |
|
10 |
#include <nlopt.h> |
|
11 |
#include <omp.h> |
|
12 |
|
|
13 |
/* this function computes the mechanical energy and its derivatives (basically only math equations) */ |
|
14 |
|
|
15 |
double compute_energy_and_forces(unsigned n, const double *vertices, double *forces, void *parameters){ |
|
16 |
|
|
17 |
struct parameters_list {int vertices_number; int cell_number; int *cells_vertices; int *vertices_number_in_each_cell; double *barycenters; double *shapes; double *targets; double *areas; double *cell_areas; |
|
18 |
int *wall_vertices; int wall_number; double *lengths; double *target_lengths; int *boundary; double *tissue_target; int anisotropy; double *relative_pressure;}; |
|
19 |
|
|
20 |
int j,previous; double N,energy=0; |
|
21 |
|
|
22 |
compute_lengths((double*)vertices, ((parameters_list*)parameters)->wall_vertices, ((parameters_list*)parameters)->wall_number, ((parameters_list*)parameters)->lengths); |
|
23 |
compute_barycenters((double*)vertices, ((parameters_list*)parameters)->vertices_number, ((parameters_list*)parameters)->cells_vertices, |
|
24 |
((parameters_list*)parameters)->vertices_number_in_each_cell, ((parameters_list*)parameters)->cell_number, ((parameters_list*)parameters)->barycenters); |
|
25 |
compute_areas((double*)vertices, ((parameters_list*)parameters)->cells_vertices, ((parameters_list*)parameters)->vertices_number_in_each_cell, |
|
26 |
((parameters_list*)parameters)->cell_number, ((parameters_list*)parameters)->areas); |
|
27 |
compute_cell_areas((double*)vertices, ((parameters_list*)parameters)->cells_vertices, ((parameters_list*)parameters)->vertices_number_in_each_cell, |
|
28 |
((parameters_list*)parameters)->cell_number, ((parameters_list*)parameters)->areas, ((parameters_list*)parameters)->cell_areas); |
|
29 |
compute_shapes((double*)vertices, ((parameters_list*)parameters)->cells_vertices, ((parameters_list*)parameters)->vertices_number_in_each_cell, |
|
30 |
((parameters_list*)parameters)->cell_number, ((parameters_list*)parameters)->barycenters, ((parameters_list*)parameters)->shapes); |
|
31 |
|
|
32 |
|
|
33 |
if (forces){ for (int i=0;i<2*((parameters_list*)parameters)->vertices_number;i++){forces[i]=0.;}} |
|
34 |
|
|
35 |
//for (int i=0;i<((parameters_list*)parameters)->vertices_number;i++){ |
|
36 |
// if (vertices[2*i+1]>7.){ forces[2*i+1]+=0.01*sinh(vertices[2*i+1]-7.);} |
|
37 |
// if (vertices[2*i+1]<-7.){ forces[2*i+1]+=0.01*sinh(vertices[2*i+1]+7.);} |
|
38 |
// if (vertices[2*i+1]>7.){ energy+=0.01*(cosh(vertices[2*i+1]-7.)-1.);} |
|
39 |
// if (vertices[2*i+1]<-7.){ energy+=0.01*(cosh(vertices[2*i+1]+7.)-1.);} |
|
40 |
//} |
|
41 |
|
|
42 |
double ablation; |
|
43 |
for (int i=0;i<((parameters_list*)parameters)->cell_number;i++){ |
|
44 |
ablation=(double)(i!=ablated_cell); |
|
45 |
if (forces){ |
|
46 |
for (j=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i];j<(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1];j++){ |
|
47 |
previous=j-1; if (j==(((parameters_list*)parameters)->vertices_number_in_each_cell)[i]){ previous=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1]-1;} |
|
48 |
/* derivatives of the area in the pressure energy */ |
|
49 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]]-=0.5*ablation*pressure*(((parameters_list*)parameters)->relative_pressure)[i]*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1]); |
|
50 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]-=0.5*ablation*pressure*(((parameters_list*)parameters)->relative_pressure)[i]*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]]); |
|
51 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[previous]]-=0.5*ablation*pressure*(((parameters_list*)parameters)->relative_pressure)[i]*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]); |
|
52 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1]-=0.5*ablation*pressure*(((parameters_list*)parameters)->relative_pressure)[i]*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]]); |
|
53 |
} |
|
54 |
} |
|
55 |
/* pressure energy */ |
|
56 |
energy+=-pressure*(((parameters_list*)parameters)->relative_pressure)[i]*ablation*(((parameters_list*)parameters)->cell_areas)[i]; |
|
57 |
} |
|
58 |
|
|
59 |
double boundary; |
|
60 |
for (int i=0;i<((parameters_list*)parameters)->cell_number;i++){ |
|
61 |
// for (j=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i];j<(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1];j++){ |
|
62 |
// previous=j-1; if (j==(((parameters_list*)parameters)->vertices_number_in_each_cell)[i]){ previous=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1]-1;} |
|
63 |
// boundary=(double)((((parameters_list*)parameters)->boundary)[j]); |
|
64 |
// if (forces){ |
|
65 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[j]]-=boundary*0.5*pressure*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1]); |
|
66 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]-=boundary*0.5*pressure*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]]); |
|
67 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[previous]]-=boundary*0.5*pressure*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]); |
|
68 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1]-=boundary*0.5*pressure*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]]); |
|
69 |
// } |
|
70 |
// |
|
71 |
// energy-=boundary*0.5*pressure*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]]*vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]- |
|
72 |
// vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]]*vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1]); |
|
73 |
// } |
|
74 |
} |
|
75 |
|
|
76 |
double trace; |
|
77 |
for (int i=0;i<((parameters_list*)parameters)->cell_number;i++){ |
|
78 |
trace=(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->targets)[3*i+1]; |
|
79 |
N=(double)((((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1])-(double)((((parameters_list*)parameters)->vertices_number_in_each_cell)[i]); |
|
80 |
ablation=(double)(i!=ablated_cell); |
|
81 |
if (forces){ |
|
82 |
for (j=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i];j<(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1];j++){ |
|
83 |
previous=j-1; if (j==(((parameters_list*)parameters)->vertices_number_in_each_cell)[i]){ previous=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1]-1;} |
|
84 |
/* derivatives of the shape matrix */ |
|
85 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]]+=ablation*shear_modulus*4.0*((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i]) |
|
86 |
*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]]-(((parameters_list*)parameters)->barycenters)[2*i])* |
|
87 |
(((parameters_list*)parameters)->cell_areas)[i]/(trace*trace*N); |
|
88 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]]+=ablation*shear_modulus*4.0*((((parameters_list*)parameters)->shapes)[3*i+2]-(((parameters_list*)parameters)->targets)[3*i+2]) |
|
89 |
*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]-(((parameters_list*)parameters)->barycenters)[2*i+1])* |
|
90 |
(((parameters_list*)parameters)->cell_areas)[i]/(trace*trace*N); |
|
91 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]+=ablation*shear_modulus*4.0*((((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1]) |
|
92 |
*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]-(((parameters_list*)parameters)->barycenters)[2*i+1])* |
|
93 |
(((parameters_list*)parameters)->cell_areas)[i]/(trace*trace*N); |
|
94 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]+=ablation*shear_modulus*4.0*((((parameters_list*)parameters)->shapes)[3*i+2]-(((parameters_list*)parameters)->targets)[3*i+2]) |
|
95 |
*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]]-(((parameters_list*)parameters)->barycenters)[2*i])* |
|
96 |
(((parameters_list*)parameters)->cell_areas)[i]/(trace*trace*N); |
|
97 |
/* derivatives of the area */ |
|
98 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]]+=ablation*shear_modulus*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1])* |
|
99 |
(pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i],2.)+ |
|
100 |
pow((((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
101 |
+2.*pow((((parameters_list*)parameters)->shapes)[3*i+2]-(((parameters_list*)parameters)->targets)[3*i+2],2.))/(2.*trace*trace); |
|
102 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]+=ablation*shear_modulus*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]])* |
|
103 |
(pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i],2.)+ |
|
104 |
pow((((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
105 |
+2.*pow((((parameters_list*)parameters)->shapes)[3*i+2]-(((parameters_list*)parameters)->targets)[3*i+2],2.))/(2.*trace*trace); |
|
106 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[previous]]+=ablation*shear_modulus*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1])* |
|
107 |
(pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i],2.)+ |
|
108 |
pow((((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
109 |
+2.*pow((((parameters_list*)parameters)->shapes)[3*i+2]-(((parameters_list*)parameters)->targets)[3*i+2],2.))/(2.*trace*trace); |
|
110 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1]+=ablation*shear_modulus*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]])* |
|
111 |
(pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i],2.)+ |
|
112 |
pow((((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
113 |
+2.*pow((((parameters_list*)parameters)->shapes)[3*i+2]-(((parameters_list*)parameters)->targets)[3*i+2],2.))/(2.*trace*trace); |
|
114 |
} |
|
115 |
} |
|
116 |
/* shape energy, contribution from the shear modulus */ |
|
117 |
energy+=ablation*shear_modulus*(((parameters_list*)parameters)->cell_areas)[i]*(pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i],2.) |
|
118 |
+pow((((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
119 |
+2.*pow((((parameters_list*)parameters)->shapes)[3*i+2]-(((parameters_list*)parameters)->targets)[3*i+2],2.))/(trace*trace);//(((parameters_list*)parameters)->cell_areas)[i]; |
|
120 |
} |
|
121 |
|
|
122 |
/* contribution of the first lame parameter, this term was neglected in the final version of the paper as it has no impact */ |
|
123 |
for (int i=0;i<((parameters_list*)parameters)->cell_number;i++){ |
|
124 |
// min=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i]; max=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1]; |
|
125 |
// trace=(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->targets)[3*i+1]; |
|
126 |
// N=(double)(max)-(double)(min); |
|
127 |
// if (forces){ |
|
128 |
// for (j=0;j<max-min;j++){ previous=j-1; if (j==0){ previous=max-min-1;} |
|
129 |
// /* derivatives of the shape matrix */ |
|
130 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[min+j]]+=lame_first_periclinal*4.0*(((parameters_list*)parameters)->cell_areas)[i]* |
|
131 |
// ((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1]) |
|
132 |
// *(vertices[2*(((parameters_list*)parameters)->cells_vertices)[min+j]]-(((parameters_list*)parameters)->barycenters)[2*i]) |
|
133 |
// /(trace*trace*N); |
|
134 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[min+j]+1]+=lame_first_periclinal*4.0*(((parameters_list*)parameters)->cell_areas)[i]* |
|
135 |
// ((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1]) |
|
136 |
// *(vertices[2*(((parameters_list*)parameters)->cells_vertices)[min+j]+1]-(((parameters_list*)parameters)->barycenters)[2*i+1]) |
|
137 |
// /(trace*trace*N); |
|
138 |
// /* derivatives of the area */ |
|
139 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[min+j]]+=lame_first_periclinal*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[min+previous]+1])* |
|
140 |
// pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
141 |
// /(2.*trace*trace); |
|
142 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[min+j]+1]+=lame_first_periclinal*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[min+previous]])* |
|
143 |
// pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
144 |
// /(2.*trace*trace); |
|
145 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[min+previous]]+=lame_first_periclinal*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[min+j]+1])* |
|
146 |
// pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
147 |
// /(2.*trace*trace); |
|
148 |
// forces[2*(((parameters_list*)parameters)->cells_vertices)[min+previous]+1]+=lame_first_periclinal*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[min+j]])* |
|
149 |
// pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
150 |
// /(2.*trace*trace); |
|
151 |
// } |
|
152 |
// } |
|
153 |
// /* area energy */ |
|
154 |
// energy+=lame_first_periclinal*(((parameters_list*)parameters)->cell_areas)[i]* |
|
155 |
// pow((((parameters_list*)parameters)->shapes)[3*i]-(((parameters_list*)parameters)->targets)[3*i]+(((parameters_list*)parameters)->shapes)[3*i+1]-(((parameters_list*)parameters)->targets)[3*i+1],2.) |
|
156 |
// /(trace*trace); |
|
157 |
} |
|
158 |
|
|
159 |
/* energy of the anticlinal walls */ |
|
160 |
for (int i=0;i<((parameters_list*)parameters)->wall_number;i++){ |
|
161 |
// /* derivatives of the lengths of the walls */ |
|
162 |
// if (forces){ |
|
163 |
// forces[2*(((parameters_list*)parameters)->wall_vertices)[2*i]]+=lame_first_anticlinal/*(((parameters_list*)parameters)->wall_out)[i]*/*2.*((((parameters_list*)parameters)->lengths)[i]-(((parameters_list*)parameters)->target_lengths)[i])* |
|
164 |
// (vertices[2*(((parameters_list*)parameters)->wall_vertices)[2*i]]-vertices[2*(((parameters_list*)parameters)->wall_vertices)[2*i+1]])/ |
|
165 |
// ((((parameters_list*)parameters)->lengths)[i]*(((parameters_list*)parameters)->target_lengths)[i]); |
|
166 |
// forces[2*(((parameters_list*)parameters)->wall_vertices)[2*i+1]]+=lame_first_anticlinal/*(((parameters_list*)parameters)->wall_out)[i]*/*2.*((((parameters_list*)parameters)->lengths)[i]-(((parameters_list*)parameters)->target_lengths)[i])* |
|
167 |
// (vertices[2*(((parameters_list*)parameters)->wall_vertices)[2*i+1]]-vertices[2*(((parameters_list*)parameters)->wall_vertices)[2*i]])/ |
|
168 |
// ((((parameters_list*)parameters)->lengths)[i]*(((parameters_list*)parameters)->target_lengths)[i]); |
|
169 |
// forces[2*(((parameters_list*)parameters)->wall_vertices)[2*i]+1]+=lame_first_anticlinal/*(((parameters_list*)parameters)->wall_out)[i]*/*2.*((((parameters_list*)parameters)->lengths)[i]-(((parameters_list*)parameters)->target_lengths)[i])* |
|
170 |
// (vertices[2*(((parameters_list*)parameters)->wall_vertices)[2*i]+1]-vertices[2*(((parameters_list*)parameters)->wall_vertices)[2*i+1]+1])/ |
|
171 |
// ((((parameters_list*)parameters)->lengths)[i]*(((parameters_list*)parameters)->target_lengths)[i]); |
|
172 |
// forces[2*(((parameters_list*)parameters)->wall_vertices)[2*i+1]+1]+=lame_first_anticlinal/*(((parameters_list*)parameters)->wall_out)[i]*/*2.*((((parameters_list*)parameters)->lengths)[i]-(((parameters_list*)parameters)->target_lengths)[i])* |
|
173 |
// (vertices[2*(((parameters_list*)parameters)->wall_vertices)[2*i+1]+1]-vertices[2*(((parameters_list*)parameters)->wall_vertices)[2*i]+1])/ |
|
174 |
// ((((parameters_list*)parameters)->lengths)[i]*(((parameters_list*)parameters)->target_lengths)[i]); |
|
175 |
// } |
|
176 |
// /* walls energy */ |
|
177 |
// /* the 2. factor comes from the fact that each wall is counted twice in the sum over the cells */ |
|
178 |
// energy+=lame_first_anticlinal*pow((((parameters_list*)parameters)->lengths)[i]-(((parameters_list*)parameters)->target_lengths)[i],2.)/(((parameters_list*)parameters)->target_lengths)[i]; |
|
179 |
} |
|
180 |
|
|
181 |
/* contribution from the anisotropic stress that mimics curvature */ |
|
182 |
if (((parameters_list*)parameters)->anisotropy==1){ |
|
183 |
double tissue_area=0.; int boundary_vertices_number=0; |
|
184 |
double tissue_shape[2]={0.,0.}; double tissue_barycenter[2]={0.,0.}; |
|
185 |
for (int i=0;i<((parameters_list*)parameters)->cell_number;i++){ |
|
186 |
for (j=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i];j<(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1];j++){ |
|
187 |
previous=j-1; if (j==(((parameters_list*)parameters)->vertices_number_in_each_cell)[i]){ previous=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1]-1;} |
|
188 |
boundary_vertices_number+=(((parameters_list*)parameters)->boundary)[j]; |
|
189 |
boundary=(double)((((parameters_list*)parameters)->boundary)[j]); |
|
190 |
tissue_area+=boundary*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]]*vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]- |
|
191 |
vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]]*vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1])/2.; |
|
192 |
tissue_barycenter[0]+=boundary*vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]]; |
|
193 |
tissue_barycenter[1]+=boundary*vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]; |
|
194 |
} |
|
195 |
} |
|
196 |
tissue_barycenter[0]/=boundary_vertices_number; |
|
197 |
tissue_barycenter[1]/=boundary_vertices_number; |
|
198 |
for (int i=0;i<(((parameters_list*)parameters)->vertices_number_in_each_cell)[((parameters_list*)parameters)->cell_number];i++){ |
|
199 |
boundary=(double)((((parameters_list*)parameters)->boundary)[i]); |
|
200 |
tissue_shape[0]+=boundary*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[i]]-tissue_barycenter[0])*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[i]]-tissue_barycenter[0]); |
|
201 |
tissue_shape[1]+=boundary*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[i]+1]-tissue_barycenter[1])*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[i]+1]-tissue_barycenter[1]); |
|
202 |
} |
|
203 |
tissue_shape[0]/=boundary_vertices_number; |
|
204 |
tissue_shape[1]/=boundary_vertices_number; |
|
205 |
trace=(((parameters_list*)parameters)->tissue_target)[0]+(((parameters_list*)parameters)->tissue_target)[1]; |
|
206 |
if (forces){ |
|
207 |
for (int i=0;i<((parameters_list*)parameters)->cell_number;i++){ |
|
208 |
for (j=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i];j<(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1];j++){ |
|
209 |
previous=j-1; if (j==(((parameters_list*)parameters)->vertices_number_in_each_cell)[i]){ previous=(((parameters_list*)parameters)->vertices_number_in_each_cell)[i+1]-1;} |
|
210 |
boundary=(double)((((parameters_list*)parameters)->boundary)[j]); |
|
211 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]]-=boundary*tissue_area*first_shape_derived_stress*2.*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]]-tissue_barycenter[0])/ |
|
212 |
(trace*boundary_vertices_number); |
|
213 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]-=boundary*tissue_area*second_shape_derived_stress*2.*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]-tissue_barycenter[1])/ |
|
214 |
(trace*boundary_vertices_number); |
|
215 |
|
|
216 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]]-=boundary*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1])* |
|
217 |
(first_shape_derived_stress*(tissue_shape[0]-(((parameters_list*)parameters)->tissue_target)[0])+ |
|
218 |
second_shape_derived_stress*(tissue_shape[1]-(((parameters_list*)parameters)->tissue_target)[1]))/(2.*trace); |
|
219 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[previous]]-=boundary*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]+1])* |
|
220 |
(first_shape_derived_stress*(tissue_shape[0]-(((parameters_list*)parameters)->tissue_target)[0])+ |
|
221 |
second_shape_derived_stress*(tissue_shape[1]-(((parameters_list*)parameters)->tissue_target)[1]))/(2.*trace); |
|
222 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[j]+1]-=boundary*(vertices[2*(((parameters_list*)parameters)->cells_vertices)[previous]])* |
|
223 |
(first_shape_derived_stress*(tissue_shape[0]-(((parameters_list*)parameters)->tissue_target)[0])+ |
|
224 |
second_shape_derived_stress*(tissue_shape[1]-(((parameters_list*)parameters)->tissue_target)[1]))/(2.*trace); |
|
225 |
forces[2*(((parameters_list*)parameters)->cells_vertices)[previous]+1]-=boundary*(-vertices[2*(((parameters_list*)parameters)->cells_vertices)[j]])* |
|
226 |
(first_shape_derived_stress*(tissue_shape[0]-(((parameters_list*)parameters)->tissue_target)[0])+ |
|
227 |
second_shape_derived_stress*(tissue_shape[1]-(((parameters_list*)parameters)->tissue_target)[1]))/(2.*trace); |
|
228 |
} |
|
229 |
} |
|
230 |
} |
|
231 |
energy-=tissue_area*(first_shape_derived_stress*(tissue_shape[0]-(((parameters_list*)parameters)->tissue_target)[0])+ |
|
232 |
second_shape_derived_stress*(tissue_shape[1]-(((parameters_list*)parameters)->tissue_target)[1]))/trace; |
|
233 |
} |
|
234 |
|
|
235 |
return(energy); |
|
236 |
|
|
237 |
} |
src/cell_division2.h (revision 3) | ||
---|---|---|
1 |
#ifndef CELL_DIVISION2_H_INCLUDED |
|
2 |
#define CELL_DIVISION2_H_INCLUDED |
|
3 |
|
|
4 |
void cell_division2(double *vertices, int vertices_number, int *cells_vertices, int *vertices_number_in_each_cell, int cell_number, int *wall_vertices, int wall_number, |
|
5 |
double *barycenters, double *areas, double *cell_areas, double *lengths, double *target_lengths, double *shapes, double *targets, |
|
6 |
int dividing_cell, int *boundary, int *border, int adjacent_cells_number, int adjacent_cell1, int adjacent_cell2, |
|
7 |
int *daughter_cells_vertices_number, int *cell1, int *cell2, int *wall1, int *wall2); |
|
8 |
|
|
9 |
#endif // CELL_DIVISION2_H_INCLUDED |
src/constants.cpp (revision 3) | ||
---|---|---|
1 |
#include <math.h> |
|
2 |
|
|
3 |
int step_number=1;//51; |
|
4 |
int max_cell_number=200;//400; //1000000 |
|
5 |
double tau1=10.; |
|
6 |
|
|
7 |
double pi=3.1415926; |
|
8 |
|
|
9 |
double initial_growth=1.; |
|
10 |
double threshold_area=3.; |
|
11 |
double threshold_division=0.; |
|
12 |
|
|
13 |
double shear_modulus=1.; |
|
14 |
double lame_first_periclinal=0.;//0.1; |
|
15 |
double lame_first_anticlinal=0.0;//0.02; |
|
16 |
double pressure=1.e-2;//6.e-2;//12.e-2; |
|
17 |
|
|
18 |
double first_shape_derived_stress=3.e-2;// 3.e-2 |
|
19 |
double second_shape_derived_stress=3.e-2; |
|
20 |
|
|
21 |
double noise_amplitude=0.1; |
|
22 |
|
|
23 |
int ablated_cell=-1; |
|
24 |
int iteration=0; |
|
25 |
int iteration_ablation=1000000; //50 |
|
26 |
|
|
27 |
double growth_differential=1.; //>=0 |
|
28 |
|
|
29 |
#pragma omp threadprivate(threshold_area,threshold_division,shear_modulus,lame_first_periclinal,lame_first_anticlinal,ablated_cell,iteration,growth_differential,first_shape_derived_stress,second_shape_derived_stress) |
src/compute_cell_walls.cpp (revision 3) | ||
---|---|---|
1 |
#include <math.h> |
|
2 |
#include "constants.h" |
|
3 |
#include "compute_cell_walls.h" |
|
4 |
#include <stdio.h> |
|
5 |
|
|
6 |
/* this function computes the list of the indices of the wall of each cell */ |
|
7 |
|
|
8 |
void compute_cell_walls(double *vertices, int *cells_vertices, int *vertices_number_in_each_cell, |
|
9 |
int cell_number, int *cell_walls, int *wall_vertices, int wall_number){ |
|
10 |
|
|
11 |
int i,j,k,previous; |
|
12 |
|
|
13 |
for (i=0;i<cell_number;i++){ |
|
14 |
for (j=vertices_number_in_each_cell[i];j<vertices_number_in_each_cell[i+1];j++){ previous=j-1; if (j==vertices_number_in_each_cell[i]){previous=vertices_number_in_each_cell[i+1]-1;} |
|
15 |
for (k=0;k<wall_number;k++){ |
|
16 |
if ((cells_vertices[previous]==wall_vertices[2*k] && cells_vertices[j]==wall_vertices[2*k+1]) || (cells_vertices[previous]==wall_vertices[2*k+1] && cells_vertices[j]==wall_vertices[2*k])){ |
|
17 |
cell_walls[j]=k; |
|
18 |
} |
|
19 |
} |
|
20 |
} |
|
21 |
} |
|
22 |
|
|
23 |
} |
src/compute_stress_anticlinal.cpp (revision 3) | ||
---|---|---|
1 |
#include "compute_stress_anticlinal.h" |
|
2 |
#include "constants.h" |
|
3 |
#include <stdio.h> |
|
4 |
|
|
5 |
/* this function computes the stress on a cell by interpolating the forces on its vertices */ |
|
6 |
|
|
7 |
void compute_stress_anticlinal(int wall_index, double *vertices, int *vertices_number_in_each_cell, int cell_number, double *stress_anticlinal, |
|
8 |
int *wall_vertices, int *cell_walls, double *lengths, double *target_lengths){ |
|
9 |
|
|
10 |
double projection[3]; |
|
11 |
projection[0]=(vertices[2*wall_vertices[2*wall_index]]-vertices[2*wall_vertices[2*wall_index+1]])*(vertices[2*wall_vertices[2*wall_index]]-vertices[2*wall_vertices[2*wall_index+1]]); |
|
12 |
projection[1]=(vertices[2*wall_vertices[2*wall_index]+1]-vertices[2*wall_vertices[2*wall_index+1]+1])*(vertices[2*wall_vertices[2*wall_index]+1]-vertices[2*wall_vertices[2*wall_index+1]+1]); |
|
13 |
projection[2]=(vertices[2*wall_vertices[2*wall_index]+1]-vertices[2*wall_vertices[2*wall_index+1]+1])*(vertices[2*wall_vertices[2*wall_index]]-vertices[2*wall_vertices[2*wall_index+1]]); |
|
14 |
projection[0]/=lengths[wall_index]*lengths[wall_index]; |
|
15 |
projection[1]/=lengths[wall_index]*lengths[wall_index]; |
|
16 |
projection[2]/=lengths[wall_index]*lengths[wall_index]; |
|
17 |
stress_anticlinal[3*wall_index]=lame_first_anticlinal*(lengths[wall_index]-target_lengths[wall_index])*projection[0]/target_lengths[wall_index]; |
|
18 |
stress_anticlinal[3*wall_index+1]=lame_first_anticlinal*(lengths[wall_index]-target_lengths[wall_index])*projection[1]/target_lengths[wall_index]; |
|
19 |
stress_anticlinal[3*wall_index+2]=lame_first_anticlinal*(lengths[wall_index]-target_lengths[wall_index])*projection[2]/target_lengths[wall_index]; |
|
20 |
|
|
21 |
|
|
22 |
} |
src/step.h (revision 3) | ||
---|---|---|
1 |
#ifndef STEP_H_INCLUDED |
|
2 |
#define STEP_H_INCLUDED |
|
3 |
|
|
4 |
void step(double *vertices, int vertices_number, int *cells_vertices, int *vertices_number_in_each_cell, int cell_number, int *wall_vertices, int wall_number, int *cell_walls, |
|
5 |
double *barycenters, double *shapes, double *targets, double *lengths, double *target_lengths, double *areas, double *cell_areas, double *forces, double *stress_periclinal, double *stress_anticlinal, |
|
6 |
int *boundary, double *growth_rate, double *relative_pressure); |
|
7 |
|
|
8 |
#endif // STEP_H_INCLUDED |
src/minimize_BFGS.cpp (revision 3) | ||
---|---|---|
1 |
#include "compute_energy_and_forces.h" |
|
2 |
#include "minimize_BFGS.h" |
|
3 |
#include <nlopt.h> |
|
4 |
#include <stdio.h> |
|
5 |
#include <stdlib.h> |
|
6 |
#include <cmath> |
|
7 |
|
|
8 |
/* this function minimizes the mechanical energy */ |
|
9 |
|
|
10 |
void minimize_BFGS(int vertices_number, int cell_number, double *vertices, int *cells_vertices, int *vertices_number_in_each_cell, double *barycenters, double *shapes, double *targets, double *areas, double *cell_areas, |
|
11 |
int *wall_vertices, int wall_number, double *lengths, double *target_lengths, int *boundary, double *relative_pressure){ |
|
12 |
|
|
13 |
nlopt_opt opt; |
|
14 |
opt=nlopt_create(NLOPT_LD_LBFGS,2*vertices_number); |
|
15 |
|
|
16 |
nlopt_set_stopval(opt, -HUGE_VAL); |
|
17 |
nlopt_set_maxeval(opt, -1.); |
|
18 |
nlopt_set_maxtime(opt, -1.); |
|
19 |
nlopt_set_xtol_rel(opt, -1.); |
|
20 |
nlopt_set_xtol_abs1(opt, 1.e-6); |
|
21 |
nlopt_set_ftol_rel(opt, -1.); |
|
22 |
nlopt_set_ftol_abs(opt, -1.); |
|
23 |
|
|
24 |
struct parameters_list {int vertices_number; int cell_number; int *cells_vertices; int *vertices_number_in_each_cell; double *barycenters; double *shapes; double *targets; double *areas; double *cell_areas; |
|
25 |
int *wall_vertices; int wall_number; double *lengths; double *target_lengths; int *boundary; double *tissue_target; int anisotropy; double *relative_pressure;}; |
|
26 |
|
|
27 |
double min_energy; double tissue_target[2]={1.,1.}; |
|
28 |
struct parameters_list parameters; |
|
29 |
parameters.vertices_number=vertices_number; |
|
30 |
parameters.cell_number=cell_number; |
|
31 |
parameters.cells_vertices=cells_vertices; |
|
32 |
parameters.vertices_number_in_each_cell=vertices_number_in_each_cell; |
|
33 |
parameters.barycenters=barycenters; |
|
34 |
parameters.shapes=shapes; |
|
35 |
parameters.targets=targets; |
|
36 |
parameters.areas=areas; |
|
37 |
parameters.cell_areas=cell_areas; |
|
38 |
parameters.wall_vertices=wall_vertices; |
|
39 |
parameters.wall_number=wall_number; |
|
40 |
parameters.lengths=lengths; |
|
41 |
parameters.target_lengths=target_lengths; |
|
42 |
parameters.boundary=boundary; |
|
43 |
parameters.tissue_target=tissue_target; |
|
44 |
parameters.anisotropy=0; |
|
45 |
parameters.relative_pressure=relative_pressure; |
|
46 |
void* pparameters=¶meters; |
|
47 |
|
|
48 |
//double forces[2*vertices_number]; |
|
49 |
//double test=compute_energy_and_forces(0, vertices, forces, pparameters); |
|
50 |
////for (int i=0; i<vertices_number;i++){ printf("%f %f %d %d\n",forces[2*i],forces[2*i+1],i,vertices_number);} printf("test\n"); |
|
51 |
//double test2; |
|
52 |
//for (int i=0;i<2*vertices_number;i++){vertices[i]+=1.e-8; |
|
53 |
//test2=compute_energy_and_forces(0, vertices, forces, pparameters); |
|
54 |
//test2-=test; |
|
55 |
//test2*=1.e8; |
|
56 |
//vertices[i]-=1.e-8; |
|
57 |
//printf("%f %f %f\n",test2,forces[i],(test2-forces[i])/forces[i]); |
|
58 |
//}printf("\n"); |
|
59 |
|
|
60 |
int reso=nlopt_set_min_objective(opt, compute_energy_and_forces, pparameters); |
|
61 |
nlopt_optimize(opt, vertices, &min_energy); |
|
62 |
|
|
63 |
tissue_target[0]=0.; tissue_target[1]=0.; |
|
64 |
int boundary_vertices_number=0.; double tissue_barycenter[2]={0.,0.}; |
|
65 |
for (int i=0;i<vertices_number_in_each_cell[cell_number];i++){ |
|
66 |
tissue_barycenter[0]+=((double)boundary[i])*vertices[2*cells_vertices[i]]; |
|
67 |
tissue_barycenter[1]+=((double)boundary[i])*vertices[2*cells_vertices[i]+1]; |
|
68 |
boundary_vertices_number+=boundary[i]; |
|
69 |
} |
|
70 |
tissue_barycenter[0]/=boundary_vertices_number; |
|
71 |
tissue_barycenter[1]/=boundary_vertices_number; |
|
72 |
|
|
73 |
for (int i=0;i<vertices_number_in_each_cell[cell_number];i++){ |
|
74 |
tissue_target[0]+=((double)boundary[i])*(vertices[2*cells_vertices[i]]-tissue_barycenter[0])*(vertices[2*cells_vertices[i]]-tissue_barycenter[0]); |
|
75 |
tissue_target[1]+=((double)boundary[i])*(vertices[2*cells_vertices[i]+1]-tissue_barycenter[1])*(vertices[2*cells_vertices[i]+1]-tissue_barycenter[1]); |
|
76 |
} |
|
77 |
tissue_target[0]/=boundary_vertices_number; |
|
78 |
tissue_target[1]/=boundary_vertices_number; |
|
79 |
|
|
80 |
parameters.tissue_target=tissue_target; |
|
81 |
parameters.anisotropy=1; |
|
82 |
pparameters=¶meters; |
|
83 |
|
|
84 |
reso=nlopt_set_min_objective(opt, compute_energy_and_forces, pparameters); |
|
85 |
nlopt_optimize(opt, vertices, &min_energy); |
|
86 |
nlopt_destroy(opt); |
|
87 |
|
|
88 |
} |
src/compute_barycenters.h (revision 3) | ||
---|---|---|
1 |
#ifndef COMPUTE_barycenters_H_INCLUDED |
|
2 |
#define COMPUTE_barycenters_H_INCLUDED |
|
3 |
|
|
4 |
void compute_barycenters(double *vertices, int vertices_number, int *cells_vertices, |
|
5 |
int *vertices_number_in_each_cell, int cell_number, double *barycenters); |
|
6 |
|
|
7 |
#endif // COMPUTE_barycenters_H_INCLUDED |
src/cell_division.cpp (revision 3) | ||
---|---|---|
1 |
#include <math.h> |
|
2 |
#include "cell_division.h" |
|
3 |
#include "constants.h" |
|
4 |
#include <stdio.h> |
|
5 |
#include <stdlib.h> |
|
6 |
#include <omp.h> |
|
7 |
|
|
8 |
/* this function: finds the division direction |
|
9 |
computes the position of the new vertices |
|
10 |
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 |
|
|
12 |
void cell_division(double *vertices, int vertices_number, int *cells_vertices, int *vertices_number_in_each_cell, int cell_number, |
|
13 |
double *barycenters, int dividing_cell, int *boundary, double *stress, double *shapes, |
|
14 |
int *adjacent_cells_number, int *adjacent_cell1, int *adjacent_cell2, int *daughter_cells_vertices_number, int *cell1, int *cell2, int *wall1, int *wall2){ |
|
15 |
|
|
16 |
///bias division |
|
17 |
//double width=3; double dilation=1.; |
|
18 |
|
|
19 |
|
|
20 |
int j; |
|
21 |
|
|
22 |
/* vector of the division line */ |
|
23 |
double division_direction[2]; |
|
24 |
/* positions of new vertices */ |
|
25 |
double new_vertex1[2]={0}; double new_vertex2[2]={0}; |
|
26 |
|
|
27 |
double eigenvalue=0; double norm; |
|
28 |
if (threshold_division>0.0){ /* probabilistic division: the probability to divide a cell following the vector n is proportionnal to |
|
29 |
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 |
double anisotropic_stress[2]; |
|
31 |
anisotropic_stress[0]=(0.5*stress[3*dividing_cell]-0.5*stress[3*dividing_cell+1])/threshold_division; |
|
32 |
anisotropic_stress[1]=0.5*stress[3*dividing_cell+2]/threshold_division; |
|
33 |
double probability[20]; |
|
34 |
for (int i=0;i<20;i++){ |
|
35 |
probability[i]=exp(cos(i*pi/19.0)*anisotropic_stress[0]+sin(i*pi/19.0)*anisotropic_stress[1]); |
|
36 |
if (probability[i]==HUGE_VAL){ printf("division_h\n"); goto division_highest_tension;} |
|
37 |
} |
|
38 |
probability[0]/=2.; probability[19]/=2.; |
|
39 |
for (int i=1;i<20;i++){probability[i]+=probability[i-1];} |
|
40 |
for (int i=0;i<20;i++){probability[i]/=probability[19];} |
|
41 |
double random=(double)rand()/(double)RAND_MAX; //printf("random %f\n",random); |
|
42 |
int random2=rand()%2; |
|
43 |
if (random<=probability[0]){ //printf("%i\n",0); |
|
44 |
division_direction[0]=1; |
|
45 |
division_direction[1]=0;} |
|
46 |
for (int i=1;i<20;i++){//printf("%f %f\n",probability[i-1],probability[i]); |
|
47 |
if (random<=probability[i] && random>probability[i-1]){ |
|
48 |
if(random2==0){//printf("%i %i\n",i,0); |
|
49 |
division_direction[0]=cos(i*0.5*pi/19.0); |
|
50 |
division_direction[1]=sin(i*0.5*pi/19.0);} |
|
51 |
if(random2==1){//printf("%i %i\n",i,1); |
|
52 |
division_direction[0]=cos(i*0.5*pi/19.0); |
|
53 |
division_direction[1]=-sin(i*0.5*pi/19.0);} |
|
54 |
} |
|
55 |
} |
|
56 |
} |
|
57 |
|
|
58 |
if (threshold_division==0.0){ /* division following the maximal stress = particular case of the previous rule */ |
|
59 |
division_highest_tension:; //printf("%f %d %d\n",stress[3*dividing_cell+2],dividing_cell,cell_number); |
|
60 |
if (stress[3*dividing_cell+2]!=0){ |
|
61 |
eigenvalue=(stress[3*dividing_cell]+stress[3*dividing_cell+1])/2.; |
|
62 |
eigenvalue+=0.5*sqrt((stress[3*dividing_cell]-stress[3*dividing_cell+1])*(stress[3*dividing_cell]-stress[3*dividing_cell+1])+ |
|
63 |
4.*stress[3*dividing_cell+2]*stress[3*dividing_cell+2]); |
|
64 |
division_direction[0]=stress[3*dividing_cell+2]; |
|
65 |
division_direction[1]=-stress[3*dividing_cell]+eigenvalue; |
|
66 |
norm=sqrt(division_direction[0]*division_direction[0]+division_direction[1]*division_direction[1]); |
|
67 |
division_direction[0]/=norm; |
|
68 |
division_direction[1]/=norm;} |
|
69 |
else if (stress[3*dividing_cell]>stress[3*dividing_cell+1]){ |
|
70 |
division_direction[0]=1; |
|
71 |
division_direction[1]=0;} |
|
72 |
else if (stress[3*dividing_cell]<stress[3*dividing_cell+1]){ |
|
73 |
division_direction[0]=0; |
|
74 |
division_direction[1]=1;} |
|
75 |
else if (stress[3*dividing_cell]==stress[3*dividing_cell+1]){ |
|
76 |
division_direction[0]=rand()/(double)RAND_MAX; |
|
77 |
division_direction[1]=sqrt(1.-division_direction[0]*division_direction[0]);} |
|
78 |
} |
|
79 |
|
|
80 |
double temp_shape[3]; |
|
81 |
temp_shape[0]=shapes[3*dividing_cell]; |
|
82 |
temp_shape[1]=shapes[3*dividing_cell+1]; |
|
83 |
temp_shape[2]=shapes[3*dividing_cell+2]; |
|
84 |
//if ((barycenters[2*dividing_cell]*barycenters[2*dividing_cell])<(width*width)){ temp_shape[0]*=dilation*dilation; temp_shape[2]*=dilation;} |
|
85 |
|
|
86 |
if (threshold_division<0.0){ /* geometrical rule: division following the shortest direction */ |
|
87 |
double shape_direction[2]; |
|
88 |
eigenvalue=(temp_shape[0]+temp_shape[1])/2.; |
|
89 |
eigenvalue+=0.5*sqrt((temp_shape[0]-temp_shape[1])*(temp_shape[0]-temp_shape[1])+ |
|
90 |
4.*temp_shape[2]*temp_shape[2]); |
|
91 |
shape_direction[0]=temp_shape[2]; |
|
92 |
shape_direction[1]=eigenvalue-temp_shape[0]; |
|
93 |
norm=sqrt(shape_direction[0]*shape_direction[0]+shape_direction[1]*shape_direction[1]); |
|
94 |
shape_direction[0]/=norm; |
|
95 |
shape_direction[1]/=norm; |
|
96 |
division_direction[0]=shape_direction[1]; |
|
97 |
division_direction[1]=-shape_direction[0]; |
|
98 |
} |
|
99 |
|
|
100 |
/* computation of the new vertices as the intersection between the walls of the cell and the division direction */ |
|
101 |
int l=0,m=0,max=vertices_number_in_each_cell[dividing_cell+1],min=vertices_number_in_each_cell[dividing_cell],previous; |
|
102 |
double test; |
|
103 |
|
|
104 |
|
|
105 |
for (int i=min;i<max;i++){ /* loop over the vertices of the dividing cell */ |
|
106 |
previous=i-1; if (i==min){previous=max-1;} |
|
107 |
test=-division_direction[1]*(vertices[2*cells_vertices[previous]]-barycenters[2*dividing_cell]); |
|
108 |
test+=division_direction[0]*(vertices[2*cells_vertices[previous]+1]-barycenters[2*dividing_cell+1]); |
|
109 |
test/=-division_direction[1]*(vertices[2*cells_vertices[previous]]-vertices[2*cells_vertices[i]])+ |
|
110 |
division_direction[0]*(vertices[2*cells_vertices[previous]+1]-vertices[2*cells_vertices[i]+1]); |
|
111 |
|
|
112 |
/* test if the considered point of the wall is on the division direction */ |
|
113 |
if ((test<1. && test>=0.) && (m==0 || m==1) && l<2){ |
|
114 |
//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 |
l++; |
|
116 |
if (l==1){ |
|
117 |
new_vertex1[0]=test*(vertices[2*cells_vertices[i]]-vertices[2*cells_vertices[previous]])+vertices[2*cells_vertices[previous]]; |
|
118 |
new_vertex1[1]=test*(vertices[2*cells_vertices[i]+1]-vertices[2*cells_vertices[previous]+1])+vertices[2*cells_vertices[previous]+1]; |
|
119 |
cell1[daughter_cells_vertices_number[0]]=vertices_number-2; daughter_cells_vertices_number[0]+=1; |
|
120 |
cell2[daughter_cells_vertices_number[1]]=vertices_number-2; daughter_cells_vertices_number[1]+=1; |
|
121 |
wall1[0]=cells_vertices[i]; |
|
122 |
wall1[1]=cells_vertices[previous];} |
|
123 |
if (l==2){ |
|
124 |
new_vertex2[0]=test*(vertices[2*cells_vertices[i]]-vertices[2*cells_vertices[previous]])+vertices[2*cells_vertices[previous]]; |
|
125 |
new_vertex2[1]=test*(vertices[2*cells_vertices[i]+1]-vertices[2*cells_vertices[previous]+1])+vertices[2*cells_vertices[previous]+1]; |
|
126 |
cell1[daughter_cells_vertices_number[0]]=vertices_number-1; daughter_cells_vertices_number[0]+=1; |
|
127 |
cell2[daughter_cells_vertices_number[1]]=vertices_number-1; daughter_cells_vertices_number[1]+=1; |
|
128 |
wall2[0]=cells_vertices[i]; |
|
129 |
wall2[1]=cells_vertices[previous];} |
|
130 |
m=2; |
|
131 |
} |
|
132 |
|
|
133 |
else if ((test<1. && test>=0.) && (m==0 || m==2) && l<2){ |
|
134 |
//if (test>0.9){test=0.9;} if (test<0.1){test=0.1;} |
|
135 |
l++; |
|
136 |
if (l==1){ |
|
137 |
new_vertex1[0]=test*(vertices[2*cells_vertices[i]]-vertices[2*cells_vertices[previous]])+vertices[2*cells_vertices[previous]]; |
|
138 |
new_vertex1[1]=test*(vertices[2*cells_vertices[i]+1]-vertices[2*cells_vertices[previous]+1])+vertices[2*cells_vertices[previous]+1]; |
|
139 |
cell1[daughter_cells_vertices_number[0]]=vertices_number-2; daughter_cells_vertices_number[0]+=1; |
|
140 |
cell2[daughter_cells_vertices_number[1]]=vertices_number-2; daughter_cells_vertices_number[1]+=1; |
|
141 |
wall1[0]=cells_vertices[i]; |
|
142 |
wall1[1]=cells_vertices[previous];} |
|
143 |
if (l==2){ |
|
144 |
new_vertex2[0]=test*(vertices[2*cells_vertices[i]]-vertices[2*cells_vertices[previous]])+vertices[2*cells_vertices[previous]]; |
|
145 |
new_vertex2[1]=test*(vertices[2*cells_vertices[i]+1]-vertices[2*cells_vertices[previous]+1])+vertices[2*cells_vertices[previous]+1]; |
|
146 |
cell1[daughter_cells_vertices_number[0]]=vertices_number-1; daughter_cells_vertices_number[0]+=1; |
|
147 |
cell2[daughter_cells_vertices_number[1]]=vertices_number-1; daughter_cells_vertices_number[1]+=1; |
|
148 |
wall2[0]=cells_vertices[i]; |
|
149 |
wall2[1]=cells_vertices[previous];} |
|
150 |
m=1; |
|
151 |
} |
|
152 |
|
|
153 |
/* write the old vertices in the two daughter cells */ |
|
154 |
if (l==0 || l==2){cell1[daughter_cells_vertices_number[0]]=cells_vertices[i]; daughter_cells_vertices_number[0]+=1;} |
|
155 |
if (l==1){cell2[daughter_cells_vertices_number[1]]=cells_vertices[i]; daughter_cells_vertices_number[1]+=1;} |
|
156 |
} |
|
157 |
|
|
158 |
/* if l<2, there has been a problem in the computation of the new vertices */ |
|
159 |
if (l!=2){printf("\n"); printf("division de %d ok,recherche des voisines\n",dividing_cell); exit(EXIT_FAILURE);} |
|
160 |
|
|
161 |
/* the new vertices are saved in the list "vertices" */ |
|
162 |
vertices[2*(vertices_number-2)]=new_vertex1[0]; vertices[2*(vertices_number-2)+1]=new_vertex1[1]; |
|
163 |
vertices[2*(vertices_number-1)]=new_vertex2[0]; vertices[2*(vertices_number-1)+1]=new_vertex2[1]; |
|
164 |
|
|
165 |
/* find the cells which are adjacent to the dividing one and have to be modified to include the new vertices */ |
|
166 |
adjacent_cell1[0]=-1; adjacent_cell2[0]=-1; adjacent_cells_number[0]=0; |
|
167 |
for (int i=0;i<cell_number-1;i++){ if (i==dividing_cell){goto nextcell;} |
|
168 |
min=vertices_number_in_each_cell[i]; max=vertices_number_in_each_cell[i+1]; previous=max-min-1; |
|
169 |
for (j=0;j<max-min;j++){ |
|
170 |
if ((cells_vertices[min+j]==wall1[1] && cells_vertices[min+previous]==wall1[0]) |
|
171 |
||(cells_vertices[min+j]==wall2[1] && cells_vertices[min+previous]==wall2[0]) |
|
172 |
){ |
|
173 |
|
|
174 |
if (adjacent_cells_number[0]==0){adjacent_cell1[0]=i;} |
|
175 |
if (adjacent_cells_number[0]==1){adjacent_cell2[0]=i;} |
|
176 |
adjacent_cells_number[0]+=1; goto nextcell; |
|
177 |
} |
|
178 |
previous=j;} |
|
179 |
nextcell:; |
|
180 |
} |
|
181 |
//printf("%d voisines trouvee(s): %d %d\n",adjacent_cells_number[0],adjacent_cell1[0],adjacent_cell2[0]); |
|
182 |
} |
src/growth_and_chemistry.cpp (revision 3) | ||
---|---|---|
1 |
#include "constants.h" |
|
2 |
#include "growth_and_chemistry.h" |
|
3 |
#include <gsl/gsl_errno.h> |
|
4 |
#include <math.h> |
|
5 |
#include <algorithm> |
|
6 |
#include <gsl/gsl_matrix.h> |
|
7 |
#include <gsl/gsl_blas.h> |
|
8 |
#include <gsl/gsl_eigen.h> |
|
9 |
#include <gsl/gsl_math.h> |
|
10 |
#include <gsl/gsl_cblas.h> |
|
11 |
|
|
12 |
/* this function computes the equations of chemistry and growth */ |
|
13 |
|
|
14 |
int growth_and_chemistry(double t, const double x[], double dx[], void *parameters){ |
|
15 |
|
|
16 |
struct parameters_list2 {int cell_number; int *cells_vertices; int *vertices_number_in_each_cell; double *shapes; double *lengths; double *cell_areas; double *barycenters; |
|
17 |
int *cell_walls; int wall_number; int *boundary; int *wall_vertices; double *vertices; double *growth_rate; double *noise;}; |
|
18 |
|
|
19 |
/* diagonalize the deformation tensor in order to compute growth */ |
|
20 |
double delta_shapes[3*(((parameters_list2*)parameters)->cell_number)]; |
|
21 |
for (int i=0; i<(((parameters_list2*)parameters)->cell_number);i++){ |
|
22 |
gsl_matrix *gsl_delta_shapes=gsl_matrix_calloc(2,2); |
|
23 |
|
|
24 |
gsl_matrix_set(gsl_delta_shapes,0,0,(((parameters_list2*)parameters)->shapes)[3*i]-x[3*i]); gsl_matrix_set(gsl_delta_shapes,1,1,(((parameters_list2*)parameters)->shapes)[3*i+1]-x[3*i+1]); |
|
25 |
gsl_matrix_set(gsl_delta_shapes,1,0,(((parameters_list2*)parameters)->shapes)[3*i+2]-x[3*i+2]); gsl_matrix_set(gsl_delta_shapes,0,1,(((parameters_list2*)parameters)->shapes)[3*i+2]-x[3*i+2]); |
|
26 |
|
|
27 |
gsl_eigen_symmv_workspace *workspace=gsl_eigen_symmv_alloc(2); gsl_vector *eigenvalues=gsl_vector_alloc(2); gsl_matrix *eigenvectors=gsl_matrix_alloc(2,2); gsl_eigen_symmv(gsl_delta_shapes,eigenvalues,eigenvectors,workspace); |
|
28 |
if (gsl_vector_get(eigenvalues,0)<0.){ gsl_vector_set(eigenvalues,0,0.);} |
|
29 |
if (gsl_vector_get(eigenvalues,1)<0.){ gsl_vector_set(eigenvalues,1,0.);} |
|
30 |
|
|
31 |
delta_shapes[3*i]=gsl_vector_get(eigenvalues,0)*gsl_matrix_get(eigenvectors,0,0)*gsl_matrix_get(eigenvectors,0,0)+gsl_vector_get(eigenvalues,1)*gsl_matrix_get(eigenvectors,0,1)*gsl_matrix_get(eigenvectors,0,1); |
|
32 |
delta_shapes[3*i+1]=gsl_vector_get(eigenvalues,0)*gsl_matrix_get(eigenvectors,1,0)*gsl_matrix_get(eigenvectors,1,0)+gsl_vector_get(eigenvalues,1)*gsl_matrix_get(eigenvectors,1,1)*gsl_matrix_get(eigenvectors,1,1); |
|
33 |
delta_shapes[3*i+2]=gsl_vector_get(eigenvalues,0)*gsl_matrix_get(eigenvectors,0,0)*gsl_matrix_get(eigenvectors,1,0)+gsl_vector_get(eigenvalues,1)*gsl_matrix_get(eigenvectors,0,1)*gsl_matrix_get(eigenvectors,1,1); |
|
34 |
|
|
35 |
gsl_vector_free(eigenvalues); gsl_matrix_free(eigenvectors); gsl_matrix_free(gsl_delta_shapes); gsl_eigen_symmv_free(workspace); |
|
36 |
} |
|
37 |
|
|
38 |
/* computation of the growth rate: |
|
39 |
the growth rate of periclinal walls is directly given by the list "growth_rate", and here we add the noise |
|
40 |
the growth of anticlinal walls is the average of the growth of the two neighbouring periclinal walls */ |
|
41 |
double cell_growth[(((parameters_list2*)parameters)->cell_number)]; |
|
42 |
double wall_growth[(((parameters_list2*)parameters)->wall_number)]; |
|
43 |
for (int i=0;i<(((parameters_list2*)parameters)->wall_number);i++){ |
|
44 |
wall_growth[i]=0.; |
|
45 |
} |
|
46 |
for (int i=0;i<(((parameters_list2*)parameters)->cell_number);i++){ |
|
47 |
//cell_growth[i]=1.; |
|
48 |
/* with noise */ |
|
49 |
cell_growth[i]=(((parameters_list2*)parameters)->growth_rate)[i]*(((parameters_list2*)parameters)->noise)[i]; |
|
50 |
for (int j=(((parameters_list2*)parameters)->vertices_number_in_each_cell)[i];j<(((parameters_list2*)parameters)->vertices_number_in_each_cell)[i+1];j++){ |
|
51 |
wall_growth[(((parameters_list2*)parameters)->cell_walls)[j]]+=0.5*cell_growth[i]*(((parameters_list2*)parameters)->noise)[i]; |
|
52 |
if ((((parameters_list2*)parameters)->boundary)[j]==1){wall_growth[(((parameters_list2*)parameters)->cell_walls)[j]]*=2.;} |
|
53 |
} |
|
54 |
} |
|
55 |
|
|
56 |
/* growth of the periclinal walls, proportionnal to the deformation, with possiblity to set negative growth, corresponding to compression, to zero |
|
57 |
this was not used in the end since it made no difference */ |
|
58 |
for (int i=0;i<(((parameters_list2*)parameters)->cell_number);i++){ |
|
59 |
dx[3*i]=cell_growth[i]*(1./(tau1*(((parameters_list2*)parameters)->cell_number)))* |
|
60 |
//std::max(0.,(((parameters_list2*)parameters)->shapes)[3*i]-x[3*i]); |
|
61 |
//(((parameters_list2*)parameters)->shapes)[3*i]-x[3*i]; |
|
62 |
delta_shapes[3*i]; |
|
63 |
dx[3*i+1]=cell_growth[i]*(1./(tau1*(((parameters_list2*)parameters)->cell_number)))* |
|
64 |
// std::max(0.,(((parameters_list2*)parameters)->shapes)[3*i+1]-x[3*i+1]); |
|
65 |
// (((parameters_list2*)parameters)->shapes)[3*i+1]-x[3*i+1]; |
|
66 |
delta_shapes[3*i+1]; |
|
67 |
dx[3*i+2]=cell_growth[i]*(1./(tau1*(((parameters_list2*)parameters)->cell_number)))* |
|
68 |
// std::max(0.,(((parameters_list2*)parameters)->shapes)[3*i+2]-x[3*i+2]); |
|
69 |
// (((parameters_list2*)parameters)->shapes)[3*i+2]-x[3*i+2]; |
|
70 |
delta_shapes[3*i+2]; |
|
71 |
} |
|
72 |
|
|
73 |
/* growth of the anticlinal walls */ |
|
74 |
for (int i=0;i<(((parameters_list2*)parameters)->wall_number);i++){ |
|
75 |
dx[3*(((parameters_list2*)parameters)->cell_number)+i]=wall_growth[i]*(1./(tau1*(((parameters_list2*)parameters)->cell_number)))* |
|
76 |
std::max((((parameters_list2*)parameters)->lengths)[i]-x[3*(((parameters_list2*)parameters)->cell_number)+i],0.); |
|
77 |
} |
|
78 |
|
|
79 |
return GSL_SUCCESS; |
|
80 |
} |
src/main.cpp (revision 3) | ||
---|---|---|
1 |
di#include <iostream> |
|
2 |
#include <string> |
|
3 |
#include <stdlib.h> |
|
4 |
#include <stdio.h> |
|
5 |
#include <time.h> |
|
6 |
#include "initialize.h" |
|
7 |
#include "step.h" |
|
8 |
#include "constants.h" |
|
9 |
#include "cell_division.h" |
|
10 |
#include "cell_division2.h" |
|
11 |
#include <math.h> |
|
12 |
#include "load_initial_state.h" |
|
13 |
#include <fstream> |
|
14 |
#include "compute_barycenters.h" |
|
15 |
#include "compute_areas.h" |
|
16 |
#include "compute_cell_areas.h" |
|
17 |
#include "compute_shapes.h" |
|
18 |
#include "compute_stress_periclinal.h" |
|
19 |
#include "compute_stress_anticlinal.h" |
|
20 |
#include "find_boundary_walls.h" |
|
21 |
#include "minimize_BFGS.h" |
|
22 |
#include <omp.h> |
|
23 |
#include "compute_cell_areas.h" |
|
24 |
#include "compute_shapes.h" |
|
25 |
#include "compute_wall_vertices.h" |
|
26 |
#include "compute_cell_walls.h" |
|
27 |
#include <dirent.h> |
|
28 |
#include "save_data.h" |
|
29 |
#include <cmath> |
|
30 |
#include "compute_lengths.h" |
|
31 |
|
|
32 |
using namespace std; |
|
33 |
|
|
34 |
int main(){ |
|
35 |
|
|
36 |
omp_set_dynamic(0); |
|
37 |
|
|
38 |
srand(time(NULL)); |
|
39 |
double global_barycenter[2]; |
|
40 |
int init_vertices_number,init_cell_number,cumulated_vertices_number,init_wall_number; |
|
41 |
|
|
42 |
// Pick the initial conditions, obtained from previous simulations |
|
43 |
//init_cell_number=5; init_vertices_number=8; cumulated_vertices_number=20; |
|
44 |
//const char* file_name="init/5_8_20.txt"; |
|
45 |
init_cell_number=101; init_vertices_number=200; cumulated_vertices_number=567; |
|
46 |
const char* file_name="init/101_200_567.txt"; |
|
47 |
//init_cell_number=300; init_vertices_number=598; cumulated_vertices_number=1736; |
|
48 |
//const char* file_name="init/300_598_1736.txt"; |
|
49 |
//init_cell_number=100; init_vertices_number=200; cumulated_vertices_number=561; |
|
50 |
//const char* file_name="init/100_200_ablation.txt"; |
|
51 |
float * init_vertices; init_vertices=(float*)calloc(2*init_vertices_number,sizeof(float)); |
|
52 |
int * init_vertices_number_in_each_cell; init_vertices_number_in_each_cell=(int*)calloc(init_cell_number+1,sizeof(int)); |
|
53 |
int * init_cells_vertices; init_cells_vertices=(int*)calloc(cumulated_vertices_number,sizeof(int)); |
|
54 |
load_initial_state(file_name, init_cell_number, init_vertices_number, init_vertices, init_vertices_number_in_each_cell, init_cells_vertices); |
|
55 |
// initial tissue loaded |
|
56 |
|
|
57 |
/* center the tissue */ |
|
58 |
global_barycenter[1]=0; global_barycenter[2]=0; |
|
59 |
//#pragma omp parallel shared(global_barycenter, init_vertices, init_vertices_number) |
|
60 |
//{ |
|
61 |
//#pragma omp for |
|
62 |
for (int i=0;i<init_vertices_number;i++){global_barycenter[1]+=init_vertices[2*i]/init_vertices_number; |
|
63 |
global_barycenter[2]+=init_vertices[2*i+1]/init_vertices_number;} |
|
64 |
//#pragma omp for |
|
65 |
for (int i=0;i<init_vertices_number;i++){init_vertices[2*i]-=global_barycenter[1]; |
|
66 |
init_vertices[2*i+1]-=global_barycenter[2];} |
|
67 |
//} |
|
68 |
// tissue centered |
|
69 |
|
|
70 |
/* find the walls which are on the boundary of the tissue */ |
|
71 |
int* init_boundary; init_boundary=(int*)calloc(init_vertices_number_in_each_cell[init_cell_number],sizeof(int)); |
|
72 |
find_boundary_walls(init_cells_vertices, init_vertices_number_in_each_cell, init_cell_number, init_boundary, &init_wall_number); |
|
73 |
int * init_wall_vertices; init_wall_vertices=(int*)calloc(2*init_wall_number,sizeof(int)); |
|
74 |
compute_wall_vertices( init_cells_vertices, init_vertices_number_in_each_cell, init_cell_number, init_wall_vertices); |
|
75 |
// boundary identified |
|
76 |
|
|
77 |
// define the parameters over witch there is a loop |
|
78 |
// threshold=0 -> division following the highest tension |
|
79 |
// threshold<0 -> division following the shortest axis of the cell |
|
80 |
|
|
81 |
// initialize the files where the data will be saved. Yes that's a lot of them |
|
82 |
|
|
83 |
// for (int m=7; m<=7; m++){ |
|
84 |
// FILE *f=NULL; char file_name[256]; |
|
85 |
// sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_boundary.txt",1.-((double)m)*0.1); |
|
86 |
// f=fopen(file_name,"a+"); |
|
87 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
88 |
// fclose(f); |
|
89 |
// } |
|
90 |
// for (int m=7; m<=7; m++){ |
|
91 |
// FILE *f=NULL; char file_name[256]; |
|
92 |
// sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_meristem.txt",1.-((double)m)*0.1); |
|
93 |
// f=fopen(file_name,"a+"); |
|
94 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
95 |
// fclose(f); |
|
96 |
// } |
|
97 |
// for (int m=7; m<=7; m++){ |
|
98 |
// FILE *f=NULL; char file_name[256]; |
|
99 |
// sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_boundary.txt",1.-((double)m)*0.1); |
|
100 |
// f=fopen(file_name,"a+"); |
|
101 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
102 |
// fclose(f); |
|
103 |
// } |
|
104 |
// for (int m=7; m<=7; m++){ |
|
105 |
// FILE *f=NULL; char file_name[256]; |
|
106 |
// sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_meristem.txt",1.-((double)m)*0.1); |
|
107 |
// f=fopen(file_name,"a+"); |
|
108 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
109 |
// fclose(f); |
|
110 |
// } |
|
111 |
// for (int m=7; m<=7; m++){ |
|
112 |
// FILE *f=NULL; char file_name[256]; |
|
113 |
// sprintf(file_name,"results_v7/boundary_curvature/stress_%1.1f.txt",1.-((double)m)*0.1); |
|
114 |
// f=fopen(file_name,"a+"); |
|
115 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
116 |
// fclose(f); |
|
117 |
// } |
|
118 |
// for (int m=7; m<=7; m++){ |
|
119 |
// FILE *f=NULL; char file_name[256]; |
|
120 |
// sprintf(file_name,"results_v7/boundary_curvature/shape_%1.1f.txt",1.-((double)m)*0.1); |
|
121 |
// f=fopen(file_name,"a+"); |
|
122 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
123 |
// fclose(f); |
|
124 |
// } |
|
125 |
// for (int m=7; m<=7; m++){ |
|
126 |
// FILE *f=NULL; char file_name[256]; |
|
127 |
// sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_boundary_filter.txt",1.-((double)m)*0.1); |
|
128 |
// f=fopen(file_name,"a+"); |
|
129 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
130 |
// fclose(f); |
|
131 |
// } |
|
132 |
// for (int m=7; m<=7; m++){ |
|
133 |
// FILE *f=NULL; char file_name[256]; |
|
134 |
// sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_meristem_filter.txt",1.-((double)m)*0.1); |
|
135 |
// f=fopen(file_name,"a+"); |
|
136 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
137 |
// fclose(f); |
|
138 |
// } |
|
139 |
// for (int m=7; m<=7; m++){ |
|
140 |
// FILE *f=NULL; char file_name[256]; |
|
141 |
// sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_boundary_filter.txt",1.-((double)m)*0.1); |
|
142 |
// f=fopen(file_name,"a+"); |
|
143 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
144 |
// fclose(f); |
|
145 |
// } |
|
146 |
// for (int m=7; m<=7; m++){ |
|
147 |
// FILE *f=NULL; char file_name[256]; |
|
148 |
// sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_meristem_filter.txt",1.-((double)m)*0.1); |
|
149 |
// f=fopen(file_name,"a+"); |
|
150 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
151 |
// fclose(f); |
|
152 |
// } |
|
153 |
// for (int m=7; m<=7; m++){ |
|
154 |
// FILE *f=NULL; char file_name[256]; |
|
155 |
// sprintf(file_name,"results_v7/boundary_curvature/stress_%1.1f_filter.txt",1.-((double)m)*0.1); |
|
156 |
// f=fopen(file_name,"a+"); |
|
157 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
158 |
// fclose(f); |
|
159 |
// } |
|
160 |
// for (int m=7; m<=7; m++){ |
|
161 |
// FILE *f=NULL; char file_name[256]; |
|
162 |
// sprintf(file_name,"results_v7/boundary_curvature/shape_%1.1f_filter.txt",1.-((double)m)*0.1); |
|
163 |
// f=fopen(file_name,"a+"); |
|
164 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
165 |
// fclose(f); |
|
166 |
// } |
|
167 |
|
|
168 |
// for (int m=5; m<=10; m++){ |
|
169 |
// FILE *f=NULL; char file_name[256]; |
|
170 |
// sprintf(file_name,"results_v7/pressure/stress_%1.1f.txt",1.+((double)m)*0.1); |
|
171 |
// f=fopen(file_name,"a+"); |
|
172 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
173 |
// fclose(f); |
|
174 |
// } |
|
175 |
// for (int m=5; m<=10; m++){ |
|
176 |
// FILE *f=NULL; char file_name[256]; |
|
177 |
// sprintf(file_name,"results_v7/pressure/shape_%1.1f.txt",1.+((double)m)*0.1); |
|
178 |
// f=fopen(file_name,"a+"); |
|
179 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
180 |
// fclose(f); |
|
181 |
// } |
|
182 |
// for (int m=5; m<=10; m++){ |
|
183 |
// FILE *f=NULL; char file_name[256]; |
|
184 |
// sprintf(file_name,"results_v7/pressure/stress_%1.1f_filter.txt",1.+((double)m)*0.1); |
|
185 |
// f=fopen(file_name,"a+"); |
|
186 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
187 |
// fclose(f); |
|
188 |
// } |
|
189 |
// for (int m=5; m<=10; m++){ |
|
190 |
// FILE *f=NULL; char file_name[256]; |
|
191 |
// sprintf(file_name,"results_v7/pressure/shape_%1.1f_filter.txt",1.+((double)m)*0.1); |
|
192 |
// f=fopen(file_name,"a+"); |
|
193 |
// fprintf(f,"mother vertex daughter x y z\n"); |
|
194 |
// fclose(f); |
|
195 |
// } |
|
196 |
|
|
197 |
for (int m=0; m<=0; m++){ |
|
198 |
FILE *f=NULL; char file_name[256]; |
|
199 |
sprintf(file_name,"results_v7/isotropic_2/stress.txt"); |
|
200 |
f=fopen(file_name,"a+"); |
|
201 |
fprintf(f,"mother vertex daughter x y z\n"); |
|
202 |
fclose(f); |
|
203 |
} |
|
204 |
for (int m=0; m<=0; m++){ |
|
205 |
FILE *f=NULL; char file_name[256]; |
|
206 |
sprintf(file_name,"results_v7/isotropic_2/shape.txt"); |
|
207 |
f=fopen(file_name,"a+"); |
|
208 |
fprintf(f,"mother vertex daughter x y z\n"); |
|
209 |
fclose(f); |
|
210 |
} |
|
211 |
for (int m=0; m<=0; m++){ |
|
212 |
FILE *f=NULL; char file_name[256]; |
|
213 |
sprintf(file_name,"results_v7/isotropic_2/stress_filter.txt"); |
|
214 |
f=fopen(file_name,"a+"); |
|
215 |
fprintf(f,"mother vertex daughter x y z\n"); |
|
216 |
fclose(f); |
|
217 |
} |
|
218 |
for (int m=0; m<=0; m++){ |
|
219 |
FILE *f=NULL; char file_name[256]; |
|
220 |
sprintf(file_name,"results_v7/isotropic_2/shape_filter.txt"); |
|
221 |
f=fopen(file_name,"a+"); |
|
222 |
fprintf(f,"mother vertex daughter x y z\n"); |
|
223 |
fclose(f); |
|
224 |
} |
|
225 |
// |
|
226 |
|
|
227 |
|
|
228 |
// parallel loop over the parameters |
|
229 |
#pragma omp parallel for schedule(dynamic,1) collapse(3) |
|
230 |
for (int meristem=0; meristem<=19; meristem++){ // several meristem, just the initial conditions are different |
|
231 |
for (int anisotropy=0; anisotropy<=0; anisotropy++){ // amplitude of the stress anisotropy |
|
232 |
//for (int stress_source=1; stress_source<=1; stress_source++){ // origin of the stress: 0=growth, 1=curvature |
|
233 |
for (int rule=-1; rule<=0; rule++){ |
|
234 |
|
|
235 |
|
|
236 |
ablated_cell=-1; // -1=no ablation, any other number n = the cell number n is killed |
|
237 |
|
|
238 |
iteration=0; |
|
239 |
|
|
240 |
threshold_division=(double)rule; // rule used for the cell division |
|
241 |
// negative number = cell divided along the short axis |
|
242 |
// 0 = cell divided along the maximal stress |
|
243 |
// positive number = probabilistic rule based on the mdeviatoric stress |
|
244 |
|
|
245 |
// define the stress anisotropy |
|
246 |
// if (stress_source==0){ // anisotropy comes from growth |
|
247 |
// growth_differential=0.999999-((double)anisotropy)*0.1; |
|
248 |
// first_shape_derived_stress=3.e-2; |
|
249 |
// second_shape_derived_stress=3.e-2; |
|
250 |
// } |
|
251 |
// if (stress_source==1){ // anisotropy comes from curvature |
|
252 |
// growth_differential=0.999999; |
|
253 |
// first_shape_derived_stress=3.e-2; |
|
254 |
// second_shape_derived_stress=(3.e-2)*(1.-((double)anisotropy)*0.1); |
|
255 |
// } |
|
256 |
|
|
257 |
|
|
258 |
/* allocation of memory */ |
|
259 |
int vertices_number=init_vertices_number; |
|
260 |
int cell_number=init_cell_number; |
|
261 |
int wall_number=init_wall_number; |
|
262 |
int i; |
|
263 |
double * vertices; vertices=(double*)calloc(2*vertices_number,sizeof(double)); /* coordinates of the vertices */ |
|
264 |
for (i=0;i<2*vertices_number;i++){vertices[i]=(double)init_vertices[i];} |
|
265 |
double r; double theta; |
|
266 |
for (i=0;i<vertices_number;i++){r=0.3*(double)(rand())/(double)RAND_MAX; theta=2.*pi*(double)(rand())/(double)RAND_MAX; |
|
267 |
vertices[2*i]+=r*cos(theta); vertices[2*i+1]+=r*sin(theta); |
|
268 |
} |
|
269 |
int * vertices_number_in_each_cell; vertices_number_in_each_cell=(int*)calloc(cell_number+1,sizeof(int)); /* list of the number of vertices in each cell */ |
|
270 |
for (i=0;i<cell_number+1;i++){vertices_number_in_each_cell[i]=init_vertices_number_in_each_cell[i];} |
|
271 |
int * cells_vertices; cells_vertices=(int*)calloc(vertices_number_in_each_cell[cell_number],sizeof(int)); /* list of the vertices of each cell, cell-per-cell */ |
|
272 |
for (i=0;i<vertices_number_in_each_cell[cell_number];i++){cells_vertices[i]=init_cells_vertices[i];} |
|
273 |
int * wall_vertices; wall_vertices=(int*)calloc(2*wall_number,sizeof(int)); /* list of the vertices of all the walls, wall-per-wall */ |
|
274 |
for (i=0;i<2*wall_number;i++){wall_vertices[i]=init_wall_vertices[i];} |
|
275 |
double * lengths; lengths=(double*)calloc(wall_number,sizeof(double)); /* lengths of the anticlinal walls */ |
|
276 |
double * target_lengths; target_lengths=(double*)calloc(wall_number,sizeof(double)); /* target lengths of the anticlinal walls */ |
|
277 |
int * cell_walls; cell_walls=(int*)calloc(vertices_number_in_each_cell[cell_number],sizeof(int)); /* list of the wall of all the cells, cell-per-cell |
|
278 |
double * barycenters; barycenters=(double*)calloc(cell_number*2,sizeof(double)); /* positions of centers of cells */ |
|
279 |
double * shapes; shapes=(double*)calloc(cell_number*3,sizeof(double)); /* shapes of cells */ |
|
280 |
double * targets; targets=(double*)calloc(cell_number*3,sizeof(double)); /* targets of cells */ |
|
281 |
double * areas; areas=(double*)calloc(vertices_number_in_each_cell[cell_number],sizeof(double)); /* areas of all the triangles between two vertices and the barycenter */ |
|
282 |
double * cell_areas; cell_areas=(double*)calloc(cell_number, sizeof(double)); /* areas of cells */ |
|
283 |
double * forces; forces=(double*)calloc(2*vertices_number, sizeof(double)); /* forces on vertices */ |
|
284 |
double * stress_periclinal; stress_periclinal=(double*)calloc(3*cell_number, sizeof(double)); /* stress on the in-the-plane walls */ |
|
285 |
double * stress_anticlinal; stress_anticlinal=(double*)calloc(3*wall_number, sizeof(double)); /* stress on the out-the-plane walls */ |
|
286 |
int * boundary; boundary=(int*)calloc(vertices_number_in_each_cell[cell_number],sizeof(int)); /* indicates if a wall belongs to the boundary of the tissue */ |
|
287 |
for (i=0;i<vertices_number_in_each_cell[cell_number];i++){boundary[i]=init_boundary[i];} |
|
288 |
double * growth_rate; growth_rate=(double*)calloc(cell_number,sizeof(double)); /* list of the growth rate of each cell*/ |
|
289 |
int * border; border=(int*)calloc(cell_number,sizeof(int)); /* indicates if a cell belongs to the boundary of the tissue */ |
|
290 |
for (i=0; i<cell_number;i++){ growth_rate[i]=1.; border[i]=0; |
|
291 |
for (int j=vertices_number_in_each_cell[i]; j<vertices_number_in_each_cell[i+1];j++){ |
|
292 |
if (boundary[j]==1.){ growth_rate[i]=growth_differential; border[i]=1; } |
|
293 |
} |
|
294 |
} |
|
295 |
double * relative_pressure; relative_pressure=(double*)calloc(cell_number,sizeof(double)); /* llist of the pressure in each cell */ |
|
296 |
for (int i=0; i<cell_number; i++){ relative_pressure[i]=1.;} |
|
297 |
|
|
298 |
/* from the vertices, initialize the program by calculating everything that has to be so: lengths, areas, stresses, ... */ |
|
299 |
initialize(vertices,vertices_number,cells_vertices,vertices_number_in_each_cell,cell_number, wall_vertices, wall_number, cell_walls, |
|
300 |
barycenters,shapes,targets,lengths,target_lengths,areas,cell_areas,forces,stress_periclinal, stress_anticlinal); |
|
301 |
|
|
302 |
/* loop until the tissue reaches the limit size */ |
|
303 |
int check_division; int total_cell_number=1; |
|
304 |
while (cell_number<max_cell_number /*&& iteration<step_number*/){check_division=0; |
|
305 |
//while (iteration<step_number || ablated_cell==-1){check_division=0; |
|
306 |
|
|
307 |
compute_barycenters(vertices, vertices_number, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters); |
|
308 |
compute_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas); |
|
309 |
compute_cell_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas, cell_areas); |
|
310 |
compute_shapes(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters, shapes); |
|
311 |
/* one step of energy minimization and growth */ |
|
312 |
step(vertices, vertices_number, cells_vertices, vertices_number_in_each_cell, cell_number, wall_vertices, wall_number, cell_walls, |
|
313 |
barycenters, shapes, targets, lengths, target_lengths, areas, cell_areas, forces, stress_periclinal, stress_anticlinal, |
|
314 |
boundary, growth_rate, relative_pressure); |
|
315 |
|
|
316 |
/* compute the stress in the pericinal walls if it is necesssary for the divisions */ |
|
317 |
if (threshold_division>=0.){ |
|
318 |
for (i=0; i<cell_number;i++){ |
|
319 |
compute_stress_periclinal(i, vertices, vertices_number_in_each_cell, cell_number, stress_periclinal, shapes, targets, cell_areas, wall_vertices, cell_walls, lengths, target_lengths); |
|
320 |
} |
|
321 |
} |
|
322 |
|
|
323 |
/* check if division is required, i.e. if a cell is too big */ |
|
324 |
for (i=0;i<cell_number;i++){ |
|
325 |
if (cell_areas[i]>threshold_area && i!=ablated_cell){check_division=1; int save_cell=1; /*if (stress_source==1){ */save_cell=1-border[i];//} |
|
326 |
|
|
327 |
|
|
328 |
/* test: increase the pressure in the cell just before division, see how it modifies the divisions */ |
|
329 |
relative_pressure[i]=1.+(double)anisotropy*0.1;//} |
|
330 |
minimize_BFGS(vertices_number, cell_number, vertices, cells_vertices, vertices_number_in_each_cell, barycenters, shapes, targets, areas, cell_areas, wall_vertices, wall_number, lengths, target_lengths, boundary,relative_pressure); |
|
331 |
compute_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas); |
|
332 |
compute_cell_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas, cell_areas); //printf("step2\n");int bug[1]={0}; |
|
333 |
compute_barycenters(vertices, vertices_number, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters); |
|
334 |
compute_shapes(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters, shapes); |
|
335 |
compute_lengths(vertices, wall_vertices, wall_number, lengths); |
|
336 |
for (int k=0; k<cell_number;k++){ |
|
337 |
compute_stress_periclinal(k, vertices, vertices_number_in_each_cell, cell_number, stress_periclinal, shapes, targets, cell_areas, wall_vertices, cell_walls, lengths, target_lengths); |
|
338 |
} |
|
339 |
relative_pressure[i]=1.; |
|
340 |
/* end of the test, pressure back to normal */ |
|
341 |
|
|
342 |
/* temporal variables to identify the neighbours of the dividing cell */ |
|
343 |
int adjacent_cells_number[1]; int adjacent_cell1[1]; int adjacent_cell2[1]; |
|
344 |
int daughter_cells_vertices_number[2]={0,0}; int cell1[10],cell2[10],wall1[2],wall2[2]; |
|
345 |
|
|
346 |
/* division, with reallocation of the memory */ |
|
347 |
cell_number+=1; vertices_number+=2; wall_number+=3; |
|
348 |
vertices=(double*)realloc(vertices, sizeof(double)*2*vertices_number); |
|
349 |
forces=(double*)realloc(forces, sizeof(double)*2*vertices_number); |
|
350 |
vertices_number_in_each_cell=(int*)realloc(vertices_number_in_each_cell, sizeof(int)*(cell_number+1)); |
|
351 |
barycenters=(double*)realloc(barycenters, sizeof(double)*2*cell_number); |
|
352 |
shapes=(double*)realloc(shapes, sizeof(double)*3*cell_number); |
|
353 |
targets=(double*)realloc(targets, sizeof(double)*3*cell_number); |
|
354 |
stress_periclinal=(double*)realloc(stress_periclinal, sizeof(double)*3*cell_number); |
|
355 |
stress_anticlinal=(double*)realloc(stress_anticlinal, sizeof(double)*3*wall_number); |
|
356 |
cell_areas=(double*)realloc(cell_areas, sizeof(double)*cell_number); |
|
357 |
growth_rate=(double*)realloc(growth_rate,sizeof(double)*cell_number); growth_rate[cell_number-1]=growth_rate[i]; |
|
358 |
border=(int*)realloc(border,sizeof(int)*cell_number); border[cell_number-1]=0; |
|
359 |
relative_pressure=(double*)realloc(relative_pressure,sizeof(double)*cell_number); relative_pressure[cell_number-1]=1.; |
|
360 |
|
|
361 |
/* find the direction of division and the position of the new vertices */ |
|
362 |
cell_division(vertices, vertices_number, cells_vertices, vertices_number_in_each_cell, cell_number, |
|
363 |
barycenters, i, boundary, stress_periclinal, shapes, |
|
364 |
adjacent_cells_number, adjacent_cell1, adjacent_cell2, daughter_cells_vertices_number, cell1, cell2, wall1, wall2); |
|
365 |
|
|
366 |
cells_vertices=(int*)realloc(cells_vertices, sizeof(int)*(vertices_number_in_each_cell[cell_number-1]+4+adjacent_cells_number[0])); |
|
367 |
wall_vertices=(int*)realloc(wall_vertices, sizeof(int)*2*wall_number); |
|
368 |
lengths=(double*)realloc(lengths, sizeof(double)*(wall_number)); |
|
369 |
target_lengths=(double*)realloc(target_lengths, sizeof(double)*(wall_number)); |
|
370 |
cell_walls=(int*)realloc(cell_walls, sizeof(int)*(vertices_number_in_each_cell[cell_number-1]+4+adjacent_cells_number[0])); |
|
371 |
areas=(double*)realloc(areas, sizeof(double)*(vertices_number_in_each_cell[cell_number-1]+4+adjacent_cells_number[0])); |
|
372 |
boundary=(int*)realloc(boundary, sizeof(int)*(vertices_number_in_each_cell[cell_number-1]+4+adjacent_cells_number[0])); |
|
373 |
|
|
374 |
/* actually performs the division based on the division identified above */ |
|
375 |
cell_division2(vertices, vertices_number, cells_vertices, vertices_number_in_each_cell, cell_number, wall_vertices, wall_number, |
|
376 |
barycenters, areas, cell_areas, lengths, target_lengths, shapes, targets, i, boundary, border, |
|
377 |
adjacent_cells_number[0], adjacent_cell1[0], adjacent_cell2[0], daughter_cells_vertices_number, cell1, cell2, wall1, wall2); |
|
378 |
|
|
379 |
/* update what is modified by the division */ |
|
380 |
compute_cell_walls(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, cell_walls, wall_vertices, wall_number); |
|
381 |
compute_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas); |
|
382 |
compute_cell_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas, cell_areas); |
|
383 |
compute_barycenters(vertices, vertices_number, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters); |
|
384 |
compute_shapes(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters, shapes); |
|
385 |
compute_lengths(vertices, wall_vertices, wall_number, lengths); |
|
386 |
|
|
387 |
|
|
388 |
/* minimize the energy after division */ |
|
389 |
minimize_BFGS(vertices_number, cell_number, vertices, cells_vertices, vertices_number_in_each_cell, barycenters, shapes, targets, areas, cell_areas, wall_vertices, wall_number, lengths, target_lengths, boundary,relative_pressure); |
|
390 |
compute_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas); |
|
391 |
compute_cell_areas(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, areas, cell_areas); |
|
392 |
compute_barycenters(vertices, vertices_number, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters); |
|
393 |
compute_shapes(vertices, cells_vertices, vertices_number_in_each_cell, cell_number, barycenters, shapes); |
|
394 |
compute_lengths(vertices, wall_vertices, wall_number, lengths); |
|
395 |
|
|
396 |
|
|
397 |
/* save the history of the divisions, used as by Marion in her statistical analysis */ |
|
398 |
#pragma omp critical |
|
399 |
{ |
|
400 |
if (save_cell==1){ |
|
401 |
FILE *f=NULL; char file_name[256]; |
|
402 |
|
|
403 |
/*if (stress_source==1){ |
|
404 |
if (rule==-1){ |
|
405 |
sprintf(file_name,"results_v7/boundary_curvature/shape_%1.1f.txt",1.-((double)anisotropy)*0.1); |
|
406 |
} |
|
407 |
if (rule==0){ |
|
408 |
sprintf(file_name,"results_v7/boundary_curvature/stress_%1.1f.txt",1.-((double)anisotropy)*0.1); |
|
409 |
} |
|
410 |
} |
|
411 |
|
|
412 |
if (stress_source==0){ |
|
413 |
if (growth_rate[i]==1.){ |
|
414 |
if (rule==-1){ |
|
415 |
sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_meristem.txt",1.-((double)anisotropy)*0.1); |
|
416 |
} |
|
417 |
if (rule==0){ |
|
418 |
sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_meristem.txt",1.-((double)anisotropy)*0.1); |
|
419 |
} |
|
420 |
} |
|
421 |
if (growth_rate[i]!=1.){ |
|
422 |
if (rule==-1){ |
|
423 |
sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_boundary.txt",1.-((double)anisotropy)*0.1); |
|
424 |
} |
|
425 |
if (rule==0){ |
|
426 |
sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_boundary.txt",1.-((double)anisotropy)*0.1); |
|
427 |
} |
|
428 |
} |
|
429 |
}*/ |
|
430 |
// if (rule==-1){ |
|
431 |
// sprintf(file_name,"results_v7/pressure/shape_%1.1f.txt",1.+((double)anisotropy)*0.1); |
|
432 |
// } |
|
433 |
// if (rule==0){ |
|
434 |
// sprintf(file_name,"results_v7/pressure/stress_%1.1f.txt",1.+((double)anisotropy)*0.1); |
|
435 |
// } |
|
436 |
|
|
437 |
if (rule==-1){ |
|
438 |
sprintf(file_name,"results_v7/isotropic_2/shape.txt"); |
|
439 |
} |
|
440 |
if (rule==0){ |
|
441 |
sprintf(file_name,"results_v7/isotropic_2/stress.txt"); |
|
442 |
} |
|
443 |
|
|
444 |
f=fopen(file_name,"a"); |
|
445 |
|
|
446 |
int write=0,count=0,count2=0; |
|
447 |
while (count<(daughter_cells_vertices_number[1]-1)){ |
|
448 |
if (write){ |
|
449 |
fprintf(f,"%d %d %d %f %f 0.0\n",1000*meristem+total_cell_number/*i+1*/,cell2[count2%daughter_cells_vertices_number[1]]+1,/*total_cell_number+1*/0/*cell_number-1*/, |
|
450 |
vertices[2*cell2[count2%daughter_cells_vertices_number[1]]], |
|
451 |
vertices[2*cell2[count2%daughter_cells_vertices_number[1]]+1]); |
|
452 |
count++; |
|
453 |
} |
|
454 |
write+=((cell2[count2%daughter_cells_vertices_number[1]])==(vertices_number-2)); |
|
455 |
count2++; |
|
456 |
} |
|
457 |
write=0; count=0; count2=0; |
|
458 |
while (count<(daughter_cells_vertices_number[0]-1)){ |
|
459 |
if (write){ |
|
460 |
fprintf(f,"%d %d %d %f %f 0.0\n",1000*meristem+total_cell_number/*i+1*/,cell1[count2%daughter_cells_vertices_number[0]]+1,/*total_cell_number+2*/1/*i*/, |
|
461 |
vertices[2*cell1[count2%daughter_cells_vertices_number[0]]], |
|
462 |
vertices[2*cell1[count2%daughter_cells_vertices_number[0]]+1]); |
|
463 |
count++; |
|
464 |
} |
|
465 |
write+=((cell1[count2%daughter_cells_vertices_number[0]])==(vertices_number-1)); |
|
466 |
count2++; |
|
467 |
} |
|
468 |
fclose(f); |
|
469 |
} |
|
470 |
} |
|
471 |
/* division saved */ |
|
472 |
|
|
473 |
|
|
474 |
/* same as above, but filter out the asymmetric divisions */ |
|
475 |
#pragma omp critical |
|
476 |
{ |
|
477 |
double area_ratio=cell_areas[i]/(cell_areas[cell_number-1]+cell_areas[i]); if (area_ratio>0.5){ area_ratio=1.-area_ratio;} |
|
478 |
double aspect_ratio=(shapes[3*i]+shapes[3*i+1])/2.; |
|
479 |
aspect_ratio-=0.5*sqrt((shapes[3*i]-shapes[3*i+1])*(shapes[3*i]-shapes[3*i+1])+4.*shapes[3*i+2]*shapes[3*i+2]); |
|
480 |
aspect_ratio=aspect_ratio/(shapes[3*i]+shapes[3*i+1]-aspect_ratio); aspect_ratio=sqrt(aspect_ratio); |
|
481 |
|
|
482 |
if (save_cell==1 && area_ratio>0.4 && aspect_ratio>0.5){ |
|
483 |
FILE *f=NULL; char file_name[256]; |
|
484 |
|
|
485 |
/*if (stress_source==1){ |
|
486 |
if (rule==-1){ |
|
487 |
sprintf(file_name,"results_v7/boundary_curvature/shape_%1.1f_filter.txt",1.-((double)anisotropy)*0.1); |
|
488 |
} |
|
489 |
if (rule==0){ |
|
490 |
sprintf(file_name,"results_v7/boundary_curvature/stress_%1.1f_filter.txt",1.-((double)anisotropy)*0.1); |
|
491 |
} |
|
492 |
} |
|
493 |
|
|
494 |
if (stress_source==0){ |
|
495 |
if (growth_rate[i]==1.){ |
|
496 |
if (rule==-1){ |
|
497 |
sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_meristem_filter.txt",1.-((double)anisotropy)*0.1); |
|
498 |
} |
|
499 |
if (rule==0){ |
|
500 |
sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_meristem_filter.txt",1.-((double)anisotropy)*0.1); |
|
501 |
} |
|
502 |
} |
|
503 |
if (growth_rate[i]!=1.){ |
|
504 |
if (rule==-1){ |
|
505 |
sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_boundary_filter.txt",1.-((double)anisotropy)*0.1); |
|
506 |
} |
|
507 |
if (rule==0){ |
|
508 |
sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_boundary_filter.txt",1.-((double)anisotropy)*0.1); |
|
509 |
} |
|
510 |
} |
|
511 |
}*/ |
|
512 |
// if (rule==-1){ |
|
513 |
// sprintf(file_name,"results_v7/pressure/shape_%1.1f_filter.txt",1.+((double)anisotropy)*0.1); |
|
514 |
// } |
|
515 |
// if (rule==0){ |
|
516 |
// sprintf(file_name,"results_v7/pressure/stress_%1.1f_filter.txt",1.+((double)anisotropy)*0.1); |
|
517 |
// } |
|
518 |
|
|
519 |
if (rule==-1){ |
|
520 |
sprintf(file_name,"results_v7/isotropic_2/shape_filter.txt"); |
|
521 |
} |
|
522 |
if (rule==0){ |
|
523 |
sprintf(file_name,"results_v7/isotropic_2/stress_filter.txt"); |
|
524 |
} |
|
525 |
|
|
526 |
f=fopen(file_name,"a"); |
|
527 |
|
|
528 |
int write=0,count=0,count2=0; |
|
529 |
while (count<(daughter_cells_vertices_number[1]-1)){ |
|
530 |
if (write){ |
|
531 |
fprintf(f,"%d %d %d %f %f 0.0\n",1000*meristem+total_cell_number/*i+1*/,cell2[count2%daughter_cells_vertices_number[1]]+1,/*total_cell_number+1*/0/*cell_number-1*/, |
|
532 |
vertices[2*cell2[count2%daughter_cells_vertices_number[1]]], |
|
533 |
vertices[2*cell2[count2%daughter_cells_vertices_number[1]]+1]); |
|
534 |
count++; |
|
535 |
} |
|
536 |
write+=((cell2[count2%daughter_cells_vertices_number[1]])==(vertices_number-2)); |
|
537 |
count2++; |
|
538 |
} |
|
539 |
write=0; count=0; count2=0; |
|
540 |
while (count<(daughter_cells_vertices_number[0]-1)){ |
|
541 |
if (write){ |
|
542 |
fprintf(f,"%d %d %d %f %f 0.0\n",1000*meristem+total_cell_number/*i+1*/,cell1[count2%daughter_cells_vertices_number[0]]+1,/*total_cell_number+2*/1/*i*/, |
|
543 |
vertices[2*cell1[count2%daughter_cells_vertices_number[0]]], |
|
544 |
vertices[2*cell1[count2%daughter_cells_vertices_number[0]]+1]); |
|
545 |
count++; |
|
546 |
} |
|
547 |
write+=((cell1[count2%daughter_cells_vertices_number[0]])==(vertices_number-1)); |
|
548 |
count2++; |
|
549 |
} |
|
550 |
fclose(f); |
|
551 |
} |
|
552 |
} |
|
553 |
|
|
554 |
|
|
555 |
#pragma omp critical |
|
556 |
{ |
|
557 |
if (save_cell==1){ |
|
558 |
FILE *f=NULL; char file_name[256]; |
|
559 |
|
|
560 |
/*if (stress_source==1){ |
|
561 |
if (rule==-1){ |
|
562 |
sprintf(file_name,"results_v7/boundary_curvature/shape_%1.1f.txt",1.-((double)anisotropy)*0.1); |
|
563 |
} |
|
564 |
if (rule==0){ |
|
565 |
sprintf(file_name,"results_v7/boundary_curvature/stress_%1.1f.txt",1.-((double)anisotropy)*0.1); |
|
566 |
} |
|
567 |
} |
|
568 |
|
|
569 |
if (stress_source==0){ |
|
570 |
if (growth_rate[i]==1.){ |
|
571 |
if (rule==-1){ |
|
572 |
sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_meristem.txt",1.-((double)anisotropy)*0.1); |
|
573 |
} |
|
574 |
if (rule==0){ |
|
575 |
sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_meristem.txt",1.-((double)anisotropy)*0.1); |
|
576 |
} |
|
577 |
} |
|
578 |
if (growth_rate[i]!=1.){ |
|
579 |
if (rule==-1){ |
|
580 |
sprintf(file_name,"results_v7/boundary_growth/shape_%1.1f_boundary.txt",1.-((double)anisotropy)*0.1); |
|
581 |
} |
|
582 |
if (rule==0){ |
|
583 |
sprintf(file_name,"results_v7/boundary_growth/stress_%1.1f_boundary.txt",1.-((double)anisotropy)*0.1); |
|
584 |
} |
|
585 |
} |
|
586 |
}*/ |
|
587 |
// if (rule==-1){ |
|
588 |
// sprintf(file_name,"results_v7/pressure/shape_%1.1f.txt",1.+((double)anisotropy)*0.1); |
|
589 |
// } |
|
590 |
// if (rule==0){ |
|
591 |
// sprintf(file_name,"results_v7/pressure/stress_%1.1f.txt",1.+((double)anisotropy)*0.1); |
|
592 |
// } |
|
593 |
|
|
594 |
if (rule==-1){ |
|
595 |
sprintf(file_name,"results_v7/isotropic_2/shape.txt"); |
|
596 |
} |
|
597 |
if (rule==0){ |
|
598 |
sprintf(file_name,"results_v7/isotropic_2/stress.txt"); |
|
599 |
} |
|
600 |
|
|
601 |
f=fopen(file_name,"a"); |
|
602 |
|
|
603 |
int write=0,count=0,count2=0; |
|
604 |
while (count<(daughter_cells_vertices_number[1]-1)){ |
|
605 |
if (write){ |
|
606 |
fprintf(f,"%d %d %d %f %f 0.0\n",1000*meristem+total_cell_number/*i+1*/,cell2[count2%daughter_cells_vertices_number[1]]+1,/*total_cell_number+1*/0/*cell_number-1*/, |
|
607 |
vertices[2*cell2[count2%daughter_cells_vertices_number[1]]], |
|
608 |
vertices[2*cell2[count2%daughter_cells_vertices_number[1]]+1]); |
|
609 |
count++; |
|
610 |
} |
|
611 |
write+=((cell2[count2%daughter_cells_vertices_number[1]])==(vertices_number-2)); |
|
612 |
count2++; |
|
613 |
} |
|
614 |
write=0; count=0; count2=0; |
|
615 |
while (count<(daughter_cells_vertices_number[0]-1)){ |
|
616 |
if (write){ |
|
617 |
fprintf(f,"%d %d %d %f %f 0.0\n",1000*meristem+total_cell_number/*i+1*/,cell1[count2%daughter_cells_vertices_number[0]]+1,/*total_cell_number+2*/1/*i*/, |
|
618 |
vertices[2*cell1[count2%daughter_cells_vertices_number[0]]], |
|
619 |
vertices[2*cell1[count2%daughter_cells_vertices_number[0]]+1]); |
|
620 |
count++; |
|
621 |
} |
|
622 |
write+=((cell1[count2%daughter_cells_vertices_number[0]])==(vertices_number-1)); |
|
623 |
count2++; |
|
624 |
} |
|
625 |
fclose(f); |
|
626 |
} |
|
627 |
} |
|
628 |
|
|
629 |
#pragma omp critical |
|
630 |
{ |
|
631 |
double area_ratio=cell_areas[i]/(cell_areas[cell_number-1]+cell_areas[i]); if (area_ratio>0.5){ area_ratio=1.-area_ratio;} |
|
632 |
double aspect_ratio=(shapes[3*i]+shapes[3*i+1])/2.; |
|
633 |
aspect_ratio-=0.5*sqrt((shapes[3*i]-shapes[3*i+1])*(shapes[3*i]-shapes[3*i+1])+4.*shapes[3*i+2]*shapes[3*i+2]); |
|
634 |
aspect_ratio=aspect_ratio/(shapes[3*i]+shapes[3*i+1]-aspect_ratio); aspect_ratio=sqrt(aspect_ratio); |
|
635 |
|
|
636 |
if (save_cell==1){ |
|
637 |
FILE *f=NULL; char file_name[256]; |
|
638 |
|
|
639 |
|
|
640 |
if (rule==-1){ |
|
641 |
sprintf(file_name,"results_v7/isotropic_2/shape_data.txt"); |
|
642 |
} |
|
643 |
if (rule==0){ |
|
644 |
sprintf(file_name,"results_v7/isotropic_2/stress_data.txt"); |
|
645 |
} |
|
646 |
|
|
647 |
f=fopen(file_name,"a"); |
|
648 |
fprintf(f,"%d %f %f %d %f %f %f\n",1000*meristem+total_cell_number,cell_areas[i],aspect_ratio, |
|
649 |
vertices_number_in_each_cell[i+1]-vertices_number_in_each_cell[i],stress_periclinal[3*i],stress_periclinal[3*i+1],stress_periclinal[3*i+2]); |
|
650 |
fclose(f); |
|
651 |
} |
|
652 |
} |
|
653 |
#pragma omp critical |
|
654 |
{ |
|
655 |
double area_ratio=cell_areas[i]/(cell_areas[cell_number-1]+cell_areas[i]); if (area_ratio>0.5){ area_ratio=1.-area_ratio;} |
|
656 |
double aspect_ratio=(shapes[3*i]+shapes[3*i+1])/2.; |
|
657 |
aspect_ratio-=0.5*sqrt((shapes[3*i]-shapes[3*i+1])*(shapes[3*i]-shapes[3*i+1])+4.*shapes[3*i+2]*shapes[3*i+2]); |
|
658 |
aspect_ratio=aspect_ratio/(shapes[3*i]+shapes[3*i+1]-aspect_ratio); aspect_ratio=sqrt(aspect_ratio); |
|
659 |
|
Formats disponibles : Unified diff