Fortran 90:如何在函数中使用模块

发布于 2024-10-10 15:39:52 字数 947 浏览 1 评论 0原文

我正在尝试编写一个使用格林函数来求解热方程的 Fortran 程序。我使用 Fortran 90 而不是 77,部分原因是我的印象是它几乎是 Fortran 77 的复制品,但添加了一些非常有用的功能。尽管主要原因是自由形式编码。我在名为“useful”的模块中有一些“有用”的常量和变量。我想在我的大多数程序、子例程、函数等中包含这些变量和常量。我正在学习 fortran。我用 perl、C++、java、matlab 和 mathematica 进行过编程。我发现这非常困难。我不明白程序和子程序之间的区别。我绝对不清楚模块是什么。我花了过去 12 个小时研究这些术语,但尚未得到简明的区别和定义。我得到了各种各样的示例,展示了如何声明这些东西,但实际上很少描述它们的用途。

我真的很感谢解释为什么我的函数“x”无法“使用”我的“有用”模块。

此外,澄清前面提到的 Fortran 功能也非常有帮助。

module useful

  integer, parameter :: N=2
  double precision, parameter :: xmin=1, xmax=10, pi=3.1415926535898
  double complex :: green(N,N), solution(N), k=(2.0,0.0)

end module useful

program main

  use useful

  !real*8 :: delta = 2**-7
  do n1 = 1, N
    do n2 = 1, N
      green(n1,n2) = exp((0,1)*k*abs(x(n2)-x(n1)))/(4*pi*abs(x(n2)-x(n1)))
      print *, x(n2)
    end do 
  end do

end program main

function x(n1)

  use useful

  real :: n1, x
  x=n1*(xmax-xmin)/N

end function x

I am trying to write a fortran program that uses green's functions to solve the heat equation. I am useing fortran 90 as opposed to 77 in part because I am under the impression that it is pretty much a replica of fortran 77 but with a few very helpful features thrown in. Though the main reason is for free form coding. I have some "useful" constants and variables in a module named "useful." I want to include those variables and constants in most of my programs, subroutines, functions, etc. I am just learning fortran. I have programed in perl, C++, java, matlab, and mathematica. I am finding it very difficult. I do not understand the difference between a program and a subroutine. I definitely have no clear idea of what a module is. I have spent the past 12 hours researching these terms and have yet to get concise distinctions and definitions. I get an assortment of samples that show how to declare these things, but very little that actually delineates what they are supposed to be used for.

I would really appreciate an explanation as to why my function, "x" is not able to "use" my "useful" module.

Also, a clarification of the previously mentioned fortran features would be really helpful.

module useful

  integer, parameter :: N=2
  double precision, parameter :: xmin=1, xmax=10, pi=3.1415926535898
  double complex :: green(N,N), solution(N), k=(2.0,0.0)

end module useful

program main

  use useful

  !real*8 :: delta = 2**-7
  do n1 = 1, N
    do n2 = 1, N
      green(n1,n2) = exp((0,1)*k*abs(x(n2)-x(n1)))/(4*pi*abs(x(n2)-x(n1)))
      print *, x(n2)
    end do 
  end do

end program main

function x(n1)

  use useful

  real :: n1, x
  x=n1*(xmax-xmin)/N

end function x

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

放赐 2024-10-17 15:39:52

让我们从一些定义开始。

Fortran 程序由程序单元组成。在所谓的 Fortran 2008(当前标准)中,有五种类型的程序单元:

  • 主程序;
  • 外部子程序;
  • 模块;
  • 子模块;
  • 块数据程序单元。

让我将您的注意力集中在前三个上。

主程序
正如标准声称的那样

不是子程序的程序单元,
模块、子模块或块数据
程序单元。

不是很有用的定义。 =) 你应该知道的是,主程序单元以关键字PROGRAM开头,它是应用程序的入口点,显然一个程序应该由一个主程序组成。

程序还可以由任意数量(包括零)的其他类型的程序单元组成。

外部子程序
子程序定义过程。有两种类型的程序,当然还有两种类型的子程序来定义它们:

  • 定义函数的函数子程序;
  • 子程序 子程序来定义子程序。

函数子程序是以 FUNCTION 语句作为其第一条语句的子程序。
子例程子程序是以 SUBROUTINE 语句作为其第一条语句的子程序。

此外,过程和子程序在程序中的出现位置也有所不同。您可以使用:

  • 外部子程序来定义外部过程;
  • 定义内部程序的内部子程序;
  • 模块子程序来定义模块过程。

外部子程序
子程序不包含在
主程序、模块、子模块或
另一个子程序

内部子程序
包含在主程序中的子程序或
另一个子程序

模块子程序
包含在模块或子模块中的子程序
但不是内部子程序

模块
它只是一个定义(类型定义、过程定义等)容器。

现在是小例子。

main.f90

! Main program unit.
PROGRAM main

  USE foo

  IMPLICIT NONE

  CALL external_bar
  CALL internal_bar
  CALL module_bar

  CONTAINS

    ! Internal subprogram defines internal procedure.
    SUBROUTINE internal_bar
      PRINT *, "inside internal procedure"
    END SUBROUTINE internal_bar

END PROGRAM main

foo.f90

! Module program unit.
MODULE foo

  IMPLICIT NONE

  CONTAINS

    ! Module subprogram defines module procedure.
    SUBROUTINE module_bar
      PRINT *, "inside module procedure"
    END SUBROUTINE module_bar

END MODULE foo

酒吧.f90

! External subprogram program unit.
! External subprogram defines external procedure.
SUBROUTINE external_bar
  PRINT *, "inside external procedure"
END SUBROUTINE external_bar

Let start with some definitions.

Fortran programs are composed of program units. In so-called Fortran 2008 (current standard) there are five types of program units:

  • main program;
  • external subprogram;
  • module;
  • submodule;
  • block data program unit.

Let me concentrate your attention on the first three.

Main program
As standard claims it is

program unit that is not a subprogram,
module, submodule, or block data
program unit.

Not very useful definition. =) What you should know is that main program unit starts with keyword PROGRAM, it is the entry point of application and obviously a program shall consist of exactly one main program.

A program may also consist any number (including zero) of other kinds of program units.

External subprogram
A subprogram defines a procedure. There are two types of procedures and of course two types of subprograms to define them:

  • function subprograms to define functions;
  • subroutine subprograms to define subroutines.

A function subprogram is a subprogram that has a FUNCTION statement as its first statement.
A subroutine subprogram is a subprogram that has a SUBROUTINE statement as its first statement.

Also both procedures and subprograms differ in place of their appearance in program. You can use:

  • external subprograms to define external procedures;
  • internal subprograms to define internal procedures;
  • module subprograms to define module procedures.

external subprogram
subprogram that is not contained in a
main program, module, submodule, or
another subprogram

internal subprogram
subprogram that is contained in a main program or
another subprogram

module subprogram
subprogram that is contained in a module or submodule
but is not an internal subprogram

Module
It is just a definitions (type denitions, procedure denitions, etc.) container.

Now small example.

main.f90

! Main program unit.
PROGRAM main

  USE foo

  IMPLICIT NONE

  CALL external_bar
  CALL internal_bar
  CALL module_bar

  CONTAINS

    ! Internal subprogram defines internal procedure.
    SUBROUTINE internal_bar
      PRINT *, "inside internal procedure"
    END SUBROUTINE internal_bar

END PROGRAM main

foo.f90

! Module program unit.
MODULE foo

  IMPLICIT NONE

  CONTAINS

    ! Module subprogram defines module procedure.
    SUBROUTINE module_bar
      PRINT *, "inside module procedure"
    END SUBROUTINE module_bar

END MODULE foo

bar.f90

! External subprogram program unit.
! External subprogram defines external procedure.
SUBROUTINE external_bar
  PRINT *, "inside external procedure"
END SUBROUTINE external_bar
养猫人 2024-10-17 15:39:52

模块是比子例程或函数更高级别的组织。

函数“x”应该能够使用有用的模块。我认为程序“main”更有可能难以正确访问“x”。您最好将函数“x”也放入模块中的“contains”语句之后。在这种情况下,从“x”中删除“useUseful”语句。那么程序 main 就会对接口有充分的了解……在 Fortran 命名法中,接口是显式的。这确保了参数传递的一致性。

如果您显示编译器的错误消息,将会有所帮助。

Fortran 95/2003 比 FORTRAN 77 更强大,具有一些额外的有用功能。变化要大得多。尝试从网络上学习它并不是一个好主意。我建议您找到 Metcalf、Reid 和 Cohen 所著的《Fortran 95/2003 Expanded》一书。

A module is a higher level of organization than a subroutine or function.

Function "x" should be able to use the module useful. I think it more likely that program "main" is having difficulty correctly accessing "x". You would do better to also place function "x" into the module after a "contains" statement. In this case remove the "use useful" statement from "x". Then the program main would have full knowledge of the interface ... in Fortran nomenclature, the interface is explicit. This ensures that the passing of arguments is consistent.

It would help if you showed the error messages from the compiler.

Fortran 95/2003 is much more than FORTRAN 77 with a few extra useful features. The changes are much larger. Trying to learn it from the web is not a good idea. I suggest that you find a copy of the book "Fortran 95/2003 Explained" by Metcalf, Reid and Cohen.

云淡风轻 2024-10-17 15:39:52

我发现你的程序有两个问题。

  1. 主子程序不知道 x() 是什么。是实数函数、整数函数等吗?您可以将以下内容添加到主程序中
    真实的、外部的:: x
    或者(正如其他人建议的那样)将函数 X() 移到您的模块中。
    为此,请在模块末尾附近添加“包含”语句,然后
    将函数放在“contains”和“end module”之间。

  2. 您的参数不匹配。在主程序中,N1 被显式声明为实数变量。在函数 X() 中,N1 被声明为实数。您需要解决这个问题。

我强烈建议您在主程序中添加“隐式无”语句,
模块和功能。这将迫使您隐式键入每个变量和函数。

I see two problems in your program.

  1. The main subroutine doesn't know what x() is. Is it a real function, integer function, etc.? You can either add the following to your main program
    real, external :: x
    Or (as others suggested) move function X() into your module.
    To do this, add a "contains" statement near the end of the module and
    put the function between the "contains" and the "end module".

  2. You have an argument mismatch. In the main program, N1 is explicitly declared as a real variable. In function X(), N1 is declared as a real. You need to fix this.

I would strongly suggest that you add "implicit none" statements to your main program,
module, and function. This will force you to implicitly type each variable and function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文