Está en la página 1de 11

function Ecuacion_del_Calor

%% Solucin en Volmenes Finitos para la ecuacion del calor en 2-D.


%% Ecuacin del calor: div( Gamma grad phi)+ S= d(rho phi)/dt
%%
%%
%% phi = energa interna (J kg^-1)
%% T = Temperatura (deg)
%% Gamma = K/c (-)
%% K = Conductividad trmica (W m^-1 deg^-1)
%% c = Calor especfico (J kg^-1 deg^-1)
%% S = fuente (W m^-3)
%% + S_C + S_P phi
%% rho = densidad
%%
%%
%% Condiciones de frontera segn la aproximacin de Patankar - volmenes
medios en fronteras.

%% - Cantidad especificada phi_u(x) en la superficie superior


%% - Flujos especficos q_e, q_w, and q_d a travs de los otros tres
lados del dominio
%%
%% Propiedades del material
%% La K vara con la posicin (x,z)
%%
%% Fuente
%% Fuente S = S_C + S_P * T
%
%% Este programa principal establece:
%% - Geometria del mallado (X_P, Z_P, X_edges, Z_edges)
%% - Informacion de la discretizacion temporal (nt, dt)
%% - Propiedades material (K_P)
%% - Fuentes (S_C, S_P)
%% - Condiciones iniciales (phi_0)
%% - Condiciones de frontera (phi_u, q_d, q_e, q_w)

%% Mallado de volmenes finitos


%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Dimensiones espaciales
% -----------------
Lx = 20; % Extension del dominio en x
%
nx = 18; % Nmero de volmenes de control en x.
Numero mayor que 1.
dx = Lx/max((nx-1),1 ); % Ancho del volumen en x
% La funcion max previene que la division
sea entre cero en 1-D (por ejemplo cuando nx=1)
%
Lz = 20; % Extension del dominio en z
%
nz = 21; % Numero de volumenes de control en z
dz = Lz/max((nz-1),1 ); % Altura de los volumenes de control en z
%% Establecer las matrices X_P, Z_P - definiendo las coordenadas (x,z)
de los centros de los volumenes finitos
x_P_vec = dx * (0:(nx-1) );
z_P_vec = dz * (0:(nz-1) )';
X_P = repmat(x_P_vec,nz,1);
Z_P = repmat(z_P_vec,1,nx);
%
%
%% Establecer las matrices del X_bordes, Z_bordes - definiendo las
coordenadas (x,z) de las interfaces de los volumenes finitos
X_edges = [ X_P(:,1) (X_P(:, 1:end-1) + diff(X_P')'/2) ...
X_P(:,end) ];
%
Z_edges = [ Z_P(1,:)' (Z_P(1:end-1, :) + diff(Z_P)/2)' ...
Z_P(end,:)' ]';
%
%
% Dimension del tiempo
% ---------------
sec_per_year = 365.25*24*3600;

%% Lt = 5; % Duracion total del tiempo de


integracion
%% nt = 101; % Numero de instantes de tiempo
Lt = 1; % Duracion total del tiempo de
integracion
nt = 51; % Numero de instantes de tiempo
dt_yr = Lt/max((nt-1),1); % Paso temporal en aos
dt = dt_yr * sec_per_year;

%% Condiciones de frontera
%%%%%%%%%%%%%%%%%%%%%%%%%
%% Flujo a traves de las fronteras este, oeste y abajo.
% q_d es negtivo a causa de que el calor fluye hacia espesores
% decrecientes.
q_d_0 = -0.50; % W m^-2
q_e_0 = 0.0; % W m^-2
%% q_w_0 = -0.50; % W m^-2
q_w_0 = 0.0; % W m^-2
%
% This code sets of simple steady B.C.s
% put "interesting" transient B.C.s into these matrices
q_d = repmat( q_d_0, nt, nx );
q_w = repmat( q_w_0, nz, nt );
q_e = repmat( q_e_0, nz, nt );
%
%
%% Temperatura phi_u en la frontera superior
% -------------------------------------
phi_u_0 = -20; % deg C
%
% Temperatura superficial cosntante y uniforme
%% phi_u = repmat( phi_u_0, nt, nx );
%
% No estacionario pero uniforme espacialmente
phi_range = 5;
time_vec = dt_yr * (0:(nt-1));
phi_seasonal = phi_u_0 + phi_range * sin( 2*pi * time_vec );
phi_u = repmat( phi_seasonal', 1, nx );
%

%
%% Parametros del material
%%%%%%%%%%%%%%%%%%%%%%%
% Establecer la matriz de propiedades trmicas. (Ejemplo: conductividad
uniforme)
K_0 = 2.0; % W m^-1 deg^-1
K_P = repmat( K_0, size(X_P) );
%
%
% Establecer la matriz de densidad. (Ejemplo: Uniforme en el dominio)
rho_0 = 900; % kg m^-3 (e.g. ice)
rho_P = repmat( rho_0, size(X_P) );
%
%
% Establecer el calor especfico. (Ejemplo: Uniforme en el dominio)
c_0 = 2000; % J kg^-1 deg^-1
c_P = repmat( c_0, size(X_P) );
%
%
% Establecer una matriz Gamma genrica. -Para flujo de calor Gamma=K/c.
%% Gamma_P = K_P./c_P;
rho_c_P = rho_P.* c_P;
%
%% Trmino de fuente
%%%%%%%%%%%%%%%%%%%%%
% S = S_C + S_P * phi_P

% spatially uniform source term, no dependence on solution phi

S_C_0 = 0; % W m^-3 s^-1


S_P_0 = 0; % W m^-3 s^-1 deg^-1
%
S_C = repmat( S_C_0, size(X_P) ); %#ok<RPMT0> % Termino de
fuente constante.
S_P = repmat( S_P_0, size(X_P) ); %#ok<RPMT0> % Terminode fuente
funcin de phi.

% Condiciones iniciales
% -----------------
%% phi_0 = zeros( size(X_P) );
%% phi_0 = repmat( phi_u, nz,1 )...
%% - [ Z_P(1,:)' cumsum(diff(Z_P))']'.* repmat(q_d, nz,1)./ K_P;
%
% Por ejemplo, establecer el valor inicial constante, igual a la
condicion de frontera en la frontera superior.
phi_0 = repmat( phi_u(1,:), nz, 1 );

%
% Resolver para phi(x,z,t) en volmenes finitos
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
phi = fvm_discretizacion( X_edges, Z_edges, X_P, Z_P, ...
nt, dt, rho_c_P, K_P, S_C, S_P,
...
phi_0, phi_u, q_d, q_e, q_w );
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%
%
dt %#ok<NOPRT>
rho_c_dz_2_over_2K = rho_c_P(1,1)*(Z_P(2,1)-Z_P(1,1)).^2/(2 * K_P(1,1))
%#ok<NOPRT,NASGU>

%% Graficacion de resultados
%
% Graficar conductividad (K_z)
% -----------------------
figure(1)
hold on; grid on; box on
surf(X_P, Z_P, K_P )
colorbar
zlabel('Conductividad (W m^{-1} deg^{-1})')
xlabel('Profundidad (m)')
title('Conductividad K_P')

% Graficar fuente (S_C)


% -----------------
figure(2)
hold on; grid on; box on
surf(X_P, Z_P, S_C )
colorbar
zlabel('Fuente S_C (W m^{-3})')
xlabel('Distancia (m)')
ylabel('Profundidad (m)')
title('Termino de fuente S_C')

% Graficar fuente (S_P)


% -----------------
figure(3)
hold on;
surf(X_P, Z_P, S_P )
colorbar
zlabel('Fuente S_P (W m^{-3} deg^{-1})')
xlabel('Distancia (m)')
ylabel('Profundidad (m)')
title('Trmino fuente S_P')
%

% 2-D, Graficar la solucin de phi(x,z)


% --------------------------------------------------
figure(2)
hold on
surf(X_P, Z_P, phi )
colorbar
xlabel('Distancia (m)')
ylabel('Profundidad (m)')
title('Mtodo de los Volmenes Finitos')
end
function phi = fvm_discretizacion( X_edges, Z_edges, X_P, Z_P, ...
nt, dt, rho_c_P, K_P, S_C, S_P,
...
phi_0, phi_u, q_d, q_e, q_w )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Esta funcion calcula phi(x,z), para una conductividad K_P(x,z) y una
fuente S dada.
%% Uso del mtodo de volumenes finitos de Patankar
%%
%% Condiciones de frontera
%% --------------------
%% En cada paso de tiempo
%% vector phi_u especifica el valor de phi en la frontera superior
%% vector q_w especifica el flujo en frontera oeste
%% vector q_e especifica el flujo en la frontera este
%% vector q_d especifica el flujo en la frontera inferior
%%
%%
%% Condiciones iniciales:
%% -------------------
%% phi = phi_0
%%
%% a_P = Coeficiente de phi_P en el punto P = (i,j)
%% a_E = Coeficiente de phi_E en el punto este de (i,j)
%% a_W, a_U, a_D para puntos Oeste, Arriba, Abajo
%% a_P_0 = Coeficiente de phi_P_0, conocido phi en el paso de tiempo
previo
%%
%% Sistema de ecuaciones para resolver phi
%%
%% big_A * phi = rhs
%%
%% big_A = matriz de coeficientes a_E etc, modificado para incluir BC
%% phi = valores desconocidos en los volumenes de control
%% rhs = Vector columna de condiciones inciales, trminofuente y
trminos BC
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Esquemas numricos segun valor de theta

% theta = 1 implicito
% theta =0.5 Crank-Nicolson
% theta = 0 explicito
% ------------------------------------------
theta = 1;

%% Inicializacin

% Geometra
% --------
%
% Obtener dX, dZ - espaciado entre los bordes del volumen finito
% -------------------------------------------------
dX = diff(X_edges')';
dZ = diff(Z_edges);
%
%
% Obtener dX_E, dx_W, dZ_U, dZ_D -
% - Distancias a los centros de volumenes adyacentes
% -----------------------------------------------
dX_e = diff(X_P')';
% Agregar la fila fictica en el borde este para mantener el tamao
[nx, nz]
dX_e = [ dX_e dX_e(:,end) ];
%
dX_w = diff(X_P')';
% Agregar la fila ficticia en el borde oeste para mantener el tamao
[nz, nx]
dX_w = [ dX_w(:,1) dX_w ];
%
dZ_u = diff(Z_P);
% Agregar la fila ficticia en el borde superior para mantener el tamao
[nz, nx]
dZ_u = [ dZ_u(1,:)' dZ_u' ]';
%
dZ_d = diff(Z_P);
% Agregar la fila ficticia en el borde inferior para mantener el tamao
[nz, nx]
dZ_d = [ dZ_d' dZ_d(end,:)' ]';
%
%
% Obtener f_e, f_w, f_u, f_d
% - distancias fraccionadas entre la interfaz del volumen y los
centros de volumenes adyacentes.
%
% ---------------------------------------------------
f_e = ones(size(X_P)) - (X_edges(:,2:end) - X_P)./ dX_e;
%
f_w = ones(size(X_P)) - (X_P - X_edges(:,1:(end-1)) )./ dX_w;
%
f_u = ones(size(Z_P)) - (Z_P - Z_edges(1:(end-1),: ))./ dZ_u;
%
f_d = ones(size(Z_P)) - (Z_edges(2:end,: ) - Z_P)./ dZ_d;
%

% Conductividades
%%%%%%%%%%%%%%%%%%%
% Si K = K(t), entonces las conductividades necesitan ser calculadas
dentro de los bucles de pasos temporales
%
% Establecer las matrices para conductividades en volumenes adyacentes.
% ------------------------------------------------------
K_E = [ K_P(:,2:end) K_P(:, end) ];
K_W = [ K_P(:,1) K_P(:,1:end-1) ];
K_U = [ K_P(1,:)' K_P(1:end-1,:)' ]';
K_D = [ K_P(2:end,:)' K_P(end,:)' ]';
%
%
% Establecer las matrices de conductividad en la interfaz
% ---------------------------------------
K_e = 1./ ( (1 - f_e)./K_P + f_e./K_E );
K_w = 1./ ( (1 - f_w)./K_P + f_w./K_W );
K_u = 1./ ( (1 - f_u)./K_P + f_u./K_U );
K_d = 1./ ( (1 - f_d)./K_P + f_d./K_D );
%
%
% Establecer los coeficientes en los puntos adyacentes.
% ---------------------------------------
% Si rho_c = rho_c(t), entonces a_P_0 necesita ser calculada dentro de
los bucles de pasos temporales

a_E = (K_e ./ dX_e).* dZ;


a_W = (K_w ./ dX_w).* dZ;
a_U = (K_u ./ dZ_u).* dX;
a_D = (K_d ./ dZ_d).* dX;
a_P_0 = (rho_c_P./dt).*dX.*dZ;

%
%
% Graficar la solucin actual
figure(5)
surf( X_P, Z_P, phi_0 )
colorbar
set(gca,'zlim', [ min(min(phi_u)), 0 ] )
xlabel('Distancia (m)')
ylabel('Profundidad (m)')
zlabel('Temperatura (^oC)')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% EL bucle de pasos temporal empieza aqui
% (Las condiciones de frontera pueden depender del tiempo)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
for i_time=1:nt

% Genera la matriz b -Incluye laparte constante de la matriz fuente S


% S= S_C + S_P* phi_P
% A continuacin se aaden la contribucin de la condicin de
frontera.
% Las contribuciones de la condicin inicial se aader tambin en cada
paso de tiempo
% b = S_C dX dZ + a_P_0.* T_P_0
% Se calcula dentro del paso temporal en caso de que S_C=S_C(t)
% ---------------------------------------------------------------
% b_0= S_C*dX*dZ
% cuando se usa theta < 1 necesitamos la solucin en todas las
vecindades.
phi_0_E = [ phi_0(:,2:end) phi_0(:, end) ];
phi_0_W = [ phi_0(:,1) phi_0(:,1:end-1) ];
phi_0_U = [ phi_0(1,:)' phi_0(1:end-1,:)' ]';
phi_0_D = [ phi_0(2:end,:)' phi_0(end,:)' ]';
% Imponer condicin inicial (para este paso de tiempo) en b.
%% b = S_C*dX*dZ+ a_P_0 .* phi_0;
b = S_C.* dX.* dZ +( 1 - theta ) * ...
(a_E.*phi_0_E + a_W.*phi_0_W + a_U.*phi_0_U + a_D.*phi_0_D)
...
+ (a_P_0 - (1 - theta) * (a_E + a_W + a_U + a_D) ).* phi_0;

% Calcular coeficiente en el punto central P


% incluye el termino fuente dependiente de phi(t) S_P
% Se calcula dentro del paso temporal en caso deque S_P=S_P(t)
% ----------------------------------------------------
%% a_P = a_E + a_W + a_U + a_D + a_P_0
a_P = theta * (a_E + a_W + a_U + a_D) + a_P_0- S_P.* dX.* dZ;

% Establecer condiciones de frontera.

% Como todos los coeficientes han sido inicializados con


% operaciones matriciales asumiendo que todos los puntos son puntos
% interiores, los coedicientes para los puntos en las fronteras
% deben ahora actualizarse correctamente incorporando condiciones
de
% frontera
%
% Especificar los flujos en las fronteras
% ---------------------------
% Tratamiento en la frontera recomendado por Patankar (pgina 50)
en
% volmenes medios en los bordesd el dominio.
%
% Las fronteras estan en puntos solucin X_B = X_P
% ------------------------------------------------
%
% Especificar phi
% -------------
% Las fronteras estan en puntos solucion X_P (Patankar)
% Volmenes medios en los bordes del dominio.
% Restablecer el coeficiente del punto de frontera a la unidad, b
al valor especificado
% y cero a los coeficientes de los puntos vecinos.
%
%
%

% Frontera Este - Flujo externo (x es positivo hacia fuera)


% =====================================================
% Incluir flujo de frontera especifico q_e en b
% Eliminar a_E de a_P
%% a_P(:,end) = a_P(:,end) - a_E(:,end);
a_P(:,end) = a_P(:,end) - theta * a_E(:,end);
b(:,end) = b(:,end) - q_e(:,i_time).* dZ(:,end);
%
% Elimina el punto ficticio Este (fuera del dominio)
a_E(:,end) = 0;
%

% Frontera Oeste - Flujo cero hacia dentro (x es positivo hacia dentro)


% =======================================================
% INcluir flujo de frontera especifico q_w en b
% Elimina a_W de a_P
%% a_P(:,1) = a_P(:,1) - a_W(:,1);
a_P(:,1) = a_P(:,1) - theta * a_W(:,1);
%
b(:,1) = b(:,1) + q_w(:,i_time).* dZ(:,1);
%
% elimina el punto ficticio Oeste (fuera del dominio)
a_W(:,1) = 0;
%

% Fondo - flujo geotrmico


% ========================
% Incluir flujo de frontera especfico q_d en b
% Eliminar a_D de a_P
%% a_P(end,:) = a_P(end,:) - a_D(end,:);
a_P(end,:) = a_P(end,:) - theta * a_D(end,:);
%
b(end,:) = b(end,:) - q_d(i_time,:).* dX(end,:);
%
% Eliminar punto ficticio bajo (fuera del dominio)
a_D(end,:) = 0;
%

%
% Frontera superior - specified phi = phi_u(t)
% =========================================
a_P(1,:) = 1;
b(1,:) = phi_u(i_time,:);
a_U(1,:) = 0;
a_E(1,:) = 0;
a_W(1,:) = 0;
a_D(1,:) = 0;
%
% Llamar al resolverdor implicito

%% phi = resolver( a_E, a_W, a_U, a_D, a_P, b );


phi = resolver( theta*a_E, theta*a_W, theta*a_U, theta*a_D, a_P,
b );
%
%
% Salvar la solucion como phi_0 para el siguiente paso de tiempo
phi_0 = phi;
%
% Graficar la solucion actual
figure(5)
if( size(X_P,2) <= 2)
plot( Z_P(:,1), phi(:,1) )
grid on;box on;
set(gca,'ylim', [ min( min(min(phi_u)),-max(max(abs(phi))) ),
...
max( 0, max(max(abs(phi))) ) ] )
xlabel('Profundidad (m)')
ylabel('Temperatura (^oC)')
else
surf( X_P, Z_P, phi )
colorbar
set(gca,'zlim', [ min(min(phi_u)), 0 ] )
xlabel('Distancia (m)')
ylabel('Profundidad (m)')
zlabel('Temperatura (^oC)')
end

end
end
function phi = resolver( a_E, a_W, a_U, a_D, a_P, b )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Matriz de solucion para phi_P en los puntos P_ij
%% a_P = coeficiente de phi_P en el punto P_ij
%% a_E = coeficiente de phi_E en el punto este de P_ij, i.e. (i,j+1)
%% a_W = coeficiente de phi_W en el punto oeste de P_ij, i.e. (i,j-
1)
%% a_U = coeficiente de phi_U en el punto encima de P_ij, i.e. (i-
1,j)
%% a_D = coeficiente de phi_D en el punto debajo de P_ij, i.e. (i+1,j)
%%
%% Sistema de ecuaciones para resolver phi
%%
%% big_A * phi = rhs
%%
%% big_A = matriz con diagonales -a_P, a_E etc,
%% phi = solucion desconocida en los puntos P de la grilla
%% rhs = vector columna de terminos constantes derivados de b
% (incluye BC, el termino de fuente constante, el paso
previo, etc)
%%
%% Entradas:
%% a_E, a_W, a_U, a_D, a_P y rhs_stuff son matrices con las mismas
dimensiones
%% que la matriz solucin.
%% Ellas ya han sido modificadas para incluir las condiciones de
frontera
%% Cada entrada X_ij en una de esas matrices "X" contiene terminos
asociados con
%% el punto central P_ij del volumen de control.
%%
%% a_P phi_P = a_E phi_E + a_W phi_W + a_U phi_U + a_D phi_D + b
%%
%% o:
%%
%% - a_P phi_P + a_E phi_E + a_W phi_W + a_U phi_U + a_D phi_D = - b
%%
%%
%% Cada matriz a_E, a_W, a_U, a_D, a_P es redimensionada en un vector
columna
%% la cual se convierte en una diagonal de la matriz big_A
%% a_P -> diagonal principal
%% a_U y a_D -> diagonales adyacentes
%% a_E y a_W -> diagonales nz+1 por encima y por debajo de la diagonal
principal
%%
%% matriz b que contiene:
%% - Trmino de fuente S_C independiente de phi.
%% - contribucion de las condiciones de frontera
%% - valores de la solucion del paso previo
%% b es redimensionado en un vector columna rhs
%% rhs = vector del lado derecho
%%
%%-----------------------------------------------------------------
% encuentra nz, nx (numero de filas y columnas)
[nz, nx] = size( b );
n_volumes = nx*nz;
%
% Transforma a_X matrices en diagonales de big_A matrix
% La columna 3 es el centro de la diagonal de big_A
Diags = zeros( n_volumes, 5 );
%% cols = [ -(nz+1) -1 0 1 (nz+1) ];
cols = [ -nz -1 0 1 nz ];
%
Diags(:, 5) = reshape(a_W, n_volumes, 1 );
Diags(:, 4) = reshape(a_U, n_volumes, 1 );
Diags(:, 3) = reshape(-a_P, n_volumes, 1 );
Diags(:, 2) = reshape(a_D, n_volumes, 1 );
Diags(:, 1) = reshape(a_E, n_volumes, 1 );

big_A = spdiags( Diags, cols, n_volumes, n_volumes)';


%
%
% Redimensiona la matriz rhs en un vector columna
rhs = reshape(-b, n_volumes, 1);
%
%
% Resuelve para phi
phi = big_A \ rhs;
%
% Redimensiona el vector columna en matriz
phi = reshape( phi, nz, nx );
end

También podría gustarte