Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Utilities for thermostats
10 : !> \author teo [tlaino] - University of Zurich - 10.2007
11 : ! **************************************************************************************************
12 : MODULE thermostat_utils
13 : USE atomic_kind_types, ONLY: atomic_kind_type,&
14 : get_atomic_kind
15 : USE cell_types, ONLY: cell_type
16 : USE cp_log_handling, ONLY: cp_get_default_logger,&
17 : cp_logger_get_default_io_unit,&
18 : cp_logger_type,&
19 : cp_to_string
20 : USE cp_output_handling, ONLY: cp_p_file,&
21 : cp_print_key_finished_output,&
22 : cp_print_key_should_output,&
23 : cp_print_key_unit_nr
24 : USE cp_units, ONLY: cp_unit_from_cp2k
25 : USE distribution_1d_types, ONLY: distribution_1d_type
26 : USE extended_system_types, ONLY: lnhc_parameters_type,&
27 : map_info_type,&
28 : npt_info_type
29 : USE input_constants, ONLY: &
30 : do_constr_atomic, do_constr_molec, do_region_defined, do_region_global, do_region_massive, &
31 : do_region_molecule, do_thermo_al, do_thermo_communication, do_thermo_csvr, do_thermo_gle, &
32 : do_thermo_no_communication, do_thermo_nose, isokin_ensemble, langevin_ensemble, &
33 : npe_f_ensemble, npe_i_ensemble, nph_uniaxial_damped_ensemble, nph_uniaxial_ensemble, &
34 : npt_f_ensemble, npt_i_ensemble, npt_ia_ensemble, nve_ensemble, nvt_adiabatic_ensemble, &
35 : nvt_ensemble, reftraj_ensemble
36 : USE input_section_types, ONLY: section_vals_get,&
37 : section_vals_get_subs_vals,&
38 : section_vals_type,&
39 : section_vals_val_get
40 : USE kinds, ONLY: default_string_length,&
41 : dp
42 : USE machine, ONLY: m_flush
43 : USE message_passing, ONLY: mp_comm_type,&
44 : mp_para_env_type
45 : USE molecule_kind_types, ONLY: get_molecule_kind,&
46 : get_molecule_kind_set,&
47 : molecule_kind_type,&
48 : write_colvar_constraint,&
49 : write_fixd_constraint,&
50 : write_g3x3_constraint,&
51 : write_g4x6_constraint
52 : USE molecule_list_types, ONLY: molecule_list_type
53 : USE molecule_types, ONLY: get_molecule,&
54 : global_constraint_type,&
55 : molecule_type
56 : USE motion_utils, ONLY: rot_ana
57 : USE particle_list_types, ONLY: particle_list_type
58 : USE particle_types, ONLY: particle_type
59 : USE physcon, ONLY: femtoseconds
60 : USE qmmm_types, ONLY: qmmm_env_type
61 : USE shell_potential_types, ONLY: shell_kind_type
62 : USE simpar_types, ONLY: simpar_type
63 : USE thermostat_types, ONLY: thermostat_info_type,&
64 : thermostat_type,&
65 : thermostats_type
66 : #include "../../base/base_uses.f90"
67 :
68 : IMPLICIT NONE
69 :
70 : PRIVATE
71 : PUBLIC :: compute_degrees_of_freedom, &
72 : compute_nfree, &
73 : setup_thermostat_info, &
74 : setup_adiabatic_thermostat_info, &
75 : ke_region_baro, &
76 : ke_region_particles, &
77 : ke_region_shells, &
78 : vel_rescale_baro, &
79 : vel_rescale_particles, &
80 : vel_rescale_shells, &
81 : get_thermostat_energies, &
82 : get_nhc_energies, &
83 : get_kin_energies, &
84 : communication_thermo_low2, &
85 : print_thermostats_status, &
86 : momentum_region_particles
87 :
88 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'thermostat_utils'
89 :
90 : CONTAINS
91 :
92 : ! **************************************************************************************************
93 : !> \brief ...
94 : !> \param cell ...
95 : !> \param simpar ...
96 : !> \param molecule_kind_set ...
97 : !> \param print_section ...
98 : !> \param particles ...
99 : !> \param gci ...
100 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
101 : ! **************************************************************************************************
102 0 : SUBROUTINE compute_nfree(cell, simpar, molecule_kind_set, &
103 : print_section, particles, gci)
104 :
105 : TYPE(cell_type), POINTER :: cell
106 : TYPE(simpar_type), POINTER :: simpar
107 : TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
108 : TYPE(section_vals_type), POINTER :: print_section
109 : TYPE(particle_list_type), POINTER :: particles
110 : TYPE(global_constraint_type), POINTER :: gci
111 :
112 : INTEGER :: natom, nconstraint_ext, nconstraint_int, &
113 : nrestraints_int, rot_dof, &
114 : roto_trasl_dof
115 :
116 : ! Retrieve information on number of atoms, constraints (external and internal)
117 :
118 : CALL get_molecule_kind_set(molecule_kind_set=molecule_kind_set, &
119 0 : natom=natom, nconstraint=nconstraint_int, nrestraints=nrestraints_int)
120 :
121 : ! Compute degrees of freedom
122 : CALL rot_ana(particles%els, dof=roto_trasl_dof, rot_dof=rot_dof, &
123 : print_section=print_section, keep_rotations=.FALSE., &
124 0 : mass_weighted=.TRUE., natoms=natom)
125 :
126 0 : roto_trasl_dof = roto_trasl_dof - MIN(SUM(cell%perd(1:3)), rot_dof)
127 :
128 : ! Saving this value of simpar preliminar to the real count of constraints..
129 0 : simpar%nfree_rot_transl = roto_trasl_dof
130 :
131 : ! compute the total number of degrees of freedom for temperature
132 0 : nconstraint_ext = gci%ntot - gci%nrestraint
133 0 : simpar%nfree = 3*natom - nconstraint_int - nconstraint_ext - roto_trasl_dof
134 :
135 0 : END SUBROUTINE compute_nfree
136 :
137 : ! **************************************************************************************************
138 : !> \brief ...
139 : !> \param thermostats ...
140 : !> \param cell ...
141 : !> \param simpar ...
142 : !> \param molecule_kind_set ...
143 : !> \param local_molecules ...
144 : !> \param molecules ...
145 : !> \param particles ...
146 : !> \param print_section ...
147 : !> \param region_sections ...
148 : !> \param gci ...
149 : !> \param region ...
150 : !> \param qmmm_env ...
151 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
152 : ! **************************************************************************************************
153 3538 : SUBROUTINE compute_degrees_of_freedom(thermostats, cell, simpar, molecule_kind_set, &
154 : local_molecules, molecules, particles, print_section, region_sections, gci, &
155 : region, qmmm_env)
156 :
157 : TYPE(thermostats_type), POINTER :: thermostats
158 : TYPE(cell_type), POINTER :: cell
159 : TYPE(simpar_type), POINTER :: simpar
160 : TYPE(molecule_kind_type), DIMENSION(:), POINTER :: molecule_kind_set
161 : TYPE(distribution_1d_type), POINTER :: local_molecules
162 : TYPE(molecule_list_type), POINTER :: molecules
163 : TYPE(particle_list_type), POINTER :: particles
164 : TYPE(section_vals_type), POINTER :: print_section, region_sections
165 : TYPE(global_constraint_type), POINTER :: gci
166 : INTEGER, INTENT(IN) :: region
167 : TYPE(qmmm_env_type), POINTER :: qmmm_env
168 :
169 : INTEGER :: ic, iw, natom, nconstraint_ext, &
170 : nconstraint_int, nrestraints_int, &
171 : rot_dof, roto_trasl_dof
172 : TYPE(cp_logger_type), POINTER :: logger
173 :
174 1769 : CPASSERT(ASSOCIATED(gci))
175 :
176 : ! Retrieve information on number of atoms, constraints (external and internal)
177 : CALL get_molecule_kind_set(molecule_kind_set=molecule_kind_set, &
178 1769 : natom=natom, nconstraint=nconstraint_int, nrestraints=nrestraints_int)
179 :
180 : ! Compute degrees of freedom
181 : CALL rot_ana(particles%els, dof=roto_trasl_dof, rot_dof=rot_dof, &
182 : print_section=print_section, keep_rotations=.FALSE., &
183 1769 : mass_weighted=.TRUE., natoms=natom)
184 :
185 7076 : roto_trasl_dof = roto_trasl_dof - MIN(SUM(cell%perd(1:3)), rot_dof)
186 :
187 : ! Collect info about thermostats
188 : CALL setup_thermostat_info(thermostats%thermostat_info_part, molecule_kind_set, &
189 : local_molecules, molecules, particles, region, simpar%ensemble, roto_trasl_dof, &
190 1769 : region_sections=region_sections, qmmm_env=qmmm_env)
191 :
192 : ! Saving this value of simpar preliminar to the real count of constraints..
193 1769 : simpar%nfree_rot_transl = roto_trasl_dof
194 :
195 : ! compute the total number of degrees of freedom for temperature
196 1769 : nconstraint_ext = gci%ntot - gci%nrestraint
197 1769 : simpar%nfree = 3*natom - nconstraint_int - nconstraint_ext - roto_trasl_dof
198 :
199 1769 : logger => cp_get_default_logger()
200 : iw = cp_print_key_unit_nr(logger, print_section, "PROGRAM_RUN_INFO", &
201 1769 : extension=".log")
202 1769 : IF (iw > 0) THEN
203 : WRITE (iw, '(/,T2,A)') &
204 815 : 'DOF| Calculation of degrees of freedom'
205 : WRITE (iw, '(T2,A,T71,I10)') &
206 815 : 'DOF| Number of atoms', natom, &
207 815 : 'DOF| Number of intramolecular constraints', nconstraint_int, &
208 815 : 'DOF| Number of intermolecular constraints', nconstraint_ext, &
209 815 : 'DOF| Invariants (translations + rotations)', roto_trasl_dof, &
210 1630 : 'DOF| Degrees of freedom', simpar%nfree
211 : WRITE (iw, '(/,T2,A)') &
212 815 : 'DOF| Restraints information'
213 : WRITE (iw, '(T2,A,T71,I10)') &
214 815 : 'DOF| Number of intramolecular restraints', nrestraints_int, &
215 1630 : 'DOF| Number of intermolecular restraints', gci%nrestraint
216 815 : IF (ASSOCIATED(gci%colv_list)) THEN
217 41 : DO ic = 1, SIZE(gci%colv_list)
218 41 : CALL write_colvar_constraint(gci%colv_list(ic), ic, iw)
219 : END DO
220 : END IF
221 815 : IF (ASSOCIATED(gci%fixd_list)) THEN
222 3 : DO ic = 1, SIZE(gci%fixd_list)
223 3 : CALL write_fixd_constraint(gci%fixd_list(ic), ic, iw)
224 : END DO
225 : END IF
226 815 : IF (ASSOCIATED(gci%g3x3_list)) THEN
227 4 : DO ic = 1, SIZE(gci%g3x3_list)
228 4 : CALL write_g3x3_constraint(gci%g3x3_list(ic), ic, iw)
229 : END DO
230 : END IF
231 815 : IF (ASSOCIATED(gci%g4x6_list)) THEN
232 4 : DO ic = 1, SIZE(gci%g4x6_list)
233 4 : CALL write_g4x6_constraint(gci%g4x6_list(ic), ic, iw)
234 : END DO
235 : END IF
236 : END IF
237 : CALL cp_print_key_finished_output(iw, logger, print_section, &
238 1769 : "PROGRAM_RUN_INFO")
239 :
240 1769 : END SUBROUTINE compute_degrees_of_freedom
241 :
242 : ! **************************************************************************************************
243 : !> \brief ...
244 : !> \param thermostat_info ...
245 : !> \param molecule_kind_set ...
246 : !> \param local_molecules ...
247 : !> \param molecules ...
248 : !> \param particles ...
249 : !> \param region ...
250 : !> \param ensemble ...
251 : !> \param nfree ...
252 : !> \param shell ...
253 : !> \param region_sections ...
254 : !> \param qmmm_env ...
255 : !> \author 10.2011 CJM - PNNL
256 : ! **************************************************************************************************
257 0 : SUBROUTINE setup_adiabatic_thermostat_info(thermostat_info, molecule_kind_set, local_molecules, &
258 : molecules, particles, region, ensemble, nfree, shell, region_sections, qmmm_env)
259 : TYPE(thermostat_info_type), POINTER :: thermostat_info
260 : TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
261 : TYPE(distribution_1d_type), POINTER :: local_molecules
262 : TYPE(molecule_list_type), POINTER :: molecules
263 : TYPE(particle_list_type), POINTER :: particles
264 : INTEGER, INTENT(IN) :: region, ensemble
265 : INTEGER, INTENT(INOUT), OPTIONAL :: nfree
266 : LOGICAL, INTENT(IN), OPTIONAL :: shell
267 : TYPE(section_vals_type), POINTER :: region_sections
268 : TYPE(qmmm_env_type), POINTER :: qmmm_env
269 :
270 : INTEGER :: dis_type, first_atom, i, ikind, imol, imol_global, ipart, itherm, katom, &
271 : last_atom, natom, natom_local, nkind, nmol_local, nmol_per_kind, nmolecule, nshell, &
272 : number, stat, sum_of_thermostats
273 0 : INTEGER, POINTER :: molecule_list(:), thermolist(:)
274 : LOGICAL :: check, do_shell, nointer, on_therm
275 : TYPE(molecule_kind_type), POINTER :: molecule_kind
276 0 : TYPE(molecule_type), POINTER :: molecule, molecule_set(:)
277 :
278 0 : NULLIFY (molecule_kind, molecule, thermostat_info%map_loc_thermo_gen, thermolist)
279 0 : nkind = SIZE(molecule_kind_set)
280 0 : do_shell = .FALSE.
281 0 : IF (PRESENT(shell)) do_shell = shell
282 : ! Counting the global number of thermostats
283 0 : sum_of_thermostats = 0
284 : ! Variable to denote independent thermostats (no communication necessary)
285 0 : nointer = .TRUE.
286 0 : check = .TRUE.
287 0 : number = 0
288 0 : dis_type = do_thermo_no_communication
289 :
290 : CALL get_adiabatic_region_info(region_sections, sum_of_thermostats, &
291 : thermolist=thermolist, &
292 : molecule_kind_set=molecule_kind_set, &
293 0 : molecules=molecules, particles=particles, qmmm_env=qmmm_env)
294 :
295 : ! map_loc_thermo_gen=>thermostat_info%map_loc_thermo_gen
296 0 : molecule_set => molecules%els
297 0 : SELECT CASE (ensemble)
298 : CASE DEFAULT
299 0 : CPABORT('Unknown ensemble')
300 : CASE (nvt_adiabatic_ensemble)
301 0 : SELECT CASE (region)
302 : CASE (do_region_global)
303 : ! Global Thermostat
304 0 : nointer = .FALSE.
305 0 : sum_of_thermostats = 1
306 : CASE (do_region_molecule)
307 : ! Molecular Thermostat
308 : itherm = 0
309 0 : DO ikind = 1, nkind
310 0 : molecule_kind => molecule_kind_set(ikind)
311 0 : nmol_per_kind = local_molecules%n_el(ikind)
312 : CALL get_molecule_kind(molecule_kind, natom=natom, &
313 0 : molecule_list=molecule_list)
314 : ! use thermolist ( ipart ) to get global indexing correct
315 0 : DO imol_global = 1, SIZE(molecule_list)
316 0 : molecule => molecule_set(molecule_list(imol_global))
317 : CALL get_molecule(molecule, first_atom=first_atom, &
318 0 : last_atom=last_atom)
319 0 : on_therm = .TRUE.
320 0 : DO katom = first_atom, last_atom
321 0 : IF (thermolist(katom) == HUGE(0)) THEN
322 : on_therm = .FALSE.
323 : EXIT
324 : END IF
325 : END DO
326 0 : IF (on_therm) THEN
327 0 : itherm = itherm + 1
328 0 : DO katom = first_atom, last_atom
329 0 : thermolist(katom) = itherm
330 : END DO
331 : END IF
332 : END DO
333 : END DO
334 0 : DO i = 1, nkind
335 0 : molecule_kind => molecule_kind_set(i)
336 0 : CALL get_molecule_kind(molecule_kind, nmolecule=nmolecule, nshell=nshell)
337 0 : IF ((do_shell) .AND. (nshell == 0)) nmolecule = 0
338 0 : sum_of_thermostats = sum_of_thermostats + nmolecule
339 : END DO
340 : ! If we have ONE kind and ONE molecule, then effectively we have a GLOBAL thermostat
341 : ! and the degrees of freedom will be computed correctly for this special case
342 0 : IF ((nmolecule == 1) .AND. (nkind == 1)) nointer = .FALSE.
343 : CASE (do_region_massive)
344 : ! Massive Thermostat
345 0 : DO i = 1, nkind
346 0 : molecule_kind => molecule_kind_set(i)
347 : CALL get_molecule_kind(molecule_kind, nmolecule=nmolecule, &
348 0 : natom=natom, nshell=nshell)
349 0 : IF (do_shell) natom = nshell
350 0 : sum_of_thermostats = sum_of_thermostats + 3*natom*nmolecule
351 : END DO
352 : END SELECT
353 :
354 0 : natom_local = 0
355 0 : DO ikind = 1, SIZE(molecule_kind_set)
356 0 : nmol_per_kind = local_molecules%n_el(ikind)
357 0 : DO imol = 1, nmol_per_kind
358 0 : i = local_molecules%list(ikind)%array(imol)
359 0 : molecule => molecule_set(i)
360 0 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
361 0 : DO ipart = first_atom, last_atom
362 0 : natom_local = natom_local + 1
363 : END DO
364 : END DO
365 : END DO
366 :
367 : ! Now map the local atoms with the corresponding thermostat
368 0 : ALLOCATE (thermostat_info%map_loc_thermo_gen(natom_local), stat=stat)
369 0 : thermostat_info%map_loc_thermo_gen = HUGE(0)
370 0 : CPASSERT(stat == 0)
371 0 : natom_local = 0
372 0 : DO ikind = 1, SIZE(molecule_kind_set)
373 0 : nmol_per_kind = local_molecules%n_el(ikind)
374 0 : DO imol = 1, nmol_per_kind
375 0 : i = local_molecules%list(ikind)%array(imol)
376 0 : molecule => molecule_set(i)
377 0 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
378 0 : DO ipart = first_atom, last_atom
379 0 : natom_local = natom_local + 1
380 : ! only map the correct region to the thermostat
381 0 : IF (thermolist(ipart) /= HUGE(0)) &
382 0 : thermostat_info%map_loc_thermo_gen(natom_local) = thermolist(ipart)
383 : END DO
384 : END DO
385 : END DO
386 : ! Here we decide which parallel algorithm to use.
387 : ! if there are only massive and molecule type thermostats we can use
388 : ! a local scheme, in cases involving any combination with a
389 : ! global thermostat we assume a coupling of degrees of freedom
390 : ! from different processors
391 0 : IF (nointer) THEN
392 : ! Distributed thermostats, no interaction
393 0 : dis_type = do_thermo_no_communication
394 : ! we only count thermostats on this processor
395 : number = 0
396 0 : DO ikind = 1, nkind
397 0 : nmol_local = local_molecules%n_el(ikind)
398 0 : molecule_kind => molecule_kind_set(ikind)
399 0 : CALL get_molecule_kind(molecule_kind, natom=natom, nshell=nshell)
400 0 : IF (do_shell) THEN
401 0 : natom = nshell
402 0 : IF (nshell == 0) nmol_local = 0
403 : END IF
404 0 : IF (region == do_region_molecule) THEN
405 0 : number = number + nmol_local
406 0 : ELSE IF (region == do_region_massive) THEN
407 0 : number = number + 3*nmol_local*natom
408 : ELSE
409 0 : CPABORT('Invalid region setup')
410 : END IF
411 : END DO
412 : ELSE
413 : ! REPlicated thermostats, INTERacting via communication
414 0 : dis_type = do_thermo_communication
415 0 : IF ((region == do_region_global) .OR. (region == do_region_molecule)) number = 1
416 : END IF
417 :
418 0 : IF (PRESENT(nfree)) THEN
419 : ! re-initializing simpar%nfree to zero because of multiple thermostats in the adiabatic sampling
420 0 : nfree = 0
421 : END IF
422 : END SELECT
423 :
424 : ! Saving information about thermostats
425 0 : thermostat_info%sum_of_thermostats = sum_of_thermostats
426 0 : thermostat_info%number_of_thermostats = number
427 0 : thermostat_info%dis_type = dis_type
428 :
429 0 : DEALLOCATE (thermolist)
430 :
431 0 : END SUBROUTINE setup_adiabatic_thermostat_info
432 :
433 : ! **************************************************************************************************
434 : !> \brief ...
435 : !> \param region_sections ...
436 : !> \param sum_of_thermostats ...
437 : !> \param thermolist ...
438 : !> \param molecule_kind_set ...
439 : !> \param molecules ...
440 : !> \param particles ...
441 : !> \param qmmm_env ...
442 : !> \author 10.2011 CJM -PNNL
443 : ! **************************************************************************************************
444 0 : SUBROUTINE get_adiabatic_region_info(region_sections, sum_of_thermostats, &
445 : thermolist, molecule_kind_set, molecules, particles, &
446 : qmmm_env)
447 : TYPE(section_vals_type), POINTER :: region_sections
448 : INTEGER, INTENT(INOUT), OPTIONAL :: sum_of_thermostats
449 : INTEGER, DIMENSION(:), POINTER :: thermolist(:)
450 : TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
451 : TYPE(molecule_list_type), POINTER :: molecules
452 : TYPE(particle_list_type), POINTER :: particles
453 : TYPE(qmmm_env_type), POINTER :: qmmm_env
454 :
455 : CHARACTER(LEN=default_string_length), &
456 0 : DIMENSION(:), POINTER :: tmpstringlist
457 : INTEGER :: first_atom, i, ig, ikind, ilist, imol, &
458 : ipart, itherm, jg, last_atom, &
459 : mregions, n_rep, nregions, output_unit
460 0 : INTEGER, DIMENSION(:), POINTER :: tmplist
461 : TYPE(cp_logger_type), POINTER :: logger
462 : TYPE(molecule_kind_type), POINTER :: molecule_kind
463 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
464 : TYPE(molecule_type), POINTER :: molecule
465 :
466 0 : NULLIFY (tmplist, tmpstringlist, thermolist, molecule_kind, molecule, molecule_set)
467 0 : NULLIFY (logger)
468 0 : logger => cp_get_default_logger()
469 0 : output_unit = cp_logger_get_default_io_unit(logger)
470 : ! CPASSERT(.NOT.(ASSOCIATED(map_loc_thermo_gen)))
471 0 : CALL section_vals_get(region_sections, n_repetition=nregions)
472 0 : ALLOCATE (thermolist(particles%n_els))
473 0 : thermolist = HUGE(0)
474 0 : molecule_set => molecules%els
475 0 : mregions = nregions
476 0 : itherm = 0
477 0 : DO ig = 1, mregions
478 0 : CALL section_vals_val_get(region_sections, "LIST", i_rep_section=ig, n_rep_val=n_rep)
479 0 : DO jg = 1, n_rep
480 0 : CALL section_vals_val_get(region_sections, "LIST", i_rep_section=ig, i_rep_val=jg, i_vals=tmplist)
481 0 : DO i = 1, SIZE(tmplist)
482 0 : ipart = tmplist(i)
483 0 : CPASSERT(((ipart > 0) .AND. (ipart <= particles%n_els)))
484 0 : IF (thermolist(ipart) == HUGE(0)) THEN
485 0 : itherm = itherm + 1
486 0 : thermolist(ipart) = itherm
487 : ELSE
488 0 : CPABORT("")
489 : END IF
490 : END DO
491 : END DO
492 0 : CALL section_vals_val_get(region_sections, "MOLNAME", i_rep_section=ig, n_rep_val=n_rep)
493 0 : DO jg = 1, n_rep
494 0 : CALL section_vals_val_get(region_sections, "MOLNAME", i_rep_section=ig, i_rep_val=jg, c_vals=tmpstringlist)
495 0 : DO ilist = 1, SIZE(tmpstringlist)
496 0 : DO ikind = 1, SIZE(molecule_kind_set)
497 0 : molecule_kind => molecule_kind_set(ikind)
498 0 : IF (molecule_kind%name == tmpstringlist(ilist)) THEN
499 0 : DO imol = 1, SIZE(molecule_kind%molecule_list)
500 0 : molecule => molecule_set(molecule_kind%molecule_list(imol))
501 0 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
502 0 : DO ipart = first_atom, last_atom
503 0 : IF (thermolist(ipart) == HUGE(0)) THEN
504 0 : itherm = itherm + 1
505 0 : thermolist(ipart) = itherm
506 : ELSE
507 0 : CPABORT("")
508 : END IF
509 : END DO
510 : END DO
511 : END IF
512 : END DO
513 : END DO
514 : END DO
515 : CALL setup_thermostat_subsys(region_sections, qmmm_env, thermolist, molecule_set, &
516 0 : subsys_qm=.FALSE., ig=ig, sum_of_thermostats=sum_of_thermostats, nregions=nregions)
517 : CALL setup_thermostat_subsys(region_sections, qmmm_env, thermolist, molecule_set, &
518 0 : subsys_qm=.TRUE., ig=ig, sum_of_thermostats=sum_of_thermostats, nregions=nregions)
519 : END DO
520 :
521 0 : CPASSERT(.NOT. ALL(thermolist == HUGE(0)))
522 :
523 : ! natom_local = 0
524 : ! DO ikind = 1, SIZE(molecule_kind_set)
525 : ! nmol_per_kind = local_molecules%n_el(ikind)
526 : ! DO imol = 1, nmol_per_kind
527 : ! i = local_molecules%list(ikind)%array(imol)
528 : ! molecule => molecule_set(i)
529 : ! CALL get_molecule ( molecule, first_atom = first_atom, last_atom = last_atom )
530 : ! DO ipart = first_atom, last_atom
531 : ! natom_local = natom_local + 1
532 : ! END DO
533 : ! END DO
534 : ! END DO
535 :
536 : ! Now map the local atoms with the corresponding thermostat
537 : ! ALLOCATE(map_loc_thermo_gen(natom_local),stat=stat)
538 : ! map_loc_thermo_gen = HUGE ( 0 )
539 : ! CPPostcondition(stat==0,cp_failure_level,routineP,failure)
540 : ! natom_local = 0
541 : ! DO ikind = 1, SIZE(molecule_kind_set)
542 : ! nmol_per_kind = local_molecules%n_el(ikind)
543 : ! DO imol = 1, nmol_per_kind
544 : ! i = local_molecules%list(ikind)%array(imol)
545 : ! molecule => molecule_set(i)
546 : ! CALL get_molecule ( molecule, first_atom = first_atom, last_atom = last_atom )
547 : ! DO ipart = first_atom, last_atom
548 : ! natom_local = natom_local + 1
549 : ! only map the correct region to the thermostat
550 : ! IF ( thermolist (ipart ) /= HUGE ( 0 ) ) &
551 : ! map_loc_thermo_gen(natom_local) = thermolist(ipart)
552 : ! END DO
553 : ! END DO
554 : ! END DO
555 :
556 : ! DEALLOCATE(thermolist, stat=stat)
557 : ! CPPostcondition(stat==0,cp_failure_level,routineP,failure)
558 0 : END SUBROUTINE get_adiabatic_region_info
559 : ! **************************************************************************************************
560 : !> \brief ...
561 : !> \param thermostat_info ...
562 : !> \param molecule_kind_set ...
563 : !> \param local_molecules ...
564 : !> \param molecules ...
565 : !> \param particles ...
566 : !> \param region ...
567 : !> \param ensemble ...
568 : !> \param nfree ...
569 : !> \param shell ...
570 : !> \param region_sections ...
571 : !> \param qmmm_env ...
572 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
573 : ! **************************************************************************************************
574 1815 : SUBROUTINE setup_thermostat_info(thermostat_info, molecule_kind_set, local_molecules, &
575 : molecules, particles, region, ensemble, nfree, shell, region_sections, qmmm_env)
576 : TYPE(thermostat_info_type), POINTER :: thermostat_info
577 : TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
578 : TYPE(distribution_1d_type), POINTER :: local_molecules
579 : TYPE(molecule_list_type), POINTER :: molecules
580 : TYPE(particle_list_type), POINTER :: particles
581 : INTEGER, INTENT(IN) :: region, ensemble
582 : INTEGER, INTENT(INOUT), OPTIONAL :: nfree
583 : LOGICAL, INTENT(IN), OPTIONAL :: shell
584 : TYPE(section_vals_type), POINTER :: region_sections
585 : TYPE(qmmm_env_type), POINTER :: qmmm_env
586 :
587 : INTEGER :: dis_type, i, ikind, natom, nkind, &
588 : nmol_local, nmolecule, nshell, number, &
589 : sum_of_thermostats
590 : LOGICAL :: check, do_shell, nointer
591 : TYPE(molecule_kind_type), POINTER :: molecule_kind
592 :
593 1815 : NULLIFY (molecule_kind)
594 1815 : nkind = SIZE(molecule_kind_set)
595 1815 : do_shell = .FALSE.
596 1815 : IF (PRESENT(shell)) do_shell = shell
597 : ! Counting the global number of thermostats
598 1815 : sum_of_thermostats = 0
599 : ! Variable to denote independent thermostats (no communication necessary)
600 1815 : nointer = .TRUE.
601 1815 : check = .TRUE.
602 1815 : number = 0
603 1815 : dis_type = do_thermo_no_communication
604 :
605 1815 : SELECT CASE (ensemble)
606 : CASE DEFAULT
607 0 : CPABORT('Unknown ensemble')
608 : CASE (isokin_ensemble, nph_uniaxial_ensemble, nph_uniaxial_damped_ensemble, &
609 : reftraj_ensemble, langevin_ensemble)
610 : ! Do Nothing
611 : CASE (nve_ensemble, nvt_ensemble, nvt_adiabatic_ensemble, npt_i_ensemble, &
612 : npt_f_ensemble, npe_i_ensemble, npe_f_ensemble, npt_ia_ensemble)
613 1727 : IF (ensemble == nve_ensemble) check = do_shell
614 2958 : IF (check) THEN
615 876 : SELECT CASE (region)
616 : CASE (do_region_global)
617 : ! Global Thermostat
618 288 : nointer = .FALSE.
619 288 : sum_of_thermostats = 1
620 : CASE (do_region_molecule)
621 : ! Molecular Thermostat
622 6052 : DO i = 1, nkind
623 5916 : molecule_kind => molecule_kind_set(i)
624 5916 : CALL get_molecule_kind(molecule_kind, nmolecule=nmolecule, nshell=nshell)
625 5916 : IF ((do_shell) .AND. (nshell == 0)) nmolecule = 0
626 11968 : sum_of_thermostats = sum_of_thermostats + nmolecule
627 : END DO
628 : ! If we have ONE kind and ONE molecule, then effectively we have a GLOBAL thermostat
629 : ! and the degrees of freedom will be computed correctly for this special case
630 136 : IF ((nmolecule == 1) .AND. (nkind == 1)) nointer = .FALSE.
631 : CASE (do_region_massive)
632 : ! Massive Thermostat
633 8882 : DO i = 1, nkind
634 8750 : molecule_kind => molecule_kind_set(i)
635 : CALL get_molecule_kind(molecule_kind, nmolecule=nmolecule, &
636 8750 : natom=natom, nshell=nshell)
637 8750 : IF (do_shell) natom = nshell
638 17632 : sum_of_thermostats = sum_of_thermostats + 3*natom*nmolecule
639 : END DO
640 : CASE (do_region_defined)
641 : ! User defined region to thermostat..
642 32 : nointer = .FALSE.
643 : ! Determine the number of thermostats defined in the input
644 32 : CALL section_vals_get(region_sections, n_repetition=sum_of_thermostats)
645 32 : IF (sum_of_thermostats < 1) &
646 : CALL cp_abort(__LOCATION__, &
647 588 : "Provide at least 1 region (&DEFINE_REGION) when using the thermostat type DEFINED")
648 : END SELECT
649 :
650 : ! Here we decide which parallel algorithm to use.
651 : ! if there are only massive and molecule type thermostats we can use
652 : ! a local scheme, in cases involving any combination with a
653 : ! global thermostat we assume a coupling of degrees of freedom
654 : ! from different processors
655 : IF (nointer) THEN
656 : ! Distributed thermostats, no interaction
657 14926 : dis_type = do_thermo_no_communication
658 : ! we only count thermostats on this processor
659 : number = 0
660 14926 : DO ikind = 1, nkind
661 14662 : nmol_local = local_molecules%n_el(ikind)
662 14662 : molecule_kind => molecule_kind_set(ikind)
663 14662 : CALL get_molecule_kind(molecule_kind, natom=natom, nshell=nshell)
664 14662 : IF (do_shell) THEN
665 58 : natom = nshell
666 58 : IF (nshell == 0) nmol_local = 0
667 : END IF
668 29588 : IF (region == do_region_molecule) THEN
669 5912 : number = number + nmol_local
670 8750 : ELSE IF (region == do_region_massive) THEN
671 8750 : number = number + 3*nmol_local*natom
672 : ELSE
673 0 : CPABORT('Invalid region setup')
674 : END IF
675 : END DO
676 : ELSE
677 : ! REPlicated thermostats, INTERacting via communication
678 324 : dis_type = do_thermo_communication
679 324 : IF ((region == do_region_global) .OR. (region == do_region_molecule)) THEN
680 292 : number = 1
681 32 : ELSE IF (region == do_region_defined) THEN
682 : CALL get_defined_region_info(region_sections, number, sum_of_thermostats, &
683 : map_loc_thermo_gen=thermostat_info%map_loc_thermo_gen, &
684 : local_molecules=local_molecules, molecule_kind_set=molecule_kind_set, &
685 32 : molecules=molecules, particles=particles, qmmm_env=qmmm_env)
686 : END IF
687 : END IF
688 :
689 588 : IF (PRESENT(nfree)) THEN
690 542 : IF ((sum_of_thermostats > 1) .OR. (dis_type == do_thermo_no_communication)) THEN
691 : ! re-initializing simpar%nfree to zero because of multiple thermostats
692 260 : nfree = 0
693 : END IF
694 : END IF
695 : END IF
696 : END SELECT
697 :
698 : ! Saving information about thermostats
699 1815 : thermostat_info%sum_of_thermostats = sum_of_thermostats
700 1815 : thermostat_info%number_of_thermostats = number
701 1815 : thermostat_info%dis_type = dis_type
702 1815 : END SUBROUTINE setup_thermostat_info
703 :
704 : ! **************************************************************************************************
705 : !> \brief ...
706 : !> \param region_sections ...
707 : !> \param number ...
708 : !> \param sum_of_thermostats ...
709 : !> \param map_loc_thermo_gen ...
710 : !> \param local_molecules ...
711 : !> \param molecule_kind_set ...
712 : !> \param molecules ...
713 : !> \param particles ...
714 : !> \param qmmm_env ...
715 : !> \author 11.2007 [tlaino] - Teodoro Laino - University of Zurich
716 : ! **************************************************************************************************
717 32 : SUBROUTINE get_defined_region_info(region_sections, number, sum_of_thermostats, &
718 : map_loc_thermo_gen, local_molecules, molecule_kind_set, molecules, particles, &
719 : qmmm_env)
720 : TYPE(section_vals_type), POINTER :: region_sections
721 : INTEGER, INTENT(OUT), OPTIONAL :: number
722 : INTEGER, INTENT(INOUT), OPTIONAL :: sum_of_thermostats
723 : INTEGER, DIMENSION(:), POINTER :: map_loc_thermo_gen
724 : TYPE(distribution_1d_type), POINTER :: local_molecules
725 : TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
726 : TYPE(molecule_list_type), POINTER :: molecules
727 : TYPE(particle_list_type), POINTER :: particles
728 : TYPE(qmmm_env_type), POINTER :: qmmm_env
729 :
730 : CHARACTER(LEN=default_string_length), &
731 32 : DIMENSION(:), POINTER :: tmpstringlist
732 : INTEGER :: first_atom, i, ig, ikind, ilist, imol, ipart, jg, last_atom, mregions, n_rep, &
733 : natom_local, nmol_per_kind, nregions, output_unit
734 32 : INTEGER, DIMENSION(:), POINTER :: thermolist, tmp, tmplist
735 : TYPE(cp_logger_type), POINTER :: logger
736 : TYPE(molecule_kind_type), POINTER :: molecule_kind
737 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
738 : TYPE(molecule_type), POINTER :: molecule
739 :
740 32 : NULLIFY (tmplist, tmpstringlist, thermolist, molecule_kind, molecule, molecule_set)
741 32 : NULLIFY (logger)
742 64 : logger => cp_get_default_logger()
743 32 : output_unit = cp_logger_get_default_io_unit(logger)
744 32 : CPASSERT(.NOT. (ASSOCIATED(map_loc_thermo_gen)))
745 32 : CALL section_vals_get(region_sections, n_repetition=nregions)
746 96 : ALLOCATE (thermolist(particles%n_els))
747 43970 : thermolist = HUGE(0)
748 32 : molecule_set => molecules%els
749 32 : mregions = nregions
750 102 : DO ig = 1, mregions
751 70 : CALL section_vals_val_get(region_sections, "LIST", i_rep_section=ig, n_rep_val=n_rep)
752 184 : DO jg = 1, n_rep
753 114 : CALL section_vals_val_get(region_sections, "LIST", i_rep_section=ig, i_rep_val=jg, i_vals=tmplist)
754 2428 : DO i = 1, SIZE(tmplist)
755 2244 : ipart = tmplist(i)
756 2244 : CPASSERT(((ipart > 0) .AND. (ipart <= particles%n_els)))
757 2358 : IF (thermolist(ipart) == HUGE(0)) THEN
758 2244 : thermolist(ipart) = ig
759 : ELSE
760 0 : CPABORT("")
761 : END IF
762 : END DO
763 : END DO
764 70 : CALL section_vals_val_get(region_sections, "MOLNAME", i_rep_section=ig, n_rep_val=n_rep)
765 74 : DO jg = 1, n_rep
766 4 : CALL section_vals_val_get(region_sections, "MOLNAME", i_rep_section=ig, i_rep_val=jg, c_vals=tmpstringlist)
767 78 : DO ilist = 1, SIZE(tmpstringlist)
768 20 : DO ikind = 1, SIZE(molecule_kind_set)
769 12 : molecule_kind => molecule_kind_set(ikind)
770 16 : IF (molecule_kind%name == tmpstringlist(ilist)) THEN
771 48 : DO imol = 1, SIZE(molecule_kind%molecule_list)
772 44 : molecule => molecule_set(molecule_kind%molecule_list(imol))
773 44 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
774 180 : DO ipart = first_atom, last_atom
775 176 : IF (thermolist(ipart) == HUGE(0)) THEN
776 132 : thermolist(ipart) = ig
777 : ELSE
778 0 : CPABORT("")
779 : END IF
780 : END DO
781 : END DO
782 : END IF
783 : END DO
784 : END DO
785 : END DO
786 : CALL setup_thermostat_subsys(region_sections, qmmm_env, thermolist, molecule_set, &
787 70 : subsys_qm=.FALSE., ig=ig, sum_of_thermostats=sum_of_thermostats, nregions=nregions)
788 : CALL setup_thermostat_subsys(region_sections, qmmm_env, thermolist, molecule_set, &
789 242 : subsys_qm=.TRUE., ig=ig, sum_of_thermostats=sum_of_thermostats, nregions=nregions)
790 : END DO
791 :
792 : ! Dump IO warning for not thermalized particles
793 29100 : IF (ANY(thermolist == HUGE(0))) THEN
794 14 : nregions = nregions + 1
795 14 : sum_of_thermostats = sum_of_thermostats + 1
796 15008 : ALLOCATE (tmp(COUNT(thermolist == HUGE(0))))
797 14980 : ilist = 0
798 14980 : DO i = 1, SIZE(thermolist)
799 14980 : IF (thermolist(i) == HUGE(0)) THEN
800 13894 : ilist = ilist + 1
801 13894 : tmp(ilist) = i
802 13894 : thermolist(i) = nregions
803 : END IF
804 : END DO
805 14 : IF (output_unit > 0) THEN
806 7 : WRITE (output_unit, '(A)') " WARNING| No thermostats defined for the following atoms:"
807 6954 : IF (ilist > 0) WRITE (output_unit, '(" WARNING|",9I8)') tmp
808 7 : WRITE (output_unit, '(A)') " WARNING| They will be included in a further unique thermostat!"
809 : END IF
810 14 : DEALLOCATE (tmp)
811 : END IF
812 43970 : CPASSERT(ALL(thermolist /= HUGE(0)))
813 :
814 : ! Now identify the local number of thermostats
815 96 : ALLOCATE (tmp(nregions))
816 116 : tmp = 0
817 32 : natom_local = 0
818 98 : DO ikind = 1, SIZE(molecule_kind_set)
819 66 : nmol_per_kind = local_molecules%n_el(ikind)
820 7384 : DO imol = 1, nmol_per_kind
821 7286 : i = local_molecules%list(ikind)%array(imol)
822 7286 : molecule => molecule_set(i)
823 7286 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
824 29321 : DO ipart = first_atom, last_atom
825 21969 : natom_local = natom_local + 1
826 29255 : tmp(thermolist(ipart)) = 1
827 : END DO
828 : END DO
829 : END DO
830 116 : number = SUM(tmp)
831 32 : DEALLOCATE (tmp)
832 :
833 : ! Now map the local atoms with the corresponding thermostat
834 96 : ALLOCATE (map_loc_thermo_gen(natom_local))
835 32 : natom_local = 0
836 98 : DO ikind = 1, SIZE(molecule_kind_set)
837 66 : nmol_per_kind = local_molecules%n_el(ikind)
838 7384 : DO imol = 1, nmol_per_kind
839 7286 : i = local_molecules%list(ikind)%array(imol)
840 7286 : molecule => molecule_set(i)
841 7286 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
842 29321 : DO ipart = first_atom, last_atom
843 21969 : natom_local = natom_local + 1
844 29255 : map_loc_thermo_gen(natom_local) = thermolist(ipart)
845 : END DO
846 : END DO
847 : END DO
848 :
849 32 : DEALLOCATE (thermolist)
850 64 : END SUBROUTINE get_defined_region_info
851 :
852 : ! **************************************************************************************************
853 : !> \brief ...
854 : !> \param region_sections ...
855 : !> \param qmmm_env ...
856 : !> \param thermolist ...
857 : !> \param molecule_set ...
858 : !> \param subsys_qm ...
859 : !> \param ig ...
860 : !> \param sum_of_thermostats ...
861 : !> \param nregions ...
862 : !> \author 11.2007 [tlaino] - Teodoro Laino - University of Zurich
863 : ! **************************************************************************************************
864 140 : SUBROUTINE setup_thermostat_subsys(region_sections, qmmm_env, thermolist, &
865 : molecule_set, subsys_qm, ig, sum_of_thermostats, nregions)
866 : TYPE(section_vals_type), POINTER :: region_sections
867 : TYPE(qmmm_env_type), POINTER :: qmmm_env
868 : INTEGER, DIMENSION(:), POINTER :: thermolist
869 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
870 : LOGICAL, INTENT(IN) :: subsys_qm
871 : INTEGER, INTENT(IN) :: ig
872 : INTEGER, INTENT(INOUT) :: sum_of_thermostats, nregions
873 :
874 : CHARACTER(LEN=default_string_length) :: label1, label2
875 : INTEGER :: first_atom, i, imolecule, ipart, &
876 : last_atom, nrep, thermo1
877 140 : INTEGER, DIMENSION(:), POINTER :: atom_index1
878 : LOGICAL :: explicit
879 : TYPE(molecule_type), POINTER :: molecule
880 :
881 140 : label1 = "MM_SUBSYS"
882 140 : label2 = "QM_SUBSYS"
883 140 : IF (subsys_qm) THEN
884 70 : label1 = "QM_SUBSYS"
885 70 : label2 = "MM_SUBSYS"
886 : END IF
887 : CALL section_vals_val_get(region_sections, TRIM(label1), i_rep_section=ig, &
888 140 : n_rep_val=nrep, explicit=explicit)
889 140 : IF (nrep == 1 .AND. explicit) THEN
890 8 : IF (ASSOCIATED(qmmm_env)) THEN
891 8 : atom_index1 => qmmm_env%qm%mm_atom_index
892 8 : IF (subsys_qm) THEN
893 4 : atom_index1 => qmmm_env%qm%qm_atom_index
894 : END IF
895 8 : CALL section_vals_val_get(region_sections, TRIM(label1), i_val=thermo1, i_rep_section=ig)
896 4 : SELECT CASE (thermo1)
897 : CASE (do_constr_atomic)
898 13820 : DO i = 1, SIZE(atom_index1)
899 13816 : ipart = atom_index1(i)
900 13816 : IF (subsys_qm .AND. qmmm_env%qm%qmmm_link .AND. ASSOCIATED(qmmm_env%qm%mm_link_atoms)) THEN
901 46 : IF (ANY(ipart == qmmm_env%qm%mm_link_atoms)) CYCLE
902 : END IF
903 13818 : IF (thermolist(ipart) == HUGE(0)) THEN
904 13814 : thermolist(ipart) = ig
905 : ELSE
906 : CALL cp_abort(__LOCATION__, &
907 : 'One atom ('//cp_to_string(ipart)//') of the '// &
908 : TRIM(label1)//' was already assigned to'// &
909 : ' the thermostatting region Nr.'//cp_to_string(thermolist(ipart))// &
910 0 : '. Please check the input for inconsistencies!')
911 : END IF
912 : END DO
913 : CASE (do_constr_molec)
914 9168 : DO imolecule = 1, SIZE(molecule_set)
915 9160 : molecule => molecule_set(imolecule)
916 9160 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
917 15908454 : IF (ANY(atom_index1 >= first_atom .AND. atom_index1 <= last_atom)) THEN
918 18436 : DO ipart = first_atom, last_atom
919 18436 : IF (thermolist(ipart) == HUGE(0)) THEN
920 13854 : thermolist(ipart) = ig
921 : ELSE
922 : CALL cp_abort(__LOCATION__, &
923 : 'One atom ('//cp_to_string(ipart)//') of the '// &
924 : TRIM(label1)//' was already assigned to'// &
925 : ' the thermostatting region Nr.'//cp_to_string(thermolist(ipart))// &
926 0 : '. Please check the input for inconsistencies!')
927 : END IF
928 : END DO
929 : END IF
930 : END DO
931 : END SELECT
932 : ELSE
933 0 : sum_of_thermostats = sum_of_thermostats - 1
934 0 : nregions = nregions - 1
935 : END IF
936 : END IF
937 140 : END SUBROUTINE setup_thermostat_subsys
938 :
939 : ! **************************************************************************************************
940 : !> \brief ...
941 : !> \param map_info ...
942 : !> \param npt ...
943 : !> \param group ...
944 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
945 : ! **************************************************************************************************
946 5444 : SUBROUTINE ke_region_baro(map_info, npt, group)
947 : TYPE(map_info_type), POINTER :: map_info
948 : TYPE(npt_info_type), DIMENSION(:, :), &
949 : INTENT(INOUT) :: npt
950 : TYPE(mp_comm_type), INTENT(IN) :: group
951 :
952 : INTEGER :: i, j, ncoef
953 :
954 10888 : map_info%v_scale = 1.0_dp
955 10888 : map_info%s_kin = 0.0_dp
956 5444 : ncoef = 0
957 13672 : DO i = 1, SIZE(npt, 1)
958 30252 : DO j = 1, SIZE(npt, 2)
959 16580 : ncoef = ncoef + 1
960 : map_info%p_kin(1, ncoef)%point = map_info%p_kin(1, ncoef)%point &
961 24808 : + npt(i, j)%mass*npt(i, j)%v**2
962 : END DO
963 : END DO
964 :
965 5444 : IF (map_info%dis_type == do_thermo_communication) CALL group%sum(map_info%s_kin)
966 :
967 5444 : END SUBROUTINE ke_region_baro
968 :
969 : ! **************************************************************************************************
970 : !> \brief ...
971 : !> \param map_info ...
972 : !> \param npt ...
973 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
974 : ! **************************************************************************************************
975 4360 : SUBROUTINE vel_rescale_baro(map_info, npt)
976 : TYPE(map_info_type), POINTER :: map_info
977 : TYPE(npt_info_type), DIMENSION(:, :), &
978 : INTENT(INOUT) :: npt
979 :
980 : INTEGER :: i, j, ncoef
981 :
982 4360 : ncoef = 0
983 11344 : DO i = 1, SIZE(npt, 1)
984 26200 : DO j = 1, SIZE(npt, 2)
985 14856 : ncoef = ncoef + 1
986 21840 : npt(i, j)%v = npt(i, j)%v*map_info%p_scale(1, ncoef)%point
987 : END DO
988 : END DO
989 :
990 4360 : END SUBROUTINE vel_rescale_baro
991 :
992 : ! **************************************************************************************************
993 : !> \brief ...
994 : !> \param map_info ...
995 : !> \param particle_set ...
996 : !> \param molecule_kind_set ...
997 : !> \param local_molecules ...
998 : !> \param molecule_set ...
999 : !> \param group ...
1000 : !> \param vel ...
1001 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
1002 : ! **************************************************************************************************
1003 25708 : SUBROUTINE ke_region_particles(map_info, particle_set, molecule_kind_set, &
1004 25708 : local_molecules, molecule_set, group, vel)
1005 :
1006 : TYPE(map_info_type), POINTER :: map_info
1007 : TYPE(particle_type), POINTER :: particle_set(:)
1008 : TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
1009 : TYPE(distribution_1d_type), POINTER :: local_molecules
1010 : TYPE(molecule_type), POINTER :: molecule_set(:)
1011 : TYPE(mp_comm_type), INTENT(IN) :: group
1012 : REAL(KIND=dp), INTENT(INOUT), OPTIONAL :: vel(:, :)
1013 :
1014 : INTEGER :: first_atom, ii, ikind, imol, imol_local, &
1015 : ipart, last_atom, nmol_local
1016 : LOGICAL :: present_vel
1017 : REAL(KIND=dp) :: mass
1018 : TYPE(atomic_kind_type), POINTER :: atomic_kind
1019 : TYPE(molecule_type), POINTER :: molecule
1020 :
1021 1553576 : map_info%v_scale = 1.0_dp
1022 1553576 : map_info%s_kin = 0.0_dp
1023 25708 : present_vel = PRESENT(vel)
1024 25708 : ii = 0
1025 1271176 : DO ikind = 1, SIZE(molecule_kind_set)
1026 1245468 : nmol_local = local_molecules%n_el(ikind)
1027 2656966 : DO imol_local = 1, nmol_local
1028 1385790 : imol = local_molecules%list(ikind)%array(imol_local)
1029 1385790 : molecule => molecule_set(imol)
1030 1385790 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
1031 5677896 : DO ipart = first_atom, last_atom
1032 3046638 : ii = ii + 1
1033 3046638 : atomic_kind => particle_set(ipart)%atomic_kind
1034 3046638 : CALL get_atomic_kind(atomic_kind=atomic_kind, mass=mass)
1035 4432428 : IF (present_vel) THEN
1036 1523319 : IF (ASSOCIATED(map_info%p_kin(1, ii)%point)) &
1037 1523319 : map_info%p_kin(1, ii)%point = map_info%p_kin(1, ii)%point + mass*vel(1, ipart)**2
1038 1523319 : IF (ASSOCIATED(map_info%p_kin(2, ii)%point)) &
1039 1523319 : map_info%p_kin(2, ii)%point = map_info%p_kin(2, ii)%point + mass*vel(2, ipart)**2
1040 1523319 : IF (ASSOCIATED(map_info%p_kin(3, ii)%point)) &
1041 1523319 : map_info%p_kin(3, ii)%point = map_info%p_kin(3, ii)%point + mass*vel(3, ipart)**2
1042 : ELSE
1043 1523319 : IF (ASSOCIATED(map_info%p_kin(1, ii)%point)) &
1044 1523319 : map_info%p_kin(1, ii)%point = map_info%p_kin(1, ii)%point + mass*particle_set(ipart)%v(1)**2
1045 1523319 : IF (ASSOCIATED(map_info%p_kin(2, ii)%point)) &
1046 1523319 : map_info%p_kin(2, ii)%point = map_info%p_kin(2, ii)%point + mass*particle_set(ipart)%v(2)**2
1047 1523319 : IF (ASSOCIATED(map_info%p_kin(3, ii)%point)) &
1048 1523319 : map_info%p_kin(3, ii)%point = map_info%p_kin(3, ii)%point + mass*particle_set(ipart)%v(3)**2
1049 : END IF
1050 : END DO
1051 : END DO
1052 : END DO
1053 :
1054 62732 : IF (map_info%dis_type == do_thermo_communication) CALL group%sum(map_info%s_kin)
1055 :
1056 25708 : END SUBROUTINE ke_region_particles
1057 :
1058 : ! **************************************************************************************************
1059 : !> \brief ...
1060 : !> \param map_info ...
1061 : !> \param particle_set ...
1062 : !> \param molecule_kind_set ...
1063 : !> \param local_molecules ...
1064 : !> \param molecule_set ...
1065 : !> \param group ...
1066 : !> \param vel ...
1067 : !> \author 07.2009 MI
1068 : ! **************************************************************************************************
1069 800 : SUBROUTINE momentum_region_particles(map_info, particle_set, molecule_kind_set, &
1070 800 : local_molecules, molecule_set, group, vel)
1071 :
1072 : TYPE(map_info_type), POINTER :: map_info
1073 : TYPE(particle_type), POINTER :: particle_set(:)
1074 : TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
1075 : TYPE(distribution_1d_type), POINTER :: local_molecules
1076 : TYPE(molecule_type), POINTER :: molecule_set(:)
1077 : TYPE(mp_comm_type), INTENT(IN) :: group
1078 : REAL(KIND=dp), INTENT(INOUT), OPTIONAL :: vel(:, :)
1079 :
1080 : INTEGER :: first_atom, ii, ikind, imol, imol_local, &
1081 : ipart, last_atom, nmol_local
1082 : LOGICAL :: present_vel
1083 : REAL(KIND=dp) :: mass
1084 : TYPE(atomic_kind_type), POINTER :: atomic_kind
1085 : TYPE(molecule_type), POINTER :: molecule
1086 :
1087 130400 : map_info%v_scale = 1.0_dp
1088 130400 : map_info%s_kin = 0.0_dp
1089 800 : present_vel = PRESENT(vel)
1090 800 : ii = 0
1091 87200 : DO ikind = 1, SIZE(molecule_kind_set)
1092 86400 : nmol_local = local_molecules%n_el(ikind)
1093 130400 : DO imol_local = 1, nmol_local
1094 43200 : imol = local_molecules%list(ikind)%array(imol_local)
1095 43200 : molecule => molecule_set(imol)
1096 43200 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
1097 172800 : DO ipart = first_atom, last_atom
1098 43200 : ii = ii + 1
1099 43200 : atomic_kind => particle_set(ipart)%atomic_kind
1100 43200 : CALL get_atomic_kind(atomic_kind=atomic_kind, mass=mass)
1101 86400 : IF (present_vel) THEN
1102 21600 : map_info%p_kin(1, ii)%point = map_info%p_kin(1, ii)%point + SQRT(mass)*vel(1, ipart)
1103 21600 : map_info%p_kin(2, ii)%point = map_info%p_kin(2, ii)%point + SQRT(mass)*vel(2, ipart)
1104 21600 : map_info%p_kin(3, ii)%point = map_info%p_kin(3, ii)%point + SQRT(mass)*vel(3, ipart)
1105 : ELSE
1106 21600 : map_info%p_kin(1, ii)%point = map_info%p_kin(1, ii)%point + SQRT(mass)*particle_set(ipart)%v(1)
1107 21600 : map_info%p_kin(2, ii)%point = map_info%p_kin(2, ii)%point + SQRT(mass)*particle_set(ipart)%v(2)
1108 21600 : map_info%p_kin(3, ii)%point = map_info%p_kin(3, ii)%point + SQRT(mass)*particle_set(ipart)%v(3)
1109 : END IF
1110 : END DO
1111 : END DO
1112 : END DO
1113 :
1114 800 : IF (map_info%dis_type == do_thermo_communication) CALL group%sum(map_info%s_kin)
1115 :
1116 800 : END SUBROUTINE momentum_region_particles
1117 :
1118 : ! **************************************************************************************************
1119 : !> \brief ...
1120 : !> \param map_info ...
1121 : !> \param molecule_kind_set ...
1122 : !> \param molecule_set ...
1123 : !> \param particle_set ...
1124 : !> \param local_molecules ...
1125 : !> \param shell_adiabatic ...
1126 : !> \param shell_particle_set ...
1127 : !> \param core_particle_set ...
1128 : !> \param vel ...
1129 : !> \param shell_vel ...
1130 : !> \param core_vel ...
1131 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
1132 : ! **************************************************************************************************
1133 19480 : SUBROUTINE vel_rescale_particles(map_info, molecule_kind_set, molecule_set, &
1134 : particle_set, local_molecules, shell_adiabatic, shell_particle_set, &
1135 19480 : core_particle_set, vel, shell_vel, core_vel)
1136 :
1137 : TYPE(map_info_type), POINTER :: map_info
1138 : TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
1139 : TYPE(molecule_type), POINTER :: molecule_set(:)
1140 : TYPE(particle_type), POINTER :: particle_set(:)
1141 : TYPE(distribution_1d_type), POINTER :: local_molecules
1142 : LOGICAL, INTENT(IN) :: shell_adiabatic
1143 : TYPE(particle_type), OPTIONAL, POINTER :: shell_particle_set(:), &
1144 : core_particle_set(:)
1145 : REAL(KIND=dp), INTENT(INOUT), OPTIONAL :: vel(:, :), shell_vel(:, :), &
1146 : core_vel(:, :)
1147 :
1148 : INTEGER :: first_atom, ii, ikind, imol, imol_local, &
1149 : ipart, jj, last_atom, nmol_local, &
1150 : shell_index
1151 : LOGICAL :: present_vel
1152 : REAL(KIND=dp) :: fac_massc, fac_masss, mass, vc(3), vs(3)
1153 : TYPE(atomic_kind_type), POINTER :: atomic_kind
1154 : TYPE(molecule_type), POINTER :: molecule
1155 : TYPE(shell_kind_type), POINTER :: shell
1156 :
1157 19480 : ii = 0
1158 19480 : jj = 0
1159 19480 : present_vel = PRESENT(vel)
1160 : ! Just few checks for consistency
1161 19480 : IF (present_vel) THEN
1162 9740 : IF (shell_adiabatic) THEN
1163 1410 : CPASSERT(PRESENT(shell_vel))
1164 1410 : CPASSERT(PRESENT(core_vel))
1165 : END IF
1166 : ELSE
1167 9740 : IF (shell_adiabatic) THEN
1168 1410 : CPASSERT(PRESENT(shell_particle_set))
1169 1410 : CPASSERT(PRESENT(core_particle_set))
1170 : END IF
1171 : END IF
1172 826036 : Kind: DO ikind = 1, SIZE(molecule_kind_set)
1173 806556 : nmol_local = local_molecules%n_el(ikind)
1174 1733072 : Mol_local: DO imol_local = 1, nmol_local
1175 907036 : imol = local_molecules%list(ikind)%array(imol_local)
1176 907036 : molecule => molecule_set(imol)
1177 907036 : CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
1178 3697444 : Particle: DO ipart = first_atom, last_atom
1179 1983852 : ii = ii + 1
1180 1983852 : IF (present_vel) THEN
1181 991926 : vel(1, ipart) = vel(1, ipart)*map_info%p_scale(1, ii)%point
1182 991926 : vel(2, ipart) = vel(2, ipart)*map_info%p_scale(2, ii)%point
1183 991926 : vel(3, ipart) = vel(3, ipart)*map_info%p_scale(3, ii)%point
1184 : ELSE
1185 991926 : particle_set(ipart)%v(1) = particle_set(ipart)%v(1)*map_info%p_scale(1, ii)%point
1186 991926 : particle_set(ipart)%v(2) = particle_set(ipart)%v(2)*map_info%p_scale(2, ii)%point
1187 991926 : particle_set(ipart)%v(3) = particle_set(ipart)%v(3)*map_info%p_scale(3, ii)%point
1188 : END IF
1189 : ! If Shell Adiabatic then apply the NHC thermostat also to the Shells
1190 2890888 : IF (shell_adiabatic) THEN
1191 152160 : shell_index = particle_set(ipart)%shell_index
1192 152160 : IF (shell_index /= 0) THEN
1193 150880 : jj = jj + 2
1194 150880 : atomic_kind => particle_set(ipart)%atomic_kind
1195 150880 : CALL get_atomic_kind(atomic_kind=atomic_kind, mass=mass, shell=shell)
1196 150880 : fac_masss = shell%mass_shell/mass
1197 150880 : fac_massc = shell%mass_core/mass
1198 150880 : IF (present_vel) THEN
1199 301760 : vs(1:3) = shell_vel(1:3, shell_index)
1200 301760 : vc(1:3) = core_vel(1:3, shell_index)
1201 75440 : shell_vel(1, shell_index) = vel(1, ipart) + fac_massc*(vs(1) - vc(1))
1202 75440 : shell_vel(2, shell_index) = vel(2, ipart) + fac_massc*(vs(2) - vc(2))
1203 75440 : shell_vel(3, shell_index) = vel(3, ipart) + fac_massc*(vs(3) - vc(3))
1204 75440 : core_vel(1, shell_index) = vel(1, ipart) + fac_masss*(vc(1) - vs(1))
1205 75440 : core_vel(2, shell_index) = vel(2, ipart) + fac_masss*(vc(2) - vs(2))
1206 75440 : core_vel(3, shell_index) = vel(3, ipart) + fac_masss*(vc(3) - vs(3))
1207 : ELSE
1208 301760 : vs(1:3) = shell_particle_set(shell_index)%v(1:3)
1209 301760 : vc(1:3) = core_particle_set(shell_index)%v(1:3)
1210 75440 : shell_particle_set(shell_index)%v(1) = particle_set(ipart)%v(1) + fac_massc*(vs(1) - vc(1))
1211 75440 : shell_particle_set(shell_index)%v(2) = particle_set(ipart)%v(2) + fac_massc*(vs(2) - vc(2))
1212 75440 : shell_particle_set(shell_index)%v(3) = particle_set(ipart)%v(3) + fac_massc*(vs(3) - vc(3))
1213 75440 : core_particle_set(shell_index)%v(1) = particle_set(ipart)%v(1) + fac_masss*(vc(1) - vs(1))
1214 75440 : core_particle_set(shell_index)%v(2) = particle_set(ipart)%v(2) + fac_masss*(vc(2) - vs(2))
1215 75440 : core_particle_set(shell_index)%v(3) = particle_set(ipart)%v(3) + fac_masss*(vc(3) - vs(3))
1216 : END IF
1217 : END IF
1218 : END IF
1219 : END DO Particle
1220 : END DO Mol_local
1221 : END DO Kind
1222 :
1223 19480 : END SUBROUTINE vel_rescale_particles
1224 :
1225 : ! **************************************************************************************************
1226 : !> \brief ...
1227 : !> \param map_info ...
1228 : !> \param particle_set ...
1229 : !> \param atomic_kind_set ...
1230 : !> \param local_particles ...
1231 : !> \param group ...
1232 : !> \param core_particle_set ...
1233 : !> \param shell_particle_set ...
1234 : !> \param core_vel ...
1235 : !> \param shell_vel ...
1236 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
1237 : ! **************************************************************************************************
1238 1840 : SUBROUTINE ke_region_shells(map_info, particle_set, atomic_kind_set, &
1239 : local_particles, group, core_particle_set, shell_particle_set, &
1240 1840 : core_vel, shell_vel)
1241 :
1242 : TYPE(map_info_type), POINTER :: map_info
1243 : TYPE(particle_type), POINTER :: particle_set(:)
1244 : TYPE(atomic_kind_type), POINTER :: atomic_kind_set(:)
1245 : TYPE(distribution_1d_type), POINTER :: local_particles
1246 : TYPE(mp_comm_type), INTENT(IN) :: group
1247 : TYPE(particle_type), OPTIONAL, POINTER :: core_particle_set(:), &
1248 : shell_particle_set(:)
1249 : REAL(KIND=dp), INTENT(INOUT), OPTIONAL :: core_vel(:, :), shell_vel(:, :)
1250 :
1251 : INTEGER :: ii, iparticle, iparticle_kind, &
1252 : iparticle_local, nparticle_kind, &
1253 : nparticle_local, shell_index
1254 : LOGICAL :: is_shell, present_vel
1255 : REAL(dp) :: mass, mu_mass, v_sc(3)
1256 : TYPE(atomic_kind_type), POINTER :: atomic_kind
1257 : TYPE(shell_kind_type), POINTER :: shell
1258 :
1259 1840 : present_vel = PRESENT(shell_vel)
1260 : ! Preliminary checks for consistency usage
1261 1840 : IF (present_vel) THEN
1262 920 : CPASSERT(PRESENT(core_vel))
1263 : ELSE
1264 920 : CPASSERT(PRESENT(shell_particle_set))
1265 920 : CPASSERT(PRESENT(core_particle_set))
1266 : END IF
1267 : ! get force on first thermostat for all the chains in the system.
1268 154040 : map_info%v_scale = 1.0_dp
1269 154040 : map_info%s_kin = 0.0_dp
1270 1840 : ii = 0
1271 :
1272 1840 : nparticle_kind = SIZE(atomic_kind_set)
1273 5520 : DO iparticle_kind = 1, nparticle_kind
1274 3680 : atomic_kind => atomic_kind_set(iparticle_kind)
1275 3680 : CALL get_atomic_kind(atomic_kind=atomic_kind, mass=mass, shell_active=is_shell, shell=shell)
1276 5520 : IF (is_shell) THEN
1277 3680 : mu_mass = shell%mass_shell*shell%mass_core/mass
1278 3680 : nparticle_local = local_particles%n_el(iparticle_kind)
1279 92000 : DO iparticle_local = 1, nparticle_local
1280 88320 : iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
1281 88320 : shell_index = particle_set(iparticle)%shell_index
1282 88320 : ii = ii + 1
1283 92000 : IF (present_vel) THEN
1284 44160 : v_sc(1) = core_vel(1, shell_index) - shell_vel(1, shell_index)
1285 44160 : v_sc(2) = core_vel(2, shell_index) - shell_vel(2, shell_index)
1286 44160 : v_sc(3) = core_vel(3, shell_index) - shell_vel(3, shell_index)
1287 44160 : map_info%p_kin(1, ii)%point = map_info%p_kin(1, ii)%point + mu_mass*v_sc(1)**2
1288 44160 : map_info%p_kin(2, ii)%point = map_info%p_kin(2, ii)%point + mu_mass*v_sc(2)**2
1289 44160 : map_info%p_kin(3, ii)%point = map_info%p_kin(3, ii)%point + mu_mass*v_sc(3)**2
1290 : ELSE
1291 44160 : v_sc(1) = core_particle_set(shell_index)%v(1) - shell_particle_set(shell_index)%v(1)
1292 44160 : v_sc(2) = core_particle_set(shell_index)%v(2) - shell_particle_set(shell_index)%v(2)
1293 44160 : v_sc(3) = core_particle_set(shell_index)%v(3) - shell_particle_set(shell_index)%v(3)
1294 44160 : map_info%p_kin(1, ii)%point = map_info%p_kin(1, ii)%point + mu_mass*v_sc(1)**2
1295 44160 : map_info%p_kin(2, ii)%point = map_info%p_kin(2, ii)%point + mu_mass*v_sc(2)**2
1296 44160 : map_info%p_kin(3, ii)%point = map_info%p_kin(3, ii)%point + mu_mass*v_sc(3)**2
1297 : END IF
1298 : END DO
1299 : END IF
1300 : END DO
1301 2880 : IF (map_info%dis_type == do_thermo_communication) CALL group%sum(map_info%s_kin)
1302 :
1303 1840 : END SUBROUTINE ke_region_shells
1304 :
1305 : ! **************************************************************************************************
1306 : !> \brief ...
1307 : !> \param map_info ...
1308 : !> \param atomic_kind_set ...
1309 : !> \param particle_set ...
1310 : !> \param local_particles ...
1311 : !> \param shell_particle_set ...
1312 : !> \param core_particle_set ...
1313 : !> \param shell_vel ...
1314 : !> \param core_vel ...
1315 : !> \param vel ...
1316 : !> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
1317 : ! **************************************************************************************************
1318 1600 : SUBROUTINE vel_rescale_shells(map_info, atomic_kind_set, particle_set, local_particles, &
1319 1600 : shell_particle_set, core_particle_set, shell_vel, core_vel, vel)
1320 :
1321 : TYPE(map_info_type), POINTER :: map_info
1322 : TYPE(atomic_kind_type), POINTER :: atomic_kind_set(:)
1323 : TYPE(particle_type), POINTER :: particle_set(:)
1324 : TYPE(distribution_1d_type), POINTER :: local_particles
1325 : TYPE(particle_type), OPTIONAL, POINTER :: shell_particle_set(:), &
1326 : core_particle_set(:)
1327 : REAL(KIND=dp), INTENT(INOUT), OPTIONAL :: shell_vel(:, :), core_vel(:, :), &
1328 : vel(:, :)
1329 :
1330 : INTEGER :: ii, iparticle, iparticle_kind, &
1331 : iparticle_local, nparticle_kind, &
1332 : nparticle_local, shell_index
1333 : LOGICAL :: is_shell, present_vel
1334 : REAL(dp) :: mass, massc, masss, umass, v(3), vc(3), &
1335 : vs(3)
1336 : TYPE(atomic_kind_type), POINTER :: atomic_kind
1337 : TYPE(shell_kind_type), POINTER :: shell
1338 :
1339 1600 : present_vel = PRESENT(vel)
1340 : ! Preliminary checks for consistency usage
1341 1600 : IF (present_vel) THEN
1342 800 : CPASSERT(PRESENT(shell_vel))
1343 800 : CPASSERT(PRESENT(core_vel))
1344 : ELSE
1345 800 : CPASSERT(PRESENT(shell_particle_set))
1346 800 : CPASSERT(PRESENT(core_particle_set))
1347 : END IF
1348 1600 : ii = 0
1349 1600 : nparticle_kind = SIZE(atomic_kind_set)
1350 : ! now scale the core-shell velocities
1351 4800 : Kind: DO iparticle_kind = 1, nparticle_kind
1352 3200 : atomic_kind => atomic_kind_set(iparticle_kind)
1353 3200 : CALL get_atomic_kind(atomic_kind=atomic_kind, mass=mass, shell_active=is_shell, shell=shell)
1354 4800 : IF (is_shell) THEN
1355 3200 : umass = 1.0_dp/mass
1356 3200 : masss = shell%mass_shell*umass
1357 3200 : massc = shell%mass_core*umass
1358 :
1359 3200 : nparticle_local = local_particles%n_el(iparticle_kind)
1360 80000 : Particles: DO iparticle_local = 1, nparticle_local
1361 76800 : iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
1362 76800 : shell_index = particle_set(iparticle)%shell_index
1363 76800 : ii = ii + 1
1364 80000 : IF (present_vel) THEN
1365 153600 : vc(1:3) = core_vel(1:3, shell_index)
1366 153600 : vs(1:3) = shell_vel(1:3, shell_index)
1367 153600 : v(1:3) = vel(1:3, iparticle)
1368 38400 : shell_vel(1, shell_index) = v(1) + map_info%p_scale(1, ii)%point*massc*(vs(1) - vc(1))
1369 38400 : shell_vel(2, shell_index) = v(2) + map_info%p_scale(2, ii)%point*massc*(vs(2) - vc(2))
1370 38400 : shell_vel(3, shell_index) = v(3) + map_info%p_scale(3, ii)%point*massc*(vs(3) - vc(3))
1371 38400 : core_vel(1, shell_index) = v(1) + map_info%p_scale(1, ii)%point*masss*(vc(1) - vs(1))
1372 38400 : core_vel(2, shell_index) = v(2) + map_info%p_scale(2, ii)%point*masss*(vc(2) - vs(2))
1373 38400 : core_vel(3, shell_index) = v(3) + map_info%p_scale(3, ii)%point*masss*(vc(3) - vs(3))
1374 : ELSE
1375 153600 : vc(1:3) = core_particle_set(shell_index)%v(1:3)
1376 153600 : vs(1:3) = shell_particle_set(shell_index)%v(1:3)
1377 153600 : v(1:3) = particle_set(iparticle)%v(1:3)
1378 38400 : shell_particle_set(shell_index)%v(1) = v(1) + map_info%p_scale(1, ii)%point*massc*(vs(1) - vc(1))
1379 38400 : shell_particle_set(shell_index)%v(2) = v(2) + map_info%p_scale(2, ii)%point*massc*(vs(2) - vc(2))
1380 38400 : shell_particle_set(shell_index)%v(3) = v(3) + map_info%p_scale(3, ii)%point*massc*(vs(3) - vc(3))
1381 38400 : core_particle_set(shell_index)%v(1) = v(1) + map_info%p_scale(1, ii)%point*masss*(vc(1) - vs(1))
1382 38400 : core_particle_set(shell_index)%v(2) = v(2) + map_info%p_scale(2, ii)%point*masss*(vc(2) - vs(2))
1383 38400 : core_particle_set(shell_index)%v(3) = v(3) + map_info%p_scale(3, ii)%point*masss*(vc(3) - vs(3))
1384 : END IF
1385 : END DO Particles
1386 : END IF
1387 : END DO Kind
1388 :
1389 1600 : END SUBROUTINE vel_rescale_shells
1390 :
1391 : ! **************************************************************************************************
1392 : !> \brief Calculates kinetic energy and potential energy of the nhc variables
1393 : !> \param nhc ...
1394 : !> \param nhc_pot ...
1395 : !> \param nhc_kin ...
1396 : !> \param para_env ...
1397 : !> \param array_kin ...
1398 : !> \param array_pot ...
1399 : !> \par History
1400 : !> none
1401 : !> \author CJM
1402 : ! **************************************************************************************************
1403 10668 : SUBROUTINE get_nhc_energies(nhc, nhc_pot, nhc_kin, para_env, array_kin, array_pot)
1404 : TYPE(lnhc_parameters_type), POINTER :: nhc
1405 : REAL(KIND=dp), INTENT(OUT) :: nhc_pot, nhc_kin
1406 : TYPE(mp_para_env_type), POINTER :: para_env
1407 : REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: array_kin, array_pot
1408 :
1409 : INTEGER :: imap, l, n, number
1410 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: akin, vpot
1411 :
1412 10668 : number = nhc%glob_num_nhc
1413 32004 : ALLOCATE (akin(number))
1414 32004 : ALLOCATE (vpot(number))
1415 774122 : akin = 0.0_dp
1416 774122 : vpot = 0.0_dp
1417 395929 : DO n = 1, nhc%loc_num_nhc
1418 385261 : imap = nhc%map_info%index(n)
1419 1796878 : DO l = 1, nhc%nhc_len
1420 1400949 : akin(imap) = akin(imap) + 0.5_dp*nhc%nvt(l, n)%mass*nhc%nvt(l, n)%v**2
1421 1786210 : vpot(imap) = vpot(imap) + nhc%nvt(l, n)%nkt*nhc%nvt(l, n)%eta
1422 : END DO
1423 : END DO
1424 :
1425 : ! Handle the thermostat distribution
1426 10668 : IF (nhc%map_info%dis_type == do_thermo_no_communication) THEN
1427 3726 : CALL para_env%sum(akin)
1428 3726 : CALL para_env%sum(vpot)
1429 6942 : ELSE IF (nhc%map_info%dis_type == do_thermo_communication) THEN
1430 4958 : CALL communication_thermo_low1(akin, number, para_env)
1431 4958 : CALL communication_thermo_low1(vpot, number, para_env)
1432 : END IF
1433 774122 : nhc_kin = SUM(akin)
1434 774122 : nhc_pot = SUM(vpot)
1435 :
1436 : ! Possibly give back kinetic or potential energy arrays
1437 10668 : IF (PRESENT(array_pot)) THEN
1438 274 : IF (ASSOCIATED(array_pot)) THEN
1439 0 : CPASSERT(SIZE(array_pot) == number)
1440 : ELSE
1441 822 : ALLOCATE (array_pot(number))
1442 : END IF
1443 35794 : array_pot = vpot
1444 : END IF
1445 10668 : IF (PRESENT(array_kin)) THEN
1446 274 : IF (ASSOCIATED(array_kin)) THEN
1447 0 : CPASSERT(SIZE(array_kin) == number)
1448 : ELSE
1449 822 : ALLOCATE (array_kin(number))
1450 : END IF
1451 35794 : array_kin = akin
1452 : END IF
1453 10668 : DEALLOCATE (akin)
1454 10668 : DEALLOCATE (vpot)
1455 10668 : END SUBROUTINE get_nhc_energies
1456 :
1457 : ! **************************************************************************************************
1458 : !> \brief Calculates kinetic energy and potential energy
1459 : !> of the csvr and gle thermostats
1460 : !> \param map_info ...
1461 : !> \param loc_num ...
1462 : !> \param glob_num ...
1463 : !> \param thermo_energy ...
1464 : !> \param thermostat_kin ...
1465 : !> \param para_env ...
1466 : !> \param array_pot ...
1467 : !> \param array_kin ...
1468 : !> \par History generalized MI [07.2009]
1469 : !> \author Teodoro Laino [tlaino] - 10.2007 - University of Zurich
1470 : ! **************************************************************************************************
1471 4532 : SUBROUTINE get_kin_energies(map_info, loc_num, glob_num, thermo_energy, thermostat_kin, &
1472 : para_env, array_pot, array_kin)
1473 :
1474 : TYPE(map_info_type), POINTER :: map_info
1475 : INTEGER, INTENT(IN) :: loc_num, glob_num
1476 : REAL(dp), DIMENSION(:), INTENT(IN) :: thermo_energy
1477 : REAL(KIND=dp), INTENT(OUT) :: thermostat_kin
1478 : TYPE(mp_para_env_type), POINTER :: para_env
1479 : REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: array_pot, array_kin
1480 :
1481 : INTEGER :: imap, n, number
1482 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: akin
1483 :
1484 4532 : number = glob_num
1485 13596 : ALLOCATE (akin(number))
1486 278686 : akin = 0.0_dp
1487 143368 : DO n = 1, loc_num
1488 138836 : imap = map_info%index(n)
1489 143368 : akin(imap) = thermo_energy(n)
1490 : END DO
1491 :
1492 : ! Handle the thermostat distribution
1493 4532 : IF (map_info%dis_type == do_thermo_no_communication) THEN
1494 1306 : CALL para_env%sum(akin)
1495 3226 : ELSE IF (map_info%dis_type == do_thermo_communication) THEN
1496 2538 : CALL communication_thermo_low1(akin, number, para_env)
1497 : END IF
1498 278686 : thermostat_kin = SUM(akin)
1499 :
1500 : ! Possibly give back kinetic or potential energy arrays
1501 4532 : IF (PRESENT(array_pot)) THEN
1502 22 : IF (ASSOCIATED(array_pot)) THEN
1503 0 : CPASSERT(SIZE(array_pot) == number)
1504 : ELSE
1505 66 : ALLOCATE (array_pot(number))
1506 : END IF
1507 66 : array_pot = 0.0_dp
1508 : END IF
1509 4532 : IF (PRESENT(array_kin)) THEN
1510 440 : IF (ASSOCIATED(array_kin)) THEN
1511 418 : CPASSERT(SIZE(array_kin) == number)
1512 : ELSE
1513 66 : ALLOCATE (array_kin(number))
1514 : END IF
1515 22856 : array_kin = akin
1516 : END IF
1517 4532 : DEALLOCATE (akin)
1518 4532 : END SUBROUTINE get_kin_energies
1519 :
1520 : ! **************************************************************************************************
1521 : !> \brief Calculates the temperatures of the regions when a thermostat is
1522 : !> applied
1523 : !> \param map_info ...
1524 : !> \param loc_num ...
1525 : !> \param glob_num ...
1526 : !> \param nkt ...
1527 : !> \param dof ...
1528 : !> \param para_env ...
1529 : !> \param temp_tot ...
1530 : !> \param array_temp ...
1531 : !> \par History generalized MI [07.2009]
1532 : !> \author Teodoro Laino [tlaino] - 10.2007 - University of Zurich
1533 : ! **************************************************************************************************
1534 274 : SUBROUTINE get_temperatures(map_info, loc_num, glob_num, nkt, dof, para_env, &
1535 : temp_tot, array_temp)
1536 : TYPE(map_info_type), POINTER :: map_info
1537 : INTEGER, INTENT(IN) :: loc_num, glob_num
1538 : REAL(dp), DIMENSION(:), INTENT(IN) :: nkt, dof
1539 : TYPE(mp_para_env_type), POINTER :: para_env
1540 : REAL(KIND=dp), INTENT(OUT) :: temp_tot
1541 : REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: array_temp
1542 :
1543 : INTEGER :: i, imap, imap2, n, number
1544 : REAL(KIND=dp) :: fdeg_of_free
1545 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: akin, deg_of_free
1546 :
1547 274 : number = glob_num
1548 822 : ALLOCATE (akin(number))
1549 822 : ALLOCATE (deg_of_free(number))
1550 35816 : akin = 0.0_dp
1551 35816 : deg_of_free = 0.0_dp
1552 18120 : DO n = 1, loc_num
1553 17846 : imap = map_info%index(n)
1554 17846 : imap2 = map_info%map_index(n)
1555 17846 : IF (nkt(n) == 0.0_dp) CYCLE
1556 17846 : deg_of_free(imap) = REAL(dof(n), KIND=dp)
1557 18120 : akin(imap) = map_info%s_kin(imap2)
1558 : END DO
1559 :
1560 : ! Handle the thermostat distribution
1561 274 : IF (map_info%dis_type == do_thermo_no_communication) THEN
1562 146 : CALL para_env%sum(akin)
1563 146 : CALL para_env%sum(deg_of_free)
1564 128 : ELSE IF (map_info%dis_type == do_thermo_communication) THEN
1565 22 : CALL communication_thermo_low1(akin, number, para_env)
1566 22 : CALL communication_thermo_low1(deg_of_free, number, para_env)
1567 : END IF
1568 35816 : temp_tot = SUM(akin)
1569 35816 : fdeg_of_free = SUM(deg_of_free)
1570 :
1571 274 : temp_tot = temp_tot/fdeg_of_free
1572 274 : temp_tot = cp_unit_from_cp2k(temp_tot, "K_temp")
1573 : ! Possibly give back temperatures of the full set of regions
1574 274 : IF (PRESENT(array_temp)) THEN
1575 274 : IF (ASSOCIATED(array_temp)) THEN
1576 0 : CPASSERT(SIZE(array_temp) == number)
1577 : ELSE
1578 822 : ALLOCATE (array_temp(number))
1579 : END IF
1580 35816 : DO i = 1, number
1581 35542 : array_temp(i) = akin(i)/deg_of_free(i)
1582 35816 : array_temp(i) = cp_unit_from_cp2k(array_temp(i), "K_temp")
1583 : END DO
1584 : END IF
1585 274 : DEALLOCATE (akin)
1586 274 : DEALLOCATE (deg_of_free)
1587 274 : END SUBROUTINE get_temperatures
1588 :
1589 : ! **************************************************************************************************
1590 : !> \brief Calculates energy associated with a thermostat
1591 : !> \param thermostat ...
1592 : !> \param thermostat_pot ...
1593 : !> \param thermostat_kin ...
1594 : !> \param para_env ...
1595 : !> \param array_pot ...
1596 : !> \param array_kin ...
1597 : !> \author Teodoro Laino [tlaino] - 10.2007 - University of Zurich
1598 : ! **************************************************************************************************
1599 55327 : SUBROUTINE get_thermostat_energies(thermostat, thermostat_pot, thermostat_kin, para_env, &
1600 : array_pot, array_kin)
1601 : TYPE(thermostat_type), POINTER :: thermostat
1602 : REAL(KIND=dp), INTENT(OUT) :: thermostat_pot, thermostat_kin
1603 : TYPE(mp_para_env_type), POINTER :: para_env
1604 : REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: array_pot, array_kin
1605 :
1606 : INTEGER :: i
1607 55327 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: thermo_energy
1608 :
1609 55327 : thermostat_pot = 0.0_dp
1610 55327 : thermostat_kin = 0.0_dp
1611 55327 : IF (ASSOCIATED(thermostat)) THEN
1612 14468 : IF (thermostat%type_of_thermostat == do_thermo_nose) THEN
1613 : ! Energy associated with the Nose-Hoover thermostat
1614 10338 : CPASSERT(ASSOCIATED(thermostat%nhc))
1615 : CALL get_nhc_energies(thermostat%nhc, thermostat_pot, thermostat_kin, para_env, &
1616 10338 : array_pot, array_kin)
1617 4130 : ELSE IF (thermostat%type_of_thermostat == do_thermo_csvr) THEN
1618 : ! Energy associated with the CSVR thermostat
1619 3706 : CPASSERT(ASSOCIATED(thermostat%csvr))
1620 11118 : ALLOCATE (thermo_energy(thermostat%csvr%loc_num_csvr))
1621 65108 : DO i = 1, thermostat%csvr%loc_num_csvr
1622 65108 : thermo_energy(i) = thermostat%csvr%nvt(i)%thermostat_energy
1623 : END DO
1624 : CALL get_kin_energies(thermostat%csvr%map_info, thermostat%csvr%loc_num_csvr, &
1625 : thermostat%csvr%glob_num_csvr, thermo_energy, &
1626 3706 : thermostat_kin, para_env, array_pot, array_kin)
1627 3706 : DEALLOCATE (thermo_energy)
1628 :
1629 424 : ELSE IF (thermostat%type_of_thermostat == do_thermo_gle) THEN
1630 : ! Energy associated with the GLE thermostat
1631 408 : CPASSERT(ASSOCIATED(thermostat%gle))
1632 1224 : ALLOCATE (thermo_energy(thermostat%gle%loc_num_gle))
1633 66504 : DO i = 1, thermostat%gle%loc_num_gle
1634 66504 : thermo_energy(i) = thermostat%gle%nvt(i)%thermostat_energy
1635 : END DO
1636 : CALL get_kin_energies(thermostat%gle%map_info, thermostat%gle%loc_num_gle, &
1637 : thermostat%gle%glob_num_gle, thermo_energy, &
1638 408 : thermostat_kin, para_env, array_pot, array_kin)
1639 408 : DEALLOCATE (thermo_energy)
1640 :
1641 : ![NB] nothing to do for Ad-Langevin?
1642 :
1643 : END IF
1644 : END IF
1645 :
1646 55327 : END SUBROUTINE get_thermostat_energies
1647 :
1648 : ! **************************************************************************************************
1649 : !> \brief Calculates the temperatures for each region associated to a thermostat
1650 : !> \param thermostat ...
1651 : !> \param tot_temperature ...
1652 : !> \param para_env ...
1653 : !> \param array_temp ...
1654 : !> \author Teodoro Laino [tlaino] - 02.2008 - University of Zurich
1655 : ! **************************************************************************************************
1656 274 : SUBROUTINE get_region_temperatures(thermostat, tot_temperature, para_env, array_temp)
1657 : TYPE(thermostat_type), POINTER :: thermostat
1658 : REAL(KIND=dp), INTENT(OUT) :: tot_temperature
1659 : TYPE(mp_para_env_type), POINTER :: para_env
1660 : REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: array_temp
1661 :
1662 : INTEGER :: i
1663 274 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: dof, nkt
1664 :
1665 274 : IF (ASSOCIATED(thermostat)) THEN
1666 274 : IF (thermostat%type_of_thermostat == do_thermo_nose) THEN
1667 : ! Energy associated with the Nose-Hoover thermostat
1668 252 : CPASSERT(ASSOCIATED(thermostat%nhc))
1669 756 : ALLOCATE (nkt(thermostat%nhc%loc_num_nhc))
1670 756 : ALLOCATE (dof(thermostat%nhc%loc_num_nhc))
1671 18054 : DO i = 1, thermostat%nhc%loc_num_nhc
1672 17802 : nkt(i) = thermostat%nhc%nvt(1, i)%nkt
1673 18054 : dof(i) = REAL(thermostat%nhc%nvt(1, i)%degrees_of_freedom, KIND=dp)
1674 : END DO
1675 : CALL get_temperatures(thermostat%nhc%map_info, thermostat%nhc%loc_num_nhc, &
1676 252 : thermostat%nhc%glob_num_nhc, nkt, dof, para_env, tot_temperature, array_temp)
1677 252 : DEALLOCATE (nkt)
1678 252 : DEALLOCATE (dof)
1679 22 : ELSE IF (thermostat%type_of_thermostat == do_thermo_csvr) THEN
1680 : ! Energy associated with the CSVR thermostat
1681 22 : CPASSERT(ASSOCIATED(thermostat%csvr))
1682 :
1683 66 : ALLOCATE (nkt(thermostat%csvr%loc_num_csvr))
1684 66 : ALLOCATE (dof(thermostat%csvr%loc_num_csvr))
1685 66 : DO i = 1, thermostat%csvr%loc_num_csvr
1686 44 : nkt(i) = thermostat%csvr%nvt(i)%nkt
1687 66 : dof(i) = REAL(thermostat%csvr%nvt(i)%degrees_of_freedom, KIND=dp)
1688 : END DO
1689 : CALL get_temperatures(thermostat%csvr%map_info, thermostat%csvr%loc_num_csvr, &
1690 22 : thermostat%csvr%glob_num_csvr, nkt, dof, para_env, tot_temperature, array_temp)
1691 22 : DEALLOCATE (nkt)
1692 22 : DEALLOCATE (dof)
1693 0 : ELSE IF (thermostat%type_of_thermostat == do_thermo_al) THEN
1694 : ! Energy associated with the AD_LANGEVIN thermostat
1695 0 : CPASSERT(ASSOCIATED(thermostat%al))
1696 :
1697 0 : ALLOCATE (nkt(thermostat%al%loc_num_al))
1698 0 : ALLOCATE (dof(thermostat%al%loc_num_al))
1699 0 : DO i = 1, thermostat%al%loc_num_al
1700 0 : nkt(i) = thermostat%al%nvt(i)%nkt
1701 0 : dof(i) = REAL(thermostat%al%nvt(i)%degrees_of_freedom, KIND=dp)
1702 : END DO
1703 : CALL get_temperatures(thermostat%al%map_info, thermostat%al%loc_num_al, &
1704 0 : thermostat%al%glob_num_al, nkt, dof, para_env, tot_temperature, array_temp)
1705 0 : DEALLOCATE (nkt)
1706 0 : DEALLOCATE (dof)
1707 0 : ELSE IF (thermostat%type_of_thermostat == do_thermo_gle) THEN
1708 : ! Energy associated with the GLE thermostat
1709 0 : CPASSERT(ASSOCIATED(thermostat%gle))
1710 :
1711 0 : ALLOCATE (nkt(thermostat%gle%loc_num_gle))
1712 0 : ALLOCATE (dof(thermostat%gle%loc_num_gle))
1713 0 : DO i = 1, thermostat%gle%loc_num_gle
1714 0 : nkt(i) = thermostat%gle%nvt(i)%nkt
1715 0 : dof(i) = REAL(thermostat%gle%nvt(i)%degrees_of_freedom, KIND=dp)
1716 : END DO
1717 : CALL get_temperatures(thermostat%gle%map_info, thermostat%gle%loc_num_gle, &
1718 0 : thermostat%gle%glob_num_gle, nkt, dof, para_env, tot_temperature, array_temp)
1719 0 : DEALLOCATE (nkt)
1720 0 : DEALLOCATE (dof)
1721 : END IF
1722 : END IF
1723 :
1724 274 : END SUBROUTINE get_region_temperatures
1725 :
1726 : ! **************************************************************************************************
1727 : !> \brief Prints status of all thermostats during an MD run
1728 : !> \param thermostats ...
1729 : !> \param para_env ...
1730 : !> \param my_pos ...
1731 : !> \param my_act ...
1732 : !> \param itimes ...
1733 : !> \param time ...
1734 : !> \author Teodoro Laino [tlaino] - 02.2008 - University of Zurich
1735 : ! **************************************************************************************************
1736 42149 : SUBROUTINE print_thermostats_status(thermostats, para_env, my_pos, my_act, itimes, time)
1737 : TYPE(thermostats_type), POINTER :: thermostats
1738 : TYPE(mp_para_env_type), POINTER :: para_env
1739 : CHARACTER(LEN=default_string_length) :: my_pos, my_act
1740 : INTEGER, INTENT(IN) :: itimes
1741 : REAL(KIND=dp), INTENT(IN) :: time
1742 :
1743 42149 : IF (ASSOCIATED(thermostats)) THEN
1744 10480 : IF (ASSOCIATED(thermostats%thermostat_part)) THEN
1745 10146 : CALL print_thermostat_status(thermostats%thermostat_part, para_env, my_pos, my_act, itimes, time)
1746 : END IF
1747 10480 : IF (ASSOCIATED(thermostats%thermostat_shell)) THEN
1748 830 : CALL print_thermostat_status(thermostats%thermostat_shell, para_env, my_pos, my_act, itimes, time)
1749 : END IF
1750 10480 : IF (ASSOCIATED(thermostats%thermostat_coef)) THEN
1751 0 : CALL print_thermostat_status(thermostats%thermostat_coef, para_env, my_pos, my_act, itimes, time)
1752 : END IF
1753 10480 : IF (ASSOCIATED(thermostats%thermostat_baro)) THEN
1754 2302 : CALL print_thermostat_status(thermostats%thermostat_baro, para_env, my_pos, my_act, itimes, time)
1755 : END IF
1756 : END IF
1757 42149 : END SUBROUTINE print_thermostats_status
1758 :
1759 : ! **************************************************************************************************
1760 : !> \brief Prints status of a specific thermostat
1761 : !> \param thermostat ...
1762 : !> \param para_env ...
1763 : !> \param my_pos ...
1764 : !> \param my_act ...
1765 : !> \param itimes ...
1766 : !> \param time ...
1767 : !> \author Teodoro Laino [tlaino] - 02.2008 - University of Zurich
1768 : ! **************************************************************************************************
1769 13278 : SUBROUTINE print_thermostat_status(thermostat, para_env, my_pos, my_act, itimes, time)
1770 : TYPE(thermostat_type), POINTER :: thermostat
1771 : TYPE(mp_para_env_type), POINTER :: para_env
1772 : CHARACTER(LEN=default_string_length) :: my_pos, my_act
1773 : INTEGER, INTENT(IN) :: itimes
1774 : REAL(KIND=dp), INTENT(IN) :: time
1775 :
1776 : INTEGER :: i, unit
1777 : LOGICAL :: new_file
1778 : REAL(KIND=dp) :: thermo_kin, thermo_pot, tot_temperature
1779 13278 : REAL(KIND=dp), DIMENSION(:), POINTER :: array_kin, array_pot, array_temp
1780 : TYPE(cp_logger_type), POINTER :: logger
1781 : TYPE(section_vals_type), POINTER :: print_key
1782 :
1783 13278 : NULLIFY (logger, print_key, array_pot, array_kin, array_temp)
1784 26556 : logger => cp_get_default_logger()
1785 :
1786 13278 : IF (ASSOCIATED(thermostat)) THEN
1787 : ! Print Energies
1788 13278 : print_key => section_vals_get_subs_vals(thermostat%section, "PRINT%ENERGY")
1789 13278 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1790 296 : CALL get_thermostat_energies(thermostat, thermo_pot, thermo_kin, para_env, array_pot, array_kin)
1791 : unit = cp_print_key_unit_nr(logger, thermostat%section, "PRINT%ENERGY", &
1792 : extension="."//TRIM(thermostat%label)//".tener", file_position=my_pos, &
1793 296 : file_action=my_act, is_new_file=new_file)
1794 296 : IF (unit > 0) THEN
1795 148 : IF (new_file) THEN
1796 13 : WRITE (unit, '(A)') "# Thermostat Potential and Kinetic Energies - Total and per Region"
1797 13 : WRITE (unit, '("#",3X,A,2X,A,13X,A,10X,A)') "Step Nr.", "Time[fs]", "Kin.[a.u.]", "Pot.[a.u.]"
1798 : END IF
1799 148 : WRITE (UNIT=unit, FMT="(I8, F12.3,6X,2F20.10)") itimes, time*femtoseconds, thermo_kin, thermo_pot
1800 148 : WRITE (unit, '(A,4F20.10)') "# KINETIC ENERGY REGIONS: ", array_kin(1:MIN(4, SIZE(array_kin)))
1801 4499 : DO i = 5, SIZE(array_kin), 4
1802 4499 : WRITE (UNIT=unit, FMT='("#",25X,4F20.10)') array_kin(i:MIN(i + 3, SIZE(array_kin)))
1803 : END DO
1804 148 : WRITE (unit, '(A,4F20.10)') "# POTENT. ENERGY REGIONS: ", array_pot(1:MIN(4, SIZE(array_pot)))
1805 4499 : DO i = 5, SIZE(array_pot), 4
1806 4499 : WRITE (UNIT=unit, FMT='("#",25X,4F20.10)') array_pot(i:MIN(i + 3, SIZE(array_pot)))
1807 : END DO
1808 148 : CALL m_flush(unit)
1809 : END IF
1810 296 : DEALLOCATE (array_kin)
1811 296 : DEALLOCATE (array_pot)
1812 296 : CALL cp_print_key_finished_output(unit, logger, thermostat%section, "PRINT%ENERGY")
1813 : END IF
1814 : ! Print Temperatures of the regions
1815 13278 : print_key => section_vals_get_subs_vals(thermostat%section, "PRINT%TEMPERATURE")
1816 13278 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1817 274 : CALL get_region_temperatures(thermostat, tot_temperature, para_env, array_temp)
1818 : unit = cp_print_key_unit_nr(logger, thermostat%section, "PRINT%TEMPERATURE", &
1819 : extension="."//TRIM(thermostat%label)//".temp", file_position=my_pos, &
1820 274 : file_action=my_act, is_new_file=new_file)
1821 274 : IF (unit > 0) THEN
1822 137 : IF (new_file) THEN
1823 12 : WRITE (unit, '(A)') "# Temperature Total and per Region"
1824 12 : WRITE (unit, '("#",3X,A,2X,A,10X,A)') "Step Nr.", "Time[fs]", "Temp.[K]"
1825 : END IF
1826 137 : WRITE (UNIT=unit, FMT="(I8, F12.3,3X,F20.10)") itimes, time*femtoseconds, tot_temperature
1827 137 : WRITE (unit, '(A,I10)') "# TEMPERATURE REGIONS: ", SIZE(array_temp)
1828 4625 : DO i = 1, SIZE(array_temp), 4
1829 4625 : WRITE (UNIT=unit, FMT='("#",22X,4F20.10)') array_temp(i:MIN(i + 3, SIZE(array_temp)))
1830 : END DO
1831 137 : CALL m_flush(unit)
1832 : END IF
1833 274 : DEALLOCATE (array_temp)
1834 274 : CALL cp_print_key_finished_output(unit, logger, thermostat%section, "PRINT%TEMPERATURE")
1835 : END IF
1836 : END IF
1837 13278 : END SUBROUTINE print_thermostat_status
1838 :
1839 : ! **************************************************************************************************
1840 : !> \brief Handles the communication for thermostats (1D array)
1841 : !> \param array ...
1842 : !> \param number ...
1843 : !> \param para_env ...
1844 : !> \author Teodoro Laino [tlaino] - University of Zurich 11.2007
1845 : ! **************************************************************************************************
1846 12498 : SUBROUTINE communication_thermo_low1(array, number, para_env)
1847 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: array
1848 : INTEGER, INTENT(IN) :: number
1849 : TYPE(mp_para_env_type), POINTER :: para_env
1850 :
1851 : INTEGER :: i, icheck, ncheck
1852 12498 : REAL(KIND=dp), DIMENSION(:), POINTER :: work, work2
1853 :
1854 37494 : ALLOCATE (work(para_env%num_pe))
1855 26028 : DO i = 1, number
1856 40590 : work = 0.0_dp
1857 13530 : work(para_env%mepos + 1) = array(i)
1858 67650 : CALL para_env%sum(work)
1859 40590 : ncheck = COUNT(work /= 0.0_dp)
1860 13530 : array(i) = 0.0_dp
1861 26028 : IF (ncheck /= 0) THEN
1862 38202 : ALLOCATE (work2(ncheck))
1863 12734 : ncheck = 0
1864 38202 : DO icheck = 1, para_env%num_pe
1865 38202 : IF (work(icheck) /= 0.0_dp) THEN
1866 25060 : ncheck = ncheck + 1
1867 25060 : work2(ncheck) = work(icheck)
1868 : END IF
1869 : END DO
1870 12734 : CPASSERT(ncheck == SIZE(work2))
1871 37794 : CPASSERT(ALL(work2 == work2(1)))
1872 :
1873 12734 : array(i) = work2(1)
1874 12734 : DEALLOCATE (work2)
1875 : END IF
1876 : END DO
1877 12498 : DEALLOCATE (work)
1878 12498 : END SUBROUTINE communication_thermo_low1
1879 :
1880 : ! **************************************************************************************************
1881 : !> \brief Handles the communication for thermostats (2D array)
1882 : !> \param array ...
1883 : !> \param number1 ...
1884 : !> \param number2 ...
1885 : !> \param para_env ...
1886 : !> \author Teodoro Laino [tlaino] - University of Zurich 11.2007
1887 : ! **************************************************************************************************
1888 250 : SUBROUTINE communication_thermo_low2(array, number1, number2, para_env)
1889 : INTEGER, DIMENSION(:, :), INTENT(INOUT) :: array
1890 : INTEGER, INTENT(IN) :: number1, number2
1891 : TYPE(mp_para_env_type), POINTER :: para_env
1892 :
1893 : INTEGER :: i, icheck, j, ncheck
1894 250 : INTEGER, DIMENSION(:, :), POINTER :: work, work2
1895 :
1896 1000 : ALLOCATE (work(number1, para_env%num_pe))
1897 606 : DO i = 1, number2
1898 309364 : work = 0
1899 154504 : work(:, para_env%mepos + 1) = array(:, i)
1900 618372 : CALL para_env%sum(work)
1901 356 : ncheck = 0
1902 1068 : DO j = 1, para_env%num_pe
1903 23584 : IF (ANY(work(:, j) /= 0)) THEN
1904 660 : ncheck = ncheck + 1
1905 : END IF
1906 : END DO
1907 154504 : array(:, i) = 0
1908 606 : IF (ncheck /= 0) THEN
1909 1424 : ALLOCATE (work2(number1, ncheck))
1910 356 : ncheck = 0
1911 1068 : DO icheck = 1, para_env%num_pe
1912 23584 : IF (ANY(work(:, icheck) /= 0)) THEN
1913 660 : ncheck = ncheck + 1
1914 572880 : work2(:, ncheck) = work(:, icheck)
1915 : END IF
1916 : END DO
1917 356 : CPASSERT(ncheck == SIZE(work2, 2))
1918 1016 : DO j = 1, ncheck
1919 286796 : CPASSERT(ALL(work2(:, j) == work2(:, 1)))
1920 : END DO
1921 154504 : array(:, i) = work2(:, 1)
1922 356 : DEALLOCATE (work2)
1923 : END IF
1924 : END DO
1925 250 : DEALLOCATE (work)
1926 250 : END SUBROUTINE communication_thermo_low2
1927 :
1928 : END MODULE thermostat_utils
|