%This program complished the process of 2D Eulerian advection with method
%of allocating memory temporarily.
clear all;clf;
Nt = 30;
output_interval = 1;
% BASIC NODES
Lx = 1000000;
Ly = 1500000;
x_midd = Lx/2;
y_midd = Ly/2;
Nx = 51;
Ny = 31;
Nx1 = Nx+1;
Ny1 = Ny+1;
dx = Lx / (Nx-1);
dy = Ly / (Ny-1);
% Basic E-nodes.
x = 0:dx:Lx;
y = 0:dy:Ly;
g_y = 10;
% PARAMETERS
kw = 10;%W/(m*K)
denw = 3300;%Kg/m^3
Cpw = 1100;%J/(Kg*K)
ks = 3;%W/(m*K)
dens = 3200;%Kg/m^3
Cps = 1000;%J/(Kg*K)
bt = 1000;%K,background temperature
wt = 1300;%K,wave temperature
% L-MARKERS
num_per_cell = 4;
% Nx_marker = (Nx-1)*num_per_cell;
% Ny_marker = (Ny-1)*num_per_cell;
Nx_marker = 400;
Ny_marker = 500;
marknum=Nx_marker*Ny_marker;
x_m_step = Lx/Nx_marker;
y_m_step = Ly/Ny_marker;
% Marker points.
xm=zeros(1,marknum); % Horizontal coordinates, m
ym=zeros(1,marknum);
Km=zeros(1,marknum); % K, kg/m^3 kt
DenCpm=zeros(1,marknum); % den*Cp hct
tdm = zeros(1,marknum); % K/den/Cp td
Tm0 = zeros(1,marknum); % temperature
% INITIALIZE K,Den*Cp in the L-markers.
m = 1;
for jm=1:1:Nx_marker
for im=1:1:Ny_marker
% Define marker coordinates
xm(m)=x_m_step/2+(jm-1)*x_m_step+(rand-0.5)*x_m_step;
ym(m)=y_m_step/2+(im-1)*y_m_step+(rand-0.5)*y_m_step;
% Marker properties
% if ( xm(m)<=x_midd+200000 && xm(m)>=x_midd-200000 && ym(m)<=y_midd+300000 && ym(m)>=y_midd-300000)
if ( xm(m)<=0.7*Lx && xm(m)>=0.3*Lx && ym(m)<=0.7*Ly && ym(m)>=0.3*Lx)
Km(m)=kw; % K wave
DenCpm(m)=denw*Cpw; % den*Cp wave
Tm0(m) = wt;
else
Km(m)=ks; % K surround
DenCpm(m)=dens*Cps; % den*Cp surround
Tm0(m) = bt;
end
% Update marker counter
m=m+1;
end
end
% Define matrix
hct = zeros(Ny,Nx); %Den*Cp
kht = zeros(Ny,Nx); %K
T0 = zeros(Ny,Nx); %T
td = zeros(Ny,Nx); %K/Den*Cp
bt = zeros(Nx*Ny, 1);
coet = zeros(Nx*Ny, Nx*Ny);
vx_matrix = zeros(Ny,Nx);
vy_matrix = zeros(Ny,Nx);
for j = 1:Nx
for i = 1:Ny
% Constant velocity
vx_matrix(i,j) = 1e-9;
vy_matrix(i,j) = 1e-9;
end
end
% DEFINE dt
kappa=max(max(Km))/min(min(DenCpm));
dtexp = min(dx,dy)^2/(3*kappa);
if(vx_matrix(1,1)~=0)
dtexp=min(dtexp,abs(dx/max(max(vx_matrix)))); % Limitation for horizontal advection timestep
end
if(vy_matrix(1,1)~=0)
dtexp=min(dtexp,abs(dy/max(max(vy_matrix)))); % Limitation for vertical advection timestep
end
dt_tem = 0.5*dtexp;
subgrdifcoe = 1;
for t = 1:Nt
% Indispensable
% Eq.8.18
w_m_x_node_t = zeros(Ny,Nx);
K_w_m_t = zeros(Ny,Nx);
DenCp_w_m_t = zeros(Ny,Nx);
% Eq.10.12
T_w_m_t = zeros(Ny,Nx);
w_m_t_t = zeros(Ny,Nx);
% !!!Backup properities K,Den*Cp and T
kht_backup = kht;
hct_backup = hct;
T_backup = T0;
% Searching the coordinate of upper-left node of every L-marker.
for m=1:1:marknum
% !!!Check L-marker in the grid
if (xm(m)>=x(1) && xm(m)<=x(Nx) && ym(m)>=y(1) && ym(m)<=y(Ny))
% Define i,j indexes for the upper left BASIC NODE(Nx*Ny)
j=fix((xm(m)-x(1))/dx)+1;
i=fix((ym(m)-y(1))/dy)+1;
if(j<1)
j=1;
elseif(j>Nx-1)
j=Nx-1;
end
if(i<1)
i=1;
elseif(i>Ny-1)
i=Ny-1;
end
% Compute distances between marker and upper-left node.
dis_x = xm(m)-x(j);
dis_y = ym(m)-y(i);
wtmij = (1-dis_x/dx)*(1-dis_y/dy);
wtmi1j = (1-dis_x/dx)*(dis_y/dy);
wtmij1 = (dis_x/dx)*(1-dis_y/dy);
wtmi1j1 = (dis_x/dx)*(dis_y/dy);
% Sum of (K/Den*Cp)*(weight) and sum of weight.
w_m_x_node_t(i,j) = w_m_x_node_t(i,j) + wtmij; % denominator% numerator
K_w_m_t(i,j) = K_w_m_t(i,j) + Km(m).*wtmij;% K
DenCp_w_m_t(i,j) = DenCp_w_m_t(i,j) + DenCpm(m).*wtmij;% Den*Cp
T_w_m_t(i,j) = T_w_m_t(i,j) + Tm0(m).*DenCpm(m)*wtmij;% T
w_m_t_t(i,j) = w_m_t_t(i,j) + DenCpm(m)*wtmij;
w_m_x_node_t(i+1,j) = w_m_x_node_t(i+1,j) + wtmi1j;
K_w_m_t(i+1,j) = K_w_m_t(i+1,j) + Km(m).*wtmi1j;
DenCp_w_m_t(i+1,j) = DenCp_w_m_t(i+1,j) + DenCpm(m).*wtmi1j;
T_w_m_t(i+1,j) = T_w_m_t(i+1,j) + Tm0(m).*wtmi1j*DenCpm(m);% T
w_m_t_t(i+1,j) = w_m_t_t(i+1,j) + DenCpm(m)*wtmi1j;
w_m_x_node_t(i,j+1) = w_m_x_node_t(i,j+1) + wtmij1;
K_w_m_t(i,j+1) = K_w_m_t(i,j+1) + Km(m).*wtmij1;
DenCp_w_m_t(i,j+1) = DenCp_w_m_t(i,j+1) + DenCpm(m).*wtmij1;
T_w_m_t(i,j+1) = T_w_m_t(i,j+1) + Tm0(m).*wtmij1*DenCpm(m);% T
w_m_t_t(i,j+1) = w_m_t_t(i,j+1) + DenCpm(m)*wtmij1;
w_m_x_node_t(i+1,j+1) = w_m_x_node_t(i+1,j+1) + wtmi1j1;
K_w_m_t(i+1,j+1) = K_w_m_t(i+1,j+1) + Km(m).*wtmi1j1;
DenCp_w_m_t(i+1,j+1) = DenCp_w_m_t(i+1,j+1) + DenCpm(m).*wtmi1j1;
T_w_m_t(i+1,j+1) = T_w_m_t(i+1,j+1) + Tm0(m).*wtmi1j1*DenCpm(m);% T
w_m_t_t(i+1,j+1) = w_m_t_t(i+1,j+1) + DenCpm(m)*wtmi1j1;
end
end
% Computing the value of K and Den*Cp and T of E-nodes.
for j = 1:Nx
for i = 1:Ny
if(w_m_x_node_t(i,j)>0)
kht(i,j) = K_w_m_t(i,j)/w_m_x_node_t(i,j);%K
hct(i,j) = DenCp_w_m_t(i,j)/w_m_x_node_t(i,j);%Den*Cp
else
kht(i,j) = kht_backup(i,j);
hct(i,j) = hct_backup(i,j);
end
td(i,j) = kht(i,j)/hct(i,j);%K/(Den*Cp)
if(w_m_t_t(i,j)>0)
T0(i,j) = T_w_m_t(i,j)/w_m_t_t(i,j);%T
else
T0(i,j) = T_backup(i,j);
end
end
end
% Apply the boundary conditions to T at every t+dt.
% Constant temperature boundary
% T = constant
% T0(1,:) = 1000;
% T0(Ny,:) = 1000;
% T0(:,1) = 1000;
% T0(:,Nx) = 1000;
% Insulting boundary condition
% T1(boudnary) = T2(internal)
T0(1,2:Nx-1) = T0(2,2:Nx-1);
T0(Ny,2:Nx-1) = T0(Ny,2:Nx-1);
T0(:,1) = T0(:,2);
T0(:,Nx) = T0(:,Nx-1);
khtdt = kht;
hctdt = hct;
% Change k and den*Cp at internal nodes with upwind difference
% Maybe don't need E-advection in the method of MIC
% for j = 2:Nx-1
% for i = 2:Ny-1
% khtdt(i,j) = dt*( -vx(i,j)*( kht(i,j)-kht(i,j-1) )/dx -vy(i,j)*( kht(i,j)-kht(i-1,j) )/dy ) +kht(i,j) ;
% hctdt(i,j) = dt*( -vx(i,j)*( hct(i,j)-hct(i,j-1) )/dx -vy(i,j)*( hct(i,j)-hct(i-1,j) )/dy ) +hct(i,j) ;
% end
% end
% kht = khtdt;
% hct = hctdt;
% Constant temperature boundary condition.
% Tbc = constant = 1000
% up and down
% for j = 1:Nx
% i = 1;
% k = (j-1)*Ny + i;
% coe(k, k) = 1;
% b(k, 1) = 1000;
% i = Ny;
% k = (j-1)*Ny + i;
% coe(k, k) = 1;
% b(k, 1) = 1000;
% end
% % left and right
% for i = 1:Ny
% j = 1;
% k = (j-1)*Ny + i;
% coe(k, k) = 1;
% b(k, 1) = 1000;
% j = Nx;
% k = (j-1)*Ny + i;
% coe(k, k) = 1;
% b(k, 1) = 1000;
% end
% Insulating boundary condition.
% Up and down
for j = 2:Nx-1
i = 1;
k = (j-1)*Ny + i;
% T(1,j) - T(2,j) = 0;
coet(k, k) = 1;
coet(k, k+1) = -1;
bt(k, 1) = 0;
i = Ny;
k = (j-1)*Ny + i;
% T(Ny,j) - T(Ny-1,j) = 0;
coet(k, k) = 1;
coet(k, k-1) = -1;
bt(k, 1) = 0;
end
% left and right
for i = 1:Ny
j = 1;
k = (j-1)*Ny + i;
coet(k, k) = 1;
coet(k, k+Ny) = -1;
bt(k, 1) = 0;
j = Nx;
k = (j-1)*Ny + i;
coet(k, k) = 1;
coet(k, k-Ny) = -1;
bt(k, 1) = 0;
end
% coefficients of interval points
for j = 2:Nx-1
for i = 2:Ny-1
k = (j-1)*Ny + i; % k is the index
if vx_matrix(i,j)>0
dtdx = (T0(i,j)-T0(i,j-1))/dx;
elseif vx_matrix(i,j)<0
dtdx = (T0(i,j+1)-T0(i,j))/dx;
end
if vy_matrix(i,j)>0
dtdy = (T0(i,j)-T0(i-1,j))/dy;
elseif vy_matrix(i,j)<0
dtdy = (T0(i+1,j)-T0(i,j))/dy;
end
coet(k, k) = (khtdt(i,j)+khtdt(i,j+1))/(2.*dx.^2)+(khtdt(i,j-1)+khtdt(i,j))/(2.*dx.^2)...
+(khtdt(i,j)+khtdt(i+1,j))/(2.*dy.^2)+(khtdt(i-1,j)+khtdt(i,j))/(2.*dy.^2)...
+hctdt(i,j)/dt_tem; % middle T3
coet(k, k-1) = -(khtdt(i-1,j)+khtdt(i,j))/(2.*dy.^2); % up T2
coet(k, k+1) = -(khtdt(i,j)+khtdt(i+1,j))/(2.*dy.^2); % down T4
coet(k, k-Ny) = -(khtdt(i,j-1)+khtdt(i,j))/(2.*dx.^2); % left T1
coet(k, k+Ny) = -(khtdt(i,j)+khtdt(i,j+1))/(2.*dx.^2); % right T5
% !!!Note that there are not advection term because MIC have
% marker transport.!!!
bt(k, 1) = T0(i,j)*hctdt(i,j)/dt_tem; %- hctdt(i,j)*(vx(i,j)*dtdx+vy(i,j)*dtdy);
end
end
%direct method:right martix is divided by coe martix on the left
u = coet \ bt;
%transform vector to grids
% U has Ny rows and Nx columns
U = reshape(u, Ny, Nx);
T1 = U;
% Computing dTi,j = dTi,j(subgrid) + dTi,j(remaining)
% Eq10.13
dTij = T1-T0;
% Computing subgrid diffusion for markers
if (subgrdifcoe>0)
% Existence of subgrid diffusion.
% Page162 How to correct the problem ?
% operating consistent subgrid diffusion .
% Clear subgrid temperature changes(dTijsub) for nodes
dTijsub = zeros(Ny,Nx);
DWTM = zeros(Ny,Nx);
% From marker to BASIC NODES
w_nodes = zeros(Ny,Nx);
% Interpolate Tm0(nodal) from E-nodes(T0) to L-markers.
for m = 1:marknum
if (xm(m)>=x(1) && xm(m)<=x(Nx) && ym(m)>=y(1) && ym(m)<=y(Ny))
% Interpolate T to BASIC NODES(Nx*Ny)
% Define i,j indexes for the upper left node
j=fix((xm(m)-x(1))/dx)+1;
i=fix((ym(m)-y(1))/dy)+1;
if(j<1)
j=1;
elseif(j>Nx-1)
j=Nx-1;
end
if(i<1)
i=1;
elseif(i>Ny-1)
i=Ny-1;
end
% Compute distances
dis_x=xm(m)-x(j);
dis_y=ym(m)-y(i);
% Compute weights
wtmij=(1-dis_x/dx)*(1-dis_y/dy);
wtmi1j=(1-dis_x/dx)*(dis_y/dy);
wtmij1=(dis_x/dx)*(1-dis_y/dy);
wtmi1j1=(dis_x/dx)*(dis_y/dy);
% Interpolate Basic node(Tm0nodal) from L-markers(T0i,j)
Tm0nodal= T0(i,j)*wtmij + T0(i+1,j)*wtmi1j ...
+T0(i,j+1)*wtmij1 + T0(i+1,j+1)*wtmi1j1;
% Eq.10.14
dTm = Tm0nodal - Tm0(m);
% Page163
tdiff = DenCpm(m)/Km(m)/(2/dx^2+2/dy^2);
% Computing subgrid diffusion
sdif=-subgrdifcoe*dt_tem/tdiff;
if(sdif<-30)
sdif=-30;
end
% Page162 Eq.10.16
dTmsub=dTm*(1-exp(sdif));
% Eq.10.19
% Tcorrected = Tm0 + dTsubgrid (+ dTremain)
Tm0(m) = Tm0(m) + dTmsub;
% Interpolate Basic node(dTijsub) from L-markers(dTmsub)
% Eq.10.17
DWTM(i,j) = DWTM(i,j) + dTmsub*DenCpm(m)*wtmij;
w_nodes(i,j) = w_nodes(i,j) + DenCpm(m)*wtmij;
DWTM(i+1,j) = DWTM(i+1,j) + dTmsub*DenCpm(m)*wtmi1j;
w_nodes(i+1,j) = w_nodes(i+1,j) + DenCpm(m)*wtmi1j;
DWTM(i,j+1) = DWTM(i,j+1) + dTmsub*DenCpm(m)*wtmij1;
w_nodes(i,j+1) = w_nodes(i,j+1) + DenCpm(m)*wtmij1;
DWTM(i+1,j+1) = DWTM(i+1,j+1) + dTmsub*DenCpm(m)*wtmi1j1;
w_nodes(i+1,j+1) = w_nodes(i+1,j+1) + DenCpm(m)*wtmi1j1;
end
end
for j = 1:Nx
for i = 1:Ny
if(w_nodes(i,j)>0)
% Compting dTijsub
% Eq.10.17
dTijsub(i,j) = DWTM(i,j)/w_nodes(i,j);
% else
% dTijsub(i,j) = dTijsub(i,j);
end
end
end
% Eq.10.18
% Update dTij
dTijremain = dTij - dTijsub;
end
% Interpolate L-markers(dTremain) from Basicnode(dTijremain)
for m = 1:marknum
if (xm(m)>=x(1) && xm(m)<=x(Nx) && ym(m)>=y(1) && ym(m)<=y(Ny))
% Define i,j indexes for the upper left node
j=fix((xm(m)-x(1))/dx)+1;
i=fix((ym(m)-y(1))/dy)+1;
if(j<1)
j=1;
elseif(j>Nx-1)
j=Nx-1;
end
if(i<1)
i=1;
elseif(i>Ny-1)
i=Ny-1;
end
% Compute distances
dis_x=xm(m)-x(j);
dis_y=ym(m)-y(i);
% Compute weights
wtmij=(1-dis_x/dx)*(1-dis_y/dy);
wtmi1j=(1-dis_x/dx)*(dis_y/dy);
wtmij1=(dis_x/dx)*(1-dis_y/dy);
wtmi1j1=(dis_x/dx)*(dis_y/dy);
% Interpolate Basic node(Tm0nodal) from L-markers(T0i,j)
dTmremain=dTijremain(i,j)*wtmij + dTijremain(i+1,j)*wtmi1j ...
+dTijremain(i,j+1)*wtmij1 + dTijremain(i+1,j+1)*wtmi1j1;
% Tcorrected = Tm0(Tm0+ dTsubgrid) + dTremain
% Eq.10.19
if(t>1)
Tm0(m) = Tm0(m) + dTmremain;
else
% Interpolate new temperature for the 1st timestep
Tm0(m) = T1(i,j)*wtmij + T1(i+1,j)*wtmi1j ...
+T1(i,j+1)*wtmij1 + T1(i+1,j+1)*wtmi1j1;
end
end
end
% Marker transport
for m = 1:marknum
vxm = 1e-9;
vym = 1e-9;
xm(m) = xm(m)+vxm*dt_tem;
ym(m) = ym(m)+vym*dt_tem;
if (xm(m) > Lx)
xm(m) = xm(m) - Lx;
elseif(xm(m) < 0)
xm(m) = xm(m) + Lx;
end
if (ym(m) > Ly)
ym(m) = ym(m) - Ly;
elseif(ym(m) < 0)
ym(m) = ym(m) + Ly;
end
end
figure(1);
pcolor(x,y,T1);colorbar;
xlabel('Horizontal(Km)');
ylabel('Vertical(Km)');
zlabel('Gravitational potential');
title(['(CTbc) Inplicit form solution of T(advection and MIC) after',num2str(t),' deltat'])
set(gca,'xaxislocation','top');
set (gca,'YDir','reverse')
colormap('Jet');
shading interp;
pause(0.01);
end