Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Polymorphism question

Li_Dong
Beginner
927 Views
Hi, all,

I looked up the support list of Intel Fortran compiler 11.1 for standard 2003, and found "polymorphic entries". But when I tested it as the following simple code:
program test
type base
integer i
end type base
type, extends(base) :: A
integer j
end type A
type, extends(base) :: B
real k
end type B
class(base), allocatable :: m
allocate(A::m)
m%j = 1
write(*,*) m%j
stop
end program test
ifort (11.1 20090827) complains that:
... error #6460: This is not a field name that is defined in the encompassing structure.
m%j
-------^
So any help? Thanks~
DONG Li
0 Kudos
1 Solution
thomas_boehme
New Contributor II
927 Views

Hi DONG Li,

I think I understand what you are trying to achieve.

However, if you want to "work" with the various mesh types in some generic form,you canoften can come up with someinterface common to all mesh types. E.g. this could be type-bound procedures (TBP), let's say for example you use a common procedure called Update(...).

You could then define the procedure Update(...) to be a TBP in your base mesh class and overload it in all mesh type extensions with the appropriate method for mesh1D, mesh2D, etc.

That way you can use a variable mesh that is of class(mesh) and work with it, even if it's a mesh1D, mesh2D, etc.. Within the TBP procedures, the generic variable mesh will be accessible as the specific type, e.g. in an overloaded Update(...) routine in mesh2d the passed type will be mesh2d, even ifis wascalled via the generic variable mesh by calling mesh%Update().

If it's not possible to come up withsuch acommon interface foryour extended types, than you have to use the SELECT TYPE construct. While I agree that it is quite cumbersome in the syntax, it has the advantage over e.g. C++ type casts, that it is alwayssafe, as it does not allow you to access a field/TBP that is not present in your instance of the class.

I am also trying to make significant use of the new OO features in our codes, and so far I managed to keep the SELECT TYPEs at a minimum by defining common interfaces via TBP. However, I want to warn you that the TBP facilities in IVF11 Update 5 still have some severe issues that can lead to internal compile errors or wrong executable code in more complex situations.

regards,
Thomas



View solution in original post

0 Kudos
6 Replies
zuch
Beginner
927 Views

You can get the access to the extended components of the dynamic parts by select type construct
try this
select type(m)
type is(A)
write(*,*) m%j
type is(base)
! here you can not access m%j
write(*,*) "do something"
class default
write(*,*) "do something"
end select
Cheers
zuch

0 Kudos
Li_Dong
Beginner
927 Views
Hi zuch,
I haven't seen this syntax before! I tried it, and it works. But this syntax is a little cumbersome, since polymorphism is for simplification and versatility. : )
Thanks for help!
DONG Li
0 Kudos
thomas_boehme
New Contributor II
927 Views
I also struggled with that in the beginning, but now I think this is actually a reasonable approach.

What it boils down to is that you need to define your fields/type-bound procedures at the highest level of the hierarchy that you intend to use them.

In your code,what would you expect to happen when you call:

allocate(base:m)
m%j = 1

That j field does not exist in the base class at all. You implicitly relied on the fact that you knew that you reserved m to be of type A. If that's the case, why not make m a class(A) object? This is still polymorphic isthere are further extensions to A.E.g. if you modify your code to something like this:


[fortran]program test
type base
integer i
end type base
type, extends(base) :: A
integer j
end type A
type, extends(A) :: B
real k
end type B
class(A), allocatable :: m
allocate(B::m)
m%j = 1
write(*,*) m%j
stop
end program test
[/fortran]
Regards, Thomas
0 Kudos
Li_Dong
Beginner
927 Views
Hi Thomas,

My purpose for doing this little test is that I want to define a common base type, and other extended types, and just use one variable whose type is determined at runtime.
For example in computational fluid dynamics, there is a base mesh type, and several other concrete mesh types like 1D mesh, and 2D quadrilateral mesh, if that test works, then I can just declare a variable named "mesh", and change its type according to runtime configuration. But now I have to declare "mesh1" and "mesh2", in 1D mesh type and 2D mesh type respectively.
Maybe it is not necessary for doing that. Just wonder. : )
Cheers,
DONG Li
0 Kudos
thomas_boehme
New Contributor II
928 Views

Hi DONG Li,

I think I understand what you are trying to achieve.

However, if you want to "work" with the various mesh types in some generic form,you canoften can come up with someinterface common to all mesh types. E.g. this could be type-bound procedures (TBP), let's say for example you use a common procedure called Update(...).

You could then define the procedure Update(...) to be a TBP in your base mesh class and overload it in all mesh type extensions with the appropriate method for mesh1D, mesh2D, etc.

That way you can use a variable mesh that is of class(mesh) and work with it, even if it's a mesh1D, mesh2D, etc.. Within the TBP procedures, the generic variable mesh will be accessible as the specific type, e.g. in an overloaded Update(...) routine in mesh2d the passed type will be mesh2d, even ifis wascalled via the generic variable mesh by calling mesh%Update().

If it's not possible to come up withsuch acommon interface foryour extended types, than you have to use the SELECT TYPE construct. While I agree that it is quite cumbersome in the syntax, it has the advantage over e.g. C++ type casts, that it is alwayssafe, as it does not allow you to access a field/TBP that is not present in your instance of the class.

I am also trying to make significant use of the new OO features in our codes, and so far I managed to keep the SELECT TYPEs at a minimum by defining common interfaces via TBP. However, I want to warn you that the TBP facilities in IVF11 Update 5 still have some severe issues that can lead to internal compile errors or wrong executable code in more complex situations.

regards,
Thomas



0 Kudos
Li_Dong
Beginner
927 Views
Hi Thomas,

Thanks for your excellent explanation! If I have read your post more early, maybe my code will be more simple and beautiful : ). Now, the only choice for me is keeping the old code for correctness. And I will keep following the transformation of Fortran to OO in the future.
Cheers,
DONG Li
0 Kudos
Reply