Line data Source code
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 : ! **************************************************************************************************
33 : MODULE cp2k_shell
34 : USE ISO_FORTRAN_ENV, ONLY: IOSTAT_END
35 : USE cp2k_info, ONLY: compile_arch,&
36 : compile_date,&
37 : compile_host,&
38 : compile_revision,&
39 : cp2k_home,&
40 : cp2k_version,&
41 : print_cp2k_license
42 : USE cp2k_runs, ONLY: run_input
43 : USE cp_files, ONLY: close_file,&
44 : open_file
45 : USE cp_log_handling, ONLY: cp_get_default_logger,&
46 : cp_logger_get_default_io_unit,&
47 : cp_logger_type
48 : USE f77_interface, ONLY: &
49 : calc_energy_force, calc_force, create_force_env, destroy_force_env, get_cell, get_energy, &
50 : get_force, get_natom, get_pos, get_stress_tensor, set_cell, set_pos
51 : USE input_cp2k_read, ONLY: empty_initial_variables
52 : USE input_section_types, ONLY: section_type
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,&
60 : m_hostnm
61 : USE message_passing, ONLY: mp_para_env_type
62 : USE physcon, ONLY: angstrom,&
63 : evolt
64 : USE string_utilities, ONLY: uppercase
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 :
85 : CONTAINS
86 :
87 : ! **************************************************************************************************
88 : !> \brief Launch the interactive CP2K shell.
89 : !> \param input_declaration ...
90 : ! **************************************************************************************************
91 0 : 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 0 : logger => cp_get_default_logger()
99 0 : shell%para_env => logger%para_env
100 0 : shell%iw = cp_logger_get_default_io_unit()
101 :
102 : DO
103 0 : IF (.NOT. parse_next_line(shell, cmd, arg1, arg2)) EXIT
104 :
105 : ! dispatch command
106 0 : SELECT CASE (cmd)
107 : CASE ('HELP')
108 0 : CALL help_command(shell)
109 : CASE ('INFO', 'INFORMATION', 'LICENSE')
110 0 : CALL info_license_command(shell)
111 : CASE ('VERSION')
112 0 : CALL version_command(shell)
113 : CASE ('WRITE_FILE')
114 0 : CALL write_file_command(shell)
115 : CASE ('LAST_ENV_ID')
116 0 : CALL get_last_env_id(shell)
117 : CASE ('BG_LOAD', 'BGLOAD')
118 0 : CALL bg_load_command(shell, input_declaration, arg1)
119 : CASE ('LOAD')
120 0 : CALL load_command(shell, input_declaration, arg1, arg2)
121 : CASE ('DESTROY')
122 0 : CALL destroy_force_env_command(shell, arg1)
123 : CASE ('NATOM', 'N_ATOM')
124 0 : CALL get_natom_command(shell, arg1)
125 : CASE ('SETPOS', 'SET_POS')
126 0 : CALL set_pos_command(shell, arg1)
127 : CASE ('SETPOSFILE', 'SET_POS_FILE')
128 0 : CALL set_pos_file_command(shell, arg1, arg2)
129 : CASE ('SETCELL', 'SET_CELL')
130 0 : CALL set_cell_command(shell, arg1)
131 : CASE ('GETCELL', 'GET_CELL')
132 0 : CALL get_cell_command(shell, arg1)
133 : CASE ('GETSTRESS', 'GET_STRESS')
134 0 : CALL get_stress_command(shell, arg1)
135 : CASE ('GETPOS', 'GET_POS')
136 0 : CALL get_pos_command(shell, arg1)
137 : CASE ('GETE', 'GET_E')
138 0 : CALL get_energy_command(shell, arg1)
139 : CASE ('EVALE', 'EVAL_E')
140 0 : CALL eval_energy_command(shell, arg1)
141 : CASE ('CALCE', 'CALC_E')
142 0 : CALL calc_energy_command(shell, arg1)
143 : CASE ('EVALEF', 'EVAL_EF')
144 0 : CALL eval_energy_force_command(shell, arg1)
145 : CASE ('GETF', 'GET_F')
146 0 : CALL get_forces_command(shell, arg1)
147 : CASE ('CALCEF', 'CALC_EF')
148 0 : CALL calc_energy_forces_command(shell, arg1)
149 : CASE ('RUN')
150 0 : CALL run_command(shell, input_declaration, arg1, arg2)
151 : CASE ('UNITS_EVA', 'UNITS_EV_A')
152 0 : CALL set_units_ev_a(shell)
153 : CASE ('UNITS_AU')
154 0 : CALL set_units_au(shell)
155 : CASE ('UNITS')
156 0 : CALL get_units(shell)
157 : CASE ('HARSH')
158 0 : shell%harsh = .TRUE.
159 : CASE ('PERMISSIVE')
160 0 : shell%harsh = .FALSE.
161 : CASE ('CD', 'CHDIR')
162 0 : CALL set_pwd_command(shell, arg1)
163 : CASE ('PWD', 'CWD')
164 0 : CALL get_pwd_command(shell)
165 : CASE ('EXIT')
166 0 : IF (shell%iw > 0) WRITE (shell%iw, '(a)') '* EXIT'
167 0 : EXIT
168 : CASE default
169 0 : CALL print_error('unknown command: '//cmd, shell)
170 : END SELECT
171 : END DO
172 :
173 0 : 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 0 : 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 0 : success = .TRUE.
192 0 : IF (shell%iw > 0) THEN
193 0 : WRITE (shell%iw, '("* READY")')
194 0 : CALL m_flush(shell%iw)
195 0 : READ (*, '(a)', iostat=iostat) line
196 0 : IF (iostat /= 0) THEN
197 0 : IF (iostat == IOSTAT_END) THEN
198 0 : WRITE (shell%iw, '(a)') '* EOF'
199 : END IF
200 0 : success = .FALSE. ! EOF
201 : END IF
202 : END IF
203 0 : CALL shell%para_env%bcast(success)
204 0 : IF (.NOT. success) RETURN
205 0 : CALL shell%para_env%bcast(line)
206 :
207 : ! extract command
208 : line = TRIM(line)
209 0 : DO i = 1, LEN_TRIM(line)
210 0 : IF (line(i:i) == ' ') EXIT
211 : END DO
212 0 : cmd = line(1:i)
213 0 : CALL uppercase(cmd)
214 0 : line = ADJUSTL(line(i:)) ! shift
215 :
216 : ! extract first arg
217 0 : DO i = 1, LEN_TRIM(line)
218 0 : IF (line(i:i) == ' ') EXIT
219 : END DO
220 0 : arg1 = line(1:i)
221 0 : line = ADJUSTL(line(i:)) ! shift
222 :
223 : ! extract second arg
224 0 : DO i = 1, LEN_TRIM(line)
225 0 : IF (line(i:i) == ' ') EXIT
226 : END DO
227 0 : arg2 = line(1:i)
228 :
229 : ! ignore remaining line
230 0 : 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 0 : 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 0 : success = .TRUE.
246 0 : IF (LEN_TRIM(str) > 0) THEN
247 0 : READ (str, *, iostat=iostat) shell%env_id
248 0 : IF (iostat /= 0) THEN
249 0 : shell%env_id = -1
250 0 : success = .FALSE.
251 0 : CALL print_error("parse_env_id failed", shell)
252 : END IF
253 0 : ELSE IF (shell%env_id < 1) THEN
254 0 : CALL print_error("last env_id not set", shell)
255 0 : success = .FALSE.
256 : END IF
257 : ! fallback: reuse last env_id
258 0 : END FUNCTION parse_env_id
259 :
260 : ! **************************************************************************************************
261 : !> \brief ...
262 : !> \param condition ...
263 : !> \param message ...
264 : !> \param shell ...
265 : !> \return ...
266 : ! **************************************************************************************************
267 0 : 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 0 : success = condition
274 0 : IF (.NOT. success) THEN
275 0 : CALL print_error(message, shell)
276 : END IF
277 0 : END FUNCTION my_assert
278 :
279 : ! **************************************************************************************************
280 : !> \brief ...
281 : !> \param message ...
282 : !> \param shell ...
283 : ! **************************************************************************************************
284 0 : SUBROUTINE print_error(message, shell)
285 : CHARACTER(LEN=*), INTENT(in) :: message
286 : TYPE(cp2k_shell_type) :: shell
287 :
288 0 : IF (shell%harsh) CPABORT(message)
289 :
290 0 : IF (shell%iw > 0) THEN
291 0 : WRITE (shell%iw, '("* ERROR ",a)') message
292 : END IF
293 0 : END SUBROUTINE print_error
294 :
295 : ! **************************************************************************************************
296 : !> \brief ...
297 : !> \param shell ...
298 : ! **************************************************************************************************
299 0 : SUBROUTINE help_command(shell)
300 : TYPE(cp2k_shell_type) :: shell
301 :
302 0 : IF (shell%iw > 0) THEN
303 0 : WRITE (shell%iw, *) 'Commands'
304 0 : WRITE (shell%iw, *) ' '
305 0 : WRITE (shell%iw, *) ' If there is [env_id] it means that an optional env_id can be given,'
306 0 : WRITE (shell%iw, *) ' if none is given it defaults to the last env_id loaded'
307 0 : WRITE (shell%iw, *) ' All commands are case insensitive.'
308 0 : WRITE (shell%iw, *) ' '
309 0 : WRITE (shell%iw, *) ' INFO: returns some information about cp2k.'
310 0 : WRITE (shell%iw, *) ' VERSION: returns shell version. (queried by ASE to assert features & bugfixes)'
311 0 : WRITE (shell%iw, *) ' WRITE_FILE: Writes content to a file (allows for using ASE over ssh).'
312 0 : WRITE (shell%iw, *) ' LOAD <inp-filename> [out-filename]: loads the filename, returns the env_id, or -1 in case of error'
313 0 : WRITE (shell%iw, *) ' out-filename is optional and defaults to <inp-filename>.out'
314 0 : WRITE (shell%iw, *) ' use "__STD_OUT__" for printing to the screen'
315 0 : WRITE (shell%iw, *) ' BG_LOAD <filename>: loads the filename, without returning the env_id'
316 0 : WRITE (shell%iw, *) ' LAST_ENV_ID: returns the env_id of the last environment loaded'
317 0 : WRITE (shell%iw, *) ' DESTROY [env_id]: destroys the given environment (last and default env'
318 0 : WRITE (shell%iw, *) ' might become invalid)'
319 0 : WRITE (shell%iw, *) ' NATOM [env_id]: returns the number of atoms in the environment env_id'
320 0 : WRITE (shell%iw, *) ' SET_POS [env_id]: sets the positions of the atoms, should be followed'
321 0 : WRITE (shell%iw, *) ' by natom*3 (on a line) and then all the positions. Returns the max'
322 0 : WRITE (shell%iw, *) ' change of the coordinates (useful to avoid extra calculations).'
323 0 : WRITE (shell%iw, *) ' SET_POS_FILE <filename> [env_id]: sets the positions of the atoms from a file.'
324 0 : WRITE (shell%iw, *) ' Returns the max change of the coordinates.'
325 0 : WRITE (shell%iw, *) ' SET_CELL [env_id]: sets the cell, should be followed by 9 numbers'
326 0 : WRITE (shell%iw, *) ' GET_CELL [env_id]: gets the cell vectors'
327 0 : WRITE (shell%iw, *) ' GET_STRESS [env_id]: gets the stress tensor of the last calculation on env_id'
328 0 : WRITE (shell%iw, *) ' GET_POS [env_id]: gets the positions of the atoms, returns'
329 0 : WRITE (shell%iw, *) ' natom*3 (on a line) and then all the positions then "* END" '
330 0 : WRITE (shell%iw, *) ' (alone on a line)'
331 0 : WRITE (shell%iw, *) ' GET_E [env_id]: gets the energy of the last calculation on env_id'
332 0 : WRITE (shell%iw, *) ' GET_F [env_id]: gets the forces on the atoms,of the last calculation on '
333 0 : WRITE (shell%iw, *) ' env_id, if only the energy was calculated the content is undefined. Returns'
334 0 : WRITE (shell%iw, *) ' natom*3 (on a line) and then all the forces then "* END" (alone on'
335 0 : WRITE (shell%iw, *) ' a line)'
336 0 : WRITE (shell%iw, *) ' CALC_E [env_id]: calculate the energy and returns it'
337 0 : WRITE (shell%iw, *) ' EVAL_E [env_id]: calculate the energy (without returning it)'
338 0 : WRITE (shell%iw, *) ' CALC_EF [env_id]: calculate energy and forces and returns them,'
339 0 : WRITE (shell%iw, *) ' first the energy on a line, then the natom*3 (on a line)'
340 0 : WRITE (shell%iw, *) ' and finally all the values and "* END" (alone on a line)'
341 0 : WRITE (shell%iw, *) ' EVAL_EF [env_id]: calculate the energy and forces (without returning them)'
342 0 : WRITE (shell%iw, *) ' RUN <inp-filename> <out-filename>: run the given input file'
343 0 : WRITE (shell%iw, *) ' HARSH: stops on any error'
344 0 : WRITE (shell%iw, *) ' PERMISSIVE: stops only on serious errors'
345 0 : WRITE (shell%iw, *) ' UNITS: returns the units used for energy and position'
346 0 : WRITE (shell%iw, *) ' UNITS_EV_A: sets the units to electron volt (energy) and Angstrom (positions)'
347 0 : WRITE (shell%iw, *) ' UNITS_AU: sets the units atomic units'
348 0 : WRITE (shell%iw, *) ' CD <dir>: change working directory'
349 0 : WRITE (shell%iw, *) ' PWD: print working directory'
350 0 : WRITE (shell%iw, *) ' EXIT: Quit the shell'
351 0 : WRITE (shell%iw, *) ' HELP: writes the present help'
352 0 : CALL m_flush(shell%iw)
353 : END IF
354 0 : END SUBROUTINE help_command
355 :
356 : ! **************************************************************************************************
357 : !> \brief ...
358 : !> \param shell ...
359 : ! **************************************************************************************************
360 0 : 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 0 : IF (shell%iw > 0) THEN
367 0 : CALL m_getcwd(cwd)
368 0 : CALL m_getpid(pid)
369 0 : CALL m_getlog(user_name)
370 0 : CALL m_hostnm(host_name)
371 : WRITE (UNIT=shell%iw, FMT="(A,A)") &
372 0 : " PROGRAM STARTED ON ", TRIM(host_name)
373 : WRITE (UNIT=shell%iw, FMT="(A,A)") &
374 0 : " PROGRAM STARTED BY ", TRIM(user_name)
375 : WRITE (UNIT=shell%iw, FMT="(A,i10)") &
376 0 : " PROGRAM PROCESS ID ", pid
377 : WRITE (UNIT=shell%iw, FMT="(A,A)") &
378 0 : " PROGRAM STARTED IN ", TRIM(cwd)
379 : WRITE (UNIT=shell%iw, FMT="(/,T2,A,T31,A50)") &
380 0 : "CP2K| version string: ", &
381 0 : ADJUSTR(TRIM(cp2k_version))
382 : WRITE (UNIT=shell%iw, FMT="(T2,A,T41,A40)") &
383 0 : "CP2K| source code revision number:", &
384 0 : ADJUSTR(compile_revision)
385 : WRITE (UNIT=shell%iw, FMT="(T2,A,T41,A40)") &
386 0 : "CP2K| is freely available from ", &
387 0 : ADJUSTR(TRIM(cp2k_home))
388 : WRITE (UNIT=shell%iw, FMT="(T2,A,T31,A50)") &
389 0 : "CP2K| Program compiled at", &
390 0 : ADJUSTR(compile_date(1:MIN(50, LEN(compile_date))))
391 : WRITE (UNIT=shell%iw, FMT="(T2,A,T31,A50)") &
392 0 : "CP2K| Program compiled on", &
393 0 : ADJUSTR(compile_host(1:MIN(50, LEN(compile_host))))
394 : WRITE (UNIT=shell%iw, FMT="(T2,A,T31,A50)") &
395 0 : "CP2K| Program compiled for", &
396 0 : ADJUSTR(compile_arch(1:MIN(50, LEN(compile_arch))))
397 :
398 0 : CALL print_cp2k_license(shell%iw)
399 0 : CALL m_flush(shell%iw)
400 : END IF
401 :
402 0 : END SUBROUTINE info_license_command
403 :
404 : ! **************************************************************************************************
405 : !> \brief ...
406 : !> \param shell ...
407 : ! **************************************************************************************************
408 0 : SUBROUTINE version_command(shell)
409 : TYPE(cp2k_shell_type) :: shell
410 :
411 0 : IF (shell%iw > 0) THEN
412 0 : WRITE (shell%iw, '(a,a)') "CP2K Shell Version: ", CP2K_SHELL_VERSION
413 0 : CALL m_flush(shell%iw)
414 : END IF
415 0 : END SUBROUTINE version_command
416 :
417 : ! **************************************************************************************************
418 : !> \brief ...
419 : !> \param shell ...
420 : ! **************************************************************************************************
421 0 : 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 0 : IF (shell%iw > 0) THEN
428 0 : READ (*, '(a)', iostat=iostat) out_filename
429 0 : IF (iostat /= 0) CPABORT('WRITE_FILE bad filename')
430 0 : READ (*, *, iostat=iostat) n_lines
431 0 : IF (iostat /= 0) CPABORT('WRITE_FILE bad number of lines')
432 : CALL open_file(file_name=TRIM(out_filename), unit_number=file_unit, &
433 0 : file_status="UNKNOWN", file_form="FORMATTED", file_action="WRITE")
434 0 : DO i = 1, n_lines
435 0 : READ (*, '(a)', iostat=iostat) line
436 0 : IF (iostat /= 0) CPABORT('WRITE_FILE read error')
437 0 : WRITE (file_unit, '(a)', iostat=iostat) TRIM(line)
438 0 : IF (iostat /= 0) CPABORT('WRITE_FILE write error')
439 : END DO
440 0 : READ (*, '(a)', iostat=iostat) line
441 0 : IF (iostat /= 0) CPABORT('WRITE_FILE read error')
442 0 : IF (TRIM(line) /= "*END") CPABORT('WRITE_FILE bad end delimiter')
443 0 : CALL close_file(unit_number=file_unit)
444 : END IF
445 0 : END SUBROUTINE write_file_command
446 :
447 : ! **************************************************************************************************
448 : !> \brief ...
449 : !> \param shell ...
450 : ! **************************************************************************************************
451 0 : SUBROUTINE get_last_env_id(shell)
452 : TYPE(cp2k_shell_type) :: shell
453 :
454 0 : IF (shell%iw > 0) THEN
455 0 : WRITE (shell%iw, '(i10)') shell%env_id
456 0 : CALL m_flush(shell%iw)
457 : END IF
458 0 : END SUBROUTINE get_last_env_id
459 :
460 : ! **************************************************************************************************
461 : !> \brief ...
462 : !> \param shell ...
463 : !> \param input_declaration ...
464 : !> \param arg1 ...
465 : ! **************************************************************************************************
466 0 : 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 0 : 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 0 : owns_out_unit=.TRUE., ierr=ierr)
479 0 : IF (ierr /= 0) THEN
480 0 : shell%env_id = -1
481 0 : 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 0 : 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 0 : IF (.NOT. my_assert(LEN_TRIM(arg1) > 0, "file argument missing", shell)) RETURN
501 0 : inp_filename = arg1
502 0 : out_filename = TRIM(inp_filename)//'.out'
503 0 : 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 0 : owns_out_unit=.TRUE., ierr=ierr)
509 0 : IF (ierr /= 0) THEN
510 0 : shell%env_id = -1
511 0 : CALL print_error("create_force_env failed", shell)
512 0 : ELSE IF (shell%iw > 0) THEN
513 0 : WRITE (shell%iw, '(i10)') shell%env_id
514 0 : CALL m_flush(shell%iw)
515 : END IF
516 0 : END SUBROUTINE load_command
517 :
518 : ! **************************************************************************************************
519 : !> \brief ...
520 : !> \param shell ...
521 : !> \param arg1 ...
522 : ! **************************************************************************************************
523 0 : 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 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
530 0 : CALL destroy_force_env(shell%env_id, ierr)
531 0 : shell%env_id = -1
532 0 : 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 0 : 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 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
547 0 : CALL get_natom(shell%env_id, n_atom, ierr)
548 0 : IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
549 0 : IF (shell%iw > 0) THEN
550 0 : WRITE (shell%iw, '(i10)', iostat=iostat) n_atom
551 0 : 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 0 : 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 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: pos
567 :
568 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
569 0 : CALL get_natom(shell%env_id, n_atom, ierr)
570 0 : IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
571 0 : ALLOCATE (pos(3*n_atom))
572 0 : IF (shell%iw > 0) THEN
573 0 : READ (*, *, iostat=iostat) n_atom
574 0 : IF (.NOT. my_assert(iostat == 0, 'setpos read n_atom failed', shell)) RETURN
575 0 : IF (.NOT. my_assert(n_atom == SIZE(pos), 'setpos invalid number of atoms', shell)) RETURN
576 0 : READ (*, *, iostat=iostat) pos
577 0 : IF (.NOT. my_assert(iostat == 0, 'setpos read coords failed', shell)) RETURN
578 0 : pos(:) = pos(:)/shell%pos_fact
579 0 : READ (*, '(a)', iostat=iostat) line
580 0 : IF (.NOT. my_assert(iostat == 0, 'setpos read END failed', shell)) RETURN
581 0 : CALL uppercase(line)
582 0 : IF (.NOT. my_assert(TRIM(line) == '*END', 'missing *END', shell)) RETURN
583 : END IF
584 :
585 0 : CALL send_pos_updates(shell, n_atom, pos)
586 0 : DEALLOCATE (pos)
587 0 : 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 0 : 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 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: pos
601 :
602 0 : IF (.NOT. parse_env_id(arg2, shell)) RETURN
603 0 : CALL get_natom(shell%env_id, n_atom, ierr)
604 0 : IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
605 0 : ALLOCATE (pos(3*n_atom))
606 :
607 0 : IF (shell%iw > 0) THEN
608 : CALL open_file(file_name=TRIM(arg1), unit_number=file_unit, &
609 0 : file_status="OLD", file_form="FORMATTED", file_action="READ")
610 0 : READ (file_unit, *, iostat=iostat) n_atom
611 0 : IF (.NOT. my_assert(iostat == 0, 'setpos read n_atom failed', shell)) RETURN
612 0 : IF (.NOT. my_assert(n_atom == SIZE(pos), 'setpos invalid number of atoms', shell)) RETURN
613 0 : READ (file_unit, *, iostat=iostat) pos
614 0 : IF (.NOT. my_assert(iostat == 0, 'setpos read coords failed', shell)) RETURN
615 0 : pos(:) = pos(:)/shell%pos_fact
616 0 : CALL close_file(unit_number=file_unit)
617 : END IF
618 :
619 0 : CALL send_pos_updates(shell, n_atom, pos)
620 0 : DEALLOCATE (pos)
621 0 : 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 0 : 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 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: old_pos
637 :
638 : ! Get the current positions
639 0 : ALLOCATE (old_pos(3*n_atom))
640 0 : CALL shell%para_env%bcast(pos)
641 0 : CALL get_pos(shell%env_id, old_pos, n_el=3*n_atom, ierr=ierr)
642 0 : IF (.NOT. my_assert(ierr == 0, 'get_pos error', shell)) RETURN
643 :
644 : ! Set, measure the change, print do to shell
645 0 : CALL set_pos(shell%env_id, new_pos=pos, n_el=3*n_atom, ierr=ierr)
646 0 : IF (.NOT. my_assert(ierr == 0, 'set_pos error', shell)) RETURN
647 0 : max_change = 0.0_dp
648 0 : DO i = 1, SIZE(pos)
649 0 : max_change = MAX(max_change, ABS(pos(i) - old_pos(i)))
650 : END DO
651 0 : DEALLOCATE (old_pos)
652 0 : IF (shell%iw > 0) THEN
653 0 : WRITE (shell%iw, '(ES22.13)') max_change*shell%pos_fact
654 0 : CALL m_flush(shell%iw)
655 : END IF
656 0 : END SUBROUTINE send_pos_updates
657 :
658 : ! **************************************************************************************************
659 : !> \brief ...
660 : !> \param shell ...
661 : !> \param arg1 ...
662 : ! **************************************************************************************************
663 0 : 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 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
671 0 : IF (shell%iw > 0) THEN
672 0 : READ (*, *, iostat=iostat) cell
673 0 : IF (.NOT. my_assert(iostat == 0, 'setcell read failed', shell)) RETURN
674 0 : cell(:, :) = cell(:, :)/shell%pos_fact
675 : END IF
676 0 : CALL shell%para_env%bcast(cell)
677 0 : CALL set_cell(shell%env_id, new_cell=cell, ierr=ierr)
678 0 : 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 0 : 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 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
694 0 : CALL get_cell(shell%env_id, cell=cell, ierr=ierr)
695 0 : IF (.NOT. my_assert(ierr == 0, 'get_cell failed', shell)) RETURN
696 0 : cell(:, :) = cell(:, :)*shell%pos_fact
697 0 : IF (shell%iw > 0) THEN
698 0 : WRITE (shell%iw, '(9ES22.13)') cell
699 0 : 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 0 : 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 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
716 0 : CALL get_stress_tensor(shell%env_id, stress_tensor=stress_tensor, ierr=ierr)
717 0 : IF (.NOT. my_assert(ierr == 0, 'get_stress_tensor failed', shell)) RETURN
718 0 : stress_tensor(:, :) = stress_tensor(:, :)*(shell%e_fact/shell%pos_fact**3)
719 0 : IF (shell%iw > 0) THEN
720 0 : WRITE (shell%iw, '(9ES22.13)') stress_tensor
721 0 : 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 0 : 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 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: pos
736 :
737 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
738 0 : CALL get_natom(shell%env_id, n_atom, ierr)
739 0 : IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
740 0 : ALLOCATE (pos(3*n_atom))
741 0 : CALL get_pos(shell%env_id, pos=pos, n_el=3*n_atom, ierr=ierr)
742 0 : IF (.NOT. my_assert(ierr == 0, 'get_pos failed', shell)) RETURN
743 0 : IF (shell%iw > 0) THEN
744 0 : WRITE (shell%iw, '(i10)') 3*n_atom
745 0 : WRITE (shell%iw, '(3ES22.13)') pos(:)*shell%pos_fact
746 0 : WRITE (shell%iw, '(a)') "* END"
747 0 : CALL m_flush(shell%iw)
748 : END IF
749 0 : DEALLOCATE (pos)
750 0 : END SUBROUTINE get_pos_command
751 :
752 : ! **************************************************************************************************
753 : !> \brief ...
754 : !> \param shell ...
755 : !> \param arg1 ...
756 : ! **************************************************************************************************
757 0 : 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 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
765 0 : CALL get_energy(shell%env_id, e_pot, ierr)
766 0 : IF (.NOT. my_assert(ierr == 0, 'get_energy failed', shell)) RETURN
767 0 : IF (shell%iw > 0) THEN
768 0 : WRITE (shell%iw, '(ES22.13)') e_pot*shell%e_fact
769 0 : 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 0 : SUBROUTINE eval_energy_command(shell, arg1)
779 : TYPE(cp2k_shell_type) :: shell
780 : CHARACTER(LEN=*), INTENT(IN) :: arg1
781 :
782 : INTEGER :: ierr
783 :
784 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
785 0 : CALL calc_energy_force(shell%env_id, calc_force=.FALSE., ierr=ierr)
786 0 : 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 0 : 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 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
802 0 : CALL calc_energy_force(shell%env_id, calc_force=.FALSE., ierr=ierr)
803 0 : IF (.NOT. my_assert(ierr == 0, 'calc_energy_force failed', shell)) RETURN
804 0 : CALL get_energy(shell%env_id, e_pot, ierr)
805 0 : IF (.NOT. my_assert(ierr == 0, 'get_energy failed', shell)) RETURN
806 0 : IF (shell%iw > 0) THEN
807 0 : WRITE (shell%iw, '(ES22.13)') e_pot*shell%e_fact
808 0 : 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 0 : 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 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
824 0 : CALL calc_energy_force(shell%env_id, calc_force=.TRUE., ierr=ierr)
825 0 : 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 0 : 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 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: forces
839 :
840 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
841 0 : CALL get_natom(shell%env_id, n_atom, ierr)
842 0 : IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
843 0 : ALLOCATE (forces(3*n_atom))
844 0 : CALL get_force(shell%env_id, frc=forces, n_el=3*n_atom, ierr=ierr)
845 0 : IF (.NOT. my_assert(ierr == 0, 'get_force failed', shell)) RETURN
846 0 : forces(:) = forces(:)*(shell%e_fact/shell%pos_fact)
847 0 : IF (shell%iw > 0) THEN
848 0 : WRITE (shell%iw, '(i10)') 3*n_atom
849 0 : WRITE (shell%iw, '(3ES22.13)') forces
850 0 : WRITE (shell%iw, '("* END")')
851 0 : CALL m_flush(shell%iw)
852 : END IF
853 0 : DEALLOCATE (forces)
854 0 : END SUBROUTINE get_forces_command
855 :
856 : ! **************************************************************************************************
857 : !> \brief ...
858 : !> \param shell ...
859 : !> \param arg1 ...
860 : ! **************************************************************************************************
861 0 : 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 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: forces
868 :
869 0 : IF (.NOT. parse_env_id(arg1, shell)) RETURN
870 0 : CALL calc_energy_force(shell%env_id, calc_force=.TRUE., ierr=ierr)
871 0 : IF (.NOT. my_assert(ierr == 0, 'calc_energy_force failed', shell)) RETURN
872 0 : CALL get_energy(shell%env_id, e_pot, ierr)
873 0 : IF (.NOT. my_assert(ierr == 0, 'get_energy failed', shell)) RETURN
874 0 : CALL get_natom(shell%env_id, n_atom, ierr)
875 0 : IF (.NOT. my_assert(ierr == 0, 'get_natom failed', shell)) RETURN
876 0 : ALLOCATE (forces(3*n_atom))
877 0 : CALL get_force(shell%env_id, frc=forces, n_el=3*n_atom, ierr=ierr)
878 0 : IF (.NOT. my_assert(ierr == 0, 'get_energy failed', shell)) RETURN
879 0 : IF (shell%iw > 0) THEN
880 0 : WRITE (shell%iw, '(ES22.13)') e_pot*shell%e_fact
881 0 : WRITE (shell%iw, '(i10)') 3*n_atom
882 0 : WRITE (shell%iw, '(3ES22.13)') forces*(shell%e_fact/shell%pos_fact)
883 0 : WRITE (shell%iw, '("* END")')
884 0 : CALL m_flush(shell%iw)
885 : END IF
886 0 : DEALLOCATE (forces)
887 0 : 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 0 : 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 0 : IF (.NOT. my_assert(LEN_TRIM(arg1) > 0, "input-file argument missing", shell)) RETURN
902 0 : IF (.NOT. my_assert(LEN_TRIM(arg2) > 0, "input-file argument missing", shell)) RETURN
903 0 : CALL run_input(input_declaration, arg1, arg2, empty_initial_variables)
904 : END SUBROUTINE run_command
905 :
906 : ! **************************************************************************************************
907 : !> \brief ...
908 : !> \param shell ...
909 : ! **************************************************************************************************
910 0 : SUBROUTINE set_units_ev_a(shell)
911 : TYPE(cp2k_shell_type) :: shell
912 :
913 0 : shell%e_fact = evolt
914 0 : shell%pos_fact = angstrom
915 0 : shell%units = 'eV_A'
916 0 : END SUBROUTINE set_units_ev_a
917 :
918 : ! **************************************************************************************************
919 : !> \brief ...
920 : !> \param shell ...
921 : ! **************************************************************************************************
922 0 : SUBROUTINE set_units_au(shell)
923 : TYPE(cp2k_shell_type) :: shell
924 :
925 0 : shell%e_fact = 1.0_dp
926 0 : shell%pos_fact = 1.0_dp
927 0 : shell%units = 'au'
928 0 : END SUBROUTINE set_units_au
929 :
930 : ! **************************************************************************************************
931 : !> \brief ...
932 : !> \param shell ...
933 : ! **************************************************************************************************
934 0 : SUBROUTINE get_units(shell)
935 : TYPE(cp2k_shell_type) :: shell
936 :
937 0 : IF (shell%iw > 0) THEN
938 0 : WRITE (shell%iw, '(a)') TRIM(shell%units)
939 0 : CALL m_flush(shell%iw)
940 : END IF
941 0 : END SUBROUTINE get_units
942 :
943 : ! **************************************************************************************************
944 : !> \brief ...
945 : !> \param shell ...
946 : !> \param arg1 ...
947 : ! **************************************************************************************************
948 0 : SUBROUTINE set_pwd_command(shell, arg1)
949 : TYPE(cp2k_shell_type) :: shell
950 : CHARACTER(LEN=*), INTENT(IN) :: arg1
951 :
952 : INTEGER :: ierr
953 :
954 0 : IF (.NOT. my_assert(LEN_TRIM(arg1) > 0, 'missing directory', shell)) RETURN
955 0 : CALL m_chdir(arg1, ierr)
956 0 : 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 0 : SUBROUTINE get_pwd_command(shell)
964 : TYPE(cp2k_shell_type) :: shell
965 :
966 : CHARACTER(LEN=default_path_length) :: cwd
967 :
968 0 : IF (shell%iw > 0) THEN
969 0 : CALL m_getcwd(cwd)
970 0 : WRITE (shell%iw, '(a)') TRIM(cwd)
971 : END IF
972 0 : END SUBROUTINE get_pwd_command
973 :
974 0 : END MODULE cp2k_shell
|