Fortran learner repository
All the basics of fortran will be covered in this repo.
Hello World
The f90 extension will be used for the fortran program.
- Fortran Program starts with PROGRAM <program_name>
- Program ends with END PROGRAM <program_name>
PROGRAM HELLO_WORLD
IMPLICIT NONE
PRINT *, "Hello, World"
END PROGRAM HELLO_WORLD
Fortran 90 is case insensitive but it is standard practice for keywords to be in UPPERCASE.
To compile,
# To compile the program to objects
gfortran -c -o main.o main.f90
# To link the objects to form the binary
gfortran -o hello_world main.o
Types, Variables, Constants, Operators
Names in fortran
The names in fortran can have a maximum of 31 alphnumeric characters (letters, numbers, underscore). The first letter of the identifier must be letter. identifiers are case insensitive.
Implicit typing in fortran
Fortran defaults to implicit typing. It means it will assign the variable type based on the first letter of the variable.
If the name of the variable starts with i, j, k, l, m or n, it is an integer. Otherwise it is an real number.
It is highly discouraged to use implicit typing. To disable implicit typing,
PROGRAM DISABLE
IMPLICIT NONE
END PROGRAM DISABLE
Variables
A variable is a data object which can be defined and redefined. All variables have a type to them. Varibles are to be declared at the beggining of a program or a sub program in a type declaration statement.
To declare a variable,
PROGRAM VARIABLE
IMPLICIT NONE
INTEGER :: VAR_1
END PROGRAM VARIABLE
All variables have implicit type assigned to them by default. To avoid it, use IMPLICIT NONE keyword.
Constants
A constant is a data object whose value cannot be changed.
A literal constant is a value without a name such as 3.14(real constant), "Hello"(character constant), (3.0,3.1)(complex constant), true(literal constant).
A named constant is a constant value with name. To declare a named constant, declare it with the rest of the variables at the beginning of the program with the parameter attribute.
PROGRAM CONSTANTS
IMPLICIT NONE
INTEGER, PARAMETER :: CONST_1 = 500
END PROGRAM CONSTANTS
Types
Fortran has 5 intrinsic data types. Fortran allows you to use derived data types which are created by the user.
INTEGER
INTEGER type allows you to use integers.
REAL
For real numbers the processor provides two REAL types,
- single precision (default REAL)
- double precision
COMPLEX
For COMPLEX number. Consist of two real numbers for real and complex part. For 2+1i, the value is (2.0,1.0)
To assign a variable to another complex, use CMPLX() function.
LOGICAL
Two LOGICAL values. .TRUE. and .FALSE.. Periods are important.
CHARACTER
For characters and strings. Length of the string is specified by the LEN specifier. If no length is specified, the default is 1.
Arrays
Series of variables can be collected into array. Arrays can be 1 - 7 dimensional arrays. Arrays are declared with DIMENSION attribute. Fortran arrays follow 1 based indexing.
To declare the array,
PROGRAM ARRAYS
IMPLICIT NONE
! Array with 3 x 4 x 5 dimension.
REAL, DIMENSION(3,4,5) :: MATRIX
END PROGRAM ARRAYS
To declare explicit lower bounds,
PROGRAM ARRAYS
IMPLICIT NONE
! Array with 3 x 4 x 5 dimension.
REAL, DIMENSION(0:4) :: MATRIX
END PROGRAM ARRAYS
Character Strings
String is a character array. The length of the string can be specified with the LEN parameter. The slices of string can be referred with (m:n) parameter.
To declare a string,
PROGRAM STRING
IMPLICIT NONE
CHARACTER(LEN = 20) :: STRING
STRING="lorem ipsum"
PRINT *,STRING
PRINT *,STRING(:4)
PRINT *,STRING(4:)
END PROGRAM STRING
Derived Data types
Derived data type is basically a struct. It consists of different types inside it.
To access the types inside the derived type, use % operator. To create a derived type,
PROGRAM DERIVED_TYPE
TYPE :: PERSON
CHARACTER(LEN=20) :: NAME
INTEGER :: AGE
END TYPE PERSON
IMPLICIT NONE
TYPE(PERSON) :: PERSON_1
PERSON_1%CHARACTER="John Doe"
PERSON_1%AGE=18
END PROGRAM DERIVED_TYPE
Arithmetic operators
Fortran supports the following operators,
- exponentiation **
- multiplication *
- division /
- addition +
- subtraction -
Fortran follows integer division by default, if no types are specified. To do real division, use the REAL() function.
Logical operators
Fortran supports the following operators,
- .NOT.
- .AND.
- .OR.
- .EQV.
- .NEQV.
.EQV. and .NEQV. are only for logical statements.
Relational operators
Fortran supports the following operators,
- == (Equal to)
- > (Greater than)
- >= (Greater than or equal to)
- < (Less than)
- <= (Less than or equal to)
- /= (Not equal to)
Intrinsic functions
Fortran provides these intrinsic function by default.
Function name | Purpose |
---|---|
abs(x) | absolute value of numeric argument |
acos(x) | inverse cosine function |
asin (x) | inverse sine function |
atan (x) | inverse tan function |
complx (x, y, [,ikind]) | converts to complex |
cos (x) | cos function |
cosh (x) | hyperbolic cosine function |
exp (x) | exponential function |
floor (x) | greatest integer less than or equal to x |
int (x) | convert to int. Removes the decimal off |
log (x) | calculate the natural log of x |
log10 (x) | calculate the log base 10 of x |
mod (x,y) | remainder function of dividing x/y. x - int(x/y)*y |
modulo (x/y) | modulo function (x - floor(x/y)*y) |
nint (x, [,ikind]) | round to nearest integer |
real (x, [,ikind]) | convert to the real number |
sin (x) | sine function |
sinh (x) | hyperbolic sine function |
sqrt (x) | square root function |
tan (x) | tan function |
tanh (x) | hyperbolic tan function |
Simple in and output
To output a text in fortran we use PRINT or WRITE functions.
- PRINT will only writes to the stdout.
- WRITE can write to any file descriptor.
Prints the given args to the stdout.
PRINT f [, iolist]
PRINT grname
PRINT takes the following arguments,
- f (format identifier)
- iolist (list of variables, substrings, arrays, records)
- grname (name of Namelist group)
Format identifier
f is an format identifier and can be,
- An asterisk (*) which indicates list-directed io
- The label of the FORMAT statement in the program.
- Integer of the label of FORMAT
- String that identifies the format.
iolist
iolist can be empty or contain these output items.
- Variables
- Substrings
- Arrays
- Array elements
- Record fields
- Any other expression
grname
grname is name of the namelist.
READ
Reads from the unit identifier given to the args specified.
READ([UNIT=] u [, [FMT=]f] [, IOSTAT=ios] [, REC=rn] [, END=s] [, ERR=s])iolist
READ f [, iolist]
READ grname
Unit identifier
u can either be external unit identifier or internal file identifier.
An external unit identifier must be one of these:
- A nonegative integer expression
- An asterisk(*), identifying the stdin.
Format identifier
f is an format identifier and can be,
- An asterisk (*) which indicates list-directed io
- The label of the FORMAT statement in the program.
- Integer of the label of FORMAT
- String that identifies the format.
I/O STATUS SPECIFIER
ios must be an integer variable or an integer array element. This will be set to zero if the read is successful and set to positive number if the read is unsuccessful.
Record number
rn must be a positive integer expression, and can be used for direct-access files only. rn can be specified for internal files.
End-of-File Specifier
s must be the label of an executable statement in the same program unit in which the READ statement occurs.
Error Specifier
s must be the label of an executable statement in the same program unit in which the READ statement occurs.
iolist
iolist can be empty or contain these output items.
- Variables
- Substrings
- Arrays
- Array elements
- Record fields
- Any other expression
grname
grname is name of the namelist.
WRITE
Writes to the unit identifier given to the args specified.
WRITE([UNIT=] u [, [FMT=]f] [, IOSTAT=ios] [, REC=rn] [, END=s] [, ERR=s])iolist
WRITE f [, iolist]
WRITE grname
Unit identifier
u can either be external unit identifier or internal file identifier.
An external unit identifier must be one of these:
- A nonegative integer expression
- An asterisk(*), identifying the stdin.
Format identifier
f is an format identifier and can be,
- An asterisk (*) which indicates list-directed io
- The label of the FORMAT statement in the program.
- Integer of the label of FORMAT
- String that identifies the format.
I/O STATUS SPECIFIER
ios must be an integer variable or an integer array element. This will be set to zero if the write is successful and set to positive number if the read is unsuccessful.
Record number
rn must be a positive integer expression, and can be used for direct-access files only. rn can be specified for internal files.
End-of-File Specifier
s must be the label of an executable statement in the same program unit in which the WRITE statement occurs.
Error Specifier
s must be the label of an executable statement in the same program unit in which the WRITE statement occurs.
iolist
iolist can be empty or contain these output items.
- Variables
- Substrings
- Arrays
- Array elements
- Record fields
- Any other expression
grname
grname is name of the namelist.
Control Constructs
If constructs
IF statement is used to run a program if the condition given is true.
LABEL IF (LOGICAL_EXPRESSION) THEN
!STATEMENT
END IF LABEL
The label is optional for the if statement.
Both ENDIF and END IF is allowed.
If else constructs
ELSE statement can also be used along with the IF for running statements if condition was false.
LABEL IF (LOGICAL_EXPRESSION) THEN
!STATEMENT
ELSE
!ALTERNATE STATEMENTS
END IF LABEL
Block if statements can be nested.
LABEL IF (LOGICAL_EXPRESSION) THEN
!STATEMENT 1
ELSE IF (LOGICAL_EXPRESSION) THEN
!STATEMENT 2
ELSE IF (LOGICAL_EXPRESSION) THEN
!STATEMENT 3
ELSE IF (LOGICAL_EXPRESSION) THEN
!STATEMENT 4
ELSE
!ALTERNATE STATEMENTS
END IF LABEL
Case constructs
The case construct has the following form,
LABEL SELECT CASE (EXPRESSION)
CASE (SELECTOR_1):
!STATEMENT
CASE (SELECTOR_2):
!STATEMENT
CASE (SELECTOR_3):
!STATEMENT
CASE DEFAULT:
!DEFAULT STATEMENT
END SELECT LABEL
Range of numbers can be specified in a case using (m:n)
Loops
Do loops
The simplest loop can be achieved using DO loop in fortran. The following code is an endless loop.
LABEL DO
!STATEMENT
END DO LABEL
To break out of the do loop, use the EXIT statement.
LABEL DO
!STATEMENT
IF (EXPRESSION) THEN
EXIT
END IF
END DO LABEL
To skip to the next iteration use CYCLE statement.
LABEL DO
!STATEMENT
IF (EXPRESSION) THEN
CYCLE
END IF
END DO LABEL
To specify a do to iterate said times. use a DO VAR=START, END, STEP statement
INTEGER :: I !CONTROL VARIABLE
DO I=0,5
!STATEMENTS
END DO
Do while Loop
To execute a condition while true, use DO WHILE loop.
LABEL DO WHILE (LOGICAL EXPRESSION)
!STATEMENTS
END DO WHILE LABEL
Procedures
A program can be built up from a collection of program units. They are,
- Main program
- Modules
- External subprogramms or Procedures
Subprogram or procedures
Subprogramms or Procedures can be called from the program.They can be,
- Functions
- Subroutines
Functions
Functions accepts arguments and returns a single quantity of any type including arrays.
Functions in principle should not modify the arguments. It is a bad practice.
Functions are of two types. They are,
- Intrinsic Functions: They are built into the language itself.
- External Functions: They are user defined.
Structure of functions is,
FUNCTION CIRCLE_AREA (RADIUS)
IMPLICIT NONE
REAL :: CIRCLE_AREA
REAL :: RADIUS
REAL, PARAMETER :: PI = 3.141592654
CIRCLE_AREA = PI * ( R**2 )
END FUNCTION CIRCLE_AREA
Functions return value is the function name itself. Return type and the argument type should be declared inside the function. Arguments are dummy and the real variable from where the function is called is used.
Note that IMPLICIT NONE should be used inside the function as well as the main program.
The result of the function can be given a different name using the RESULT option. The RESULT option is optional in most cases but must be used when using the recursive functions.
FUNCTION CIRCLE_AREA (RADIUS) RESULT (AREA)
IMPLICIT NONE
REAL :: CIRCLE_AREA
REAL :: RADIUS
REAL, PARAMETER :: PI = 3.141592654
AREA = PI * ( R**2 )
END FUNCTION CIRCLE_AREA
To call the function from the program, one must declare the function with type to use. Functions can be assigned to the variables directly.
PROGRAM MAIN
IMPLICIT NONE
REAL, PARAMETER :: RADIUS = 2
REAL :: CIRCLE_AREA
PRINT *, CIRCLE_AREA (RADIUS)
END PROGRAM MAIN
FUNCTION CIRCLE_AREA (RADIUS)
IMPLICIT NONE
REAL :: CIRCLE_AREA
REAL :: RADIUS
REAL, PARAMETER :: PI = 3.141592654
CIRCLE_AREA = PI * ( R**2 )
END FUNCTION CIRCLE_AREA
RETURN Statements
To return from a function early, use the RETURN keyword.
Subroutines
Functions are only used in case it returns only one thing. In all other cases, subroutines are used. Subroutines returns nothing. Subroutines may or may not modify the arguments given. Subroutines has to be called and cannot be assigned to a variable.
PROGRAM SWAP_NUMBERS
IMPLICIT NONE
REAL :: X = 5
REAL :: Y = 6
PRINT *,X,Y
CALL SWAP (X,Y)
PRINT *,X,Y
END PROGRAM SWAP_NUMBERS
SUBROUTINE SWAP (X,Y)
IMPLICIT NONE
REAL :: BUFFER
REAL :: X
REAL :: Y
BUFFER = X
X = Y
Y = BUFFER
END SUBROUTINE SWAP
Intent
Fortran allows the specification of intention of the arguments used for in the subroutine. There are three intents,
- INTENT (IN) Arguments are read only
- INTENT (OUT) Arguments are write only
- INTENT (INOUT) Arguments are read and write allowed
Intents are mentioned as options in argument type declaration.
PROGRAM SWAP_NUMBERS
IMPLICIT NONE
REAL, INTENT (INOUT) :: X = 5
REAL, INTENT (INOUT) :: Y = 6
PRINT *,X,Y
CALL SWAP (X,Y)
PRINT *,X,Y
END PROGRAM SWAP_NUMBERS
SUBROUTINE SWAP (X,Y)
IMPLICIT NONE
REAL :: BUFFER
REAL :: X
REAL :: Y
BUFFER = X
X = Y
Y = BUFFER
END SUBROUTINE SWAP
License
This project is licensed under GNU GPL v3.0 or later license. Feel free to use the project.