(git:e5b1968)
Loading...
Searching...
No Matches
ace_nlist.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \par History
10!> HAF (16-Apr-2025) : Import into CP2K
11!> \author HAF and yury-lysogorskiy and ralf-drautz
12! **************************************************************************************************
13
15
17 USE cell_types, ONLY: cell_type
24 USE kinds, ONLY: dp
25 USE physcon, ONLY: angstrom
26#include "./base/base_uses.f90"
27
28 IMPLICIT NONE
29
30 PRIVATE
31 PUBLIC ace_interface
32
33 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ace_nlist'
34
35CONTAINS
36
37!
38!-------------------------------------------------------------------------------------
39
40! **************************************************************************************************
41!> \brief ...
42!> \param ace_natom ...
43!> \param ace_atype ...
44!> \param pot_ace ...
45!> \param ace_force ...
46!> \param ace_virial ...
47!> \param fist_nonbond_env ...
48!> \param cell ...
49!> \param ace_data ...
50! **************************************************************************************************
51 SUBROUTINE ace_interface(ace_natom, ace_atype, pot_ace, ace_force, ace_virial, &
52 fist_nonbond_env, cell, ace_data)
53
54 INTEGER, INTENT(IN) :: ace_natom, ace_atype(1:ace_natom)
55 REAL(kind=dp), INTENT(OUT) :: pot_ace, ace_force(1:3, 1:ace_natom), &
56 ace_virial(1:6)
57 TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env
58 TYPE(cell_type), POINTER :: cell
59 TYPE(ace_data_type), POINTER :: ace_data
60
61#if defined(__ACE)
62 INTEGER :: atom_a, atom_b, counter, ilist, k, m, n, &
63 natom, nghost, num_update
64 INTEGER, ALLOCATABLE, DIMENSION(:) :: ghostidx, listidx
65 REAL(kind=8), allocatable :: forceunroll(:)
66 REAL(kind=dp) :: cell_v(3), dv(1:3), energy(1:ace_natom)
67 TYPE(fist_neighbor_type), POINTER :: nonbonded
68 TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair
69 TYPE(pos_type), DIMENSION(:), POINTER :: r_last_update_pbc
70
71 natom = ace_natom
72
73 CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, &
74 r_last_update_pbc=r_last_update_pbc, &
75 num_update=num_update, counter=counter)
76
77 IF ((counter == 1) .OR. (ace_data%refupdate /= num_update)) THEN
78 ! fist neighborlist are new:
79 ace_data%refupdate = num_update
80
81 IF (.NOT. ALLOCATED(ace_data%neiat)) THEN
82 ALLOCATE (ace_data%neiat(0:natom))
83 ELSE
84 cpassert(SIZE(ace_data%neiat) > natom)
85 END IF
86
87 !if more than one mpi task, some neighorlists might be empty
88 !do we need to check for lone atoms?
89 ALLOCATE (ghostidx(natom), listidx(natom))
90 nghost = 0
91 ace_data%neiat(:) = 0
92 ace_data%nei = 0
93 DO n = 1, SIZE(nonbonded%neighbor_kind_pairs)
94 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(n)
95 IF (neighbor_kind_pair%npairs > 0) THEN
96 IF ((neighbor_kind_pair%cell_vector(1) == 0) .AND. &
97 (neighbor_kind_pair%cell_vector(2) == 0) .AND. &
98 (neighbor_kind_pair%cell_vector(3) == 0)) THEN
99 DO ilist = 1, natom
100 ghostidx(ilist) = ilist
101 END DO
102 ELSE
103 ghostidx = 0
104 END IF
105 DO ilist = 1, neighbor_kind_pair%npairs
106 atom_a = ace_data%inverse_index_map(neighbor_kind_pair%list(1, ilist))
107 atom_b = ace_data%inverse_index_map(neighbor_kind_pair%list(2, ilist))
108 IF ((atom_a == 0) .OR. (atom_b == 0)) cycle
109 ace_data%neiat(atom_a) = ace_data%neiat(atom_a) + 1
110 IF (ghostidx(atom_b) == 0) THEN
111 ! new ghost
112 nghost = nghost + 1
113 ghostidx(atom_b) = nghost + natom
114 END IF
115 END DO
116 END IF
117 END DO
118 ! build running sum
119 DO n = 1, natom
120 ace_data%neiat(n) = ace_data%neiat(n) + ace_data%neiat(n - 1)
121 END DO
122 ace_data%nei = ace_data%neiat(natom)
123 ace_data%nghost = nghost
124
125 IF (ALLOCATED(ace_data%nlist)) THEN
126 IF (SIZE(ace_data%nlist) < ace_data%nei) THEN
127 DEALLOCATE (ace_data%nlist)
128 ALLOCATE (ace_data%nlist(1:ace_data%nei))
129 END IF
130 ELSE
131 ALLOCATE (ace_data%nlist(1:ace_data%nei))
132 END IF
133
134 IF (ALLOCATED(ace_data%attype)) THEN
135 IF (SIZE(ace_data%attype) < natom + nghost) THEN
136 DEALLOCATE (ace_data%atpos)
137 DEALLOCATE (ace_data%attype)
138 DEALLOCATE (ace_data%origin)
139 DEALLOCATE (ace_data%shift)
140 ALLOCATE (ace_data%atpos(1:3, 1:natom + nghost))
141 ALLOCATE (ace_data%attype(1:natom + nghost))
142 ALLOCATE (ace_data%origin(1:natom + nghost))
143 ALLOCATE (ace_data%shift(1:3, 1:natom + nghost))
144 END IF
145 ELSE
146 ALLOCATE (ace_data%atpos(1:3, 1:natom + nghost))
147 ALLOCATE (ace_data%attype(1:natom + nghost))
148 ALLOCATE (ace_data%origin(1:natom + nghost))
149 ALLOCATE (ace_data%shift(1:3, 1:natom + nghost))
150 END IF
151 ace_data%attype(1:natom) = ace_atype(:)
152
153 DO n = 1, natom
154 ace_data%atpos(:, n) = r_last_update_pbc(ace_data%use_indices(n))%r*angstrom
155 ace_data%origin(n) = n
156 END DO
157 ace_data%shift(:, :) = 0
158
159 k = natom
160 listidx(1:natom) = ace_data%neiat(0:natom - 1)
161 DO n = 1, SIZE(nonbonded%neighbor_kind_pairs)
162 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(n)
163 IF (neighbor_kind_pair%npairs > 0) THEN
164 IF ((neighbor_kind_pair%cell_vector(1) == 0) .AND. &
165 (neighbor_kind_pair%cell_vector(2) == 0) .AND. &
166 (neighbor_kind_pair%cell_vector(3) == 0)) THEN
167 DO m = 1, natom
168 ghostidx(m) = m
169 END DO
170 ELSE
171 ghostidx = 0
172 END IF
173 dv = real(neighbor_kind_pair%cell_vector, kind=dp)
174 ! dimensions it's not periodic with should be zero in cell_vector
175 ! so should always be valid:
176 cell_v = matmul(cell%hmat, dv)*angstrom
177 DO ilist = 1, neighbor_kind_pair%npairs
178 atom_a = ace_data%inverse_index_map(neighbor_kind_pair%list(1, ilist))
179 atom_b = ace_data%inverse_index_map(neighbor_kind_pair%list(2, ilist))
180 IF ((atom_a == 0) .OR. (atom_b == 0)) cycle
181 IF (ghostidx(atom_b) == 0) THEN
182 k = k + 1
183 ace_data%atpos(:, k) = ace_data%atpos(:, atom_b) + cell_v
184 ace_data%shift(:, k) = neighbor_kind_pair%cell_vector
185 ace_data%origin(k) = atom_b
186 ace_data%attype(k) = ace_atype(atom_b)
187 ghostidx(atom_b) = k
188 END IF
189 listidx(atom_a) = listidx(atom_a) + 1
190 ace_data%nlist(listidx(atom_a)) = ghostidx(atom_b)
191 END DO
192 END IF
193 END DO
194
195 DEALLOCATE (ghostidx)
196 DEALLOCATE (listidx)
197
198! transforming to c call
199! -> atom index will change from 1...n to 0...n-1 -> subtract 1 from neighborlist
200 ace_data%nlist(1:ace_data%nei) = ace_data%nlist(1:ace_data%nei) - 1
201 ace_data%origin(1:natom + nghost) = ace_data%origin(1:natom + nghost) - 1
202!-----------------------------------------------
203
204 ELSE ! no changes in neighbor list just update positions:
205 nghost = ace_data%nghost
206 DO n = 1, natom
207 ace_data%atpos(:, n) = r_last_update_pbc(ace_data%use_indices(n))%r*angstrom
208 END DO
209 DO n = natom + 1, natom + nghost
210 dv = real(ace_data%shift(:, n), kind=dp)*angstrom
211 !origin+1 since we already changed to C notation for origin:
212 ace_data%atpos(:, n) = ace_data%atpos(:, ace_data%origin(n) + 1) + matmul(cell%hmat, dv)
213 END DO
214 END IF
215
216! -> force array
217 ALLOCATE (forceunroll(1:3*natom))
218 forceunroll = 0.0
219 pot_ace = 0.0
220 ace_virial = 0.0
221
222 CALL ace_model_compute( &
223 natomc=natom, &
224 nghostc=nghost, &
225 neic=ace_data%nei, &
226 neiatc=ace_data%neiat, &
227 originc=ace_data%origin, &
228 nlistc=ace_data%nlist, &
229 attypec=ace_data%attype, &
230 atposc=reshape(ace_data%atpos, (/3*(natom + nghost)/)), &
231 forcec=forceunroll, &
232 virialc=ace_virial, &
233 energyc=energy, &
234 model=ace_data%model)
235
236 ace_force = reshape(forceunroll, (/3, natom/))
237 pot_ace = sum(energy(1:natom))
238
239 DEALLOCATE (forceunroll)
240
241#else
242 mark_used(ace_natom)
243 mark_used(ace_atype)
244 mark_used(pot_ace)
245 mark_used(ace_force)
246 mark_used(ace_virial)
247 mark_used(fist_nonbond_env)
248 mark_used(cell)
249 mark_used(ace_data)
250 cpabort("CP2K was compiled without ACE library.")
251#endif
252
253 END SUBROUTINE ace_interface
254
255!----------------------------------------------------------------------------------
256
257END MODULE ace_nlist
Interface to ACE C wrapper.
Definition ace_wrapper.F:12
subroutine, public ace_model_compute(natomc, nghostc, neic, neiatc, originc, nlistc, attypec, atposc, forcec, virialc, energyc, model)
...
Handles all functions related to the CELL.
Definition cell_types.F:15
Define the neighbor list data types and the corresponding functionality.
subroutine, public fist_nonbond_env_get(fist_nonbond_env, potparm14, potparm, nonbonded, rlist_cut, rlist_lowsq, aup, lup, ei_scale14, vdw_scale14, shift_cutoff, do_electrostatics, r_last_update, r_last_update_pbc, rshell_last_update_pbc, rcore_last_update_pbc, cell_last_update, num_update, last_update, counter, natom_types, long_range_correction, ij_kind_full_fac, eam_data, quip_data, nequip_data, allegro_data, deepmd_data, ace_data, charges)
sets a fist_nonbond_env
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
Type defining parameters related to the simulation cell.
Definition cell_types.F:55