Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Fortran模块中定义的函数打印到标准输出_Fortran - Fatal编程技术网

从Fortran模块中定义的函数打印到标准输出

从Fortran模块中定义的函数打印到标准输出,fortran,Fortran,我正在努力学习Fortran(不幸的是,这是我的研究小组的一项必要任务)——我给自己设定的任务之一是将数字配方书中的一个必要函数(相关的勒让德多项式)打包成符合Fortran 03的模块。原始程序(f77)具有以下形式的一些错误处理: if(m.lt.0.or.m.gt.1.or.abs(x).gt.1)pause 'bad arguments in plgndr' 自f77以来,Pause似乎已被弃用,因为使用此行会导致编译错误,因此我尝试了以下方法: module sha_helper

我正在努力学习Fortran(不幸的是,这是我的研究小组的一项必要任务)——我给自己设定的任务之一是将数字配方书中的一个必要函数(相关的勒让德多项式)打包成符合Fortran 03的模块。原始程序(f77)具有以下形式的一些错误处理:

if(m.lt.0.or.m.gt.1.or.abs(x).gt.1)pause 'bad arguments in plgndr'
自f77以来,Pause似乎已被弃用,因为使用此行会导致编译错误,因此我尝试了以下方法:

module sha_helper
    implicit none
    public :: plgndr, factorial!, ylm

contains
    ! numerical recipes Associated Legendre Polynomials rewritten for f03
    function plgndr(l,m,x) result(res_plgndr)
        integer, intent(in) :: l, m
        real, intent(in) :: x
        real :: res_plgndr, fact, pll, pmm, pmmp1, somx2
        integer ::  i,ll
        if (m.lt.0.or.m.gt.l.or.abs(x).gt.1) then 
            write (*, *) "bad arguments to plgndr, aborting", m, x
            res_plgndr=-10e6 !return a ridiculous value
        else
            pmm = 1.
            if (m.gt.0) then
                somx2 = sqrt((1.-x)*(1.+x))
                fact = 1.
                do i = 1, m
                    pmm = -pmm*fact*somx2
                    fact = fact+2
                end do
            end if
            if (l.eq.m) then
                res_plgndr = pmm
            else
                pmmp1 = x*(2*m+1)*pmm
                if(l.eq.m+1) then
                    res_plgndr = pmmp1
                else
                    do ll = m+2, l
                        pll = (x*(2*ll-1)*pmmp1-(ll+m-1)*pmm)/(ll-m)
                        pmm = pmmp1
                        pmmp1 = pll
                    end do
                    res_plgndr = pll
                end if
            end if
        end if
    end function plgndr

    recursive function factorial(n) result(factorial_result)
        integer, intent(in) :: n
        integer, parameter :: RegInt_K = selected_int_kind(20) !should be enough for the factorials I am using
        integer (kind = RegInt_K) :: factorial_result
        if (n <= 0) then
            factorial_result = 1
        else 
            factorial_result = n * factorial(n-1)
        end if 
    end function factorial

!     function ylm(l,m,theta,phi) result(res_ylm)
!         integer, intent(in) :: l, m
!         real, intent(in) :: theta, phi
!         real :: res_ylm, front_block
!         real, parameter :: pi = 3.1415926536
!         front_block = sqrt((2*l+1)*factorial(l-abs(m))/(4*pi*))
!     end function ylm

end module sha_helper
尝试:


您的程序执行所谓的递归IO-对
plgndr
的初始调用位于IO语句(打印语句)[将输出定向到控制台]的输出项列表中-在该函数中,您还尝试执行另一个IO语句[输出到控制台]。这是不允许的-参见F2003的9.11p2和p3或F2008的9.12p2

解决方案是将函数调用与主程序中的io语句分离,即

REAL :: a_temporary
...
a_temporary = plgndr(1,2,0.1)
PRINT *, a_temporary
F2008中的其他替代方案(但不是F2003-因此第一段中的[]部分)包括将函数的输出定向到不同的逻辑单元(注意,
WRITE(*、…
PRINT…
引用相同的单元)

在F2008中,您还可以将WRITE语句替换为带有消息的STOP语句(消息必须是常量,这样您就不会报告有问题的值)


某些编程风格不鼓励在函数中执行IO的部分原因是可能会无意中调用递归IO。

请编辑您的问题,以包含完整的代码。所包含的程序片段中显然没有错误。因此,这可能是由于程序的其他部分中的某些内容造成的。谢谢--在这种情况下,NE是为了避免函数中的IO,在主代码中有一种错误检查的好方法吗?我猜你可以在函数的范围之外选择一个返回值并检查它。h一个单独的错误标志参数或类似参数。如果它仍然是一个函数(即,我希望它在更复杂的表达式中作为主函数引用),那么我也希望我的函数是纯函数-这目前排除了使用[error]STOP或doing IO(尽管在未来的标准中可能会取消对错误停止的限制)。如果支持,则使用
IEEE\u值(x,IEEE\u QUIET\u NAN)
作为良好的“无效”值,因为在随后使用时,该值会敏感地传播。
if (m.lt.0.or.m.gt.l.or.abs(x).gt.1) then
   write (*, *) "bad arguments to plgndr, aborting", m, x
   stop
else
   ...
end if
REAL :: a_temporary
...
a_temporary = plgndr(1,2,0.1)
PRINT *, a_temporary