Solution of the 2D-Laplace's Equation (Heat diffusion) with Finite Difference (Jacobi-IM, GS-IM, PSOR) FORTRAN CODE
The steady-state temperature distribution over a 1m x 1m square plate for different boundary conditions are found out by solving the simple Laplace equation using the finite difference method.
In this study, our main objective is to solve the Laplace equation of heat diffusion for a 2D square solid domain. This is a very basic and benchmark problem in the field of computational heat transfer.
This computational problem is solved with the help of numeric simulation technique written in FORTRAN 95.
Source Code: (Fortran 95)
PROGRAM ELLIPTICSOLVER_NMN_CASE3
IMPLICIT NONE
REAL, DIMENSION(:,:), ALLOCATABLE ::X,Y,TOLD,TNEW
REAL ::DX,DY,R
INTEGER ::NX,NY,METHOD
NX=40 !INPUT
NY=40 !INPUT
ALLOCATE(X(NX,NY),Y(NX,NY),TOLD(NX,NY),TNEW(NX,NY))
CALL GRID(X,Y,NX,NY,DX,DY)
R=(DX/DY)
TOLD=0.0
TNEW=0.0
CALL BOUNDARYCONDITION(TOLD,NX,NY,X)
TNEW=TOLD
METHOD=1 !INPUT 1=GAUSSSEIDEL, 2=JACOBI, 3=PSOR
SELECT CASE(METHOD)
CASE(1)
CALL GAUSSSEIDEL(TOLD,TNEW,NX,NY,R,X)
CASE(2)
CALL JACOBI(TOLD,TNEW,NX,NY,R,X)
CASE(3)
CALL PSOR(TOLD,TNEW,NX,NY,R,X)
CASE DEFAULT
CALL GAUSSSEIDEL(TOLD,TNEW,NX,NY,R,X)
END SELECT
CALL DATAWRITER(NX,NY,X,Y,TNEW)
END PROGRAM ELLIPTICSOLVER_NMN_CASE3
SUBROUTINE GRID(X,Y,NX,NY,DX,DY)
IMPLICIT NONE
INTEGER, INTENT(IN) ::NX,NY
REAL, DIMENSION(NX,NY) ::X,Y
REAL :: LX,LY
REAL, INTENT(OUT) ::DX,DY
INTEGER I,J
LX=1
LY=1
DX=LX/REAL(NX-1)
DY=LY/REAL(NY-1)
DO J=1,NY
DO I=1,NX
X(I,J)=(I-1)*DX
Y(I,J)=(J-1)*DY
END DO
END DO
END SUBROUTINE GRID
SUBROUTINE BOUNDARYCONDITION(TOLD,NX,NY,X)
INTEGER ,INTENT(IN) ::NX,NY
REAL, DIMENSION(NX,NY)::TOLD,X
REAL :: TRW
INTEGER I,J
TRW=0
DO I=1,NX
DO J=1,NY
IF(J==1) THEN
TOLD(I,J)=100*(1+X(I,J))
ELSE IF(I==NX) THEN
TOLD(I,J)=TRW
ELSE
TOLD(I,J)=0.0
END IF
END DO
END DO
END SUBROUTINE BOUNDARYCONDITION
SUBROUTINE BOUNDARYUPDATE(TNEW,NX,NY,X)
INTEGER, INTENT(IN) ::NX,NY
REAL, DIMENSION(NX,NY)::TNEW,X
REAL ::TRW
INTEGER I,J
!TTW=0 ADIABATIC
TRW=0
!TLW=0 ADIABATIC
!TBW=100
DO I=1,NX
DO J=1,NY
IF(I==1) THEN
TNEW(I,J)=TNEW(I+1,J)
ELSE IF(J==1) THEN
TNEW(I,J)=100*(1+X(I,J))
ELSE IF(I==NX) THEN
TNEW(I,J)=TRW
ELSE IF(J==NY) THEN
TNEW(I,J)=TNEW(I,J-1)
END IF
END DO
END DO
!CORNER TREATMENT
TNEW(1,1)=(TNEW(1,2)+TNEW(2,1))/2
TNEW(1,NY)=(TNEW(1,NY-1)+TNEW(2,NY))/2
TNEW(NX,1)=(TNEW(NX,2)+TNEW(NX-1,1))/2
TNEW(NX,NY)=(TNEW(NX,NY-1)+TNEW(NX-1,NY))/2
END SUBROUTINE BOUNDARYUPDATE
SUBROUTINE DATAWRITER(NX,NY,X,Y,TNEW)
INTEGER,INTENT(IN) ::NX,NY
REAL, DIMENSION(NX,NY)::TNEW,X,Y
INTEGER I,J
OPEN(20,FILE="DATA.txt")
DO J=1,NY
DO I=1,NX
WRITE(20,*)X(I,J),Y(I,J),TNEW(I,J)
END DO
END DO
CLOSE(20)
END SUBROUTINE DATAWRITER
!######################################## Gauss seidel ###########################
SUBROUTINE GAUSSSEIDEL(TOLD,TNEW,NX,NY,R,X)
INTEGER, INTENT(IN) ::NX,NY
REAL,DIMENSION(NX,NY) ::X
REAL,DIMENSION(NX,NY) ::TOLD,TNEW
REAL, INTENT(IN) ::R
REAL ::ERROR,ERRORMAX
INTEGER ::COUNTER,I,J
COUNTER=0
ERROR=0.0
ERRORMAX=0.00001
DO
ERROR=0.0
DO I=2,NX-1
DO J=2,NY-1
TNEW(I,J)=(TOLD(I+1,J)+TNEW(I-1,J)+ (R*R)*(TOLD(I,J+1)+TNEW(I,J-1)))/(2.0+2.0*(R*R))
ERROR= ERROR + (TNEW(I,J)-TOLD(I,J))**2
END DO
END DO
CALL BOUNDARYUPDATE(TNEW,NX,NY,X)
TOLD=TNEW
COUNTER=COUNTER+1
PRINT *,SQRT(ERROR)/(NX*NY)
IF (SQRT(ERROR)/(NX*NY)<ERRORMAX) EXIT
END DO
END SUBROUTINE GAUSSSEIDEL
!######################################## Jacobi ############################
SUBROUTINE JACOBI(TOLD,TNEW,NX,NY,R,X)
INTEGER, INTENT(IN) ::NX,NY
REAL,DIMENSION(NX,NY) ::X
REAL,DIMENSION(NX,NY) ::TOLD,TNEW
REAL, INTENT(IN) ::R
REAL ::ERROR,ERRORMAX
INTEGER ::COUNTER,I,J
COUNTER=0
ERROR=0.0
ERRORMAX=0.00001
DO
ERROR=0.0
DO I=2,NX-1
DO J=2,NY-1
TNEW(I,J)=(TOLD(I+1,J)+TOLD(I-1,J)+ (R*R)*(TOLD(I,J+1)+TOLD(I,J-1)))/(2.0+2.0*(R*R))
ERROR= ERROR + (TNEW(I,J)-TOLD(I,J))**2
END DO
END DO
CALL BOUNDARYUPDATE(TNEW,NX,NY,X)
TOLD=TNEW
COUNTER=COUNTER+1
PRINT *,SQRT(ERROR)/(NX*NY)
IF (SQRT(ERROR)/(NX*NY)<ERRORMAX) EXIT
END DO
END SUBROUTINE JACOBI
!######################################## POINT SOR ###############################
SUBROUTINE PSOR(TOLD,TNEW,NX,NY,R,X)
INTEGER, INTENT(IN) ::NX,NY
REAL,DIMENSION(NX,NY) ::X
REAL,DIMENSION(NX,NY) ::TOLD,TNEW
REAL, INTENT(IN) ::R
REAL ::ERROR,ERRORMAX,W
INTEGER ::COUNTER,I,J
COUNTER=0
ERROR=0.0
ERRORMAX=0.000000001
W=1.5
DO
ERROR=0.0
DO I=2,NX-1
DO J=2,NY-1
TNEW(I,J)=(1-W)*TOLD(I,J)+(W*(TOLD(I+1,J)+TNEW(I-1,J)+ (R*R)*(TOLD(I,J+1)+TNEW(I,J-1))))/(2.0+2.0*(R*R))
ERROR= ERROR + (TNEW(I,J)-TOLD(I,J))**2
END DO
END DO
CALL BOUNDARYUPDATE(TNEW,NX,NY,X)
TOLD=TNEW
COUNTER=COUNTER+1
PRINT *,SQRT(ERROR)/(NX*NY)
IF (SQRT(ERROR)/(NX*NY)<ERRORMAX) EXIT
END DO
END SUBROUTINE PSOR
Results:
Comments
Post a Comment