1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2019  CP2K developers group                                               !
4!--------------------------------------------------------------------------------------------------!
5
6! **************************************************************************************************
7!> \par History
8!>      give the md_env its own para_env Joost VandeVondele 07.2003
9!>      Teodoro Laino - 09.2007 - University of Zurich - generalizing thermostats
10!>                                and barostats
11!> \author CJM SEPT-12-02
12! **************************************************************************************************
13MODULE md_environment_types
14   USE averages_types,                  ONLY: average_quantities_type,&
15                                              create_averages,&
16                                              release_averages,&
17                                              retain_averages
18   USE barostat_types,                  ONLY: barostat_type,&
19                                              release_barostat_type,&
20                                              retain_barostat_type
21   USE cell_types,                      ONLY: cell_type
22   USE cp_para_env,                     ONLY: cp_para_env_release,&
23                                              cp_para_env_retain
24   USE cp_para_types,                   ONLY: cp_para_env_type
25   USE extended_system_types,           ONLY: npt_info_type
26   USE force_env_types,                 ONLY: force_env_release,&
27                                              force_env_retain,&
28                                              force_env_type
29   USE free_energy_types,               ONLY: fe_env_release,&
30                                              free_energy_type
31   USE input_constants,                 ONLY: do_thermo_al,&
32                                              langevin_ensemble
33   USE input_section_types,             ONLY: section_vals_get_subs_vals,&
34                                              section_vals_type
35   USE kinds,                           ONLY: dp
36   USE md_ener_types,                   ONLY: md_ener_type,&
37                                              release_md_ener,&
38                                              retain_md_ener
39   USE reftraj_types,                   ONLY: reftraj_type,&
40                                              release_reftraj,&
41                                              retain_reftraj
42   USE simpar_types,                    ONLY: simpar_type
43   USE thermal_region_types,            ONLY: release_thermal_regions,&
44                                              retain_thermal_regions,&
45                                              thermal_regions_type
46   USE thermostat_types,                ONLY: release_thermostats,&
47                                              retain_thermostats,&
48                                              thermostat_type,&
49                                              thermostats_type
50#include "../base/base_uses.f90"
51
52   IMPLICIT NONE
53
54   PRIVATE
55
56! **************************************************************************************************
57   TYPE md_environment_type
58      ! para_env is the parallel environment of the MD,  i.e. the systems
59      ! that are dealt with by the integrator e.g in the PIMD this could
60      ! be parent of every bead.
61      PRIVATE
62      INTEGER                                    :: id_nr, ref_count
63      LOGICAL                                    :: init, first_time, ehrenfest_md
64      INTEGER, POINTER                           :: itimes
65      REAL(KIND=dp), POINTER                     :: used_time, t
66      REAL(KIND=dp), POINTER                     :: constant
67      TYPE(cp_para_env_type), POINTER            :: para_env
68      TYPE(cell_type), POINTER                   :: cell
69      TYPE(force_env_type), POINTER              :: force_env
70      TYPE(md_ener_type), POINTER                :: md_ener
71      TYPE(thermostats_type), POINTER            :: thermostats
72      TYPE(barostat_type), POINTER               :: barostat
73      TYPE(reftraj_type), POINTER                :: reftraj
74      TYPE(free_energy_type), POINTER           :: fe_env
75      TYPE(simpar_type), POINTER                 :: simpar
76      TYPE(average_quantities_type), POINTER     :: averages
77      TYPE(thermal_regions_type), POINTER        :: thermal_regions
78   END TYPE md_environment_type
79
80   ! *** Public subroutines and data types ***
81   PUBLIC :: md_environment_type, set_md_env, get_md_env, md_env_create, &
82             md_env_release, need_per_atom_wiener_process
83
84   ! *** Global parameters ***
85   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'md_environment_types'
86   INTEGER, SAVE, PRIVATE :: last_md_env_id = 0
87
88CONTAINS
89
90! **************************************************************************************************
91!> \brief Creates MD environment
92!>      Purpose: Initialise the integrator environment.
93!>      retain the para_env for this environment (should be used for parallel
94!>      communications)
95!> \param md_env the force environment to retain
96!> \param md_section ...
97!> \param para_env ...
98!> \param force_env ...
99! **************************************************************************************************
100   SUBROUTINE md_env_create(md_env, md_section, para_env, force_env)
101      TYPE(md_environment_type), POINTER                 :: md_env
102      TYPE(section_vals_type), POINTER                   :: md_section
103      TYPE(cp_para_env_type), POINTER                    :: para_env
104      TYPE(force_env_type), POINTER                      :: force_env
105
106      CHARACTER(LEN=*), PARAMETER :: routineN = 'md_env_create', routineP = moduleN//':'//routineN
107
108      TYPE(section_vals_type), POINTER                   :: averages_section
109
110      ALLOCATE (md_env)
111      last_md_env_id = last_md_env_id + 1
112      md_env%id_nr = last_md_env_id
113      md_env%ref_count = 1
114
115      NULLIFY (md_env%itimes)
116      NULLIFY (md_env%constant)
117      NULLIFY (md_env%t)
118      NULLIFY (md_env%cell)
119      NULLIFY (md_env%simpar)
120      NULLIFY (md_env%thermostats)
121      NULLIFY (md_env%barostat)
122      NULLIFY (md_env%force_env)
123      NULLIFY (md_env%fe_env)
124      NULLIFY (md_env%md_ener)
125      NULLIFY (md_env%reftraj)
126      NULLIFY (md_env%averages)
127      NULLIFY (md_env%thermal_regions)
128      md_env%para_env => para_env
129      CALL cp_para_env_retain(md_env%para_env)
130      ALLOCATE (md_env%itimes)
131      ALLOCATE (md_env%constant)
132      ALLOCATE (md_env%used_time)
133      ALLOCATE (md_env%t)
134      md_env%itimes = -1
135      md_env%constant = 0.0_dp
136      md_env%used_time = 0.0_dp
137      md_env%t = 0.0_dp
138      md_env%init = .TRUE.
139      md_env%first_time = .TRUE.
140      md_env%ehrenfest_md = .FALSE.
141      averages_section => section_vals_get_subs_vals(md_section, "AVERAGES")
142      CALL create_averages(md_env%averages, averages_section, force_env=force_env)
143
144   END SUBROUTINE md_env_create
145
146! **************************************************************************************************
147!> \brief releases the given md env
148!> \param md_env the md environment to release
149!> \par History
150!>      04.2003 created [fawzi]
151!> \author fawzi
152!> \note
153!>      see doc/ReferenceCounting.html
154! **************************************************************************************************
155   SUBROUTINE md_env_release(md_env)
156      TYPE(md_environment_type), POINTER                 :: md_env
157
158      CHARACTER(len=*), PARAMETER :: routineN = 'md_env_release', routineP = moduleN//':'//routineN
159
160      IF (ASSOCIATED(md_env)) THEN
161         CPASSERT(md_env%ref_count > 0)
162         md_env%ref_count = md_env%ref_count - 1
163         IF (md_env%ref_count == 0) THEN
164            CALL fe_env_release(md_env%fe_env)
165            CALL cp_para_env_release(md_env%para_env)
166            DEALLOCATE (md_env%itimes)
167            DEALLOCATE (md_env%constant)
168            DEALLOCATE (md_env%used_time)
169            DEALLOCATE (md_env%t)
170
171            NULLIFY (md_env%cell)
172            NULLIFY (md_env%simpar)
173            CALL release_barostat_type(md_env%barostat)
174            CALL release_thermostats(md_env%thermostats)
175            CALL release_reftraj(md_env%reftraj)
176            CALL release_md_ener(md_env%md_ener)
177            CALL force_env_release(md_env%force_env)
178            CALL release_averages(md_env%averages)
179            CALL release_thermal_regions(md_env%thermal_regions)
180            DEALLOCATE (md_env)
181         END IF
182      END IF
183   END SUBROUTINE md_env_release
184
185! **************************************************************************************************
186!> \brief get components of MD environment type
187!> \param md_env the force environment to retain
188!> \param itimes ...
189!> \param constant ...
190!> \param used_time ...
191!> \param cell ...
192!> \param simpar ...
193!> \param npt ...
194!> \param force_env ...
195!> \param para_env ...
196!> \param reftraj ...
197!> \param t ...
198!> \param init ...
199!> \param first_time ...
200!> \param fe_env ...
201!> \param thermostats ...
202!> \param barostat ...
203!> \param thermostat_coeff ...
204!> \param thermostat_part ...
205!> \param thermostat_shell ...
206!> \param thermostat_baro ...
207!> \param thermostat_fast ...
208!> \param thermostat_slow ...
209!> \param md_ener ...
210!> \param averages ...
211!> \param thermal_regions ...
212!> \param ehrenfest_md ...
213! **************************************************************************************************
214   SUBROUTINE get_md_env(md_env, itimes, constant, used_time, cell, simpar, npt, &
215                         force_env, para_env, reftraj, t, init, first_time, fe_env, thermostats, barostat, &
216                         thermostat_coeff, thermostat_part, thermostat_shell, thermostat_baro, &
217                         thermostat_fast, thermostat_slow, md_ener, averages, &
218                         thermal_regions, ehrenfest_md)
219
220      TYPE(md_environment_type), POINTER                 :: md_env
221      INTEGER, OPTIONAL, POINTER                         :: itimes
222      REAL(KIND=dp), OPTIONAL, POINTER                   :: constant, used_time
223      TYPE(cell_type), OPTIONAL, POINTER                 :: cell
224      TYPE(simpar_type), OPTIONAL, POINTER               :: simpar
225      TYPE(npt_info_type), OPTIONAL, POINTER             :: npt(:, :)
226      TYPE(force_env_type), OPTIONAL, POINTER            :: force_env
227      TYPE(cp_para_env_type), OPTIONAL, POINTER          :: para_env
228      TYPE(reftraj_type), OPTIONAL, POINTER              :: reftraj
229      REAL(KIND=dp), OPTIONAL, POINTER                   :: t
230      LOGICAL, OPTIONAL                                  :: init, first_time
231      TYPE(free_energy_type), OPTIONAL, POINTER          :: fe_env
232      TYPE(thermostats_type), OPTIONAL, POINTER          :: thermostats
233      TYPE(barostat_type), OPTIONAL, POINTER             :: barostat
234      TYPE(thermostat_type), OPTIONAL, POINTER           :: thermostat_coeff, thermostat_part, &
235                                                            thermostat_shell, thermostat_baro, &
236                                                            thermostat_fast, thermostat_slow
237      TYPE(md_ener_type), OPTIONAL, POINTER              :: md_ener
238      TYPE(average_quantities_type), OPTIONAL, POINTER   :: averages
239      TYPE(thermal_regions_type), OPTIONAL, POINTER      :: thermal_regions
240      LOGICAL, OPTIONAL                                  :: ehrenfest_md
241
242      CHARACTER(LEN=*), PARAMETER :: routineN = 'get_md_env', routineP = moduleN//':'//routineN
243
244      LOGICAL                                            :: check
245
246      check = ASSOCIATED(md_env)
247      CPASSERT(check)
248      IF (PRESENT(itimes)) itimes => md_env%itimes
249      IF (PRESENT(fe_env)) fe_env => md_env%fe_env
250      IF (PRESENT(constant)) constant => md_env%constant
251      IF (PRESENT(used_time)) used_time => md_env%used_time
252      IF (PRESENT(t)) t => md_env%t
253      IF (PRESENT(cell)) cell => md_env%cell
254      IF (PRESENT(simpar)) simpar => md_env%simpar
255      IF (PRESENT(thermostats)) thermostats => md_env%thermostats
256      IF (PRESENT(barostat)) barostat => md_env%barostat
257      IF (PRESENT(thermostat_part) .OR. PRESENT(thermostat_coeff) .OR. &
258          PRESENT(thermostat_baro) .OR. PRESENT(thermostat_shell) .OR. &
259          PRESENT(thermostat_fast) .OR. PRESENT(thermostat_slow)) THEN
260         IF (ASSOCIATED(md_env%thermostats)) THEN
261            IF (PRESENT(thermostat_part)) THEN
262               thermostat_part => md_env%thermostats%thermostat_part
263            END IF
264            IF (PRESENT(thermostat_coeff)) THEN
265               thermostat_coeff => md_env%thermostats%thermostat_coef
266            END IF
267            IF (PRESENT(thermostat_shell)) THEN
268               thermostat_shell => md_env%thermostats%thermostat_shell
269            END IF
270            IF (PRESENT(thermostat_fast)) THEN
271               thermostat_fast => md_env%thermostats%thermostat_fast
272            END IF
273            IF (PRESENT(thermostat_slow)) THEN
274               thermostat_slow => md_env%thermostats%thermostat_slow
275            END IF
276            IF (PRESENT(thermostat_baro)) THEN
277               thermostat_baro => md_env%thermostats%thermostat_baro
278            END IF
279         END IF
280      END IF
281      IF (PRESENT(npt)) THEN
282         IF (ASSOCIATED(md_env%barostat)) THEN
283            npt => md_env%barostat%npt
284         END IF
285      END IF
286      IF (PRESENT(averages)) averages => md_env%averages
287      IF (PRESENT(force_env)) force_env => md_env%force_env
288      IF (PRESENT(para_env)) para_env => md_env%para_env
289      IF (PRESENT(reftraj)) reftraj => md_env%reftraj
290      IF (PRESENT(md_ener)) md_ener => md_env%md_ener
291      IF (PRESENT(init)) init = md_env%init
292      IF (PRESENT(first_time)) first_time = md_env%first_time
293      IF (PRESENT(ehrenfest_md)) ehrenfest_md = md_env%ehrenfest_md
294      IF (PRESENT(thermal_regions)) thermal_regions => md_env%thermal_regions
295
296   END SUBROUTINE get_md_env
297
298! **************************************************************************************************
299!> \brief Set the integrator environment to the correct program.
300!> \param md_env the force environment to retain
301!> \param itimes ...
302!> \param constant ...
303!> \param cell ...
304!> \param simpar ...
305!> \param fe_env ...
306!> \param force_env ...
307!> \param para_env ...
308!> \param init ...
309!> \param first_time ...
310!> \param thermostats ...
311!> \param barostat ...
312!> \param reftraj ...
313!> \param md_ener ...
314!> \param averages ...
315!> \param thermal_regions ...
316!> \param ehrenfest_md ...
317! **************************************************************************************************
318   SUBROUTINE set_md_env(md_env, itimes, constant, cell, simpar, fe_env, force_env, &
319                         para_env, init, first_time, thermostats, barostat, reftraj, md_ener, averages, &
320                         thermal_regions, ehrenfest_md)
321
322      TYPE(md_environment_type), POINTER                 :: md_env
323      INTEGER, OPTIONAL, POINTER                         :: itimes
324      REAL(KIND=dp), OPTIONAL, POINTER                   :: constant
325      TYPE(cell_type), OPTIONAL, POINTER                 :: cell
326      TYPE(simpar_type), OPTIONAL, POINTER               :: simpar
327      TYPE(free_energy_type), OPTIONAL, POINTER          :: fe_env
328      TYPE(force_env_type), OPTIONAL, POINTER            :: force_env
329      TYPE(cp_para_env_type), OPTIONAL, POINTER          :: para_env
330      LOGICAL, OPTIONAL                                  :: init, first_time
331      TYPE(thermostats_type), OPTIONAL, POINTER          :: thermostats
332      TYPE(barostat_type), OPTIONAL, POINTER             :: barostat
333      TYPE(reftraj_type), OPTIONAL, POINTER              :: reftraj
334      TYPE(md_ener_type), OPTIONAL, POINTER              :: md_ener
335      TYPE(average_quantities_type), OPTIONAL, POINTER   :: averages
336      TYPE(thermal_regions_type), OPTIONAL, POINTER      :: thermal_regions
337      LOGICAL, OPTIONAL                                  :: ehrenfest_md
338
339      CHARACTER(LEN=*), PARAMETER :: routineN = 'set_md_env', routineP = moduleN//':'//routineN
340
341      LOGICAL                                            :: check
342
343      check = ASSOCIATED(md_env)
344      CPASSERT(check)
345      IF (PRESENT(init)) md_env%init = init
346      IF (PRESENT(first_time)) md_env%first_time = first_time
347      IF (PRESENT(ehrenfest_md)) md_env%ehrenfest_md = ehrenfest_md
348      IF (PRESENT(cell)) md_env%cell => cell
349      IF (PRESENT(barostat)) THEN
350         CALL release_barostat_type(md_env%barostat)
351         CALL retain_barostat_type(barostat)
352         md_env%barostat => barostat
353      END IF
354      IF (PRESENT(thermostats)) THEN
355         CALL release_thermostats(md_env%thermostats)
356         CALL retain_thermostats(thermostats)
357         md_env%thermostats => thermostats
358      END IF
359      IF (PRESENT(simpar)) md_env%simpar => simpar
360      IF (PRESENT(itimes)) md_env%itimes => itimes
361      IF (PRESENT(fe_env)) md_env%fe_env => fe_env
362      IF (PRESENT(constant)) md_env%constant => constant
363      IF (PRESENT(para_env)) md_env%para_env => para_env
364      IF (PRESENT(force_env)) THEN
365         IF (ASSOCIATED(force_env)) THEN
366            CALL force_env_retain(force_env)
367         END IF
368         IF (ASSOCIATED(md_env%force_env)) THEN
369            CALL force_env_release(md_env%force_env)
370         END IF
371         md_env%force_env => force_env
372      END IF
373      IF (PRESENT(reftraj)) THEN
374         CALL release_reftraj(md_env%reftraj)
375         CALL retain_reftraj(reftraj)
376         md_env%reftraj => reftraj
377      END IF
378      IF (PRESENT(md_ener)) THEN
379         CALL release_md_ener(md_env%md_ener)
380         CALL retain_md_ener(md_ener)
381         md_env%md_ener => md_ener
382      END IF
383      IF (PRESENT(averages)) THEN
384         CALL release_averages(md_env%averages)
385         CALL retain_averages(averages)
386         md_env%averages => averages
387      END IF
388      IF (PRESENT(thermal_regions)) THEN
389         CALL release_thermal_regions(md_env%thermal_regions)
390         CALL retain_thermal_regions(thermal_regions)
391         md_env%thermal_regions => thermal_regions
392      END IF
393
394   END SUBROUTINE set_md_env
395
396! **************************************************************************************************
397!> \brief ...
398!> \param md_env ...
399!> \return ...
400!> \par History
401!>      02.2012 created [noamb]
402!> \author Noam Bernstein
403! **************************************************************************************************
404   FUNCTION need_per_atom_wiener_process(md_env)
405      TYPE(md_environment_type), POINTER                 :: md_env
406      LOGICAL                                            :: need_per_atom_wiener_process
407
408! return value
409! check for Langevin ensemble
410
411      need_per_atom_wiener_process = (md_env%simpar%ensemble == langevin_ensemble)
412      IF (need_per_atom_wiener_process) RETURN
413
414      ! check for adaptive-Langevin thermostat
415      IF (.NOT. ASSOCIATED(md_env%thermostats)) RETURN
416      IF (.NOT. ASSOCIATED(md_env%thermostats%thermostat_part)) RETURN
417      need_per_atom_wiener_process = (md_env%thermostats%thermostat_part%type_of_thermostat == do_thermo_al)
418
419   END FUNCTION need_per_atom_wiener_process
420
421END MODULE md_environment_types
422