(git:852b9a4)
Loading...
Searching...
No Matches
ipi_driver.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Driver mode - To communicate with i-PI Python wrapper
10!> \par History
11!> none
12!> \author Michele Ceriotti 03.2012
13! **************************************************************************************************
15 USE iso_c_binding, ONLY: c_char, &
16 c_double, &
17 c_int, &
18 c_loc, &
19 c_null_char, &
20 c_ptr
21 USE bibliography, ONLY: ceriotti2014, &
22 kapil2016, &
23 cite_reference
24 USE cell_methods, ONLY: cell_create, &
26 USE cell_types, ONLY: cell_release, &
30 USE cp_subsys_types, ONLY: cp_subsys_get, &
34 USE force_env_types, ONLY: force_env_get, &
40 USE kinds, ONLY: default_path_length, &
42 dp, &
43 int_4
47#ifndef __NO_SOCKETS
48 USE sockets_interface, ONLY: writebuffer, &
49 readbuffer, &
51 uwait
52#endif
53 USE virial_types, ONLY: virial_type
54#include "./base/base_uses.f90"
55
56 IMPLICIT NONE
57
58 PRIVATE
59
60 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ipi_driver'
61
62 PUBLIC :: run_driver
63
64CONTAINS
65
66! **************************************************************************************************
67!> \brief ...
68!> \param force_env ...
69!> \param globenv ...
70!> \par History
71!> 12.2013 included in repository
72!> \author Ceriotti
73! **************************************************************************************************
74
75 SUBROUTINE run_driver(force_env, globenv)
76 TYPE(force_env_type), POINTER :: force_env
77 TYPE(global_environment_type), POINTER :: globenv
78
79 CHARACTER(len=*), PARAMETER :: routinen = 'run_driver'
80
81#ifdef __NO_SOCKETS
82 INTEGER :: handle
83 CALL timeset(routinen, handle)
84 cpabort("CP2K was compiled with the __NO_SOCKETS option!")
85 mark_used(globenv)
86 mark_used(force_env)
87#else
88 INTEGER, PARAMETER :: msglen = 12
89
90 CHARACTER(len=default_path_length) :: c_hostname, drv_hostname, drv_prefix
91 CHARACTER(LEN=default_string_length) :: header
92 INTEGER :: drv_port, handle, i_drv_unix, &
93 idir, ii, inet, ip, iwait, &
94 nat, output_unit, socket
95 TYPE(mp_request_type), DIMENSION(2) :: wait_req
96 INTEGER(KIND=int_4), POINTER :: wait_msg(:)
97 LOGICAL :: drv_unix, fwait, hasdata, &
98 ionode, should_stop
99 REAL(kind=dp) :: cellh(3, 3), cellih(3, 3), &
100 mxmat(9), pot, vir(3, 3)
101 REAL(kind=dp), ALLOCATABLE :: combuf(:)
102 TYPE(cell_type), POINTER :: cpcell
103 TYPE(mp_para_env_type), POINTER :: para_env
104 TYPE(cp_subsys_type), POINTER :: subsys
105 TYPE(section_vals_type), POINTER :: drv_section, motion_section
106 TYPE(virial_type), POINTER :: virial
107 REAL(kind=dp) :: sleeptime
108 INTEGER, DIMENSION(3) :: perd
109 TYPE(cell_type), POINTER :: oldcell
110
111 CALL timeset(routinen, handle)
112
113 CALL cite_reference(ceriotti2014)
114 CALL cite_reference(kapil2016)
115
116! server address parsing
117! buffers and temporaries for communication
118! access cp2k structures
119
120 cpassert(ASSOCIATED(force_env))
121 CALL force_env_get(force_env, para_env=para_env)
122
123 hasdata = .false.
124 ionode = para_env%is_source()
125
126 output_unit = cp_logger_get_default_io_unit()
127
128 ! reads driver parameters from input
129 motion_section => section_vals_get_subs_vals(force_env%root_section, "MOTION")
130 drv_section => section_vals_get_subs_vals(motion_section, "DRIVER")
131
132 CALL section_vals_val_get(drv_section, "HOST", c_val=drv_hostname)
133 CALL section_vals_val_get(drv_section, "PORT", i_val=drv_port)
134 CALL section_vals_val_get(drv_section, "UNIX", l_val=drv_unix)
135 CALL section_vals_val_get(drv_section, "PREFIX", c_val=drv_prefix)
136 CALL section_vals_val_get(drv_section, "SLEEP_TIME", r_val=sleeptime)
137 cpassert(sleeptime >= 0)
138
139 ! opens the socket
140 socket = 0
141 inet = 1
142 i_drv_unix = 1 ! a bit convoluted. socket.c uses a different convention...
143 IF (drv_unix) i_drv_unix = 0
144 IF (output_unit > 0) THEN
145 WRITE (output_unit, *) "@ i-PI DRIVER BEING LOADED"
146 WRITE (output_unit, *) "@ INPUT DATA: ", trim(drv_hostname), drv_port, drv_unix
147 END IF
148
149 IF (drv_unix) THEN
150 ! for UNIX sockets, HOST names the socket file which lives at
151 ! /tmp/<PREFIX>_<HOST> (PREFIX must match the peer's convention,
152 ! e.g. "ipi" for i-PI)
153 c_hostname = "/tmp/"//trim(drv_prefix)//"_"//trim(drv_hostname)//c_null_char
154 ELSE
155 c_hostname = trim(drv_hostname)//c_null_char
156 END IF
157 IF (ionode) CALL open_connect_socket(socket, i_drv_unix, drv_port, c_hostname)
158
159 NULLIFY (wait_msg)
160 ALLOCATE (wait_msg(1))
161 !now we have a socket, so we can initialize the CP2K environments.
162 NULLIFY (cpcell)
163 CALL cell_create(cpcell)
164 driver_loop: DO
165 ! do communication on master node only...
166 header = ""
167
168 CALL para_env%sync()
169
170 ! non-blocking sync to avoid useless CPU consumption
171 IF (ionode) THEN
172 CALL readbuffer(socket, header, msglen)
173 wait_msg = 0
174 DO iwait = 0, para_env%num_pe - 1
175 IF (iwait /= para_env%source) THEN
176 CALL para_env%send(msg=wait_msg, dest=iwait, tag=666)
177 END IF
178 END DO
179 ELSE
180 CALL para_env%irecv(msgout=wait_msg, source=para_env%source, &
181 tag=666, request=wait_req(2))
182 CALL mp_testany(wait_req(2:), flag=fwait)
183 DO WHILE (.NOT. fwait)
184 CALL mp_testany(wait_req(2:), flag=fwait)
185 CALL uwait(sleeptime)
186 END DO
187 END IF
188
189 CALL para_env%sync()
190
191 CALL para_env%bcast(header)
192
193 IF (output_unit > 0) WRITE (output_unit, *) " @ DRIVER MODE: Message from server: ", trim(header)
194 IF (trim(header) == "STATUS") THEN
195
196 CALL para_env%sync()
197 IF (ionode) THEN ! does not need init (well, maybe it should, just to check atom numbers and the like... )
198 IF (hasdata) THEN
199 CALL writebuffer(socket, "HAVEDATA ", msglen)
200 ELSE
201 CALL writebuffer(socket, "READY ", msglen)
202 END IF
203 END IF
204 CALL para_env%sync()
205 ELSE IF (trim(header) == "POSDATA") THEN
206 IF (ionode) THEN
207 CALL readbuffer(socket, mxmat, 9)
208 cellh = reshape(mxmat, [3, 3])
209 CALL readbuffer(socket, mxmat, 9)
210 cellih = reshape(mxmat, [3, 3])
211 CALL readbuffer(socket, nat)
212 cellh = transpose(cellh)
213 cellih = transpose(cellih)
214 END IF
215 CALL para_env%bcast(cellh)
216 CALL para_env%bcast(cellih)
217 CALL para_env%bcast(nat)
218 IF (.NOT. ALLOCATED(combuf)) ALLOCATE (combuf(3*nat))
219 IF (ionode) CALL readbuffer(socket, combuf, nat*3)
220 CALL para_env%bcast(combuf)
221
222 CALL force_env_get(force_env, subsys=subsys)
223 IF (nat /= subsys%particles%n_els) THEN
224 cpabort("@DRIVER MODE: Uh-oh! Particle number mismatch between i-PI and cp2k input!")
225 END IF
226 ii = 0
227 DO ip = 1, subsys%particles%n_els
228 DO idir = 1, 3
229 ii = ii + 1
230 subsys%particles%els(ip)%r(idir) = combuf(ii)
231 END DO
232 END DO
233 NULLIFY (oldcell)
234 CALL cp_subsys_get(subsys, cell=oldcell)
235 perd = oldcell%perd
236
237 CALL init_cell(cpcell, hmat=cellh, periodic=perd)
238 CALL cp_subsys_set(subsys, cell=cpcell)
239
240 CALL force_env_calc_energy_force(force_env, calc_force=.true.)
241
242 IF (output_unit > 0) WRITE (output_unit, *) " @ DRIVER MODE: Received positions "
243
244 combuf = 0
245 ii = 0
246 DO ip = 1, subsys%particles%n_els
247 DO idir = 1, 3
248 ii = ii + 1
249 combuf(ii) = subsys%particles%els(ip)%f(idir)
250 END DO
251 END DO
252 CALL force_env_get(force_env, potential_energy=pot)
253 CALL force_env_get(force_env, cell=cpcell)
254 CALL cp_subsys_get(subsys, virial=virial)
255 vir = transpose(virial%pv_virial)
256
257 CALL external_control(should_stop, "IPI", globenv=globenv)
258 IF (should_stop) EXIT driver_loop
259
260 hasdata = .true.
261 ELSE IF (trim(header) == "GETFORCE") THEN
262 IF (output_unit > 0) WRITE (output_unit, *) " @ DRIVER MODE: Returning v,forces,stress "
263 IF (ionode) THEN
264 CALL writebuffer(socket, "FORCEREADY ", msglen)
265 CALL writebuffer(socket, pot)
266 CALL writebuffer(socket, nat)
267 CALL writebuffer(socket, combuf, 3*nat)
268 CALL writebuffer(socket, reshape(vir, [9]), 9)
269
270 ! i-pi can also receive an arbitrary string, that will be printed out to the "extra"
271 ! trajectory file. this is useful if you want to return additional information, e.g.
272 ! atomic charges, wannier centres, etc. one must return the number of characters, then
273 ! the string. here we just send back zero characters.
274 nat = 0
275 CALL writebuffer(socket, nat) ! writes out zero for the length of the "extra" field (not implemented yet!)
276 END IF
277 hasdata = .false.
278 ELSE
279 IF (output_unit > 0) WRITE (output_unit, *) " @DRIVER MODE: Socket disconnected, time to exit."
280 EXIT driver_loop
281 END IF
282 END DO driver_loop
283
284 ! clean up
285 CALL cell_release(cpcell)
286 DEALLOCATE (wait_msg)
287#endif
288
289 CALL timestop(handle)
290
291 END SUBROUTINE run_driver
292END MODULE ipi_driver
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public kapil2016
integer, save, public ceriotti2014
Handles all functions related to the CELL.
subroutine, public init_cell(cell, hmat, periodic)
Initialise/readjust a simulation cell after hmat has been changed.
subroutine, public cell_create(cell, hmat, periodic, tag)
allocates and initializes a cell
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public cell_release(cell)
releases the given cell (see doc/ReferenceCounting.html)
Definition cell_types.F:668
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_set(subsys, atomic_kinds, particles, local_particles, molecules, molecule_kinds, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, results, cell, cell_ref, use_ref_cell)
sets various propreties of the subsys
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell)
returns information about various attributes of the given subsys
Interface for the force calculations.
recursive subroutine, public force_env_calc_energy_force(force_env, calc_force, consistent_energies, skip_external_control, eval_energy_forces, require_consistent_energy_force, linres, calc_stress_tensor)
Interface routine for force and energy calculations.
Interface for the force calculations.
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env, ipi_env)
returns various attributes about the force environment
Define type storing the global information of a run. Keep the amount of stored data small....
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Driver mode - To communicate with i-PI Python wrapper.
Definition ipi_driver.F:14
subroutine, public run_driver(force_env, globenv)
...
Definition ipi_driver.F:76
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
integer, parameter, public int_4
Definition kinds.F:51
Interface to the message passing library MPI.
Implements UNIX and INET sockets.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
represents a system: atoms, molecules, their pos,vel,...
wrapper to abstract the force evaluation of the various methods
contains the initially parsed file and the initial parallel environment
stores all the informations relevant to an mpi environment