标签: fortran2003

使用Python包装Modern Fortran代码的当前最佳方法

我知道,并使用f2py2e来包装一些旧的Fortran 77代码,但我的理解是它不适用于较新的Fortran 95代码.我已经研究了我应该使用的东西,并且遇到了fwrapG3 f2py,它们似乎都没有给出它们当前状态的任何解释,或者如何使用它们.我已经看到f2py的版本可以选择使用第三代f2py,但它被评为不起作用.鉴于此,我不知道应该使用哪个项目.我应该使用哪一个?

这个问题现已交叉发布到Computational Science堆栈交换站点(并在其中回答),我应该使用哪个包来用Python包装Modern Fortran Code?

python fortran numpy fortran95 fortran2003

14
推荐指数
1
解决办法
4806
查看次数

Fortran派生类型赋值

假设我有一个Fortran派生类型

type :: atype
    integer :: n
    integer :: a(10)
    integer, allocatable :: b(:)
 end type
Run Code Online (Sandbox Code Playgroud)

我有两个这种类型的实例

type(atype) :: t1, t2
Run Code Online (Sandbox Code Playgroud)

当我做以下任务时到底发生了什么?

t2 = t1
Run Code Online (Sandbox Code Playgroud)

我对此感兴趣,因为我想正确地创建派生类型变量的副本意味着,标量组件应该相等,数组组件的每个元素应该相等,并且可分配的数组应该具有相同的分配大小,并且元素应该相等.目前我只想写一个子程序,它正确地复制和分配组件.

subroutine copy_atype(from, to)
    type(atype) :: from, to
    to%n = from%n
    to%a = from%a
    if (allocated(to%b)) deallocate(to%b)
    if (allocated(from%b) then
        allocate(to%b(size(from%b)))
        to%b = from%b
    end if
end subroutine
Run Code Online (Sandbox Code Playgroud)

我希望指导标准中的相应部分.

我正在使用gfortran 4.7.

fortran gfortran fortran2003

14
推荐指数
1
解决办法
3414
查看次数

Heaviside函数的优化实现

我想(超)优化Heaviside函数的实现.

我正在研究一种速度特别重要的数值算法(在Fortran中).它多次使用Heaviside函数,目前由signum内部函数实现如下:

heaviside = 0.5*sign(1,x)+1
Run Code Online (Sandbox Code Playgroud)

我主要感兴趣的是x是intel处理器上的双精度实数.

是否有可能开发更高效的Heaviside功能实现?也许使用汇编语言,超优化代码或调用现有的外部库?

optimization assembly fortran intel fortran2003

10
推荐指数
1
解决办法
3374
查看次数

2003年fortran中类型和类别之间的差异

我被告知我的博士学位,我必须学习fortran 2003语言.我以前从未使用过OOP程序,也没有使用过fortran程序.我试图了解类型和类之间的区别.我知道类是使用'TYPE'关键字声明的,但我也看到了使用关键字'CLASS'的例子,所以我感到困惑.希望有道理.

fortran fortran2003

10
推荐指数
1
解决办法
2922
查看次数

从C库头自动生成Fortran 2003绑定(使用iso_c_bindings内部模块)

有没有使用Fortran 2003标准的内部模块从C库头自动生成Fortan 绑定的工具iso_c_bindings

我对 C 转换为Fortran 不感兴趣,但只生成绑定.

c binding fortran fortran2003 fortran-iso-c-binding

8
推荐指数
1
解决办法
706
查看次数

将 Fortran 整数值分配给 malloc 分配的 C 内存目标

假设您创建了一个 Fortran array(:),其中包含指向在 C 中分配的内存的指针malloc(如最佳答案所示,下面重复了代码)。有没有办法使用 Fortran 数组(即 iso_c_bindings)将整数值写入这个分配的内存中?或者我必须在 C 中做到这一点?

#include "stdlib.h"
int *create_storage()
{
   /* Array of four integers. */
   return malloc(sizeof(int) * 4);
}

void destroy_storage(int *ptr)
{
   free(ptr);
}


PROGRAM fortran_side
  USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_F_POINTER, C_INT
  IMPLICIT NONE
  INTERFACE
    FUNCTION create_storage() BIND(C, NAME='create_storage')
      USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
      IMPLICIT NONE
      TYPE(C_PTR) :: create_storage
    END FUNCTION create_storage
    SUBROUTINE destroy_storage(p) BIND(C, NAME='destroy_storage')
      USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
      IMPLICIT NONE …
Run Code Online (Sandbox Code Playgroud)

c fortran fortran2003 fortran-iso-c-binding

8
推荐指数
1
解决办法
99
查看次数

具有重载赋值的嵌套派生类型

我有一个wrapper包含其他派生类型(over)的派生类型().对于后者,赋值运算符已经过载.由于派生类型的赋值按默认的组件方式发生,我希望分配两个实例wrapperover在某个时刻调用重载的赋值.但是,使用下面的程序似乎并非如此.仅当我还重载用于在实例之间wrapper包含显式赋值的赋值时over(通过取消注释注释的代码行),才会调用重载的赋值.为什么?我发现它有点违反直觉.有没有办法避免包装类型的过载?

module test_module
  implicit none

  type :: over
    integer :: ii = 0
  end type over

  type :: wrapper
    type(over) :: myover
  end type wrapper

  interface assignment(=)
    module procedure over_assign
    !module procedure wrapper_assign
  end interface assignment(=)

contains

  subroutine over_assign(other, self)
    type(over), intent(out) :: other
    type(over), intent(in) :: self

    print *, "Assignment of over called"
    other%ii = -1

  end subroutine over_assign

  !subroutine wrapper_assign(other, self)
  !  type(wrapper), intent(out) …
Run Code Online (Sandbox Code Playgroud)

fortran fortran95 fortran2003

7
推荐指数
1
解决办法
1363
查看次数

Fortran 的“最终”子程序在实际使用中是否足够可靠?

现代 Fortran 包含各种面向对象的思想,包括通过FINAL关键字“析构函数”的概念。

MODULE mobject
  TYPE :: tobject
    ! Data declarations
  CONTAINS
    FINAL :: finalize
  END TYPE
CONTAINS
  SUBROUTINE finalize(object)
    TYPE(tobject) object
    ...
  END SUBROUTINE
END MODULE
Run Code Online (Sandbox Code Playgroud)

然而,这个功能可靠吗?值得注意的是,我注意到有关何时以及是否会调用它的不一致,英特尔 Fortran 19 和 GFortan 7、8 之间存在主要差异:

  • GFortran 无法销毁存储在数组中的对象。
  • 英特尔 Fortran:
    • 在分配时执行虚假和潜在的多余破坏,甚至可能在包含垃圾数据的内存上,以及
    • 从函数返回时执行对析构函数的虚假调用。

我注意到 gfortran-7.4.0 和 gfortran-8.2.1.2 之间没有区别。

这些不一致给我带来了一些关于析构函数的实际可用性的问题。是否有任何一种行为完全符合标准?这个标准不清楚吗?标准是否可能包含导致不直观行为的条款?

详细分析(代码见下)

  • 程序块。Gfortran 不会为在 PROGRAM 块中声明的实例调用析构函数,而 Ifort 会(参见run1示例)。

  • 标量对象。对于声明为标量的实例,如果变量已经看到任何形式的初始化,Gfortran 和 IFort 都会调用析构函数。然而,英特尔 Fortran 在分配函数返回值时,也会调用它

    • 在用函数中的数据覆盖之前在堆栈上的未初始化对象上,以及
    • 似乎在newObject函数的末尾。

    然而,这可以通过在执行任何清理之前显式检查对象是否已初始化来防止。

这意味着,程序员必须明确检查实例是否已初始化。

  • 数组中的对象。如果对象包含在数组中,并且数组超出范围,

    • Gfortran 不会调用析构函数。
    • 英特尔 Fortran 可能会调用析构函数,具体取决于给定数组成员的初始化方式。
    • 数组是否声明没有区别allocatable …

fortran gfortran fortran2003 intel-fortran

7
推荐指数
1
解决办法
338
查看次数

Fortran2003:指向函数的过程指针返回指向多态类型的指针

对于一个新项目,我正在考虑使用 Fortran2003 的面向对象特性。我尝试过的一件事涉及一个过程指针,它指向一个函数(不是子例程),该函数返回一个指向多态类型的指针。我想知道这样的构造是否合法,因为我从不同的编译器得到了混合的结果(见下文)。

作为一个具体的例子,考虑以下函数接口:

abstract interface
   function if_new_test(lbls) result(t)
      import :: test_t
      class(test_t),pointer       :: t
      character(len=*),intent(in) :: lbls(:)
   end function if_new_test
end interface
Run Code Online (Sandbox Code Playgroud)

并且使用代码应该有一个过程指针,可以指向具有这个接口的函数:

procedure(if_new_test),pointer :: nt
Run Code Online (Sandbox Code Playgroud)

我在问这是否合法,因为 gfortran (4.7.2) 用消息抱怨这个过程指针声明:

错误:(1) 处的 CLASS 变量“nt”必须是虚拟的、可分配的或指针

我不明白这个错误信息,因为nt它本身是一个指针,它指向的函数返回的也是一个指针。

作为参考,示例的完整源代码如下。第一,包含我的派生类型、接口和函数/子例程的模块:

module test_m

   implicit none

   type :: test_t
      character(len=10) :: label
      contains
      procedure :: print => print_test
   end type test_t

   type,extends(test_t) :: test2_t
      character(len=10) :: label2
      contains
      procedure :: print => print_test2
   end type test2_t

   abstract interface
      function if_new_test(lbls) result(t)
         import :: …
Run Code Online (Sandbox Code Playgroud)

polymorphism fortran pointers fortran2003

6
推荐指数
1
解决办法
1223
查看次数

Fortran 中函数返回值的直接索引

是否有可能直接在函数的返回值上使用索引?像这样的东西:

readStr()(2:5)
Run Code Online (Sandbox Code Playgroud)

wherereadStr()是一个返回字符串或数组的函数。在许多其他语言中,这是很有可能的,但是 Fortran 呢?我的示例中的语法当然无法编译。有没有其他语法可以使用?

fortran fortran90 fortran2003

6
推荐指数
1
解决办法
229
查看次数