Sie sind auf Seite 1von 36

barra.

function [x,u] = barra(N)


x=linspace(0,1,N+1);
A=zeros(N-1,N-1);
F=zeros(N-1,1);
h=(1-0)/N;

for i=1:length(A) % Las filas de la matriz van desde i:N-1


for j=1:length(A) %Las columnas de la matriz van desde i:N-1
if i==j
A(i,j)=1+2/h^2;
elseif i==j+1
A(i,j)=-1/h^2;
elseif i==j-1
A(i,j)=-1/h^2;
else
A(i,j)=0; %Esta opcion es opcional ya que la matriz
inicialmente es de ceros
end
end
end

for m=1:length(F)
%Debido a que los valores de la frontera son 0, no habría que añadir
%nada sumando a la función.
F(m)= funcion(x(m+1));
%Empieza en 2 debido a que x(1) es en el primer valor del vector, y
%solo hay que utilizar los puntos intermedios, es decir todos los
%puntos menos el primero y el ultimo.
end
u=A\F;
Funcion.m

function m = funcion(x)
%m=1;
m=sin(2.*pi.*x);
end

Pintarbarra.m

function pintarbarra(N)
close all
inicial = 0;
final = 0;
[x,u] = barra(N);
%Ya que u solo tiene los valores de los puntos intermedios, habrá que
%añadirle el inicial y el final para poder representarlo.

y = zeros(1,N+1);
y(1) = inicial;
for i=1:length(u)
y(i+1) = u(i);
end
y(N+1) = final;

plot(x,y)
end

Por ejemplo para N=10.


Como se puede visualizar la barra adopta la forma de la carga aplicada f(x).

Sí, primero resuelto a mano y luego pasado a código.


Barra_c.m

function [x,u] = barra_c(N)


x=linspace(0,1,N+1);
A=zeros(N-1,N-1);
F=zeros(N-1,1);
h=(1-0)/N;

for i=1:length(A) % Las filas de la matriz van desde i:N-1


for j=1:length(A) %Las columnas de la matriz van desde i:N-1
if i==j
A(i,j)= funcion_c(i)+2/h^2; %Tanto i como j
elseif i==j+1
A(i,j)=-1/h^2;
elseif i==j-1
A(i,j)=-1/h^2;
else
A(i,j)=0; %Esta opcion es opcional ya que la matriz
inicialmente es de ceros
end
end
end

for m=1:length(F)
%Debido a que los valores de la frontera son 0, no habría que añadir
%nada sumando a la función.
F(m)= funcion(x(m+1));
%Empieza en 2 debido a que x(1) es en el primer valor del vector, y
%solo hay que utilizar los puntos intermedios, es decir todos los
%puntos menos el primero y el ultimo.
end
u=A\F;

Funcion_c.m

function m=funcion_c(x)
%m=1;
m=x^2*sin(x);
end

La función función.m sigue siendo igual, y en pintarbarra.m solo cambia el nombre con la
nueva función.
Por ejemplo para N=10.

Tanto para la funcion.m como 1 como sin(2*pi*x) se nota el claro efecto de c(x) =x ^2*sin(x)
por ejemplo, que es la función de oposición que hace el material de la barra al ser deformado.
funcionPhi.m

function y = funcionPhi(t)
y=cos(4*t);

funcionPsi.m

function y=funcionPsi(x)
y=0.5*ones(size(x));

transporte.m

function u=transporte(x,t,c)
% calcula u(x,t) solucion de la ecuacion de transporte con velocidad
c>0
% d_t u + c d_x u =0
% u(0,t)=phi(t)
% u(x,0)=psi(x)

%Calculamos el punto x0: x=ct+x0


x0=x-c*t;

% x0 esta dentro del tubo usamos psi


% Si x0 se sale del tubo usamos t0
% 0 = c t0 + x0;
t0=-x0/c;

u=funcionPsi(x0).*(x0>=0)+funcionPhi(t0).*(x0<0);
movieTransport.m

function movieTransport(L,T,c)
% Dibuja la solucion de la ecuacion del transporte
% d_t u + c d_x u =0
% u(0,t)=phi(t)
% u(x,0)=psi(x)
% para c>0 en el intervalo [0,L] para tiempos desde 0 hasta T
% L= longitud de la barra
% T= tiempo final

x=linspace(0,L,100);

%Pintamos primero la condicion inicial:


u=transporte(x,0,c);
plot(x,u);
%Para que la visualizacion sea siempre en el mismo marco, es mejor
%definirlo:
rango_visualizacion=[0 L -2 2];
axis(rango_visualizacion);
%de lo contrario, los ejes iran cambiando automaticamente y el efecto
no es
%el deseado

disp('Pulsa intro para continuar')


pause

tiempos=linspace(0,T,50);

for i=1:50
u=transporte(x,tiempos(i),c);
plot(x,u);
axis(rango_visualizacion);
pause(0.2);
end
Si iniciamos al movimiento con: movieTransport(10,5,1)

Al pulsar ENTER comienza la simulación, inicialmente una barra horizontal y conforme pasa el
tiempo, esta va cambiando a lo largo del tiempo. La función se desplaza hacia la derecha.
Ambas funciones, funcionPhi.m, funcionPsi.m son idénticas al apartado anterior, solo cambian:

movieTransport.m

function movieTransport(L,T,c)
% Dibuja la solucion de la ecuacion del transporte
% d_t u - c d_x u =0
% u(0,t)=phi(t)
% u(x,0)=psi(x)
% para c<0 en el intervalo [-L,0] para tiempos desde 0 hasta T
% L= longitud de la barra
% T= tiempo final

%Antes para (c>0) --> x=linspace(0,L,100);


x=linspace(-L,0,100); %Ahora para c<0

%Pintamos primero la condicion inicial:


u=transporte(x,0,c);
plot(x,u);
%Para que la visualizacion sea siempre en el mismo marco, es mejor
%definirlo:

%Antes para (c>0) --> rango_visualizacion=[0 L -2 2];


rango_visualizacion=[-L 0 -2 2]; %Ahora para c<0

axis(rango_visualizacion);
%de lo contrario, los ejes iran cambiando automaticamente y el efecto
no es
%el deseado

disp('Pulsa intro para continuar')


pause

tiempos=linspace(0,T,50);

for i=1:50
u=transporte(x,tiempos(i),c);
plot(x,u);
axis(rango_visualizacion);
pause(0.2);
end
transporte.m

function u=transporte(x,t,c)
% calcula u(x,t) solucion de la ecuacion de transporte con velocidad
c<0
% d_t u - c d_x u =0
% u(0,t)=phi(t)
% u(x,0)=psi(x)

%Calculamos el punto x0: x=-ct+x0

%Antes (c>0) --> x0=x-c*t;


x0=x+c*t; %Ahora para c<0

% x0 esta dentro del tubo usamos psi


% Si x0 se sale del tubo usamos t0
% 0 = - c t0 + x0;

%Antes (c>0) --> t0=-x0/c;


t0=x0/c; %Ahora para c<0

u=funcionPsi(x0).*(x0>=0) + funcionPhi(t0).*(x0<0);

Si iniciamos el movimiento con: movieTransport(10,5,1)


Al pulsar ENTER comienza la simulación, inicialmente una barra deformada y conforme pasa el
tiempo, esta va cambiando a lo largo del tiempo.

Pasados unos segundos vemos el desplazamiento hacia la izquierda de la función.


a)

velocidadc.m

function z=velocidadc(x,t)

z=x;

funcionPsi.m

function y=funcionPsi(x)

y=cos(2*x);

solucionu.m

function u=solucionu(x,t)
%Devuelve el valor de la funcion u(x,t)

x0=x./exp(t);

u=funcionPsi(x0);

curva_caracteristica.m

function x=curva_caracteristica(x0,t)
%Devuelve el valor de la curva caracteristica que pasa por x0
%Por ejemplo, para c(x,t)=x, la curva es x=x0*exp(t)

x=x0*exp(t);
movieTransport.m

function movieTransport(a,b,T)
% Dibuja la solucion de la ecuacion del transporte
% d_t u + c(x,t) d_x u =0
% u(x,0)=psi(x)
% para c>0 en el intervalo [a,b] para tiempos desde 0 hasta T
% L= longitud de la barra
% T= tiempo final
x=linspace(a,b,200);
tiempos=linspace(0,T,50);
% Codigo para pintar las curvas características:
close all;
subplot(2,1,2);
hold on;
xlabel('x');
ylabel('t');
x0=linspace(a,b,20);

for i=1:length(x0)
xcurva=curva_caracteristica(x0(i),tiempos);
plot(xcurva,tiempos);
axis([a b 0 T]);
end
title('Curvas caracteristicas');

xcurva1=curva_caracteristica(x0(11),tiempos);
xcurva2=curva_caracteristica(x0(14),tiempos);
p1=plot(xcurva1(1),0,'ro');
p2=plot(xcurva2(1),0,'ro');

subplot(2,1,1);
%Pintamos primero la condición inicial:
u=funcionPsi(x);
plot(x,u);
hold on;
plot(xcurva1(1),funcionPsi(xcurva1(1)),'ro');
plot(xcurva2(1),funcionPsi(xcurva2(1)),'ro');
hold off;
%Para que la visualización sea siempre en el mismo marco, es mejor
%definirlo:
rango_visualizacion=[a b -2 2];
axis(rango_visualizacion); %de lo contrario, los ejes irán cambiando
automáticamente y el efecto no es el deseado
title('Funcion u(x,t)')
disp('Pulsa intro para continuar')
pause
for i=1:50
u=solucionu(x,tiempos(i));
plot(x,u);
hold on;
plot(xcurva1(i),solucionu(xcurva1(i),tiempos(i)),'ro');
plot(xcurva2(i),solucionu(xcurva2(i),tiempos(i)),'ro');
hold off;
set(p1,'xdata',xcurva1(i),'ydata',tiempos(i));
set(p2,'xdata',xcurva2(i),'ydata',tiempos(i));
axis(rango_visualizacion);
pause(0.2);
end
𝑑𝑥 𝑑𝑥 𝑑𝑥
𝑐(𝑥, 𝑡) = 𝑥 → =𝑥 → = 𝑑𝑡 → ∫ = ∫ 𝑑𝑡 → ln(𝑥) = 𝑡 + 𝑐
𝑑𝑡 𝑥 𝑥

→ ln(𝑥) = 𝑡 + 𝑐 → x = 𝑒𝑡 ∗ 𝑐 → 𝑥 = 𝑒𝑡 ∗ 𝑐

𝑥(0) = 𝑥0 = 𝑒 0 ∗ 𝑐 → 𝑐 = 𝑥0

𝑥 = 𝑥0 ∗ 𝑒 𝑡 → Curva característica.

𝑥
𝑥0 = → Solución u.
𝑒𝑡

𝑐(𝑥, 𝑡) = 𝑥 → Velocidad c.

𝜓(𝑥) = cos(2𝑥) → FunciónPsi.

Al abrir los ficheros curva_caracteristica.m, velocidadc.m y solucionu.m nos damos cuenta de


que para la curva_caracteristica está definida la función 𝑥 = 𝑥0 ∗ 𝑒 𝑡 que es la anteriormente
calculada y es la que definirá las curvas características y se puedan pintar posteriormente
𝑥
Para la solución u, ésta contiene 𝑥0 = que es la consecuencia de despejar x0 de la ecuación
𝑒𝑡
anterior, ésta definirá el inicio de la función.

Y para la velocidad, nos encontramos un parámetro x, donde c(x) = x es decir c depende de una
función, en este caso x, pero podría ser cualquiera, que al o largo de su posición puede
cambiar.
𝑑𝑥 𝑑𝑥 𝑑𝑥
𝑐(𝑥, 𝑡) = 2 − 𝑥 → =2−𝑥 → = 𝑑𝑡 → ∫ = ∫ 𝑑𝑡 → −ln(2 − 𝑥) = 𝑡 + 𝑐
𝑑𝑡 2−𝑥 2−𝑥

→ ln(2 − 𝑥) = −𝑡 + 𝑐 → 2 − x = 𝑒 −𝑡 ∗ 𝑐 → 𝑥 = −𝑒 −𝑡 ∗ 𝑐 + 2

𝑥(0) = 𝑥0 = −𝑒 −0 ∗ 𝑐 + 2 → 𝑐 = −𝑥0 + 2

𝑥 = 2 + (𝑥0 − 2) ∗ 𝑒 −𝑡 → Curva característica.

𝑥0 = 2 + (𝑥 − 2) ∗ 𝑒 𝑡 → Solución u.

𝑐(𝑥, 𝑡) = 2 − 𝑥 → Velocidad c.

𝜓(𝑥) = sin(4𝑥) → FunciónPsi.

velocidadc.m

function z=velocidadc(x,t)

z=2-x;

funcionPsi.m

function y=funcionPsi(x)

y=sin(4*x);

solucionu.m

function u=solucionu(x,t)
%Devuelve el valor de la funcion u(x,t)

x0=2+(x-2).*exp(t);

u=funcionPsi(x0);
curva_caracteristica.m

function x=curva_caracteristica(x0,t)
%Devuelve el valor de la curva caracteristica que pasa por x0
%Por ejemplo, para c(x,t)=2-x, la curva es x=2+(x0-2).*exp(-t);

x=2+(x0-2).*exp(-t);

El fichero movieTransport.m sigue siendo el mismo que en el apartado a.

Si iniciamos el movimiento con: movieTransport(-5,1.9,1)


La función movieTransport.m no cambia.

Solo cambia las siguientes:

velocidadc.m

function z=velocidadc(x,t)

z=2;

funcionPsi.m

function y=funcionPsi(x)

y=1*(x<0.5)+0.5*(x>=0.5);

solucionu.m

function u=solucionu(x,t)
%Devuelve el valor de la funcion u(x,t)

x0=x-2*t;

u=funcionPsi(x0);

curva_caracteristica.m

function x=curva_caracteristica(x0,t)
%Devuelve el valor de la curva caracteristica que pasa por x0
%Por ejemplo, para c(x,t)=2, la curva es x=2*t +x0;

x=2*t +x0;
Dando resultados para: movieTransport(0,1,1)

Se desplaza hacia la derecha hasta desaparecer.


movieTransport.m

function movieTransport(L,T,dx,dt)
% Calcula la solucion del transporte con flujo dado por la funcion flujo.m
% mediante el metodo de diferencias finitas
% Dibuja la solucion de la ecuacion del transporte
% d_t u + d_x(F(u)) =0
% u(0,t)=phi(t)
% u(x,0)=psi(x)
%
% L= longitud de la barra
% T= tiempo final
% dx= paso en la variable x
% dt= paso en la variable t
nx=round(L/dx);
nt=round(T/dt);
x=linspace(0,L,nx+1);
tiempos=linspace(0,T,nt+1);
rango_visualizacion=[0 L -0.5 1.5];

cfl=dt/dx;

u0=funcionPsi(x);
u=zeros(1,nx);

%Pintamos primero la condicion inicial:


plot(x,funcionPsi(x));
axis(rango_visualizacion);
disp('Pulsa intro para continuar')
pause

%bucle para ir pintando los distintos tiempor t0, t1, t2, t3, ...
for n=1:nt
%bucle para calcular u(x_i,tn)
for i=2:nx+1
u(i)=u0(i)-cfl*(flujo(u0(i))-flujo(u0(i-1)));
end
%El primero lo tengo que calcular usando la condicion de frontera
u(1)=funcionPhi(tiempos(n));

%Para la siguiente iteracion empiezo por el nuevo que acabo de calcular


%dibujo en el rango de visualizacion
plot(x,u);
axis(rango_visualizacion);
pause(0.2);

u0=u;
end
flujo.m

function y=flujo(u)
c=1;
y=c*u;

funcionPhi.m

function y = funcionPhi(t)
y=1;
end

funcionPsi.m

function y=funcionPsi(x)
y=1*(x<0.5)+0.5*(x>=0.5);
end

Ejecutando con: movieTransport(1,0.25,0.01,0.005)


Ejecutando con: movieTransport(1,0.25,0.005,0.0025)
movieTransport(1,0.25,0.001,0.00025)

La primera evoluciona mucho más rápido que la segunda y con poco tiempo evoluciona rápido
pero con incrementos pequeños

La segunda evoluciona mucho más lenta que la primera. Con incrementos pequeños.
movieTransport(1,0.25,0.01,0.003)

Velocidad normalita a cambios grandes


movieTransport(1,0.25,0.01,0.005)

Muy parecida pero mejorando el tiempo


movieTransport(1,0.25,0.01,0.008)

Igual que antes pero un poco mas rapido


movieTransport(1,0.25,0.01,0.015)

Este efecto tan raro, significa que el código ha explotado, no significan nada.
movieTransport(1,0.25,0.01,0.02)

Cuando se acercan a ser iguales ocurre un fenomeno un tanto extraño.

Este efecto tan raro, significa que el código ha explotado, no significan nada.
C=2
movieTransport(1,0.25,0.01,0.003)
movieTransport(1,0.25,0.01,0.005) – mas de lo mismo.

movieTransport(1,0.25,0.01,0.008)
movieTransport(1,0.25,0.01,0.015)

movieTransport(1,0.25,0.01,0.02)

Este efecto tan raro, significa que el código ha explotado, no significan nada.

¿Qué ocurre? ¿Qué pasa cuando d_t = d_x?

-Cuando se aproximan el código explota.

Das könnte Ihnen auch gefallen