The repository contains phase-field Fortran codes using
- internal procedures
- pure procedures
Procedures in Fortran are of two types:
- function
- subroutine
A function has a single output, however, a subroutine can produce several. This is the primary distinction between a function and a subroutine. Additionally, a user-defined function is used similarly to an intrinsic function, however using a subroutine requires a call
keyword [Ref].
Internal procedures differ from the intrinsic procedures. The intrinsics are defined by the standard e.g., call cpu_time ( ). Internal procedures, on the other hand, are defined by the user and are placed in the same file. The contains statement separates the main program from the subprogram i.e., the internal procedure. The basic idea is shown below.
In many aspects, procedures are similar to the main program. They have a similar appearance, a name, and can also have local variables. That is why the procedures are also called sub-programs.
The subprogram declares the dummy arguments with the intent attribute and can also declare local variables. In the subroutine, the intent (out) declared variable stores the value of the expression but in the function, the value can be stored in the function itself. Therefore, Fortran functions are very much like mathematical functions.
The following example does show the use of subroutine and function. The main program declares the parameters and makes a call to subroutine fluctuation1
and invokes function fluctuation2
.
program example
implicit none
integer ( kind = 4 ), parameter :: Nx = 64, Ny = 64
real ( kind = 8 ) , parameter :: c0 = 0.4, noise = 0.02
real ( kind = 8 ) , dimension ( Nx, Ny ) :: con
! thermal fluctuation
call fluctuation1 ( con, c0, noise ) ! subroutine
con = fluctuation2 ( c0, noise ) ! function
! internal subprograms
contains
subroutine fluctuation1 ( con_, c0_, noise_ )
implicit none
real ( kind = 8 ), dimension ( Nx, Ny ), intent ( out ) :: con_
real ( kind = 8 ), intent ( in ) :: noise_, c0_
real ( kind = 8 ), dimension ( Nx, Ny ) :: r_
call random_number ( r_ )
con_ = c0_ + noise_*( 0.5 - r_ )
end subroutine fluctuation1
!---
function fluctuation2 ( c0_, noise_ )
implicit none
real ( kind = 8 ), dimension ( Nx, Ny ) :: fluctuation2, r_
real ( kind = 8 ), intent ( in ) :: noise_, c0_
call random_number ( r_ )
fluctuation2 = c0_ + noise_* ( 0.5 - r_ )
end function fluctuation2
end program
The second feature of this repository is the use of pure procedures. The feature was introduced in Fortran 95. In pure procedures, the intent attribute of all dummy variables must be declared. We usually use simple procedures for the initial microstructure and pure procedures for the evolution.
Here we present some conventions.
- The filename is based on: the algorithm, the model name, dislin library (if used), the type of internal procedure i.e., function or subroutine, and the version. All files are written in free source format.
- The usage of comments in the code serves many purposes. They are used to differentiate different sections with the style
==
, for procedures with---
and for others with simply!
- The granularity of the program depends on the number of procedures. For instance, the left code makes 4 calls to subroutines and right code only 1; therefore, the former is called fine-grained and later coarse-grained code.
-
The program makes calls to many routines; they are either intrinsic or user-defined. To differentiate, we write all intrinsic subroutines with small letters, and user-defined routines with first letter capital.
-
The user-defined routines are written with associated action verbs. For instance, we usually introduce fluctuation at the initial stage and we set the boundary conditions. This style is also proposed by Norman S. Clerman, see rule 26, 27. The table clarifies the concept:
Intrinsic | User-defined |
---|---|
random_number ( ) | Introduce_fluctuation |
cpu_time ( ) | Set_boundary_conditions |
- To make the procedure arguments easy to follow,
_
is appended at the end of dummy arguments. This practice makes them consistent with the actual argument. For example, the code above has the dummy argumentcon_
for the actual argumentcon
.
git clone https://github.com/Shahid718/Fortran-Phase-field-codes-using-Internal-Procedures
- using a script by Dislin
f90link -a -r8 main
- The general commands with dislin graphical library are:
For Linux OS — with gfortran — to compile, enter
gfortran main.f90 -o main -L/usr/local/dislin/ -I/usr/local/dislin/gf/real64 -ldislin_d
and to run, enter
./main
and for windows — with gfortran and with intel — to compile, enter
gfortran main.f90 -o main -Ic:\dislin\gf\real64 c:\dislin\dismg_d.a -luser32 -lgdi32 -lopengl32
ifort main.f90 -Ic:\dislin_intel\ifc\real64 c:\dislin_intel\disifl_d.lib user32.lib gdi32.lib opengl32.lib
and to run, enter
main
- For the codes without dislin, there is no need to link the dislin library.
In case, you find issues to report or having trouble using the codes, you may contact via email