标签: fortran90

Fortran 2003绑定到C中的库:如何翻译枚举和#defines?

我正在为C库编写Fortran绑定.

使用枚举翻译定义的常量(在库头中)的最佳实践是什么,例如

typedef enum cufftType_t {
  CUFFT_R2C = 0x2a,     // Real to Complex (interleaved)
  CUFFT_C2R = 0x2c,     // Complex (interleaved) to Real
  CUFFT_C2C = 0x29,     // Complex to Complex, interleaved
  CUFFT_D2Z = 0x6a,     // Double to Double-Complex
  CUFFT_Z2D = 0x6c,     // Double-Complex to Double
  CUFFT_Z2Z = 0x69      // Double-Complex to Double-Complex
} cufftType;
Run Code Online (Sandbox Code Playgroud)

以及如何使用翻译常数#define,例如

#define CUFFT_FORWARD -1 // Forward FFT
#define CUFFT_INVERSE  1 // Inverse FFT
Run Code Online (Sandbox Code Playgroud)

或这些的组合

typedef enum cufftCompatibility_t {
    CUFFT_COMPATIBILITY_NATIVE          = 0x00, …
Run Code Online (Sandbox Code Playgroud)

c fortran fortran90

5
推荐指数
1
解决办法
906
查看次数

来自 Fortran 的回调 Python

现在我正在使用f2pyFortran 代码调用 Python 函数。我尝试了一个非常简单的例子,但没有成功。

Fortran90代码:

subroutine foo(fun,r)
external fun
integer ( kind = 4 ) i
real ( kind = 8 ) r
r=0.0D+00
do i= 1,5
    r=r+fun(i)
enddo
end
Run Code Online (Sandbox Code Playgroud)

使用命令行:

f2py -c -m 回调callback.f90

Python代码:

import callback

def f(i):
    return i * i
print callback.foo(f)
Run Code Online (Sandbox Code Playgroud)

错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: `Required argument 'r' (pos 2) not found`
Run Code Online (Sandbox Code Playgroud)

python callback fortran90 f2py

5
推荐指数
1
解决办法
684
查看次数

在`function`语句中定义结果数据类型

好吧,我先说一下我为什么要这样做.我经常用C/C++编写代码,所以对我来说定义函数非常自然:

vector<int> TestFunct (int a, int b){
<some code here>

return <result>;}
Run Code Online (Sandbox Code Playgroud)

现在我正在学习Fortran,所以我声明这样的函数:

function TestFunc(a,b)
        integer, dimension(:)    :: TestFunc
        integer                  :: a
        integer                  :: b
        <some code here>
endfunction TestFunc
Run Code Online (Sandbox Code Playgroud)

但我最近了解到结果的数据类型可以在函数语句中定义,例如:<data_type> function TestFunc(a,b),这对我来说更自然,因为我习惯了类似的C++声明.

问题是,当我'尝试定义一个向量(实际上是一个integer, dimension(:)严格说话)作为结果数据类型时,我有ifort错误#5082(我将在下一行详述).

在一个例子中,对于代码:

real, dimension(:) function TestFunc(a,b)
         integer, intent(in)    :: a
         integer, intent(in)    :: b

         <more code here>

endfunction Testfunc
Run Code Online (Sandbox Code Playgroud)

我得到输出:

main.f90(23): error #5082: Syntax error, found ',' when expecting one of: ( * ) ( :: %FILL , …
Run Code Online (Sandbox Code Playgroud)

fortran function variable-declaration fortran90 intel-fortran

5
推荐指数
1
解决办法
953
查看次数

Fortran 中用户定义的运算符

我有一个关于在 Fortran 中编写用户定义运算符的正确方法的问题。更具体地说,我将提供我的问题的示例。我正在致力于为称为“粒子”的球形粒子创建用户定义的数据类型。我想定义一个运算符,它采用现有的 Particle 对象数组并向其中添加一个新的 Particle 对象。我想知道如何定义用户定义的运算符来执行这样的操作。

目前,在 Particle 的类型定义中,我有以下几行:

procedure, public:: addNewParticleTo
generic:: operator(.spawn.) => addNewParticleTo
Run Code Online (Sandbox Code Playgroud)

接下来,我有一个定义如下的子例程:

subroutine addNewParticleTo(a_LHS, a_RHS)
  implicit none
  class(Particle), dimension(:), allocatable, intent(in):: a_LHS
  class(Particle), dimension(:), allocatable, intent(inout):: a_RHS
  <rest of the code>
end subroutine addNewParticleTo
Run Code Online (Sandbox Code Playgroud)

我打算将运算符调用为:

particle .spawn. particleArray
Run Code Online (Sandbox Code Playgroud)

我想知道这是否是执行此操作的正确方法。对此的任何建议或建议都会非常有帮助。

fortran user-defined-functions user-defined-types fortran90 fortran95

5
推荐指数
1
解决办法
1582
查看次数

fortran:尝试制作最小的堆栈数据结构

关于 SO 上的堆栈的问题,终于!我的一生都让我走到了这一步。

所以我需要将我制作的一些相当大的自定义数据结构合并到一个堆栈中。我决定编写一个仅包含一个整数值的最小堆栈结构。这里是 -

MODULE STACK_MODULE
 IMPLICIT NONE

 TYPE ELEMENT_TYPE
  INTEGER(4) :: VAL
  TYPE(ELEMENT_TYPE), POINTER :: PREV
 END TYPE ELEMENT_TYPE

 TYPE STACK_TYPE
  INTEGER(4) :: SIZE=0
  TYPE(ELEMENT_TYPE), POINTER :: LASTIN
 END TYPE STACK_TYPE

 CONTAINS
  SUBROUTINE PUSH(VAL_,STACK)
   IMPLICIT NONE
   INTEGER(4), INTENT(IN) :: VAL_
   TYPE(STACK_TYPE), INTENT(INOUT) :: STACK
   TYPE(ELEMENT_TYPE),TARGET       :: CURRENT
   ! INIT CURRENT
   CURRENT%VAL = VAL_
   CURRENT%PREV => STACK%LASTIN
   ! ADD CURRENT TO STACK
   STACK%LASTIN => CURRENT
   STACK%SIZE = STACK%SIZE+1
   RETURN
  END SUBROUTINE PUSH

  SUBROUTINE POP(STACK,VAL_)
   IMPLICIT NONE
   TYPE(STACK_TYPE), INTENT(INOUT) :: …
Run Code Online (Sandbox Code Playgroud)

stack fortran fortran90 fortran95 fortran2003

5
推荐指数
1
解决办法
707
查看次数

读取未知形状的多维数组

我想从文件中获取数据,该文件的数据内容可以具有可变大小。然而,结构非常简单。3 列和未定义的行数。我认为使用可分配的多维数组和显式 DO 循环可以解决我的问题。到目前为止,这是我的代码

program arraycall
    implicit none

    integer, dimension(:,:), allocatable :: array
    integer :: max_rows, max_cols, row, col

    allocate(array(row,col))

    open(10, file='boundary.txt', access='sequential', status='old', FORM='FORMATTED')

     DO row = 1, max_rows
       DO col = 1, max_cols
            READ (10,*) array (row, col)
       END DO
     END DO

     print *, array (row,col)

     deallocate(array)

 end program arraycall 
Run Code Online (Sandbox Code Playgroud)

现在我面临的问题是我不知道应该如何定义这些 max_rows 和 max_cols ,这与它的大小未知的事实产生共鸣。

示例文件可能看起来像

11 12 13

21 22 23

31 32 33

41 42 43
Run Code Online (Sandbox Code Playgroud)

所以我想出了一种动态(动态)估计文件记录长度的方法。更新一下,方便以后给其他人参考

!---------------------------------------------------------------------
! Estimate the number of records in the …
Run Code Online (Sandbox Code Playgroud)

arrays fortran dynamic-arrays fortran90

5
推荐指数
1
解决办法
3503
查看次数

Fortran 90声明可分配数组的差异

两者之间有区别吗?

integer, intent(in) :: n
integer, dimension(:), allocatable :: a
allocate(a(n))
Run Code Online (Sandbox Code Playgroud)

integer, intent(in) :: n
integer, dimension(n) :: a
Run Code Online (Sandbox Code Playgroud)

在哪种情况下我们会使用第一个版本?也许我误解了可分配的数组,第二个版本甚至是可分配的数组?

arrays fortran memory-management gfortran fortran90

5
推荐指数
1
解决办法
402
查看次数

如何在 Fortran 90 中向动态数组添加新元素

当我最初无法预测数组的确切大小时,我需要在 Fortran 90 中使用动态数组。所以我编写了一段代码,每次将新元素添加到数组末尾时,该代码都应该扩展可分配数组:

  subroutine DArray()

  double precision, dimension(:), allocatable :: list

  allocate(list(1))

  list(1) = 1.1

  call AddToList(list, 2.2)
  call AddToList(list, 3.2)
  call AddToList(list, 4.2)
  call AddToList(list, 5.2)

  print *, list(1)
  print *, list(2)
  print *, list(3)
  print *, list(4)
  print *, list(5)


  end



  subroutine AddToList(list, element)

  double precision :: element
  double precision, dimension(:), allocatable :: list
  double precision, dimension(:), allocatable :: clist

  if(allocated(list)) then
    isize = size(list)
    allocate(clist(isize+1))
    do i=1,isize
        clist(i) = list(i)
    end do
    clist(i+1) = element

    deallocate(list) …
Run Code Online (Sandbox Code Playgroud)

fortran dynamic-arrays fortran90 intel-fortran

5
推荐指数
1
解决办法
2万
查看次数

Fortran 中的并行读取能否提高性能?

我有一个 fortran90 代码,(到目前为止)大部分时间都花在 I/O 上,因为需要读取非常大的数据文件(至少 1GB 及以上)。需要写入包含计算结果的较小但仍然很大的数据文件。相比之下,一些快速傅里叶变换和其他计算很快就能完成。我已经并行化 (OpenMP) 其中一些计算,但考虑到上述 I/O 问题,总体性能增益很小。

我目前的策略是立即读取整个文件:

open(unit=10, file="data", status="old")

do i=1,verylargenumber
  read(10,*) var1(i), var2(i), var3(i)
end do

close(10)
Run Code Online (Sandbox Code Playgroud)

然后执行操作var1等。我的问题是是否有一个合适的策略使用(最好是)OpenMP 来加速读取过程,特别是考虑到数据文件(如果有任何区别)都很大。

我可以在 Lustre 文件系统上运行这些计算,原则上这为并行 I/O 提供了优势,尽管常规文件系统的通用解决方案将受到赞赏。

我的直觉是这个问题没有解决办法,但我想确认一下。

parallel-processing fortran openmp fortran90 lustre

5
推荐指数
1
解决办法
913
查看次数

Fortran 嵌套 WHERE 语句

我有一个带有嵌套 WHERE 语句的 Fortran 90 源代码。有一个问题,但似乎很难理解到底发生了什么。我想把它转换成DO-IF结构以便调试。我不清楚的是如何翻译嵌套的 WHERE。

所有数组都具有相同的大小。

WHERE (arrayA(:) > 0)
    diff_frac(:) = 1.5 * arrayA(:)
    WHERE (diff_frac(:) > 2)
        arrayC(:) = arrayC(:) + diff_frac(:)
    ENDWHERE
ENDWHERE
Run Code Online (Sandbox Code Playgroud)

我的选项A:

DO i=1, SIZE(arrayA)
  IF (arrayA(i) > 0) THEN
    diff_frac(i) = 1.5 * arrayA(i)
    DO j=1, SIZE(diff_frac)
      IF (diff_frac(j) > 2) THEN
          arrayC(j) = arrayC(j) + diff_frac(j)
      ENDIF
    ENDDO
  ENDIF
ENDDO
Run Code Online (Sandbox Code Playgroud)

我的选项B:

DO i=1, SIZE(arrayA)
  IF (arrayA(i) > 0) THEN
    diff_frac(i) = 1.5 * arrayA(i)        
    IF (diff_frac(i) > 2) THEN
        arrayC(i) = …
Run Code Online (Sandbox Code Playgroud)

fortran nested where fortran90

5
推荐指数
1
解决办法
6292
查看次数