webgl-ff++.js est un code javascript qui permet de visualiser aisément des résultats obtenus par FreeFem++.
On considère l'équation de Poisson
$$ \left\{ \begin{array}{ll} -\Delta u=1&\text{ dans }\Omega=(0,1)^2\\ u=0&\text{ sur }\partial\Omega \end{array} \right. $$La résolution sous FreeFem++ peut s'effectuer à l'aide du script suivant
Poisson.edpmesh Th=square(30,30);
fespace Vh(Th,P1),Wh(Th,P0);
int[int] Dirichlet=[1,2,3,4];
macro grad(u) [dx(u),dy(u)]//
Vh u,v;
solve Poisson(u,v)=int2d(Th)(grad(u)'*grad(v))-int2d(Th)(v)+on(Dirichlet,u=0);
Wh sigma=grad(u)'*grad(u);
savemesh(Th,"Poisson/Th.msh");
{ofstream file("Poisson/u.p1");file<<u[];}
{ofstream file("Poisson/sigma.p0");file<<sigma[];}
plot(u,ps="Poisson/u.eps");
plot(sigma,ps="Poisson/sigma.eps",fill=1);
Il suffit alors d'exécuter ce dernier d'un terminal de commande
$ FreeFem++ Poisson.edp
Le maillage est stocké sous le nom Th.msh
la solution approchée dans u.p1
et le carré de la norme sous sigma.p0
.
Les sorties graphiques par défaut sont sauvées au format .eps
(pour comparaison).
Poisson.html<html>
<body>
<canvas width="640px" id="u"></canvas>
<canvas width="640px" id="sigma"></canvas>
</body>
<script src="../webgl-ff++v1.js"></script>
<script>
let Th=readmesh("../edp/Poisson/Th.msh");
{
let u=readFE(Th,"../edp/Poisson/u.p1","P1");
let canvas=GL(document.querySelector('#u'),Th.bb);
canvas.plot(u,{hcolors:HSV});
}
{
let sigma=readFE(Th,"../edp/Poisson/sigma.p0","P0");
let canvas=GL(document.querySelector('#sigma'),Th.bb);
canvas.plot(sigma,{hcolors:HSV,mesh_color:black});
}
</script>
</html>
webgl-ff++ peut représenter des fonctions éléments finis P0, P1 et P1dc. Le maillage doit être stocké au format FreeFem++.
webgl-ff++ peut être utilisé afin de réaliser des animations Javascript dans les pages HTML.
beam.edpmesh Th;int Dirichlet;
real L=20,H=1;
{
int dn=5;
Th=square(L*dn,H*dn,[L*x,H*y]);
Dirichlet=4;
}
real sqrt2=sqrt(2.);
macro e(u) [dx(u[0]),dy(u[1]),(dx(u[1])+dy(u[0]))/sqrt2]//
macro div(u) (dx(u[0])+dy(u[1]))//
fespace Wh(Th,[P1,P1]);
macro u [u1,u2]//
macro up [up1,up2]//
macro uP [uP1,uP2]//
macro v [v1,v2]//
Wh u,v,up,uP;
real t=0,dt=10.,T=2000;
real mu=1,lambda=1,rho=1;
Wh [U1,U2]=[-x,0]; // initial displacement
Wh [V1,V2]=[0,0.1*sin(2.*x/L)]; // initial velocity
//Wh [V1,V2]=[0,0]; // initial velocity
real dt2=square(dt);
problem elasticity(u,v,init=t)=int2d(Th)(rho*u'*v/dt2+2.*mu*e(u)'*e(v)+lambda*div(u)*div(v))
+int2d(Th)(rho*(-2*up+uP)'*v/dt2)
+on(Dirichlet,u1=0,u2=0);
// initialisation
uP=[U1,U2];
up=[U1+dt*V1,U2+dt*V2];
real exa=0.2;
int iter=0;
for(t=0;t<T;t+=dt){
mesh Sh=movemesh(Th,[x+exa*u1,y+exa*u2]);
savemesh(Sh,"beam/Sh"+iter+".msh");iter++;
elasticity;
plot(Sh);
uP=up;
up=u;
}
beam.html<html>
<body style="padding:0;margin:0;">
<canvas id="glcanvas" style="width:100%; background-color:#EEEEEE;"></canvas>
</body>
<script src="../webgl-ff++v1.js"></script>
<script>
let bb={Xmin:0,Xmax:25,Ymin:-8,Ymax:9};
let target=document.querySelector('#glcanvas');
let gl=GL(target,bb);
let iter=0;
let Sh=readmesh("../edp/beam/Sh"+iter+".msh");
gl.plot(Sh);
var run=true;
function render(now) {
Sh=readmesh("../edp/beam/Sh"+iter+".msh");
clearScene(gl);
gl.plot(Sh);
iter=iter+1; // convert to seconds
if(iter==200){run=false;iter=0;}
if (run) requestAnimationFrame(render);
}
requestAnimationFrame(render);
target.addEventListener("click",function(){run=!run;requestAnimationFrame(render);});
</script>
</html>