标签: fortran90

指针作为虚拟参数

我对以下程序有些困惑

module test
   implicit none

   type TestType
      integer :: i
   end type

contains
   subroutine foo(test)
      type (TestType), intent(out) :: test
      test%i = 5 
   end subroutine

   subroutine bar(test)
      type (TestType), intent(out) :: test
      test%i = 6 
   end subroutine

end module

program hello
   use test
   type(TestType) :: t

   call foo(t)
   print *, t%i 
   call bar(t)
   print *, t%i 
end program hello
Run Code Online (Sandbox Code Playgroud)

及其衍生物。稍后再谈。正如我们所知,Fortran语言传递程序参数作为一个传递引用,这意味着实体出现在伪参数test两者foobar被许可的堆栈上相同的内存空间program hello。到现在为止还挺好。

假设我在program hello中定义type(TestType) :: t为一个指针,并分配它。

program hello
   use …
Run Code Online (Sandbox Code Playgroud)

pointers fortran90

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

模块调用具有隐式接口的外部过程

以下代码,结合模块程序外部程序

module module_dummy

  implicit none

contains

  subroutine foo(a)

    real, intent(inout) :: a(:)

    call bar(a)

  end subroutine foo

end module module_dummy

program main

  use module_dummy

  implicit none 

  integer, parameter :: nelems = 100000000
  real,  allocatable :: a(:)

  allocate( a(nelems) )
  a = 0.0
  call foo(a)
  print *, a(1:10)
  deallocate(a)

end program main

subroutine bar(a)

  implicit none

  real, intent(inout) :: a(:)

  a = 1.0      

end subroutine bar
Run Code Online (Sandbox Code Playgroud)

似乎失败了:

  1. segmentation fault
  2. 打印块0.000而不是块1.000

在我迄今为止尝试过的任何平台上。该问题与 的隐式接口声明 …

module interface subroutine fortran90

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

Fortran:从矩阵中提取列和行并将它们用作乘法的一维数组

假设我有矩阵A并且B都有大小 nxn 。现在我想把A的每一列当作一个列矩阵ColA(i)[i=1,n],把B矩阵的每一行当作一个行矩阵RowB(j)[j=1,n]。

现在我可以使用matmul函数来构造一个新矩阵,称为C其元素是通过将所有可能的 i 和 j 值乘以 ColA 和 RowB 来找到的吗?就像是

do i = 1, n
 do j= 1, n
    C(i,j) = matmul( ColA(i), RowB(j) ) 
 end do
end do
Run Code Online (Sandbox Code Playgroud)

arrays fortran matrix fortran90

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

如果参数列表不同,Fortran 95 是否允许两个子例程具有相同的名称?

如果参数列表的长度不同,Fortran 95 标准是否允许两个子例程(或函数)具有相同的名称?例如,

subroutine a(i)
! code here
end subroutine a

subroutine a(j,k)
! code here
end subroutine a
Run Code Online (Sandbox Code Playgroud)

fortran fortran90 fortran95

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

在fortran循环中使用指针变量

我想知道什么应该是使用指针变量作为循环计数的fortran程序的行为?比如使用gfortran,这个程序:

program foo
  integer, pointer :: x
  integer, target :: y
  x => y
  do x=0,10
    y = 100                                                                                                                                                                                                                   
    print*, "hello"
  enddo
end program
Run Code Online (Sandbox Code Playgroud)

执行时变成无限循环.这应该发生吗?

fortran loops fortran90

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

有什么方法可以将一组变量值通过子程序传递给没有公共块的函数?

我不想在我的程序中使用公共块.我的主程序调用一个调用函数的子程序.该函数需要子程序中的变量.

有什么方法可以将子程序中的信息集传递给函数?

program
...

call CONDAT(i,j)

end program

SUBROUTINE CONDAT(i,j)

common /contact/ iab11,iab22,xx2,yy2,zz2
common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
call function f(x)
RETURN
END

function f(x)
common /contact/ iab11,iab22,xx2,yy2,zz2
common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
end
Run Code Online (Sandbox Code Playgroud)

fortran fortran77 fortran90

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

如何在Fortran中执行整数log2()?

一个显而易见的方法是:

integer function log2_i(val) result(res)
    implicit none
    integer, intent(IN) :: val

    if (val<0) then
        print *, "ERROR in log2_i(): val cannot be negative."
    else if (val==0) then
        print *, "ERROR in log2_i(): todo: return the integer equivalent of (-inf)..."
    else if (val==1) then
        res = 0
    else
        res = FLOOR( LOG(val+0.0d0)/LOG(2.0d0) )
    endif
end function log2_i
Run Code Online (Sandbox Code Playgroud)

使用Fortran的位移操作符有更好的方法吗?

这个问题几乎相同,但使用无符号整数.不幸的是,符号位将禁止使用相同的算法.

performance fortran bit-manipulation logarithm fortran90

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

Fortran中双精度除以整数

现在我正在处理在我之前从事该项目的人的 Fortran 代码。代码比较大,这里就不提供了。在这个代码的很多地方都有双精度值除以整数。IE:

double precision :: a,c
integer :: b
a = 1.0d0
b = 3
c = a/b
Run Code Online (Sandbox Code Playgroud)

这有时会导致比常规浮点数错误更严重的错误。我会为您复制粘贴其中一个这样的错误:3.00000032899483。对于他的目的来说,这是可以的,但对我来说,这个错误是可怕的。似乎fortran正在将实数除以整数,然后将数字放大到双精度,添加一些随机的东西。如果我会写,当然可以处理:

c = a/(real(b,8))
Run Code Online (Sandbox Code Playgroud)

所以,我可以做到,但是搜索他的所有代码需要很长时间。这就是为什么,我尝试以下一种方式重载 (/) 运算符:

MODULE divisionoverload
!-----------------------------------------------------
   INTERFACE OPERATOR (/)
      MODULE PROCEDURE real_divoverinteger
   END INTERFACE OPERATOR ( / )
CONTAINS
!-----------------------------------------------------

DOUBLE PRECISION FUNCTION real_divoverinteger(a,b)
   IMPLICIT NONE
   DOUBLE PRECISION, INTENT (IN) :: a 
   INTEGER, INTENT(IN) :: b 

   real_divoverinteger = a/real(b,8)
END FUNCTION real_divoverinteger

END MODULE divisionoverload
Run Code Online (Sandbox Code Playgroud)

但是 gfortran4.8 给我的错误清楚地表明这与内在除法运算符冲突:

 MODULE PROCEDURE real_divoverinteger
                                          1
Error: Operator interface at (1) …
Run Code Online (Sandbox Code Playgroud)

precision fortran division fortran90

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

翻转矩阵 fortran

我想翻转我的矩阵。使得 T(1,1)=C(2,1)

我已经制作了这个程序,我发现了一个应该在线完成的代码,C=T(2:1:-1, :)但是当尝试获得应该是 3 的值 C(1,1) 时,我得到 1.3533635457363350E-306。你如何翻转矩阵使得向上变成向下?

program main


implicit none
  integer iMax, jMax
  double precision, dimension(:,:), allocatable :: T,C

double precision x, dx,f,L2old,L2norm

integer i, j,n


 allocate(T(0:2, 0:2))
 allocate(C(0:2, 0:2))


T(1,1)=1
T(1,2)=2
T(2,1)=3
T(2,2)=4

write(*,*) T(2,2)

C=T(2:1:-1, :)

Write(*,*) C(1,2)


end program main
Run Code Online (Sandbox Code Playgroud)

fortran matrix gfortran fortran90

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

减少 Fortran 90 中数组的大小

假设我有一个数组:

real, dimension(100000, 5) :: a
Run Code Online (Sandbox Code Playgroud)

该数组将由实数填充,a(0, :)直到a(n, :)wheren是小于 的数字100000。填充完所有值后,我们可以决定的值n(让我们假设它30000)。我想将数组重塑为:

real, dimension(30000, 5) :: a
Run Code Online (Sandbox Code Playgroud)

只是为了删除数组中未使用的元素。我不希望执行任何数组复制过程,因为数组很大,因此它会破坏程序效率。这里有解决办法吗?

fortran fortran90

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