Fortran: реализация подпрограммы, которая принимает другую подпрограмму в качестве аргумента в Fortran 90/95.

Я хотел бы написать подпрограмму Fortran, которая принимает имя другой подпрограммы в качестве аргумента - представьте, что первая подпрограмма является решателем PDE, а вторая обеспечивает правую часть PDE. Обратите внимание, что вторая подпрограмма может быть реализована другими, и поэтому мы можем ничего не знать о ней, кроме ее подписи.

Это возможно с использованием абстрактных интерфейсов и операторов процедуры. См., Например, https://github.com/jacobwilliams/PowellOpt/blob/master/src/newuoa.f90

Конечно, это также можно сделать с помощью внешних функций: http://malayamaarutham.blogspot.com/2006/02/passing-function-names-as-arguments-in.html

Однако абстрактные интерфейсы и операторы процедур доступны только после Fortran 2003, а внешние функции нежелательны. А вот и мой первый вопрос:

Можно ли передать имя подпрограммы в качестве аргумента в Fortran 90/95 без использования абстрактных интерфейсов и операторов процедур или внешних функций?

Вначале ответ показался мне отрицательным, потому что я видел это обсуждение: http://computer-programming-forum.com/49-fortran/dba58f497a8dc996.htm

К счастью, после дополнительных исследований я обнаружил, что это возможно через обычный интерфейс (не абстрактный), согласно таким источникам, как Fortran | Передача функций в качестве аргументов других функций, как передать имена подпрограмм в качестве аргументов в Fortran?, https://www.tek-tips.com/viewthread.cfm?qid=1572869.

Я реализовал следующий фрагмент кода в качестве минимального рабочего примера. Мой второй вопрос:

Соответствует ли следующий фрагмент кода Fortran 90/95?

Я пробовал скомпилировать код с помощью gfortran, ifort и g95. Первые два компилятора были довольны, но g95 выдвинул предупреждение, что

use fun_mod, only : fun
                    1
Warning (102): MODULE PROCEDURE 'fun' USEd at (1) is not referenced

когда я казнил

g95 -Wall -Wextra -std=f95 -pedantic main.f90

Полученный исполняемый файл работал без проблем, но почему это предупреждение? Это глюк g95? Если нет, то как избавиться от этого предупреждения? Любые другие комментарии / критика кода также будут высоко оценены.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
module proc_mod 
! PROC_MOD provides a subroutine PROC(X, Y, F) that invokes a subroutine
! F at (X, Y) and then increment Y by 1.

implicit none
private 
public :: proc


contains


subroutine proc(x, y, f)

implicit none

real, intent(in) :: x(:)
real, intent(out) :: y

interface
    subroutine f(x, y)
    real, intent(in) :: x(:)
    real, intent(out) :: y
    end subroutine f
end interface

call f(x, y)
y = y + 1.0

end subroutine proc 


end module proc_mod
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
module fun_mod
! FUN_MOD provides a subroutine FUN(X, Y) that sets Y = SUM(X**2).
! In practice, this module is provided by OTHERS, and we do not
! know how it is implemented except for the signature of FUN.

implicit none
private 
public :: fun 


contains 


subroutine fun(x, y)

implicit none
real, intent(in) :: x(:)
real, intent(out)  :: y 

y = sum(x**2)

end subroutine fun


end module fun_mod
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program main 
! MAIN tests PROC(X, Y, FUN) with PROC from PROC_MOD and FUN from FUN_MOD.

use proc_mod, only : proc
use fun_mod, only : fun
implicit none

real :: x(3), y

call random_number(x)
print *, x

call proc(x, y, fun)
print *, y

print *, sum(x**2) + 1.0

end program main 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Обратите внимание, что в этом коде нам нужно написать блок интерфейса для FUN в каждой подпрограмме, которая получает FUN в качестве аргумента. Было бы утомительно, если бы у меня было много таких подпрограмм. Это мотивирует мой третий вопрос:

Можно ли обернуть интерфейс FUN в модуль и обойтись без интерфейсного блока с помощью модуля?(Я пытался, но безуспешно.)

Большое спасибо!

Изменить: как указано @Ian Bush и @francescalus, возможно, мне следует согласиться с использованием абстрактных интерфейсов и операторов процедур, проверяя, реализуют ли компиляторы пользователей такую ​​функцию F2003. Итак, вот 4-й вопрос:

Какая самая ранняя версия широко используемых компиляторов Фортрана (gfortran, ifort, nagfor, pgfortran...), реализующая абстрактный интерфейс и оператор процедуры?

Я знаю, что должен сам проверить документацию - обязательно. Я задаю этот вопрос здесь на всякий случай, если кто-то знает ответ. Позже я отредактирую вопрос, включив в него ответ на случай, если кто-то еще ищет то же самое. Спасибо.

Ответ на четвертый вопрос:

0 ответов

Другие вопросы по тегам