(git:374b731)
Loading...
Searching...
No Matches
thermostat_mapping.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \author Teodoro Laino [tlaino] - 10.2007 - University of Zurich
10! **************************************************************************************************
12
13 USE cell_types, ONLY: use_perd_x,&
28 USE kinds, ONLY: dp
37 USE molecule_types, ONLY: get_molecule,&
40 USE simpar_types, ONLY: simpar_type
41 USE util, ONLY: locate,&
42 sort
43#include "../../base/base_uses.f90"
44
45 IMPLICIT NONE
46
47 PUBLIC :: thermostat_mapping_region, &
50
51 PRIVATE
52 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'thermostat_mapping'
53
54CONTAINS
55! **************************************************************************************************
56!> \brief Main general setup for adiabatic thermostat regions (Nose only)
57!> \param map_info ...
58!> \param deg_of_freedom ...
59!> \param massive_atom_list ...
60!> \param molecule_kind_set ...
61!> \param local_molecules ...
62!> \param molecule_set ...
63!> \param para_env ...
64!> \param natoms_local ...
65!> \param simpar ...
66!> \param number ...
67!> \param region ...
68!> \param gci ...
69!> \param shell ...
70!> \param map_loc_thermo_gen ...
71!> \param sum_of_thermostats ...
72!> \author CJM - PNNL
73! **************************************************************************************************
74 SUBROUTINE adiabatic_mapping_region(map_info, deg_of_freedom, massive_atom_list, &
75 molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, simpar, &
76 number, region, gci, shell, map_loc_thermo_gen, sum_of_thermostats)
77
78 TYPE(map_info_type), POINTER :: map_info
79 INTEGER, DIMENSION(:), POINTER :: deg_of_freedom, massive_atom_list
80 TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
81 TYPE(distribution_1d_type), POINTER :: local_molecules
82 TYPE(molecule_type), POINTER :: molecule_set(:)
83 TYPE(mp_para_env_type), POINTER :: para_env
84 INTEGER, INTENT(OUT) :: natoms_local
85 TYPE(simpar_type), POINTER :: simpar
86 INTEGER, INTENT(INOUT) :: number
87 INTEGER, INTENT(IN) :: region
88 TYPE(global_constraint_type), POINTER :: gci
89 LOGICAL, INTENT(IN) :: shell
90 INTEGER, DIMENSION(:), POINTER :: map_loc_thermo_gen
91 INTEGER, INTENT(INOUT) :: sum_of_thermostats
92
93 CHARACTER(LEN=*), PARAMETER :: routinen = 'adiabatic_mapping_region'
94
95 INTEGER :: handle, nkind, nmol_local, nsize, &
96 number_of_thermostats
97 INTEGER, DIMENSION(:), POINTER :: const_mol, tot_const
98 INTEGER, DIMENSION(:, :), POINTER :: point
99
100 CALL timeset(routinen, handle)
101
102 NULLIFY (const_mol, tot_const, point)
103 cpassert(.NOT. ASSOCIATED(deg_of_freedom))
104 cpassert(.NOT. ASSOCIATED(massive_atom_list))
105
106 nkind = SIZE(molecule_kind_set)
107 CALL adiabatic_region_evaluate(map_info%dis_type, natoms_local, nmol_local, &
108 const_mol, tot_const, point, local_molecules, molecule_kind_set, molecule_set, &
109 simpar, shell)
110
111 ! Now we can allocate the target array s_kin and p_kin..
112 SELECT CASE (region)
114 nsize = number
115 CASE DEFAULT
116 ! STOP PROGRAM
117 END SELECT
118 ALLOCATE (map_info%s_kin(nsize))
119 ALLOCATE (map_info%v_scale(nsize))
120 ALLOCATE (map_info%p_kin(3, natoms_local))
121 ALLOCATE (map_info%p_scale(3, natoms_local))
122! nullify thermostat pointers
123 ! Allocate index array to 1
124 ALLOCATE (map_info%index(1))
125 ALLOCATE (map_info%map_index(1))
126 ALLOCATE (deg_of_freedom(1))
127
128 CALL massive_list_generate(molecule_set, molecule_kind_set, &
129 local_molecules, para_env, massive_atom_list, region, shell)
130
131 CALL adiabatic_mapping_region_low(region, map_info, nkind, point, &
132 deg_of_freedom, local_molecules, const_mol, massive_atom_list, &
133 tot_const, molecule_set, number_of_thermostats, shell, gci, &
134 map_loc_thermo_gen)
135
136 number = number_of_thermostats
137 sum_of_thermostats = number
138 CALL para_env%sum(sum_of_thermostats)
139
140! check = (number==number_of_thermostats)
141! CPPrecondition(check,cp_fatal_level,routineP,failure)
142 DEALLOCATE (const_mol)
143 DEALLOCATE (tot_const)
144 DEALLOCATE (point)
145
146 CALL timestop(handle)
147
148 END SUBROUTINE adiabatic_mapping_region
149
150! **************************************************************************************************
151!> \brief Performs the real mapping for the thermostat region
152!> \param region ...
153!> \param map_info ...
154!> \param nkind ...
155!> \param point ...
156!> \param deg_of_freedom ...
157!> \param local_molecules ...
158!> \param const_mol ...
159!> \param massive_atom_list ...
160!> \param tot_const ...
161!> \param molecule_set ...
162!> \param ntherm ...
163!> \param shell ...
164!> \param gci ...
165!> \param map_loc_thermo_gen ...
166!> \author Teodoro Laino [tlaino] - University of Zurich - 10.2007
167! **************************************************************************************************
168 SUBROUTINE adiabatic_mapping_region_low(region, map_info, nkind, point, &
169 deg_of_freedom, local_molecules, const_mol, massive_atom_list, tot_const, &
170 molecule_set, ntherm, shell, gci, map_loc_thermo_gen)
171
172 INTEGER, INTENT(IN) :: region
173 TYPE(map_info_type), POINTER :: map_info
174 INTEGER :: nkind
175 INTEGER, DIMENSION(:, :), POINTER :: point
176 INTEGER, DIMENSION(:), POINTER :: deg_of_freedom
177 TYPE(distribution_1d_type), POINTER :: local_molecules
178 INTEGER, DIMENSION(:), POINTER :: const_mol, massive_atom_list, tot_const
179 TYPE(molecule_type), POINTER :: molecule_set(:)
180 INTEGER, INTENT(OUT) :: ntherm
181 LOGICAL, INTENT(IN) :: shell
182 TYPE(global_constraint_type), POINTER :: gci
183 INTEGER, DIMENSION(:), POINTER :: map_loc_thermo_gen
184
185 CHARACTER(LEN=*), PARAMETER :: routinen = 'adiabatic_mapping_region_low'
186
187 INTEGER :: first_atom, first_shell, glob_therm_num, handle, icount, ielement, ii, ikind, &
188 imol, imol_local, ipart, jj, k, kk, last_atom, last_shell, nglob_cns, nmol_local, number
189 LOGICAL :: check, global_constraints, &
190 have_thermostat
191 REAL(dp), SAVE, TARGET :: unity
192 TYPE(molecule_type), POINTER :: molecule
193
194 CALL timeset(routinen, handle)
195 unity = 1.0_dp
196 global_constraints = ASSOCIATED(gci)
197 deg_of_freedom = 0
198 icount = 0
199 number = 0
200 ntherm = 0
201 nglob_cns = 0
202 IF (global_constraints) nglob_cns = gci%ntot - gci%nrestraint
203 IF (region == do_region_global) THEN
204 ! Global Region
205 check = (map_info%dis_type == do_thermo_communication)
206 cpassert(check)
207 DO ikind = 1, nkind
208 DO jj = point(1, ikind), point(2, ikind)
209 IF (map_loc_thermo_gen(jj) /= huge(0)) THEN
210 DO ii = 1, 3
211 map_info%p_kin(ii, jj)%point => map_info%s_kin(1)
212 map_info%p_scale(ii, jj)%point => map_info%v_scale(1)
213 END DO
214 ELSE
215 DO ii = 1, 3
216 NULLIFY (map_info%p_kin(ii, jj)%point)
217 map_info%p_scale(ii, jj)%point => unity
218 END DO
219 END IF
220 END DO
221 deg_of_freedom(1) = deg_of_freedom(1) + tot_const(ikind)
222 map_info%index(1) = 1
223 map_info%map_index(1) = 1
224 number = 1
225 END DO
226 deg_of_freedom(1) = deg_of_freedom(1) + nglob_cns
227 ELSE IF (region == do_region_molecule) THEN
228 ! Molecular Region
229 IF (map_info%dis_type == do_thermo_no_communication) THEN
230 ! This is the standard case..
231 DO ikind = 1, nkind
232 nmol_local = local_molecules%n_el(ikind)
233 DO imol_local = 1, nmol_local
234 imol = local_molecules%list(ikind)%array(imol_local)
235 number = number + 1
236 have_thermostat = .true.
237! determine if the local molecule belongs to a thermostat
238 DO kk = point(1, number), point(2, number)
239 ! WRITE ( *, * ) 'kk', size(map_loc_thermo_gen), kk, map_loc_thermo_gen ( kk )
240 IF (map_loc_thermo_gen(kk) == huge(0)) THEN
241 have_thermostat = .false.
242 EXIT
243 END IF
244 END DO
245! If molecule has a thermostat, then map
246 IF (have_thermostat) THEN
247! glob_therm_num is the global thermostat number attached to the local molecule
248! We can test to make sure all atoms in the local molecule belong to the same
249! global thermostat as a way to detect errors.
250 glob_therm_num = map_loc_thermo_gen(point(1, number))
251 ntherm = ntherm + 1
252 CALL reallocate(map_info%index, 1, ntherm)
253 CALL reallocate(map_info%map_index, 1, ntherm)
254 CALL reallocate(deg_of_freedom, 1, ntherm)
255 map_info%index(ntherm) = glob_therm_num
256 map_info%map_index(ntherm) = ntherm
257 deg_of_freedom(ntherm) = const_mol(number)
258 DO kk = point(1, number), point(2, number)
259 DO jj = 1, 3
260 map_info%p_kin(jj, kk)%point => map_info%s_kin(ntherm)
261 map_info%p_scale(jj, kk)%point => map_info%v_scale(ntherm)
262 END DO
263 END DO
264! If molecule has no thermostat, then nullify pointers to that atom
265 ELSE
266 DO kk = point(1, number), point(2, number)
267 DO jj = 1, 3
268 NULLIFY (map_info%p_kin(jj, kk)%point)
269 map_info%p_scale(jj, kk)%point => unity
270 END DO
271 END DO
272 END IF
273 END DO
274 END DO
275 ELSE IF (map_info%dis_type == do_thermo_communication) THEN
276 ! This case is quite rare and happens only when we have one molecular
277 ! kind and one molecule..
278 cpassert(nkind == 1)
279 number = number + 1
280 ntherm = ntherm + 1
281 map_info%index(ntherm) = ntherm
282 map_info%map_index(ntherm) = ntherm
283 deg_of_freedom(ntherm) = deg_of_freedom(ntherm) + tot_const(nkind)
284 DO kk = point(1, nkind), point(2, nkind)
285 IF (map_loc_thermo_gen(kk) /= huge(0)) THEN
286 DO jj = 1, 3
287 map_info%p_kin(jj, kk)%point => map_info%s_kin(ntherm)
288 map_info%p_scale(jj, kk)%point => map_info%v_scale(ntherm)
289 END DO
290 ELSE
291 END IF
292 DO jj = 1, 3
293 NULLIFY (map_info%p_kin(jj, kk)%point)
294 map_info%p_scale(jj, kk)%point => unity
295 END DO
296 END DO
297 ELSE
298 cpabort("")
299 END IF
300 IF (nglob_cns /= 0) THEN
301 cpabort("Molecular thermostats with global constraints are impossible!")
302 END IF
303 ELSE IF (region == do_region_massive) THEN
304 ! Massive Region
305 check = (map_info%dis_type == do_thermo_no_communication)
306 cpassert(check)
307 DO ikind = 1, nkind
308 nmol_local = local_molecules%n_el(ikind)
309 DO imol_local = 1, nmol_local
310 icount = icount + 1
311 imol = local_molecules%list(ikind)%array(imol_local)
312 molecule => molecule_set(imol)
313 CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom, &
314 first_shell=first_shell, last_shell=last_shell)
315 IF (shell) THEN
316 first_atom = first_shell
317 last_atom = last_shell
318 ELSE
319 IF ((tot_const(icount) > 0) .OR. (nglob_cns /= 0)) THEN
320 cpabort("Massive thermostats with constraints are impossible!")
321 END IF
322 END IF
323 k = 0
324
325 have_thermostat = .true.
326 DO ii = point(1, icount), point(2, icount)
327 IF (map_loc_thermo_gen(ii) /= 1) THEN
328 have_thermostat = .false.
329 EXIT
330 END IF
331 END DO
332
333 IF (have_thermostat) THEN
334 DO ii = point(1, icount), point(2, icount)
335 ipart = first_atom + k
336 ielement = locate(massive_atom_list, ipart)
337 k = k + 1
338 DO jj = 1, 3
339 ntherm = ntherm + 1
340 CALL reallocate(map_info%index, 1, ntherm)
341 CALL reallocate(map_info%map_index, 1, ntherm)
342 map_info%index(ntherm) = (ielement - 1)*3 + jj
343 map_info%map_index(ntherm) = ntherm
344 map_info%p_kin(jj, ii)%point => map_info%s_kin(ntherm)
345 map_info%p_scale(jj, ii)%point => map_info%v_scale(ntherm)
346 END DO
347 END DO
348 ELSE
349 DO ii = point(1, icount), point(2, icount)
350 DO jj = 1, 3
351 NULLIFY (map_info%p_kin(jj, ii)%point)
352 map_info%p_scale(jj, ii)%point => unity
353 END DO
354 END DO
355 END IF
356 IF (first_atom + k - 1 /= last_atom) THEN
357 cpabort("Inconsistent mapping of particles")
358 END IF
359 END DO
360 END DO
361 ELSE
362 cpabort("Invalid region!")
363 END IF
364
365 CALL timestop(handle)
366
367 END SUBROUTINE adiabatic_mapping_region_low
368
369! **************************************************************************************************
370!> \brief creates the mapping between the system and the thermostats
371!> \param dis_type ...
372!> \param natoms_local ...
373!> \param nmol_local ...
374!> \param const_mol ...
375!> \param tot_const ...
376!> \param point ...
377!> \param local_molecules ...
378!> \param molecule_kind_set ...
379!> \param molecule_set ...
380!> \param simpar ...
381!> \param shell ...
382!> \author Teodoro Laino [tlaino] - 10.2007 - University of Zurich
383! **************************************************************************************************
384 SUBROUTINE adiabatic_region_evaluate(dis_type, natoms_local, nmol_local, const_mol, &
385 tot_const, point, local_molecules, molecule_kind_set, molecule_set, simpar, shell)
386 INTEGER, INTENT(IN) :: dis_type
387 INTEGER, INTENT(OUT) :: natoms_local, nmol_local
388 INTEGER, DIMENSION(:), POINTER :: const_mol, tot_const
389 INTEGER, DIMENSION(:, :), POINTER :: point
390 TYPE(distribution_1d_type), POINTER :: local_molecules
391 TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
392 TYPE(molecule_type), POINTER :: molecule_set(:)
393 TYPE(simpar_type), POINTER :: simpar
394 LOGICAL, INTENT(IN) :: shell
395
396 CHARACTER(LEN=*), PARAMETER :: routinen = 'adiabatic_region_evaluate'
397
398 INTEGER :: atm_offset, first_atom, handle, icount, ikind, ilist, imol, imol_local, katom, &
399 last_atom, natom, nc, nfixd, nkind, nmol_per_kind, nmolecule, nshell
400 TYPE(fixd_constraint_type), DIMENSION(:), POINTER :: fixd_list
401 TYPE(molecule_kind_type), POINTER :: molecule_kind
402 TYPE(molecule_type), POINTER :: molecule
403
404 CALL timeset(routinen, handle)
405
406 natoms_local = 0
407 nmol_local = 0
408 nkind = SIZE(molecule_kind_set)
409 NULLIFY (fixd_list, molecule_kind, molecule)
410 ! Compute the TOTAL number of molecules and atoms on THIS PROC and
411 ! TOTAL number of molecules of IKIND on THIS PROC
412 DO ikind = 1, nkind
413 molecule_kind => molecule_kind_set(ikind)
414 CALL get_molecule_kind(molecule_kind, natom=natom, nshell=nshell)
415 IF (shell) THEN
416 IF (nshell /= 0) THEN
417 natoms_local = natoms_local + nshell*local_molecules%n_el(ikind)
418 nmol_local = nmol_local + local_molecules%n_el(ikind)
419 END IF
420 ELSE
421 natoms_local = natoms_local + natom*local_molecules%n_el(ikind)
422 nmol_local = nmol_local + local_molecules%n_el(ikind)
423 END IF
424 END DO
425
426 cpassert(.NOT. ASSOCIATED(const_mol))
427 cpassert(.NOT. ASSOCIATED(tot_const))
428 cpassert(.NOT. ASSOCIATED(point))
429 IF (dis_type == do_thermo_no_communication) THEN
430 ALLOCATE (const_mol(nmol_local))
431 ALLOCATE (tot_const(nmol_local))
432 ALLOCATE (point(2, nmol_local))
433
434 point(:, :) = 0
435 atm_offset = 0
436 icount = 0
437 DO ikind = 1, nkind
438 nmol_per_kind = local_molecules%n_el(ikind)
439 molecule_kind => molecule_kind_set(ikind)
440 CALL get_molecule_kind(molecule_kind, nconstraint=nc, natom=natom, &
441 fixd_list=fixd_list, nshell=nshell)
442 IF (shell) natom = nshell
443 DO imol_local = 1, nmol_per_kind
444 icount = icount + 1
445 point(1, icount) = atm_offset + 1
446 point(2, icount) = atm_offset + natom
447 IF (.NOT. shell) THEN
448 ! nc keeps track of all constraints but not fixed ones..
449 ! Let's identify fixed atoms for this molecule
450 nfixd = 0
451 imol = local_molecules%list(ikind)%array(imol_local)
452 molecule => molecule_set(imol)
453 CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
454 IF (ASSOCIATED(fixd_list)) THEN
455 DO katom = first_atom, last_atom
456 DO ilist = 1, SIZE(fixd_list)
457 IF ((katom == fixd_list(ilist)%fixd) .AND. &
458 (.NOT. fixd_list(ilist)%restraint%active)) THEN
459 SELECT CASE (fixd_list(ilist)%itype)
461 nfixd = nfixd + 1
463 nfixd = nfixd + 2
464 CASE (use_perd_xyz)
465 nfixd = nfixd + 3
466 END SELECT
467 END IF
468 END DO
469 END DO
470 END IF
471 const_mol(icount) = nc + nfixd
472 tot_const(icount) = const_mol(icount)
473 END IF
474 atm_offset = point(2, icount)
475 END DO
476 END DO
477 ELSE IF (dis_type == do_thermo_communication) THEN
478 ALLOCATE (const_mol(nkind))
479 ALLOCATE (tot_const(nkind))
480 ALLOCATE (point(2, nkind))
481 point(:, :) = 0
482 atm_offset = 0
483 ! nc keeps track of all constraints but not fixed ones..
484 DO ikind = 1, nkind
485 nmol_per_kind = local_molecules%n_el(ikind)
486 molecule_kind => molecule_kind_set(ikind)
487 CALL get_molecule_kind(molecule_kind, nconstraint=nc, natom=natom, &
488 nmolecule=nmolecule, nconstraint_fixd=nfixd, nshell=nshell)
489 IF (shell) natom = nshell
490 IF (.NOT. shell) THEN
491 const_mol(ikind) = nc
492 ! Let's consider the fixed atoms only for the total number of constraints
493 ! in case we are in REPLICATED/INTERACTING thermostats
494 tot_const(ikind) = const_mol(ikind)*nmolecule + nfixd
495 END IF
496 point(1, ikind) = atm_offset + 1
497 point(2, ikind) = atm_offset + natom*nmol_per_kind
498 atm_offset = point(2, ikind)
499 END DO
500 END IF
501 IF ((.NOT. simpar%constraint) .OR. shell) THEN
502 const_mol = 0
503 tot_const = 0
504 END IF
505
506 CALL timestop(handle)
507
508 END SUBROUTINE adiabatic_region_evaluate
509
510! **************************************************************************************************
511!> \brief Main general setup thermostat regions (thermostat independent)
512!> \param map_info ...
513!> \param deg_of_freedom ...
514!> \param massive_atom_list ...
515!> \param molecule_kind_set ...
516!> \param local_molecules ...
517!> \param molecule_set ...
518!> \param para_env ...
519!> \param natoms_local ...
520!> \param simpar ...
521!> \param number ...
522!> \param region ...
523!> \param gci ...
524!> \param shell ...
525!> \param map_loc_thermo_gen ...
526!> \param sum_of_thermostats ...
527!> \author Teodoro Laino [tlaino] - University of Zurich - 10.2007
528! **************************************************************************************************
529 SUBROUTINE thermostat_mapping_region(map_info, deg_of_freedom, massive_atom_list, &
530 molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, simpar, &
531 number, region, gci, shell, map_loc_thermo_gen, sum_of_thermostats)
532
533 TYPE(map_info_type), POINTER :: map_info
534 INTEGER, DIMENSION(:), POINTER :: deg_of_freedom, massive_atom_list
535 TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
536 TYPE(distribution_1d_type), POINTER :: local_molecules
537 TYPE(molecule_type), POINTER :: molecule_set(:)
538 TYPE(mp_para_env_type), POINTER :: para_env
539 INTEGER, INTENT(OUT) :: natoms_local
540 TYPE(simpar_type), POINTER :: simpar
541 INTEGER, INTENT(IN) :: number, region
542 TYPE(global_constraint_type), POINTER :: gci
543 LOGICAL, INTENT(IN) :: shell
544 INTEGER, DIMENSION(:), POINTER :: map_loc_thermo_gen
545 INTEGER, INTENT(IN) :: sum_of_thermostats
546
547 CHARACTER(LEN=*), PARAMETER :: routinen = 'thermostat_mapping_region'
548
549 INTEGER :: handle, nkind, nmol_local, nsize, &
550 number_of_thermostats
551 INTEGER, DIMENSION(:), POINTER :: const_mol, tot_const
552 INTEGER, DIMENSION(:, :), POINTER :: point
553 LOGICAL :: check
554
555 CALL timeset(routinen, handle)
556
557 NULLIFY (const_mol, tot_const, point)
558 cpassert(.NOT. ASSOCIATED(deg_of_freedom))
559 cpassert(.NOT. ASSOCIATED(massive_atom_list))
560
561 nkind = SIZE(molecule_kind_set)
562 CALL mapping_region_evaluate(map_info%dis_type, natoms_local, nmol_local, &
563 const_mol, tot_const, point, local_molecules, molecule_kind_set, molecule_set, &
564 region, simpar, shell, map_loc_thermo_gen, sum_of_thermostats, para_env)
565
566 ! Now we can allocate the target array s_kin and p_kin..
567 SELECT CASE (region)
569 nsize = number
570 CASE (do_region_defined)
571 nsize = sum_of_thermostats
572 END SELECT
573 ALLOCATE (map_info%s_kin(nsize))
574 ALLOCATE (map_info%v_scale(nsize))
575 ALLOCATE (map_info%p_kin(3, natoms_local))
576 ALLOCATE (map_info%p_scale(3, natoms_local))
577 ! Allocate index array
578 ALLOCATE (map_info%index(number))
579 ALLOCATE (map_info%map_index(number))
580 ALLOCATE (deg_of_freedom(number))
581
582 CALL massive_list_generate(molecule_set, molecule_kind_set, &
583 local_molecules, para_env, massive_atom_list, region, shell)
584
585 CALL thermostat_mapping_region_low(region, map_info, nkind, point, &
586 deg_of_freedom, local_molecules, const_mol, massive_atom_list, &
587 tot_const, molecule_set, number_of_thermostats, shell, gci, &
588 map_loc_thermo_gen)
589
590 check = (number == number_of_thermostats)
591 cpassert(check)
592 DEALLOCATE (const_mol)
593 DEALLOCATE (tot_const)
594 DEALLOCATE (point)
595
596 CALL timestop(handle)
597
598 END SUBROUTINE thermostat_mapping_region
599
600! **************************************************************************************************
601!> \brief Performs the real mapping for the thermostat region
602!> \param region ...
603!> \param map_info ...
604!> \param nkind ...
605!> \param point ...
606!> \param deg_of_freedom ...
607!> \param local_molecules ...
608!> \param const_mol ...
609!> \param massive_atom_list ...
610!> \param tot_const ...
611!> \param molecule_set ...
612!> \param number ...
613!> \param shell ...
614!> \param gci ...
615!> \param map_loc_thermo_gen ...
616!> \author Teodoro Laino [tlaino] - University of Zurich - 10.2007
617! **************************************************************************************************
618 SUBROUTINE thermostat_mapping_region_low(region, map_info, nkind, point, &
619 deg_of_freedom, local_molecules, const_mol, massive_atom_list, tot_const, &
620 molecule_set, number, shell, gci, map_loc_thermo_gen)
621
622 INTEGER, INTENT(IN) :: region
623 TYPE(map_info_type), POINTER :: map_info
624 INTEGER :: nkind
625 INTEGER, DIMENSION(:, :), POINTER :: point
626 INTEGER, DIMENSION(:), POINTER :: deg_of_freedom
627 TYPE(distribution_1d_type), POINTER :: local_molecules
628 INTEGER, DIMENSION(:), POINTER :: const_mol, massive_atom_list, tot_const
629 TYPE(molecule_type), POINTER :: molecule_set(:)
630 INTEGER, INTENT(OUT) :: number
631 LOGICAL, INTENT(IN) :: shell
632 TYPE(global_constraint_type), POINTER :: gci
633 INTEGER, DIMENSION(:), POINTER :: map_loc_thermo_gen
634
635 CHARACTER(LEN=*), PARAMETER :: routinen = 'thermostat_mapping_region_low'
636
637 INTEGER :: first_atom, first_shell, handle, i, icount, ielement, ii, ikind, imap, imol, &
638 imol_local, ipart, itmp, jj, k, kk, last_atom, last_shell, nglob_cns, nmol_local
639 INTEGER, ALLOCATABLE, DIMENSION(:) :: tmp, wrk
640 LOGICAL :: check, global_constraints
641 TYPE(molecule_type), POINTER :: molecule
642
643 CALL timeset(routinen, handle)
644
645 global_constraints = ASSOCIATED(gci)
646 deg_of_freedom = 0
647 icount = 0
648 number = 0
649 nglob_cns = 0
650 IF (global_constraints) nglob_cns = gci%ntot - gci%nrestraint
651 IF (region == do_region_global) THEN
652 ! Global Region
653 check = (map_info%dis_type == do_thermo_communication)
654 cpassert(check)
655 DO ikind = 1, nkind
656 DO jj = point(1, ikind), point(2, ikind)
657 DO ii = 1, 3
658 map_info%p_kin(ii, jj)%point => map_info%s_kin(1)
659 map_info%p_scale(ii, jj)%point => map_info%v_scale(1)
660 END DO
661 END DO
662 deg_of_freedom(1) = deg_of_freedom(1) + tot_const(ikind)
663 map_info%index(1) = 1
664 map_info%map_index(1) = 1
665 number = 1
666 END DO
667 deg_of_freedom(1) = deg_of_freedom(1) + nglob_cns
668 ELSE IF (region == do_region_defined) THEN
669 ! User defined Region to thermostat
670 check = (map_info%dis_type == do_thermo_communication)
671 cpassert(check)
672 ! Lets' identify the matching of the local thermostat w.r.t. the global one
673 itmp = SIZE(map_loc_thermo_gen)
674 ALLOCATE (tmp(itmp))
675 ALLOCATE (wrk(itmp))
676 tmp(:) = map_loc_thermo_gen
677 CALL sort(tmp, itmp, wrk)
678 number = 1
679 map_info%index(number) = tmp(1)
680 map_info%map_index(number) = tmp(1)
681 deg_of_freedom(number) = tot_const(tmp(1))
682 DO i = 2, itmp
683 IF (tmp(i) /= tmp(i - 1)) THEN
684 number = number + 1
685 map_info%index(number) = tmp(i)
686 map_info%map_index(number) = tmp(i)
687 deg_of_freedom(number) = tot_const(tmp(i))
688 END IF
689 END DO
690 DEALLOCATE (tmp)
691 DEALLOCATE (wrk)
692 DO jj = 1, SIZE(map_loc_thermo_gen)
693 DO ii = 1, 3
694 imap = map_loc_thermo_gen(jj)
695 map_info%p_kin(ii, jj)%point => map_info%s_kin(imap)
696 map_info%p_scale(ii, jj)%point => map_info%v_scale(imap)
697 END DO
698 END DO
699 IF (nglob_cns /= 0) THEN
700 CALL cp_abort(__location__, &
701 "User Defined thermostats with global constraints not implemented!")
702 END IF
703 ELSE IF (region == do_region_molecule) THEN
704 ! Molecular Region
705 IF (map_info%dis_type == do_thermo_no_communication) THEN
706 ! This is the standard case..
707 DO ikind = 1, nkind
708 nmol_local = local_molecules%n_el(ikind)
709 DO imol_local = 1, nmol_local
710 imol = local_molecules%list(ikind)%array(imol_local)
711 number = number + 1
712 map_info%index(number) = imol
713 map_info%map_index(number) = number
714 deg_of_freedom(number) = const_mol(number)
715 DO kk = point(1, number), point(2, number)
716 DO jj = 1, 3
717 map_info%p_kin(jj, kk)%point => map_info%s_kin(number)
718 map_info%p_scale(jj, kk)%point => map_info%v_scale(number)
719 END DO
720 END DO
721 END DO
722 END DO
723 ELSE IF (map_info%dis_type == do_thermo_communication) THEN
724 ! This case is quite rare and happens only when we have one molecular
725 ! kind and one molecule..
726 cpassert(nkind == 1)
727 number = number + 1
728 map_info%index(number) = number
729 map_info%map_index(number) = number
730 deg_of_freedom(number) = deg_of_freedom(number) + tot_const(nkind)
731 DO kk = point(1, nkind), point(2, nkind)
732 DO jj = 1, 3
733 map_info%p_kin(jj, kk)%point => map_info%s_kin(number)
734 map_info%p_scale(jj, kk)%point => map_info%v_scale(number)
735 END DO
736 END DO
737 ELSE
738 cpabort("")
739 END IF
740 IF (nglob_cns /= 0) THEN
741 cpabort("Molecular thermostats with global constraints are impossible!")
742 END IF
743 ELSE IF (region == do_region_massive) THEN
744 ! Massive Region
745 check = (map_info%dis_type == do_thermo_no_communication)
746 cpassert(check)
747 DO ikind = 1, nkind
748 nmol_local = local_molecules%n_el(ikind)
749 DO imol_local = 1, nmol_local
750 icount = icount + 1
751 imol = local_molecules%list(ikind)%array(imol_local)
752 molecule => molecule_set(imol)
753 CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom, &
754 first_shell=first_shell, last_shell=last_shell)
755 IF (shell) THEN
756 first_atom = first_shell
757 last_atom = last_shell
758 ELSE
759 IF ((tot_const(icount) > 0) .OR. (nglob_cns /= 0)) THEN
760 cpabort("Massive thermostats with constraints are impossible!")
761 END IF
762 END IF
763 k = 0
764 DO ii = point(1, icount), point(2, icount)
765 ipart = first_atom + k
766 ielement = locate(massive_atom_list, ipart)
767 k = k + 1
768 DO jj = 1, 3
769 number = number + 1
770 map_info%index(number) = (ielement - 1)*3 + jj
771 map_info%map_index(number) = number
772 map_info%p_kin(jj, ii)%point => map_info%s_kin(number)
773 map_info%p_scale(jj, ii)%point => map_info%v_scale(number)
774 END DO
775 END DO
776 IF (first_atom + k - 1 /= last_atom) THEN
777 cpabort("Inconsistent mapping of particles")
778 END IF
779 END DO
780 END DO
781 ELSE
782 cpabort("Invalid region!")
783 END IF
784
785 CALL timestop(handle)
786
787 END SUBROUTINE thermostat_mapping_region_low
788
789! **************************************************************************************************
790!> \brief creates the mapping between the system and the thermostats
791!> \param dis_type ...
792!> \param natoms_local ...
793!> \param nmol_local ...
794!> \param const_mol ...
795!> \param tot_const ...
796!> \param point ...
797!> \param local_molecules ...
798!> \param molecule_kind_set ...
799!> \param molecule_set ...
800!> \param region ...
801!> \param simpar ...
802!> \param shell ...
803!> \param map_loc_thermo_gen ...
804!> \param sum_of_thermostats ...
805!> \param para_env ...
806!> \author Teodoro Laino [tlaino] - 10.2007 - University of Zurich
807! **************************************************************************************************
808 SUBROUTINE mapping_region_evaluate(dis_type, natoms_local, nmol_local, const_mol, &
809 tot_const, point, local_molecules, molecule_kind_set, molecule_set, region, &
810 simpar, shell, map_loc_thermo_gen, sum_of_thermostats, para_env)
811 INTEGER, INTENT(IN) :: dis_type
812 INTEGER, INTENT(OUT) :: natoms_local, nmol_local
813 INTEGER, DIMENSION(:), POINTER :: const_mol, tot_const
814 INTEGER, DIMENSION(:, :), POINTER :: point
815 TYPE(distribution_1d_type), POINTER :: local_molecules
816 TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
817 TYPE(molecule_type), POINTER :: molecule_set(:)
818 INTEGER, INTENT(IN) :: region
819 TYPE(simpar_type), POINTER :: simpar
820 LOGICAL, INTENT(IN) :: shell
821 INTEGER, DIMENSION(:), POINTER :: map_loc_thermo_gen
822 INTEGER, INTENT(IN) :: sum_of_thermostats
823 TYPE(mp_para_env_type), POINTER :: para_env
824
825 CHARACTER(LEN=*), PARAMETER :: routinen = 'mapping_region_evaluate'
826
827 INTEGER :: atm_offset, first_atom, handle, i, iatm, icount, id_region, ikind, ilist, imol, &
828 imol_local, j, jatm, katom, last_atom, natom, nc, nfixd, nkind, nmol_per_kind, nmolecule, &
829 nshell
830 TYPE(colvar_constraint_type), DIMENSION(:), &
831 POINTER :: colv_list
832 TYPE(fixd_constraint_type), DIMENSION(:), POINTER :: fixd_list
833 TYPE(g3x3_constraint_type), DIMENSION(:), POINTER :: g3x3_list
834 TYPE(g4x6_constraint_type), DIMENSION(:), POINTER :: g4x6_list
835 TYPE(molecule_kind_type), POINTER :: molecule_kind
836 TYPE(molecule_type), POINTER :: molecule
837
838 CALL timeset(routinen, handle)
839
840 natoms_local = 0
841 nmol_local = 0
842 nkind = SIZE(molecule_kind_set)
843 NULLIFY (fixd_list, molecule_kind, molecule, colv_list, g3x3_list, g4x6_list)
844 ! Compute the TOTAL number of molecules and atoms on THIS PROC and
845 ! TOTAL number of molecules of IKIND on THIS PROC
846 DO ikind = 1, nkind
847 molecule_kind => molecule_kind_set(ikind)
848 CALL get_molecule_kind(molecule_kind, natom=natom, nshell=nshell)
849 IF (shell) THEN
850 IF (nshell /= 0) THEN
851 natoms_local = natoms_local + nshell*local_molecules%n_el(ikind)
852 nmol_local = nmol_local + local_molecules%n_el(ikind)
853 END IF
854 ELSE
855 natoms_local = natoms_local + natom*local_molecules%n_el(ikind)
856 nmol_local = nmol_local + local_molecules%n_el(ikind)
857 END IF
858 END DO
859
860 cpassert(.NOT. ASSOCIATED(const_mol))
861 cpassert(.NOT. ASSOCIATED(tot_const))
862 cpassert(.NOT. ASSOCIATED(point))
863 IF (dis_type == do_thermo_no_communication) THEN
864 ALLOCATE (const_mol(nmol_local))
865 ALLOCATE (tot_const(nmol_local))
866 ALLOCATE (point(2, nmol_local))
867
868 point(:, :) = 0
869 atm_offset = 0
870 icount = 0
871 DO ikind = 1, nkind
872 nmol_per_kind = local_molecules%n_el(ikind)
873 molecule_kind => molecule_kind_set(ikind)
874 CALL get_molecule_kind(molecule_kind, nconstraint=nc, natom=natom, &
875 fixd_list=fixd_list, nshell=nshell)
876 IF (shell) natom = nshell
877 DO imol_local = 1, nmol_per_kind
878 icount = icount + 1
879 point(1, icount) = atm_offset + 1
880 point(2, icount) = atm_offset + natom
881 IF (.NOT. shell) THEN
882 ! nc keeps track of all constraints but not fixed ones..
883 ! Let's identify fixed atoms for this molecule
884 nfixd = 0
885 imol = local_molecules%list(ikind)%array(imol_local)
886 molecule => molecule_set(imol)
887 CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
888 IF (ASSOCIATED(fixd_list)) THEN
889 DO katom = first_atom, last_atom
890 DO ilist = 1, SIZE(fixd_list)
891 IF ((katom == fixd_list(ilist)%fixd) .AND. &
892 (.NOT. fixd_list(ilist)%restraint%active)) THEN
893 SELECT CASE (fixd_list(ilist)%itype)
895 nfixd = nfixd + 1
897 nfixd = nfixd + 2
898 CASE (use_perd_xyz)
899 nfixd = nfixd + 3
900 END SELECT
901 END IF
902 END DO
903 END DO
904 END IF
905 const_mol(icount) = nc + nfixd
906 tot_const(icount) = const_mol(icount)
907 END IF
908 atm_offset = point(2, icount)
909 END DO
910 END DO
911 ELSE IF (dis_type == do_thermo_communication) THEN
912 IF (region == do_region_defined) THEN
913 ! Setup of the arbitrary region
914 ALLOCATE (tot_const(sum_of_thermostats))
915 ALLOCATE (point(2, 0))
916 ALLOCATE (const_mol(0))
917 atm_offset = 0
918 tot_const = 0
919 const_mol = 0
920 point = 0
921 DO ikind = 1, nkind
922 nmol_per_kind = local_molecules%n_el(ikind)
923 molecule_kind => molecule_kind_set(ikind)
924 CALL get_molecule_kind(molecule_kind, nconstraint=nc, natom=natom, &
925 fixd_list=fixd_list, colv_list=colv_list, g3x3_list=g3x3_list, &
926 g4x6_list=g4x6_list, nshell=nshell)
927 IF (shell) natom = nshell
928 DO imol_local = 1, nmol_per_kind
929 IF (.NOT. shell) THEN
930 ! First if nc is not zero let's check if all atoms of a molecule
931 ! are in the same thermostatting region..
932 imol = local_molecules%list(ikind)%array(imol_local)
933 molecule => molecule_set(imol)
934 id_region = map_loc_thermo_gen(atm_offset + 1)
935 IF (all(map_loc_thermo_gen(atm_offset + 1:atm_offset + natom) == id_region)) THEN
936 ! All the atoms of a molecule are within the same thermostatting
937 ! region.. this is the easy case..
938 tot_const(id_region) = tot_const(id_region) + nc
939 ELSE
940 ! If not let's check the single constraints defined for this molecule
941 ! and continue only when atoms involved in the constraint belong to
942 ! the same thermostatting region
943 IF (ASSOCIATED(colv_list)) THEN
944 DO i = 1, SIZE(colv_list)
945 IF (.NOT. colv_list(i)%restraint%active) THEN
946 iatm = atm_offset + colv_list(i)%i_atoms(1)
947 DO j = 2, SIZE(colv_list(i)%i_atoms)
948 jatm = atm_offset + colv_list(i)%i_atoms(j)
949 IF (map_loc_thermo_gen(iatm) /= map_loc_thermo_gen(jatm)) THEN
950 CALL cp_abort(__location__, &
951 "User Defined Region: "// &
952 "A constraint (COLV) was defined between two thermostatting regions! "// &
953 "This is not allowed!")
954 END IF
955 END DO
956 id_region = map_loc_thermo_gen(iatm)
957 tot_const(id_region) = tot_const(id_region) + 1
958 END IF
959 END DO
960 END IF
961 IF (ASSOCIATED(g3x3_list)) THEN
962 DO i = 1, SIZE(g3x3_list)
963 IF (.NOT. g3x3_list(i)%restraint%active) THEN
964 iatm = atm_offset + g3x3_list(i)%a
965 jatm = atm_offset + g3x3_list(i)%b
966 IF (map_loc_thermo_gen(iatm) /= map_loc_thermo_gen(jatm)) THEN
967 CALL cp_abort(__location__, &
968 "User Defined Region: "// &
969 "A constraint (G3X3) was defined between two thermostatting regions! "// &
970 "This is not allowed!")
971 END IF
972 jatm = atm_offset + g3x3_list(i)%c
973 IF (map_loc_thermo_gen(iatm) /= map_loc_thermo_gen(jatm)) THEN
974 CALL cp_abort(__location__, &
975 "User Defined Region: "// &
976 "A constraint (G3X3) was defined between two thermostatting regions! "// &
977 "This is not allowed!")
978 END IF
979 END IF
980 id_region = map_loc_thermo_gen(iatm)
981 tot_const(id_region) = tot_const(id_region) + 3
982 END DO
983 END IF
984 IF (ASSOCIATED(g4x6_list)) THEN
985 DO i = 1, SIZE(g4x6_list)
986 IF (.NOT. g4x6_list(i)%restraint%active) THEN
987 iatm = atm_offset + g4x6_list(i)%a
988 jatm = atm_offset + g4x6_list(i)%b
989 IF (map_loc_thermo_gen(iatm) /= map_loc_thermo_gen(jatm)) THEN
990 CALL cp_abort(__location__, &
991 " User Defined Region: "// &
992 "A constraint (G4X6) was defined between two thermostatting regions! "// &
993 "This is not allowed!")
994 END IF
995 jatm = atm_offset + g4x6_list(i)%c
996 IF (map_loc_thermo_gen(iatm) /= map_loc_thermo_gen(jatm)) THEN
997 CALL cp_abort(__location__, &
998 " User Defined Region: "// &
999 "A constraint (G4X6) was defined between two thermostatting regions! "// &
1000 "This is not allowed!")
1001 END IF
1002 jatm = atm_offset + g4x6_list(i)%d
1003 IF (map_loc_thermo_gen(iatm) /= map_loc_thermo_gen(jatm)) THEN
1004 CALL cp_abort(__location__, &
1005 " User Defined Region: "// &
1006 "A constraint (G4X6) was defined between two thermostatting regions! "// &
1007 "This is not allowed!")
1008 END IF
1009 END IF
1010 id_region = map_loc_thermo_gen(iatm)
1011 tot_const(id_region) = tot_const(id_region) + 6
1012 END DO
1013 END IF
1014 END IF
1015 ! Here we handle possibly fixed atoms
1016 IF (ASSOCIATED(fixd_list)) THEN
1017 CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
1018 iatm = 0
1019 DO katom = first_atom, last_atom
1020 iatm = iatm + 1
1021 DO ilist = 1, SIZE(fixd_list)
1022 IF ((katom == fixd_list(ilist)%fixd) .AND. &
1023 (.NOT. fixd_list(ilist)%restraint%active)) THEN
1024 id_region = map_loc_thermo_gen(atm_offset + iatm)
1025 SELECT CASE (fixd_list(ilist)%itype)
1027 tot_const(id_region) = tot_const(id_region) + 1
1029 tot_const(id_region) = tot_const(id_region) + 2
1030 CASE (use_perd_xyz)
1031 tot_const(id_region) = tot_const(id_region) + 3
1032 END SELECT
1033 END IF
1034 END DO
1035 END DO
1036 END IF
1037 END IF
1038 atm_offset = atm_offset + natom
1039 END DO
1040 END DO
1041 CALL para_env%sum(tot_const)
1042 ELSE
1043 ALLOCATE (const_mol(nkind))
1044 ALLOCATE (tot_const(nkind))
1045 ALLOCATE (point(2, nkind))
1046 point(:, :) = 0
1047 atm_offset = 0
1048 ! nc keeps track of all constraints but not fixed ones..
1049 DO ikind = 1, nkind
1050 nmol_per_kind = local_molecules%n_el(ikind)
1051 molecule_kind => molecule_kind_set(ikind)
1052 CALL get_molecule_kind(molecule_kind, nconstraint=nc, natom=natom, &
1053 nmolecule=nmolecule, nconstraint_fixd=nfixd, nshell=nshell)
1054 IF (shell) natom = nshell
1055 IF (.NOT. shell) THEN
1056 const_mol(ikind) = nc
1057 ! Let's consider the fixed atoms only for the total number of constraints
1058 ! in case we are in REPLICATED/INTERACTING thermostats
1059 tot_const(ikind) = const_mol(ikind)*nmolecule + nfixd
1060 END IF
1061 point(1, ikind) = atm_offset + 1
1062 point(2, ikind) = atm_offset + natom*nmol_per_kind
1063 atm_offset = point(2, ikind)
1064 END DO
1065 END IF
1066 END IF
1067 IF ((.NOT. simpar%constraint) .OR. shell) THEN
1068 const_mol = 0
1069 tot_const = 0
1070 END IF
1071
1072 CALL timestop(handle)
1073
1074 END SUBROUTINE mapping_region_evaluate
1075
1076! **************************************************************************************************
1077!> \brief ...
1078!> \param molecule_set ...
1079!> \param molecule_kind_set ...
1080!> \param local_molecules ...
1081!> \param para_env ...
1082!> \param massive_atom_list ...
1083!> \param region ...
1084!> \param shell ...
1085! **************************************************************************************************
1086 SUBROUTINE massive_list_generate(molecule_set, molecule_kind_set, &
1087 local_molecules, para_env, massive_atom_list, region, shell)
1088
1089 TYPE(molecule_type), POINTER :: molecule_set(:)
1090 TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
1091 TYPE(distribution_1d_type), POINTER :: local_molecules
1092 TYPE(mp_para_env_type), POINTER :: para_env
1093 INTEGER, POINTER :: massive_atom_list(:)
1094 INTEGER, INTENT(IN) :: region
1095 LOGICAL, INTENT(IN) :: shell
1096
1097 CHARACTER(LEN=*), PARAMETER :: routinen = 'massive_list_generate'
1098
1099 INTEGER :: first_atom, first_shell, handle, i, ikind, imol, iproc, j, natom, ncount, nkind, &
1100 nmol_per_kind, nshell, num_massive_atm, num_massive_atm_local, offset
1101 INTEGER, DIMENSION(:), POINTER :: array_num_massive_atm, local_atm_list, &
1102 work
1103 TYPE(molecule_kind_type), POINTER :: molecule_kind
1104 TYPE(molecule_type), POINTER :: molecule
1105
1106 CALL timeset(routinen, handle)
1107
1108 num_massive_atm_local = 0
1109 NULLIFY (local_atm_list)
1110 CALL reallocate(local_atm_list, 1, num_massive_atm_local)
1111
1112 nkind = SIZE(molecule_kind_set)
1113 DO ikind = 1, nkind
1114 nmol_per_kind = local_molecules%n_el(ikind)
1115 DO imol = 1, nmol_per_kind
1116 i = local_molecules%list(ikind)%array(imol)
1117 molecule => molecule_set(i)
1118 molecule_kind => molecule%molecule_kind
1119 CALL get_molecule_kind(molecule_kind, natom=natom, nshell=nshell)
1120 IF (region == do_region_massive) THEN
1121 IF (shell) THEN
1122 natom = nshell
1123 END IF
1124 num_massive_atm_local = num_massive_atm_local + natom
1125 CALL reallocate(local_atm_list, 1, num_massive_atm_local)
1126 CALL get_molecule(molecule, first_atom=first_atom, first_shell=first_shell)
1127 IF (shell) THEN
1128 first_atom = first_shell
1129 END IF
1130 DO j = 1, natom
1131 local_atm_list(num_massive_atm_local - natom + j) = first_atom - 1 + j
1132 END DO
1133 END IF
1134 END DO
1135 END DO
1136
1137 ALLOCATE (array_num_massive_atm(para_env%num_pe))
1138 CALL para_env%allgather(num_massive_atm_local, array_num_massive_atm)
1139
1140 num_massive_atm = sum(array_num_massive_atm)
1141 ALLOCATE (massive_atom_list(num_massive_atm))
1142
1143 offset = 0
1144 DO iproc = 1, para_env%num_pe
1145 ncount = array_num_massive_atm(iproc)
1146 ALLOCATE (work(ncount))
1147 IF (para_env%mepos == (iproc - 1)) THEN
1148 DO i = 1, ncount
1149 work(i) = local_atm_list(i)
1150 END DO
1151 ELSE
1152 work(:) = 0
1153 END IF
1154 CALL para_env%bcast(work, iproc - 1)
1155 DO i = 1, ncount
1156 massive_atom_list(offset + i) = work(i)
1157 END DO
1158 DEALLOCATE (work)
1159 offset = offset + array_num_massive_atm(iproc)
1160 END DO
1161
1162 ! Sort atom list
1163 ALLOCATE (work(num_massive_atm))
1164 CALL sort(massive_atom_list, num_massive_atm, work)
1165 DEALLOCATE (work)
1166
1167 DEALLOCATE (local_atm_list)
1168 DEALLOCATE (array_num_massive_atm)
1169
1170 CALL timestop(handle)
1171
1172 END SUBROUTINE massive_list_generate
1173
1174! **************************************************************************************************
1175!> \brief Initialize the map_info for barostat thermostat
1176!> \param map_info ...
1177!> \param ndeg ...
1178!> \param num_thermo ...
1179!> \author Teodoro Laino [tlaino] - 10.2007 - University of Zurich
1180! **************************************************************************************************
1181 SUBROUTINE init_baro_map_info(map_info, ndeg, num_thermo)
1182
1183 TYPE(map_info_type), POINTER :: map_info
1184 INTEGER, INTENT(IN) :: ndeg, num_thermo
1185
1186 CHARACTER(LEN=*), PARAMETER :: routinen = 'init_baro_map_info'
1187
1188 INTEGER :: handle, i
1189
1190 CALL timeset(routinen, handle)
1191
1192 ALLOCATE (map_info%s_kin(num_thermo))
1193 ALLOCATE (map_info%v_scale(num_thermo))
1194 ALLOCATE (map_info%p_kin(1, ndeg))
1195 ALLOCATE (map_info%p_scale(1, ndeg))
1196 ! Allocate the index array
1197 ALLOCATE (map_info%index(1))
1198 ALLOCATE (map_info%map_index(1))
1199
1200 ! Begin the mapping loop
1201 DO i = 1, ndeg
1202 map_info%p_kin(1, i)%point => map_info%s_kin(1)
1203 map_info%p_scale(1, i)%point => map_info%v_scale(1)
1204 END DO
1205 map_info%index(1) = 1
1206 map_info%map_index(1) = 1
1207
1208 CALL timestop(handle)
1209
1210 END SUBROUTINE init_baro_map_info
1211
1212END MODULE thermostat_mapping
1213
Handles all functions related to the CELL.
Definition cell_types.F:15
integer, parameter, public use_perd_xyz
Definition cell_types.F:42
integer, parameter, public use_perd_y
Definition cell_types.F:42
integer, parameter, public use_perd_xz
Definition cell_types.F:42
integer, parameter, public use_perd_x
Definition cell_types.F:42
integer, parameter, public use_perd_z
Definition cell_types.F:42
integer, parameter, public use_perd_yz
Definition cell_types.F:42
integer, parameter, public use_perd_xy
Definition cell_types.F:42
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
Lumps all possible extended system variables into one type for easy access and passing.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_thermo_no_communication
integer, parameter, public do_region_molecule
integer, parameter, public do_region_massive
integer, parameter, public do_region_global
integer, parameter, public do_region_defined
integer, parameter, public do_thermo_communication
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Utility routines for the memory handling.
Interface to the message passing library MPI.
Define the molecule kind structure types and the corresponding functionality.
subroutine, public get_molecule_kind(molecule_kind, atom_list, bond_list, bend_list, ub_list, impr_list, opbend_list, colv_list, fixd_list, g3x3_list, g4x6_list, vsite_list, torsion_list, shell_list, name, mass, charge, kind_number, natom, nbend, nbond, nub, nimpr, nopbend, nconstraint, nconstraint_fixd, nfixd, ncolv, ng3x3, ng4x6, nvsite, nfixd_restraint, ng3x3_restraint, ng4x6_restraint, nvsite_restraint, nrestraints, nmolecule, nsgf, nshell, ntorsion, molecule_list, nelectron, nelectron_alpha, nelectron_beta, bond_kind_set, bend_kind_set, ub_kind_set, impr_kind_set, opbend_kind_set, torsion_kind_set, molname_generated)
Get informations about a molecule kind.
Define the data structure for the molecule information.
subroutine, public get_molecule(molecule, molecule_kind, lmi, lci, lg3x3, lg4x6, lcolv, first_atom, last_atom, first_shell, last_shell)
Get components from a molecule data set.
Type for storing MD parameters.
subroutine, public adiabatic_mapping_region(map_info, deg_of_freedom, massive_atom_list, molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, simpar, number, region, gci, shell, map_loc_thermo_gen, sum_of_thermostats)
Main general setup for adiabatic thermostat regions (Nose only)
subroutine, public thermostat_mapping_region(map_info, deg_of_freedom, massive_atom_list, molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, simpar, number, region, gci, shell, map_loc_thermo_gen, sum_of_thermostats)
Main general setup thermostat regions (thermostat independent)
subroutine, public init_baro_map_info(map_info, ndeg, num_thermo)
Initialize the map_info for barostat thermostat.
All kind of helpful little routines.
Definition util.F:14
pure integer function, public locate(array, x)
Purpose: Given an array array(1:n), and given a value x, a value x_index is returned which is the ind...
Definition util.F:61
structure to store local (to a processor) ordered lists of integers.
stores all the informations relevant to an mpi environment
Simulation parameter type for molecular dynamics.