24小时热门版块排行榜    

CyRhmU.jpeg
查看: 2789  |  回复: 34
本帖产生 1 个 程序强帖 ,点击这里进行查看

snoopyzhao

至尊木虫 (职业作家)

★ ★
小木虫(金币+0.5):给个红包,谢谢回帖交流
zyj8119(金币+1, 程序强帖+1): 见识了! 2011-02-25 16:43:43
引用回帖:
Originally posted by 阿黛拉 at 2011-02-25 09:23:25:
您好,非常感谢您的帮助。
还有个问题想请您帮助解决---如您所看到,比如说有38个ions,前10个ions是一组,后28个是一组, 举例15  0.512  0.569  0.717-  27 2.79  36 2.79  37 2.79   8 2.80   6 2.80  13 ...

大概是这个样子,如果我没有理解错的话。
CODE:
program ex

implicit none
character(len = 128) :: line, fm
integer :: ios, len_line, i, j, ion_num, ion_tmp
real, dimension(5000) :: table
integer, dimension(5000) :: ion
integer, dimension(5000) :: ion_table ! ion in table
integer, parameter :: ion_pos = 10
real :: sum_1, sum_2, sum_3 ! ion_table < 10; ion_table > 28; ion_table > 10 & ion_table < 28
integer :: i_1, i_2, i_3

do
   read (*,'(a)', iostat = ios) line
   if (ios < 0) exit
   if (index(line, 'nearest neighbor table') /= 0) exit
end do

j = 0

do
   read (*,'(a)', iostat = ios) line
   if (ios < 0) exit
   if (index(line, 'LATTYP') /= 0) exit
   if (len(trim(line)) == 0) cycle
   len_line = len(trim(line(27:)))
   write(fm,'(a,i0,a)') '(', len_line/9,'(tr1,i3,tr1,f4.2))'
   read (line(27:), fm) (ion_table(i), table(i), i=j+1,j+len_line/9)
   read(line, '(tr1,i3)') ion_tmp
   if (ion_tmp /= 0) ion_num = ion_tmp
   do i=j+1, j+len_line/9
      ion(i) = ion_num
   end do
   j = j + len_line/9
end do

write (*,'(i3,tr2,i3,tr2,f4.2)') (ion(i), ion_table(i), table(i), i= 1, j)

sum_1 = 0.0
sum_2 = 0.0
sum_3 = 0.0
i_1 =0
i_2 =0
i_3 =0

do i=1,j
   if (ion(i) <= ion_pos) then  ! ion <= 10
      if (ion_table(i) <= ion_pos) then ! ion_table <= 10
         sum_1 = sum_1 + table(i)
         i_1 = i_1 + 1
         write(1,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      else
         sum_3 = sum_3 + table(i) ! ion_table > 10
         i_3 = i_3 + 1
         write(3,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      end if
   else ! ion > 10
      if (ion_table(i) >= (ion(j) - ion_pos)) then ! ion_table >= 28
         sum_2 = sum_2 + table(i)
         i_2 = i_2 + 1
         write(2,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      else
         sum_3 = sum_3 + table(i) ! ion_table < 28
         i_3 = i_3 + 1
         write(3,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      end if
   end if
end do

write(*,*) sum(table(1:j))/j

print *, sum_1, i_1, sum_2, i_2, sum_3, i_3

write(*,*) sum_1/i_1, sum_2/i_2, sum_3/i_3

end program ex

[ Last edited by snoopyzhao on 2011-2-25 at 11:08 ]
21楼2011-02-25 10:57:14
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

阿黛拉

银虫 (小有名气)

引用回帖:
Originally posted by snoopyzhao at 2011-02-25 10:03:44:
这个应该是可以做到的,添加一个 ions 序号的数组,添加一个最短距离中 ions 序号的数组,然后加几个判断就可以了,呵呵……

但要重新考试一下如何去读这些数据了……

您好,我正在算一个小的体系,打算测试一下。仔细读了您编的程序,尽管有一些地方没弄明白,但是我说一下我读后的想法,希望您指点一下。对于ion_table < 10; ion_table > 28; ion_table > 10 & ion_table < 28这个定义,我觉得和我的想法不符。我根据你的程序语言,叙述一下我的理解。
ion_pos = 10,当ion(i) <= ion_pos,计算机读到ion_table <= 10,加和取平均,这是我想要的第一个数据。前10个原子是相同的原子,设为原子1,这个数据是原子1间的平均间距。
ion(i) > ion_pos,计算机读到 ion_table >10 & ion_table <= 38时,加和取平均,这是我想要的第二个数据。后28个原子是相同的原子,设为原子2,这个数据是原子2间的平均间距。
ion(i) 从1到38循环时if ( ion(i) <= ion_pos), ion_table > 10& ion_table <= 38) 和 if ( ion(i) > ion_pos,ion_table <= 10)时加和取平均,这是我想要的第三个数据。这一个是原子1和原子2间的平均间距。我写我的想法的时候关于等号我在小心的求证,唯恐脑袋不灵就写错了。请您指教。谢谢 呵呵。。。
进退有度,才不至进退维谷;宠辱皆忘,方可以宠辱不惊。
22楼2011-02-25 15:41:54
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

snoopyzhao

至尊木虫 (职业作家)


小木虫(金币+0.5):给个红包,谢谢回帖交流
引用回帖:
Originally posted by 阿黛拉 at 2011-02-25 15:41:54:
您好,我正在算一个小的体系,打算测试一下。仔细读了您编的程序,尽管有一些地方没弄明白,但是我说一下我读后的想法,希望您指点一下。对于ion_table < 10; ion_table > 28; ion_table > 10 & i ...

你写这么多,我还是看不懂,你举一个数值的例子给我看一下,你打算如何算吧……
23楼2011-02-25 17:55:17
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

snoopyzhao

至尊木虫 (职业作家)


小木虫(金币+0.5):给个红包,谢谢回帖交流
引用回帖:
Originally posted by 阿黛拉 at 2011-02-25 15:41:54:
您好,我正在算一个小的体系,打算测试一下。仔细读了您编的程序,尽管有一些地方没弄明白,但是我说一下我读后的想法,希望您指点一下。对于ion_table < 10; ion_table > 28; ion_table > 10 & i ...

另外,你看一下程序中给出的 fort.1,fort.2,和 fort.3 的内容。其中第一列是所谓的原子序号,第三列是第一列原子和第二列原子之间的距离。你看一下,它是否符合你的要求……
24楼2011-02-25 17:57:22
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

阿黛拉

银虫 (小有名气)

引用回帖:
Originally posted by snoopyzhao at 2011-02-25 17:57:22:
另外,你看一下程序中给出的 fort.1,fort.2,和 fort.3 的内容。其中第一列是所谓的原子序号,第三列是第一列原子和第二列原子之间的距离。你看一下,它是否符合你的要求……

好的我举个例子
比如说B4N2,前四个是B,后两个是N,我想求B-B、B-N、N-N间的平均距离。
nearest neighbor table中比如第一行
1  0.388  0.481  0.529-   6 2.91   5 2.94   4 2.92   3 2.94代表1号原子B与6号N、5号N、4号B和3号B的距离。
所以要想求B-B平均间距,需要把前四行有关B-B的距离读出来求和也就是
4 2.92   3 2.94
3 2.94   4 2.90
1 2.94   2 2.94
1 2.94   2 2.90这几个整数后的小数
同理求B-N、N-N间的平均距离。
ion  position               nearest neighbor table
   1  0.388  0.481  0.529-   6 2.91   5 2.94   4 2.92   3 2.94
   2  0.596  0.481  0.529-   6 2.94   5 2.92   3 2.94   4 2.90
   3  0.492  0.377  0.529-   5 2.90   6 2.91   1 2.94   2 2.94
   4  0.492  0.585  0.529-   1 2.94   2 2.90   5 2.93   6 2.93
   5  0.492  0.481  0.425-   2 2.90   1 2.94   3 2.94   6 2.94
   6  0.492  0.481  0.633-   2 2.94   1 2.93   3 2.92   5 2.94

[ Last edited by 阿黛拉 on 2011-2-26 at 09:21 ]
进退有度,才不至进退维谷;宠辱皆忘,方可以宠辱不惊。
25楼2011-02-26 09:17:35
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

snoopyzhao

至尊木虫 (职业作家)


小木虫(金币+0.5):给个红包,谢谢回帖交流
引用回帖:
好的我举个例子
比如说B4N2,前四个是B,后两个是N,我想求B-B、B-N、N-N间的平均距离。
nearest neighbor table中比如第一行
1  0.388  0.481  0.529-   6 2.91   5 2.94   4 2.92   3 2.94代表1号原子B与6号N、5号N、4号B和3号B的距离。
所以要想求B-B平均间距,需要把前四行有关B-B的距离读出来求和也就是
4 2.92   3 2.94
3 2.94   4 2.90
1 2.94   2 2.94
1 2.94   2 2.90这几个整数后的小数
同理求B-N、N-N间的平均距离。
ion  position               nearest neighbor table
   1  0.388  0.481  0.529-   6 2.91   5 2.94   4 2.92   3 2.94
   2  0.596  0.481  0.529-   6 2.94   5 2.92   3 2.94   4 2.90
   3  0.492  0.377  0.529-   5 2.90   6 2.91   1 2.94   2 2.94
   4  0.492  0.585  0.529-   1 2.94   2 2.90   5 2.93   6 2.93
   5  0.492  0.481  0.425-   2 2.90   1 2.94   3 2.94   6 2.94
   6  0.492  0.481  0.633-   2 2.94   1 2.93   3 2.92   5 2.94

你的意思是 1-4 与 5-6 分成两组,在第一组中,后面的序号如果小于等于 4 算在第 1 种情况里;后面一组中,后面的序号大于等于 5 算在第 2 种情况里。在第一组中,后面的序号大于 4,并且小于等于 6 的算在第 3 种情况里;在第二组中,后面的序号小于 5 的算在第三种情况里,是这样的吗?
引用回帖:
您好,非常感谢您的帮助。
还有个问题想请您帮助解决---如您所看到,比如说有38个ions,前10个ions是一组,后28个是一组, 举例15  0.512  0.569  0.717-  27 2.79  36 2.79  37 2.79   8 2.80   6 2.80  13 2.83,这是第15个ion与第27.36.37.8.6.13的距离分别为2.79,2.79,2.80,2.80,2.83,我可否实现这样一种想法:1  分别对于前10个在读取后面的整数时如果<10,读取整数后面的距离求和平均,输出平均值;2  后28个对于>28的读取整数后的间距求和取平均输出;3  对于所有的前10个后面的整数>10和后28个后面的整数<28的,读取求和取平均输出。
另外10,28这两个数能否设计成可调的参数?

在这段话中,你的意思好象不那么明确,呵呵……如果我们把情况弄得更复杂的话,现在我们有 38 个 ion,1-10 为一组,11-27 为一组,28-38 为一组。假定我们需要算第 1 组与第 3 组的情况,按你最新的意思进行计算,便与前面的意思矛盾了。按你最新的意思,我们需要定义四个数, ion_pos_1 = 1、ion_pos_2=10、ion_pos_3=28、ion_pos_4=38。首先在 1-10 这组中,读取后面的整数 1-10 后面的数,求平均值,此乃第一种情况;在28-38这一组中,读取后面整数28-38的数,求平均值,此乃第二种情况;在1-10这一组中,读取后面整数为 28-38后面的数,加上28-38这一组中,后面整数为1-10后面的数,加和,求平均值。

应该是这样的吧……
26楼2011-02-26 09:51:54
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

阿黛拉

银虫 (小有名气)

引用回帖:
Originally posted by snoopyzhao at 2011-02-25 17:57:22:
另外,你看一下程序中给出的 fort.1,fort.2,和 fort.3 的内容。其中第一列是所谓的原子序号,第三列是第一列原子和第二列原子之间的距离。你看一下,它是否符合你的要求……

您好这是我参照您的程序修改的。对于这一行
real :: sum_1, sum_2, sum_3 ! ion_table <= 4; ion_table > 4不确定。
我在linux下运行出来的是a.out,请问window下用fortran如何编译成执行文件,我点Go的时候编译出现E:/Debug/ex.exe黑色屏幕,我输入OUTCARenter没反应,请问是什么原因?
program ex

implicit none
character(len = 128) :: line, fm
integer :: ios, len_line, i, j, ion_num, ion_tmp
real, dimension(5000) :: table
integer, dimension(5000) :: ion
integer, dimension(5000) :: ion_table ! ion in table
integer, parameter :: ion_pos = 10
real :: sum_1, sum_2, sum_3 ! ion_table <= 4; ion_table > 4
integer :: i_1, i_2, i_3

do
   read (*,'(a)', iostat = ios) line
   if (ios < 0) exit
   if (index(line, 'nearest neighbor table') /= 0) exit
end do

j = 0

do
   read (*,'(a)', iostat = ios) line
   if (ios < 0) exit
   if (index(line, 'LATTYP') /= 0) exit
   if (len(trim(line)) == 0) cycle
   len_line = len(trim(line(27))
   write(fm,'(a,i0,a)') '(', len_line/9,'(tr1,i3,tr1,f4.2))'
   read (line(27, fm) (ion_table(i), table(i), i=j+1,j+len_line/9)
   read(line, '(tr1,i3)') ion_tmp
   if (ion_tmp /= 0) ion_num = ion_tmp
   do i=j+1, j+len_line/9
      ion(i) = ion_num
   end do
   j = j + len_line/9
end do

write (*,'(i3,tr2,i3,tr2,f4.2)') (ion(i), ion_table(i), table(i), i= 1, j)

sum_1 = 0.0
sum_2 = 0.0
sum_3 = 0.0
i_1 =0
i_2 =0
i_3 =0

do i=1,j
   if (ion(i) <= ion_pos) then  ! ion <= 4
      if (ion_table(i) <= ion_pos) then ! ion_table <= 4
         sum_1 = sum_1 + table(i)
         i_1 = i_1 + 1
         write(1,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      else
         sum_3 = sum_3 + table(i) ! ion_table > 4
         i_3 = i_3 + 1
         write(3,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      end if
   else ! ion > 4
      if (ion_table(i) > (ion(j) - ion_pos)) then ! ion_table > 4
         sum_2 = sum_2 + table(i)
         i_2 = i_2 + 1
         write(2,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      else
         sum_3 = sum_3 + table(i) ! ion_table < =4
         i_3 = i_3 + 1
         write(3,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      end if
   end if
end do

write(*,*) sum(table(1:j))/j

print *, sum_1, i_1, sum_2, i_2, sum_3, i_3

write(*,*) sum_1/i_1, sum_2/i_2, sum_3/i_3

end program ex
进退有度,才不至进退维谷;宠辱皆忘,方可以宠辱不惊。
27楼2011-02-26 09:59:35
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

阿黛拉

银虫 (小有名气)

引用回帖:
Originally posted by snoopyzhao at 2011-02-26 09:51:54:
你的意思是 1-4 与 5-6 分成两组,在第一组中,后面的序号如果小于等于 4 算在第 1 种情况里;后面一组中,后面的序号大于等于 5 算在第 2 种情况里。在第一组中,后面的序号大于 4,并且小于等于 6 的算在第 ...

非常抱歉,是我犯了很严重的错误。我当时没想明白。好在程序构架不需要改动,逻辑上改一下。谢谢 呵呵
进退有度,才不至进退维谷;宠辱皆忘,方可以宠辱不惊。
28楼2011-02-26 10:04:26
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

snoopyzhao

至尊木虫 (职业作家)


小木虫(金币+0.5):给个红包,谢谢回帖交流
引用回帖:
在这段话中,你的意思好象不那么明确,呵呵……如果我们把情况弄得更复杂的话,现在我们有 38 个 ion,1-10 为一组,11-27 为一组,28-38 为一组。假定我们需要算第 1 组与第 3 组的情况,按你最新的意思进行计算,便与前面的意思矛盾了。按你最新的意思,我们需要定义四个数, ion_pos_1 = 1、ion_pos_2=10、ion_pos_3=28、ion_pos_4=38。首先在 1-10 这组中,读取后面的整数 1-10 后面的数,求平均值,此乃第一种情况;在28-38这一组中,读取后面整数28-38的数,求平均值,此乃第二种情况;在1-10这一组中,读取后面整数为 28-38后面的数,加上28-38这一组中,后面整数为1-10后面的数,加和,求平均值。

应该是这样的吧……

根据上面的意思,重新整理了一下:
CODE:
program ex

implicit none
character(len = 128) :: line, fm
integer :: ios, len_line, i, j, ion_num, ion_tmp
real, dimension(5000) :: table
integer, dimension(5000) :: ion
integer, dimension(5000) :: ion_table ! ion in table
integer, parameter :: ion_pos_1 = 1
integer, parameter :: ion_pos_2 = 10
integer, parameter :: ion_pos_3 = 28
integer, parameter :: ion_pos_4 = 38
real :: sum_1, sum_2, sum_3
integer :: i_1, i_2, i_3

do
   read (*,'(a)', iostat = ios) line
   if (ios < 0) exit
   if (index(line, 'nearest neighbor table') /= 0) exit
end do

j = 0

do
   read (*,'(a)', iostat = ios) line
   if (ios < 0) exit
   if (index(line, 'LATTYP') /= 0) exit
   if (len(trim(line)) == 0) cycle
   len_line = len(trim(line(27:)))
   write(fm,'(a,i0,a)') '(', len_line/9,'(tr1,i3,tr1,f4.2))'
   read (line(27:), fm) (ion_table(i), table(i), i=j+1,j+len_line/9)
   read(line, '(tr1,i3)') ion_tmp
   if (ion_tmp /= 0) ion_num = ion_tmp
   do i=j+1, j+len_line/9
      ion(i) = ion_num
   end do
   j = j + len_line/9
end do

write (*,'(i3,tr2,i3,tr2,f4.2)') (ion(i), ion_table(i), table(i), i= 1, j)

sum_1 = 0.0
sum_2 = 0.0
sum_3 = 0.0
i_1 =0
i_2 =0
i_3 =0

do i=1,j
   if (ion(i) >= ion_pos_1 .and. ion(i) <= ion_pos_2) then
      if (ion_table(i) >= ion_pos_1 .and. ion_table(i) <= ion_pos_2) then
         sum_1 = sum_1 + table(i)
         i_1 = i_1 + 1
         write(1,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      else if (ion_table(i) >= ion_pos_3 .and. ion_table(i) <= ion_pos_4) then
         sum_3 = sum_3 + table(i)
         i_3 = i_3 + 1
         write(3,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      end if
   else if (ion(i) >= ion_pos_3 .and. ion(i) <= ion_pos_4) then
      if (ion_table(i) >= ion_pos_3 .and. ion_table(i) <= ion_pos_4) then
         sum_2 = sum_2 + table(i)
         i_2 = i_2 + 1
         write(2,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
! the following four lines could be deleted, for they give same result as the above sum_3...
      else if (ion_table(i) >= ion_pos_1 .and. ion_table(i) <= ion_pos_2) then
         sum_3 = sum_3 + table(i)
         i_3 = i_3 + 1
         write(3,'(i3,tr2,i3,tr2,f4.2)') ion(i), ion_table(i), table(i)
      end if
   end if
end do

write(*,*) sum(table(1:j))/j

write(*,*), sum_1, i_1, sum_2, i_2, sum_3, i_3

write(*,*) sum_1/i_1, sum_2/i_2, sum_3/i_3

end program ex

29楼2011-02-26 10:13:17
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

snoopyzhao

至尊木虫 (职业作家)


小木虫(金币+0.5):给个红包,谢谢回帖交流
引用回帖:
Originally posted by 阿黛拉 at 2011-02-26 09:59:35:
您好这是我参照您的程序修改的。对于这一行
real :: sum_1, sum_2, sum_3 ! ion_table <= 4; ion_table > 4不确定。
我在linux下运行出来的是a.out,请问window下用fortran如何编译成执行文件,我点Go的 ...

你改 ! 后面的东西没有用的,那是用来注释的,为了读者能够更好的理解它,呵呵……

在 Linux 下编译出来 a.out 之后,用下面的方式运行

./a.out < OUTCAR > output

在 windows 下,我没有用过 IDE,所以,不了解你说的情况,因为这是一个命令行程序,你只能在命令行下运行它,双击应该没有什么作用的,呵呵……
30楼2011-02-26 10:24:10
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 阿黛拉 的主题更新
普通表情 高级回复(可上传附件)
信息提示
请填处理意见