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).
u.p1
sigma.p0Poisson.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>