(git:374b731)
Loading...
Searching...
No Matches
cp2k_shell.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Interactive shell of CP2K
10!> \note
11!> sample of a simple runner that uses the f77_interface
12!> it can be used to connect c programs, communicating through std-in/ std-out
13!>
14!> positions are in angstrom, energies in evolt
15!>
16!> commands:
17!> load filename: loads the filename, returns the env_id, or -1 in case of error
18!> natom [env_id]: returns the number of atoms in the environment env_id
19!> (defaults to the last loaded)
20!> setpos [env_id]: sets the positions of the atoms, should be followed
21!> by natom*3 (on a line) and then all the positions [angstrom]
22!> getpos [env_id]: gets the positions of the atoms, returns
23!> natom*3 (on a line) and then all the positions [angstrom]
24!> calcE [env_id]: calculate the energy and returns it (in eV)
25!> calcEF [env_id]: calculate the energy and forces and returns it,
26!> first the energy on a line (in eV), then the natom*3 (on a line)
27!> and finally all the values (in eV/angstrom)
28!> \par History
29!> 2019: Complete refactoring (Ole Schuett)
30!>
31!> \author Fawzi Mohamed
32! **************************************************************************************************
34 USE iso_fortran_env, ONLY: iostat_end
35 USE cp2k_info, ONLY: compile_arch,&
39 cp2k_home,&
42 USE cp2k_runs, ONLY: run_input
43 USE cp_files, ONLY: close_file,&
48 USE f77_interface, ONLY: &
51 USE input_cp2k_read, ONLY: empty_initial_variables
53 USE kinds, ONLY: default_path_length,&
54 dp
55 USE machine, ONLY: m_chdir,&
56 m_flush,&
57 m_getcwd,&
58 m_getlog,&
59 m_getpid,&
62 USE physcon, ONLY: angstrom,&
63 evolt
65#include "../base/base_uses.f90"
66
67 IMPLICIT NONE
68 PRIVATE
69
70 ! Queried by ASE. Increase version after bug-fixing or behavior changes.
71 CHARACTER(LEN=*), PARAMETER :: CP2K_SHELL_VERSION = "7.0"
72
73 TYPE cp2k_shell_type
74 REAL(dp) :: pos_fact = 1.0_dp
75 REAL(dp) :: e_fact = 1.0_dp
76 LOGICAL :: harsh = .false.
77 TYPE(mp_para_env_type), POINTER :: para_env => null()
78 CHARACTER(LEN=5) :: units = "au"
79 INTEGER :: env_id = -1
80 INTEGER :: iw = -1
81 END TYPE cp2k_shell_type
82
83 PUBLIC :: launch_cp2k_shell
84
85CONTAINS
86
87! **************************************************************************************************
88!> \brief Launch the interactive CP2K shell.
89!> \param input_declaration ...
90! **************************************************************************************************
91 SUBROUTINE launch_cp2k_shell(input_declaration)
92 TYPE(section_type), POINTER :: input_declaration
93
94 CHARACTER(LEN=default_path_length) :: arg1, arg2, cmd
95 TYPE(cp2k_shell_type) :: shell
96 TYPE(cp_logger_type), POINTER :: logger
97
98 logger => cp_get_default_logger()
99 shell%para_env => logger%para_env
101
102 DO
103 IF (.NOT. parse_next_line(shell, cmd, arg1, arg2)) EXIT
104
105 ! dispatch command
106 SELECT CASE (cmd)
107 CASE ('HELP')
108 CALL help_command(shell)
109 CASE ('INFO', 'INFORMATION', 'LICENSE')
110 CALL info_license_command(shell)
111 CASE ('VERSION')
112 CALL version_command(shell)
113 CASE ('WRITE_FILE')
114 CALL write_file_command(shell)
115 CASE ('LAST_ENV_ID')
116 CALL get_last_env_id(shell)
117 CASE ('BG_LOAD', 'BGLOAD')
118 CALL bg_load_command(shell, input_declaration, arg1)
119 CASE ('LOAD')
120 CALL load_command(shell, input_declaration, arg1, arg2)
121 CASE ('DESTROY')
122 CALL destroy_force_env_command(shell, arg1)
123 CASE ('NATOM', 'N_ATOM')
124 CALL get_natom_command(shell, arg1)
125 CASE ('SETPOS', 'SET_POS')
126 CALL set_pos_command(shell, arg1)
127 CASE ('SETPOSFILE', 'SET_POS_FILE')
128 CALL set_pos_file_command(shell, arg1, arg2)
129 CASE ('SETCELL', 'SET_CELL')
130 CALL set_cell_command(shell, arg1)
131 CASE ('GETCELL', 'GET_CELL')
132 CALL get_cell_command(shell, arg1)
133 CASE ('GETSTRESS', 'GET_STRESS')
134 CALL get_stress_command(shell, arg1)
135 CASE ('GETPOS', 'GET_POS')
136 CALL get_pos_command(shell, arg1)
137 CASE ('GETE', 'GET_E')
138 CALL get_energy_command(shell, arg1)
139 CASE ('EVALE', 'EVAL_E')
140 CALL eval_energy_command(shell, arg1)
141 CASE ('CALCE', 'CALC_E')
142 CALL calc_energy_command(shell, arg1)
143 CASE ('EVALEF', 'EVAL_EF')
144 CALL eval_energy_force_command(shell, arg1)
145 CASE ('GETF', 'GET_F')
146 CALL get_forces_command(shell, arg1)
147 CASE ('CALCEF', 'CALC_EF')
148 CALL calc_energy_forces_command(shell, arg1)
149 CASE ('RUN')
150 CALL run_command(shell, input_declaration, arg1, arg2)
151 CASE ('UNITS_EVA', 'UNITS_EV_A')
152 CALL set_units_ev_a(shell)
153 CASE ('UNITS_AU')
154 CALL set_units_au(shell)
155 CASE ('UNITS')
156 CALL get_units(shell)
157 CASE ('HARSH')
158 shell%harsh = .true.
159 CASE ('PERMISSIVE')
160 shell%harsh = .false.
161 CASE ('CD', 'CHDIR')
162 CALL set_pwd_command(shell, arg1)
163 CASE ('PWD', 'CWD')
164 CALL get_pwd_command(shell)
165 CASE ('EXIT')
166 IF (shell%iw > 0) WRITE (shell%iw, '(a)') '* EXIT'
167 EXIT
168 CASE default
169 CALL print_error('unknown command: '//cmd, shell)
170 END SELECT
171 END DO
172
173 END SUBROUTINE launch_cp2k_shell
174
175! **************************************************************************************************
176!> \brief ...
177!> \param shell ...
178!> \param cmd ...
179!> \param arg1 ...
180!> \param arg2 ...
181!> \return ...
182! **************************************************************************************************
183 FUNCTION parse_next_line(shell, cmd, arg1, arg2) RESULT(success)
184 TYPE(cp2k_shell_type) :: shell
185 CHARACTER(LEN=*), INTENT(out) :: cmd, arg1, arg2
186 LOGICAL :: success
187
188 CHARACTER(LEN=default_path_length) :: line
189 INTEGER :: i, iostat
190
191 success = .true.
192 IF (shell%iw > 0) THEN
193 WRITE (shell%iw, '("* READY")')
194 CALL m_flush(shell%iw)
195 READ (*, '(a)', iostat=iostat) line
196 IF (iostat /= 0) THEN
197 IF (iostat == iostat_end) THEN
198 WRITE (shell%iw, '(a)') '* EOF'
199 END IF
200 success = .false. ! EOF
201 END IF
202 END IF
203 CALL shell%para_env%bcast(success)
204 IF (.NOT. success) RETURN
205 CALL shell%para_env%bcast(line)
206
207 ! extract command
208 line = trim(line)
209 DO i = 1, len_trim(line)
210 IF (line(i:i) == ' ') EXIT
211 END DO
212 cmd = line(1:i)
213 CALL uppercase(cmd)
214 line = adjustl(line(i:)) ! shift
215
216 ! extract first arg
217 DO i = 1, len_trim(line)
218 IF (line(i:i) == ' ') EXIT
219 END DO
220 arg1 = line(1:i)
221 line = adjustl(line(i:)) ! shift
222
223 ! extract second arg
224 DO i = 1, len_trim(line)
225 IF (line(i:i) == ' ') EXIT
226 END DO
227 arg2 = line(1:i)
228
229 ! ignore remaining line
230 END FUNCTION parse_next_line
231
232! **************************************************************************************************
233!> \brief Falls be env_id unchagned if not provided
234!> \param str ...
235!> \param shell ...
236!> \return ...
237! **************************************************************************************************
238 FUNCTION parse_env_id(str, shell) RESULT(success)
239 CHARACTER(LEN=*), INTENT(in) :: str
240 TYPE(cp2k_shell_type) :: shell
241 LOGICAL :: success
242
243 INTEGER :: iostat
244
245 success = .true.
246 IF (len_trim(str) > 0) THEN
247 READ (str, *, iostat=iostat) shell%env_id
248 IF (iostat /= 0) THEN
249 shell%env_id = -1
250 success = .false.
251 CALL print_error("parse_env_id failed", shell)
252 END IF
253 ELSE IF (shell%env_id < 1) THEN
254 CALL print_error("last env_id not set", shell)
255 success = .false.
256 END IF
257 ! fallback: reuse last env_id
258 END FUNCTION parse_env_id
259
260! **************************************************************************************************
261!> \brief ...
262!> \param condition ...
263!> \param message ...
264!> \param shell ...
265!> \return ...
266! **************************************************************************************************
267 FUNCTION my_assert(condition, message, shell) RESULT(success)
268 LOGICAL, INTENT(in) :: condition
269 CHARACTER(LEN=*), INTENT(in) :: message
270 TYPE(cp2k_shell_type) :: shell
271 LOGICAL :: success
272
273 success = condition
274 IF (.NOT. success) THEN
275 CALL print_error(message, shell)
276 END IF
277 END FUNCTION my_assert
278
279! **************************************************************************************************
280!> \brief ...
281!> \param message ...
282!> \param shell ...
283! **************************************************************************************************
284 SUBROUTINE print_error(message, shell)
285 CHARACTER(LEN=*), INTENT(in) :: message
286 TYPE(cp2k_shell_type) :: shell
287
288 IF (shell%harsh) cpabort(message)
289
290 IF (shell%iw > 0) THEN
291 WRITE (shell%iw, '("* ERROR ",a)') message
292 END IF
293 END SUBROUTINE print_error
294
295! **************************************************************************************************
296!> \brief ...
297!> \param shell ...
298! **************************************************************************************************
299 SUBROUTINE help_command(shell)
300 TYPE(cp2k_shell_type) :: shell
301
302 IF (shell%iw > 0) THEN
303 WRITE (shell%iw, *) 'Commands'
304 WRITE (shell%iw, *) ' '
305 WRITE (shell%iw, *) ' If there is [env_id] it means that an optional env_id can be given,'
306 WRITE (shell%iw, *) ' if none is given it defaults to the last env_id loaded'
307 WRITE (shell%iw, *) ' All commands are case insensitive.'
308 WRITE (shell%iw, *) ' '
309 WRITE (shell%iw, *) ' INFO: returns some information about cp2k.'
310 WRITE (shell%iw, *) ' VERSION: returns shell version. (queried by ASE to assert features & bugfixes)'
311 WRITE (shell%iw, *) ' WRITE_FILE: Writes content to a file (allows for using ASE over ssh).'
312 WRITE (shell%iw, *) ' LOAD <inp-filename> [out-filename]: loads the filename, returns the env_id, or -1 in case of error'
313 WRITE (shell%iw, *) ' out-filename is optional and defaults to <inp-filename>.out'
314 WRITE (shell%iw, *) ' use "__STD_OUT__" for printing to the screen'
315 WRITE (shell%iw, *) ' BG_LOAD <filename>: loads the filename, without returning the env_id'
316 WRITE (shell%iw, *) ' LAST_ENV_ID: returns the env_id of the last environment loaded'
317 WRITE (shell%iw, *) ' DESTROY [env_id]: destroys the given environment (last and default env'
318 WRITE (shell%iw, *) ' might become invalid)'
319 WRITE (shell%iw, *) ' NATOM [env_id]: returns the number of atoms in the environment env_id'
320 WRITE (shell%iw, *) ' SET_POS [env_id]: sets the positions of the atoms, should be followed'
321 WRITE (shell%iw, *) ' by natom*3 (on a line) and then all the positions. Returns the max'
322 WRITE (shell%iw, *) ' change of the coordinates (useful to avoid extra calculations).'
323 WRITE (shell%iw, *) ' SET_POS_FILE <filename> [env_id]: sets the positions of the atoms from a file.'
324 WRITE (shell%iw, *) ' Returns the max change of the coordinates.'
325 WRITE (shell%iw, *) ' SET_CELL [env_id]: sets the cell, should be followed by 9 numbers'
326 WRITE (shell%iw, *) ' GET_CELL [env_id]: gets the cell vectors'
327 WRITE (shell%iw, *) ' GET_STRESS [env_id]: gets the stress tensor of the last calculation on env_id'
328 WRITE (shell%iw, *) ' GET_POS [env_id]: gets the positions of the atoms, returns'
329 WRITE (shell%iw, *) ' natom*3 (on a line) and then all the positions then "* END" '
330 WRITE (shell%iw, *) ' (alone on a line)'
331 WRITE (shell%iw, *) ' GET_E [env_id]: gets the energy of the last calculation on env_id'
332 WRITE (shell%iw, *) ' GET_F [env_id]: gets the forces on the atoms,of the last calculation on '
333 WRITE (shell%iw, *) ' env_id, if only the energy was calculated the content is undefined. Returns'
334 WRITE (shell%iw, *) ' natom*3 (on a line) and then all the forces then "* END" (alone on'
335 WRITE (shell%iw, *) ' a line)'
336 WRITE (shell%iw, *) ' CALC_E [env_id]: calculate the energy and returns it'
337 WRITE (shell%iw, *) ' EVAL_E [env_id]: calculate the energy (without returning it)'
338 WRITE (shell%iw, *) ' CALC_EF [env_id]: calculate energy and forces and returns them,'
339 WRITE (shell%iw, *) ' first the energy on a line, then the natom*3 (on a line)'
340 WRITE (shell%iw, *) ' and finally all the values and "* END" (alone on a line)'
341 WRITE (shell%iw, *) ' EVAL_EF [env_id]: calculate the energy and forces (without returning them)'
342 WRITE (shell%iw, *) ' RUN <inp-filename> <out-filename>: run the given input file'
343 WRITE (shell%iw, *) ' HARSH: stops on any error'
344 WRITE (shell%iw, *) ' PERMISSIVE: stops only on serious errors'
345 WRITE (shell%iw, *) ' UNITS: returns the units used for energy and position'
346 WRITE (shell%iw, *) ' UNITS_EV_A: sets the units to electron volt (energy) and Angstrom (positions)'
347 WRITE (shell%iw, *) ' UNITS_AU: sets the units atomic units'
348 WRITE (shell%iw, *) ' CD <dir>: change working directory'
349 WRITE (shell%iw, *) ' PWD: print working directory'
350 WRITE (shell%iw, *) ' EXIT: Quit the shell'
351 WRITE (shell%iw, *) ' HELP: writes the present help'
352 CALL m_flush(shell%iw)
353 END IF
354 END SUBROUTINE help_command
355
356! **************************************************************************************************
357!> \brief ...
358!> \param shell ...
359! **************************************************************************************************
360 SUBROUTINE info_license_command(shell)
361 TYPE(cp2k_shell_type) :: shell
362
363 CHARACTER(LEN=default_path_length) :: cwd, host_name, user_name
364 INTEGER :: pid
365
366 IF (shell%iw > 0) THEN
367 CALL m_getcwd(cwd)
368 CALL m_getpid(pid)
369 CALL m_getlog(user_name)
370 CALL m_hostnm(host_name)
371 WRITE (unit=shell%iw, fmt="(A,A)") &
372 " PROGRAM STARTED ON ", trim(host_name)
373 WRITE (unit=shell%iw, fmt="(A,A)") &
374 " PROGRAM STARTED BY ", trim(user_name)
375 WRITE (unit=shell%iw, fmt="(A,i10)") &
376 " PROGRAM PROCESS ID ", pid
377 WRITE (unit=shell%iw, fmt="(A,A)") &
378 " PROGRAM STARTED IN ", trim(cwd)
379 WRITE (unit=shell%iw, fmt="(/,T2,A,T31,A50)") &
380 "CP2K| version string: ", &
381 adjustr(trim(cp2k_version))
382 WRITE (unit=shell%iw, fmt="(T2,A,T41,A40)") &
383 "CP2K| source code revision number:", &
384 adjustr(compile_revision)
385 WRITE (unit=shell%iw, fmt="(T2,A,T41,A40)") &
386 "CP2K| is freely available from ", &
387 adjustr(trim(cp2k_home))
388 WRITE (unit=shell%iw, fmt="(T2,A,T31,A50)") &
389 "CP2K| Program compiled at", &
390 adjustr(compile_date(1:min(50, len(compile_date))))
391 WRITE (unit=shell%iw, fmt="(T2,A,T31,A50)") &
392 "CP2K| Program compiled on", &
393 adjustr(compile_host(1:min(50, len(compile_host))))
394 WRITE (unit=shell%iw, fmt="(T2,A,T31,A50)") &
395 "CP2K| Program compiled for", &
396 adjustr(compile_arch(1:min(50, len(compile_arch))))
397
398 CALL print_cp2k_license(shell%iw)
399 CALL m_flush(shell%iw)
400 END IF
401
402 END SUBROUTINE info_license_command
403
404! **************************************************************************************************
405!> \brief ...
406!> \param shell ...
407! **************************************************************************************************
408 SUBROUTINE version_command(shell)
409 TYPE(cp2k_shell_type) :: shell
410
411 IF (shell%iw > 0) THEN
412 WRITE (shell%iw, '(a,a)') "CP2K Shell Version: ", cp2k_shell_version
413 CALL m_flush(shell%iw)
414 END IF
415 END SUBROUTINE version_command
416
417! **************************************************************************************************
418!> \brief ...
419!> \param shell ...
420! **************************************************************************************************
421 SUBROUTINE write_file_command(shell)
422 TYPE(cp2k_shell_type) :: shell
423
424 CHARACTER(LEN=default_path_length) :: line, out_filename
425 INTEGER :: file_unit, i, iostat, n_lines
426
427 IF (shell%iw > 0) THEN
428 READ (*, '(a)', iostat=iostat) out_filename
429 IF (iostat /= 0) cpabort('WRITE_FILE bad filename')
430 READ (*, *, iostat=iostat) n_lines
431 IF (iostat /= 0) cpabort('WRITE_FILE bad number of lines')
432 CALL open_file(file_name=trim(out_filename), unit_number=file_unit, &
433 file_status="UNKNOWN", file_form="FORMATTED", file_action="WRITE")
434 DO i = 1, n_lines
435 READ (*, '(a)', iostat=iostat) line
436 IF (iostat /= 0) cpabort('WRITE_FILE read error')
437 WRITE (file_unit, '(a)', iostat=iostat) trim(line)
438 IF (iostat /= 0) cpabort('WRITE_FILE write error')
439 END DO
440 READ (*, '(a)', iostat=iostat) line
441 IF (iostat /= 0) cpabort('WRITE_FILE read error')
442 IF (trim(line) /= "*END") cpabort('WRITE_FILE bad end delimiter')
443 CALL close_file(unit_number=file_unit)
444 END IF
445 END SUBROUTINE write_file_command
446
447! **************************************************************************************************
448!> \brief ...
449!> \param shell ...
450! **************************************************************************************************
451 SUBROUTINE get_last_env_id(shell)
452 TYPE(cp2k_shell_type) :: shell
453
454 IF (shell%iw > 0) THEN
455 WRITE (shell%iw, '(i10)') shell%env_id
456 CALL m_flush(shell%iw)
457 END IF
458 END SUBROUTINE get_last_env_id
459
460! **************************************************************************************************
461!> \brief ...
462!> \param shell ...
463!> \param input_declaration ...
464!> \param arg1 ...
465! **************************************************************************************************
466 SUBROUTINE bg_load_command(shell, input_declaration, arg1)
467 TYPE(cp2k_shell_type) :: shell
468 TYPE(section_type), POINTER :: input_declaration
469 CHARACTER(LEN=*) :: arg1
470
471 INTEGER :: ierr
472
473 IF (.NOT. my_assert(len_trim(arg1) > 0, "file argument missing", shell)) RETURN
474 CALL create_force_env(new_env_id=shell%env_id, &
475 input_declaration=input_declaration, &
476 input_path=trim(arg1), &
477 output_path=trim(arg1)//'.out', &
478 owns_out_unit=.true., ierr=ierr)
479 IF (ierr /= 0) THEN
480 shell%env_id = -1
481 CALL print_error("create_force_env failed", shell)
482 END IF
483 END SUBROUTINE bg_load_command
484
485! **************************************************************************************************
486!> \brief ...
487!> \param shell ...
488!> \param input_declaration ...
489!> \param arg1 ...
490!> \param arg2 ...
491! **************************************************************************************************
492 SUBROUTINE load_command(shell, input_declaration, arg1, arg2)
493 TYPE(cp2k_shell_type) :: shell
494 TYPE(section_type), POINTER :: input_declaration
495 CHARACTER(LEN=*), INTENT(IN) :: arg1, arg2
496
497 CHARACTER(LEN=default_path_length) :: inp_filename, out_filename
498 INTEGER :: ierr
499
500 IF (.NOT. my_assert(len_trim(arg1) > 0, "file argument missing", shell)) RETURN
501 inp_filename = arg1
502 out_filename = trim(inp_filename)//'.out'
503 IF (len_trim(arg2) > 0) out_filename = arg2
504 CALL create_force_env(new_env_id=shell%env_id, &
505 input_declaration=input_declaration, &
506 input_path=inp_filename, &
507 output_path=out_filename, &
508 owns_out_unit=.true., ierr=ierr)
509 IF (ierr /= 0) THEN
510 shell%env_id = -1
511 CALL print_error("create_force_env failed", shell)
512 ELSE IF (shell%iw > 0) THEN
513 WRITE (shell%iw, '(i10)') shell%env_id
514 CALL m_flush(shell%iw)
515 END IF
516 END SUBROUTINE load_command
517
518! **************************************************************************************************
519!> \brief ...
520!> \param shell ...
521!> \param arg1 ...
522! **************************************************************************************************
523 SUBROUTINE destroy_force_env_command(shell, arg1)
524 TYPE(cp2k_shell_type) :: shell
525 CHARACTER(LEN=*), INTENT(IN) :: arg1
526
527 INTEGER :: ierr
528
529 IF (.NOT. parse_env_id(arg1, shell)) RETURN
530 CALL destroy_force_env(shell%env_id, ierr)
531 shell%env_id = -1
532 IF (ierr /= 0) CALL print_error('destroy_force_env failed', shell)
533 END SUBROUTINE destroy_force_env_command
534
535! **************************************************************************************************
536!> \brief ...
537!> \param shell ...
538!> \param arg1 ...
539! **************************************************************************************************
540 SUBROUTINE get_natom_command(shell, arg1)
541 TYPE(cp2k_shell_type) :: shell
542 CHARACTER(LEN=*), INTENT(IN) :: arg1
543
544 INTEGER :: ierr, iostat, n_atom
545
546 IF (.NOT. parse_env_id(arg1, shell)) RETURN
547 CALL get_natom(shell%env_id, n_atom, ierr)
548 IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
549 IF (shell%iw > 0) THEN
550 WRITE (shell%iw, '(i10)', iostat=iostat) n_atom
551 CALL m_flush(shell%iw)
552 END IF
553 END SUBROUTINE get_natom_command
554
555! **************************************************************************************************
556!> \brief ...
557!> \param shell ...
558!> \param arg1 ...
559! **************************************************************************************************
560 SUBROUTINE set_pos_command(shell, arg1)
561 TYPE(cp2k_shell_type) :: shell
562 CHARACTER(LEN=*), INTENT(IN) :: arg1
563
564 CHARACTER(LEN=default_path_length) :: line
565 INTEGER :: ierr, iostat, n_atom
566 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: pos
567
568 IF (.NOT. parse_env_id(arg1, shell)) RETURN
569 CALL get_natom(shell%env_id, n_atom, ierr)
570 IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
571 ALLOCATE (pos(3*n_atom))
572 IF (shell%iw > 0) THEN
573 READ (*, *, iostat=iostat) n_atom
574 IF (.NOT. my_assert(iostat == 0, 'setpos read n_atom failed', shell)) RETURN
575 IF (.NOT. my_assert(n_atom == SIZE(pos), 'setpos invalid number of atoms', shell)) RETURN
576 READ (*, *, iostat=iostat) pos
577 IF (.NOT. my_assert(iostat == 0, 'setpos read coords failed', shell)) RETURN
578 pos(:) = pos(:)/shell%pos_fact
579 READ (*, '(a)', iostat=iostat) line
580 IF (.NOT. my_assert(iostat == 0, 'setpos read END failed', shell)) RETURN
581 CALL uppercase(line)
582 IF (.NOT. my_assert(trim(line) == '*END', 'missing *END', shell)) RETURN
583 END IF
584
585 CALL send_pos_updates(shell, n_atom, pos)
586 DEALLOCATE (pos)
587 END SUBROUTINE set_pos_command
588
589! **************************************************************************************************
590!> \brief Set the positions based on coordinates in a file
591!> \param shell ...
592!> \param arg1 Filename
593!> \param arg2 Environment ID
594! **************************************************************************************************
595 SUBROUTINE set_pos_file_command(shell, arg1, arg2)
596 TYPE(cp2k_shell_type) :: shell
597 CHARACTER(LEN=*), INTENT(IN) :: arg1, arg2
598
599 INTEGER :: file_unit, ierr, iostat, n_atom
600 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: pos
601
602 IF (.NOT. parse_env_id(arg2, shell)) RETURN
603 CALL get_natom(shell%env_id, n_atom, ierr)
604 IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
605 ALLOCATE (pos(3*n_atom))
606
607 IF (shell%iw > 0) THEN
608 CALL open_file(file_name=trim(arg1), unit_number=file_unit, &
609 file_status="OLD", file_form="FORMATTED", file_action="READ")
610 READ (file_unit, *, iostat=iostat) n_atom
611 IF (.NOT. my_assert(iostat == 0, 'setpos read n_atom failed', shell)) RETURN
612 IF (.NOT. my_assert(n_atom == SIZE(pos), 'setpos invalid number of atoms', shell)) RETURN
613 READ (file_unit, *, iostat=iostat) pos
614 IF (.NOT. my_assert(iostat == 0, 'setpos read coords failed', shell)) RETURN
615 pos(:) = pos(:)/shell%pos_fact
616 CALL close_file(unit_number=file_unit)
617 END IF
618
619 CALL send_pos_updates(shell, n_atom, pos)
620 DEALLOCATE (pos)
621 END SUBROUTINE set_pos_file_command
622
623! **************************************************************************************************
624!> \brief Update the positions for an environment
625!> \param shell Shell on on which to write the maximum change in coordinates
626!> \param n_atom Number of atoms in the target environment
627!> \param pos Positions of the new argument
628! **************************************************************************************************
629 SUBROUTINE send_pos_updates(shell, n_atom, pos)
630 TYPE(cp2k_shell_type) :: shell
631 INTEGER :: n_atom
632 REAL(kind=dp), DIMENSION(:) :: pos
633
634 INTEGER :: i, ierr
635 REAL(kind=dp) :: max_change
636 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: old_pos
637
638 ! Get the current positions
639 ALLOCATE (old_pos(3*n_atom))
640 CALL shell%para_env%bcast(pos)
641 CALL get_pos(shell%env_id, old_pos, n_el=3*n_atom, ierr=ierr)
642 IF (.NOT. my_assert(ierr == 0, 'get_pos error', shell)) RETURN
643
644 ! Set, measure the change, print do to shell
645 CALL set_pos(shell%env_id, new_pos=pos, n_el=3*n_atom, ierr=ierr)
646 IF (.NOT. my_assert(ierr == 0, 'set_pos error', shell)) RETURN
647 max_change = 0.0_dp
648 DO i = 1, SIZE(pos)
649 max_change = max(max_change, abs(pos(i) - old_pos(i)))
650 END DO
651 DEALLOCATE (old_pos)
652 IF (shell%iw > 0) THEN
653 WRITE (shell%iw, '(ES22.13)') max_change*shell%pos_fact
654 CALL m_flush(shell%iw)
655 END IF
656 END SUBROUTINE send_pos_updates
657
658! **************************************************************************************************
659!> \brief ...
660!> \param shell ...
661!> \param arg1 ...
662! **************************************************************************************************
663 SUBROUTINE set_cell_command(shell, arg1)
664 TYPE(cp2k_shell_type) :: shell
665 CHARACTER(LEN=*), INTENT(IN) :: arg1
666
667 INTEGER :: ierr, iostat
668 REAL(kind=dp), DIMENSION(3, 3) :: cell
669
670 IF (.NOT. parse_env_id(arg1, shell)) RETURN
671 IF (shell%iw > 0) THEN
672 READ (*, *, iostat=iostat) cell
673 IF (.NOT. my_assert(iostat == 0, 'setcell read failed', shell)) RETURN
674 cell(:, :) = cell(:, :)/shell%pos_fact
675 END IF
676 CALL shell%para_env%bcast(cell)
677 CALL set_cell(shell%env_id, new_cell=cell, ierr=ierr)
678 IF (.NOT. my_assert(ierr == 0, 'set_cell failed', shell)) RETURN
679 END SUBROUTINE set_cell_command
680
681! **************************************************************************************************
682!> \brief ...
683!> \param shell ...
684!> \param arg1 ...
685! **************************************************************************************************
686 SUBROUTINE get_cell_command(shell, arg1)
687 TYPE(cp2k_shell_type) :: shell
688 CHARACTER(LEN=*), INTENT(IN) :: arg1
689
690 INTEGER :: ierr
691 REAL(kind=dp), DIMENSION(3, 3) :: cell
692
693 IF (.NOT. parse_env_id(arg1, shell)) RETURN
694 CALL get_cell(shell%env_id, cell=cell, ierr=ierr)
695 IF (.NOT. my_assert(ierr == 0, 'get_cell failed', shell)) RETURN
696 cell(:, :) = cell(:, :)*shell%pos_fact
697 IF (shell%iw > 0) THEN
698 WRITE (shell%iw, '(9ES22.13)') cell
699 CALL m_flush(shell%iw)
700 END IF
701 END SUBROUTINE get_cell_command
702
703! **************************************************************************************************
704!> \brief ...
705!> \param shell ...
706!> \param arg1 ...
707! **************************************************************************************************
708 SUBROUTINE get_stress_command(shell, arg1)
709 TYPE(cp2k_shell_type) :: shell
710 CHARACTER(LEN=*), INTENT(IN) :: arg1
711
712 INTEGER :: ierr
713 REAL(kind=dp), DIMENSION(3, 3) :: stress_tensor
714
715 IF (.NOT. parse_env_id(arg1, shell)) RETURN
716 CALL get_stress_tensor(shell%env_id, stress_tensor=stress_tensor, ierr=ierr)
717 IF (.NOT. my_assert(ierr == 0, 'get_stress_tensor failed', shell)) RETURN
718 stress_tensor(:, :) = stress_tensor(:, :)*(shell%e_fact/shell%pos_fact**3)
719 IF (shell%iw > 0) THEN
720 WRITE (shell%iw, '(9ES22.13)') stress_tensor
721 CALL m_flush(shell%iw)
722 END IF
723 END SUBROUTINE get_stress_command
724
725! **************************************************************************************************
726!> \brief ...
727!> \param shell ...
728!> \param arg1 ...
729! **************************************************************************************************
730 SUBROUTINE get_pos_command(shell, arg1)
731 TYPE(cp2k_shell_type) :: shell
732 CHARACTER(LEN=*), INTENT(IN) :: arg1
733
734 INTEGER :: ierr, n_atom
735 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: pos
736
737 IF (.NOT. parse_env_id(arg1, shell)) RETURN
738 CALL get_natom(shell%env_id, n_atom, ierr)
739 IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
740 ALLOCATE (pos(3*n_atom))
741 CALL get_pos(shell%env_id, pos=pos, n_el=3*n_atom, ierr=ierr)
742 IF (.NOT. my_assert(ierr == 0, 'get_pos failed', shell)) RETURN
743 IF (shell%iw > 0) THEN
744 WRITE (shell%iw, '(i10)') 3*n_atom
745 WRITE (shell%iw, '(3ES22.13)') pos(:)*shell%pos_fact
746 WRITE (shell%iw, '(a)') "* END"
747 CALL m_flush(shell%iw)
748 END IF
749 DEALLOCATE (pos)
750 END SUBROUTINE get_pos_command
751
752! **************************************************************************************************
753!> \brief ...
754!> \param shell ...
755!> \param arg1 ...
756! **************************************************************************************************
757 SUBROUTINE get_energy_command(shell, arg1)
758 TYPE(cp2k_shell_type) :: shell
759 CHARACTER(LEN=*), INTENT(IN) :: arg1
760
761 INTEGER :: ierr
762 REAL(kind=dp) :: e_pot
763
764 IF (.NOT. parse_env_id(arg1, shell)) RETURN
765 CALL get_energy(shell%env_id, e_pot, ierr)
766 IF (.NOT. my_assert(ierr == 0, 'get_energy failed', shell)) RETURN
767 IF (shell%iw > 0) THEN
768 WRITE (shell%iw, '(ES22.13)') e_pot*shell%e_fact
769 CALL m_flush(shell%iw)
770 END IF
771 END SUBROUTINE get_energy_command
772
773! **************************************************************************************************
774!> \brief ...
775!> \param shell ...
776!> \param arg1 ...
777! **************************************************************************************************
778 SUBROUTINE eval_energy_command(shell, arg1)
779 TYPE(cp2k_shell_type) :: shell
780 CHARACTER(LEN=*), INTENT(IN) :: arg1
781
782 INTEGER :: ierr
783
784 IF (.NOT. parse_env_id(arg1, shell)) RETURN
785 CALL calc_energy_force(shell%env_id, calc_force=.false., ierr=ierr)
786 IF (ierr /= 0) CALL print_error('calc_energy_force failed', shell)
787 END SUBROUTINE eval_energy_command
788
789! **************************************************************************************************
790!> \brief ...
791!> \param shell ...
792!> \param arg1 ...
793! **************************************************************************************************
794 SUBROUTINE calc_energy_command(shell, arg1)
795 TYPE(cp2k_shell_type) :: shell
796 CHARACTER(LEN=*), INTENT(IN) :: arg1
797
798 INTEGER :: ierr
799 REAL(kind=dp) :: e_pot
800
801 IF (.NOT. parse_env_id(arg1, shell)) RETURN
802 CALL calc_energy_force(shell%env_id, calc_force=.false., ierr=ierr)
803 IF (.NOT. my_assert(ierr == 0, 'calc_energy_force failed', shell)) RETURN
804 CALL get_energy(shell%env_id, e_pot, ierr)
805 IF (.NOT. my_assert(ierr == 0, 'get_energy failed', shell)) RETURN
806 IF (shell%iw > 0) THEN
807 WRITE (shell%iw, '(ES22.13)') e_pot*shell%e_fact
808 CALL m_flush(shell%iw)
809 END IF
810 END SUBROUTINE calc_energy_command
811
812! **************************************************************************************************
813!> \brief ...
814!> \param shell ...
815!> \param arg1 ...
816! **************************************************************************************************
817 SUBROUTINE eval_energy_force_command(shell, arg1)
818 TYPE(cp2k_shell_type) :: shell
819 CHARACTER(LEN=*), INTENT(IN) :: arg1
820
821 INTEGER :: ierr
822
823 IF (.NOT. parse_env_id(arg1, shell)) RETURN
824 CALL calc_energy_force(shell%env_id, calc_force=.true., ierr=ierr)
825 IF (ierr /= 0) CALL print_error('calc_energy_force failed', shell)
826 END SUBROUTINE eval_energy_force_command
827
828! **************************************************************************************************
829!> \brief ...
830!> \param shell ...
831!> \param arg1 ...
832! **************************************************************************************************
833 SUBROUTINE get_forces_command(shell, arg1)
834 TYPE(cp2k_shell_type) :: shell
835 CHARACTER(LEN=*), INTENT(IN) :: arg1
836
837 INTEGER :: ierr, n_atom
838 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: forces
839
840 IF (.NOT. parse_env_id(arg1, shell)) RETURN
841 CALL get_natom(shell%env_id, n_atom, ierr)
842 IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
843 ALLOCATE (forces(3*n_atom))
844 CALL get_force(shell%env_id, frc=forces, n_el=3*n_atom, ierr=ierr)
845 IF (.NOT. my_assert(ierr == 0, 'get_force failed', shell)) RETURN
846 forces(:) = forces(:)*(shell%e_fact/shell%pos_fact)
847 IF (shell%iw > 0) THEN
848 WRITE (shell%iw, '(i10)') 3*n_atom
849 WRITE (shell%iw, '(3ES22.13)') forces
850 WRITE (shell%iw, '("* END")')
851 CALL m_flush(shell%iw)
852 END IF
853 DEALLOCATE (forces)
854 END SUBROUTINE get_forces_command
855
856! **************************************************************************************************
857!> \brief ...
858!> \param shell ...
859!> \param arg1 ...
860! **************************************************************************************************
861 SUBROUTINE calc_energy_forces_command(shell, arg1)
862 TYPE(cp2k_shell_type) :: shell
863 CHARACTER(LEN=*), INTENT(IN) :: arg1
864
865 INTEGER :: ierr, n_atom
866 REAL(kind=dp) :: e_pot
867 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: forces
868
869 IF (.NOT. parse_env_id(arg1, shell)) RETURN
870 CALL calc_energy_force(shell%env_id, calc_force=.true., ierr=ierr)
871 IF (.NOT. my_assert(ierr == 0, 'calc_energy_force failed', shell)) RETURN
872 CALL get_energy(shell%env_id, e_pot, ierr)
873 IF (.NOT. my_assert(ierr == 0, 'get_energy failed', shell)) RETURN
874 CALL get_natom(shell%env_id, n_atom, ierr)
875 IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
876 ALLOCATE (forces(3*n_atom))
877 CALL get_force(shell%env_id, frc=forces, n_el=3*n_atom, ierr=ierr)
878 IF (.NOT. my_assert(ierr == 0, 'get_energy failed', shell)) RETURN
879 IF (shell%iw > 0) THEN
880 WRITE (shell%iw, '(ES22.13)') e_pot*shell%e_fact
881 WRITE (shell%iw, '(i10)') 3*n_atom
882 WRITE (shell%iw, '(3ES22.13)') forces*(shell%e_fact/shell%pos_fact)
883 WRITE (shell%iw, '("* END")')
884 CALL m_flush(shell%iw)
885 END IF
886 DEALLOCATE (forces)
887 END SUBROUTINE calc_energy_forces_command
888
889! **************************************************************************************************
890!> \brief ...
891!> \param shell ...
892!> \param input_declaration ...
893!> \param arg1 ...
894!> \param arg2 ...
895! **************************************************************************************************
896 SUBROUTINE run_command(shell, input_declaration, arg1, arg2)
897 TYPE(cp2k_shell_type) :: shell
898 TYPE(section_type), POINTER :: input_declaration
899 CHARACTER(LEN=*), INTENT(IN) :: arg1, arg2
900
901 IF (.NOT. my_assert(len_trim(arg1) > 0, "input-file argument missing", shell)) RETURN
902 IF (.NOT. my_assert(len_trim(arg2) > 0, "input-file argument missing", shell)) RETURN
903 CALL run_input(input_declaration, arg1, arg2, empty_initial_variables)
904 END SUBROUTINE run_command
905
906! **************************************************************************************************
907!> \brief ...
908!> \param shell ...
909! **************************************************************************************************
910 SUBROUTINE set_units_ev_a(shell)
911 TYPE(cp2k_shell_type) :: shell
912
913 shell%e_fact = evolt
914 shell%pos_fact = angstrom
915 shell%units = 'eV_A'
916 END SUBROUTINE set_units_ev_a
917
918! **************************************************************************************************
919!> \brief ...
920!> \param shell ...
921! **************************************************************************************************
922 SUBROUTINE set_units_au(shell)
923 TYPE(cp2k_shell_type) :: shell
924
925 shell%e_fact = 1.0_dp
926 shell%pos_fact = 1.0_dp
927 shell%units = 'au'
928 END SUBROUTINE set_units_au
929
930! **************************************************************************************************
931!> \brief ...
932!> \param shell ...
933! **************************************************************************************************
934 SUBROUTINE get_units(shell)
935 TYPE(cp2k_shell_type) :: shell
936
937 IF (shell%iw > 0) THEN
938 WRITE (shell%iw, '(a)') trim(shell%units)
939 CALL m_flush(shell%iw)
940 END IF
941 END SUBROUTINE get_units
942
943! **************************************************************************************************
944!> \brief ...
945!> \param shell ...
946!> \param arg1 ...
947! **************************************************************************************************
948 SUBROUTINE set_pwd_command(shell, arg1)
949 TYPE(cp2k_shell_type) :: shell
950 CHARACTER(LEN=*), INTENT(IN) :: arg1
951
952 INTEGER :: ierr
953
954 IF (.NOT. my_assert(len_trim(arg1) > 0, 'missing directory', shell)) RETURN
955 CALL m_chdir(arg1, ierr)
956 IF (ierr /= 0) CALL print_error('changing directory failed', shell)
957 END SUBROUTINE set_pwd_command
958
959! **************************************************************************************************
960!> \brief ...
961!> \param shell ...
962! **************************************************************************************************
963 SUBROUTINE get_pwd_command(shell)
964 TYPE(cp2k_shell_type) :: shell
965
966 CHARACTER(LEN=default_path_length) :: cwd
967
968 IF (shell%iw > 0) THEN
969 CALL m_getcwd(cwd)
970 WRITE (shell%iw, '(a)') trim(cwd)
971 END IF
972 END SUBROUTINE get_pwd_command
973
974END MODULE cp2k_shell
static void parse_next_line(const char key[], FILE *fp, const char format[], const int nargs,...)
Parses next line from file, expecting it to match "${key} ${format}".
Definition grid_replay.c:42
some minimal info about CP2K, including its version and license
Definition cp2k_info.F:16
character(len= *), parameter, public cp2k_home
Definition cp2k_info.F:43
character(len= *), parameter, public compile_host
Definition cp2k_info.F:61
character(len= *), parameter, public compile_arch
Definition cp2k_info.F:49
subroutine, public print_cp2k_license(iunit)
...
Definition cp2k_info.F:281
character(len= *), parameter, public compile_revision
Definition cp2k_info.F:37
character(len= *), parameter, public compile_date
Definition cp2k_info.F:55
character(len= *), parameter, public cp2k_version
Definition cp2k_info.F:41
subroutine, public run_input(input_declaration, input_file_path, output_file_path, initial_variables, mpi_comm)
runs the given input
Definition cp2k_runs.F:958
Interactive shell of CP2K.
Definition cp2k_shell.F:33
subroutine, public launch_cp2k_shell(input_declaration)
Launch the interactive CP2K shell.
Definition cp2k_shell.F:92
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:308
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:119
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...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
interface to use cp2k as library
recursive subroutine, public destroy_force_env(env_id, ierr, q_finalize)
deallocates the force_env with the given id
subroutine, public get_natom(env_id, n_atom, ierr)
returns the number of atoms in the given force env
subroutine, public get_cell(env_id, cell, per, ierr)
gets a cell
recursive subroutine, public calc_energy_force(env_id, calc_force, ierr)
updates the energy and the forces of given force_env
subroutine, public get_energy(env_id, e_pot, ierr)
returns the energy of the last configuration calculated
subroutine, public get_pos(env_id, pos, n_el, ierr)
gets the positions of the particles
recursive subroutine, public create_force_env(new_env_id, input_declaration, input_path, output_path, mpi_comm, output_unit, owns_out_unit, input, ierr, work_dir, initial_variables)
creates a new force environment using the given input, and writing the output to the given output uni...
subroutine, public set_cell(env_id, new_cell, ierr)
sets a new cell
subroutine, public set_pos(env_id, new_pos, n_el, ierr)
sets the positions of the particles
subroutine, public get_stress_tensor(env_id, stress_tensor, ierr)
gets the stress tensor
subroutine, public get_force(env_id, frc, n_el, ierr)
gets the forces of the particles
recursive subroutine, public calc_force(env_id, pos, n_el_pos, e_pot, force, n_el_force, ierr)
returns the energy of the configuration given by the positions passed as argument
parse cp2k input files
objects that represent the structure of input sections and the data contained in an input section
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_getpid(pid)
...
Definition machine.F:555
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:106
subroutine, public m_getcwd(curdir)
...
Definition machine.F:507
subroutine, public m_chdir(dir, ierror)
...
Definition machine.F:536
subroutine, public m_getlog(user)
...
Definition machine.F:632
subroutine, public m_hostnm(hname)
...
Definition machine.F:474
Interface to the message passing library MPI.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public evolt
Definition physcon.F:183
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represent a section of the input file
stores all the informations relevant to an mpi environment