Révision 22

README.txt (revision 22)
1
----------------------------------------------------------------------
2
			        - Dandelion -
3
    Dandelion pappus morphing is actuated by radially patterned material swelling
4
----------------------------------------------------------------------
5

  
6
FreeFem++ simulation scripte used in the following publication :
7
Madeleine Seale, Annamaria Kiss, Simone Bovio, Ignazio Maria Viola, Enrico
8
Mastropaolo, Arezki Boudaoud, Naomi Nakayama, "Dandelion pappus morphing is actuated by radially patterned material swelling", doi: https://doi.org/10.1101/2021.08.23.457337
9
----------------------------------------------------------------------
10

  
11
Author :
12
--------
13
Annamaria Kiss (annamaria.kiss@ens-lyon.fr, Laboratoire RDP, ENS Lyon)
14

  
15
Download
16
--------
17
svn --username $USER checkout http://forge.cbp.ens-lyon.fr/svn/dandelion
18

  
19
Dependency
20
--------
21
The scripte is interpreted and executed by the FreeFem++ software:
22
https://freefem.org/
23

  
24
Usage
25
-----
26
FreeFemm++ dandelion.cpp [-param value]
27

  
28
If no options are given, the reference model is simulated, namely all parametervalues are chosen to have their reference values. Parameter values can be specified by using the parameter's name as option. Accepted options are the following (see Table 1 and Table 2 of the publication for parameter description and reference values).
29
- geometrical parameters: D, H, Hpod, R, Hside, Wside, Wvasculature, Dcavity
30
- vasculature displacement: dvasc
31
- swelling factors: scort, spod, sside, svasc
32

  
33

  
34
Example 1 : the reference model
35
================================
36
FreeFemm++ dandelion.cpp
37

  
38

  
39
nvertex=40
40
  --  mesh:  Nb of Triangles =   8774, Nb of Vertices 4629
41
  -- Solve : 
42
          min -0.292037  max 0.292132
43
----------------------
44
Areachanges (Awet/Adry) :
45
----------------------
46
cortex -> 1.67524
47
floral podium -> 1.61194
48
side -> 1.79592
49
vasculature -> 1.2898
50
----------------------
51
Generated side angle = 19.5215 degrees
52
----------------------
53
times: compile 0.008144s, execution 9.69662s,  mpirank:0
54
 CodeAlloc : nb ptr  5686,  size :562720 mpirank: 0
55
Ok: Normal End
56

  
57
Example 2 : higher swelling abilities for the cortex generates higher side angle
58
================================
59
FreeFem++ dandelion.cpp -scort 0.7
60

  
61

  
62
nvertex=40
63
  --  mesh:  Nb of Triangles =   8774, Nb of Vertices 4629
64
  -- Solve : 
65
          min -0.404528  max 0.404761
66
----------------------
67
Areachanges (Awet/Adry) :
68
----------------------
69
cortex -> 2.21836
70
floral podium -> 1.54942
71
side -> 1.54601
72
vasculature -> 1.25095
73
----------------------
74
Generated side angle = 31.9336 degrees
75
----------------------
76
times: compile 0.007776s, execution 10.0292s,  mpirank:0
77
 CodeAlloc : nb ptr  5686,  size :562720 mpirank: 0
78
Ok: Normal End
79

  
dandelion.cpp (revision 22)
1
/***************************
2
 * ----------------------------------------------------------------------
3
 * Dandelion pappus morphing is actuated by radially patterned material swelling
4
 * ----------------------------------------------------------------------
5
 * 
6
 * FreeFem++ simulation scripte used in the following publication :
7
 * 
8
 * Madeleine Seale, Annamaria Kiss, Simone Bovio, Ignazio Maria Viola, Enrico
9
 * Mastropaolo, Arezki Boudaoud, Naomi Nakayama, 
10
 * "Dandelion pappus morphing is actuated by radially patterned material swelling",
11
 * doi: https://doi.org/10.1101/2021.08.23.457337
12
 * 
13
 * Author :
14
 * Annamaria Kiss 
15
 * (annamaria.kiss@ens-lyon.fr, Laboratoire RDP, ENS Lyon)
16
 * 
17
 * ***************************/
18

  
19
include "getARGV.idp"
20

  
21
// reading script arguments
22
for (int i=0;i<ARGV.n;++i)
23
{ cout << ARGV[i] << " ";}
24
cout<<endl;
25

  
26
/***************************
27
*      GLOSSARY
28
*   nectary = floral podium
29
*   mesophyl = cortex
30
/****************************/
31

  
32
/*************************************************************
33
 *                  PARAMETERS
34
 * **********************************************************/
35

  
36
string output = getARGV("-out", ".");
37

  
38
// ---------------- geometrical parameters ----------------
39

  
40
// (lengths are measured in micrometers)
41
real units=200;
42

  
43
// actuator dimensions
44
real lx=getARGV("-D", 491.0)/units;       //sd =34.4
45
real ly=getARGV("-H", 240.0)/units;      //sd=36.0
46

  
47
// floral podium
48
real hnect = getARGV("-Hpod", 38.8)/units;   //sd=9.6
49
real Rmeasured=getARGV("-R", 363.0)/units;    //sd=49.4
50
real R=Rmeasured-hnect;
51

  
52
// side
53
real hside=getARGV("-Hside", 91.4)/units;     //12.6
54
real lside=getARGV("-Wside", 47.6)/units;     //6.6
55

  
56
// vasculature
57
real vthickness=getARGV("-Wvasculature", 34.3)/units;//5.5
58
real cwidth=getARGV("-Dcavity", 74.8)/units;    //15.2
59

  
60
// vasculature displacement (from vascular bundle distance)
61
real vd=getARGV("-dvasc", 15.3)/units; //15.3*0.22
62
real vposition=lx/2-vthickness-hnect/ly*(lx/2-cwidth/2-vthickness);
63

  
64
// mesh parameters
65
int nvertex=40;
66
cout << "nvertex="<<nvertex<<endl;
67

  
68
// ---------------- Material properties ----------------
69

  
70
// Poisson's ratio
71
real nu = 0.29;
72

  
73
// Young modulus
74
real Ev;   // vasculature Young modulus
75
real fEm; // cortex Em/Ev 
76
real fEn;  // floral podium En/Ev 
77
real fEs;  // side     Es/Ev 
78
	
79
// measured values for the density (Mean, SD)
80
real dm=0.668060839; //sd=0.04091249
81
real dn=1.01896008; //sd=0.015464575
82
real ds=0.918032482; //sd=0.075097509
83
real dv=0.882171532; //sd=0.066651037
84

  
85
// Young modulus is linked to measured densities
86
Ev=1;   // vasculature Young modulus
87
fEm=dm/dv; // cortex Em/Ev 
88
fEn=dn/dv;  // floral podium  En/Ev 
89
fEs=ds/dv;  // side     Es/Ev 
90

  
91
// -----   swelling ability of each region is a parameter
92
real ani = getARGV("-ani", 1.);// anisotropy of swelling property
93
real sm = -getARGV("-scort", 0.464888);// cortex swelling property
94
real sn = -getARGV("-spod", 0.443697);// floral podium swelling property
95
real ss = -getARGV("-sside", 0.573482);// side swelling property
96
real sv = -getARGV("-svasc", 0.236087);// vasculature swelling property
97

  
98

  
99
/*************************************************************
100
 *                  GEOMETRY and MESH
101
 * **********************************************************/
102

  
103
func real lineD(real xA, real xB, real yA, real yB)
104
{	return (yB-yA)/(xB-xA);
105
}
106

  
107
func real lineC(real xA, real xB, real yA, real yB)
108
{	return (yA*xB-yB*xA)/(xB-xA);
109
}
110

  
111
func real angleToVertical(real Mx, real My, real Nx, real Ny)
112
{ /*  Computes the sinus of angle between the MN vector and Oy   */
113
	return asin((Nx-Mx)/sqrt((Mx-Nx)^2+(My-Ny)^2))*180/pi;
114
}
115

  
116
// ----------------- External boundary/ -----------------
117

  
118
real rnect=lx/2-vthickness;
119
real tB=2*pi-acos(rnect/R);
120
real tA=pi+acos(rnect/R);
121
real xC=0;
122
real yC=sqrt(R*R-rnect*rnect);
123

  
124
// top
125
border a1(t=0,1){x=lx/2+t*(lx/2-vthickness-lx/2);y=0;label=11;};
126
border a2(t=tB,tA){x=xC+R*cos(t);y=yC+R*sin(t);label=12;};
127
border a3(t=0,1){x=-lx/2+vthickness+t*(-lx/2-(-lx/2+vthickness));y=0;label=13;};
128
// left
129
border b1(t=0,1){x=-lx/2;y=t*(-ly);label=2;};
130
// bottom
131
border c1(t=0,1){x=-lx/2+t*(-cwidth/2-vthickness+lx/2);y=-ly;label=31;};
132
border c2(t=0,1){x=-cwidth/2-vthickness+t*vthickness;y=-ly;label=32;};
133
border c3(t=0,1){x=cwidth/2+t*vthickness;y=-ly;label=33;};
134
border c4(t=0,1){x=cwidth/2+vthickness+t*(lx/2-cwidth/2-vthickness);y=-ly;label=34;};
135
// right
136
border d1(t=0,1){x=lx/2;y=-ly+t*(ly);label=4;};
137

  
138
// -------------------- Internal boundary/ -----------------
139

  
140
real xA=-rnect; real yA=0;
141
real xB=-cwidth/2; real yB=-ly;
142
real D=lineD(xA, xB, yA, yB);
143
real C=lineC(xA, xB, yA, yB);
144
real delta=D^2*(C-yC)^2-(1+D^2)*((C-yC)^2-(R+hnect)^2);
145
real xM=(-D*(C-yC)+sqrt(delta))/(D^2+1);
146
real yM=D*xM+C;
147
real tN=2*pi+asin(-sqrt((R+hnect)^2-xM^2)/(R+hnect));
148
real tM=3*pi-tN;
149

  
150
// hole
151
border vide1(t=0,1){x=-cwidth/2+t*(xM+cwidth/2);y=-ly+t*(yM+ly);label=51;};
152
border vide2(t=tM,tN){x=xC+(R+hnect)*cos(t);y=yC+(R+hnect)*sin(t);label=52;};
153
border vide3(t=0,1){x=-xM+t*(cwidth/2+xM);y=yM+t*(-ly-yM);label=53;};
154

  
155
// ------------------- Define the mesh -------------------
156

  
157
mesh Th = buildmesh (a1(nvertex*vthickness)+a2(nvertex*2*rnect)+a3(nvertex*vthickness) // top
158
                     + b1(nvertex*ly) + d1(nvertex*ly) // sides
159
                     + c1(nvertex*lx/2) + c2(nvertex*vthickness) // left bottom
160
                     + vide1(nvertex*ly) + vide2(nvertex*(lx-2*vthickness)) + vide3(nvertex*ly)  //hole
161
                     + c3(nvertex*vthickness) + c4(nvertex*lx/2)  // right bottom
162
                     );
163

  
164
/*************************************************************
165
 *                  DEFINITION OF the REGIONS
166
 * **********************************************************/
167

  
168
real xA1=-(vposition+vthickness), yA1=-hnect;
169
real xB1=-cwidth/2-vthickness, yB1=-ly;
170
real xA2=(vposition+vthickness), yA2=-hnect;
171
real xB2=cwidth/2+vthickness, yB2=-ly;
172
real D1=lineD(xA1, xB1, yA1, yB1);
173
real C1=lineC(xA1, xB1, yA1, yB1);
174
real D2=lineD(xA2, xB2, yA2, yB2);
175
real C2=lineC(xA2, xB2, yA2, yB2);
176

  
177
func bool vasculatureBool(real xx, real yy)
178
{	return (((yy>D1*xx+C1) && (yy<D1*(xx-vthickness)+C1)) || ((yy>D2*xx+C2)&& (yy<D2*(xx+vthickness)+C2)) );
179
}
180

  
181
func bool nectaryBool(real xx, real yy)
182
{	return (yy>D1*(xx-vthickness)+C1)&&(yy>D2*(xx+vthickness)+C2);
183
}
184

  
185
func bool sideBool(real xx, real yy)
186
{	return   (yy>-hside) && (((xx<-lx/2+lside)&&(yy<D1*xx+C1)) || ( (xx>lx/2-lside)&& (yy<D2*xx+C2))  );
187
}
188

  
189
func bool mesophylBool(real xx, real yy)
190
{	return (!vasculatureBool(xx,yy)) && (!nectaryBool(xx,yy)) && (!sideBool(xx,yy));
191
}
192

  
193

  
194
/*************************************************************
195
 *                  DEFINE THE FINITE ELEMENT SPACE
196
 * **********************************************************/
197

  
198
fespace Vh(Th,[P2,P2]);  // vector on the mesh (displacement vector)
199
Vh [u1,u2], [v1,v2];
200

  
201
fespace Sh(Th, P2);   // scalar on the mesh, P2 elements
202
fespace Sh0(Th,P0);   // scalar on the mesh, P0 elements
203
fespace Sh1(Th,P1);   // scalar on the mesh, P1 elements
204

  
205
Sh0 strain, stress;
206

  
207
// bounding box for the plot (use the same for all images so that they can be superposed)
208
func bb=[[-lx/2*1.5,-ly*1],[lx/2*1.5,ly*.1]];
209
//real coef=1.;
210
//cout << "Coefficent of amplification:"<<coef<<endl;
211
plot(Th, ps=output+"/mesh-original.eps", bb=bb, wait=1);
212

  
213
// macro to redefine variables on the displaced mesh 
214
macro redefineVariable(vvv)
215
{	real[int] temp(vvv[].n);
216
	temp=vvv[]; vvv=0; vvv[]=temp;
217
	vvv=vvv;
218
}//
219

  
220

  
221
real sqrt2=sqrt(2.);
222
macro epsilon(u1,u2)  [dx(u1),dy(u2),(dy(u1)+dx(u2))/sqrt2] // EOM
223
//the sqrt2 is because we want: epsilon(u1,u2)'* epsilon(v1,v2) $==  \epsilon(\bm{u}): \epsilon(\bm{v})$
224
macro div(u1,u2) ( dx(u1)+dy(u2) ) // EOM
225

  
226
/*************************************************************
227
 *                 SPATIAL DEPENDENCE OF MATERIAL PROPERTIES
228
 * **********************************************************/
229

  
230
// define region geometry as a finite element field
231

  
232
//string mutname="mnsv";
233
func vasculature=int(vasculatureBool(x,y));
234
func nectary=int(nectaryBool(x,y));
235
func side=int(sideBool(x,y));
236
func mesophyl=int(mesophylBool(x,y));
237

  
238
func geometry = 1*vasculature + 3*nectary + 2*side + 4*mesophyl;
239

  
240
// definition of FE variables for the structural domains
241
Sh0 vasculatureh=vasculature;
242
Sh0 nectaryh=nectary;
243
Sh0 sideh=side;
244
Sh0 mesophylh=mesophyl;
245

  
246
Sh0 geometryh=geometry;
247
string fname=output+"/geometry-original.eps";
248
plot(geometryh,fill=1, ps=fname, bb=bb, wait=1 );
249

  
250

  
251
// spatial dependence of Young modulus
252
func E=Ev*(vasculature + fEn*nectary + fEs*side + fEm*mesophyl);
253
Sh0 Eh=E;
254

  
255
// spatial dependence of the swelling property
256
func s=sv*vasculature + sn*nectary + ss*side + sm*mesophyl;
257
Sh0 sh=s;
258

  
259
// spatial dependence of the anisotropy of the swelling property
260
Sh0 anih=ani;
261

  
262
func mu=E/(2*(1+nu));
263
func lambda=E*nu/((1+nu)*(1-2*nu));
264

  
265
/*************************************************************
266
 *                  SOLVING THE FEM
267
 * **********************************************************/
268

  
269
solve Lame([u1,u2],[v1,v2])=
270
  int2d(Th)(
271
	    lambda*div(u1,u2)*div(v1,v2) 	
272
	    + 2.*mu*( epsilon(u1,u2)'*epsilon(v1,v2) ) 
273
	      )
274
  - int2d(Th) ( sh/(1.+anih)*((2.*mu+lambda)*dx(v1)+lambda*dy(v2)) )
275
  - int2d(Th) ( ani*sh/(1.+anih)*(lambda*dx(v1)+(2.*mu+lambda)*dy(v2)) )
276
+ on(32,u1=vd,u2=0) + on(33,u1=-vd,u2=0) 
277
  ;
278

  
279

  
280
/*************************************************************
281
 *                  RESULTS
282
 * **********************************************************/
283

  
284
// compute original region volumes
285
real voltotal0=int2d(Th)(1);
286
real volvasculature0=int2d(Th)(vasculatureh);
287
real volnectary0=int2d(Th)(nectaryh);
288
real volmesophyl0=int2d(Th)(mesophylh);
289
real volside0=int2d(Th)(sideh);
290

  
291

  
292
// move the mesh and plot the deformed mesh
293
mesh Th0=Th;
294
Th=movemesh(Th,[x+u1,y+u2]);
295

  
296
plot(Th, Th0,  ps=output+"/mesh-original+deformed-superposed.eps",bb=bb, wait=1);
297
plot(Th,  ps=output+"/mesh-deformed.eps",bb=bb, wait=1);
298

  
299
redefineVariable(geometryh);
300
plot(geometryh, fill=1, ps=output+"/geometry-deformed.eps",bb=bb, wait=1);
301

  
302
// compute deformed region volumes
303
redefineVariable(vasculatureh);
304
redefineVariable(nectaryh);
305
redefineVariable(sideh);
306
redefineVariable(mesophylh);
307

  
308
real voltotal=int2d(Th)(1);
309
real volvasculature=int2d(Th)(vasculatureh);
310
real volnectary=int2d(Th)(nectaryh);
311
real volside=int2d(Th)(sideh);
312
real volmesophyl=int2d(Th)(mesophylh);
313

  
314
// compute areachanges
315
real am=volmesophyl0/volmesophyl;
316
real an=volnectary0/volnectary;
317
real as=volside0/volside;
318
real av=volvasculature0/volvasculature;
319

  
320
// compute the generated side angle
321
real height=hside;
322
real Nx=lx/2+u1(lx/2.,0), Ny=u2(lx/2.,0);
323
real Mx=lx/2+u1(lx/2.,-height), My=-height+u2(lx/2.,-height);
324
real sideangle=angleToVertical(Mx, My, Nx, Ny);
325

  
326
/*************************************************************
327
 *        PRINT RESULTS
328
 * **********************************************************/
329
cout<<"----------------------"<<endl;
330
cout<<"Areachanges (Awet/Adry) :"<<endl;
331
cout<<"----------------------"<<endl;
332
cout<<"cortex -> "<<am<<endl;
333
cout<<"floral podium -> "<<an<<endl;
334
cout<<"side -> "<<as<<endl;
335
cout<<"vasculature -> "<<av<<endl;
336
cout<<"----------------------"<<endl;
337
cout<<"Generated side angle = "<<sideangle<<" degrees"<<endl;
338
cout<<"----------------------"<<endl;

Formats disponibles : Unified diff