Resumen: En este ejemplo vamos a considerar un problema relativo a la ecuación del calor en el que el coeficiente de conductividad térmica es una matriz no constante. En la discretización en tiempo se consideran los métodos implícitos de Euler y de Gear.
Sean
donde
Para calcular una solución aproximada, procedemos como sigue:
Discretizamos en tiempo tratando la variable
Cada problema estacionario se discretiza mediante el método de los elementos finitos sobre una triangulación dada, como en los ejemplos de problemas elípticos considerados con anterioridad.
Consideramos una partición uniforme del intervalo
Para cada
Denotamos
Para
Para
se tiene la siguiente ecuación (aproximada)
Para cada
Por tanto, el esquema discreto en tiempo es como sigue: dado
Obsérvese que, para cada
El espacio natural para buscar la solución del problema
Obsérvese que todos los problemas
y que solo difieren en la forma lineal. En la resolución numérica, esto se traduce en el hecho de que todos los sistemas lineales a resolver tienen la misma matriz, que, por lo tanto, solo habrá que construir y factorizar la primera vez.
Resolvemos el problema para:
x
//
// Problem data
//
real L = 10., T = 3.;
real f0 = 1., x1 = -4., x2 = -3., y1 = 2.5, y2 = 3.5;
real mu0 = 1., sigma0 = 0.5;
real sigma = -0.5/sigma0;
func K11 = 1.+x*x;
func K22 = 1.+y*y;
func K12 = 0.1*x*y;
func f = f0*(x1 < x)*(x < x2)*(y1 < y)*(y < y2);
func u0 = mu0 * exp(sigma*(x*x+y*y));
//
// Discretization data
//
int nt = 50, nx = 50, ny = 50;
real dt = T/nt, undt = 1./dt;
//
// Mesh
//
mesh Th = square(nx, ny, [L*(-1+2*x), L*(-1+2*y)]);
plot(Th, wait=true);
//
// FE space:
//
fespace Vh(Th,P1);
Vh u, v;
Vh fh = f, uold;
plot(fh, fill = true, value = true,
cmm = "PDE right hand side", wait = true);
//
// Problem
// Option "solver" allow to choose the method to use
problem Heat2DEuler(u , v, solver = Cholesky, init = 1) =
int2d(Th)(undt * u*v + K11*dx(u)*dx(v) + K22*dy(u)*dy(v)
+ K12*(dx(u)*dy(v) + dy(u)*dx(v)))
- int2d(Th)(fh*v) - int2d(Th)(undt*uold*v)
+ on(1,2,3,4, u = 0.);
//
// Computations and plots
//
u = u0;
plot(u, nbiso = 40, dim = 3, fill=true,
cmm = "Initial u, t = 0", wait = true);
real t;
for (int k = 1; k < nt+1; k ++){
uold = u;
t = k*dt;
Heat2DEuler;
plot(u, nbiso = 40, dim = 3, fill=true, value = true,
cmm = "Solution al t = " + t, wait=true);
}
// Use the "prev=true" option in plots with t > 0
// to preserve the aspect ratio of previous plot
Consideramos ahora una discretización en tiempo usando el esquema implícito de Gear de dos pasos:
Sustituyendo en la ecuación diferencial de
Para cada
Por tanto, el algoritmo completo es como sigue:
xxxxxxxxxx
//
// Data
//
real L = 10., T = 3.;
real f0 = 1., x1 = -4., x2 = -3., y1 = 2.5, y2 = 3.5;
real mu0 = 1., sigma0 = 0.5;
real sigma = -0.5/sigma0;
func K11 = 1.+x*x;
func K22 = 1.+y*y;
func K12 = 0.1*x*y;
func f = f0*(x1 < x)*(x < x2)*(y1 < y)*(y < y2);
func u0 = mu0 * exp(sigma*(x*x+y*y));
// Discretization data
int nt = 50, nx = 50, ny = 50;
real dt = T/nt;
real dt1 = 1./dt, dt2 = 0.5*dt1, dt3 = 3.*dt2, dt4 = 2*dt1;
//
// Mesh
//
mesh Th = square(nx, ny, [L*(-1+2*x), L*(-1+2*y)]);
plot(Th, wait=true);
//
// FE space:
//
fespace Vh(Th,P1);
Vh u, v;
Vh fh = f, uold1, uold2;
// uold1 --> u_{i-1}, uold2 --> u_{i-2}
plot(fh, fill = true, value = true, cmm = "PDE right hand side", wait = true);
//
// Problem for the first step: Euler squeme
//
uold1 = u0;
plot(uold1, nbiso = 40, dim = 3, fill=true, cmm = "Initial u, t = 0", wait = true);
solve Euler(u , v, solver = Cholesky) =
int2d(Th)(dt1 * u*v + K11*dx(u)*dx(v) + K22*dy(u)*dy(v)
+ K12*(dx(u)*dy(v) + dy(u)*dx(v)))
- int2d(Th)(fh*v) - int2d(Th)(dt1*uold1*v)
+ on(1,2,3,4, u = 0.);
plot(u, nbiso = 40, dim = 3, fill=true, cmm = "Solution u, t = "+ dt, wait = true);
//
// Problem for Gear steps
problem Heat2DGear(u , v, solver = Cholesky, init = 1) =
int2d(Th)(dt3 * u*v + K11*dx(u)*dx(v) + K22*dy(u)*dy(v)
+ K12*(dx(u)*dy(v) + dy(u)*dx(v)))
- int2d(Th)(fh*v) - int2d(Th)(dt4*uold1*v) + int2d(Th)(dt2*uold2*v)
+ on(1,2,3,4, u = 0.);
//
// Computations of Gear steps
//
real t;
for (int k = 2; k < nt+1; k ++){
uold2 = uold1;
uold1 = u;
t = k*dt;
Heat2DGear;
plot(u, nbiso=40, dim = 3, fill=true, value = true, prev = true,
cmm = "Solution al t = " + t, wait=true);
}
Resolver el problema
Condición de Neumann homogénea sobre toda la frontera del dominio:
Condición de Fourier sobre toda la frontera:
Condiciones mixtas Dirichlet-Neumann, tomando
Anna Doubova - Rosa Echevarría - Dpto. EDAN - Universidad de Sevilla