如何将$ n $粒子之间的距离保持在一定范围内?

时间:2016-03-26 04:02:33

标签: algorithm fortran graph-algorithm fortran90 fortran77

我正在研究分子动力学中的一个问题,需要在一个大小为[-L,L] x [-L,L]的盒子中随机生成np粒子的位置数组。实际上,我需要为x坐标生成x-数组,x(1)= 0,y-坐标的y-数组为y(1)= y(2)= 0。我需要粒子使得相邻粒子之间的距离在一定范围内(例如:0.9 <= r <= 1.1),如下图所示: enter image description here

但是在我的代码中我得到这样的东西: enter image description here

看看红线是如何大于我想要的。

我的代码是

REAL, DIMENSION(np) :: x, y
REAL :: w1, w2, minv, maxv, xij, yij, rij
INTEGER :: i, j

!Generating random coordinates for the particles
x(1) = 0.0d0
y(1) = 0.0d0
y(2) = 0.0d0
!-------------------------------------------------------------------------  
! translation and rotaion of the whole system were froze (saving 4 degrees of
! freedome)
! x(1) = 0.0d0; y(1) = 0.0d0    fix one particle in the origin
! y(2) = 0.0d0              fix the second particle on the x-axis
!-------------------------------------------------------------------------

rmatrix = 100.0
minv = 0.0
maxv = 10
iter0 = 0
101 DO WHILE(maxv >= 1.1 .OR. minv <= 0.9) 
iter0 = iter0 + 1
PRINT *, iter0
    CALL init_random_seed()
    DO i = 2, np
        CALL RANDOM_NUMBER(w1)
        x(i) = 10 * w1 - 5
    END DO
    DO i = 3, np
        CALL RANDOM_NUMBER(w2)
        y(i) = 10 * w2 - 5
    END DO
! rmatrix contains the distances between all particles 
    DO i = 1, np
        DO j = 1, np
            IF(j .NE. i) THEN
                xij = x(i) - x(j)
                yij = y(i) - y(j)
                rij = SQRT(xij * xij + yij * yij)
                rmatrix(i,j) = rij
            END IF
        END DO
    END DO
    minv = MINVAL(rmatrix) ! This is the minimum distance between any two 
                          ! particles ( distance cannot be smaller)
                          ! which is the left endpoint of the range interval
    DO i = 1, np     ! Here is my attempt to control the righ endpoint of          
        DO j = 1, np  ! the range interval. ( This needs to be edited)
            IF(j .NE. i) THEN
                maxv = MIN(maxv, rmatrix(i,j))
            END IF
        END DO
        IF(maxv >= 1.1) THEN
            GOTO 101
        END IF
    END DO
END DO

CONTANIS
      SUBROUTINE init_random_seed()
        INTEGER :: i, n, clock
        INTEGER, DIMENSION(:), ALLOCATABLE :: seed

        CALL RANDOM_SEED(size = n)
        ALLOCATE(seed(n))

        CALL SYSTEM_CLOCK(COUNT=clock)

        seed = clock + 37 * (/ (i - 1, i = 1, n) /)

        CALL RANDOM_SEED(PUT = seed)

      END SUBROUTINE init_random_seed

0 个答案:

没有答案