본문 바로가기

LIGGGHTS

Atom은 죽지 않는다. ID를 남길 뿐이다.

LIGGGHTS에서 Atom은 생성되면서 고유의 ID를 부여 받는다. 그리고 Atom은 box를 벗어나면 사라지게 된다. 이 과정에서 Atom의 ID가 rearrage되는가? 그렇지 않다.

이번 포스팅은 이로 인한 문제들을 살펴보도록 하자.

 

먼저, 예제를 보면 왼쪽부터 오른쪽으로 순차적으로 생성된 총 10개의 Atom들이다. 따라서, 왼쪽이 1번 그리고 제일 오른쪽이 10번 Atom이 되겠다.

1번과 10번 Atom이 결국 box밖으로 떨어지므로 남은 Atom은 총 8개이다.

따라서, Atom의 총 개수를 찾으면 8개로 나온다. Atom의 총 개수는 variable로 찾을 수 있다.

variable                   N_atoms equal count(all)

print                      "                       "
print                      "=== PRINT LIVE ATOMS ==="
print                      "N_atoms is = ${N_atoms}"

출력되는 결과는?

N_atoms is = 8

2개가 사라졌으므로, 총 8개의 Atom으로 표시된다. 그렇다면 8개의 Atom으로 loop를 돌리면 어떻게 될까?

### Scan atoms
variable                   N_atoms equal count(all)

print                      "                       "
print                      "=== PRINT LIVE ATOMS ==="
print                      "N_atoms is = ${N_atoms}"


label                      loop_atoms
variable                   index_i loop ${N_atoms}
     variable              posx equal c_atom_x[${index_i}]
     variable              posy equal c_atom_y[${index_i}]
     variable              posz equal c_atom_z[${index_i}]     
     variable              rad  equal c_cal_radius[${index_i}]
     print                 "${index_i}, ${posx}, ${posy}, ${posz}, ${rad}"

next                       index_i
jump                       v_test_1.in loop_atoms

Atom은 사라져도 ID는 남아있다. 그러므로 2번 부터 9번까지의 Atom이 살아 있으나, Loop를 돌리는 경우 1부터 8개의 Atom을 스캔하게 된다.

=== PRINT LIVE ATOMS ===
N_atoms is = 8
1, 0, 0, 0, 0
2, -0.011, 0, -0.014000343143064, 0.001
3, -0.008, 0, -0.0140003220179652, 0.001
4, -0.005, 0, -0.014000343143064, 0.001
5, -0.002, 0, -0.0140003220179652, 0.001
6, 0.001, 0, -0.014000343143064, 0.001
7, 0.004, 0, -0.0140003220179652, 0.001
8, 0.007, 0, -0.014000343143064, 0.001

사라진 ID의 Atom을 스캔하여도 error는 발생하지 않는다. 다만, per-atom peroperties들이 0으로 나타나게 된다. 추후 이를 이용한 계산을 하는 경우 에러가 발생한다.

그렇다면 생성된 Atom의 ID를 초과해서 Loop를 돌리면 어떻게 될까?

print                      "                       "
print                      "=== PRINT ALL ATOMS ==="


label                      loop_atoms1
variable                   index_j loop 11
     variable              posx equal c_atom_x[${index_j}]
     variable              posy equal c_atom_y[${index_j}]
     variable              posz equal c_atom_z[${index_j}]     
     print                 "${index_j}, ${posx}, ${posy}, ${posz}"
next                       index_j
jump                       v_test_1.in loop_atoms1

애초에 생성하지 않았던 11번 ID까지도 에러가 발생하지 않음을 알 수 있다.

=== PRINT ALL ATOMS ===
1, 0, 0, 0
2, -0.011, 0, -0.014000343143064
3, -0.008, 0, -0.0140003220179652
4, -0.005, 0, -0.014000343143064
5, -0.002, 0, -0.0140003220179652
6, 0.001, 0, -0.014000343143064
7, 0.004, 0, -0.0140003220179652
8, 0.007, 0, -0.014000343143064
9, 0.01, 0, -0.0140003220179652
10, 0, 0, 0
11, 0, 0, 0

그렇다면, write_data 후 read_data로 살아있는 Atom들만 불러 들이면 안될까?

write_data                 atoms.info

그럴리가, 살아있는 8개의 Atom정보만 저장이 되지만, Atom ID는 2부터 8로 살아있는 아이디만 저장된다.

LAMMPS data file via write_data, version Version LIGGGHTS-PUBLIC 3.8.0, compiled 2023-04-24-22:04:34 by jinsun, git commit 5207ed861b1351eb03ccd7bc4c4e612b00c8ff56, timestep = 20000

8 atoms
2 atom types

-1.0000000000000001e-01 1.0000000000000001e-01 xlo xhi
-1.0000000000000001e-01 1.0000000000000001e-01 ylo yhi
-2.9999999999999999e-02 8.0000000000000002e-02 zlo zhi

Atoms

2 1 2.0000000000000000e-03 2.2000000000000000e+03 -1.0999999999999999e-02 0.0000000000000000e+00 -1.4000343143064004e-02 0 0 0
3 1 2.0000000000000000e-03 1.9999999999999998e+03 -8.0000000000000002e-03 0.0000000000000000e+00 -1.4000322017965205e-02 0 0 0
4 1 2.0000000000000000e-03 2.2000000000000000e+03 -5.0000000000000001e-03 0.0000000000000000e+00 -1.4000343143064004e-02 0 0 0
5 1 2.0000000000000000e-03 1.9999999999999998e+03 -2.0000000000000000e-03 0.0000000000000000e+00 -1.4000322017965205e-02 0 0 0
9 1 2.0000000000000000e-03 1.9999999999999998e+03 1.0000000000000000e-02 0.0000000000000000e+00 -1.4000322017965205e-02 0 0 0
6 1 2.0000000000000000e-03 2.2000000000000000e+03 1.0000000000000000e-03 0.0000000000000000e+00 -1.4000343143064004e-02 0 0 0
7 1 2.0000000000000000e-03 1.9999999999999998e+03 4.0000000000000001e-03 0.0000000000000000e+00 -1.4000322017965205e-02 0 0 0
8 1 2.0000000000000000e-03 2.2000000000000000e+03 7.0000000000000001e-03 0.0000000000000000e+00 -1.4000343143064004e-02 0 0 0

Velocities

2 0.0000000000000000e+00 0.0000000000000000e+00 -6.4971997710591412e-16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
3 0.0000000000000000e+00 0.0000000000000000e+00 -1.3710669630574993e-14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
4 0.0000000000000000e+00 0.0000000000000000e+00 -6.4971997710591412e-16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
5 0.0000000000000000e+00 0.0000000000000000e+00 -1.3710669630574993e-14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
9 0.0000000000000000e+00 0.0000000000000000e+00 -1.3710669630574993e-14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
6 0.0000000000000000e+00 0.0000000000000000e+00 -6.4971997710591412e-16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
7 0.0000000000000000e+00 0.0000000000000000e+00 -1.3710669630574993e-14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00
8 0.0000000000000000e+00 0.0000000000000000e+00 -6.4971997710591412e-16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00

그렇다면 어떻게 손쉽게 남아있는 Atom으로 Loop를 돌릴 수 있을까?

먼저 남아있는 Atom의 최대 ID를 찾아보자.

variable                   id_max atom id
dump                       print_id all custom 1 atk.deb id v_id_max

variable은 id attribute로 atom vector값을 얻을 수 있다. 따라서 dump를 통해 출력하여야 한다.

또한, dump는 attribute로 id를 지원한다. 위의 코드는 두가지 형태를 모두 출력한다.

step에 따라 다음과 같은 출력 결과를 얻을 수 있다.

ITEM: ATOMS id v_id_max 
1 1 
2 2 
3 3 
4 4 
5 5 
6 6 
7 7 
8 8 
9 9 
10 10

초반에는 10개의 Atom이 모두 살아있다.

ITEM: ATOMS id v_id_max 
2 2 
3 3 
4 4 
5 5 
9 9 
6 6 
7 7 
8 8

box 밖으로 사라지면 8개만 남는다. 최대 ID는 9번 이다.

그렇다면? Compute reduce를 이용하여 Maximum ID를 찾아 Loop를 돌리면 되지 않는가?

###
variable                   id_max atom id
dump                       print_id all custom 1 atk.deb id v_id_max

compute                    max_id all reduce update_on_run_end yes max v_id_max
variable                   max_atom_id equal c_max_id

이렇게,

그리고 Looping중 사라진 Atom을 제외하려면, mass가 0인 Atom만 골라내면 되겠다.

label                      loop_atoms2
variable                   index_k loop ${max_atom_id}
     variable ak1 equal c_cal_mass[${index_k}]
    if "${ak1} != 0" then &
     "variable              posx equal c_atom_x[${index_k}]" &
     "variable              posy equal c_atom_y[${index_k}]" &
     "variable              posz equal c_atom_z[${index_k}]" &
     "print                 '${index_k}, ${posx}, ${posy}, ${posz}'"
next                       index_k
jump                       v_test_1.in loop_atoms2

Cool!

=== PRINT REAL ATOMS ===
2, -0.011, 0, -0.014000343143064
3, -0.008, 0, -0.0140003220179652
4, -0.005, 0, -0.014000343143064
5, -0.002, 0, -0.0140003220179652
6, 0.001, 0, -0.014000343143064
7, 0.004, 0, -0.0140003220179652
8, 0.007, 0, -0.014000343143064
9, 0.01, 0, -0.0140003220179652

'LIGGGHTS' 카테고리의 다른 글

여러가지 findings  (0) 2023.08.19
GranWall에 작용하는 Force의 추출  (0) 2023.08.17
write_data and read_data  (0) 2023.08.07
Variable of variable  (1) 2023.08.05
Atom style variable의 연산  (0) 2023.08.01