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

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

       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”返回坐标和节点的位移;调用它可以正常工作,并且值正确存储在 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 的值。

我直到主子程序结束才解除分配数组

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

子程序运行良好,因为我在调用过程中将 xi、yi 和 zi 作为参数提供,但现在我必须使用子程序,在调用过程中我无法传递它们。

那么,为什么会发生这种情况?

感谢您抽出宝贵时间……并为我的错误感到抱歉。

更新
我使用与主程序等效的 Subruotine 'UEDINC'。它就像我使用的 FEM-Programm 的 API。这个子例程在每个增量结束时被调用,我的所有代码和我的子例程都在这个子例程中/在这个子例程中调用。
“NODVAR”由 FEM 程序提供并记录在案。它为每个节点i调用并返回一个 dim(3) 数组中的值,这里是 nodein 和 nodedis,0/1 表示返回的是什么:坐标或其位移,token1 和 token2 会返回一些我做的信息不需要。

我证实,从“NODVAR”返回的值是我通过打印出来的期望值。我还通过打印存储在我的数组中的值,在将它们存储在我的数组中的 vom '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 有 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)' 显然不在我编译的代码中,只有一些标记用于演示]

4

2 回答 2

2

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

write(0,*)x,y,z

写入 vector x,然后是 vector y,然后是 vector z。格式子句(即*)告诉编译器写出它认为合适的数字。幸运的是,它选择在每行上按顺序写入 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),...您必须编写语句来执行此操作,就像您的第一个输出语句一样。

于 2013-07-12T09:08:20.103 回答
1

我觉得你的问题相当混乱。您是说您发现数组xi, yi, zi中的值出乎意料吗?你有什么证据表明价值观发生了变化?

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

你用的是什么编译器?

PSreal (kind=8)不保证是 8 字节实数。种类的数值不可移植,并且在编译器之间有所不同。

于 2013-07-12T07:35:26.503 回答