Fortran Derived Types Tutorial
This tutorial introduces Fortran derived data types, from basic intrinsic types to object-oriented type-bound procedures.
Prerequisites
Basic Fortran knowledge (variables, subroutines)
Fortran 90+ compiler (gfortran, ifort, nvfortran)
Learning objective
By the end of this tutorial, you will:
Define and use derived types
Apply automatic constructors
Pass derived types to subroutines
Implement type-bound procedures
Complete Code Example
The complete tutorial code is available in derived_types_tutorial.f90
Concept Breakdown
1. Intrinsic Data Types
Purpose: Basic variable declaration without structure.
program grid_example
implicit none
integer :: nx, ny, dx, dy
nx = 50
ny = 50
dx = 2
dy = 2
end program grid_example
Characteristics:
Simple, but each variable is independent
No logical grouping
Limited scalability
2. Derived Data Types
Purpose: Group related variables into a single logical unit.
program grid_example
implicit none
type gridType
integer :: nx, ny, dx, dy
end type gridType
type(gridType) :: grid
grid%nx = 50
grid%ny = 50
grid%dx = 2
grid%dy = 2
end program grid_example
Characteristics:
Groups multiple variables into a single composite object
Provides logical grouping of related data
Scalable and reusable across programs and subroutines
Access components using the
%operator (e.g.,grid%nx)
3. Derived Type with Constructor
Purpose: Group related data into a single unit.
program test
implicit none
type gridType
integer :: nx, ny, dx, dy
end type gridType
type(gridType) :: grid
! Automatic structure constructor
grid = gridType (nx=50, ny=50, dx=2, dy=2)
end program
Characteristics:
gridTypegroups four integers logicallyAutomatic constructor
gridType(...)is implicitly availableNamed arguments improve readability
4. Subroutine with Derived Type Argument
Purpose: Initialize derived types through procedural programming.
program test
implicit none
type gridType
integer :: nx, ny, dx, dy
end type gridType
type(gridType) :: grid
call createGrid (grid, nx=50, ny=50, dx=2, dy=2)
contains
subroutine createGrid (this, nx, ny, dx, dy)
type(gridType), intent(inout) :: this
integer, intent(in) :: nx, ny, dx, dy
this%nx = nx
this%ny = ny
this%dx = dx
this%dy = dy
print*, this%nx, this%ny, this%dx, this%dy
end subroutine createGrid
end program
Key Points:
Use
intent(inout)rather thanintent(out)(preserves existing data)Component access via
%operator:this%nxSubroutine contained in program (implicit interface)
Tip
intent(inout) is recommended over intent(out) because it avoids undefined initial values if the derived type has allocatable components or later extensions.
5. Type-Bound Procedures (Object-Oriented Fortran)
Purpose: Attach methods directly to types (Fortran 2003+).
module gridType_module
implicit none
type gridType
integer :: nx, ny, dx, dy
contains
procedure :: createGrid
end type gridType
contains
subroutine createGrid (this, nx, ny, dx, dy)
class(gridType), intent(inout) :: this ! Must be CLASS
integer, intent(in) :: nx, ny, dx, dy
this%nx = nx
this%ny = ny
this%dx = dx
this%dy = dy
print*, this%nx, this%ny, this%dx, this%dy
end subroutine createGrid
end module gridType_module
program test
use gridType_module
implicit none
type(gridType) :: grid
call grid%createGrid (nx=50, ny=50, dx=2, dy=2)
end program
Why CLASS instead of TYPE?
Type |
Use Case |
Polymorphic |
|---|---|---|
|
Non-polymorphic arguments |
No |
|
Polymorphic arguments (type extensions) |
Yes |
For type-bound procedures, the passed object is polymorphic, so CLASS is mandatory.
Comparison Table
Concept |
Syntax Example |
|---|---|
Intrinsic type |
|
Derived type definition |
|
Automatic constructor |
|
Component access |
|
Subroutine with derived type |
|
Type-bound procedure |
|
Polymorphic argument |
|
Compilation and Execution
#compile
gfortran -o derived_types_tutorial derived_types_tutorial.f90
# Run
./derived_types_tutorial
Expected Output (Example 4):
50 50 2 2
Key Takeaways
Important
Use
intent(inout)for derived type arguments in subroutinesPrefer
CLASSoverTYPEfor type-bound procedure argumentsEncapsulate types in modules for reusability and clean interfaces
Use automatic constructors with named arguments for clarity
Exercises
Modify the grid to include a real component called
resolutionAdd a method
printGrid()to display formatted outputCreate an extended type
grid3DTypewith annzcomponentImplement validation in
createGridto ensure positive grid dimensions
Further Reading
Modern Fortran Explained (Metcalf, Reid, Cohen)
Introduction to Programming with Fortran (Chivers , Sleightholme)