问题
I'm developing a Fortran program for scientific computing. I want to use procedure pointers to assign the boundary conditions in the problem, shown in the following main program
program main
use boundary
implicit none
bc1 => boundaryA
bc2 => boundaryB
bc3 => boundaryC
call comp_boundary
end program
I define all the boundary operations "boundaryA/B/C" in a "boundary" module
module boundary
implicit none
procedure(boundary_type), pointer :: bc1,bc2,bc3
abstract interface
subroutine boundary_type(i)
integer :: i
end subroutine
end interface
contains
subroutine boundaryA(i)
integer :: i
print*, 'Boundary A at ',i
end subroutine
subroutine boundaryB(i)
integer :: i
print*, 'Boundary B at ',i
end subroutine
subroutine boundaryC(i)
integer :: i
print*, 'Boundary C at',i
end subroutine
subroutine comp_boundary
call bc1(1)
call bc2(2)
call bc3(3)
end subroutine
end module
This works well.
But my question is that if, say, boundaryC
has not one input argument, but two, then my definition for the abstract interface boundary_type
doesn't work now.
Is that possible to use the procedure pointer to deal with this case? Or any other way around?
回答1:
You could achieve this with an OPTIONAL
argument. This is more an academic solution as there is always conservation of misery. As the comment of High Performance Mark states, your decision to use one or two arguments will need to be made somewhere.
Nonetheless, the OPTIONAL
argument would require to add this too all subroutines and could therefore be not really the solution you request as all subroutines are essentially changed. It is essentially the same solution you gave, with just different set of procedure arguments.
MODULE boundary
IMPLICIT NONE
PROCEDURE(boundary_type), POINTER :: bc1,bc2
ABSTRACT INTERFACE
SUBROUTINE boundary_type(i,j)
INTEGER :: i
INTEGER, OPTIONAL :: j
END SUBROUTINE boundary_type
END INTERFACE
CONTAINS
SUBROUTINE boundaryA(i,j)
INTEGER :: i
INTEGER, OPTIONAL :: j
PRINT *, 'Boundary A at ',i
END SUBROUTINE boundaryA
SUBROUTINE boundaryB(i,j)
INTEGER :: i
INTEGER, OPTIONAL :: j
PRINT *, 'Boundary B at ',i,j
END SUBROUTINE boundaryB
SUBROUTINE comp_boundary
CALL bc1(1)
CALL bc2(2,3)
END SUBROUTINE comp_boundary
END MODULE boundary
Note: the subroutine boundaryB
must always be called with both arguments as no check is done for the availability of j
(using PRESENT
)
来源:https://stackoverflow.com/questions/48296424/how-to-use-procedure-pointers-for-subroutines-with-different-number-of-arguments