Fortran generic procedure error: may not be generic - fortran

I know that you can make generic procedures using abstract types, like in here:
fortran class declaration of dummy argument
But can I do the same sort of thing with the following code?
module proc_mod
public :: forced,ideal
interface forced; module procedure forced1; end interface
interface forced; module procedure forced2; end interface
contains
function forced1() result(forced)
implicit none
integer:: forced
forced = 1
end function
function forced2(t) result(forced)
implicit none
integer,intent(in) :: t
integer:: forced
forced = t
end function
function ideal() result(i)
implicit none
integer:: i
i = 2
end function
end module
program procTest
use proc_mod
implicit none
integer :: n
procedure(forced), pointer:: funPointer => NULL()
write(*,'(A)') "Please enter the type of vortex calculation you wish to use."
read(*,*) n
select case( n )
case( 1 ); funPointer => forced
case( 2 ); funPointer => ideal
case default; funPointer => ideal
end select
write(*,'(A,I3)') "You chose function: ", funPointer()
stop
end program
Right now I'm getting the error: funPointer may not be generic. I'm sure there's a way around it, but I'm unfamiliar with generic procedures.

No, you cannot make procedure pointer to a generic procedure. You also cannot pass generic procedures as dummy argument. You must always choose one specific function.
You should perhaps explain what is your intention, not just show some code and ask if it can be done differently. But anyway, take in mind that Fortran generics are used for compile time dispatch.

Related

How to avoid rewriting the same interface for a deferred type-bound procedure implemented in a submodule?

Consider the following code, which defines an abstract type foo with a deferred procedure sub, and a type foo2 which extends foo:
MODULE m
TYPE, ABSTRACT:: foo
CONTAINS
PROCEDURE(sub_int), DEFERRED:: sub
END TYPE
INTERFACE
SUBROUTINE sub_int(THIS, x)
IMPORT:: foo
CLASS(foo), INTENT(IN):: THIS
DOUBLE PRECISION, INTENT(INOUT):: x
END SUBROUTINE
END INTERFACE
TYPE, EXTENDS(foo):: foo2
CONTAINS
PROCEDURE:: sub
END TYPE
INTERFACE
MODULE SUBROUTINE sub(THIS, x)
CLASS(foo2), INTENT(IN):: THIS
DOUBLE PRECISION, INTENT(INOUT):: x
END SUBROUTINE
END INTERFACE
END MODULE
SUBMODULE (m) s
CONTAINS
MODULE PROCEDURE sub
x= x**2
END PROCEDURE
END SUBMODULE
Is there a way to avoid writing the second interface?
I understand that it is needed in order to declare sub as a module procedure (otherwise the implementation would need to be done in the module, and not in the submodule), but is this the only way to do it?
In other words, is it possible to implement the procedure sub for foo2 without rewriting the entire interface for it?
It is not possible. A separate module subprogram requires an interface block, either in its defining submodule or an ancestor of its defining submodule.
Whether a procedure happens to be nominated by one (or more!) bindings of one (or more!) types is totally irrelevant.

How to point with one method to two different methods?

I have intention to point with the same procedure to two different procedures but I have not experienced programmer in Fortran so I need help.
This is my simple code:
module types
type :: type_one
integer, private :: a1,a2
contains
procedure, public :: f_data => set_data_a1
procedure, public :: f_data => cal_data_a2
end type type_one
private :: set_data_a1,cal_data_a2
contains
integer function set_data_a1(this)
class(type_one) :: this
this%a1 = 2
end function set_data_a1
integer function calc_data_a2(this)
class(type_one) :: this
this%a2 = this%a1 + 3
end function calc_data_a2
end module types
program types_pro
implicit none
type(type_one) :: type_obj
type_obj%f_data()
end program types_pro
I got this error:
`There is already a procedure with binding name 'f_data' for the derived type 'type_one' |
Is it possible to call both procedures at the same time with type_obj%f_data()?
A generic name, such as your f_data, allows calling procedures with different input signatures (rank, type, kind, and number of arguments) by the same name. But, because they have the same argument signatures the compiler can't determine which of calc_data_a1 and calc_data_a2 to execute when your code makes a call to f_data.
Which leads me to a question for you: How do you expect the compiler or code to behave ? What do you want the compiler to do ? (OK that was two questions.)
As a general rule, if you want the compiler to execute two procedures you have to make two calls. You could, I suppose, have one procedure call the other if you want both to run when one is called.
If you want to wrap multiple functions behind the same name they have to have different input signatures so that the compiler can work out which one to call.
Obviously my earlier version of this answer wasn't explicit enough:
No, there is no way to write your code to execute two different procedures in response to a single call to one of them. (Unless, that is, the one calls the other.) Furthermore, it is unreasonable to expect a single (procedure) pointer to point, at any one time, at more than one target.

Type bound procedures of polymorphic components of derived types

I am writing some simulation code (almost) from scratch and want to use OOP features from fortran to keep it easier to maintain. I've learned in a fortran workshop, that one should be carefull when using OOP features within performance critical parts of the code.
My naive first approach (ignoring the warning) would be the following snippet. The background is the calculation of a system energy which needs an interaction potential. For this potential, I use an abstract type (potential). All users can then add their own potentials as extensions and define a keyword that is used to allocate their potential. The energy calculation in the main program does not change.
module system_mod
implicit none
type, abstract :: potential
contains
procedure(init), deferred :: init
procedure(eval), deferred :: eval
end type
type, extends(potential) :: my_potential
! some parameters
contains
procedure :: init => init_my_potential
procedure :: eval => eval_my_potential
end type
! omitted: other extensions of 'potential'
! and abstract interface of potential
type :: system
! some components
class(potential), allocatable :: pair_potential
contains
procedure :: init ! subroutine, which is used to allocate pair_potential depending on a passed keyword
end type
contains
! implementation of all routines
end module system_mod
program main
use system_mod, only: potential, my_potential, system
implicit none
character(len=3) :: keyword !
integer :: i
real :: coordinates(n,3) ! n is a huge number
real :: energy, system_energy
type(system) :: test_system
call test_system%init ( keyword )
! keyword tells which of the extensions of 'potential' is allocated
do i = 1, n
energy = test_system%pair_potential%eval ( ... )
system_energy = system_energy + energy
end do
end program
I think my main problem concerning the performance is that I don't get what the compiler actually does at compile time and which things are done at run time.
So my questions are:
How or when does the compiler check, which instance of 'eval' to use?
When the keyword is known at compile time, is there a type check in every iteration of the loop?
Would it be better to, for example, use a procedure pointer in the main program, and associate it at the beginning to the according 'eval' procedure?
Thank you very much in advance!
It has a virtual table of procedures that are possible to be called for the binding for all extended types and decides in run-time from this table.
Setting keyword may not help, it depends on how much the compiler is clever. I would use type instead of class if the type is known at the compile time. This is very likely to skip the vtable look-up.
The procedure pointer will affect the flow of the instructions too, although you may save some part of the vtable look-up. This really depends on the internals and is worth a try and some performance measurement.

Access a parameter from an interface (Fortran)

I am using a parameter to fix the precision of the used types.
This works fine until I try to use the same type within an interface. Consider this small example:
module Hello
implicit none
save
integer, parameter :: K = selected_real_kind(10)
contains
subroutine dosomething(fun)
real(K) :: foo
interface
function fun(bar)
real(K) :: bar
real(K) :: fun
end function fun
end interface
end subroutine
end module
Here, foo would be of the desired type, whereas the compiler (gfortran) complains for 'bar' and 'fun'.
The error is
Error: Parameter 'k' at (1) has not been declared or is a variable, which does
not reduce to a constant expression
Is there a way to get this working?
(For now, I am just writing selected_real_kind(10) everywhere but this is not elegant at all)
Thank you!
The easiest way is to add import inside the interface. It is somewhat of a misdesign that the definitions of the module are outside the scope of the interface. Plain import will import everything.
....
subroutine dosomething(fun)
real(K) :: foo
interface
function fun(bar)
import
real(K) :: bar
real(K) :: fun
end function fun
end interface
end subroutine
....
Also possible: import :: K

Is it possible to emulate mixed abstract/deferred and regular procedures in Fortran 2003?

When I try to mix both regular procedures and deferred procedures in one abstract type, gfortran balks at any invocation of the regular procedures:
" Error: Base object for type-bound procedure call at (1) is of ABSTRACT type 'tbody' "
type, abstract :: tBody
private
...
contains
procedure :: init => new_Body
...
procedure (contained), deferred :: PointIn
end type tBody
abstract interface
logical(LGT) pure function contained( Body, Point )
import :: tBody, tAffinePoint, LGT
class(tBody), intent(IN) :: Body
type(tAffinePoint), intent(IN) :: Point
end function contained
end interface
subroutine newCuboid( this, ... )
class(tCuboid), intent(OUT) :: this
...
call this%tBody%init( ... )
.... [gfortran halts here]
end subroutine newCuboid
Is there a way to arrange the type tBody so that I can have both abstract, deferred procedures and regular, instantiated procedures?
No.
There's a simple solution - replace call this%tBody%init(...) with call new_Body(...) (you may need to make appropriate accessibility changes).
Possibly feeble rationalisation - you are not resolving the procedure on the basis of the type of the reference (because that's hard coded), so don't use type bound procedure syntax.
Another solution in some cases is to split the type hierarchy further, so that the abstract type tBody has a non-abstract parent that hosts the initial implementation of the "not deferred" procedures.