Line data Source code
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 Methods to performs a path integral run
10 : !> \author fawzi
11 : !> \par History
12 : !> 02.2005 created [fawzi]
13 : !> 11.2006 modified so it might actually work [hforbert]
14 : !> 10.2015 added RPMD propagator
15 : !> 10.2015 added exact harmonic integrator [Felix Uhl]
16 : !> \note quick & dirty rewrite of my python program
17 : ! **************************************************************************************************
18 : MODULE pint_methods
19 :
20 : USE atomic_kind_list_types, ONLY: atomic_kind_list_type
21 : USE atomic_kind_types, ONLY: atomic_kind_type,&
22 : get_atomic_kind
23 : USE bibliography, ONLY: Brieuc2016,&
24 : Ceriotti2010,&
25 : Ceriotti2012,&
26 : Shiga2022,&
27 : cite_reference
28 : USE cell_types, ONLY: cell_type
29 : USE constraint, ONLY: rattle_control,&
30 : shake_control,&
31 : shake_update_targets
32 : USE constraint_util, ONLY: getold
33 : USE cp_external_control, ONLY: external_control
34 : USE cp_log_handling, ONLY: cp_get_default_logger,&
35 : cp_logger_get_default_io_unit,&
36 : cp_logger_type,&
37 : cp_to_string
38 : USE cp_output_handling, ONLY: cp_add_iter_level,&
39 : cp_iterate,&
40 : cp_p_file,&
41 : cp_print_key_finished_output,&
42 : cp_print_key_should_output,&
43 : cp_print_key_unit_nr,&
44 : cp_rm_iter_level
45 : USE cp_subsys_types, ONLY: cp_subsys_get,&
46 : cp_subsys_type
47 : USE cp_units, ONLY: cp_unit_from_cp2k,&
48 : cp_unit_to_cp2k
49 : USE distribution_1d_types, ONLY: distribution_1d_type
50 : USE f77_interface, ONLY: f_env_add_defaults,&
51 : f_env_rm_defaults,&
52 : f_env_type
53 : USE force_env_types, ONLY: force_env_get
54 : USE gle_system_dynamics, ONLY: gle_cholesky_stab,&
55 : gle_matrix_exp,&
56 : restart_gle
57 : USE gle_system_types, ONLY: gle_dealloc,&
58 : gle_init,&
59 : gle_thermo_create
60 : USE global_types, ONLY: global_environment_type
61 : USE helium_interactions, ONLY: helium_intpot_scan
62 : USE helium_io, ONLY: helium_write_cubefile
63 : USE helium_methods, ONLY: helium_create,&
64 : helium_init,&
65 : helium_release
66 : USE helium_sampling, ONLY: helium_do_run,&
67 : helium_step
68 : USE helium_types, ONLY: helium_solvent_p_type
69 : USE input_constants, ONLY: integrate_exact,&
70 : integrate_numeric,&
71 : propagator_bcmd,&
72 : propagator_cmd,&
73 : propagator_rpmd,&
74 : transformation_normal,&
75 : transformation_stage
76 : USE input_cp2k_restarts, ONLY: write_restart
77 : USE input_section_types, ONLY: &
78 : section_type, section_vals_add_values, section_vals_get, section_vals_get_subs_vals, &
79 : section_vals_release, section_vals_retain, section_vals_type, section_vals_val_get, &
80 : section_vals_val_set, section_vals_val_unset
81 : USE kinds, ONLY: default_path_length,&
82 : default_string_length,&
83 : dp
84 : USE machine, ONLY: m_flush,&
85 : m_walltime
86 : USE mathconstants, ONLY: twopi
87 : USE mathlib, ONLY: gcd
88 : USE message_passing, ONLY: mp_comm_self,&
89 : mp_para_env_type
90 : USE molecule_kind_list_types, ONLY: molecule_kind_list_type
91 : USE molecule_kind_types, ONLY: molecule_kind_type
92 : USE molecule_list_types, ONLY: molecule_list_type
93 : USE molecule_types, ONLY: global_constraint_type,&
94 : molecule_type
95 : USE parallel_rng_types, ONLY: GAUSSIAN,&
96 : rng_stream_type
97 : USE particle_list_types, ONLY: particle_list_type
98 : USE particle_types, ONLY: particle_type
99 : USE pint_gle, ONLY: pint_calc_gle_energy,&
100 : pint_gle_init,&
101 : pint_gle_step
102 : USE pint_io, ONLY: pint_write_action,&
103 : pint_write_centroids,&
104 : pint_write_com,&
105 : pint_write_ener,&
106 : pint_write_line,&
107 : pint_write_rgyr,&
108 : pint_write_step_info,&
109 : pint_write_trajectory
110 : USE pint_normalmode, ONLY: normalmode_calc_uf_h,&
111 : normalmode_env_create,&
112 : normalmode_init_masses,&
113 : normalmode_release
114 : USE pint_piglet, ONLY: pint_calc_piglet_energy,&
115 : pint_piglet_create,&
116 : pint_piglet_init,&
117 : pint_piglet_release,&
118 : pint_piglet_step
119 : USE pint_pile, ONLY: pint_calc_pile_energy,&
120 : pint_pile_init,&
121 : pint_pile_release,&
122 : pint_pile_step
123 : USE pint_public, ONLY: pint_levy_walk
124 : USE pint_qtb, ONLY: pint_calc_qtb_energy,&
125 : pint_qtb_init,&
126 : pint_qtb_release,&
127 : pint_qtb_step
128 : USE pint_staging, ONLY: staging_calc_uf_h,&
129 : staging_env_create,&
130 : staging_init_masses,&
131 : staging_release
132 : USE pint_transformations, ONLY: pint_f2uf,&
133 : pint_u2x,&
134 : pint_x2u
135 : USE pint_types, ONLY: &
136 : e_conserved_id, e_kin_thermo_id, e_kin_virial_id, e_potential_id, pint_env_type, &
137 : thermostat_gle, thermostat_none, thermostat_nose, thermostat_piglet, thermostat_pile, &
138 : thermostat_qtb
139 : USE replica_methods, ONLY: rep_env_calc_e_f,&
140 : rep_env_create
141 : USE replica_types, ONLY: rep_env_release,&
142 : replica_env_type
143 : USE simpar_types, ONLY: create_simpar_type,&
144 : release_simpar_type
145 : #include "../base/base_uses.f90"
146 :
147 : IMPLICIT NONE
148 : PRIVATE
149 :
150 : LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .TRUE.
151 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pint_methods'
152 :
153 : PUBLIC :: do_pint_run
154 :
155 : CONTAINS
156 :
157 : ! ***************************************************************************
158 : !> \brief Create a path integral environment
159 : !> \param pint_env ...
160 : !> \param input ...
161 : !> \param input_declaration ...
162 : !> \param para_env ...
163 : !> \par History
164 : !> Fixed some bugs [hforbert]
165 : !> Added normal mode transformation [hforbert]
166 : !> 10.2015 Added RPMD propagator and harmonic integrator [Felix Uhl]
167 : !> 10.2018 Added centroid constraints [cschran+rperez]
168 : !> 10.2021 Added beadwise constraints [lduran]
169 : !> \author fawzi
170 : !> \note Might return an unassociated pointer in parallel on the processors
171 : !> that are not needed.
172 : ! **************************************************************************************************
173 1682 : SUBROUTINE pint_create(pint_env, input, input_declaration, para_env)
174 :
175 : TYPE(pint_env_type), INTENT(OUT) :: pint_env
176 : TYPE(section_vals_type), POINTER :: input
177 : TYPE(section_type), POINTER :: input_declaration
178 : TYPE(mp_para_env_type), POINTER :: para_env
179 :
180 : CHARACTER(len=*), PARAMETER :: routineN = 'pint_create'
181 :
182 : CHARACTER(len=2*default_string_length) :: msg
183 : CHARACTER(len=default_path_length) :: output_file_name, project_name
184 : INTEGER :: handle, iat, ibead, icont, idim, idir, &
185 : ierr, ig, itmp, nrep, prep
186 : LOGICAL :: explicit, ltmp
187 : REAL(kind=dp) :: dt, mass, omega
188 : TYPE(cp_subsys_type), POINTER :: subsys
189 : TYPE(f_env_type), POINTER :: f_env
190 : TYPE(global_constraint_type), POINTER :: gci
191 : TYPE(particle_list_type), POINTER :: particles
192 : TYPE(replica_env_type), POINTER :: rep_env
193 : TYPE(section_vals_type), POINTER :: constraint_section, gle_section, nose_section, &
194 : piglet_section, pile_section, pint_section, qtb_section, transform_section
195 :
196 58 : CALL timeset(routineN, handle)
197 :
198 58 : NULLIFY (f_env, subsys, particles, nose_section, gle_section, gci)
199 :
200 58 : CPASSERT(ASSOCIATED(input))
201 58 : CPASSERT(input%ref_count > 0)
202 58 : NULLIFY (rep_env)
203 58 : pint_section => section_vals_get_subs_vals(input, "MOTION%PINT")
204 58 : CALL section_vals_val_get(pint_section, "p", i_val=nrep)
205 : CALL section_vals_val_get(pint_section, "proc_per_replica", &
206 58 : i_val=prep)
207 : ! Maybe let the user have his/her way as long as prep is
208 : ! within the bounds of number of CPUs??
209 58 : IF ((prep < 1) .OR. (prep > para_env%num_pe) .OR. &
210 : (MOD(prep*nrep, para_env%num_pe) /= 0)) THEN
211 2 : prep = para_env%num_pe/gcd(para_env%num_pe, nrep)
212 2 : IF (para_env%is_source()) THEN
213 1 : WRITE (UNIT=msg, FMT=*) "PINT WARNING: Adjusting number of processors per replica to ", prep
214 57 : CPWARN(msg)
215 : END IF
216 : END IF
217 :
218 : ! replica_env modifies the global input structure - which is wrong - one
219 : ! of the side effects is the inifite adding of the -r-N string to the
220 : ! project name and the output file name, which corrupts restart files.
221 : ! For now: save the project name and output file name and restore them
222 : ! after the rep_env_create has executed - the initialization of the
223 : ! replicas will run correctly anyways.
224 : ! TODO: modify rep_env so that it behaves better
225 58 : CALL section_vals_val_get(input, "GLOBAL%PROJECT_NAME", c_val=project_name)
226 58 : CALL section_vals_val_get(input, "GLOBAL%OUTPUT_FILE_NAME", c_val=output_file_name)
227 : CALL rep_env_create(rep_env, para_env=para_env, input=input, &
228 58 : input_declaration=input_declaration, nrep=nrep, prep=prep, row_force=.TRUE.)
229 58 : CALL section_vals_val_set(input, "GLOBAL%PROJECT_NAME", c_val=TRIM(project_name))
230 58 : IF (LEN_TRIM(output_file_name) > 0) THEN
231 0 : CALL section_vals_val_set(input, "GLOBAL%OUTPUT_FILE_NAME", c_val=TRIM(output_file_name))
232 : ELSE
233 58 : CALL section_vals_val_unset(input, "GLOBAL%OUTPUT_FILE_NAME")
234 : END IF
235 58 : IF (.NOT. ASSOCIATED(rep_env)) RETURN
236 :
237 58 : NULLIFY (pint_env%logger)
238 58 : pint_env%logger => cp_get_default_logger()
239 58 : CALL cp_add_iter_level(pint_env%logger%iter_info, "PINT")
240 :
241 58 : NULLIFY (pint_env%replicas, pint_env%input, pint_env%staging_env, &
242 58 : pint_env%normalmode_env, pint_env%propagator)
243 58 : pint_env%p = nrep
244 58 : pint_env%replicas => rep_env
245 58 : pint_env%ndim = rep_env%ndim
246 58 : pint_env%input => input
247 :
248 58 : CALL section_vals_retain(pint_env%input)
249 :
250 : ! get first step, last step, number of steps, etc
251 : CALL section_vals_val_get(input, "MOTION%PINT%ITERATION", &
252 58 : i_val=itmp)
253 58 : pint_env%first_step = itmp
254 : CALL section_vals_val_get(input, "MOTION%PINT%MAX_STEP", &
255 58 : explicit=explicit)
256 58 : IF (explicit) THEN
257 : CALL section_vals_val_get(input, "MOTION%PINT%MAX_STEP", &
258 0 : i_val=itmp)
259 0 : pint_env%last_step = itmp
260 0 : pint_env%num_steps = pint_env%last_step - pint_env%first_step
261 : ELSE
262 : CALL section_vals_val_get(input, "MOTION%PINT%NUM_STEPS", &
263 58 : i_val=itmp)
264 58 : pint_env%num_steps = itmp
265 58 : pint_env%last_step = pint_env%first_step + pint_env%num_steps
266 : END IF
267 :
268 : CALL section_vals_val_get(pint_section, "DT", &
269 58 : r_val=pint_env%dt)
270 58 : pint_env%t = pint_env%first_step*pint_env%dt
271 :
272 58 : CALL section_vals_val_get(pint_section, "nrespa", i_val=pint_env%nrespa)
273 58 : CALL section_vals_val_get(pint_section, "Temp", r_val=pint_env%kT)
274 : CALL section_vals_val_get(pint_section, "T_TOL", &
275 58 : r_val=pint_env%t_tol)
276 :
277 58 : CALL section_vals_val_get(pint_section, "HARM_INT", i_val=pint_env%harm_integrator)
278 :
279 58 : ALLOCATE (pint_env%propagator)
280 : CALL section_vals_val_get(pint_section, "propagator", &
281 58 : i_val=pint_env%propagator%prop_kind)
282 : !Initialize simulation temperature depending on the propagator
283 : !As well as the scaling factor for the physical potential
284 58 : IF (pint_env%propagator%prop_kind == propagator_rpmd) THEN
285 18 : pint_env%propagator%temp_phys2sim = REAL(pint_env%p, dp)
286 18 : pint_env%propagator%physpotscale = 1.0_dp
287 : ELSE
288 40 : pint_env%propagator%temp_phys2sim = 1.0_dp
289 40 : pint_env%propagator%physpotscale = 1.0_dp/REAL(pint_env%p, dp)
290 : END IF
291 58 : pint_env%propagator%temp_sim2phys = 1.0_dp/pint_env%propagator%temp_phys2sim
292 58 : pint_env%kT = pint_env%kT*pint_env%propagator%temp_phys2sim
293 :
294 : CALL section_vals_val_get(pint_section, "transformation", &
295 58 : i_val=pint_env%transform)
296 :
297 58 : IF ((pint_env%propagator%prop_kind == propagator_cmd) .AND. &
298 : (pint_env%transform /= transformation_normal)) THEN
299 0 : CPABORT("CMD propagator without normal modes not implemented!")
300 : END IF
301 :
302 58 : IF ((pint_env%propagator%prop_kind == propagator_bcmd) .AND. &
303 : (pint_env%transform /= transformation_normal)) THEN
304 0 : CPABORT("BCMD propagator without normal modes not implemented!")
305 : END IF
306 :
307 58 : NULLIFY (pint_env%tx, pint_env%tv, pint_env%tv_t, pint_env%tv_old, pint_env%tv_new, pint_env%tf)
308 :
309 58 : pint_env%nnos = 0
310 58 : pint_env%pimd_thermostat = thermostat_none
311 58 : nose_section => section_vals_get_subs_vals(input, "MOTION%PINT%NOSE")
312 58 : CALL section_vals_get(nose_section, explicit=explicit)
313 58 : IF (explicit) THEN
314 26 : IF (pint_env%propagator%prop_kind == propagator_rpmd) THEN
315 0 : CPABORT("RPMD propagator with Nose-thermostat not implemented!")
316 : END IF
317 26 : IF (pint_env%propagator%prop_kind == propagator_bcmd) THEN
318 0 : CPABORT("BCMD propagator with Nose-thermostat not implemented!")
319 : END IF
320 26 : CALL section_vals_val_get(nose_section, "nnos", i_val=pint_env%nnos)
321 26 : IF (pint_env%nnos > 0) THEN
322 26 : pint_env%pimd_thermostat = thermostat_nose
323 : ALLOCATE ( &
324 : pint_env%tx(pint_env%nnos, pint_env%p, pint_env%ndim), &
325 : pint_env%tv(pint_env%nnos, pint_env%p, pint_env%ndim), &
326 : pint_env%tv_t(pint_env%nnos, pint_env%p, pint_env%ndim), &
327 : pint_env%tv_old(pint_env%nnos, pint_env%p, pint_env%ndim), &
328 : pint_env%tv_new(pint_env%nnos, pint_env%p, pint_env%ndim), &
329 520 : pint_env%tf(pint_env%nnos, pint_env%p, pint_env%ndim))
330 88244 : pint_env%tx = 0._dp
331 88244 : pint_env%tv = 0._dp
332 88244 : pint_env%tv_t = 0._dp
333 88244 : pint_env%tv_old = 0._dp
334 88244 : pint_env%tv_new = 0._dp
335 88244 : pint_env%tf = 0._dp
336 : END IF
337 : END IF
338 :
339 58 : pint_env%beta = 1._dp/(pint_env%kT*pint_env%propagator%temp_sim2phys)
340 : !TODO
341 : ! v_tol not in current input structure
342 : ! should also probably be part of nose_section
343 : ! CALL section_vals_val_get(transform_section,"v_tol_nose",r_val=pint_env%v_tol)
344 : !MK ... but we have to initialise v_tol
345 58 : pint_env%v_tol = 0.0_dp ! to be fixed
346 :
347 : pint_env%randomG = rng_stream_type( &
348 : name="pint_randomG", &
349 : distribution_type=GAUSSIAN, &
350 58 : extended_precision=.TRUE.)
351 :
352 174 : ALLOCATE (pint_env%e_pot_bead(pint_env%p))
353 410 : pint_env%e_pot_bead = 0._dp
354 58 : pint_env%e_pot_h = 0._dp
355 58 : pint_env%e_kin_beads = 0._dp
356 58 : pint_env%e_pot_t = 0._dp
357 58 : pint_env%e_gle = 0._dp
358 58 : pint_env%e_pile = 0._dp
359 58 : pint_env%e_piglet = 0._dp
360 58 : pint_env%e_qtb = 0._dp
361 58 : pint_env%e_kin_t = 0._dp
362 290 : pint_env%energy(:) = 0.0_dp
363 :
364 : !TODO: rearrange to use standard nose hoover chain functions/data types
365 :
366 : ALLOCATE ( &
367 : pint_env%x(pint_env%p, pint_env%ndim), &
368 : pint_env%v(pint_env%p, pint_env%ndim), &
369 : pint_env%f(pint_env%p, pint_env%ndim), &
370 : pint_env%external_f(pint_env%p, pint_env%ndim), &
371 : pint_env%ux(pint_env%p, pint_env%ndim), &
372 : pint_env%ux_t(pint_env%p, pint_env%ndim), &
373 : pint_env%uv(pint_env%p, pint_env%ndim), &
374 : pint_env%uv_t(pint_env%p, pint_env%ndim), &
375 : pint_env%uv_new(pint_env%p, pint_env%ndim), &
376 : pint_env%uf(pint_env%p, pint_env%ndim), &
377 : pint_env%uf_h(pint_env%p, pint_env%ndim), &
378 : pint_env%centroid(pint_env%ndim), &
379 : pint_env%rtmp_ndim(pint_env%ndim), &
380 1682 : pint_env%rtmp_natom(pint_env%ndim/3))
381 362632 : pint_env%x = 0._dp
382 362632 : pint_env%v = 0._dp
383 362632 : pint_env%f = 0._dp
384 362632 : pint_env%external_f = 0._dp
385 362632 : pint_env%ux = 0._dp
386 362632 : pint_env%ux_t = 0._dp
387 362632 : pint_env%uv = 0._dp
388 362632 : pint_env%uv_t = 0._dp
389 362632 : pint_env%uv_new = 0._dp
390 362632 : pint_env%uf = 0._dp
391 362632 : pint_env%uf_h = 0._dp
392 64984 : pint_env%centroid(:) = 0.0_dp
393 64984 : pint_env%rtmp_ndim = 0._dp
394 21700 : pint_env%rtmp_natom = 0._dp
395 58 : pint_env%time_per_step = 0.0_dp
396 :
397 58 : IF (pint_env%transform == transformation_stage) THEN
398 : transform_section => section_vals_get_subs_vals(input, &
399 0 : "MOTION%PINT%STAGING")
400 0 : ALLOCATE (pint_env%staging_env)
401 : CALL staging_env_create(pint_env%staging_env, transform_section, &
402 0 : p=pint_env%p, kT=pint_env%kT)
403 : ELSE
404 : transform_section => section_vals_get_subs_vals(input, &
405 58 : "MOTION%PINT%NORMALMODE")
406 58 : IF (pint_env%propagator%prop_kind == propagator_bcmd) THEN
407 2 : CALL section_vals_val_get(transform_section, "GAMMA", explicit=explicit)
408 2 : IF (explicit) THEN
409 : CALL section_vals_val_set(transform_section, "GAMMA", &
410 0 : r_val=SQRT(2.0_dp/(pint_env%p*pint_env%dt*pint_env%kT)))
411 : ELSE
412 : CALL section_vals_val_set(transform_section, "MODEFACTOR", &
413 2 : r_val=0.5_dp*pint_env%p*pint_env%dt*pint_env%kT)
414 : END IF
415 : END IF
416 58 : ALLOCATE (pint_env%normalmode_env)
417 : CALL normalmode_env_create(pint_env%normalmode_env, &
418 58 : transform_section, p=pint_env%p, kT=pint_env%kT, propagator=pint_env%propagator%prop_kind)
419 58 : IF (para_env%is_source()) THEN
420 29 : IF (pint_env%harm_integrator == integrate_numeric) THEN
421 97 : IF (10.0_dp*pint_env%dt/REAL(pint_env%nrespa, dp) > &
422 : twopi/(pint_env%p*SQRT(MAXVAL(pint_env%normalmode_env%lambda))* &
423 : pint_env%normalmode_env%modefactor)) THEN
424 : msg = "PINT WARNING| Number of RESPA steps to small "// &
425 0 : "to integrate the harmonic springs."
426 0 : CPWARN(msg)
427 : END IF
428 : END IF
429 : END IF
430 : END IF
431 174 : ALLOCATE (pint_env%mass(pint_env%ndim))
432 : CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, &
433 58 : f_env=f_env)
434 58 : CALL force_env_get(force_env=f_env%force_env, subsys=subsys)
435 58 : CALL cp_subsys_get(subsys, particles=particles, gci=gci)
436 :
437 : !TODO length of pint_env%mass is redundant
438 58 : idim = 0
439 21700 : DO iat = 1, pint_env%ndim/3
440 21642 : CALL get_atomic_kind(particles%els(iat)%atomic_kind, mass=mass)
441 86626 : DO idir = 1, 3
442 64926 : idim = idim + 1
443 86568 : pint_env%mass(idim) = mass
444 : END DO
445 : END DO
446 58 : CALL f_env_rm_defaults(f_env, ierr)
447 58 : CPASSERT(ierr == 0)
448 :
449 : ALLOCATE (pint_env%Q(pint_env%p), &
450 : pint_env%mass_beads(pint_env%p, pint_env%ndim), &
451 464 : pint_env%mass_fict(pint_env%p, pint_env%ndim))
452 58 : IF (pint_env%transform == transformation_stage) THEN
453 : CALL staging_init_masses(pint_env%staging_env, mass=pint_env%mass, &
454 : mass_beads=pint_env%mass_beads, mass_fict=pint_env%mass_fict, &
455 0 : Q=pint_env%Q)
456 : ELSE
457 : CALL normalmode_init_masses(pint_env%normalmode_env, &
458 : mass=pint_env%mass, mass_beads=pint_env%mass_beads, &
459 58 : mass_fict=pint_env%mass_fict, Q=pint_env%Q)
460 : END IF
461 :
462 58 : NULLIFY (pint_env%gle)
463 58 : gle_section => section_vals_get_subs_vals(input, "MOTION%PINT%GLE")
464 58 : CALL section_vals_get(gle_section, explicit=explicit)
465 58 : IF (explicit) THEN
466 2 : ALLOCATE (pint_env%gle)
467 : CALL gle_init(pint_env%gle, dt=pint_env%dt/pint_env%nrespa, temp=pint_env%kT, &
468 2 : section=gle_section)
469 2 : IF (pint_env%pimd_thermostat == thermostat_none .AND. pint_env%gle%ndim > 0) THEN
470 2 : pint_env%pimd_thermostat = thermostat_gle
471 :
472 : ! initialize a GLE with ALL degrees of freedom on node 0,
473 : ! as it seems to me that here everything but force eval is replicated
474 2 : pint_env%gle%loc_num_gle = pint_env%p*pint_env%ndim
475 2 : pint_env%gle%glob_num_gle = pint_env%gle%loc_num_gle
476 6 : ALLOCATE (pint_env%gle%map_info%index(pint_env%gle%loc_num_gle))
477 18434 : DO itmp = 1, pint_env%gle%loc_num_gle
478 18434 : pint_env%gle%map_info%index(itmp) = itmp
479 : END DO
480 2 : CALL gle_thermo_create(pint_env%gle, pint_env%gle%loc_num_gle)
481 :
482 : ! here we should have read a_mat and c_mat;
483 : !we can therefore compute the matrices needed for the propagator
484 : ! deterministic part of the propagator
485 : CALL gle_matrix_exp((-pint_env%dt/pint_env%nrespa*0.5_dp)*pint_env%gle%a_mat, &
486 62 : pint_env%gle%ndim, 15, 15, pint_env%gle%gle_t)
487 : ! stochastic part
488 8 : CALL gle_cholesky_stab(pint_env%gle%c_mat - MATMUL(pint_env%gle%gle_t, &
489 8 : MATMUL(pint_env%gle%c_mat, TRANSPOSE(pint_env%gle%gle_t))), &
490 2184 : pint_env%gle%gle_s, pint_env%gle%ndim)
491 : ! and initialize the additional momenta
492 2 : CALL pint_gle_init(pint_env)
493 : END IF
494 : END IF
495 :
496 : !Setup pile thermostat
497 58 : NULLIFY (pint_env%pile_therm)
498 58 : pile_section => section_vals_get_subs_vals(input, "MOTION%PINT%PILE")
499 58 : CALL section_vals_get(pile_section, explicit=explicit)
500 58 : IF (explicit) THEN
501 10 : CALL cite_reference(Ceriotti2010)
502 : CALL section_vals_val_get(pint_env%input, &
503 : "MOTION%PINT%INIT%THERMOSTAT_SEED", &
504 10 : i_val=pint_env%thermostat_rng_seed)
505 10 : IF (pint_env%pimd_thermostat == thermostat_none) THEN
506 10 : pint_env%pimd_thermostat = thermostat_pile
507 250 : ALLOCATE (pint_env%pile_therm)
508 : CALL pint_pile_init(pile_therm=pint_env%pile_therm, &
509 : pint_env=pint_env, &
510 : normalmode_env=pint_env%normalmode_env, &
511 10 : section=pile_section)
512 : ELSE
513 0 : CPABORT("PILE thermostat can't be used with another thermostat.")
514 : END IF
515 : END IF
516 :
517 : !Setup PIGLET thermostat
518 58 : NULLIFY (pint_env%piglet_therm)
519 58 : piglet_section => section_vals_get_subs_vals(input, "MOTION%PINT%PIGLET")
520 58 : CALL section_vals_get(piglet_section, explicit=explicit)
521 58 : IF (explicit) THEN
522 2 : CALL cite_reference(Ceriotti2012)
523 : CALL section_vals_val_get(pint_env%input, &
524 : "MOTION%PINT%INIT%THERMOSTAT_SEED", &
525 2 : i_val=pint_env%thermostat_rng_seed)
526 2 : IF (pint_env%pimd_thermostat == thermostat_none) THEN
527 2 : pint_env%pimd_thermostat = thermostat_piglet
528 50 : ALLOCATE (pint_env%piglet_therm)
529 : CALL pint_piglet_create(pint_env%piglet_therm, &
530 : pint_env, &
531 2 : piglet_section)
532 : CALL pint_piglet_init(pint_env%piglet_therm, &
533 : pint_env, &
534 : piglet_section, &
535 2 : dt=pint_env%dt, para_env=para_env)
536 : ELSE
537 0 : CPABORT("PIGLET thermostat can't be used with another thermostat.")
538 : END IF
539 : END IF
540 :
541 : !Setup qtb thermostat
542 58 : NULLIFY (pint_env%qtb_therm)
543 58 : qtb_section => section_vals_get_subs_vals(input, "MOTION%PINT%QTB")
544 58 : CALL section_vals_get(qtb_section, explicit=explicit)
545 58 : IF (explicit) THEN
546 6 : CALL cite_reference(Brieuc2016)
547 : CALL section_vals_val_get(pint_env%input, &
548 : "MOTION%PINT%INIT%THERMOSTAT_SEED", &
549 6 : i_val=pint_env%thermostat_rng_seed)
550 6 : IF (pint_env%pimd_thermostat == thermostat_none) THEN
551 6 : pint_env%pimd_thermostat = thermostat_qtb
552 : CALL pint_qtb_init(qtb_therm=pint_env%qtb_therm, &
553 : pint_env=pint_env, &
554 : normalmode_env=pint_env%normalmode_env, &
555 6 : section=qtb_section)
556 : ELSE
557 0 : CPABORT("QTB thermostat can't be used with another thermostat.")
558 : END IF
559 : END IF
560 :
561 : ! force PILE for BCMD
562 58 : IF (pint_env%propagator%prop_kind == propagator_bcmd) THEN
563 2 : IF (pint_env%pimd_thermostat == thermostat_none) THEN
564 : !crate section
565 2 : pile_section => section_vals_get_subs_vals(input, "MOTION%PINT%PILE")
566 2 : CALL section_vals_get(pile_section, explicit=explicit)
567 2 : IF (.NOT. explicit) THEN
568 2 : CALL section_vals_add_values(pile_section)
569 : END IF
570 : CALL section_vals_val_get(pint_env%input, &
571 : "MOTION%PINT%INIT%THERMOSTAT_SEED", &
572 2 : i_val=pint_env%thermostat_rng_seed)
573 2 : pint_env%pimd_thermostat = thermostat_pile
574 50 : ALLOCATE (pint_env%pile_therm)
575 : CALL pint_pile_init(pile_therm=pint_env%pile_therm, &
576 : pint_env=pint_env, &
577 : normalmode_env=pint_env%normalmode_env, &
578 2 : section=pile_section)
579 : END IF
580 2 : IF (pint_env%pimd_thermostat /= thermostat_pile) THEN
581 0 : CPABORT("PILE/no thermostat currently needed for BCMD")
582 : END IF
583 2 : CALL cite_reference(Shiga2022)
584 : END IF
585 :
586 : !Initialize integrator scheme
587 58 : CALL section_vals_val_get(pint_section, "HARM_INT", i_val=pint_env%harm_integrator)
588 58 : IF (pint_env%harm_integrator == integrate_exact) THEN
589 24 : IF (pint_env%pimd_thermostat == thermostat_nose) THEN
590 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| Nose Thermostat only available in "// &
591 0 : "the numeric harmonic integrator. Switching to numeric harmonic integrator."
592 0 : CPWARN(msg)
593 0 : pint_env%harm_integrator = integrate_numeric
594 : END IF
595 24 : IF (pint_env%pimd_thermostat == thermostat_gle) THEN
596 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| GLE Thermostat only available in "// &
597 0 : "the numeric harmonic integrator. Switching to numeric harmonic integrator."
598 0 : CPWARN(msg)
599 0 : pint_env%harm_integrator = integrate_numeric
600 : END IF
601 34 : ELSE IF (pint_env%harm_integrator == integrate_numeric) THEN
602 34 : IF (pint_env%pimd_thermostat == thermostat_pile) THEN
603 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| PILE Thermostat only available in "// &
604 2 : "the exact harmonic integrator. Switching to exact harmonic integrator."
605 2 : CPWARN(msg)
606 2 : pint_env%harm_integrator = integrate_exact
607 : END IF
608 34 : IF (pint_env%pimd_thermostat == thermostat_piglet) THEN
609 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| PIGLET Thermostat only available in "// &
610 0 : "the exact harmonic integrator. Switching to exact harmonic integrator."
611 0 : CPWARN(msg)
612 0 : pint_env%harm_integrator = integrate_exact
613 : END IF
614 34 : IF (pint_env%pimd_thermostat == thermostat_qtb) THEN
615 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| QTB Thermostat only available in "// &
616 0 : "the exact harmonic integrator. Switching to exact harmonic integrator."
617 0 : CPWARN(msg)
618 0 : pint_env%harm_integrator = integrate_exact
619 : END IF
620 34 : IF (pint_env%propagator%prop_kind == propagator_bcmd) THEN
621 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| BCMD needs the exact harmonic "// &
622 0 : "integrator. Switching to exact harmonic integrator."
623 0 : CPWARN(msg)
624 0 : pint_env%harm_integrator = integrate_exact
625 : END IF
626 : END IF
627 :
628 58 : IF (pint_env%harm_integrator == integrate_exact) THEN
629 26 : IF (pint_env%nrespa /= 1) THEN
630 18 : pint_env%nrespa = 1
631 18 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| Adjusting NRESPA to 1 for exact harmonic integration."
632 18 : CPWARN(msg)
633 : END IF
634 26 : NULLIFY (pint_env%wsinex)
635 78 : ALLOCATE (pint_env%wsinex(pint_env%p))
636 26 : NULLIFY (pint_env%iwsinex)
637 52 : ALLOCATE (pint_env%iwsinex(pint_env%p))
638 26 : NULLIFY (pint_env%cosex)
639 52 : ALLOCATE (pint_env%cosex(pint_env%p))
640 26 : dt = pint_env%dt/REAL(pint_env%nrespa, KIND=dp)
641 : !Centroid mode shoud not be propagated
642 26 : pint_env%wsinex(1) = 0.0_dp
643 26 : pint_env%iwsinex(1) = dt
644 26 : pint_env%cosex(1) = 1.0_dp
645 212 : DO ibead = 2, pint_env%p
646 186 : omega = SQRT(pint_env%normalmode_env%lambda(ibead))
647 186 : pint_env%wsinex(ibead) = SIN(omega*dt)*omega
648 186 : pint_env%iwsinex(ibead) = SIN(omega*dt)/omega
649 212 : pint_env%cosex(ibead) = COS(omega*dt)
650 : END DO
651 : END IF
652 :
653 : CALL section_vals_val_get(pint_section, "FIX_CENTROID_POS", &
654 58 : l_val=ltmp)
655 58 : IF (ltmp .AND. (pint_env%transform == transformation_normal)) THEN
656 0 : pint_env%first_propagated_mode = 2
657 : ELSE
658 58 : pint_env%first_propagated_mode = 1
659 : END IF
660 :
661 : ! Constraint information:
662 58 : NULLIFY (pint_env%simpar)
663 : constraint_section => section_vals_get_subs_vals(pint_env%input, &
664 58 : "MOTION%CONSTRAINT")
665 58 : CALL section_vals_get(constraint_section, explicit=explicit)
666 58 : CALL create_simpar_type(pint_env%simpar)
667 58 : pint_env%simpar%constraint = explicit
668 58 : pint_env%kTcorr = 1.0_dp
669 :
670 : ! Determine if beadwise constraints are activated
671 58 : pint_env%beadwise_constraints = .FALSE.
672 : CALL section_vals_val_get(constraint_section, "PIMD_BEADWISE_CONSTRAINT", &
673 58 : l_val=pint_env%beadwise_constraints)
674 58 : IF (pint_env%simpar%constraint) THEN
675 6 : IF (pint_env%beadwise_constraints) THEN
676 2 : CALL pint_write_line("Using beadwise constraints")
677 : ELSE
678 4 : CALL pint_write_line("Using centroid constraints")
679 : END IF
680 : END IF
681 :
682 58 : IF (explicit) THEN
683 : ! Staging not supported yet, since lowest mode is assumed
684 : ! to be related to centroid
685 6 : IF (pint_env%transform == transformation_stage) THEN
686 0 : CPABORT("Constraints are not supported for staging transformation")
687 : END IF
688 :
689 : ! Check thermostats that are not supported:
690 6 : IF (pint_env%pimd_thermostat == thermostat_gle) THEN
691 : WRITE (UNIT=msg, FMT=*) "GLE Thermostat not supported for "// &
692 0 : "constraints. Switch to NOSE for numeric integration."
693 0 : CPABORT(msg)
694 : END IF
695 : ! Warn for NOSE
696 6 : IF (pint_env%pimd_thermostat == thermostat_nose) THEN
697 : !Beadwise constraints not supported
698 2 : IF (pint_env%beadwise_constraints) THEN
699 0 : CPABORT("Beadwise constraints are not supported for NOSE Thermostat.")
700 : !Centroid constraints supported
701 : ELSE
702 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| Nose Thermostat set to "// &
703 2 : "zero for constrained atoms. Careful interpretation of temperature."
704 2 : CPWARN(msg)
705 : WRITE (UNIT=msg, FMT=*) "PINT WARNING| Lagrange multipliers are "// &
706 2 : "are printed every RESPA step and need to be treated carefully."
707 2 : CPWARN(msg)
708 : END IF
709 : END IF
710 :
711 : CALL section_vals_val_get(constraint_section, "SHAKE_TOLERANCE", &
712 6 : r_val=pint_env%simpar%shake_tol)
713 : pint_env%simpar%info_constraint = cp_print_key_unit_nr(pint_env%logger, &
714 : constraint_section, &
715 : "CONSTRAINT_INFO", &
716 : extension=".shakeLog", &
717 6 : log_filename=.FALSE.)
718 : pint_env%simpar%lagrange_multipliers = cp_print_key_unit_nr(pint_env%logger, &
719 : constraint_section, &
720 : "LAGRANGE_MULTIPLIERS", &
721 : extension=".LagrangeMultLog", &
722 6 : log_filename=.FALSE.)
723 : pint_env%simpar%dump_lm = &
724 : BTEST(cp_print_key_should_output(pint_env%logger%iter_info, &
725 : constraint_section, &
726 6 : "LAGRANGE_MULTIPLIERS"), cp_p_file)
727 :
728 : ! Determine constrained atoms:
729 6 : pint_env%n_atoms_constraints = 0
730 12 : DO ig = 1, gci%ncolv%ntot
731 : ! Double counts, if the same atom is involved in different collective variables
732 12 : pint_env%n_atoms_constraints = pint_env%n_atoms_constraints + SIZE(gci%colv_list(ig)%i_atoms)
733 : END DO
734 :
735 18 : ALLOCATE (pint_env%atoms_constraints(pint_env%n_atoms_constraints))
736 6 : icont = 0
737 12 : DO ig = 1, gci%ncolv%ntot
738 24 : DO iat = 1, SIZE(gci%colv_list(ig)%i_atoms)
739 12 : icont = icont + 1
740 18 : pint_env%atoms_constraints(icont) = gci%colv_list(ig)%i_atoms(iat)
741 : END DO
742 : END DO
743 :
744 : ! Set the correction to the temperature due to the frozen degrees of freedom in NOSE:
745 : CALL section_vals_val_get(pint_section, "kT_CORRECTION", &
746 6 : l_val=ltmp)
747 6 : IF (ltmp) THEN
748 0 : pint_env%kTcorr = 1.0_dp + REAL(3*pint_env%n_atoms_constraints, dp)/(REAL(pint_env%ndim, dp)*REAL(pint_env%p, dp))
749 : END IF
750 : END IF
751 :
752 58 : CALL timestop(handle)
753 :
754 638 : END SUBROUTINE pint_create
755 :
756 : ! ***************************************************************************
757 : !> \brief Release a path integral environment
758 : !> \param pint_env the pint_env to release
759 : !> \par History
760 : !> Added normal mode transformation [hforbert]
761 : !> \author Fawzi Mohamed
762 : ! **************************************************************************************************
763 58 : SUBROUTINE pint_release(pint_env)
764 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
765 :
766 58 : CALL rep_env_release(pint_env%replicas)
767 58 : CALL section_vals_release(pint_env%input)
768 58 : IF (ASSOCIATED(pint_env%staging_env)) THEN
769 0 : CALL staging_release(pint_env%staging_env)
770 0 : DEALLOCATE (pint_env%staging_env)
771 : END IF
772 58 : IF (ASSOCIATED(pint_env%normalmode_env)) THEN
773 58 : CALL normalmode_release(pint_env%normalmode_env)
774 58 : DEALLOCATE (pint_env%normalmode_env)
775 : END IF
776 :
777 58 : DEALLOCATE (pint_env%mass)
778 58 : DEALLOCATE (pint_env%e_pot_bead)
779 :
780 58 : DEALLOCATE (pint_env%x)
781 58 : DEALLOCATE (pint_env%v)
782 58 : DEALLOCATE (pint_env%f)
783 58 : DEALLOCATE (pint_env%external_f)
784 58 : DEALLOCATE (pint_env%mass_beads)
785 58 : DEALLOCATE (pint_env%mass_fict)
786 58 : DEALLOCATE (pint_env%ux)
787 58 : DEALLOCATE (pint_env%ux_t)
788 58 : DEALLOCATE (pint_env%uv)
789 58 : DEALLOCATE (pint_env%uv_t)
790 58 : DEALLOCATE (pint_env%uv_new)
791 58 : DEALLOCATE (pint_env%uf)
792 58 : DEALLOCATE (pint_env%uf_h)
793 58 : DEALLOCATE (pint_env%centroid)
794 58 : DEALLOCATE (pint_env%rtmp_ndim)
795 58 : DEALLOCATE (pint_env%rtmp_natom)
796 58 : DEALLOCATE (pint_env%propagator)
797 :
798 58 : IF (pint_env%simpar%constraint) THEN
799 6 : DEALLOCATE (pint_env%atoms_constraints)
800 : END IF
801 58 : CALL release_simpar_type(pint_env%simpar)
802 :
803 58 : IF (pint_env%harm_integrator == integrate_exact) THEN
804 26 : DEALLOCATE (pint_env%wsinex)
805 26 : DEALLOCATE (pint_env%iwsinex)
806 26 : DEALLOCATE (pint_env%cosex)
807 : END IF
808 :
809 84 : SELECT CASE (pint_env%pimd_thermostat)
810 : CASE (thermostat_nose)
811 26 : DEALLOCATE (pint_env%tx)
812 26 : DEALLOCATE (pint_env%tv)
813 26 : DEALLOCATE (pint_env%tv_t)
814 26 : DEALLOCATE (pint_env%tv_old)
815 26 : DEALLOCATE (pint_env%tv_new)
816 26 : DEALLOCATE (pint_env%tf)
817 : CASE (thermostat_gle)
818 2 : CALL gle_dealloc(pint_env%gle)
819 : CASE (thermostat_pile)
820 12 : CALL pint_pile_release(pint_env%pile_therm)
821 12 : DEALLOCATE (pint_env%pile_therm)
822 : CASE (thermostat_piglet)
823 2 : CALL pint_piglet_release(pint_env%piglet_therm)
824 2 : DEALLOCATE (pint_env%piglet_therm)
825 : CASE (thermostat_qtb)
826 6 : CALL pint_qtb_release(pint_env%qtb_therm)
827 64 : DEALLOCATE (pint_env%qtb_therm)
828 : END SELECT
829 :
830 58 : DEALLOCATE (pint_env%Q)
831 :
832 58 : END SUBROUTINE pint_release
833 :
834 : ! ***************************************************************************
835 : !> \brief Tests the path integral methods
836 : !> \param para_env parallel environment
837 : !> \param input the input to test
838 : !> \param input_declaration ...
839 : !> \author fawzi
840 : ! **************************************************************************************************
841 0 : SUBROUTINE pint_test(para_env, input, input_declaration)
842 : TYPE(mp_para_env_type), POINTER :: para_env
843 : TYPE(section_vals_type), POINTER :: input
844 : TYPE(section_type), POINTER :: input_declaration
845 :
846 : INTEGER :: i, ib, idim, unit_nr
847 : REAL(kind=dp) :: c, e_h, err
848 0 : REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: x1
849 : TYPE(pint_env_type) :: pint_env
850 :
851 0 : CPASSERT(ASSOCIATED(para_env))
852 0 : CPASSERT(ASSOCIATED(input))
853 0 : CPASSERT(para_env%is_valid())
854 0 : CPASSERT(input%ref_count > 0)
855 0 : unit_nr = cp_logger_get_default_io_unit()
856 0 : CALL pint_create(pint_env, input, input_declaration, para_env)
857 0 : ALLOCATE (x1(pint_env%ndim, pint_env%p))
858 0 : x1(:, :) = pint_env%x
859 0 : CALL pint_x2u(pint_env)
860 0 : pint_env%x = 0._dp
861 0 : CALL pint_u2x(pint_env)
862 0 : err = 0._dp
863 0 : DO i = 1, pint_env%ndim
864 0 : err = MAX(err, ABS(x1(1, i) - pint_env%x(1, i)))
865 : END DO
866 0 : IF (unit_nr > 0) WRITE (unit_nr, *) "diff_r1="//cp_to_string(err)
867 :
868 0 : CALL pint_calc_uf_h(pint_env, e_h=e_h)
869 0 : c = -pint_env%staging_env%w_p**2
870 0 : pint_env%f = 0._dp
871 0 : DO idim = 1, pint_env%ndim
872 0 : DO ib = 1, pint_env%p
873 : pint_env%f(ib, idim) = pint_env%f(ib, idim) + &
874 : c*(2._dp*pint_env%x(ib, idim) &
875 : - pint_env%x(MODULO(ib - 2, pint_env%p) + 1, idim) &
876 0 : - pint_env%x(MODULO(ib, pint_env%p) + 1, idim))
877 : END DO
878 : END DO
879 0 : CALL pint_f2uf(pint_env)
880 0 : err = 0._dp
881 0 : DO idim = 1, pint_env%ndim
882 0 : DO ib = 1, pint_env%p
883 0 : err = MAX(err, ABS(pint_env%uf(ib, idim) - pint_env%uf_h(ib, idim)))
884 : END DO
885 : END DO
886 0 : IF (unit_nr > 0) WRITE (unit_nr, *) "diff_f_h="//cp_to_string(err)
887 :
888 0 : END SUBROUTINE pint_test
889 :
890 : ! ***************************************************************************
891 : !> \brief Perform a path integral simulation
892 : !> \param para_env parallel environment
893 : !> \param input the input to test
894 : !> \param input_declaration ...
895 : !> \param globenv ...
896 : !> \par History
897 : !> 2003-11 created [fawzi]
898 : !> 2009-12-14 globenv parameter added to handle soft exit
899 : !> requests [lwalewski]
900 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
901 : !> \author Fawzi Mohamed
902 : ! **************************************************************************************************
903 204 : SUBROUTINE do_pint_run(para_env, input, input_declaration, globenv)
904 : TYPE(mp_para_env_type), POINTER :: para_env
905 : TYPE(section_vals_type), POINTER :: input
906 : TYPE(section_type), POINTER :: input_declaration
907 : TYPE(global_environment_type), POINTER :: globenv
908 :
909 : CHARACTER(len=*), PARAMETER :: routineN = 'do_pint_run'
910 : INTEGER, PARAMETER :: helium_only_mid = 1, &
911 : int_pot_scan_mid = 4, &
912 : solute_only_mid = 2, &
913 : solute_with_helium_mid = 3
914 :
915 : CHARACTER(len=default_string_length) :: stmp
916 : INTEGER :: handle, mode
917 : LOGICAL :: explicit, helium_only, int_pot_scan, &
918 : solvent_present
919 68 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
920 : TYPE(pint_env_type) :: pint_env
921 : TYPE(section_vals_type), POINTER :: helium_section
922 :
923 68 : CALL timeset(routineN, handle)
924 :
925 68 : CPASSERT(ASSOCIATED(para_env))
926 68 : CPASSERT(ASSOCIATED(input))
927 68 : CPASSERT(para_env%is_valid())
928 68 : CPASSERT(input%ref_count > 0)
929 :
930 : ! check if helium solvent is present
931 68 : NULLIFY (helium_section)
932 : helium_section => section_vals_get_subs_vals(input, &
933 68 : "MOTION%PINT%HELIUM")
934 68 : CALL section_vals_get(helium_section, explicit=explicit)
935 68 : IF (explicit) THEN
936 : CALL section_vals_val_get(helium_section, "_SECTION_PARAMETERS_", &
937 26 : l_val=solvent_present)
938 : ELSE
939 42 : solvent_present = .FALSE.
940 : END IF
941 :
942 : ! check if there is anything but helium
943 68 : IF (solvent_present) THEN
944 : CALL section_vals_val_get(helium_section, "HELIUM_ONLY", &
945 26 : l_val=helium_only)
946 : ELSE
947 42 : helium_only = .FALSE.
948 : END IF
949 :
950 : ! check wheather to perform solute-helium interaction pot scan
951 68 : IF (solvent_present) THEN
952 : CALL section_vals_val_get(helium_section, "INTERACTION_POT_SCAN", &
953 26 : l_val=int_pot_scan)
954 : ELSE
955 42 : int_pot_scan = .FALSE.
956 : END IF
957 :
958 : ! input consistency check
959 68 : IF (helium_only .AND. int_pot_scan) THEN
960 0 : stmp = "Options HELIUM_ONLY and INTERACTION_POT_SCAN are exclusive"
961 0 : CPABORT(stmp)
962 : END IF
963 :
964 : ! select mode of operation
965 : mode = 0
966 68 : IF (solvent_present) THEN
967 26 : IF (helium_only) THEN
968 10 : mode = helium_only_mid
969 : ELSE
970 16 : IF (int_pot_scan) THEN
971 0 : mode = int_pot_scan_mid
972 : ELSE
973 16 : mode = solute_with_helium_mid
974 : END IF
975 : END IF
976 : ELSE
977 42 : mode = solute_only_mid
978 : END IF
979 :
980 : ! perform the simulation according to the chosen mode
981 10 : SELECT CASE (mode)
982 :
983 : CASE (helium_only_mid)
984 10 : CALL helium_create(helium_env, input)
985 10 : CALL helium_init(helium_env, pint_env)
986 10 : CALL helium_do_run(helium_env, globenv)
987 10 : CALL helium_release(helium_env)
988 :
989 : CASE (solute_only_mid)
990 42 : CALL pint_create(pint_env, input, input_declaration, para_env)
991 42 : CALL pint_init(pint_env)
992 42 : CALL pint_do_run(pint_env, globenv)
993 42 : CALL pint_release(pint_env)
994 :
995 : CASE (int_pot_scan_mid)
996 0 : CALL pint_create(pint_env, input, input_declaration, para_env)
997 : ! TODO only initialization of positions is necessary, but rep_env_calc_e_f called
998 : ! from within pint_init_f does something to the replica environments which can not be
999 : ! avoided (has something to do with f_env_add_defaults) so leaving for now..
1000 0 : CALL pint_init(pint_env)
1001 0 : CALL helium_create(helium_env, input, solute=pint_env)
1002 0 : CALL pint_run_scan(pint_env, helium_env)
1003 0 : CALL helium_release(helium_env)
1004 0 : CALL pint_release(pint_env)
1005 :
1006 : CASE (solute_with_helium_mid)
1007 16 : CALL pint_create(pint_env, input, input_declaration, para_env)
1008 : ! init pint without helium forces (they are not yet initialized)
1009 16 : CALL pint_init(pint_env)
1010 : ! init helium with solute's positions (they are already initialized)
1011 16 : CALL helium_create(helium_env, input, solute=pint_env)
1012 16 : CALL helium_init(helium_env, pint_env)
1013 : ! reinit pint forces with helium forces (they are now initialized)
1014 16 : CALL pint_init_f(pint_env, helium_env=helium_env)
1015 :
1016 16 : CALL pint_do_run(pint_env, globenv, helium_env=helium_env)
1017 16 : CALL helium_release(helium_env)
1018 16 : CALL pint_release(pint_env)
1019 :
1020 : CASE DEFAULT
1021 68 : CPABORT("Unknown mode ("//TRIM(ADJUSTL(cp_to_string(mode)))//")")
1022 : END SELECT
1023 :
1024 68 : CALL timestop(handle)
1025 :
1026 1972 : END SUBROUTINE do_pint_run
1027 :
1028 : ! ***************************************************************************
1029 : !> \brief Reads the restart, initializes the beads, etc.
1030 : !> \param pint_env ...
1031 : !> \par History
1032 : !> 11.2003 created [fawzi]
1033 : !> actually ASSIGN input pointer [hforbert]
1034 : !> 2010-12-16 turned into a wrapper routine [lwalewski]
1035 : !> \author Fawzi Mohamed
1036 : ! **************************************************************************************************
1037 58 : SUBROUTINE pint_init(pint_env)
1038 :
1039 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
1040 :
1041 58 : CALL pint_init_x(pint_env)
1042 58 : CALL pint_init_v(pint_env)
1043 58 : CALL pint_init_t(pint_env)
1044 58 : CALL pint_init_f(pint_env)
1045 :
1046 58 : END SUBROUTINE pint_init
1047 :
1048 : ! ***************************************************************************
1049 : !> \brief Assign initial postions to the beads.
1050 : !> \param pint_env ...
1051 : !> \date 2010-12-15
1052 : !> \author Lukasz Walewski
1053 : !> \note Initialization is done in the following way:
1054 : !> 1. assign all beads with the same classical positions from
1055 : !> FORCE_EVAL (hot start)
1056 : !> 2. spread the beads around classical positions as if they were
1057 : !> free particles (if requested)
1058 : !> 3. replace positions generated in steps 1-2 with the explicit
1059 : !> ones if they are explicitly given in the input structure
1060 : !> 4. apply Gaussian noise to the positions generated so far (if
1061 : !> requested)
1062 : ! **************************************************************************************************
1063 58 : SUBROUTINE pint_init_x(pint_env)
1064 :
1065 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
1066 :
1067 : CHARACTER(len=5*default_string_length) :: msg, tmp
1068 : INTEGER :: ia, ib, ic, idim, input_seed, n_rep_val
1069 : LOGICAL :: done_init, done_levy, done_rand, &
1070 : explicit, levycorr, ltmp
1071 : REAL(kind=dp) :: tcorr, var
1072 : REAL(kind=dp), DIMENSION(3) :: x0
1073 : REAL(kind=dp), DIMENSION(3, 2) :: seed
1074 58 : REAL(kind=dp), DIMENSION(:), POINTER :: bx, r_vals
1075 58 : TYPE(rng_stream_type), ALLOCATABLE :: rng_gaussian
1076 : TYPE(section_vals_type), POINTER :: input_section
1077 :
1078 64984 : DO idim = 1, pint_env%ndim
1079 362632 : DO ib = 1, pint_env%p
1080 362574 : pint_env%x(ib, idim) = pint_env%replicas%r(idim, ib)
1081 : END DO
1082 : END DO
1083 :
1084 58 : done_levy = .FALSE.
1085 : CALL section_vals_val_get(pint_env%input, &
1086 : "MOTION%PINT%INIT%LEVY_POS_SAMPLE", &
1087 58 : l_val=ltmp)
1088 : CALL section_vals_val_get(pint_env%input, &
1089 : "MOTION%PINT%INIT%LEVY_TEMP_FACTOR", &
1090 58 : r_val=tcorr)
1091 58 : IF (ltmp) THEN
1092 :
1093 0 : IF (pint_env%beadwise_constraints) THEN
1094 : WRITE (UNIT=msg, FMT=*) "Beadwise constraints are not supported for "// &
1095 : "the initialization of the beads as free particles. "// &
1096 0 : "Please use hot start (default)."
1097 0 : CPABORT(msg)
1098 : END IF
1099 :
1100 0 : NULLIFY (bx)
1101 0 : ALLOCATE (bx(3*pint_env%p))
1102 : CALL section_vals_val_get(pint_env%input, &
1103 0 : "MOTION%PINT%INIT%LEVY_SEED", i_val=input_seed)
1104 0 : seed(:, :) = REAL(input_seed, KIND=dp)
1105 : ! seed(:,:) = next_rng_seed()
1106 : rng_gaussian = rng_stream_type( &
1107 : name="tmp_rng_gaussian", &
1108 : distribution_type=GAUSSIAN, &
1109 : extended_precision=.TRUE., &
1110 0 : seed=seed)
1111 :
1112 : CALL section_vals_val_get(pint_env%input, &
1113 : "MOTION%PINT%INIT%LEVY_CORRELATED", &
1114 0 : l_val=levycorr)
1115 :
1116 0 : IF (levycorr) THEN
1117 :
1118 : ! correlated Levy walk - the same path for all atoms
1119 0 : x0 = [0.0_dp, 0.0_dp, 0.0_dp]
1120 0 : CALL pint_levy_walk(x0, pint_env%p, 1.0_dp, bx, rng_gaussian)
1121 0 : idim = 0
1122 0 : DO ia = 1, pint_env%ndim/3
1123 0 : var = SQRT(1.0_dp/(pint_env%kT*tcorr*pint_env%mass(3*ia)))
1124 0 : DO ic = 1, 3
1125 0 : idim = idim + 1
1126 0 : DO ib = 1, pint_env%p
1127 0 : pint_env%x(ib, idim) = pint_env%x(ib, idim) + bx(3*(ib - 1) + ic)*var
1128 : END DO
1129 : END DO
1130 : END DO
1131 :
1132 : ELSE
1133 :
1134 : ! uncorrelated bead initialization - distinct Levy walk for each atom
1135 0 : idim = 0
1136 0 : DO ia = 1, pint_env%ndim/3
1137 0 : x0(1) = pint_env%x(1, 3*(ia - 1) + 1)
1138 0 : x0(2) = pint_env%x(1, 3*(ia - 1) + 2)
1139 0 : x0(3) = pint_env%x(1, 3*(ia - 1) + 3)
1140 0 : var = SQRT(1.0_dp/(pint_env%kT*tcorr*pint_env%mass(3*ia)))
1141 0 : CALL pint_levy_walk(x0, pint_env%p, var, bx, rng_gaussian)
1142 0 : DO ic = 1, 3
1143 0 : idim = idim + 1
1144 0 : DO ib = 1, pint_env%p
1145 0 : pint_env%x(ib, idim) = pint_env%x(ib, idim) + bx(3*(ib - 1) + ic)
1146 : END DO
1147 : END DO
1148 : END DO
1149 :
1150 : END IF
1151 :
1152 0 : DEALLOCATE (bx)
1153 0 : done_levy = .TRUE.
1154 : END IF
1155 :
1156 58 : done_init = .FALSE.
1157 58 : NULLIFY (input_section)
1158 : input_section => section_vals_get_subs_vals(pint_env%input, &
1159 58 : "MOTION%PINT%BEADS%COORD")
1160 58 : CALL section_vals_get(input_section, explicit=explicit)
1161 58 : IF (explicit) THEN
1162 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1163 8 : n_rep_val=n_rep_val)
1164 8 : IF (n_rep_val > 0) THEN
1165 8 : CPASSERT(n_rep_val == 1)
1166 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1167 8 : r_vals=r_vals)
1168 8 : IF (SIZE(r_vals) /= pint_env%p*pint_env%ndim) THEN
1169 0 : CPABORT("Invalid size of MOTION%PINT%BEADS%COORD")
1170 : END IF
1171 8 : ic = 0
1172 9278 : DO idim = 1, pint_env%ndim
1173 46358 : DO ib = 1, pint_env%p
1174 37080 : ic = ic + 1
1175 46350 : pint_env%x(ib, idim) = r_vals(ic)
1176 : END DO
1177 : END DO
1178 : done_init = .TRUE.
1179 : END IF
1180 : END IF
1181 :
1182 58 : done_rand = .FALSE.
1183 : CALL section_vals_val_get(pint_env%input, &
1184 : "MOTION%PINT%INIT%RANDOMIZE_POS", &
1185 58 : l_val=ltmp)
1186 58 : IF (ltmp) THEN
1187 :
1188 0 : IF (pint_env%beadwise_constraints) THEN
1189 : WRITE (UNIT=msg, FMT=*) "Beadwise constraints are not supported if "// &
1190 : "a random noise is applied to the initialization of the bead positions. "// &
1191 0 : "Please use hot start (default)."
1192 0 : CPABORT(msg)
1193 : END IF
1194 :
1195 0 : DO idim = 1, pint_env%ndim
1196 0 : DO ib = 1, pint_env%p
1197 : pint_env%x(ib, idim) = pint_env%x(ib, idim) + &
1198 : pint_env%randomG%next(variance=pint_env%beta/ &
1199 0 : SQRT(12.0_dp*pint_env%mass(idim)))
1200 : END DO
1201 : END DO
1202 : done_rand = .TRUE.
1203 : END IF
1204 :
1205 58 : WRITE (tmp, '(A)') "Bead positions initialization:"
1206 58 : IF (done_init) THEN
1207 8 : WRITE (msg, '(A,A)') TRIM(tmp), " input structure"
1208 50 : ELSE IF (done_levy) THEN
1209 0 : WRITE (msg, '(A,A)') TRIM(tmp), " Levy random walk"
1210 : ELSE
1211 50 : WRITE (msg, '(A,A)') TRIM(tmp), " hot start"
1212 : END IF
1213 58 : CALL pint_write_line(msg)
1214 :
1215 58 : IF (done_levy) THEN
1216 0 : WRITE (msg, '(A,F6.3)') "Levy walk at effective temperature: ", tcorr
1217 : END IF
1218 :
1219 58 : IF (done_rand) THEN
1220 0 : WRITE (msg, '(A)') "Added gaussian noise to the positions of the beads."
1221 0 : CALL pint_write_line(msg)
1222 : END IF
1223 :
1224 116 : END SUBROUTINE pint_init_x
1225 :
1226 : ! ***************************************************************************
1227 : !> \brief Initialize velocities
1228 : !> \param pint_env the pint env in which you should initialize the
1229 : !> velocity
1230 : !> \par History
1231 : !> 2010-12-16 gathered all velocity-init code here [lwalewski]
1232 : !> 2011-04-05 added centroid velocity initialization [lwalewski]
1233 : !> 2011-12-19 removed optional parameter kT, target temperature is
1234 : !> now determined from the input directly [lwalewski]
1235 : !> \author fawzi
1236 : !> \note Initialization is done according to the following protocol:
1237 : !> 1. set all the velocities to FORCE_EVAL%SUBSYS%VELOCITY if present
1238 : !> 2. scale the velocities according to the actual temperature
1239 : !> (has no effect if vels not present in 1.)
1240 : !> 3. draw vels for the remaining dof from MB distribution
1241 : !> (all or non-centroid modes only depending on 1.)
1242 : !> 4. add random noise to the centroid vels if CENTROID_SPEED == T
1243 : !> 5. set the vels for all dof to 0.0 if VELOCITY_QUENCH == T
1244 : !> 6. set the vels according to the explicit values from the input
1245 : !> if present
1246 : ! **************************************************************************************************
1247 58 : SUBROUTINE pint_init_v(pint_env)
1248 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
1249 :
1250 : CHARACTER(len=default_string_length) :: msg, stmp, stmp1, stmp2, unit_str
1251 : INTEGER :: first_mode, i, ia, ib, ic, idim, ierr, &
1252 : itmp, j, n_rep_val, nparticle, &
1253 : nparticle_kind
1254 : LOGICAL :: done_init, done_quench, done_scale, &
1255 : done_sped, explicit, ltmp, vels_present
1256 : REAL(kind=dp) :: actual_t, ek, factor, rtmp, target_t, &
1257 : unit_conv
1258 58 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: vel
1259 58 : REAL(kind=dp), DIMENSION(:), POINTER :: r_vals
1260 : TYPE(atomic_kind_list_type), POINTER :: atomic_kinds
1261 58 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1262 : TYPE(cell_type), POINTER :: cell
1263 : TYPE(cp_logger_type), POINTER :: logger
1264 : TYPE(cp_subsys_type), POINTER :: subsys
1265 : TYPE(distribution_1d_type), POINTER :: local_molecules, local_particles
1266 : TYPE(f_env_type), POINTER :: f_env
1267 : TYPE(global_constraint_type), POINTER :: gci
1268 : TYPE(molecule_kind_list_type), POINTER :: molecule_kinds
1269 58 : TYPE(molecule_kind_type), DIMENSION(:), POINTER :: molecule_kind_set
1270 : TYPE(molecule_list_type), POINTER :: molecules
1271 58 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
1272 : TYPE(particle_list_type), POINTER :: particles
1273 58 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1274 : TYPE(section_vals_type), POINTER :: input_section
1275 :
1276 58 : NULLIFY (logger)
1277 116 : logger => cp_get_default_logger()
1278 :
1279 : ! Get constraint info, if needed
1280 : ! Create a force environment which will be identical to
1281 : ! the bead that is being processed by the processor.
1282 58 : IF (pint_env%simpar%constraint) THEN
1283 6 : NULLIFY (subsys, cell)
1284 6 : NULLIFY (atomic_kinds, local_particles, particles)
1285 6 : NULLIFY (local_molecules, molecules, molecule_kinds, gci)
1286 6 : NULLIFY (atomic_kind_set, molecule_kind_set, particle_set, molecule_set)
1287 :
1288 6 : CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, f_env=f_env)
1289 6 : CALL force_env_get(force_env=f_env%force_env, subsys=subsys)
1290 6 : CALL f_env_rm_defaults(f_env, ierr)
1291 6 : CPASSERT(ierr == 0)
1292 :
1293 : ! Get gci and more from subsys
1294 : CALL cp_subsys_get(subsys=subsys, &
1295 : cell=cell, &
1296 : atomic_kinds=atomic_kinds, &
1297 : local_particles=local_particles, &
1298 : particles=particles, &
1299 : local_molecules=local_molecules, &
1300 : molecules=molecules, &
1301 : molecule_kinds=molecule_kinds, &
1302 6 : gci=gci)
1303 :
1304 6 : nparticle_kind = atomic_kinds%n_els
1305 6 : atomic_kind_set => atomic_kinds%els
1306 6 : molecule_kind_set => molecule_kinds%els
1307 6 : nparticle = particles%n_els
1308 6 : particle_set => particles%els
1309 6 : molecule_set => molecules%els
1310 :
1311 : ! Allocate work storage
1312 18 : ALLOCATE (vel(3, nparticle))
1313 6 : vel(:, :) = 0.0_dp
1314 : CALL getold(gci, local_molecules, molecule_set, &
1315 12 : molecule_kind_set, particle_set, cell)
1316 : END IF
1317 :
1318 : ! read the velocities from the input file if they are given explicitly
1319 58 : vels_present = .FALSE.
1320 58 : NULLIFY (input_section)
1321 : input_section => section_vals_get_subs_vals(pint_env%input, &
1322 58 : "FORCE_EVAL%SUBSYS%VELOCITY")
1323 58 : CALL section_vals_get(input_section, explicit=explicit)
1324 58 : IF (explicit) THEN
1325 :
1326 : CALL section_vals_val_get(input_section, "PINT_UNIT", &
1327 2 : c_val=unit_str)
1328 2 : unit_conv = cp_unit_to_cp2k(1.0_dp, TRIM(unit_str))
1329 :
1330 : ! assign all the beads with the same velocities from FORCE_EVAL%SUBSYS%VELOCITY
1331 2 : NULLIFY (r_vals)
1332 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1333 2 : n_rep_val=n_rep_val)
1334 2 : stmp = ""
1335 2 : WRITE (stmp, *) n_rep_val
1336 : msg = "Invalid number of atoms in FORCE_EVAL%SUBSYS%VELOCITY ("// &
1337 2 : TRIM(ADJUSTL(stmp))//")."
1338 2 : IF (3*n_rep_val /= pint_env%ndim) THEN
1339 0 : CPABORT(msg)
1340 : END IF
1341 14 : DO ia = 1, pint_env%ndim/3
1342 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1343 12 : i_rep_val=ia, r_vals=r_vals)
1344 12 : itmp = SIZE(r_vals)
1345 12 : stmp = ""
1346 12 : WRITE (stmp, *) itmp
1347 : msg = "Number of coordinates != 3 in FORCE_EVAL%SUBSYS%VELOCITY ("// &
1348 12 : TRIM(ADJUSTL(stmp))//")."
1349 12 : IF (itmp /= 3) THEN
1350 0 : CPABORT(msg)
1351 : END IF
1352 110 : DO ib = 1, pint_env%p
1353 396 : DO ic = 1, 3
1354 288 : idim = 3*(ia - 1) + ic
1355 384 : pint_env%v(ib, idim) = r_vals(ic)*unit_conv
1356 : END DO
1357 : END DO
1358 : END DO
1359 :
1360 : vels_present = .TRUE.
1361 : END IF
1362 :
1363 : ! set the actual temperature...
1364 : IF (vels_present) THEN
1365 : ! ...from the initial velocities
1366 2 : ek = 0.0_dp
1367 14 : DO ia = 1, pint_env%ndim/3
1368 : rtmp = 0.0_dp
1369 48 : DO ic = 1, 3
1370 36 : idim = 3*(ia - 1) + ic
1371 48 : rtmp = rtmp + pint_env%v(1, idim)*pint_env%v(1, idim)
1372 : END DO
1373 14 : ek = ek + 0.5_dp*pint_env%mass(idim)*rtmp
1374 : END DO
1375 2 : actual_t = 2.0_dp*ek/pint_env%ndim
1376 : ELSE
1377 : ! ...using the temperature value from the input
1378 56 : actual_t = pint_env%kT
1379 : END IF
1380 :
1381 : ! set the target temperature
1382 58 : target_t = pint_env%kT
1383 : CALL section_vals_val_get(pint_env%input, &
1384 : "MOTION%PINT%INIT%VELOCITY_SCALE", &
1385 58 : l_val=done_scale)
1386 58 : IF (vels_present) THEN
1387 2 : IF (done_scale) THEN
1388 : ! rescale the velocities to match the target temperature
1389 2 : rtmp = SQRT(target_t/actual_t)
1390 14 : DO ia = 1, pint_env%ndim/3
1391 110 : DO ib = 1, pint_env%p
1392 396 : DO ic = 1, 3
1393 288 : idim = 3*(ia - 1) + ic
1394 384 : pint_env%v(ib, idim) = rtmp*pint_env%v(ib, idim)
1395 : END DO
1396 : END DO
1397 : END DO
1398 : ELSE
1399 : target_t = actual_t
1400 : END IF
1401 : END IF
1402 :
1403 : ! draw velocities from the M-B distribution...
1404 : IF (vels_present) THEN
1405 : ! ...for non-centroid modes only
1406 2 : CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
1407 2 : first_mode = 2
1408 : ELSE
1409 : ! ...for all the modes
1410 : first_mode = 1
1411 : END IF
1412 64984 : DO idim = 1, SIZE(pint_env%uv, 2)
1413 362596 : DO ib = first_mode, SIZE(pint_env%uv, 1)
1414 : pint_env%uv(ib, idim) = &
1415 362538 : pint_env%randomG%next(variance=target_t/pint_env%mass_fict(ib, idim))
1416 : END DO
1417 : END DO
1418 :
1419 : ! add random component to the centroid velocity if requested
1420 58 : done_sped = .FALSE.
1421 : CALL section_vals_val_get(pint_env%input, &
1422 : "MOTION%PINT%INIT%CENTROID_SPEED", &
1423 58 : l_val=ltmp)
1424 58 : IF (ltmp) THEN
1425 0 : CALL pint_u2x(pint_env, ux=pint_env%uv, x=pint_env%v)
1426 0 : DO idim = 1, pint_env%ndim
1427 : rtmp = pint_env%randomG%next(variance=pint_env%mass(idim)*pint_env%kT) &
1428 0 : /pint_env%mass(idim)
1429 0 : DO ib = 1, pint_env%p
1430 0 : pint_env%v(ib, idim) = pint_env%v(ib, idim) + rtmp
1431 : END DO
1432 : END DO
1433 0 : CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
1434 0 : done_sped = .TRUE.
1435 : END IF
1436 :
1437 : ! quench (set to zero) velocities for all the modes if requested
1438 : ! (disregard all the initialization done so far)
1439 58 : done_quench = .FALSE.
1440 : CALL section_vals_val_get(pint_env%input, &
1441 : "MOTION%PINT%INIT%VELOCITY_QUENCH", &
1442 58 : l_val=ltmp)
1443 58 : IF (ltmp) THEN
1444 0 : DO idim = 1, pint_env%ndim
1445 0 : DO ib = 1, pint_env%p
1446 0 : pint_env%v(ib, idim) = 0.0_dp
1447 : END DO
1448 : END DO
1449 0 : CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
1450 0 : done_quench = .TRUE.
1451 : END IF
1452 :
1453 : ! set the velocities to the values from the input if they are explicit
1454 : ! (disregard all the initialization done so far)
1455 58 : done_init = .FALSE.
1456 58 : NULLIFY (input_section)
1457 : input_section => section_vals_get_subs_vals(pint_env%input, &
1458 58 : "MOTION%PINT%BEADS%VELOCITY")
1459 58 : CALL section_vals_get(input_section, explicit=explicit)
1460 58 : IF (explicit) THEN
1461 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1462 8 : n_rep_val=n_rep_val)
1463 8 : IF (n_rep_val > 0) THEN
1464 8 : CPASSERT(n_rep_val == 1)
1465 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1466 8 : r_vals=r_vals)
1467 8 : IF (SIZE(r_vals) /= pint_env%p*pint_env%ndim) THEN
1468 0 : CPABORT("Invalid size of MOTION%PINT%BEAD%VELOCITY")
1469 : END IF
1470 8 : itmp = 0
1471 9278 : DO idim = 1, pint_env%ndim
1472 46358 : DO ib = 1, pint_env%p
1473 37080 : itmp = itmp + 1
1474 46350 : pint_env%v(ib, idim) = r_vals(itmp)
1475 : END DO
1476 : END DO
1477 8 : CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
1478 8 : done_init = .TRUE.
1479 : END IF
1480 : END IF
1481 :
1482 58 : unit_conv = cp_unit_from_cp2k(1.0_dp, "K")
1483 58 : WRITE (stmp1, '(F10.2)') target_t*pint_env%propagator%temp_sim2phys*unit_conv
1484 58 : msg = "Bead velocities initialization:"
1485 58 : IF (done_init) THEN
1486 8 : msg = TRIM(msg)//" input structure"
1487 50 : ELSE IF (done_quench) THEN
1488 0 : msg = TRIM(msg)//" quenching (set to 0.0)"
1489 : ELSE
1490 50 : IF (vels_present) THEN
1491 2 : msg = TRIM(ADJUSTL(msg))//" centroid +"
1492 : END IF
1493 50 : msg = TRIM(ADJUSTL(msg))//" Maxwell-Boltzmann at "//TRIM(ADJUSTL(stmp1))//" K."
1494 : END IF
1495 58 : CALL pint_write_line(msg)
1496 :
1497 58 : IF (done_init .AND. done_quench) THEN
1498 0 : msg = "WARNING: exclusive options requested (velocity restart and quenching)"
1499 0 : CPWARN(msg)
1500 0 : msg = "WARNING: velocity restart took precedence"
1501 0 : CPWARN(msg)
1502 : END IF
1503 :
1504 58 : IF ((.NOT. done_init) .AND. (.NOT. done_quench)) THEN
1505 50 : IF (vels_present .AND. done_scale) THEN
1506 2 : WRITE (stmp1, '(F10.2)') actual_t*unit_conv
1507 2 : WRITE (stmp2, '(F10.2)') target_t*unit_conv
1508 : msg = "Scaled initial velocities from "//TRIM(ADJUSTL(stmp1))// &
1509 2 : " to "//TRIM(ADJUSTL(stmp2))//" K as requested."
1510 2 : CPWARN(msg)
1511 : END IF
1512 50 : IF (done_sped) THEN
1513 0 : msg = "Added random component to the initial centroid velocities."
1514 0 : CPWARN(msg)
1515 : END IF
1516 : END IF
1517 :
1518 : ! Apply constraints to the initial velocities
1519 58 : IF (pint_env%simpar%constraint) THEN
1520 6 : IF (pint_env%propagator%prop_kind == propagator_rpmd) THEN
1521 : ! Multiply with 1/SQRT(n_beads) due to normal mode transformation in RPMD
1522 0 : factor = SQRT(REAL(pint_env%p, dp))
1523 : ELSE
1524 : ! lowest NM is centroid
1525 : factor = 1.0_dp
1526 : END IF
1527 : ! Beadwise constraints
1528 6 : IF (pint_env%beadwise_constraints) THEN
1529 2 : IF (pint_env%logger%para_env%is_source()) THEN
1530 1 : CALL pint_u2x(pint_env, ux=pint_env%uv, x=pint_env%v)
1531 5 : DO ib = 1, pint_env%p
1532 16 : DO i = 1, nparticle
1533 52 : DO j = 1, 3
1534 : ! Centroid is also constrained. This has to be changed if the initialization
1535 : ! of the positions of the beads is done as free particles (LEVY_POS_SAMPLE)
1536 : ! or if a Gaussian noise is added (RANDOMIZE_POS)
1537 36 : particle_set(i)%r(j) = pint_env%x(1, j + (i - 1)*3)/factor
1538 48 : vel(j, i) = pint_env%v(ib, j + (i - 1)*3)
1539 : END DO
1540 : END DO
1541 : ! Possibly update the target values
1542 : CALL shake_update_targets(gci, local_molecules, molecule_set, &
1543 : molecule_kind_set, pint_env%dt, &
1544 4 : f_env%force_env%root_section)
1545 : CALL rattle_control(gci, local_molecules, molecule_set, &
1546 : molecule_kind_set, particle_set, &
1547 : vel, pint_env%dt, pint_env%simpar%shake_tol, &
1548 : pint_env%simpar%info_constraint, &
1549 : pint_env%simpar%lagrange_multipliers, &
1550 : .FALSE., &
1551 : cell, mp_comm_self, &
1552 4 : local_particles)
1553 17 : DO i = 1, nparticle
1554 52 : DO j = 1, 3
1555 48 : pint_env%v(ib, j + (i - 1)*3) = vel(j, i)
1556 : END DO
1557 : END DO
1558 : END DO
1559 : ! Transform back to normal modes:
1560 1 : CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
1561 : END IF
1562 : ! Broadcast updated velocities to other nodes
1563 182 : CALL pint_env%logger%para_env%bcast(pint_env%uv)
1564 : ! Centroid constraints
1565 : ELSE
1566 : ! Transform positions and velocities to Cartesian coordinates:
1567 4 : IF (pint_env%logger%para_env%is_source()) THEN
1568 8 : DO i = 1, nparticle
1569 26 : DO j = 1, 3
1570 18 : particle_set(i)%r(j) = pint_env%x(1, j + (i - 1)*3)/factor
1571 24 : vel(j, i) = pint_env%uv(1, j + (i - 1)*3)/factor
1572 : END DO
1573 : END DO
1574 : ! Possibly update the target values
1575 : CALL shake_update_targets(gci, local_molecules, molecule_set, &
1576 : molecule_kind_set, pint_env%dt, &
1577 2 : f_env%force_env%root_section)
1578 : CALL rattle_control(gci, local_molecules, molecule_set, &
1579 : molecule_kind_set, particle_set, &
1580 : vel, pint_env%dt, pint_env%simpar%shake_tol, &
1581 : pint_env%simpar%info_constraint, &
1582 : pint_env%simpar%lagrange_multipliers, &
1583 : .FALSE., &
1584 : cell, mp_comm_self, &
1585 2 : local_particles)
1586 : END IF
1587 : ! Broadcast updated velocities to other nodes
1588 4 : CALL pint_env%logger%para_env%bcast(vel)
1589 : ! Transform back to normal modes
1590 16 : DO i = 1, nparticle
1591 52 : DO j = 1, 3
1592 48 : pint_env%uv(1, j + (i - 1)*3) = vel(j, i)*factor
1593 : END DO
1594 : END DO
1595 : END IF
1596 : END IF
1597 :
1598 116 : END SUBROUTINE pint_init_v
1599 :
1600 : ! ***************************************************************************
1601 : !> \brief Assign initial postions and velocities to the thermostats.
1602 : !> \param pint_env ...
1603 : !> \param kT ...
1604 : !> \date 2010-12-15
1605 : !> \author Lukasz Walewski
1606 : !> \note Extracted from pint_init
1607 : ! **************************************************************************************************
1608 58 : SUBROUTINE pint_init_t(pint_env, kT)
1609 :
1610 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
1611 : REAL(kind=dp), INTENT(in), OPTIONAL :: kT
1612 :
1613 : INTEGER :: ib, idim, ii, inos, n_rep_val
1614 : LOGICAL :: explicit, gle_restart
1615 : REAL(kind=dp) :: mykt
1616 58 : REAL(kind=dp), DIMENSION(:), POINTER :: r_vals
1617 : TYPE(section_vals_type), POINTER :: input_section
1618 :
1619 110 : IF (pint_env%pimd_thermostat == thermostat_nose) THEN
1620 :
1621 26 : mykt = pint_env%kT
1622 26 : IF (PRESENT(kT)) mykt = kT
1623 9476 : DO idim = 1, SIZE(pint_env%tv, 3)
1624 29096 : DO ib = 1, SIZE(pint_env%tv, 2)
1625 88218 : DO inos = 1, SIZE(pint_env%tv, 1)
1626 : pint_env%tv(inos, ib, idim) = &
1627 78768 : pint_env%randomG%next(variance=mykt/pint_env%Q(ib))
1628 : END DO
1629 : END DO
1630 : END DO
1631 26 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
1632 74 : pint_env%tv(:, 1, :) = 0.0_dp
1633 : END IF
1634 :
1635 26 : NULLIFY (input_section)
1636 : input_section => section_vals_get_subs_vals(pint_env%input, &
1637 26 : "MOTION%PINT%NOSE%COORD")
1638 26 : CALL section_vals_get(input_section, explicit=explicit)
1639 26 : IF (explicit) THEN
1640 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1641 6 : n_rep_val=n_rep_val)
1642 6 : IF (n_rep_val > 0) THEN
1643 6 : CPASSERT(n_rep_val == 1)
1644 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1645 6 : r_vals=r_vals)
1646 6 : IF (SIZE(r_vals) /= pint_env%p*pint_env%ndim*pint_env%nnos) THEN
1647 0 : CPABORT("Invalid size of MOTION%PINT%NOSE%COORD")
1648 : END IF
1649 6 : ii = 0
1650 60 : DO idim = 1, pint_env%ndim
1651 276 : DO ib = 1, pint_env%p
1652 918 : DO inos = 1, pint_env%nnos
1653 648 : ii = ii + 1
1654 864 : pint_env%tx(inos, ib, idim) = r_vals(ii)
1655 : END DO
1656 : END DO
1657 : END DO
1658 : END IF
1659 : END IF
1660 26 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
1661 74 : pint_env%tx(:, 1, :) = 0.0_dp
1662 : END IF
1663 :
1664 26 : NULLIFY (input_section)
1665 : input_section => section_vals_get_subs_vals(pint_env%input, &
1666 26 : "MOTION%PINT%NOSE%VELOCITY")
1667 26 : CALL section_vals_get(input_section, explicit=explicit)
1668 26 : IF (explicit) THEN
1669 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1670 6 : n_rep_val=n_rep_val)
1671 6 : IF (n_rep_val > 0) THEN
1672 6 : CPASSERT(n_rep_val == 1)
1673 : CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
1674 6 : r_vals=r_vals)
1675 6 : IF (SIZE(r_vals) /= pint_env%p*pint_env%ndim*pint_env%nnos) THEN
1676 0 : CPABORT("Invalid size of MOTION%PINT%NOSE%VELOCITY")
1677 : END IF
1678 6 : ii = 0
1679 60 : DO idim = 1, pint_env%ndim
1680 276 : DO ib = 1, pint_env%p
1681 918 : DO inos = 1, pint_env%nnos
1682 648 : ii = ii + 1
1683 864 : pint_env%tv(inos, ib, idim) = r_vals(ii)
1684 : END DO
1685 : END DO
1686 : END DO
1687 : END IF
1688 6 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
1689 0 : pint_env%tv(:, 1, :) = 0.0_dp
1690 : END IF
1691 : END IF
1692 :
1693 32 : ELSE IF (pint_env%pimd_thermostat == thermostat_gle) THEN
1694 2 : NULLIFY (input_section)
1695 : input_section => section_vals_get_subs_vals(pint_env%input, &
1696 2 : "MOTION%PINT%GLE")
1697 2 : CALL section_vals_get(input_section, explicit=explicit)
1698 2 : IF (explicit) THEN
1699 : CALL restart_gle(pint_env%gle, input_section, save_mem=.FALSE., &
1700 2 : restart=gle_restart)
1701 : END IF
1702 : END IF
1703 :
1704 58 : END SUBROUTINE pint_init_t
1705 :
1706 : ! ***************************************************************************
1707 : !> \brief Prepares the forces, etc. to perform an PIMD step
1708 : !> \param pint_env ...
1709 : !> \param helium_env ...
1710 : !> \par History
1711 : !> Added nh_energy calculation [hforbert]
1712 : !> Bug fixes for no thermostats [hforbert]
1713 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1714 : !> \author fawzi
1715 : ! **************************************************************************************************
1716 148 : SUBROUTINE pint_init_f(pint_env, helium_env)
1717 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
1718 : TYPE(helium_solvent_p_type), DIMENSION(:), &
1719 : OPTIONAL, POINTER :: helium_env
1720 :
1721 : INTEGER :: ib, idim, inos
1722 : REAL(kind=dp) :: e_h
1723 : TYPE(cp_logger_type), POINTER :: logger
1724 :
1725 74 : NULLIFY (logger)
1726 74 : logger => cp_get_default_logger()
1727 :
1728 : ! initialize iteration info
1729 74 : CALL cp_iterate(logger%iter_info, iter_nr=pint_env%first_step)
1730 74 : CALL cp_iterate(pint_env%logger%iter_info, iter_nr=pint_env%first_step)
1731 :
1732 74 : CALL pint_x2u(pint_env)
1733 74 : CALL pint_calc_uf_h(pint_env=pint_env, e_h=e_h)
1734 74 : CALL pint_calc_f(pint_env)
1735 :
1736 : ! add helium forces to the solute's internal ones
1737 : ! Assume that helium has been already initialized and helium_env(1)
1738 : ! contains proper forces in force_avrg array at ionode
1739 74 : IF (PRESENT(helium_env)) THEN
1740 16 : IF (logger%para_env%is_source()) THEN
1741 728 : pint_env%f(:, :) = pint_env%f(:, :) + helium_env(1)%helium%force_avrg(:, :)
1742 : END IF
1743 2896 : CALL logger%para_env%bcast(pint_env%f)
1744 : END IF
1745 74 : CALL pint_f2uf(pint_env)
1746 :
1747 : ! set the centroid forces to 0 if FIX_CENTROID_POS
1748 74 : IF (pint_env%first_propagated_mode == 2) THEN
1749 0 : pint_env%uf(1, :) = 0.0_dp
1750 : END IF
1751 :
1752 74 : CALL pint_calc_e_kin_beads_u(pint_env)
1753 74 : CALL pint_calc_e_vir(pint_env)
1754 65144 : DO idim = 1, SIZE(pint_env%uf_h, 2)
1755 364088 : DO ib = pint_env%first_propagated_mode, SIZE(pint_env%uf_h, 1)
1756 364014 : pint_env%uf(ib, idim) = REAL(pint_env%nrespa, dp)*pint_env%uf(ib, idim)
1757 : END DO
1758 : END DO
1759 :
1760 74 : IF (pint_env%nnos > 0) THEN
1761 9576 : DO idim = 1, SIZE(pint_env%uf_h, 2)
1762 29556 : DO ib = 1, SIZE(pint_env%uf_h, 1)
1763 : pint_env%tf(1, ib, idim) = (pint_env%mass_fict(ib, idim)* &
1764 29520 : pint_env%uv(ib, idim)**2 - pint_env%kT)/pint_env%Q(ib)
1765 : END DO
1766 : END DO
1767 :
1768 9576 : DO idim = 1, pint_env%ndim
1769 29556 : DO ib = 1, pint_env%p
1770 60228 : DO inos = 1, pint_env%nnos - 1
1771 : pint_env%tf(inos + 1, ib, idim) = pint_env%tv(inos, ib, idim)**2 - &
1772 60228 : pint_env%kT/pint_env%Q(ib)
1773 : END DO
1774 69768 : DO inos = 1, pint_env%nnos - 1
1775 : pint_env%tf(inos, ib, idim) = pint_env%tf(inos, ib, idim) &
1776 60228 : - pint_env%tv(inos, ib, idim)*pint_env%tv(inos + 1, ib, idim)
1777 : END DO
1778 : END DO
1779 : END DO
1780 36 : CALL pint_calc_nh_energy(pint_env)
1781 : END IF
1782 :
1783 74 : END SUBROUTINE pint_init_f
1784 :
1785 : ! ***************************************************************************
1786 : !> \brief Perform the PIMD simulation (main MD loop)
1787 : !> \param pint_env ...
1788 : !> \param globenv ...
1789 : !> \param helium_env ...
1790 : !> \par History
1791 : !> 2003-11 created [fawzi]
1792 : !> renamed from pint_run to pint_do_run because of conflicting name
1793 : !> of pint_run in input_constants [hforbert]
1794 : !> 2009-12-14 globenv parameter added to handle soft exit
1795 : !> requests [lwalewski]
1796 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1797 : !> \author Fawzi Mohamed
1798 : !> \note Everything should be read for an md step.
1799 : ! **************************************************************************************************
1800 58 : SUBROUTINE pint_do_run(pint_env, globenv, helium_env)
1801 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
1802 : TYPE(global_environment_type), POINTER :: globenv
1803 : TYPE(helium_solvent_p_type), DIMENSION(:), &
1804 : OPTIONAL, POINTER :: helium_env
1805 :
1806 : INTEGER :: k, step
1807 : LOGICAL :: should_stop
1808 : REAL(kind=dp) :: scal
1809 : TYPE(cp_logger_type), POINTER :: logger
1810 : TYPE(f_env_type), POINTER :: f_env
1811 :
1812 : ! initialize iteration info
1813 58 : CALL cp_iterate(pint_env%logger%iter_info, iter_nr=pint_env%first_step)
1814 :
1815 : ! iterate replica pint counter by accessing the globally saved
1816 : ! force environment error/logger variables and setting them
1817 : ! explicitly to the pimd "PINT" step value
1818 : CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, &
1819 58 : f_env=f_env)
1820 58 : NULLIFY (logger)
1821 58 : logger => cp_get_default_logger()
1822 : CALL cp_iterate(logger%iter_info, &
1823 58 : iter_nr=pint_env%first_step)
1824 58 : CALL f_env_rm_defaults(f_env)
1825 :
1826 58 : pint_env%iter = pint_env%first_step
1827 :
1828 58 : IF (PRESENT(helium_env)) THEN
1829 16 : IF (ASSOCIATED(helium_env)) THEN
1830 : ! set the properties accumulated over the whole MC process to 0
1831 36 : DO k = 1, SIZE(helium_env)
1832 84 : helium_env(k)%helium%proarea%accu(:) = 0.0_dp
1833 84 : helium_env(k)%helium%prarea2%accu(:) = 0.0_dp
1834 84 : helium_env(k)%helium%wnmber2%accu(:) = 0.0_dp
1835 84 : helium_env(k)%helium%mominer%accu(:) = 0.0_dp
1836 21 : IF (helium_env(k)%helium%rho_present) THEN
1837 0 : helium_env(k)%helium%rho_accu(:, :, :, :) = 0.0_dp
1838 : END IF
1839 36 : IF (helium_env(k)%helium%rdf_present) THEN
1840 0 : helium_env(k)%helium%rdf_accu(:, :) = 0.0_dp
1841 : END IF
1842 : END DO
1843 : END IF
1844 : END IF
1845 :
1846 : ! write the properties at 0-th step
1847 58 : CALL pint_calc_energy(pint_env)
1848 58 : CALL pint_calc_total_action(pint_env)
1849 58 : CALL pint_write_ener(pint_env)
1850 58 : CALL pint_write_action(pint_env)
1851 58 : CALL pint_write_centroids(pint_env)
1852 58 : CALL pint_write_trajectory(pint_env)
1853 58 : CALL pint_write_com(pint_env)
1854 58 : CALL pint_write_rgyr(pint_env)
1855 :
1856 : ! main PIMD loop
1857 696 : DO step = 1, pint_env%num_steps
1858 :
1859 638 : pint_env%iter = pint_env%iter + 1
1860 : CALL cp_iterate(pint_env%logger%iter_info, &
1861 : last=(step == pint_env%num_steps), &
1862 638 : iter_nr=pint_env%iter)
1863 : CALL cp_iterate(logger%iter_info, &
1864 : last=(step == pint_env%num_steps), &
1865 638 : iter_nr=pint_env%iter)
1866 638 : pint_env%t = pint_env%t + pint_env%dt
1867 :
1868 638 : IF (pint_env%t_tol > 0.0_dp) THEN
1869 0 : IF (ABS(2._dp*pint_env%e_kin_beads/(pint_env%p*pint_env%ndim) &
1870 : - pint_env%kT) > pint_env%t_tol) THEN
1871 0 : scal = SQRT(pint_env%kT*(pint_env%p*pint_env%ndim)/(2.0_dp*pint_env%e_kin_beads))
1872 0 : pint_env%uv = scal*pint_env%uv
1873 0 : CALL pint_init_f(pint_env, helium_env=helium_env)
1874 : END IF
1875 : END IF
1876 638 : CALL pint_step(pint_env, helium_env=helium_env)
1877 :
1878 638 : CALL pint_write_ener(pint_env)
1879 638 : CALL pint_write_action(pint_env)
1880 638 : CALL pint_write_centroids(pint_env)
1881 638 : CALL pint_write_trajectory(pint_env)
1882 638 : CALL pint_write_com(pint_env)
1883 638 : CALL pint_write_rgyr(pint_env)
1884 :
1885 : CALL write_restart(root_section=pint_env%input, &
1886 638 : pint_env=pint_env, helium_env=helium_env)
1887 :
1888 : ! exit from the main loop if soft exit has been requested
1889 638 : CALL external_control(should_stop, "PINT", globenv=globenv)
1890 696 : IF (should_stop) EXIT
1891 :
1892 : END DO
1893 :
1894 : ! remove iteration level
1895 58 : CALL cp_rm_iter_level(pint_env%logger%iter_info, "PINT")
1896 :
1897 58 : END SUBROUTINE pint_do_run
1898 :
1899 : ! ***************************************************************************
1900 : !> \brief Performs a scan of the helium-solute interaction energy
1901 : !> \param pint_env ...
1902 : !> \param helium_env ...
1903 : !> \date 2013-11-26
1904 : !> \parm History
1905 : !> 2016-07-14 Modified to work with independent helium_env [cschran]
1906 : !> \author Lukasz Walewski
1907 : ! **************************************************************************************************
1908 0 : SUBROUTINE pint_run_scan(pint_env, helium_env)
1909 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
1910 : TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
1911 :
1912 : CHARACTER(len=default_string_length) :: comment
1913 : INTEGER :: unit_nr
1914 0 : REAL(kind=dp), DIMENSION(:, :, :), POINTER :: DATA
1915 : TYPE(section_vals_type), POINTER :: print_key
1916 :
1917 0 : NULLIFY (pint_env%logger, print_key)
1918 0 : pint_env%logger => cp_get_default_logger()
1919 :
1920 : ! assume that ionode always has at least one helium_env
1921 0 : IF (pint_env%logger%para_env%is_source()) THEN
1922 : print_key => section_vals_get_subs_vals(helium_env(1)%helium%input, &
1923 0 : "MOTION%PINT%HELIUM%PRINT%RHO")
1924 : END IF
1925 :
1926 : ! perform the actual scan wrt the COM of the solute
1927 0 : CALL helium_intpot_scan(pint_env, helium_env)
1928 :
1929 : ! output the interaction potential into a cubefile
1930 : ! assume that ionode always has at least one helium_env
1931 0 : IF (pint_env%logger%para_env%is_source()) THEN
1932 :
1933 : unit_nr = cp_print_key_unit_nr( &
1934 : pint_env%logger, &
1935 : print_key, &
1936 : middle_name="helium-pot", &
1937 : extension=".cube", &
1938 : file_position="REWIND", &
1939 0 : do_backup=.FALSE.)
1940 :
1941 0 : comment = "Solute - helium interaction potential"
1942 0 : NULLIFY (DATA)
1943 0 : DATA => helium_env(1)%helium%rho_inst(1, :, :, :)
1944 : CALL helium_write_cubefile( &
1945 : unit_nr, &
1946 : comment, &
1947 : helium_env(1)%helium%center - 0.5_dp* &
1948 : (helium_env(1)%helium%rho_maxr - helium_env(1)%helium%rho_delr), &
1949 : helium_env(1)%helium%rho_delr, &
1950 : helium_env(1)%helium%rho_nbin, &
1951 0 : DATA)
1952 :
1953 0 : CALL m_flush(unit_nr)
1954 0 : CALL cp_print_key_finished_output(unit_nr, pint_env%logger, print_key)
1955 :
1956 : END IF
1957 :
1958 : ! output solute positions
1959 0 : CALL pint_write_centroids(pint_env)
1960 0 : CALL pint_write_trajectory(pint_env)
1961 :
1962 0 : END SUBROUTINE pint_run_scan
1963 :
1964 : ! ***************************************************************************
1965 : !> \brief Does an PINT step (and nrespa harmonic evaluations)
1966 : !> \param pint_env ...
1967 : !> \param helium_env ...
1968 : !> \par History
1969 : !> various bug fixes [hforbert]
1970 : !> 10.2015 Added RPMD propagator and harmonic integrator [Felix Uhl]
1971 : !> 04.2016 Changed to work with helium_env [cschran]
1972 : !> 10.2018 Added centroid constraints [cschran+rperez]
1973 : !> 10.2021 Added beadwise constraints [lduran]
1974 : !> \author fawzi
1975 : ! **************************************************************************************************
1976 638 : SUBROUTINE pint_step(pint_env, helium_env)
1977 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
1978 : TYPE(helium_solvent_p_type), DIMENSION(:), &
1979 : OPTIONAL, POINTER :: helium_env
1980 :
1981 : CHARACTER(len=*), PARAMETER :: routineN = 'pint_step'
1982 :
1983 : INTEGER :: handle, i, ia, ib, idim, ierr, inos, &
1984 : iresp, j, k, nbeads, nparticle, &
1985 : nparticle_kind
1986 : REAL(kind=dp) :: dt_temp, dti, dti2, dti22, e_h, factor, &
1987 : rn, tdti, time_start, time_stop, tol
1988 638 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: pos, vel
1989 638 : REAL(kind=dp), DIMENSION(:, :, :), POINTER :: tmp
1990 : TYPE(atomic_kind_list_type), POINTER :: atomic_kinds
1991 638 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1992 : TYPE(cell_type), POINTER :: cell
1993 : TYPE(cp_subsys_type), POINTER :: subsys
1994 : TYPE(distribution_1d_type), POINTER :: local_molecules, local_particles
1995 : TYPE(f_env_type), POINTER :: f_env
1996 : TYPE(global_constraint_type), POINTER :: gci
1997 : TYPE(molecule_kind_list_type), POINTER :: molecule_kinds
1998 638 : TYPE(molecule_kind_type), DIMENSION(:), POINTER :: molecule_kind_set
1999 : TYPE(molecule_list_type), POINTER :: molecules
2000 638 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
2001 : TYPE(particle_list_type), POINTER :: particles
2002 638 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2003 :
2004 638 : CALL timeset(routineN, handle)
2005 638 : time_start = m_walltime()
2006 :
2007 638 : rn = REAL(pint_env%nrespa, dp)
2008 638 : dti = pint_env%dt/rn
2009 638 : dti2 = dti/2._dp
2010 638 : tdti = 2.*dti
2011 638 : dti22 = dti**2/2._dp
2012 :
2013 : ! Get constraint info, if needed
2014 : ! Create a force environment which will be identical to
2015 : ! the bead that is being processed by the processor.
2016 638 : IF (pint_env%simpar%constraint) THEN
2017 24 : NULLIFY (subsys, cell)
2018 24 : NULLIFY (atomic_kinds, local_particles, particles)
2019 24 : NULLIFY (local_molecules, molecules, molecule_kinds, gci)
2020 24 : NULLIFY (atomic_kind_set, molecule_kind_set, particle_set, molecule_set)
2021 :
2022 24 : CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, f_env=f_env)
2023 24 : CALL force_env_get(force_env=f_env%force_env, subsys=subsys)
2024 24 : CALL f_env_rm_defaults(f_env, ierr)
2025 24 : CPASSERT(ierr == 0)
2026 :
2027 : ! Get gci and more from subsys
2028 : CALL cp_subsys_get(subsys=subsys, &
2029 : cell=cell, &
2030 : atomic_kinds=atomic_kinds, &
2031 : local_particles=local_particles, &
2032 : particles=particles, &
2033 : local_molecules=local_molecules, &
2034 : molecules=molecules, &
2035 : molecule_kinds=molecule_kinds, &
2036 24 : gci=gci)
2037 :
2038 24 : nparticle_kind = atomic_kinds%n_els
2039 24 : atomic_kind_set => atomic_kinds%els
2040 24 : molecule_kind_set => molecule_kinds%els
2041 24 : nparticle = particles%n_els
2042 24 : nbeads = pint_env%p
2043 24 : particle_set => particles%els
2044 24 : molecule_set => molecules%els
2045 :
2046 : ! Allocate work storage
2047 72 : ALLOCATE (pos(3, nparticle))
2048 48 : ALLOCATE (vel(3, nparticle))
2049 24 : pos(:, :) = 0.0_dp
2050 24 : vel(:, :) = 0.0_dp
2051 :
2052 24 : IF (pint_env%propagator%prop_kind == propagator_rpmd) THEN
2053 : ! Multiply with 1/SQRT(n_beads) due to normal mode transformation in RPMD
2054 0 : factor = SQRT(REAL(pint_env%p, dp))
2055 : ELSE
2056 : factor = 1.0_dp
2057 : END IF
2058 :
2059 : CALL getold(gci, local_molecules, molecule_set, &
2060 48 : molecule_kind_set, particle_set, cell)
2061 : END IF
2062 :
2063 900 : SELECT CASE (pint_env%harm_integrator)
2064 : CASE (integrate_numeric)
2065 :
2066 938 : DO iresp = 1, pint_env%nrespa
2067 :
2068 : ! integrate bead positions, first_propagated_mode = { 1, 2 }
2069 : ! Nose needs an extra step
2070 676 : IF (pint_env%pimd_thermostat == thermostat_nose) THEN
2071 :
2072 : !Set thermostat action of constrained DoF to zero:
2073 616 : IF (pint_env%simpar%constraint) THEN
2074 48 : DO k = 1, pint_env%n_atoms_constraints
2075 32 : ia = pint_env%atoms_constraints(k)
2076 144 : DO j = 3*(ia - 1) + 1, 3*ia
2077 416 : pint_env%tv(:, 1, j) = 0.0_dp
2078 : END DO
2079 : END DO
2080 : END IF
2081 :
2082 : ! Exempt centroid from thermostat for CMD
2083 616 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2084 5920 : pint_env%tx(:, 1, :) = 0.0_dp
2085 5920 : pint_env%tv(:, 1, :) = 0.0_dp
2086 5920 : pint_env%tf(:, 1, :) = 0.0_dp
2087 : END IF
2088 :
2089 4832 : DO i = pint_env%first_propagated_mode, pint_env%p
2090 : pint_env%ux(i, :) = pint_env%ux(i, :) - &
2091 93968 : dti22*pint_env%uv(i, :)*pint_env%tv(1, i, :)
2092 : END DO
2093 411700 : pint_env%tx = pint_env%tx + dti*pint_env%tv + dti22*pint_env%tf
2094 :
2095 616 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2096 5920 : pint_env%tx(:, 1, :) = 0.0_dp
2097 5920 : pint_env%tv(:, 1, :) = 0.0_dp
2098 5920 : pint_env%tf(:, 1, :) = 0.0_dp
2099 : END IF
2100 :
2101 : END IF
2102 : !Integrate position in harmonic springs (uf_h) and physical potential
2103 : !(uf)
2104 5124 : DO i = pint_env%first_propagated_mode, pint_env%p
2105 : pint_env%ux_t(i, :) = pint_env%ux(i, :) + &
2106 : dti*pint_env%uv(i, :) + &
2107 : dti22*(pint_env%uf_h(i, :) + &
2108 133140 : pint_env%uf(i, :))
2109 : END DO
2110 :
2111 : ! apply thermostats to velocities
2112 1292 : SELECT CASE (pint_env%pimd_thermostat)
2113 : CASE (thermostat_nose)
2114 :
2115 616 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2116 5920 : pint_env%tx(:, 1, :) = 0.0_dp
2117 5920 : pint_env%tv(:, 1, :) = 0.0_dp
2118 5920 : pint_env%tf(:, 1, :) = 0.0_dp
2119 : END IF
2120 :
2121 : pint_env%uv_t = pint_env%uv - dti2* &
2122 230368 : pint_env%uv*pint_env%tv(1, :, :)
2123 616 : tmp => pint_env%tv_t
2124 616 : pint_env%tv_t => pint_env%tv
2125 616 : pint_env%tv => tmp
2126 411700 : pint_env%tv = pint_env%tv_old + tdti*pint_env%tf
2127 411700 : pint_env%tv_old = pint_env%tv_t
2128 411700 : pint_env%tv_t = pint_env%tv_t + dti2*pint_env%tf
2129 : CASE DEFAULT
2130 58492 : pint_env%uv_t = pint_env%uv
2131 : END SELECT
2132 :
2133 : !Set thermostat action of constrained DoF to zero:
2134 676 : IF (pint_env%simpar%constraint) THEN
2135 48 : DO k = 1, pint_env%n_atoms_constraints
2136 32 : ia = pint_env%atoms_constraints(k)
2137 144 : DO j = 3*(ia - 1) + 1, 3*ia
2138 384 : pint_env%tv(:, 1, j) = 0.0_dp
2139 416 : pint_env%tv_t(:, 1, j) = 0.0_dp
2140 : END DO
2141 : END DO
2142 : END IF
2143 :
2144 : ! Exempt centroid from thermostat for CMD
2145 676 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2146 5920 : pint_env%tx(:, 1, :) = 0.0_dp
2147 5920 : pint_env%tv(:, 1, :) = 0.0_dp
2148 5920 : pint_env%tf(:, 1, :) = 0.0_dp
2149 : END IF
2150 :
2151 : !Integrate harmonic velocities and physical velocities
2152 173368 : pint_env%uv_t = pint_env%uv_t + dti2*(pint_env%uf_h + pint_env%uf)
2153 :
2154 : ! physical forces are only applied in first respa step.
2155 173368 : pint_env%uf = 0.0_dp
2156 : ! calc harmonic forces at new pos
2157 173368 : pint_env%ux = pint_env%ux_t
2158 :
2159 : ! Apply centroid constraints (SHAKE)
2160 676 : IF (pint_env%simpar%constraint) THEN
2161 16 : IF (pint_env%logger%para_env%is_source()) THEN
2162 32 : DO i = 1, nparticle
2163 104 : DO j = 1, 3
2164 72 : pos(j, i) = pint_env%ux(1, j + (i - 1)*3)
2165 96 : vel(j, i) = pint_env%uv_t(1, j + (i - 1)*3)
2166 : END DO
2167 : END DO
2168 :
2169 : ! Possibly update the target values
2170 : CALL shake_update_targets(gci, local_molecules, molecule_set, &
2171 : molecule_kind_set, dti, &
2172 8 : f_env%force_env%root_section)
2173 : CALL shake_control(gci, local_molecules, molecule_set, &
2174 : molecule_kind_set, particle_set, &
2175 : pos, vel, dti, pint_env%simpar%shake_tol, &
2176 : pint_env%simpar%info_constraint, &
2177 : pint_env%simpar%lagrange_multipliers, &
2178 : pint_env%simpar%dump_lm, cell, &
2179 8 : mp_comm_self, local_particles)
2180 : END IF
2181 : ! Positions and velocities of centroid were constrained by SHAKE
2182 16 : CALL pint_env%logger%para_env%bcast(pos)
2183 16 : CALL pint_env%logger%para_env%bcast(vel)
2184 : ! Transform back to normal modes:
2185 64 : DO i = 1, nparticle
2186 208 : DO j = 1, 3
2187 144 : pint_env%ux(1, j + (i - 1)*3) = pos(j, i)
2188 192 : pint_env%uv_t(1, j + (i - 1)*3) = vel(j, i)
2189 : END DO
2190 : END DO
2191 :
2192 : END IF
2193 : ! Exempt centroid from thermostat for CMD
2194 676 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2195 5920 : pint_env%tx(:, 1, :) = 0.0_dp
2196 5920 : pint_env%tv(:, 1, :) = 0.0_dp
2197 5920 : pint_env%tf(:, 1, :) = 0.0_dp
2198 : END IF
2199 :
2200 676 : CALL pint_calc_uf_h(pint_env=pint_env, e_h=e_h)
2201 173368 : pint_env%uv_t = pint_env%uv_t + dti2*(pint_env%uf_h + pint_env%uf)
2202 :
2203 : ! For last respa step include integration of physical and helium
2204 : ! forces
2205 676 : IF (iresp == pint_env%nrespa) THEN
2206 262 : CALL pint_u2x(pint_env)
2207 262 : CALL pint_calc_f(pint_env)
2208 : ! perform helium step and add helium forces
2209 262 : IF (PRESENT(helium_env)) THEN
2210 50 : CALL helium_step(helium_env, pint_env)
2211 : !Update force of solute in pint_env
2212 50 : IF (pint_env%logger%para_env%is_source()) THEN
2213 1150 : pint_env%f(:, :) = pint_env%f(:, :) + helium_env(1)%helium%force_avrg(:, :)
2214 : END IF
2215 4550 : CALL pint_env%logger%para_env%bcast(pint_env%f)
2216 : END IF
2217 :
2218 262 : CALL pint_f2uf(pint_env)
2219 : ! set the centroid forces to 0 if FIX_CENTROID_POS
2220 262 : IF (pint_env%first_propagated_mode == 2) THEN
2221 0 : pint_env%uf(1, :) = 0.0_dp
2222 : END IF
2223 : !Scale physical forces and integrate velocities with physical
2224 : !forces
2225 128944 : pint_env%uf = pint_env%uf*rn
2226 128944 : pint_env%uv_t = pint_env%uv_t + dti2*pint_env%uf
2227 :
2228 : END IF
2229 :
2230 : ! Apply second half of thermostats
2231 938 : SELECT CASE (pint_env%pimd_thermostat)
2232 : CASE (thermostat_nose)
2233 : ! Exempt centroid from thermostat for CMD
2234 616 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2235 5920 : pint_env%tx(:, 1, :) = 0.0_dp
2236 5920 : pint_env%tv(:, 1, :) = 0.0_dp
2237 5920 : pint_env%tf(:, 1, :) = 0.0_dp
2238 : END IF
2239 3760 : DO i = 1, 6
2240 3380 : tol = 0._dp
2241 1353452 : pint_env%uv_new = pint_env%uv_t/(1.+dti2*pint_env%tv(1, :, :))
2242 154976 : DO idim = 1, pint_env%ndim
2243 678416 : DO ib = 1, pint_env%p
2244 : pint_env%tf(1, ib, idim) = (pint_env%mass_fict(ib, idim)* &
2245 : pint_env%uv_new(ib, idim)**2 - pint_env%kT*pint_env%kTcorr)/ &
2246 675036 : pint_env%Q(ib)
2247 : END DO
2248 : END DO
2249 :
2250 : !Set thermostat action of constrained DoF to zero:
2251 3380 : IF (pint_env%simpar%constraint) THEN
2252 288 : DO k = 1, pint_env%n_atoms_constraints
2253 192 : ia = pint_env%atoms_constraints(k)
2254 864 : DO j = 3*(ia - 1) + 1, 3*ia
2255 2496 : pint_env%tf(:, 1, j) = 0.0_dp
2256 : END DO
2257 : END DO
2258 : END IF
2259 :
2260 : ! Exempt centroid from thermostat for CMD
2261 3380 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2262 35520 : pint_env%tx(:, 1, :) = 0.0_dp
2263 35520 : pint_env%tv(:, 1, :) = 0.0_dp
2264 35520 : pint_env%tf(:, 1, :) = 0.0_dp
2265 : END IF
2266 :
2267 154976 : DO idim = 1, pint_env%ndim
2268 678416 : DO ib = 1, pint_env%p
2269 1743120 : DO inos = 1, pint_env%nnos - 1
2270 : pint_env%tv_new(inos, ib, idim) = &
2271 : (pint_env%tv_t(inos, ib, idim) + dti2*pint_env%tf(inos, ib, idim))/ &
2272 1219680 : (1._dp + dti2*pint_env%tv(inos + 1, ib, idim))
2273 : pint_env%tf(inos + 1, ib, idim) = &
2274 : (pint_env%tv_new(inos, ib, idim)**2 - &
2275 1219680 : pint_env%kT*pint_env%kTcorr/pint_env%Q(ib))
2276 : tol = MAX(tol, ABS(pint_env%tv(inos, ib, idim) &
2277 1743120 : - pint_env%tv_new(inos, ib, idim)))
2278 : END DO
2279 : !Set thermostat action of constrained DoF to zero:
2280 523440 : IF (pint_env%simpar%constraint) THEN
2281 10368 : DO k = 1, pint_env%n_atoms_constraints
2282 6912 : ia = pint_env%atoms_constraints(k)
2283 31104 : DO j = 3*(ia - 1) + 1, 3*ia
2284 82944 : pint_env%tv_new(:, 1, j) = 0.0_dp
2285 89856 : pint_env%tf(:, 1, j) = 0.0_dp
2286 : END DO
2287 : END DO
2288 : END IF
2289 :
2290 : ! Exempt centroid from thermostat for CMD
2291 523440 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2292 3196800 : pint_env%tx(:, 1, :) = 0.0_dp
2293 3196800 : pint_env%tv(:, 1, :) = 0.0_dp
2294 3196800 : pint_env%tf(:, 1, :) = 0.0_dp
2295 : END IF
2296 :
2297 : pint_env%tv_new(pint_env%nnos, ib, idim) = &
2298 : pint_env%tv_t(pint_env%nnos, ib, idim) + &
2299 523440 : dti2*pint_env%tf(pint_env%nnos, ib, idim)
2300 : tol = MAX(tol, ABS(pint_env%tv(pint_env%nnos, ib, idim) &
2301 523440 : - pint_env%tv_new(pint_env%nnos, ib, idim)))
2302 : tol = MAX(tol, ABS(pint_env%uv(ib, idim) &
2303 523440 : - pint_env%uv_new(ib, idim)))
2304 : !Set thermostat action of constrained DoF to zero:
2305 523440 : IF (pint_env%simpar%constraint) THEN
2306 10368 : DO k = 1, pint_env%n_atoms_constraints
2307 6912 : ia = pint_env%atoms_constraints(k)
2308 31104 : DO j = 3*(ia - 1) + 1, 3*ia
2309 89856 : pint_env%tv_new(:, 1, j) = 0.0_dp
2310 : END DO
2311 : END DO
2312 : END IF
2313 : ! Exempt centroid from thermostat for CMD
2314 675036 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2315 3196800 : pint_env%tx(:, 1, :) = 0.0_dp
2316 3196800 : pint_env%tv(:, 1, :) = 0.0_dp
2317 3196800 : pint_env%tf(:, 1, :) = 0.0_dp
2318 : END IF
2319 :
2320 : END DO
2321 : END DO
2322 :
2323 678416 : pint_env%uv = pint_env%uv_new
2324 2421536 : pint_env%tv = pint_env%tv_new
2325 3380 : IF (tol <= pint_env%v_tol) EXIT
2326 : ! Exempt centroid from thermostat for CMD
2327 3760 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2328 35520 : pint_env%tx(:, 1, :) = 0.0_dp
2329 35520 : pint_env%tv(:, 1, :) = 0.0_dp
2330 35520 : pint_env%tf(:, 1, :) = 0.0_dp
2331 : END IF
2332 : END DO
2333 :
2334 : ! Apply centroid constraints (RATTLE)
2335 616 : IF (pint_env%simpar%constraint) THEN
2336 16 : IF (pint_env%logger%para_env%is_source()) THEN
2337 : ! Reset particle r, due to force calc:
2338 32 : DO i = 1, nparticle
2339 104 : DO j = 1, 3
2340 72 : vel(j, i) = pint_env%uv(1, j + (i - 1)*3)
2341 96 : particle_set(i)%r(j) = pint_env%ux(1, j + (i - 1)*3)
2342 : END DO
2343 : END DO
2344 :
2345 : ! Small time step for all small integrations steps
2346 : ! Big step for last RESPA
2347 8 : IF (iresp == pint_env%nrespa) THEN
2348 4 : dt_temp = dti
2349 : ELSE
2350 4 : dt_temp = dti*rn
2351 : END IF
2352 : CALL rattle_control(gci, local_molecules, molecule_set, &
2353 : molecule_kind_set, particle_set, &
2354 : vel, dt_temp, pint_env%simpar%shake_tol, &
2355 : pint_env%simpar%info_constraint, &
2356 : pint_env%simpar%lagrange_multipliers, &
2357 : pint_env%simpar%dump_lm, cell, &
2358 8 : mp_comm_self, local_particles)
2359 : END IF
2360 : ! Velocities of centroid were constrained by RATTLE
2361 : ! Broadcast updated velocities to other nodes
2362 16 : CALL pint_env%logger%para_env%bcast(vel)
2363 :
2364 64 : DO i = 1, nparticle
2365 208 : DO j = 1, 3
2366 192 : pint_env%uv(1, j + (i - 1)*3) = vel(j, i)
2367 : END DO
2368 : END DO
2369 : END IF
2370 :
2371 2048 : DO inos = 1, pint_env%nnos - 1
2372 : pint_env%tf(inos, :, :) = pint_env%tf(inos, :, :) &
2373 264200 : - pint_env%tv(inos, :, :)*pint_env%tv(inos + 1, :, :)
2374 : END DO
2375 :
2376 : ! Exempt centroid from thermostat for CMD
2377 616 : IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
2378 5920 : pint_env%tx(:, 1, :) = 0.0_dp
2379 5920 : pint_env%tv(:, 1, :) = 0.0_dp
2380 5920 : pint_env%tf(:, 1, :) = 0.0_dp
2381 : END IF
2382 :
2383 : CASE (thermostat_gle)
2384 4 : CALL pint_gle_step(pint_env)
2385 55300 : pint_env%uv = pint_env%uv_t
2386 : CASE DEFAULT
2387 3196 : pint_env%uv = pint_env%uv_t
2388 : END SELECT
2389 : END DO
2390 :
2391 : CASE (integrate_exact)
2392 : ! The Liouvillian splitting is as follows:
2393 : ! 1. Thermostat
2394 : ! 2. 0.5*physical integration
2395 : ! 3. Exact harmonic integration + apply constraints (SHAKE)
2396 : ! 4. 0.5*physical integration
2397 : ! 5. Thermostat + apply constraints (RATTLE)
2398 :
2399 : ! 1. Apply thermostats
2400 688 : SELECT CASE (pint_env%pimd_thermostat)
2401 : CASE (thermostat_pile)
2402 : CALL pint_pile_step(vold=pint_env%uv, &
2403 : vnew=pint_env%uv_t, &
2404 : p=pint_env%p, &
2405 : ndim=pint_env%ndim, &
2406 : first_mode=pint_env%first_propagated_mode, &
2407 : masses=pint_env%mass_fict, &
2408 312 : pile_therm=pint_env%pile_therm)
2409 : CASE (thermostat_piglet)
2410 : CALL pint_piglet_step(vold=pint_env%uv, &
2411 : vnew=pint_env%uv_t, &
2412 : first_mode=pint_env%first_propagated_mode, &
2413 : masses=pint_env%mass_fict, &
2414 10 : piglet_therm=pint_env%piglet_therm)
2415 : CASE (thermostat_qtb)
2416 : CALL pint_qtb_step(vold=pint_env%uv, &
2417 : vnew=pint_env%uv_t, &
2418 : p=pint_env%p, &
2419 : ndim=pint_env%ndim, &
2420 : masses=pint_env%mass_fict, &
2421 30 : qtb_therm=pint_env%qtb_therm)
2422 : CASE DEFAULT
2423 1456 : pint_env%uv_t = pint_env%uv
2424 : END SELECT
2425 :
2426 : ! 2. 1/2*Physical integration
2427 1542598 : pint_env%uv_t = pint_env%uv_t + dti2*pint_env%uf
2428 :
2429 : ! 3. Exact harmonic integration
2430 376 : IF (pint_env%first_propagated_mode == 1) THEN
2431 : ! The centroid is integrated via standard velocity-verlet
2432 : ! Commented out code is only there to show similarities to
2433 : ! Numeric integrator
2434 : pint_env%ux_t(1, :) = pint_env%ux(1, :) + &
2435 233710 : dti*pint_env%uv_t(1, :) !+ &
2436 : ! dti22*pint_env%uf_h(1, :)
2437 : !pint_env%uv_t(1, :) = pint_env%uv_t(1, :)+ &
2438 : ! dti2*pint_env%uf_h(1, :)
2439 : ELSE
2440 : ! set velocities to zero for fixed centroids
2441 0 : pint_env%ux_t(1, :) = pint_env%ux(1, :)
2442 0 : pint_env%uv_t(1, :) = 0.0_dp
2443 : END IF
2444 : ! Other modes are integrated exactly
2445 2352 : DO i = 2, pint_env%p
2446 : pint_env%ux_t(i, :) = pint_env%cosex(i)*pint_env%ux(i, :) &
2447 1077530 : + pint_env%iwsinex(i)*pint_env%uv_t(i, :)
2448 : pint_env%uv_t(i, :) = pint_env%cosex(i)*pint_env%uv_t(i, :) &
2449 1077906 : - pint_env%wsinex(i)*pint_env%ux(i, :)
2450 : END DO
2451 :
2452 : ! Apply constraints (SHAKE)
2453 376 : IF (pint_env%simpar%constraint) THEN
2454 : ! Beadwise constraints
2455 16 : IF (pint_env%beadwise_constraints) THEN
2456 8 : IF (pint_env%logger%para_env%is_source()) THEN
2457 : ! Transform positions and velocities to Cartesian coordinates:
2458 4 : CALL pint_u2x(pint_env, ux=pint_env%ux_t, x=pint_env%x)
2459 4 : CALL pint_u2x(pint_env, ux=pint_env%uv_t, x=pint_env%v)
2460 20 : DO ib = 1, nbeads
2461 64 : DO i = 1, nparticle
2462 208 : DO j = 1, 3
2463 144 : pos(j, i) = pint_env%x(ib, j + (i - 1)*3)
2464 192 : vel(j, i) = pint_env%v(ib, j + (i - 1)*3)
2465 : END DO
2466 : END DO
2467 : ! Possibly update the target values
2468 : CALL shake_update_targets(gci, local_molecules, molecule_set, &
2469 : molecule_kind_set, dti, &
2470 16 : f_env%force_env%root_section)
2471 : CALL shake_control(gci, local_molecules, molecule_set, &
2472 : molecule_kind_set, particle_set, &
2473 : pos, vel, dti, pint_env%simpar%shake_tol, &
2474 : pint_env%simpar%info_constraint, &
2475 : pint_env%simpar%lagrange_multipliers, &
2476 : pint_env%simpar%dump_lm, cell, &
2477 16 : mp_comm_self, local_particles)
2478 68 : DO i = 1, nparticle
2479 208 : DO j = 1, 3
2480 144 : pint_env%x(ib, j + (i - 1)*3) = pos(j, i)
2481 192 : pint_env%v(ib, j + (i - 1)*3) = vel(j, i)
2482 : END DO
2483 : END DO
2484 : END DO
2485 : ! Transform back to normal modes:
2486 4 : CALL pint_x2u(pint_env, ux=pint_env%ux_t, x=pint_env%x)
2487 4 : CALL pint_x2u(pint_env, ux=pint_env%uv_t, x=pint_env%v)
2488 : END IF
2489 : ! Broadcast positions and velocities to all nodes
2490 728 : CALL pint_env%logger%para_env%bcast(pint_env%ux_t)
2491 728 : CALL pint_env%logger%para_env%bcast(pint_env%uv_t)
2492 : ! Centroid constraints
2493 : ELSE
2494 8 : IF (pint_env%logger%para_env%is_source()) THEN
2495 : ! Transform positions and velocities to Cartesian coordinates:
2496 16 : DO i = 1, nparticle
2497 52 : DO j = 1, 3
2498 36 : pos(j, i) = pint_env%ux_t(1, j + (i - 1)*3)/factor
2499 48 : vel(j, i) = pint_env%uv_t(1, j + (i - 1)*3)/factor
2500 : END DO
2501 : END DO
2502 : ! Possibly update the target values
2503 : CALL shake_update_targets(gci, local_molecules, molecule_set, &
2504 : molecule_kind_set, dti, &
2505 4 : f_env%force_env%root_section)
2506 : CALL shake_control(gci, local_molecules, molecule_set, &
2507 : molecule_kind_set, particle_set, &
2508 : pos, vel, dti, pint_env%simpar%shake_tol, &
2509 : pint_env%simpar%info_constraint, &
2510 : pint_env%simpar%lagrange_multipliers, &
2511 : pint_env%simpar%dump_lm, cell, &
2512 4 : mp_comm_self, local_particles)
2513 : END IF
2514 : ! Broadcast positions and velocities to all nodes
2515 8 : CALL pint_env%logger%para_env%bcast(pos)
2516 8 : CALL pint_env%logger%para_env%bcast(vel)
2517 : ! Transform back to normal modes:
2518 32 : DO i = 1, nparticle
2519 104 : DO j = 1, 3
2520 72 : pint_env%ux_t(1, j + (i - 1)*3) = pos(j, i)*factor
2521 96 : pint_env%uv_t(1, j + (i - 1)*3) = vel(j, i)*factor
2522 : END DO
2523 : END DO
2524 : END IF
2525 : ! Positions and velocities were constrained by SHAKE
2526 : END IF
2527 : ! Update positions
2528 1542598 : pint_env%ux = pint_env%ux_t
2529 :
2530 : ! 4. 1/2*Physical integration
2531 1542598 : pint_env%uf = 0.0_dp
2532 376 : CALL pint_u2x(pint_env)
2533 376 : CALL pint_calc_f(pint_env)
2534 : ! perform helium step and add helium forces
2535 376 : IF (PRESENT(helium_env)) THEN
2536 22 : CALL helium_step(helium_env, pint_env)
2537 : !Update force of solute in pint_env
2538 22 : IF (pint_env%logger%para_env%is_source()) THEN
2539 1802 : pint_env%f(:, :) = pint_env%f(:, :) + helium_env(1)%helium%force_avrg(:, :)
2540 : END IF
2541 7186 : CALL pint_env%logger%para_env%bcast(pint_env%f)
2542 : END IF
2543 376 : CALL pint_f2uf(pint_env)
2544 : ! set the centroid forces to 0 if FIX_CENTROID_POS
2545 376 : IF (pint_env%first_propagated_mode == 2) THEN
2546 0 : pint_env%uf(1, :) = 0.0_dp
2547 : END IF
2548 1542598 : pint_env%uv_t = pint_env%uv_t + dti2*pint_env%uf
2549 :
2550 : ! 5. Apply thermostats
2551 688 : SELECT CASE (pint_env%pimd_thermostat)
2552 : CASE (thermostat_pile)
2553 : CALL pint_pile_step(vold=pint_env%uv_t, &
2554 : vnew=pint_env%uv, &
2555 : p=pint_env%p, &
2556 : ndim=pint_env%ndim, &
2557 : first_mode=pint_env%first_propagated_mode, &
2558 : masses=pint_env%mass_fict, &
2559 312 : pile_therm=pint_env%pile_therm)
2560 : CASE (thermostat_piglet)
2561 : CALL pint_piglet_step(vold=pint_env%uv_t, &
2562 : vnew=pint_env%uv, &
2563 : first_mode=pint_env%first_propagated_mode, &
2564 : masses=pint_env%mass_fict, &
2565 10 : piglet_therm=pint_env%piglet_therm)
2566 : CASE (thermostat_qtb)
2567 : CALL pint_qtb_step(vold=pint_env%uv_t, &
2568 : vnew=pint_env%uv, &
2569 : p=pint_env%p, &
2570 : ndim=pint_env%ndim, &
2571 : masses=pint_env%mass_fict, &
2572 30 : qtb_therm=pint_env%qtb_therm)
2573 : CASE DEFAULT
2574 1456 : pint_env%uv = pint_env%uv_t
2575 : END SELECT
2576 :
2577 : ! Apply constraints (RATTLE)
2578 1014 : IF (pint_env%simpar%constraint) THEN
2579 : ! Beadwise constraints
2580 16 : IF (pint_env%beadwise_constraints) THEN
2581 8 : IF (pint_env%logger%para_env%is_source()) THEN
2582 : ! Transform positions and velocities to Cartesian coordinates:
2583 : ! Reset particle r, due to force calc:
2584 4 : CALL pint_u2x(pint_env, ux=pint_env%ux, x=pint_env%x)
2585 4 : CALL pint_u2x(pint_env, ux=pint_env%uv, x=pint_env%v)
2586 20 : DO ib = 1, nbeads
2587 64 : DO i = 1, nparticle
2588 208 : DO j = 1, 3
2589 144 : particle_set(i)%r(j) = pint_env%x(ib, j + (i - 1)*3)
2590 192 : vel(j, i) = pint_env%v(ib, j + (i - 1)*3)
2591 : END DO
2592 : END DO
2593 : CALL rattle_control(gci, local_molecules, &
2594 : molecule_set, molecule_kind_set, &
2595 : particle_set, vel, dti, &
2596 : pint_env%simpar%shake_tol, &
2597 : pint_env%simpar%info_constraint, &
2598 : pint_env%simpar%lagrange_multipliers, &
2599 : pint_env%simpar%dump_lm, cell, &
2600 16 : mp_comm_self, local_particles)
2601 68 : DO i = 1, nparticle
2602 208 : DO j = 1, 3
2603 192 : pint_env%v(ib, j + (i - 1)*3) = vel(j, i)
2604 : END DO
2605 : END DO
2606 : END DO
2607 : ! Transform back to normal modes:
2608 4 : CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
2609 : END IF
2610 728 : CALL pint_env%logger%para_env%bcast(pint_env%uv)
2611 : ! Centroid constraints
2612 : ELSE
2613 8 : IF (pint_env%logger%para_env%is_source()) THEN
2614 : ! Transform positions and velocities to Cartesian coordinates:
2615 : ! Reset particle r, due to force calc:
2616 16 : DO i = 1, nparticle
2617 52 : DO j = 1, 3
2618 36 : vel(j, i) = pint_env%uv(1, j + (i - 1)*3)/factor
2619 48 : particle_set(i)%r(j) = pint_env%ux(1, j + (i - 1)*3)/factor
2620 : END DO
2621 : END DO
2622 : CALL rattle_control(gci, local_molecules, &
2623 : molecule_set, molecule_kind_set, &
2624 : particle_set, vel, dti, &
2625 : pint_env%simpar%shake_tol, &
2626 : pint_env%simpar%info_constraint, &
2627 : pint_env%simpar%lagrange_multipliers, &
2628 : pint_env%simpar%dump_lm, cell, &
2629 4 : mp_comm_self, local_particles)
2630 : END IF
2631 : ! Velocities of centroid were constrained by RATTLE
2632 : ! Broadcast updated velocities to other nodes
2633 8 : CALL pint_env%logger%para_env%bcast(vel)
2634 :
2635 : ! Transform back to normal modes:
2636 : ! Multiply with SQRT(n_beads) due to normal mode transformation
2637 32 : DO i = 1, nparticle
2638 104 : DO j = 1, 3
2639 96 : pint_env%uv(1, j + (i - 1)*3) = vel(j, i)*factor
2640 : END DO
2641 : END DO
2642 : END IF
2643 : END IF
2644 :
2645 : END SELECT
2646 :
2647 638 : IF (pint_env%simpar%constraint) THEN
2648 24 : DEALLOCATE (pos, vel)
2649 : END IF
2650 :
2651 : ! calculate the energy components
2652 638 : CALL pint_calc_energy(pint_env)
2653 638 : CALL pint_calc_total_action(pint_env)
2654 :
2655 : ! check that the number of PINT steps matches
2656 : ! the number of force evaluations done so far
2657 : !TODO make this check valid if we start from ITERATION != 0
2658 : ! CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id,&
2659 : ! f_env=f_env,new_error=new_error)
2660 : ! NULLIFY(logger)
2661 : ! logger => cp_error_get_logger(new_error)
2662 : ! IF(logger%iter_info%iteration(2)/=pint_env%iter+1)&
2663 : ! CPABORT("md & force_eval lost sychro")
2664 : ! CALL f_env_rm_defaults(f_env,new_error,ierr)
2665 :
2666 638 : time_stop = m_walltime()
2667 638 : pint_env%time_per_step = time_stop - time_start
2668 638 : CALL pint_write_step_info(pint_env)
2669 638 : CALL timestop(handle)
2670 :
2671 1276 : END SUBROUTINE pint_step
2672 :
2673 : ! ***************************************************************************
2674 : !> \brief Calculate the energy components (private wrapper function)
2675 : !> \param pint_env ...
2676 : !> \date 2011-01-07
2677 : !> \author Lukasz Walewski
2678 : ! **************************************************************************************************
2679 1392 : SUBROUTINE pint_calc_energy(pint_env)
2680 :
2681 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
2682 :
2683 : REAL(KIND=dp) :: e_h
2684 :
2685 696 : CALL pint_calc_e_kin_beads_u(pint_env)
2686 696 : CALL pint_calc_e_vir(pint_env)
2687 :
2688 696 : CALL pint_calc_uf_h(pint_env, e_h=e_h)
2689 696 : pint_env%e_pot_h = e_h
2690 :
2691 952 : SELECT CASE (pint_env%pimd_thermostat)
2692 : CASE (thermostat_nose)
2693 256 : CALL pint_calc_nh_energy(pint_env)
2694 : CASE (thermostat_gle)
2695 6 : CALL pint_calc_gle_energy(pint_env)
2696 : CASE (thermostat_pile)
2697 324 : CALL pint_calc_pile_energy(pint_env)
2698 : CASE (thermostat_qtb)
2699 36 : CALL pint_calc_qtb_energy(pint_env)
2700 : CASE (thermostat_piglet)
2701 696 : CALL pint_calc_piglet_energy(pint_env)
2702 : END SELECT
2703 :
2704 : pint_env%energy(e_kin_thermo_id) = &
2705 : (0.5_dp*REAL(pint_env%p, dp)*REAL(pint_env%ndim, dp)*pint_env%kT - &
2706 696 : pint_env%e_pot_h)*pint_env%propagator%temp_sim2phys
2707 :
2708 4992 : pint_env%energy(e_potential_id) = SUM(pint_env%e_pot_bead)
2709 :
2710 : pint_env%energy(e_conserved_id) = &
2711 : pint_env%energy(e_potential_id)*pint_env%propagator%physpotscale + &
2712 : pint_env%e_pot_h + &
2713 : pint_env%e_kin_beads + &
2714 : pint_env%e_pot_t + &
2715 : pint_env%e_kin_t + &
2716 696 : pint_env%e_gle + pint_env%e_pile + pint_env%e_piglet + pint_env%e_qtb
2717 :
2718 : pint_env%energy(e_potential_id) = &
2719 696 : pint_env%energy(e_potential_id)/REAL(pint_env%p, dp)
2720 :
2721 696 : END SUBROUTINE pint_calc_energy
2722 :
2723 : ! ***************************************************************************
2724 : !> \brief Calculate the harmonic force in the u basis
2725 : !> \param pint_env the path integral environment in which the harmonic
2726 : !> forces should be calculated
2727 : !> \param e_h ...
2728 : !> \par History
2729 : !> Added normal mode transformation [hforbert]
2730 : !> \author fawzi
2731 : ! **************************************************************************************************
2732 1446 : SUBROUTINE pint_calc_uf_h(pint_env, e_h)
2733 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
2734 : REAL(KIND=dp), INTENT(OUT) :: e_h
2735 :
2736 1446 : IF (pint_env%transform == transformation_stage) THEN
2737 : CALL staging_calc_uf_h(pint_env%staging_env, &
2738 : pint_env%mass_beads, &
2739 : pint_env%ux, &
2740 : pint_env%uf_h, &
2741 0 : pint_env%e_pot_h)
2742 : ELSE
2743 : CALL normalmode_calc_uf_h(pint_env%normalmode_env, &
2744 : pint_env%mass_beads, &
2745 : pint_env%ux, &
2746 : pint_env%uf_h, &
2747 1446 : pint_env%e_pot_h)
2748 : END IF
2749 1446 : e_h = pint_env%e_pot_h
2750 2571630 : pint_env%uf_h = pint_env%uf_h/pint_env%mass_fict
2751 1446 : END SUBROUTINE pint_calc_uf_h
2752 :
2753 : ! ***************************************************************************
2754 : !> \brief calculates the force (and energy) in each bead, returns the sum
2755 : !> of the potential energy
2756 : !> \param pint_env path integral environment on which you want to calculate
2757 : !> the forces
2758 : !> \param x positions at which you want to evaluate the forces
2759 : !> \param f the forces
2760 : !> \param e potential energy on each bead
2761 : !> \par History
2762 : !> 2009-06-15 moved helium calls out from here [lwalewski]
2763 : !> \author fawzi
2764 : ! **************************************************************************************************
2765 712 : SUBROUTINE pint_calc_f(pint_env, x, f, e)
2766 : TYPE(pint_env_type), INTENT(IN) :: pint_env
2767 : REAL(kind=dp), DIMENSION(:, :), INTENT(in), &
2768 : OPTIONAL, TARGET :: x
2769 : REAL(kind=dp), DIMENSION(:, :), INTENT(out), &
2770 : OPTIONAL, TARGET :: f
2771 : REAL(kind=dp), DIMENSION(:), INTENT(out), &
2772 : OPTIONAL, TARGET :: e
2773 :
2774 : INTEGER :: ib, idim
2775 712 : REAL(kind=dp), DIMENSION(:), POINTER :: my_e
2776 712 : REAL(kind=dp), DIMENSION(:, :), POINTER :: my_f, my_x
2777 :
2778 712 : my_x => pint_env%x
2779 0 : IF (PRESENT(x)) my_x => x
2780 712 : my_f => pint_env%f
2781 712 : IF (PRESENT(f)) my_f => f
2782 712 : my_e => pint_env%e_pot_bead
2783 712 : IF (PRESENT(e)) my_e => e
2784 338446 : DO idim = 1, pint_env%ndim
2785 2035630 : DO ib = 1, pint_env%p
2786 2034918 : pint_env%replicas%r(idim, ib) = my_x(ib, idim)
2787 : END DO
2788 : END DO
2789 712 : CALL rep_env_calc_e_f(pint_env%replicas, calc_f=.TRUE.)
2790 338446 : DO idim = 1, pint_env%ndim
2791 2035630 : DO ib = 1, pint_env%p
2792 : !ljw: is that fine ? - idim <-> ib
2793 2034918 : my_f(ib, idim) = pint_env%replicas%f(idim, ib)
2794 : END DO
2795 : END DO
2796 5152 : my_e = pint_env%replicas%f(SIZE(pint_env%replicas%f, 1), :)
2797 :
2798 712 : END SUBROUTINE pint_calc_f
2799 :
2800 : ! ***************************************************************************
2801 : !> \brief Calculate the kinetic energy of the beads (in the u variables)
2802 : !> \param pint_env ...
2803 : !> \param uv ...
2804 : !> \param e_k ...
2805 : !> \par History
2806 : !> Bug fix to give my_uv a default location if not given in call [hforbert]
2807 : !> \author fawzi
2808 : ! **************************************************************************************************
2809 770 : SUBROUTINE pint_calc_e_kin_beads_u(pint_env, uv, e_k)
2810 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
2811 : REAL(kind=dp), DIMENSION(:, :), INTENT(in), &
2812 : OPTIONAL, TARGET :: uv
2813 : REAL(kind=dp), INTENT(out), OPTIONAL :: e_k
2814 :
2815 : INTEGER :: ib, idim
2816 : REAL(kind=dp) :: res
2817 770 : REAL(kind=dp), DIMENSION(:, :), POINTER :: my_uv
2818 :
2819 770 : res = -1.0_dp
2820 770 : my_uv => pint_env%uv
2821 0 : IF (PRESENT(uv)) my_uv => uv
2822 770 : res = 0._dp
2823 403430 : DO idim = 1, pint_env%ndim
2824 2398262 : DO ib = 1, pint_env%p
2825 2397492 : res = res + pint_env%mass_fict(ib, idim)*my_uv(ib, idim)**2
2826 : END DO
2827 : END DO
2828 770 : res = res*0.5
2829 770 : IF (.NOT. PRESENT(uv)) pint_env%e_kin_beads = res
2830 770 : IF (PRESENT(e_k)) e_k = res
2831 770 : END SUBROUTINE pint_calc_e_kin_beads_u
2832 :
2833 : ! ***************************************************************************
2834 : !> \brief Calculate the virial estimator of the real (quantum) kinetic energy
2835 : !> \param pint_env ...
2836 : !> \param e_vir ...
2837 : !> \author hforbert
2838 : !> \note This subroutine modifies pint_env%energy(e_kin_virial_id) global
2839 : !> variable [lwalewski]
2840 : ! **************************************************************************************************
2841 770 : ELEMENTAL SUBROUTINE pint_calc_e_vir(pint_env, e_vir)
2842 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
2843 : REAL(kind=dp), INTENT(out), OPTIONAL :: e_vir
2844 :
2845 : INTEGER :: ib, idim
2846 : REAL(kind=dp) :: res, xcentroid
2847 :
2848 : res = -1.0_dp
2849 770 : res = 0._dp
2850 403430 : DO idim = 1, pint_env%ndim
2851 : ! calculate the centroid
2852 402660 : xcentroid = 0._dp
2853 2397492 : DO ib = 1, pint_env%p
2854 2397492 : xcentroid = xcentroid + pint_env%x(ib, idim)
2855 : END DO
2856 402660 : xcentroid = xcentroid/REAL(pint_env%p, dp)
2857 2398262 : DO ib = 1, pint_env%p
2858 2397492 : res = res + (pint_env%x(ib, idim) - xcentroid)*pint_env%f(ib, idim)
2859 : END DO
2860 : END DO
2861 : res = 0.5_dp*(REAL(pint_env%ndim, dp)* &
2862 770 : (pint_env%kT*pint_env%propagator%temp_sim2phys) - res/REAL(pint_env%p, dp))
2863 770 : pint_env%energy(e_kin_virial_id) = res
2864 770 : IF (PRESENT(e_vir)) e_vir = res
2865 770 : END SUBROUTINE pint_calc_e_vir
2866 :
2867 : ! ***************************************************************************
2868 : !> \brief calculates the energy (potential and kinetic) of the Nose-Hoover
2869 : !> chain thermostats
2870 : !> \param pint_env the path integral environment
2871 : !> \author fawzi
2872 : ! **************************************************************************************************
2873 292 : ELEMENTAL SUBROUTINE pint_calc_nh_energy(pint_env)
2874 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
2875 :
2876 : INTEGER :: ib, idim, inos
2877 : REAL(kind=dp) :: ekin, epot
2878 :
2879 292 : ekin = 0._dp
2880 39928 : DO idim = 1, pint_env%ndim
2881 131008 : DO ib = 1, pint_env%p
2882 407412 : DO inos = 1, pint_env%nnos
2883 367776 : ekin = ekin + pint_env%Q(ib)*pint_env%tv(inos, ib, idim)**2
2884 : END DO
2885 : END DO
2886 : END DO
2887 292 : pint_env%e_kin_t = 0.5_dp*ekin
2888 292 : epot = 0._dp
2889 39928 : DO idim = 1, pint_env%ndim
2890 131008 : DO ib = 1, pint_env%p
2891 407412 : DO inos = 1, pint_env%nnos
2892 367776 : epot = epot + pint_env%tx(inos, ib, idim)
2893 : END DO
2894 : END DO
2895 : END DO
2896 292 : pint_env%e_pot_t = pint_env%kT*epot
2897 292 : END SUBROUTINE pint_calc_nh_energy
2898 :
2899 : ! ***************************************************************************
2900 : !> \brief calculates the total link action of the PI system (excluding helium)
2901 : !> \param pint_env the path integral environment
2902 : !> \return ...
2903 : !> \author Felix Uhl
2904 : ! **************************************************************************************************
2905 696 : ELEMENTAL FUNCTION pint_calc_total_link_action(pint_env) RESULT(link_action)
2906 : TYPE(pint_env_type), INTENT(IN) :: pint_env
2907 : REAL(KIND=dp) :: link_action
2908 :
2909 : INTEGER :: iatom, ibead, idim, indx
2910 : REAL(KIND=dp) :: hb2m, tau, tmp_link_action
2911 : REAL(KIND=dp), DIMENSION(3) :: r
2912 :
2913 : !tau = 1/(k_B T p)
2914 696 : tau = pint_env%beta/REAL(pint_env%p, dp)
2915 :
2916 696 : link_action = 0.0_dp
2917 113226 : DO iatom = 1, pint_env%ndim/3
2918 : ! hbar / (2.0*m)
2919 112530 : hb2m = 1.0_dp/pint_env%mass((iatom - 1)*3 + 1)
2920 112530 : tmp_link_action = 0.0_dp
2921 565296 : DO ibead = 1, pint_env%p - 1
2922 1811064 : DO idim = 1, 3
2923 1358298 : indx = (iatom - 1)*3 + idim
2924 1811064 : r(idim) = pint_env%x(ibead, indx) - pint_env%x(ibead + 1, indx)
2925 : END DO
2926 565296 : tmp_link_action = tmp_link_action + (r(1)*r(1) + r(2)*r(2) + r(3)*r(3))
2927 : END DO
2928 450120 : DO idim = 1, 3
2929 337590 : indx = (iatom - 1)*3 + idim
2930 450120 : r(idim) = pint_env%x(pint_env%p, indx) - pint_env%x(1, indx)
2931 : END DO
2932 112530 : tmp_link_action = tmp_link_action + (r(1)*r(1) + r(2)*r(2) + r(3)*r(3))
2933 113226 : link_action = link_action + tmp_link_action/hb2m
2934 : END DO
2935 :
2936 696 : link_action = link_action/(2.0_dp*tau)
2937 :
2938 696 : END FUNCTION pint_calc_total_link_action
2939 :
2940 : ! ***************************************************************************
2941 : !> \brief calculates the potential action of the PI system (excluding helium)
2942 : !> \param pint_env the path integral environment
2943 : !> \return ...
2944 : !> \author Felix Uhl
2945 : ! **************************************************************************************************
2946 696 : ELEMENTAL FUNCTION pint_calc_total_pot_action(pint_env) RESULT(pot_action)
2947 : TYPE(pint_env_type), INTENT(IN) :: pint_env
2948 : REAL(KIND=dp) :: pot_action
2949 :
2950 : REAL(KIND=dp) :: tau
2951 :
2952 696 : tau = pint_env%beta/REAL(pint_env%p, dp)
2953 4992 : pot_action = tau*SUM(pint_env%e_pot_bead)
2954 :
2955 696 : END FUNCTION pint_calc_total_pot_action
2956 :
2957 : ! ***************************************************************************
2958 : !> \brief calculates the total action of the PI system (excluding helium)
2959 : !> \param pint_env the path integral environment
2960 : !> \author Felix Uhl
2961 : ! **************************************************************************************************
2962 696 : ELEMENTAL SUBROUTINE pint_calc_total_action(pint_env)
2963 : TYPE(pint_env_type), INTENT(INOUT) :: pint_env
2964 :
2965 696 : pint_env%pot_action = pint_calc_total_pot_action(pint_env)
2966 696 : pint_env%link_action = pint_calc_total_link_action(pint_env)
2967 :
2968 696 : END SUBROUTINE pint_calc_total_action
2969 :
2970 2 : END MODULE pint_methods
|