問題描述:代碼計算的結果,按照時間順序,分別存放在不同的文件夾內,但是結果文件具有相同的文件名字,如下:
/postproc1/data.dat
/postproc2/data.dat
/postproc3/data.dat
...
現在要對大量結果文件進行后處理,將特定點上的數據導出,得到特定點上,壓力隨時間的變化關系。
我要用Fortran寫個小程序來實現。代碼如下:
1 program main 2 implicit none 3 4 character(len = 3) :: cTemp 5 character(len = 100) :: fileplace 6 integer, parameter :: time_sequence=27 ! number of time sequences = np 7 integer, parameter :: np=27 ! corresponding pressure = time_sequence 8 integer, parameter :: ntap=15 ! number of taps 9 integer :: tap(ntap) ! I index of taps (places) 10 integer :: k, i, j, m,n 11 real :: x,y,u,v,w,rho 12 real :: p(np,ntap) 13 14 data tap /603,643,666,685,700,715,727,740,751,762,773,799,826,857,895/ ! I index of the tap 15 16 17 do j = 1, ntap 18 19 write(*,"('Begin to figure out No.' i2 ' tap!')") j 20 21 do k = 584, 584+time_sequence-1 22 23 write(cTemp, '(i3)') k 24 fileplace = '/home/postproc'//trim(adjustl(cTemp))//"/" ! Name of the folder, not include the name of the target file 25 open(k,file=trim(adjustl(fileplace)) // "results_grid_1_tecplot.dat", form='formatted', status='old') 26 27 do i = 1, tap(j)+1 28 read(k,*) 29 end do 30 31 read(k,'(1x,7(1pe15.6))') x,y,u,v,w,rho,p(k-583,j) 32 close(k) 33 34 end do 35 36 end do 37 38 open(10,file='time_pressure_1-7.dat', status='new') 39 40 do m = 1, time_sequence 41 write(10,'(1x,I3,7(1pe15.6))') m, p(m,1), p(m,2), p(m,3), p(m,4), p(m,5), p(m,6), p(m,7) 42 end do 43 44 close(10) 45 46 open(20,file='time_pressure_8-15.dat', status='new') 47 48 do m = 1, time_sequence 49 write(20,'(1x,I3,8(1pe15.6))') m, p(m,8), p(m,9), p(m,10), p(m,11), p(m,12), p(m,13), p(m,14), p(m,15) 50 end do 51 52 close(20) 53 54 end
現在對代碼說明如下:
14行,數組tap用於存放tap的I方向的索引值。
23行,將數字 k 賦值給字符串cTemp,用於記錄文件夾名字中的數字。
24行,fileplace指定上文所說的不同的文件夾的名字,不包含要處理的文件的名字。因為文件夾的名字只有數字是不同的,所以要把數字給提取出來,作為字符串,這樣的話,就可以循環進入不同的文件夾。其 中 // 是將字符串連接起來。adjustl將字符串的內容左對齊,空格置於右端,而trim的作用是把字符串后(就是右端)的空格去除。這三個命令都是Fortran內置的,可以直接使用。
末尾的"/"千萬不能省略,因為這個斜杠將文件夾的名字與下文的文件的名字分隔開,如果沒有這個斜杠,就不能正確地讀到文件名。
25行, // 將文件夾的名字與文件的名字連接起來。
27行,do循環。因為read是按行的順序來讀的,而我要導出的數據不在第一行,因此,目標行之前的數據仍然要讀,但是不做記錄。
31行,將讀取到的數據記錄下來,其中數據最后一列是壓力,將壓力記錄到數組p中,數組p的第一個索引代表時間序列,第二個索引代表哪一個tap(就是空間位置)。
'(1x,7(1pe15.6))' 表示輸出的格式:
1x:表示將輸出的位置向右移動一個位置;
7:表示將要記錄的7個數據全都用這一個格式;
1pe15.6,其中p表示輸出數據時的縮放值,其前的1表示1倍,即不縮放;e表示以指數類型輸出浮點數,15.6表示使用15個字符字段,小數部分占7位。
40行,do循環,將數組p寫出。這里,數據一共有15列,我分開來寫了,輸出到兩個文件內。因為write這個命令,后邊不能寫太長,一共132位,超過這個值,編譯的時候就會提示太長,需要分行寫。分行寫,用 & 這個符號寫在行尾。
48行,同40行。
代碼主要參考了以下兩篇文章,感謝。
http://bbs.06climate.com/forum.php?mod=viewthread&tid=24905
https://stackoverflow.com/questions/16142292/defining-path-for-file-in-fortran