“了解分子模拟:从算法到应用程序”中有关分子动力学代码的问题

时间:2019-02-12 06:46:14

标签: fortran

您需要先阅读本书才能回答我的问题。

-背景- 我正在尝试学习《分子动力学》,并且从应该被介绍的书籍开始,但是在理解方程式或它们的解释时遇到了很多麻烦。我已经尝试了6到7本书,从介绍性章节开始,然后翻阅本书中的代码,我可以复制这些代码,以便为方程提供一些上下文,因为我无法理解它们。很明显,他们希望您具有很多先决的物理知识(似乎特别是MD知识),以了解方程式如何转换为一段代码。我参加了物理课程和3D物理引擎课程,但是这些知识对这项工作没有帮助。我唯一能找到的代码在“了解分子模拟:从算法到应用程序” 中,我对此有一些疑问,我在书中找不到答案。 如果您有任何对初学者更友好的先决条件书籍或课程,可以帮助我了解本书的背景材料,那就太棒了-背景知识-

这正是代码在书中的显示方式,我读到您应该在主程序结束后放置子例程,这就是我所做的。因为我只能找到处理非常小的代码段的fortran教程,所以我不确定是否应该在所有地方都使用stopendreturn它显示在这里,如果implicit none应该在其中,并且我应该将每个子例程放在不同的文件或类似的文件中。 循环与python中的循环基本相同,因此我已经可以理解一些代码了,但是我看不到大图。

我面临的主要问题是,我在书中的任何地方都没有声明过我使用的许多变量(尽管我找到了关于它们代表某些变量的解释),这可能就是程序无法运行的原因。我收到此错误消息“启动失败。找不到二进制文件。”

如何声明变量delttmaxf(force),en(energy),ranflattice_posxvtempxmdtxrboxr2i,{ {1}},r6iffxx?其中一些甚至可能不是变量,但我不认为它们是内置在fortran中的,因为我找不到关于它们的任何信息。另外我猜tmax与npart(N个粒子)的数目相同,所以为什么他们要使用2个不同的变量?

这些变量是什么意思? (我可以找到的vif除外)

每个原子的x,y,z坐标存储在哪里?我假设它们将存储在1个列表(或fortran中的等效项)中,每个列表包含3个值(对于x,y,z)或3个包含每个列表中所有x,y,z坐标的列表,在en子例程中。但是,情况并非如此,因为仅initx被循环通过。

在子例程的开头立即将v设置为0时,为什么enforce()的输入?您不能在没有输入的情况下在函数内部声明它吗?

program main
call init

t=0
do while (t.lt.tmax)
call force(f,en)
call integrate(f,en)
t=t+delt
call sample
enddo
stop
end

subroutine init
sumv=0
sumv2=0
do i=1, npart
    x(i)=lattice_pos(i)
    v(i)=(ranf()-0.5)
    sumv=sumv+v(1)
    sumv2=sumv2+v(i)**2
enddo
sumv=sumv/npart
sumv2=sumv2/npart
fs=sqrt(3*temp/sumv2)
do i=1,npart
    v(i)=(v(i)-sumv)*fs
    xm(i)=x(i)-v(i)*dt
enddo
return

subroutine force(f, en)
en=0
do i=1, npart-1
    do j=i+1, npart
        xr=xr-box*nint(xr/box)
        r2=xr**2
        if (r2.lt.rc2) then
            r2i=1/r2
            r6i=r2i**3
            ff=48*r2i*r6i*(r6i-0.5)
            f(i)=f(i)+ff*xr
            f(j)=f(j)-ff*xr
            en=en+4*r6i*(r6i-1)-ecut
        endif
    enddo
enddo
return
end

subroutine integrate(f,en)
sumv=0
sumv2=0
dp i=1,npart
    xx=2*x(i)-xm(i)+delt**2*f(i)
    vi=(xx-xm(i))/(2*delt)
    sumv=sumv+vi
    sumv2=sumv2+vi**2
    xm(i)=x(i)
    x(i)=xx
enddo
temp=sumv2/(3*npart)
etot=(en+0.5*sumv2)/npart
return
end
    implicit none
end program main

1 个答案:

答案 0 :(得分:3)

与许多其他教科书一样,“理解分子模拟:从算法到应用程序”中的示例代码是伪代码。它不完整(例如,缺少声明),并且比“仅是数学”要更明确地说明算法。本书令人困惑,因为他们为伪代码编写了不完整的Fortran。

这仍然是一个很好的“一般问题”:了解如何使用带有Fortran的老式教科书材料:-)

http://www.acmm.nl/molsim/frenkel_smit/index.html(阿姆斯特丹多尺度建模中心网站)上,您可以找到本书http://www.acmm.nl/molsim/frenkel_smit/README.html的实际Fortran代码,正如伊恩·布什(Ian Bush)所写的那样,该代码是老式的,艾伦和蒂尔德斯利本书有更新的更新的代码:https://github.com/Allen-Tildesley/

关于您的问题:

  1. 如何声明变量delt,tmax,f(force),en(energy),ranf,lattice_pos,x,v,temp,xm,dt,xr,box,r2i,r6i,ff, xx和vi?其中一些甚至可能不是变量,但我不认为它们是内置在fortran中的,因为我找不到关于它们的任何信息。另外我猜tmax与npart(N个粒子)的数目相同,所以为什么他们要使用2个不同的变量?

    您必须阅读有关算法的章节才能理解变量。但是,它们的列表在本书的“ xxi”页面上。

  2. 每个原子的x,y,z坐标存储在哪里?我假设它们将存储在1个列表(或fortran中的等效项)中,每个列表包含3个值(对于x,y,z)或3个包含每个列表中所有x,y,z坐标的列表,在init子例程中。但是事实并非如此,因为只有x和v循环通过。

    在这里,伪代码还是有限制的。您可以使用多个选项来声明变量:(i)作者(请参见上面的文件链接)使用“公共块”,这是Fortran特定类型的全局变量。 (ii)在Fortran 90及更高版本中可用的模块变量是“更好的全局变量”。 (iii)将所有数据封装为可在主程序中声明的派生类型中,然后传递给子例程。

    位置(在示例中)存储为数组x(npmax)y(npmax)z(npmax)npmax是最大粒子数。伪代码中未显示。请注意,在最新版本的Fortran(90及更高版本)中,您可以编写矢量操作,例如x = x + v*dt(其中x和v是 all 粒子的位置和速度,而dt是标量时间步)。

  3. 当在子例程开始时立即将其设置为0时,为什么要输入force()?您不能在没有输入的情况下在函数内部声明它吗?

    在Fortran中,传递需要更新的变量作为子例程的参数是常见的,但不是强制性的。编程样式各不相同。