首页 文章

Fortran,数组改变了他们的 Value 观

提问于
浏览
0

我有一个非常奇怪的问题,似乎我的某些实际情况正在发生变化 .

我有一个模块:

c\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
      module Koordinaten
      implicit none

      save
       real(kind=8),allocatable,dimension(:) :: xi, yi, zi 
       integer,allocatable,dimension(:) :: setnodes, st
       real(8),allocatable, dimension(:) :: sx,sy,sz
       Integer :: setdaten
      end 
c/////////////////////////////////////////////////////////

在大多数的suroutines和主子程序中使用它(这个子程序被调用并且每个模拟的结束增量,除了我的代码之外什么都不做 . ) . 在那里,在主程序中,所有都被分配 .

SUBROUTINE UEDINC (INC,INCSUB)
       use Koordinaten          

      implicit none

c     ** Start of generated type statements **
      include 'dimen'
      include 'jname'
      include 'statistics'
      include 'spaceset'
      integer inc, incsub
      integer :: i, nsets,k
      character(265), dimension(ndset) :: setname
c     ** End of generated type statements **

      write(0,*)"NUMNP: ",NUMNP
      allocate(xi(NUMNP))
      allocate(yi(NUMNP))
      allocate(zi(NUMNP))
      allocate(setnodes(NUMNP))
      allocate(st(NUMNP))
      allocate(sx(NUMNP))
      allocate(sy(NUMNP))
      allocate(sz(NUMNP))
      allocate(ri(NUMNP))
      allocate(delta_r(NUMNP))
      allocate(dummy(NUMNP))

NUMNP来自'dimen' . (在Modul中使用NUMNP作为尺寸创建尺寸不起作用,我不知道为什么,但这不是我现在的问题)

接下来调用子程序执行此操作:

c#########################################################
      subroutine einlesen ()
      use Koordinaten
      use zyl_para

      implicit none

c     ** Start of generated type statements **
      include 'dimen'
      integer :: i, j
      integer :: token1, token2
      real(8), dimension(3) :: nodein, nodedis

c     ** End of generated type statements **

      write(0,*)"--- lese Koordinaten ein ---"
      write(0,*)"Anzahl der Datenpunkte: ", NUMNP

      do i=1,NUMNP

         call NODVAR(0,i,nodein,token1,token2)
         call NOdVAR(1,i,nodedis,token1,token2)

         xi(i)=nodein(1)+nodedis(1)
         yi(i)=nodein(2)+nodedis(2)
         zi(i)=nodein(3)+nodedis(3)

      end do

      write(0,*)"--- Koordinaten eingelesen ---"
      do i=1, NUMNP
      write(0,*)xi(i),yi(i),zi(i) 
      end do
      write(0,*)"§§§§§§§§§§§§§§§§§"
      write(0,*)xi(i),yi(i),zi(i)
      return
      end subroutine einlesen
c#########################################################

这是一个奇怪的部分:Thr子程序'NODVAR'返回一个节点的Koordinates和Displacement;调用它工作得很好,值在nodein(1:3)和nodedis(1:3)中正确存储 .

write(0,*)xi,yi,zi

给出了存储在xi中的3列值,所以yi和zi的值基本上都是xi

Update 值不完全相等,它们有点不同:

....
  -20.0000765815728       -20.0000760759377       -20.0000751985753
  -20.0000726178150       -20.0000671623785       -20.0000576162833
  -20.0000427864046       -20.0000214978710       -19.9999932382105
  -19.9999590389013       -18.9999215100902       -18.9998779514709
  -18.9998277903388       -18.9997725557635       -18.9997146854248
  -18.9996577298267       -18.9996059540004       -18.9995633069003
  -18.9995325241422       -18.9995144999731       -18.9995087694121
  -18.9995144999742       -18.9995325241444       -18.9995633069036
  -18.9996059540045       -18.9996577298314       -18.9997146854297
  -18.9997725557682       -18.9998277903431       -18.9998779514747
  -18.9999215100934       -18.9999598955851       -18.9999939247953
  -19.0000218363084       -19.0000426285757       -19.0000570432278
  -19.0000664612509       -19.0000719811992       -19.0000746027515
  -19.0000754299370       -19.0000747701169       -19.0000754299373
  -19.0000746027519       -19.0000719811998       -19.0000664612514
  -19.0000570432280       -19.0000426285755       -19.0000218363074
  -18.9999939247935       -18.9999598955826       -17.9999226880232
  -17.9998792166917       -17.9998290553161       -17.9997737084839
  -17.9997156002768       -17.9996582203842       -17.9996058186853
   ....

END update

do i=1, NUMNP
  write(0,*)xi(i),yi(i),zi(i) 
  end do

打印xi,yi和zi的值 .

我不释放数组直到主子程序结束

打印不是问题,问题是,下一个子程序使用这个koordinates,但似乎有相同的问题 .

子程序运行正常,因为我在调用期间给了xi,yi和zi作为参数,但现在我必须使用子程序,在调用期间我无法传递它们 .

那么,为什么会这样呢?

谢谢你的时间......抱歉我的错误 .

UPDATE
我将Subruotine 'UEDINC' euqivalent用于主程序 . 它就像我使用的FEM-Programm的API一样 . 在每个增量结束时调用此子例程,并且我的所有代码和子例程都在此子例程中/在此子例程中调用 .
'NODVAR'由FEM-Program和dokumented提供 . 它被调用每个节点 i 并在dim(3)的arry中返回值,这里是nodein和nodedis,0/1表示返回的内容:koordinates或它们的位移,token1和token2返回一些我做的信息不需要 .

我证实,从“NODVAR”返回的值是我打算将它们打印出来的值 . 我还在循环中打印出值,将它们存储到我的数组中,通过打印存储在我的数组中的值,这里它们也正确 .

我知道,Kind = 8不可移植,但它适用于ifort,并且代码根本不必是可移植的 .

Further investigation
我修改了我的代码,我现在有以下子程序:

c##########################################################

      implicit none


c     ** Start of generated type statements **


      integer :: ndaten, i, j
      integer :: token1, token2
      real(8), dimension(3) :: nodein, nodedis
      real(8), dimension(ndaten) :: x,y,z
c     ** End of generated type statements **

      write(0,*)"--- lese Koordinaten ein ---"
      write(0,*)"Anzahl der Datenpunkte: ", ndaten

      do i=1,ndaten

         call NODVAR(0,i,nodein,token1,token2)
         call NOdVAR(1,i,nodedis,token1,token2)

         x(i)=nodein(1)+nodedis(1)
         y(i)=nodein(2)+nodedis(2)
         z(i)=nodein(3)+nodedis(3)
         write(0,*)x(i),y(i),z(i)    ***(1)
      end do

      write(0,*)"*****************"
      write(0,*)x,y,z                ***(2)

      write(0,*)"--- Koordinaten eingelesen ---"
      return
      end subroutine einlesen
c#########################################################

arrys x,y,z有dim(NUMNP)并且基本上是空的,我没有对它们进行调用这个子程序,ndaten = NUMNP

(1)如我所料,给予我:

-19.9999205042055       4.174743870006559E-005  -2.49993530375797
  -19.9998768725013       0.362341804670311       -2.47354036781631
  -19.9998267169371       0.734574978337486       -2.38959111446343
  -19.9997716931358        1.10321804323537       -2.24337882624597
  -19.9997141644151        1.45282900896610       -2.03451636821160
  -19.9996575908584        1.76783665097058       -1.76773205553564
  -19.9996061583064        2.03464970008098       -1.45274943026036
  -19.9995638755175        2.24353899096506       -1.10315640708085
  -19.9995334705205        2.38977079851914      -0.734524030614783
  -19.9995156926493        2.47372965346901      -0.362296534411106
  -19.9995100448173        2.50012385767524       4.865608618193709E-010
   ....

(2)给我:

-19.9999205042055       -19.9998768725013       -19.9998267169371
  -19.9997716931358       -19.9997141644151       -19.9996575908584
  -19.9996061583064       -19.9995638755175       -19.9995334705205
  -19.9995156926493       -19.9995100448173       -19.9995156926504
  -19.9995334705227       -19.9995638755208       -19.9996061583105
  -19.9996575908630       -19.9997141644199       -19.9997716931404
  -19.9998267169414       -19.9998768725051       -19.9999205042086
  -19.9999590389038       -19.9999932382123       -20.0000214978720
  -20.0000427864049       -20.0000576162831       -20.0000671623780
  -20.0000726178145       -20.0000751985748       -20.0000760759375
  -20.0000765815728       -20.0000760759378       -20.0000751985753
  -20.0000726178150       -20.0000671623785       -20.0000576162833
  -20.0000427864046       -20.0000214978710       -19.9999932382105
  -19.9999590389013       -18.9999215100902       -18.9998779514709
  -18.9998277903388       -18.9997725557635       -18.9997146854248
  -18.9996577298267       -18.9996059540004       -18.9995633069003
  -18.9995325241422       -18.9995144999731       -18.9995087694121
  -18.9995144999742       -18.9995325241444       -18.9995633069036
  -18.9996059540045       -18.9996577298314       -18.9997146854297
  -18.9997725557682       -18.9998277903431       -18.9998779514747
  -18.9999215100934       -18.9999598955851       -18.9999939247953
  -19.0000218363084       -19.0000426285757       -19.0000570432278
   ...

['(1)'和'(2)'显然不在我编译的代码中,只有一些标记用于演示]

2 回答

  • 1

    在你的第二个输出中读取值然后向下,在你第一次读取值然后向下,你会发现它们是相同的数字 . 这个说法

    write(0,*)x,y,z
    

    写矢量 x ,然后矢量 y ,然后矢量 z . format子句(即 * )告诉编译器在它认为合适时写入数字 . 幸运的是,它选择在每一行写出3个值,按顺序 x(1),x(2),x(3),newLine,x(4),...,y(1),y(2),... 这已经欺骗你以为它正在写(错误地) x(i),y(i),z(i) 但是你的想法在这里不正确,而不是程序 .

    如果你想要写入 x(1),y(1),z(1),newLine,x(2),... 的值,你必须编写语句来做,就像你的第一个输出语句那样 .

  • 2

    我发现你的问题相当令人困惑 . 你是说你发现数组_396705中的值是意料之外的吗?您的证据表明 Value 观发生了变化?

    如果变量的值在预期之外发生变化,那么在Fortran中有两个可能导致此类问题的错误:1)数组下标超出范围,或2)实际和虚拟过程参数之间存在分歧 . 最简单的第一步,找出这些错误并启用编译器的所有错误和警告选项,尤其是运行时下标边界检查 . 还要确保将所有过程(子例程和函数)放在模块中,并将它们放在_396706中,以便编译器可以检查参数的一致性 .

    你用的是什么编译器?

    附: real (kind=8) 不保证是8字节的实数 . 种类的数字值不可移植,并且编译器之间不同 .

相关问题