- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am very new to FORTRAN, especially the OOP programming using FORTRAN.
I am reading some online notes but I think the resources are a little bit limited on OOP for beginners.
This is how I tried to create a class and overload its constructor:
!**************************************************************************** ! Grid Class !**************************************************************************** ! ! CLASS: Geo >> Point >> .:Grid:. >> Vector ! ! PURPOSE: Grids are same as points but assignable to a coordinate system ! !**************************************************************************** module class_grid use class_point implicit none private public :: grid !========================================== ! Class Properties !========================================== type, extends(point) :: grid !< grid class properties: private !! nothing private Integer, public :: cd !! coordinate system for displacements Integer, public :: ps !! BC (permanent single point) contains !! end type grid !> !------------------------------------------ interface grid module procedure grid_init01 module procedure grid_init02 end interface Contains !========================================== ! M e t h o d s !========================================== ! Constructor type(grid) function grid_init01(id, cp, x1, x2, x3, cd, ps) Integer, intent(in) :: id !! ID of geo object Integer, intent(in) :: cp !! ID of coordinate system Real, intent(in) :: x1 !! first coordinate Real, intent(in) :: x2 !! second coordinate Real, intent(in) :: x3 !! third coordinate Integer, intent(in) :: cd !! coordinate system for displacements Integer, intent(in) :: ps !! BC (permanent single point) grid_init01.id = id grid_init01.cp = cp grid_init01.x1 = x1 grid_init01.x2 = x2 grid_init01.x3 = x3 grid_init01.cd = cd grid_init01.ps = ps end function grid_init01 type(grid) function grid_init02(id, x1, x2, x3) Integer, intent(in) :: id !! ID of geo object Real, intent(in) :: x1 !! first coordinate Real, intent(in) :: x2 !! second coordinate Real, intent(in) :: x3 !! third coordinate Integer :: cd !! coordinate system for displacements Integer :: ps !! BC (permanent single point) cd = 0 ps = 0 grid_init02.id = id grid_init02.cp = 0 grid_init02.x1 = x1 grid_init02.x2 = x2 grid_init02.x3 = x3 grid_init02.cd = cd grid_init02.ps = ps end function grid_init02 !------------------------------------------ end module class_grid
I suppose that the grid_init01 and grid_init02 are constructors that are selected based on given arguments.
But when I use:
type(grid) :: G1 type(grid) :: G2 G1 = grid(1, 1, 1, 1, 1, 1, 1) G2 = grid(1, 1, 1, 1)
I will get a compiler error:
error #8212: Omitted field is not initialized. Field initialization missing: [CD]
So did I get it wrong?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dummy arguments x1, x2, x3 are real, so the 2nd to 4th arguments to the constructor call for G2 should be real too:
G2 = grid(1, 1.0, 1.0, 1.0)
Similarly, the 3rd to 5th arguments for the constructor for G1 should also be 1.0.
I'm assuming your point type is declared something like:
module class_point implicit none private public :: point type point private Integer, public :: id Integer, public :: cp real, public :: x1, x2, x3 end type end module
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dummy arguments x1, x2, x3 are real, so the 2nd to 4th arguments to the constructor call for G2 should be real too:
G2 = grid(1, 1.0, 1.0, 1.0)
Similarly, the 3rd to 5th arguments for the constructor for G1 should also be 1.0.
I'm assuming your point type is declared something like:
module class_point implicit none private public :: point type point private Integer, public :: id Integer, public :: cp real, public :: x1, x2, x3 end type end module
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
S. PMay wrote:
I am very new to FORTRAN, especially the OOP programming using FORTRAN.
I am reading some online notes but I think the resources are a little bit limited on OOP for beginners...
Take a look at this, especially the reference in the footnote "Scientific Software Design: The Object-Oriented Way" by Rouson et al.
https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world
By the way, note a related thread on this forum regarding constructors:
https://software.intel.com/pt-br/node/721089
Also, note the standard Fortran delimiter for derived type components is "%" and not period (.); the latter is a non-standard extension supported by Intel Fortran but it may not work with other compilers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A note on the sample program in #1 aside from the issue related to constructors.
The OOP model as presented above presents the data as Array of Structures (AOS). This format is not favorable to SIMD instructions. Using Structure of Arrays (SOA) is much more friendly to SIMD instructions. Using narrow SSE SIMD instructions (2 doubles/4 floats) may not have experienced a significant difference making the tradeoff between classical particle and high performance computing requirements. AVX/AVX2 with wider SIMD vectors changed this, and now AVX512 (8 or 16 wide vectors) changed this even more. For systems of large numbers of particles, your program design should have performance a higher weight than particle abstractness into a single object.
Use of SOA's is not so difficult if you make your abstraction at the level of "a collection of particles" as opposed to "each particle". Then make your particle-to-particle interactions being described as particle-to-collection or particle-to-collection subset. Programming in this manner will make better use of the CPU (i.e. less time to solution/integration step).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
S. PMay wrote:
I am very new to FORTRAN ...
Fyi, following ISO/IEC standard 1539:1991 published more than 25 years ago it has been trying to be referred to as Fortran, not FORTRAN!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Mark, FortranFan, Jim;
Thank you very much. Every time I ask a question I learn more than just the answer to my question.
Just in case, I was wondering is there the possibility to call constructor of the base class to initialize common fields, so I don't have to rewrite it in the constructor of inherited class?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I believe the compiler is using the default constructor that comes with derived types and not your functions. That explains why it says fields are not initialized when you dont supply enough arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
S. MPay wrote:
.. I was wondering is there the possibility to call constructor of the base class to initialize common fields, so I don't have to rewrite it in the constructor of inherited class?
Yes, say your 'class' e_t (extended derived type in Fortran) inherits a base class named b_t, you can do <xx>%b_t = b_t(..) where <xx> is the object of type e_t because the base type in 'contained' in the extended type. Look into the limitations when the base is an abstract type though.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Andrew Smith wrote:
I believe the compiler is using the default constructor that comes with derived types and not your functions. That explains why it says fields are not initialized when you dont supply enough arguments.
Now I understand why G1 = grid(1, 1, 1, 1, 1, 1, 1) would work. I need to input appropriate type so the compiler can detect which constructor to use otherwise it will simply try the default constructor.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:
Yes, say your 'class' e_t (extended derived type in Fortran) inherits a base class named b_t, you can do <xx>%b_t = b_t(..) where <xx> is the object of type e_t because the base type in 'contained' in the extended type. Look into the limitations when the base is an abstract type though.
Thanks, that made my life much easier!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page