2013-07-12 48 views
0

我有一個非常奇怪的問題,看起來,不知怎的,我的一些實例正在發生變化。Fortran,數組更改它們的值

我有一個MODUL:

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尺寸如MODUL大小不工作,我不知道爲什麼,但是那不是我的問題現在)

下一個調用子程序這樣做:

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和一個節點的位移;調用它工作得很好,值在nodein(1:3)和nodedis(1:3)中正確存儲。

write(0,*)xi,yi,zi 

給出了存儲在十一值的3列,所以基本上義和ZI有十一

更新 值的數值並不完全相等,它們之間的區別位:

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

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提供並進行了調試。它被稱爲每個節點並返回dim(3)arry中的值,這裏nodein和nodedis,0/1表示什麼給回:koordinates或它們的位移,token1和token2返回一些信息我不需要。

我驗證了,給出的'NODVAR'的值是我期望通過打印出來的值。我還打印出循環中的值,通過打印存儲在我的arry中的值,將它們存儲到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的暗淡(NUMNP)基本屬於空白,我什麼都不做與他們beofre調用這個子程序,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.50.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)' 顯然不是在我的代碼編譯並僅用於演示一些標記]

+0

嗨,主程序我錯了,我使用Subruotine'UEDINC'euivalent作爲主程序。它像我的FEM-Programm中的API一樣工作。這個子程序在每次增量結束時調用,所有我的代碼和子程序都在這個子程序中/在這個子程序中調用。 'NODVAR'由FEM-Program提供,並且已經dokumented。它被調用給每個節點i,並在dim(3)arry中給出值,在這裏nodein和nodedis,0/1表示給出的是什麼:koordinates或它們的位移,token1和token2返回一些信息,我做不需要。 –

+0

我證實了,給出的'NODVAR'值是我期望通過打印出來的值。 –

+0

感謝您的建議,我的意見現在在更新。 –

回答

2

在你的第二個輸出中,讀取下一個值,然後讀取下來的值,然後你會發現它們是相同的數字。這種說法

write(0,*)x,y,z 

寫道矢量x,則載體y,則載體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),...您必須編寫語句來執行該操作,如第一條輸出語句所做的那樣。

+0

雖然這很奇怪,因爲我有相同的子程序在另一個「程序」中工作,我得到了我期望的列中的數據。 –

+0

謝謝你的幫助。爲第三。時間。 –

1

我找到你質疑相當混亂。你是說你發現數組xi, yi, zi中的值是意想不到的嗎?你有什麼證據表明價值觀發生了變化?

如果一個變量的值超出了你的期望值,在Fortran中有兩個可能的錯誤會導致這樣的問題:1)數組下標超出範圍,或者2)實際過程參數和僞過程參數之間不一致。最簡單的第一步,搜索這些錯誤並打開編譯器的所有錯誤和警告選項,特別是運行時間下標邊界檢查。還要確保將所有過程(子例程和函數)放在模塊中,並且它們都會被編譯器檢查參數一致性。

你使用什麼編譯器?

P.S. real (kind=8)不保證是一個8字節的真實。種類的數字值不可移植並且在編譯器之間不同。

+0

嗨,我可以使用有限元程序在手動存儲和計算值的情況下對這些值進行驗證。所以我知道,他們錯了。我還打印出循環過程中的值,它們將vom'NODVAR'存儲到我的數組中,在這裏它們也是正確的。 我知道,Kind = 8不是可操作的,但它適用於ifort,並且代碼不必是可移植的。 –

+0

謝謝你的幫助。 –

+0

@Alex,在您尋求幫助時,最好擁有便攜式/標準確認碼。否則,你期待每個人都有一個特定的編譯器 - 處理器組合。不會工作。 – BaRud