Fortran,数组改变了他们的价值观

时间:2013-07-12 06:36:56

标签: arrays fortran

我有一个非常奇怪的问题,似乎我的某些实际情况有所改变。

我有一个模块:

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'。 (在模块中创建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

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

  ....
  -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
   ....

结束更新

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

打印xi,yi和zi的值。

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

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

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

那么,为什么会这样呢?

感谢您的时间......并为我的错误感到抱歉。

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

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

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

进一步调查
我修改了我的代码,现在我有以下子程序:

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有昏暗(NUMNP)并且基本上是空的,我没有对它们做任何事情而是调用这个子程序,ndaten = NUM​​NP

(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 个答案:

答案 0 :(得分:2)

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

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),...的值,你必须编写语句来做,就像你的第一个输出语句那样。

答案 1 :(得分:1)

我发现你的问题相当令人困惑。您是说您发现数组xi, yi, zi中的值是意外的?你有什么证据表明这些价值已发生了变化?

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

您使用的是哪种编译器?

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