2015-04-13 1 views
0

Прежде всего, я полный новичок в FORTRAN. С учетом сказанного я пытаюсь «построить» ящик, затем произвольно генерировать координаты x, y, z для 100 атомов. Оттуда цель состоит в том, чтобы вычислить расстояние между каждым атомом, которое становится значением «r» уравнения потенциальной энергии Леннарда-Джонса. Затем вычислите потенциал LJ и, наконец, суммируйте потенциал всей коробки. Предыдущий вопрос, который я задал об этом проекте, - here. Проблема в том, что я получаю одно и то же вычисляемое значение снова и снова. Мой код ниже.Цикл счетчика FORTRAN возвращает несколько итераций того же значения

program energytot 
    implicit none 

    integer, parameter :: n = 100 
    integer :: i, j, k, seed(12) 
    double precision :: sigma, r, epsilon, lx, ly, lz 
    double precision, dimension(n) :: x, y, z, cx, cy, cz 
    double precision, dimension(n*(n+1)/2) :: dx, dy, dz, LJx, LJy, LJz 
    sigma = 4.1 
    epsilon = 1.7 
    !Box length with respect to the axis 
    lx = 15 
    ly = 15 
    lz = 15 

    do i=1,12 
     seed(i)=i+3 
    end do 
    !generate n random numbers for x, y, z 
    call RANDOM_SEED(PUT = seed) 
    call random_number(x) 
    call random_number(y) 
    call random_number(z) 
    !convert random numbers into x, y, z coordinates 
    cx = ((2*x)-1)*(lx*0.5) 
    cy = ((2*y)-1)*(lx*0.5) 
    cz = ((2*z)-1)*(lz*0.5) 

    do j=1,n-1 
     do k=j+1,n 
      dx = ABS((cx(j) - cx(k))) 
      LJx = 4 * epsilon * ((sigma/dx(j))**12 - (sigma/dx(j))**6) 
      dy = ABS((cy(j) - cy(k))) 
      LJy = 4 * epsilon * ((sigma/dy(j))**12 - (sigma/dy(j))**6) 
      dz = ABS((cz(j) - cz(k))) 
      LJz = 4 * epsilon * ((sigma/dz(j))**12 - (sigma/dz(j))**6) 
     end do 
    end do 

    print*, dx 
    end program energytot 
+0

Я перестроенный свой код таким образом, что я не использую массив. Мой вопрос в основном спорный –

ответ

1

В чем ваш вопрос? Что вы хотите, чтобы ваш код делал, и что он делает вместо этого?

Если у вас возникли проблемы с утверждением окончательного печати print*, dx, попробуйте вместо этого:

print *, 'dx = ' 
    do i = 1, n * (n + 1)/2 
    print *, dx(i) 
    end do 

кажется, что ах слишком велика, чтобы быть распечатаны без петли.

Кроме того, похоже, что вы повторно назначаете массив dx (и другие массивы в цикле) на одно значение. Попробуйте вместо этого:

i = 0 
    do j=1,n-1 
     do k=j+1,n 
      i = i + 1 
      dx(i) = ABS((cx(j) - cx(k))) 
     end do 
    end do 

Таким образом, каждое значение cx(j) - cx(k) сохранялось на другой элемент dx, а не перезаписывать ранее сохраненные значения.

+0

добавление «i» помогло с первоначальной проблемой. Позднее я столкнулся с ними и в конечном итоге полностью удалил массив –

0

Мой новый код выглядит примерно так:

program energytot 
    implicit none 

    integer, parameter :: n = 6 
    integer :: i, j, k, seed(12) 
    double precision :: sigma, r, epsilon, lx, ly, lz, etot, pot, rx, ry, rz 
    double precision, dimension(n) :: x, y, z, cx, cy, cz 
    sigma = 4.1 
    epsilon = 1.7 
    etot=0 
    !Box length with respect to the axis 
    lx = 15 
    ly = 15 
    lz = 15 

    do i=1,12 
     seed(i)=i+90 
    end do 
    !generate n random numbers for x, y, z 
    call RANDOM_SEED(PUT = seed) 
    call random_number(x) 
    call random_number(y) 
    call random_number(z) 
    !convert random numbers into x, y, z coordinates 
    cx = ((2*x)-1)*(lx*0.5) 
    cy = ((2*y)-1)*(lx*0.5) 
    cz = ((2*z)-1)*(lz*0.5) 

    do j=1,n-1 
     do k=j+1,n 
      rx = (cx(j) - cx(k)) 
      ry = (cy(j) - cy(k)) 
      rz = (cz(j) - cz(k)) 
      !Apply minimum image convention 
      rx=rx-lx*anint(rx/lx) 
      ry=ry-ly*anint(ry/ly) 
      rz=rz-lz*anint(rz/lz) 

      r=sqrt(rx**2+ry**2+rz**2) 
      pot=4 * epsilon * ((sigma/r)**12 - (sigma/r)**6) 
      print*,pot 
      etot=etot+pot 

     end do 
    end do 

    print*, etot 

    end program energytot 
Смежные вопросы