WebGL-FF++.js

T Télécharger

webgl-ff++.js est un code javascript qui permet de visualiser aisément des résultats obtenus par FreeFem++.

Quick Start

Prérequis - Installer FreeFem++

Résolution sous 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.p0

Inclusion des résultats dans une page web

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>

Ouput

Élément Fini P1
Élément Finie P0

webgl-ff++ peut représenter des fonctions éléments finis P0, P1 et P1dc. Le maillage doit être stocké au format FreeFem++.

Animations

webgl-ff++ peut être utilisé afin de réaliser des animations Javascript dans les pages HTML.

FreeFem++ : Poutre élastique

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;
}

Inclusion des résultats dans une page web

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>

Output

Évolution d'une poutre élastique