2013-06-12 37 views
0

我遇到一個變量被覆蓋的問題,因爲我不知道原因。我已經發布了下面的代碼塊,以便您可以看到事情是如何聲明的。將變量應變Qi,Qf,Qd,tel和Gc傳遞給子程序並用於計算ssgrad,strn0,strss0。Fortran:自己更改的變量

我的問題是,電話和Gc傳遞到子例程確定,但由於某些原因在這段代碼中更改值。

使用打印語句我發現問題首先發生在第二個循環中。當我將strss0設置爲0時,Gc和tel將兩者的值從等於1改變爲看似隨機的數字:tel = 11.52822 Gc = -8.789086(剛纔爲了舉例而示出)

每次我運行代碼它們被設置爲相同的值。

只是讓你知道,這個子程序接口與商業有限元軟件包。

提前任何幫助,非常感謝這個

subroutine initcalcs(strain,Qi,Qf,Qd,tel,Gc,ssgrad,strn0,strss0) 

    implicit none 

    integer :: i,j 

    real*8:: nstrn0,nstrs0,strn0,strnf,varsq,normvar,lmbda0,lmbdaf, 
# ssgrad,t0,tt,tel,nstrnf,nstrsf,Gc 

    real*8, dimension(3) :: strain,stran0,stranf,strss0,strssf,var 

    real*8, dimension(3,3) :: Qd,Qi,Qf 


    lmbda0=1.0d0                       


    nstrn0=0.0d0                    
    do i=1,3 
     stran0(i)=0.0d0 
     stran0(i)=strain(i)*lmbda0               
     nstrn0=nstrn0+stran0(i)**2               
    end do                      

    nstrn0=dsqrt(nstrn0)                  


    do i=1,3 
     strss0(i)=0.0d0 
    end do 
+0

你試過把它們聲明爲'intent(in)'變量嗎? –

回答

3

在Fortran中,有內存值的腐敗的兩個常見的原因。一個是下標錯誤,您使用不正確的下標值分配給數組元素。這寫入陣列外部的內存位置。另一個是調用過程(子例程或函數)中的參數與過程的僞參數之間的分歧。要麼會導致問題出現在與實際原因不同的源代碼位置。建議:檢查您的代碼是否存在這些問題。打開編譯器的嚴格警告和錯誤檢查選項。使用Fortran> = 90和模塊使Fortran能夠更好地自動查找參數一致性問題。您可以使用調試器監控內存位置,並查看修改它的內容。

1

我同意M. S. B .:打開嚴格的警告和錯誤檢查,並驗證子例程調用是否傳遞具有與子例程相同類型和形狀(數組維數)的參數。

變量聲明語法中的冒號意味着這是Fortran90或更高版本。如果是這種情況,我強烈建議使用INTENT修飾符來指定參數是否爲只讀。

例如,讓我們假設傳遞給這個例程,strainQiQfQdtel的論點,並Gc是隻讀的輸入參數是ssgradstrn0strss0返回作爲輸出;也就是說,他們所擁有的任何價值都會被這個例程所覆蓋。

的參數的變量聲明將變爲:

real*8, dimension(3), intent(in) :: strain 
real*8, dimension(3,3), intent(in) :: Qi, Qf, Qd 
real*8, intent(in) :: tel, Gc 

real*8, intent(out) :: strn0, ssgrad 
real*8, dimension(3), intent(out) :: strss0 

INTENT關鍵字是一個除的Fortran 90,其允許用戶指定哪些參數是隻讀(INTENT(IN)),初始化,但其可以在例程中修改(INTENT(INOUT)),並將其視爲未初始化,並將在例程中設置(INTENT(OUT))。

如果未指定INTENT是,它是默認爲INOUT這與FORTRAN 77是一致的(請注意,有INTENT(INOUT)INTENT之間沒有被指定細微的差別,但他們都沒有在這個例子中相關)。

如果一個例程試圖將一個值分配給一個聲明爲INTENT(IN)的變量,並且至少會在一個聲明爲INTENT(OUT)的變量未分配值時發出警告,那麼一個好的編譯器會引發錯誤。

如果可能,請在所有應爲只讀的變量上設置INTENT(IN)。這可能是不可能的,這取決於這些變量如何傳遞給其他例程。如果未在此例程中調用的例程的參數上指定INTENT,則它將默認爲INOUT。如果您通過INTENT(IN)變量作爲INTENT(INOUT)參數,則編譯器將引發錯誤。如果在您控制的代碼中發生這種情況,則必須在多個例程中指定INTENT。這可能會也可能不需要,具體取決於您是否想要普遍改進代碼或只是很快解決這個問題。

我假設這些變量中的一些被傳遞給有限元包中的外部例程,我猜測它們與代碼相關而不是編譯;我不確定在這種情況下如何處理編譯時意圖檢查。