View
1
Download
0
Category
Preview:
Citation preview
Introduccion a FreeFem++
Eliseo Chacon VeraDepartamento de Matematicas.
Facultad de Matematicas.Universidad de Murciaeliseo@um.es
6 de septiembre de 2018
INDICE INDICE
Indice
1. Introduccion 2
2. Ejemplos basicos 62.1. Aritmetica basica . . . . . . . . . . . . . . . . . . . . . . . . . 62.2. Uso de los ciclos . . . . . . . . . . . . . . . . . . . . . . . . . . 62.3. Manejo de arrays . . . . . . . . . . . . . . . . . . . . . . . . . 7
3. Curvas parametricas en 2d 7
4. Triangulaciones 2D 9
5. Funciones de base 15
6. Formulacion variacional 176.1. Opciones para plot . . . . . . . . . . . . . . . . . . . . . . . . 20
7. Problemas de evolucion en tiempo 21
8. Caso 3d 278.1. Etiquetado de los contornos . . . . . . . . . . . . . . . . . . . 31
9. Ecuaciones de Navier-Stokes 369.1. Caso 2d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369.2. Caso 3d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1 Introduccion a FreeFem++
1 INTRODUCCION
1. Introduccion
Los archivos de ordenes se guardan con la terminacion .edp, el nombreno es importante pero sı lo es la terminacion. Se debe de usar un editor detexto plano como notepad u otros, es decir, que no contenga macros; porejemplo Microsoft Word no sirve.
Normalmente, en un entorno Linux y en una terminal de texto, se ejecutanmediante la orden
FreeFem++ nombre.edp
aunque esto depende del entorno de trabajo y varıa en un entorno Windowsdonde se puede lanzar el trabajo con el raton de forma usual.
Sus caracterısticas se resumen en
Este lenguaje esta desarrollado en C++ por lo que los aspectos basicosse refieren a C++.
trabaja las EDPs en forma variacional
elementos finitos 2d/3d de varios tipos
triangulaciones 2d/3d
resolutores lineales para matrices llenas y huecas
software libre
etc...
Puede tratar problemas complejos
Bueno para investigacion y docencia
2 Introduccion a FreeFem++
1 INTRODUCCION
Figura 1: Primera pagina del manual de FreeFem++
3 Introduccion a FreeFem++
1 INTRODUCCION
Figura 2: Sitio web: www.freefem.org/ff++/index.htm
4 Introduccion a FreeFem++
1 INTRODUCCION
Un poco de historia:
1985: MacFEM-PCFEM
1995: freefem+ ( F. Hecht y otros)
2000: freefem++ ( F. Hecht )
2000: freefem3D ( Del Pino y otros)
2009: freefem++3D ( F. Hecht)
http://www.freefem.org/ff++/index.htm
Ideas principales:
Sigue la matematica =⇒ formulacion variacional
uso de Elementos Finitos
Algoritmos responsabilidad del usuario
Bloques: Problemas elıpticos
Generadores de triangulaciones con adaptacion de malla
Si es elementos finitos se puede hacer con Freefem++
5 Introduccion a FreeFem++
2 EJEMPLOS BASICOS
2. Ejemplos basicos
2.1. Aritmetica basica
Lanzar el archivo aritmetica.edp para ver distintos tipos de datos:
real x=3.14,y;
int i,j;
cout<< " x = "<< x << "\n";
x=1;y=2;x=y;i=0;j=1;
cout<< 1+3 << " " << 1./3 <<endl;
cout<< 10^10. << "\n";
cout<< 10^-10. << endl;
cout<< -10^-2.+5 << " = 4.99 \n";
cout<< 10^-2.+5 << " =5.01"<<endl;
cout<< " 8^(1/3) = "<< (8)^(1./3.) <<"\n";
cout<<"\n\n";
cout<< "--> Numeros complejos: ahora i= sqrt(-1) "<<endl;
cout<< 10-10i <<"\n";
complex c;
c=(-1+0i)^(1./3.);
cout<< " -1^(1/3) = "<< c <<"\n";
cout<<"\n\n\n";
2.2. Uso de los ciclos
Lanzar el archivo ciclos.edp para ver como funcionan:
// ejemplo con for
//
for (int i=0;i<10;i=i+1)
cout <<i <<endl;
//
// ejemplo con while
//
int j=0;
real eps=1;
while (eps+1!=eps)
6 Introduccion a FreeFem++
2.3 Manejo de arrays 3 CURVAS PARAMETRICAS EN 2D
cout <<j <<" eps= "<<eps<<endl;
eps=eps/2;
j++;
if(abs(eps)<1e-16) break;
bool see=(eps+1==1);
string c1="Comprobamos cuando eps+1=1. ";
string c2="0-->False 1-->True. ";
string c3=" Resultado es ";
cout<<c1+c2+c3<<see<<endl;
cout<<"\n\n"<<endl;
if(see) break;
cout <<j <<" eps-->eps/2= "<<eps<<" eps+1= "<<eps+1<<endl;
2.3. Manejo de arrays
Lanzar el archivo arrays.edp para ver operaciones basicas con arrays:
int n=20;
real[int] a(20);
for (int i=0;i<n;i=i+1)
a[i]=cos(n*pi/(i+1));
cout << "a=" << a << endl;
cout << "Sum of a[i]=" << a.sum << endl;
cout << " size of a = " << a.n << endl;
cout << " minimum of a = " << a.min << endl;
cout << " ||a||_1 = "<<a.l1<<endl;
cout << " ||a||_2 = "<<a.l2<<endl;
cout << " ||a||_infty = " <<a.linfty<<endl;
3. Curvas parametricas en 2d
La generacion de curvas parametricas en 2d es la clave para poder des-cribir geometrias en el plano donde se resuelven las ecuaciones en derivadasparciales. Tambien es clave para la construccion de geometrias 3d, como ve-remos en su momento.
7 Introduccion a FreeFem++
3 CURVAS PARAMETRICAS EN 2D
Some parametric curves
Figura 3: Algunas curvas parametricas. Los ejes tambien se describen deforma parametrica
Lanzar el archivo curvas.edp para observar la geberacion de alguna deellas, incluidas los ejes cartesianos:
real b=1,a=1;
func real phix(real t)
return (a+b)*cos(t)-b*cos(t*(a+b)/b);
func real phiy(real t)
return (a+b)*sin(t)-b*sin(t*(a+b)/b);
border C(t=0,2*pi) x=phix(t); y=phiy(t);
border OX(t=-0.5,5)x=t;y=0;
border OY(t=-0.5,5)x=0;y=t;
border G(t=-2,2)x=t;y=t^2;
string text="Some parametric curves";
plot(cmm=text,OX(1),OY(1),C(30),G(10),
wait=1,ps="curves.eps");
8 Introduccion a FreeFem++
4 TRIANGULACIONES 2D
4. Triangulaciones 2D
Archivo rectangle.edp:
border a(t=0,2)x=t;y=0;label=1;
border b(t=0,1)x=2;y=t;label=1;
border c(t=0,2)x=2-t;y=1;label=2;
border d(t=0,1)x=0;y=1-t;label=1;
int n=5;
mesh th=buildmesh(a(2*n)+b(n)+c(2*n)+d(n));
plot(th,wait=1,ps="rectangulo.eps");
Orientacion es la clave: El interior es la izquierda de la curva
Ordenes para generar y describir una geometrıa 2d :
border define y describe parametricamente cada trozo de contorno
label asigna una etiqueta a cada trozo de contorno
buildmesh genera la triangulacion a partir de contornos
mesh tipo de variable construida con buildmesh
Aquı se puede ver como la orientacion es fundamental. El interior del domi-nio siempre queda a la izquierda del sentido de recorrido del parametro en lafrontera.
Archivo elispsehuecos.edp
real pi=4*atan(1.0);
border a(t=0,2*pi)x=2*cos(t);y=sin(t);
9 Introduccion a FreeFem++
4 TRIANGULACIONES 2D
Figura 4: La orientacion de la curva es la clave
border b(t=0,2*pi)x=.3+.3*cos(t);y=.3*sin(t);
border c(t=0,2*pi)x=-.5+.3*cos(t);y=0.3+.3*sin(t);
mesh nohole=buildmesh(a(50)+b(30)+c(20));
mesh hole=buildmesh(a(50)+b(-30)+c(-20));
plot(nohole,wait=1,ps="nohole.eps");
plot(hole,wait=1,ps="hole.eps");
La curva cardioide de la portada se describe mediante las siguientes ecuacio-nes:
x(t) = (a+ b) cos(t)− b cos(a+ b
bt),
y(t) = (a+ b) sin(t)− b sin(a+ b
bt)
Archivo cardioid.edp:
//Cardioid
real b=1.,a=1;
func real phix(real t)
return (a+b)*cos(t)-b*cos(t*(a+b)/b);
func real phiy(real t)
return (a+b)*sin(t)-b*sin(t*(a+b)/b);
border C(t=0,2*pi) x=phix(t); y=phiy(t);
10 Introduccion a FreeFem++
4 TRIANGULACIONES 2D
Figura 5: Cardioide
mesh Th = buildmesh(C(50));
plot(Th,wait=1);
Ejemplo 1 Archivo Lshape.edp
border a(t=0,1)x=t;y=0;label=1;
border b(t=0,0.5)x=1;y=t;label=2;
border c(t=0,0.5)x=1-t;y=0.5;label=3;
border d(t=0.5,1)x=0.5;y=t;label=4;
border e(t=0.5,1)x=1-t;y=1;
border f(t=0,1)x=0;y=1-t;
int n=5;
mesh rh=buildmesh(a(n)+b(n)+c(n)+d(n)+e(n)+f(n));
savemesh(rh,"Lshape.msh");
mesh th=readmesh("Lshape.msh");
plot(th,wait=1,ps="Lshape.eps");
Ejemplo 2 Se pueden guardar y leer los datos de una triangulacion usandosavemesh y readmesh:
11 Introduccion a FreeFem++
4 TRIANGULACIONES 2D
//
// codigo triangle2d.edp
//
border a(t=0,1)x=t;y=0;label=1;
border b(t=0,1)x=1-t;y=t;label=2;
border c(t=0,1)x=0;y=1-t;label=3;
int nn=2;
mesh th=buildmesh(a(nn)+b(nn)+c(nn));
savemesh(th,"triangle2d.msh");
th=readmesh("triangle2d.msh");
plot(th,wait=1,ps="triangle2d.eps");
En la siguiente pagina se ven los datos del archivo junto con la geometrıaque se describe
12 Introduccion a FreeFem++
4 TRIANGULACIONES 2D
Archivo triangle2d.mesh
10 9 9
0 0 3
0.323801507627 0 1
0.647603015254 0 1
1 0 2
0 0.323801507627 3
0.30928980099 0.324146353802 0
0.675445396471 0.324554603529 2
0 0.647603015254 3
0.324554603529 0.675445396471 2
0 1 3
10 8 9 0
8 5 6 0
6 9 8 0
1 6 5 0
7 9 6 0
1 2 6 0
6 2 3 0
4 7 3 0
6 3 7 0
10 8 3
8 5 3
5 1 3
4 7 2
7 9 2
9 10 2
1 2 1
2 3 1
3 4 1
nv nt neb nv= # vertices, nt= # triangles, nt= # edges on boundaryx y label...
......
n1 n2 n3 r n1, n2,n3 = numbering of vertices each triangle, r= # region...
......
ne1 ne2 label ne1, ne2 = # numbering of vertices each bundary edge...
......
13 Introduccion a FreeFem++
4 TRIANGULACIONES 2D
Ejemplo 3 En este ejemplo se describen dos geometrıas anexas que se pue-den usar para resolver problemas sobre materiales con caracterısticas fısicasdistintas.
//
// codigo tworectangletests.edp
//
int n = 10,m=1,lower = 1,upper = 2, inner = 3;
real cOX=-0.5,cOY=-1.25;
border OX(t=-.1,1)x = cOX+t; y =cOY;
border OY(t=-.1,1)x = cOX; y =cOY+t;
border C01(t=0,1)x = 0; y = -t;label = lower;
border C02(t=0,1)x = 1.5*t; y=-1;label = lower;
...
border C13(t=0,1)x = 1;y = -0.5+0.5*t; label = inner;
plot(C01(n),OX(m),OY(m),wait=true);
plot(C01(n),C02(n),OX(m),OY(m),wait=true);
...
mesh Th = buildmesh(C01(n)+C02(n)+C03(n)+
C04(n)+C05(n)+C06(n)+ C11(-n)+C12(-n)+C13(-n));
plot(Th, OX(m),OY(m),cmm="Triangulation + Axis ");
Triangulation + Axis
14 Introduccion a FreeFem++
5 FUNCIONES DE BASE
5. Funciones de base
Una vez que se tiene una triangulacion Th (el nombre Th es irrelevante),se puede construir (colgando de ella) sobre este objeto Th otro que es elespacio de elementos finitos. Basicamente, es una estructura de datos querespeta las reglas basicas que se deben de cumplir sobre los nodos para poderser considerado como espacio de elementos finitos.
Dado un objeto (espacio de elementos finitos) Vh (el nombre Vh tambienes irrelevante), definido mediante fespace Vh(Th,P1); y dado una funcion(objeto) de esta clase, u entonce sobre u se tienen varias opciones:
asignar valor directamente a u, por ejemplo u = x+y∗sin(x∗y) o bienu=1*(x^2+y^2<1) usando que una asignacion logica numericamentevale 1 si es cierta y 0 si es falsa
• (bool = true) ≡ 1,
• (bool = false) ≡ 0
usar u[] para acceder a u como un array y a cada uno de sus grados delibertad usando u[][i].
podemos saber su longitud usando u.n
etc...ver manual
El archivo VerPoligonal.edp permite ver una funcion poligonal a trozosdefinida sobre cada nodo de una triangulacion
mesh Th=square(2,2);
fespace Vh(Th,P1);
Vh u;
int i,n=u.n;
cout<<u.n<<endl;// Numero de nodos
u[][0]=2;
u[][1]=0;
u[][2]=3;
u[][3]=2;
u[][4]=10;
u[][5]=7;
u[][6]=6;
15 Introduccion a FreeFem++
5 FUNCIONES DE BASE
Figura 6: Funcion poligonal
u[][7]=4;
u[][8]=2;
plot(Th,u,wait=1,value=1,nbiso=50,dim=3);
El archivo Verbase.edp permite ver las funciones de base ası como susoporte en dos geometrias distintas. Observar como al redefinir el objetoTh cambian los objeto que cuelgan de Th, a saber, cambian Vh y u sinnecesidad de indicarlo:
mesh Th=square(4,4);
fespace Vh(Th,P1);
Vh u;
int i,n=u.n;
u=0;
for (i=0;i<n;i++) // all degree of freedom
u[][i]=1; // funcion de base i-esima
plot(Th,u,wait=1,value=1,nbiso=50,dim=3);
u[][i]=0; // reset
// Nueva triangulacion
real b=1,a=1;
func real phix(real t)
return (a+b)*cos(t)-b*cos(t*(a+b)/b);
func real phiy(real t)
16 Introduccion a FreeFem++
6 FORMULACION VARIACIONAL
return (a+b)*sin(t)-b*sin(t*(a+b)/b);
border C(t=0,2*pi) x=phix(t); y=phiy(t);
Th = buildmesh(C(50));
fespace Vh(Th,P1);
u=0;
for (i=0;i<u.n;i++) // all degree of freedom
u[][i]=1; // funcion de base i-esima
plot(Th,u,wait=1,value=1,nbiso=50,dim=3);
u[][i]=0; // reset
Funciones de base en dos geometrıas y triangulaciones distintas
6. Formulacion variacional
Para resolver este problema
−∆u(x, y) = f(x, y), (x, y) ∈ Ω
u(x, y) = 0, (x, y) ∈ ∂Ω
usamos la formulacion variacional y buscamos u ∈ Vh tal que∫Ω
∇u · ∇v =
∫Ω
f v, ∀v ∈ Vh
donde tomamos Ω = ∪T una union de triangulos y, si uT es la restriccion deu a T, entonces
Vh = u ∈ C0(Ω); uT ∈ P1; .
17 Introduccion a FreeFem++
6 FORMULACION VARIACIONAL
Estamos tomando funciones continuas que sobre cada triangulo T son poli-nomios de grado 1 en las variables (x, y), esto es, funciones continuas y P1
a trozos. Si tomamos la parte bilineal a(u, v) y el termino lineal l(v) dadoscomo
a(u, v) =
∫Ω
∇u · ∇v,
l(v) =
∫Ω
fv
entonces el problema debemos de escribirlo en la forma:
problem nombre(u,v) = a(u,v) - l(v)
+ (boundary condition);
Por ejemplo, el problema variacional anterior se escribe en la forma:
problem laplace(u,v) =
int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v)) //bilinear part
-int2d(Th)(f*v) // right hand side
+on(a,u=0); // Dirichlet BC
Ejemplo 4 Problema de Laplace en una elipse con Poisson-ellipse.edp
border a(t=0,2*pi)x=2*cos(t);y=sin(t);
mesh Th= buildmesh (a(150));
plot(Th);
fespace Vh(Th,P1);
Vh u, v;
func f=sin(x*y);
problem laplace(u,v) =
int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v)) //bilinear part
-int2d(Th)(f*v) // right hand side
+on(a,u=0); // Dirichlet BC
laplace; //solve the pde
plot(u); //visualizacion
int2d(th)(...) y similares, se usan
18 Introduccion a FreeFem++
6 FORMULACION VARIACIONAL
Figura 7: Malla y solucion, vista 2d y 3d para el problema sobre la elipse
con producto de incognitas y funciones tests
solo con funciones test y datos
NO CON AMBAS A LA VEZ
NO es correcto
int2d(th)(dx(u)*dx(v)+dy(u)*dy(v)-f*v)
+on(1,u=0)
SI es correcto
int2d(th)(dx(u)*dx(v)+dy(u)*dy(v)) // bilinear part
+int2d(th)(-f*v) // right hand side
+on(1,u=0)
Ejemplo 5 Para ν > 0 constante podemos resolver el problema de transportedifusion
−ν∆u(x, y) +~b · ~∇u = f(x, y), (x, y) ∈ Ω
u(x, y) = 0, (x, y) ∈ ∂Ω
de la misma forma usando la formulacion variacional. Entonces buscamosu ∈ Vh tal que
ν
∫Ω
∇u · ∇v +
∫Ω
(~b · ~∇u)v =
∫Ω
f v, ∀v ∈ Vh
Se puede experimentar la importancia del numero de Peclet Pe =|b|ν
con
respecto a la talla de la particion y la aparicion o no de inestabilidades en elcalculo. Lanzar el siguiente codigo ConveccionDifusionElipse.edp
19 Introduccion a FreeFem++
6.1 Opciones para plot 6 FORMULACION VARIACIONAL
border elipse(t=0,2*pi)x=2*cos(t);y=sin(t);label=1;
mesh Th=buildmesh(elipse(100));
plot(Th,wait=1);
fespace Vh(Th,P1);
Vh u,v;
real b1=1.0,b2=1.0,nu=0.1;
problem nombre(u,v)=int2d(Th2)(
nu*(dx(u)*dx(v)+dy(u)*dy(v))
)
+int2d(Th2)(
(b1*dx(u)+b2*dy(u))*v
)
-int2d(Th2)(1*v)+on(1,u=0);
for (int i=0;i<100;i++)
b1=sin(i*pi/2);
b2=cos(i*pi/2);
nombre;
plot(u,dim=3,fill=1,cmm="nu = "+nu);
6.1. Opciones para plot
Existen varias opciones una vez que se tiene una grafica en pantalla. Conla tecla ? se obtiene un menu de informacion con las distintas opciones cuandose tiene la malla
f o click del raton avanza el proceso
V muestra todos los vertices
+,- hace un zoom + ‘o -
= restaura el zoom
g muestra la geometrıa
m muestra la triangulacion
3 da una visualizacion 3D
20 Introduccion a FreeFem++
7 PROBLEMAS DE EVOLUCION EN TIEMPO
b muestra los numeros de referencia de los lados de los triangulos
Cuando se tiene el dibujo
ac y AC aumenta o disminuye el coeficiente de las flechas
b y g cambia el color de la grafica
f rellena color entre lıneas de mismo valor
v muestra los valores numericos en las lıneas de mismo valor
7. Problemas de evolucion en tiempo
Podemos resolver la ecuacion del calor
∂tu(t, x, y)− ν∆u(t, x, y) = f(t, x, y), (t, x, y) ∈ (0, T )× Ω,
u(t, x, y) = 0, (t, x, y) ∈ (0, T )× ∂Ω,
u(0, x, y) = u0(x, y), (x, y) ∈ Ω,
siendo ∂Ω la frontera de Ω. Usamos elementos finitos en espacio y diferenciasfinitas en tiempo. La idea es resolver cada nivel de tiempo apoyandose enel anterior de forma explıcita con Euler explıcito o de forma implıcita conEuler implıcito. Siempre es aconsejable hacerlo con Euler implıcito debido alas mejores propiedades de estabilidad del esquema.
La evolucion temporal se simula con un ciclo for o while.
Euler explıcito: Ponemos u0 = u0 y para n ≥ 1 resolvemos
un+1 − un
∆t− ν∆un = fn, Ω
un = 0, ∂Ω
u0 = u0, Ω.
La formulacion variacional queda como:Dado un, calcular un+1 ∈ Vh tal que
1
∆t
∫Ω
un+1v = ν
∫Ω
∇un · ∇v +
∫Ω
fn v +1
∆t
∫Ω
unv ∀v ∈ Vh
y aquı todo el calculo es explıcito pero menos estable, es decir, los pasosde tiempo deben ser mas pequenos.
21 Introduccion a FreeFem++
7 PROBLEMAS DE EVOLUCION EN TIEMPO
Euler implıcito: Ponemos u0 = u0 y para n ≥ 1 resolvemos
un+1 − un
∆t− ν∆un+1 = fn+1, Ω,
un = 0, ∂Ω
u0 = u, Ω.
con formulacion variacional:
Calcular un+1 ∈ Vh tal que
1
∆t
∫Ω
un+1v − ν∫
Ω
∇un+1 · ∇v =
∫Ω
fn+1 v +1
∆t
∫Ω
unv ∀v ∈ Vh
que es mas recomendable por ser mas estable, es decir, permite pasosde tiempo mas grandes.
Similarmente se puede usar Crank-Nicolson
Permitiendo transporte, ademas de difusion, podemos resolver el problema
∂tu− ν∆u+~b · ~∇u = f, (0, T )× Ω
u = 0, (0, T )× ∂Ω
u(0, x, y) = u0, Ω
donde b = (b1, b2) es la direccion del transporte. La forma mas convenientede resolver este problema es usando Euler implıcito:
Ponemos u0 = u0 y para n ≥ 1 resolvemos
un+1 − un
∆t− ν∆un+1 +~b · ~∇un+1 = fn+1, Ω
un = 0, ∂Ω
u0 = u0, Ω.
con formulacion variacional:Dado un calcular un+1 ∈ Vh tal que para todo v ∈ Vh
1
∆t
∫Ω
un+1v − ν∫
Ω
∇un+1 · ∇v +
∫Ω
~b · ~∇un+1 v =
∫Ω
fn+1 v +1
∆t
∫Ω
unv
22 Introduccion a FreeFem++
7 PROBLEMAS DE EVOLUCION EN TIEMPO
Figura 8: Vista 3D del valor final para difusion 2d. Observar que los valoresson pequenos, la solucion se desvanece.
Ejemplo 6 Aplicamos la ecuacion de difusion a una fuente de calor en undisco centrado en el rectangulo (0, 1)2 del plano.
Dato inicial para difusion 2d
Valor final para difusion 2d
Archivo Ecuacion_Calor2D_Euler_Implicito.edp
23 Introduccion a FreeFem++
7 PROBLEMAS DE EVOLUCION EN TIEMPO
//
// Resolvemos
// u_t-nu*Lap(u)=0 en el dominio
// u(0,x,y)=0 en la frontera
// u(t=0,x,y)=1 si ((x-0.5)^2+(y-0.5)^2<0.05) como dato inicial
// u(t=0,x,y)=1 si ((x-0.5)^2+(y-0.5)^2<0.05) como dato inicial
//
mesh Th=square(80,80);
fespace Vh(Th,P1); // P1 FE space
Vh uh0,uh1,vh; // unkown and test function.
real dt=0.1;
real alpha=1.0/dt;
real nu=1;
real t=0;// tiempo inicial
// dato inicial
uh0=1*((x-0.5)^2+(y-0.5)^2<0.05);
plot(Th,uh0,dim=3,fill=1,value=1,cmm="Valor inicial",wait=1);
//
// Esquema es (1/Dt)u^n+1-nu*Lap(u^n+1)=(1/Dt)u^n
//
// o bien, en formulacion variacional
//
// (1/Dt)(u^n+1,v)+nu*(Grad(u^n+1),Grad(v))
// -(1/Dt)(u^n,v)=0
//
problem EulerIm(uh1,vh) = // definion of the problem
int2d(Th)(alpha*uh1*vh) //(1/Dt)(u^n+1,v)
//+nu*(Grad(u^n),Grad(v))
+int2d(Th)( nu*(dx(uh1)*dx(vh) + dy(uh1)*dy(vh)) )
-int2d(Th)(alpha*uh0*vh)//-(1/Dt)(u^n+1,v)
+ on(1,2,3,4,uh1=0); // boundary condition form
for(int j=1;j<11;j++)
EulerIm; // solve the problem
t=t+dt;
// to see the result
24 Introduccion a FreeFem++
7 PROBLEMAS DE EVOLUCION EN TIEMPO
Figura 9: Valor final para difusion y transporte 2d
Figura 10: Vista 3D del valor final para difusion y transporte 2d
plot(Th,uh1,fill=1,value=1,dim=3,
cmm="Euler implicito para la ecuacion del calor.
Difusion "+nu+" tiempo total "+t,wait=1);
uh0=uh1;// actualizar
La modificacion a realizar si queremos tener transporte es muy facil:Archivo Difusion_Transporte_Euler_Implicito.edp
//
// Resolvemos
// u_t-nu*Lap(u)+b*Grad(u)=0 en el dominio
// u(0,x,y)=0 en la frontera
// u(t=0,x,y)=1 si ((x-0.5)^2+(y-0.5)^2<0.05) como dato inicial
25 Introduccion a FreeFem++
7 PROBLEMAS DE EVOLUCION EN TIEMPO
// u(t=0,x,y)=1 si ((x-0.5)^2+(y-0.5)^2<0.05) como dato inicial
//
mesh Th=square(80,80);
fespace Vh(Th,P1); // P1 FE space
Vh uh0,uh1,vh; // unkown and test function.
real dt=0.1;
real alpha=1.0/dt;
real nu=0.05;
real t=0;// tiempo inicial
// dato inicial
uh0=1*((x-0.5)^2+(y-0.5)^2<0.05);
plot(Th,uh0,fill=1,value=1,cmm="valor inicial",wait=1);
//
// Esquema es (1/Dt)u^n+1-nu*Lap(u^n+1)
// +b*Grad(u^n+1)*v-(1/Dt)u^n=0
//
// o bien, en formulacion variacional
//
// (1/Dt)(u^n+1,v)+nu*(Grad(u^n+1),Grad(v))
// +b*Grad(u^n+1)*v-(1/Dt)(u^n,v)=0
//
real b1=1.0,b2=1.0;
problem EulerIm(uh1,vh) = // definion of the problem
int2d(Th)(alpha*uh1*vh) //(1/Dt)(u^n+1,v)
//+nu*(Grad(u^n),Grad(v))
+int2d(Th)( nu*(dx(uh1)*dx(vh) + dy(uh1)*dy(vh)) )
+int2d(Th)( (b1*dx(uh1) + b2*dy(uh1))*vh)
-int2d(Th)(alpha*uh0*vh)//-(1/Dt)(u^n+1,v)
+ on(1,2,3,4,uh1=0); // boundary condition form
for(int j=1;j<=10;j++)
EulerIm; // solve the problem
t=t+dt;
// to see the result
plot(Th,uh1,dim=2,fill=1,value=1,
cmm="Difusion y transporte. tiempo total "+t,wait=1);
uh0=uh1;// actualizar
26 Introduccion a FreeFem++
8 CASO 3D
Figura 11: Construccion de geometrıa 3d con capas
8. Caso 3d
La construccion clave es la de las capas de tetraedros desde una trian-gulacion 2D y el visualizador mas conveniente es medit: La geometrıa massencilla se puede describir como
Ω3D = Ω2D × [zmin, zmax]
con funciones zmin < zmax : Ω2D 7→ R, ver Figura 11. La funcion basica esbuildlayers.
Ejemplo 7 Lanzar el codigo triangulo3d.edp:
load "msh3";
load "medit";
border a(t=0,1)x=t;y=0;;
border b(t=0,1)x=1-t;y=t;;
border c(t=0,1)x=0;y=1-t;;
int nn=1;
mesh Th2=buildmesh(a(nn)+b(nn)+c(nn));
int ncapas=1;
real zmin=0,zmax=2;
mesh3 Th=buildlayers(Th2,nlayers,zbound=[zmin,zmax]);
medit(" Triangle1capa ", Th);
savemesh(Th,"Th3d.mesh");
27 Introduccion a FreeFem++
8 CASO 3D
Figura 12: Sobre un triangulo se construyen tres tetraedros basicos, y seforma una capa. Generado con triangulo3d.edp
El archivo Th3d.mesh tiene toda la informacion relativa a la particion. Losdatos que aparecen son
MeshVersionFormatted 1
Dimension 3
Vertices
6
0 1 0 3
0 1 1 3
0 0 0 3
0 0 1 3
1 0 0 2
1 0 1 2
Tetrahedra
3
1 6 3 5 0
1 4 3 6 0
1 6 2 4 0
Triangles
8
2 4 6 0
5 3 1 1
1 3 4 2
4 2 1 2
5 1 6 3
28 Introduccion a FreeFem++
8 CASO 3D
Figura 13: Otra vista de los 3 tetraedros generados con triangulo3d.edpy se ven aquı los numeros que identifican las caras. Tambien se muestra elresultado de dos capas, ncapas=2
2 6 1 3
3 5 6 4
6 4 3 4
End
Ejemplo 8 Podemos generar un rectangulo 2d y sobre el construir un cuboa base de tetraedros. Lanzar el codigo cubo.edp
load "msh3"
load "medit"
int nn=1;
mesh Th2=square(nn,nn);
int nlayers=1;
real zmin=0,zmax=2;
mesh3 Th=buildlayers(Th2,ncapas,zbound=[zmin,zmax]);
medit(" Sol ", Th);
Las cotas mınimas y maximas en la generacion de capas zmin y zmax puedenser funciones.
Ejemplo 9 Lanzar el archivo buildlayermesh.edp:
//
// codigo buildlayermesh.edp
29 Introduccion a FreeFem++
8 CASO 3D
Figura 14: Triangulacion basica de un cubo y varias capa. Realizado concubo.edp .
Figura 15: Triangulacion 3D generada con buildlayermesh.edp
//
load "msh3"
load "medit"
border C0(t=0,2*pi) x=7*cos(t); y=10*sin(t);;
border C1(t=0,2*pi) x=3+2*cos(t); y=0.5*sin(t);;
mesh Th=buildmesh(C0(100)+C1(-20));
func zmin=-1+sin(x*y)/3;
func zmax=2;
int MaxLayer=10;
mesh3 Th3=buildlayers(Th, MaxLayer,zbound=[zmin,zmax]);
savemesh(Th3,"region1hole.mesh");
medit("regionwithhole",Th3);
30 Introduccion a FreeFem++
8.1 Etiquetado de los contornos 8 CASO 3D
Ejemplo 10 Se ve una geometrıa un poco mas elaborada en figura3d.edp
//
// codigo figura3d.edp
//
load "msh3"
load "medit"
real L=15;
real H=6;
border aa(t=0,L)x=t; y=0 ;label=1;
border bb(t=0,H)x=L; y= t ;label=2;
border cc(t=0,L)x=L-t; y=H ;label=3;
border dd(t=0,H)x= 0 ; y = H-t;label=4;
border C1(t=0,2*pi) x=3+0.5*cos(t); y=3+0.5*sin(t);label=5;
int n=6;
mesh Th2d=buildmesh(aa(9*n)+bb(4*n)+cc(9*n)+dd(4*n)+C1(-4*n));
plot(Th2d,wait=1,ps="superficie.eps");
func zmin=-1.5*(x<3)+(+1.5-x)*(x>3)*(x<7)-5.5*(x>7);
func zmax=1;
int[int] rup=[0,200], rdown=[0,100],rmid(10);
rmid=[1,11,2,22,3,33,4,44,5,55];
int MaxLayer=10;
mesh3 Th3=buildlayers(Th2d, MaxLayer,zbound=[zmin,zmax],
reffacemid=rmid,
reffaceup = rup,
reffacelow = rdown);
savemesh(Th3,"region1hole.mesh");
medit("regionconbujero",Th3);
8.1. Etiquetado de los contornos
Se usan variables enteras para modificar las etiquetas del contorno de lageometria 3D. Por defecto la superficie del fondo se etiqueta con 0 y laslaterales se heredan de las etiquetas 2d.
Se pueden cambiar las etiquetas de las superficies
labelup=[0,2] asigna 2 superficie superior.
labeldown=[0,1] asigna 1 superficie inferior.
31 Introduccion a FreeFem++
8.1 Etiquetado de los contornos 8 CASO 3D
Figura 16: Triangulacion con figura3d.edp
labelmid=[1,1,2,1,3,1,4,1,5,1] asigna 1 a todas las caras sobrelados 1, 2, 3,4,5.
La superficie 2D a partir de la que se generan las capas se etiqueta como0 y en el contorno de la geometrıa 3D la tapa superior se identifica con200 (arbitrario el 200) usando rup=[0,200],
luego la parte inferior se identifica con 100 usando rdown=[0,100] y
finalmente, cada etiqueta de cada borde de la superficie 2D se puedemodificar de acuerdo a rmid=[1,11,2,22,3,33,4,44,5,55]. Aquı, porejemplo, se usa el 11 para la cara que se asienta sobre el borde 1, el 22para la que se asienta sobre el 2, etc...
Las ordenes correspondientes son
int[int] rup=[0,200], rdown=[0,100],rmid(10);
rmid=[1,11,2,22,3,33,4,44,5,55];
Ejemplo 11 Se puede conseguir el efecto de una profundidad variable y deuna orilla:
32 Introduccion a FreeFem++
8.1 Etiquetado de los contornos 8 CASO 3D
Figura 17: Vistas diferentes con grosores distintos
load "msh3"
load "medit"
real eps=0.01;// grosor de la orilla
int nn=10;
border cc(t=0,2*pi)x=cos(t);y=sin(t);;
mesh Th2= buildmesh(cc(100));
func zmin= 2-sqrt(4-(x*x+y*y));// bottom
func zmax= eps+ 2-sqrt(3.);//surface
mesh3 Th=buildlayers(Th2,nn,
coef= max((zmax-zmin)/zmax,1./(nn*2)),
zbound=[zmin,zmax]);
medit("costa",Th);
Ejemplo 12 La resolucion de un problema de Laplace en dimension 3 espoco diferente del caso 2d. Lo unico es identificar las caras de la geometrıa3d donde plantear las condiciones de contorno:
//
33 Introduccion a FreeFem++
8.1 Etiquetado de los contornos 8 CASO 3D
Figura 18: −∆u = 1 con u = 0 en paredes verticales y ∂nu = 0 en base ytope.
// codigo Laplaciano3d.edp
//
load "msh3"
load "medit"
int nn=8;
mesh Th2=square(nn,nn);// 2D mesh
real zmin=0,zmax=2;
int[int] rup=[0,200],rdown=[0,100];
int[int] rmid=[1,1,2,1,3,1,4,1];
mesh3 Th=buildlayers(Th2,nn, zbound=[zmin,zmax],
labelup=rup, labeldown=rdown, labelmid=rmid);
func f=1. ;
fespace Vh(Th,P13d);
Vh u,v;
macro Grad3(u) [dx(u),dy(u),dz(u)] // EOM
problem Lap3d(u,v,solver=CG) =
int3d(Th)(Grad3(v)’ *Grad3(u))
- int3d(Th)(f*v)+ on(1,u=0);
Lap3d;
medit(" Laplacian3D ", Th, u );
Ejemplo 13 Se plantea el mismo problema en una geometrıa distinta:
//
// codigo discoLaplace3d.edp
34 Introduccion a FreeFem++
8.1 Etiquetado de los contornos 8 CASO 3D
//
load "msh3"
load "medit"
real eps=.015;// shore thickness
int nn=20;
border cc(t=0,2*pi)x=cos(t);y=sin(t);label=1;;
mesh Th2= buildmesh(cc(100));
func zmin= 2-sqrt(4-(x*x+y*y));// bottom
func zmax= eps+ 2-sqrt(3.);//surface
int[int] rup=[0,200],rdown=[0,100];
int[int] rmid=[1,1];
mesh3 Th=buildlayers(Th2,nn,
coef= max((zmax-zmin)/zmax,1./(nn*2)),
zbound=[zmin,zmax],
labelup=rup,
labeldown=rdown,
labelmid=rmid);
func f=1. ;
fespace Vh(Th,P13d);
Vh u,v;
//
macro Grad3(u) [dx(u),dy(u),dz(u)] // EOM
//
problem Lap3d(u,v,solver=CG) =
int3d(Th)(Grad3(u)’ *Grad3(v))
- int3d(Th)(f*v)
+ on(1,100, u=0);
Lap3d;
medit("myshore",Th,u);
35 Introduccion a FreeFem++
9 ECUACIONES DE NAVIER-STOKES
9. Ecuaciones de Navier-Stokes
9.1. Caso 2d
Las ecuaciones de Stokes en un dominio Ω ⊂ R2 consisten en:Buscamos ~u ∈ H1(Ω)2 y p ∈ L2(Ω) tal que
−∆~u+∇p = f en Ωdiv(~u) = 0 en Ω+C.C.
o bien,(∇~u,∇~v)Ω − (p, div(u))Ω = (f, v) en Ω
−(q, div(~u))Ω = 0 en Ω+C.C.
En el test de la cavidad se toma [0, 1] × [0, 1] con el par P2-P1 y el codigocon el que se calcula la aproximacion es el siguiente:
//
//Stokes2dCavity.edp
//
mesh Th=square(10,10);
fespace Xh(Th,P2);
fespace Mh(Th,P1);
Xh u1,v1,u2,v2;
Mh p,q;
solve Stokes (u1,u2,p,v1,v2,q) =
int2d(Th)( dx(u1)*dx(v1)+dy(u1)*dy(v1)
+dx(u2)*dx(v2)+dy(u2)*dy(v2)
-p*dx(v1)-p*dy(v2)
-q*dx(u1)-q*dy(u2)
)
+on(1,2,4,u1=0,u2=0)
+on(3,u1=1,u2=0); // C.C. en borde superior
plot(cmm=" Velocidad [u1,u2] ",[u1,u2]);
plot(cmm=" Presion ",p);
plot(cmm=" Velocidad y Presion ",[u1,u2],p);
Si ahora nos fijamos en las ecuacione de Navier-Stokes evolutivas:
36 Introduccion a FreeFem++
9.1 Caso 2d 9 ECUACIONES DE NAVIER-STOKES
Vec Value00.05263430.1052690.1579030.2105370.2631720.3158060.368440.4210750.4737090.5263430.5789780.6316120.6842470.7368810.7895150.842150.8947840.9474181.00005
Velocidad [u1,u2] IsoValue-49.7096-44.6966-39.6837-34.6708-29.6578-24.6449-19.632-14.619-9.6061-4.593170.4197625.4326910.445615.458620.471525.484430.497435.510340.523245.5362
Presion IsoValue-49.71-44.697-39.6841-34.6711-29.6581-24.6452-19.6322-14.6192-9.60627-4.59330.419675.4326410.445615.458620.471525.484530.497535.510440.523445.5364
Vec Value00.05263430.1052690.1579030.2105370.2631720.3158060.368440.4210750.4737090.5263430.5789780.6316120.6842470.7368810.7895150.842150.8947840.9474181.00005
Figura 19: Velocidad y presion Stokes2dCavity.edp
Buscamos u(t) ∈ H1(Ω)2 y p(t) ∈ L2(Ω) tal que
∂tu+ (u · ∇)u−∆u+∇p = f en Ωdiv(u) = 0 en Ω+C.C.
o bien,
( DDtu, v) + (∇u,∇v)Ω − (p, div(u))Ω = (f, v) en Ω
−(q, div(u))Ω = 0 en Ω+C.C.
Nonlinealidad tratada con convect que resuelve:
∂tφ+ u∇φ = 0,
φ(0, x) = φ0(x).
El codigo es el siguiente:
//
// codigo NS2d.edp
//
mesh Th=square(32,32);
fespace Xh(Th,P2);
fespace Mh(Th,P1);
Xh u2,v2, u1,v1,up1=0,up2=0;
Mh p,q;
real Re=5000,nu=1/Re;
real dt=0.1;
problem NS(u1,u2,p,v1,v2,q,solver=UMFPACK) =
37 Introduccion a FreeFem++
9.2 Caso 3d 9 ECUACIONES DE NAVIER-STOKES
Velocidad [u1,u2] Presion
velocidad y presion obtenidos con Cavity.edp
int2d(Th)( (1/dt)*(u1*v1+u2*v2)
+nu*(dx(u1)*dx(v1)+dy(u1)*dy(v1)
+dx(u2)*dx(v2)+dy(u2)*dy(v2) )
-p*dx(v1)- p*dy(v2)
+dx(u1)*q+ dy(u2)*q)
+int2d(Th)(
-(1/dt)*convect([up1,up2],-dt,up1)*v1
-(1/dt)*convect([up1,up2],-dt,up2)*v2
)
+on(1,2,4,u1=0,u2=0)+on(3,u1=1,u2=0);
for (i=0;i<=400;i++)
NS;
up1=u1;
up2=u2;
plot(coef=.5,cmm=" Velocidad ",[u1,u2]);
;
plot(cmm=" Pressure ",p);
9.2. Caso 3d
El paso del caso 2d al 3d se resuelve considerando la triangulacion 3d yanadiendo la tercera componente a la formulacion variacional:
Ejemplo 14 Vemos primero el caso de la cavidad 3d
38 Introduccion a FreeFem++
9.2 Caso 3d 9 ECUACIONES DE NAVIER-STOKES
//
// codigo Stokes3dcavity.edp
//
load "msh3";
load "medit";
int nn=15;
mesh Th2=square(nn,nn);// 2D mesh
fespace Vh2(Th2,P2);// cross-section space
Vh2 ux,uz,p2;
real zmin=0,zmax=1,yy;
int[int] rup=[0,200],rdown=[0,100];
int[int] rmid=[1,1,2,1,3,1,4,1];
mesh3 Th=buildlayers(Th2,nn, zbound=[zmin,zmax],
labelup=rup, labeldown=rdown, labelmid=rmid);// 3D mesh
fespace VVh(Th,[P23d,P23d,P23d,P13d]);
VVh [u1,u2,u3,p];
VVh [v1,v2,v3,q];
macro Grad(u) [dx(u),dy(u),dz(u)]// EOM
macro div(u1,u2,u3) (dx(u1)+dy(u2)+dz(u3)) //EOM
varf vStokes([u1,u2,u3,p],[v1,v2,v3,q]) =
int3d(Th)(Grad(u1)’*Grad(v1) +Grad(u2)’*Grad(v2)
+Grad(u3)’*Grad(v3)
- div(u1,u2,u3)*q - div(v1,v2,v3)*p
)
+on(1,100,u1=0,u2=0,u3=0)+ on(200,u1=1.,u2=0,u3=0) ;
matrix A=vStokes(VVh,VVh);
set(A,solver=GMRES);
real[int] b= vStokes(0,VVh);
p[]= A^-1 * b;
for(int i=1;i<10;i++)
yy=i/10.;
ux= u1(x,yy,y);
uz= u3(x,yy,y);
p2= p(x,yy,y);
plot([ux,uz],p2,cmm=" cut y = "+yy,wait= 1);
if (i==5)
plot([ux,uz],p2,cmm=" cut y = "+yy,wait= 1);;
39 Introduccion a FreeFem++
9.2 Caso 3d 9 ECUACIONES DE NAVIER-STOKES
cut y = 0.5
Figura 20: Problema de Stokes en el test de la cavidad.
Figura 21: Se pueden usar geometrias realisticas como esta del Puerto deCartagena.
;
medit("cavity3d",Th,p);
medit("cavity3d",Th,u3);
medit("cavity3d",Th,u2);
medit("cavity3d",Th,u1);
Ejemplo 15 Aplicacion de las ecuaciones de Stokes en el puerto de Carta-gena nos generan los resultados que se ven en la Figura 21
40 Introduccion a FreeFem++
Recommended