Challenge

Steady and Unsteady 2-D Heat Conduction (using GNU Octave)

2-D HEAT CONDUCTION - Steady & Transient State solutions

The idea is to simulate heat conduction phenomenon over a 2D planar geometry subjected to specified boundary condition for temperature, using numerical discretization and iterative solvers.

The solution is sought for both Steady and Unsteady/ Transient state of conduction. Also, three different iterative solvers are implemented for this computation- (i) Jacobi, (ii) Gauss-Seidel and (ii) Successive-Over-Relaxation (or SOR).

Visualizing the problem geometry:-

2D geometry is kept the same for both Steady and Transient State conduction. The peripheral temperatures for all four sides of the 2D plane are treated as the boundary conditions. For simplicity, the domain dimensions are taken as unit meter (i.e. 1 square-meter area). The temperature values of the four corners are taken as the average of the adjacent boundary temperatures.

The plane is dicretized into a mesh with equal nodes (12 nodes) in the horizontal (X) and the vertical (Y) direction. As the conduction equation consists of PDE terms that are of elliptical type, central differencing scheme for the space derivative terms to gather information from nodes on both X & Y axes aids in decretizing and computing the governing equation at each of the internal nodes.

STEADY STATE SOLUTION

The priliminary equation for Steady State conduction is expressed as follows:

`(del^2 T)/(del x^2) + (del^2 T)/(del y^2) = 0`

Upon dicretizing the above elliptical type PDEs using central differencing scheme, we get

`[ (T_(i+1,j) – 2T_(i,j) + T_(i-1,j))/(Delta x^2) ] + [ (T_(i,j-1) – 2T_(i,j) + T_(i,j+1))/(Delta y^2) ] = 0`

On simplifying further, we obtain the final expression for `T_(i,j)` as

`T_(i,j) = (1/k) [ ((T_(i+1,j) + T_(i-1,j))/(Delta x^2) ) + ( (T_(i,j-1) + T_(i,j+1))/(Delta y^2) ) ]` …… Eqn (1)

Where `k = (2(Delta x^2 + Delta y^2))/( Delta x^2 * Delta y^2)`

The equation can be further modified with the number of nodes in X & Y directions being the same, making `Delta x^2 = Delta y^2` (or dx = dy). The program code however, employs the general expression as the derived Eqn(1) in order to maintain variable versatility.

Program Code

To begin the computation, values of the internal nodes of the Temperature Field are assigned a guess value of 298 K. In order to facilitate convergence of the solution, a desired ‘tolerance’ for the final solution is set, which is compared with an ‘error’ term during each iteration. The iterations of this convergence loop continue until the ‘error’ falls within the tolerance limit, yielding the converged solution.

Three different iterative solvers are wriiten to solve the final expression of Steady State conduction. An input is taken from the user for the choice of solver, accoridng to which the corresponding code block is executed. The solver also keeps track of the number of iterations and the evaluation time taken to reach solution convergence. Acquired results are then depicted as Temperature Contours with appropriate scaling.

As time derivative term is equated to zero in case of steady state simulation, iterations based on time-steps gets omitted due to absence of any coupled linear expressions and thus, the solution type can be essentially thought of as Explicit Intergration

The program code including explanatory comments is as follows:

% STEADY STATE 2D HEAT CONDUCTION CODE
clear all; 
close all;
clc;

L = 1;           % Domain Area as 1 square-meter
nx=12; ny=12;    % Grid points in X and Y direction resp. 
% Creating the Mesh and determing the grid spacings in X and Y directions  
x=linspace(0,L,nx); dx=x(2)-x(1);
y=linspace(0,L,ny); dy=y(2)-y(1);
y0=fliplr(y);   % Reversing/Flipping Y-axis to aptly use in plotting  

% Temperture Boundary Conditions
T = ones(nx,ny)*298 ; % Initial Guess Value for the Temperture Field
% Boundary Temperature Values  
T(2:nx-1,1) = 400;   % Left
T(2:nx-1,ny) = 800;  % Right 
T(1,2:ny-1) = 600;   % Top
T(nx,2:ny-1) = 900;  % Bottom
% Corner Temperature Values (as average of boundary values)
T(1,1) = (T(2,1)+T(1,2))/2;
T(1,end) = (T(1,2)+T(2,ny))/2;
T(end,1) = (T(nx-1,1)+T(nx,2))/2;
T(end,end) = (T(nx-1,ny)+T(nx,ny-1))/2;

error = 100;       % Initializing error variable 
tolerance = 1e-4;  % Defining requisite tolerance for solution convergence  
t_old = T;         % Variable to store values from previous iteration
iteration_count=0; % Variable to count completed interations upto convergence
k = (2*((dx^2)+(dy^2)))/((dx^2)*(dy^2));

% Taking user input for choice of Iterative Solver
iterative_solver= input(" Steady State Solver type - n (i) Jacobi (press 1) n (ii) Gauss Seidel (press 2) n (iii) Successive-Over-Relaxation (press 3) n");

% Computing the various solutions based on the user input 
if iterative_solver==1  % JACOBI METHOD
  tic;     % Start timer                   
  % CONVERGENCE LOOP 
    while (error>tolerance)
      iteration_count=iteration_count+1; % Increment conunter for each iteration
         % SPACE LOOP to solve all 2D grid points 
         for i = 2:nx-1
              for j = 2:ny-1
                 % Splitting the final expression for fool-proofing
                 A = (t_old(i-1,j)+t_old(i+1,j))/(dx^2);
                 B = (t_old(i,j-1)+t_old(i,j+1))/(dy^2);
                 T(i,j) = (1/k)*(A+B);
              endfor
         endfor
      error = max(max(abs(t_old-T))); % Determining maximum error value
      t_old = T;                      % Updating old values for next iteration  
     
   endwhile
   t_eval = toc;  % Stop timer and store computation time 
   
elseif iterative_solver==2  % GAUSS-SEIDEL METHOD
    tic; % Start timer
    % CONVERGENCE LOOP  
    while (error>tolerance)
      iteration_count=iteration_count+1; % Increment conunter for each iteration
         % SPACE LOOP to solve all 2D grid points
         for i = 2:nx-1
              for j = 2:ny-1
                  % Splitting the final expression for fool-proofing
                  A = (T(i-1,j)+t_old(i+1,j))/(dx^2);
                  B = (T(i,j-1)+t_old(i,j+1))/(dy^2);
                  T(i,j) = (1/k)*(A+B);
              endfor
         endfor
      error = max(max(abs(t_old-T))); % Determining maximum error value 
      t_old = T;                     % Updating old values for next iteration
   
   endwhile
   t_eval = toc;        % Stop timer and store computation time 
    
elseif iterative_solver==3  % SOR METHOD
   omega = 1.2;   % Relaxation Factor
   tic;           % Start timer
   % CONVERGENCE LOOP 
     while (error>tolerance)
       iteration_count=iteration_count+1; % Increment conunter for each iteration
         % SPACE LOOP to solve all 2D grid points
         for i = 2:nx-1
              for j = 2:ny-1
                  % Splitting the final expression for fool-proofing
                  A = (T(i-1,j)+t_old(i+1,j))/(dx^2);
                  B = (T(i,j-1)+t_old(i,j+1))/(dy^2);
                  T(i,j)= ((1-omega)*t_old(i,j)) + ((omega/k)*(A+B));
              endfor
         endfor
      error = max(max(abs(t_old-T))); % Determining maximum error value
      t_old = T;                      % Updating old values for next iteration  
     
   endwhile
   t_eval = toc;    % Stop timer and store computation time 
   
endif  
  
 % PLOTTING THE TEMPERATURE CONTOUR 
figure (1)
contourf(x,y0,T);
[C,H] = contourf(x,y0,T);
colorbar; 
colormap(jet);
clabel(C,H);
xlabel('X-direction'); ylabel('Y-direcction');
title_text=sprintf('n2D HEAT CONDUCTION - STEADY STATE SOLUTION n Iteration Count = %d ; Computation Time = %d sec', iteration_count,t_eval);
title(title_text);

   

   

Input via Command Window:

Results

The following are the temperature contours plotted for each iterative solver methods:

(I) JACOBI METHOD

(II) GAUSS-SEIDEL METHOD

(III) SUCCESSIVE-OVER-RELAXATION (or SOR) METHOD

A glipse of performances of the iterative solvers can be observed from the number of iterations taken by the solver to reach solution convergence and proportionally, the time taken to do so. Jacobi method takes the highest time for the computation and runs 301 iterations whereas SOR attains convergence in 109 iterations thereby taking less time.

TRANSIENT (UNSTEADY) STATE SOLUTION

In case of transient state, the equation is expressed as-

`(del T)/(del t) = alpha [(del^2 T)/(del x^2) + (del^2 T)/(del y^2) ]`

As the equation consists of a time derivative term, the solution can be sought using both Explicit and Implicit Integration. Thus, a for-loop running sufficent number of time steps until the solution tends to steady state has to additionally included in the code block.

(i) EXPLICIT

The transient state equation is discretized as follows:

`(T_(i,j)^(n+1) – T_(i,j)^n)/(Delta t) = alpha [(T_(i+1,j) – 2T_(i,j) + T_(i-1,j))/(Delta x^2) + (T_(i,j-1) – 2T_(i,j) + T_(i,j+1))/(Delta y^2) ]^n`

Where `alpha =` Thermal Diffusivity

Upon simplification, we obtain the final expression as:

`T_(i,j)^(n+1) = T_(i,j)^n + k_1 (T_(i+1,j) – 2T_(i,j) + T_(i-1,j))^n + k_2(T_(i,j-1) – 2T_(i,j) + T_(i,j+1))^n` …..... Eqn (2)

Where `k_1 = (alpha Delta t)/(Delta x^2)` and `k_2 = (alpha Delta t)/(Delta y^2)` ; which are referred as CFL numbers, used for stabilty analysis of the solution.

Since the right-hand side of the equation (older time-step values) is readily solvable duirng each iteration to solve for the newer time-step, iterative solvers are not required here. A convergence may be used within the for-loop for time-step counting if desired, although the solution is expected to converge even by iterating with enough number of time-steps.

(ii) IMPLICIT

For implicit integration, Eqn (2) can be utilized by changing the time-step at which the right-hand side values are taken.

`T_(i,j)^(n+1) = T_(i,j)^n + k_1 (T_(i+1,j) – 2T_(i,j) + T_(i-1,j))^(n+1) + k_2(T_(i,j-1) – 2T_(i,j) + T_(i,j+1))^(n+1)`

Where again `k_1 = (alpha Delta t)/(Delta x^2)` and `k_2 = (alpha Delta t)/(Delta y^2)` [CFL numbers]

The equation can be further manipulated to obtain the final expression as:

`T_(i,j)^(n+1) = [ T_(i,j)^n + k_1 (T_(i+1,j) + T_(i-1,j))^(n+1) + k_2(T_(i,j-1) + T_(i,j+1))^(n+1) ]/((1+2k_1+2k_2))` ………. Eqn (3)

To compute this expression, all the three iterative solvers are employed i.e. Jacobi, Gauss-Siedel and SOR. Unlike explicit one, the code block for these solvers also consist of a convergence loop similar to as used in the steady state solution code.

However, it is crucial to note the loop within which the Temperature matrices update iteratively. The set of old values to be used for solution convergence have to be updated inside the convergence loop, while the temperature values from a preceeding time-step have to be updated outside the convergence loop (i.e. within the for-loop of time-steps).

Program Code

The initial code lines are similar to the program code for steady state, inclusive of mesh creation, defining boundary conditions, requisite variable assignment and user input is taken for the choice of solution integral – Explicit or Implicit.

Since explicit integral does not include any iterative solvers, the choice directly renders a problem solution. But, as different iterative solvers are employed under Implicit integral, user input is taken again as a sub-choice for the solver. This is implemented as nested if-else command within the program code, that executes the appropriate code block cooresponding to the choice of user to compute the solution.

General expressions as given by Eqn (2) & (3) are used instead of further reducing it using dx = dy, to retain the versatility of the program code. The number of iterations to converge and time taken to compute the same are also calculated to compare the three solvers. Final results are then rendered as suitable Temperature Contours.

The program code including explanatory comments is as follows:

clear all; 
close all;
clc;

L = 1;                         % Domain Area as 1 square-meter
nx=12; ny=12;                  % Grid points in X and Y direction resp. 
% Creating the Mesh and determing the grid spacings in X and Y directions
x=linspace(0,L,nx); dx=x(2)-x(1);
y=linspace(0,L,ny); dy=y(2)-y(1);
y0 = fliplr(y);  % Reversing/Flipping Y-axis to aptly use in plotting
% Defining the Number of Time-Steps 
t_end = 700; dt=0.5;
t_n = t_end/dt;

% Temperture Boundary Conditions
T = ones(nx,ny)*298 ; % Initial Guess Value for the Temperture Field
% Boundary Temperature Values
T(2:nx-1,1) = 400;   % Left
T(2:nx-1,ny) = 800;  % Right 
T(1,2:ny-1) = 600;   % Top
T(nx,2:ny-1) = 900;  % Bottom
% Corner Temperature Values (as average of boundary values)
T(1,1) = (T(2,1)+T(1,2))/2;
T(1,end) = (T(1,2)+T(2,ny))/2;
T(end,1) = (T(nx-1,1)+T(nx,2))/2;
T(end,end) = (T(nx-1,ny)+T(nx,ny-1))/2;

error = 100;       % Initializing error variable 
tolerance = 1e-4;  % Defining requisite tolerance for solution convergence  
t_old = T;         % Variable to store values from previous iteration
Prev_T = T;        % Variable to store values from previous Time-Step
iteration_count=0; % Variable to count completed interations upto convergence

% Taking user input for choice of Solution Integral
printf("TRANSIENT 2D HEAT CONDUCTION n");
ans = input("Select solution integral:- n (1) EXPLICIT [press 1] n (2) IMPLICIT [press 2] n");

% Computing the various solutions based on the user input 
if ans ==1    % EXPLICIT 
   alpha=1e-3; % Thermal diffusivity
   k1=(alpha*dt)/(dx^2); k2=(alpha*dt)/(dy^2); % Calculating CFL values
   tic;    % Start timer 
   % For-loop to count the number of Time-Steps  
   for nt=1:t_n
        
         % SPACE LOOP to solve all 2D grid points 
          for i=2:nx-1
             for j=2:ny-1
               % Splitting the final expression for fool-proofing
               A = k1*(t_old(i-1,j)-2*t_old(i,j)+t_old(i+1,j));
               B = k2*(t_old(i,j-1)-2*t_old(i,j)+t_old(i,j+1));
               T(i,j) = t_old(i,j) + A + B;
             endfor
          endfor
        error=max(max(abs(t_old-T)));  % Determining maximum error value
        t_old=T;                       % Updating old values for next iteration
        iteration_count=iteration_count+1; % Increment conunter for each iteration
         
     endfor 
     t_eval = toc;  % Stop timer and store computation time 
   
   % PLOTTING THE TEMPERATURE CONTOUR - EXPLICIT
    figure (1)
    contourf(x,y0,T);
    [C,H] = contourf(x,y0,T);
    colorbar; 
    colormap(jet);
    clabel(C,H);
    xlabel('X-direction'); ylabel('Y-direcction');
    itle_text=sprintf('2D HEAT CONDUCTION - TRANSIENT STATE SOLUTION [EXPLICIT] n Iteration Count = %d ; Computation Time = %d ', iteration_count,t_eval);
    title(title_text);
  
elseif ans==2   % IMPLICIT
   % Taking user input for choice of Iterative Solver
   iterative_solver = input("nSelect Solver type - n (i) Jacobi (press 1) n (ii) Gauss Seidel (press 2) n (iii) Successive-Over-Relaxation (press 3) n");
 
   alpha=1.3;                                   % Thermal diffusivity
   k1=(alpha*dt)/(dx^2); k2=(alpha*dt)/(dy^2);  % Calculating CFL values
   denom = 1+2*k1+2*k2;
        
   if iterative_solver==1  % JACOBI METHOD
     tic; % Start timer 
     % For-loop to count the number of Time-Steps
     for nt=1:t_n
       error=100; % Re-initializing error term for each time-step loop
       % CONVERGENCE LOOP  
         while (error>tolerance)
          iteration_count=iteration_count+1; % Increment conunter for each iteration  
          % SPACE LOOP to solve all 2D grid points 
              for i = 2:nx-1
                  for j = 2:ny-1
                    % Splitting the final expression for fool-proofing
                    A = k1*(t_old(i-1,j)+t_old(i+1,j));
                    B = k2*(t_old(i,j-1)+t_old(i,j+1));
                    T(i,j)= (Prev_T(i,j)+ A + B)/denom;
                 endfor
              endfor
           error = max(max(abs(t_old-T)));  % Determining maximum error value
           t_old = T;                       % Updating old values for next iteration
         endwhile
         Prev_T = T;                        % Updating old values for next Time-Step
       endfor
       t_eval = toc;  % Stop timer and store computation time 

    elseif iterative_solver==2  % GAUSS-SEIDEL METHOD
    tic; % Start timer 
    % For-loop to count the number of Time-Steps
    for nt=1:t_n
     error=100; % Re-initializing error term for each time-step loop
     % CONVERGENCE LOOP   
       while (error>tolerance)
          iteration_count=iteration_count+1; % Increment conunter for each iteration
          % SPACE LOOP to solve all 2D grid points 
             for i = 2:nx-1
                for j = 2:ny-1
                   % Splitting the final expression for fool-proofing
                    A = k1*(T(i-1,j)+t_old(i+1,j));
                    B = k2*(T(i,j-1)+t_old(i,j+1));
                    T(i,j)= (Prev_T(i,j)+ A + B)/denom;
                endfor
            endfor
      error = max(max(abs(t_old-T)));  % Determining maximum error value
      t_old = T;                       % Updating old values for next iteration
   
    endwhile
   Prev_T = T;                        % Updating old values for next Time-Step
  endfor
  t_eval = toc;  % Stop timer and store computation time 
   
elseif iterative_solver==3 % SUCCESSIVE-OVER-RELAXATION METHOD
   omega = 1.2;  % Relaxation Factor
   tic;          % Start timer 
   % For-loop to count the number of Time-Steps
    for nt=1:t_n
    error=100; % Re-initializing error term for each time-step loop
    % CONVERGENCE LOOP  
     while (error>tolerance)
       iteration_count=iteration_count+1;  % Increment conunter for each iteration
       % SPACE LOOP to solve all 2D grid points 
         for i = 2:nx-1
              for j = 2:ny-1
                 % Splitting the final expression for fool-proofing
                  A = k1*(T(i-1,j)+t_old(i+1,j));
                  B = k2*(T(i,j-1)+t_old(i,j+1));
                  T(i,j)= ((1-omega)*t_old(i,j)) + (omega*(Prev_T(i,j)+ A + B))/denom;
              endfor
         endfor
      error = max(max(abs(t_old-T)));  % Determining maximum error value
      t_old = T;                       % Updating old values for next iteration
     
     endwhile
     Prev_T = T;                      % Updating old values for next Time-Step
   endfor
   t_eval = toc;  % Stop timer and store computation time 
 
endif  
  
% PLOTTING THE TEMPERATURE CONTOUR - IMPLICIT
figure (1)
contourf(x,y0,T);
[C,H] = contourf(x,y0,T);
colorbar; 
colormap(jet);
clabel(C,H);
xlabel('X-direction'); ylabel('Y-direcction');
title_text=sprintf('2D HEAT CONDUCTION - TRANSIENT STATE SOLUTION [IMPLICIT]n Iteration Count = %d ; Computation Time = %d ', iteration_count,t_eval);
title(title_text);

  
else 
  printf("nINVALID CHOICEn"); 
endif

Input via Command Window:

Results

The temperature contours for each of the user choices are as follows:

(I) EXPLICIT

(II) IMPLICIT : JACOBI

(III) IMPLICIT : GAUSS-SEIDEL

(IV) IMPLICIT : SUCCESSIVE-OVER-RELAXATION (or SOR)

As evident from the computation time taken, all the implicit integrals take longer time compared to the explicit integrals.

Similar to the observation in the Steady State simulation, the SOR method takes lesser time to solve running 1486 iterations for convergence. On the other hand, Jacobi method takes 2017 iterations to reach convergence taking a comparatively longer computation time.

A summary table encompassing the recorded performance parameters is given below.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.