Я пишу n-мерный численный решатель в Fortran. Я создал модуль для того же самого, который вызывается из основной программы. Я использовал external
для вызова неизвестной функции, когда писал для ода первого порядка. Однако на тиражирование результат более чем в одном измерении с помощью external
я получаю следующую ошибкуИспользование внешней функции в модуле
Error: EXTERNAL attribute conflicts with DIMENSION attribute in 'f_x'
Это означает, что мой компилятор не может обрабатывать внешнюю функцию с выходом массива.
Я попытался с помощью блока интерфейса предопределить параметры функции с фиксированными размерами и я в конечном итоге с этой ошибкой
Error: PROCEDURE attribute conflicts with INTENT attribute in 'f_x'
Есть ли способ в Fortran иметь внешнюю функцию, возвращающую массив инициализируется с помощью фиктивная функция в подпрограмме.
Вот код, который я использовал.
module int_adaptive
implicit none
contains
subroutine RK4nd(f_x, norder, nvar, x_0, t_0, t_f, x_out, t_out)
INTERFACE
FUNCTION f_x (x_0, t_0)
integer, parameter :: dp=kind(0.d0)
REAL(dp), INTENT(IN) :: x_0(2, 3), t_0
REAL, intent(out) :: f_x(2,3)
END FUNCTION f_x
END INTERFACE
integer, parameter :: dp=kind(0.d0)
integer :: norder, i, nvar
external :: f_x
real(dp), intent(in):: x_0(norder, nvar), t_0, t_f
real(dp) :: x_out(norder, nvar), t_out, k1(norder, nvar), y1(norder, nvar), y(norder, nvar)
real(dp) :: k2(norder, nvar), k3(norder, nvar), k4(norder, nvar),&
y2(norder, nvar), y3(norder, nvar), y4(norder, nvar)!, f_x(norder, nvar)
real(dp) :: h_min, h_0, h_max, tol, err_est, h, t
if (h_0<h) then
h = h_0
end if
if ((t_f - t_0) < 0.0) then
h = -h
end if
t = t_0
y = x_0
do while (t .NE. t_f)
k1 = f_x(y, t)
y1 = y + k1*h/2.0
k2 = f_x(y1, t+h/2.0)
y2 = y + k2*h/2.0
k3 = f_x(y2, t+h/2.0)
y3 = y + k3*h
k4 = f_x(y3, t+h)
y4 = y + (k1+ 2*k2 + 2*k3 +k4)*h/6.0
t = t + h
y = y4
end do
x_out = y
t_out = t
end subroutine
end module
Я мог бы определить стандартный интегратор с входом фиксированной функции внутри модуля и назвать его по имени непосредственно, но так как я имею дело с ОДУ различных заказов будет сложно каждый раз, когда я меняю заказ я необходимо также обновить этот модуль.
У меня есть смысл удалить внешний блок, но это была цель, которая сделала трюк. Ошибка компилятора. Необходимо проверить его. Большое спасибо – Astroynamicist