1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2019  CP2K developers group                                               !
4!--------------------------------------------------------------------------------------------------!
5
6! **************************************************************************************************
7!> \brief Handles the type to compute averages during an MD
8!> \author Teodoro Laino [tlaino] - 03.2008 - University of Zurich
9! **************************************************************************************************
10MODULE averages_types
11   USE cell_types,                      ONLY: cell_type
12   USE colvar_utils,                    ONLY: get_clv_force,&
13                                              number_of_colvar
14   USE cp_log_handling,                 ONLY: cp_get_default_logger,&
15                                              cp_logger_type,&
16                                              cp_to_string
17   USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
18                                              cp_print_key_unit_nr
19   USE force_env_types,                 ONLY: force_env_type
20   USE input_section_types,             ONLY: section_vals_get,&
21                                              section_vals_get_subs_vals,&
22                                              section_vals_remove_values,&
23                                              section_vals_type,&
24                                              section_vals_val_get
25   USE kinds,                           ONLY: default_string_length,&
26                                              dp
27   USE md_ener_types,                   ONLY: md_ener_type
28   USE virial_types,                    ONLY: virial_create,&
29                                              virial_release,&
30                                              virial_type
31#include "../base/base_uses.f90"
32
33   IMPLICIT NONE
34
35   PRIVATE
36
37! **************************************************************************************************
38   TYPE average_quantities_type
39      INTEGER                                       :: id_nr, ref_count, itimes_start
40      LOGICAL                                       :: do_averages
41      TYPE(section_vals_type), POINTER              :: averages_section
42      ! Real Scalar Quantities
43      REAL(KIND=dp)                                 :: avetemp, avepot, avekin, &
44                                                       avevol, aveca, avecb, avecc
45      REAL(KIND=dp)                                 :: avetemp_baro, avehugoniot, avecpu
46      REAL(KIND=dp)                                 :: aveal, avebe, avega, avepress, &
47                                                       avekinc, avetempc, avepxx
48      REAL(KIND=dp)                                 :: avetemp_qm, avekin_qm, econs
49      ! Virial
50      TYPE(virial_type), POINTER                    :: virial
51      ! Colvar
52      REAL(KIND=dp), POINTER, DIMENSION(:)          :: avecolvar
53      REAL(KIND=dp), POINTER, DIMENSION(:)          :: aveMmatrix
54   END TYPE average_quantities_type
55
56! **************************************************************************************************
57   INTERFACE get_averages
58      MODULE PROCEDURE get_averages_rs, get_averages_rv, get_averages_rm
59   END INTERFACE get_averages
60
61! *** Public subroutines and data types ***
62   PUBLIC :: average_quantities_type, create_averages, release_averages, &
63             retain_averages, compute_averages
64
65! *** Global parameters ***
66   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'averages_types'
67   INTEGER, SAVE, PRIVATE :: last_avg_env_id = 0
68
69CONTAINS
70
71! **************************************************************************************************
72!> \brief Creates averages environment
73!> \param averages ...
74!> \param averages_section ...
75!> \param virial_avg ...
76!> \param force_env ...
77!> \author Teodoro Laino [tlaino] - 03.2008 - University of Zurich
78! **************************************************************************************************
79   SUBROUTINE create_averages(averages, averages_section, virial_avg, force_env)
80      TYPE(average_quantities_type), POINTER             :: averages
81      TYPE(section_vals_type), POINTER                   :: averages_section
82      LOGICAL, INTENT(IN), OPTIONAL                      :: virial_avg
83      TYPE(force_env_type), POINTER                      :: force_env
84
85      CHARACTER(LEN=*), PARAMETER :: routineN = 'create_averages', &
86         routineP = moduleN//':'//routineN
87
88      INTEGER                                            :: i, nint
89      LOGICAL                                            :: do_colvars
90
91      ALLOCATE (averages)
92      NULLIFY (averages%virial)
93      NULLIFY (averages%avecolvar)
94      NULLIFY (averages%aveMmatrix)
95      ! Point to the averages section
96      averages%averages_section => averages_section
97      ! Initialize averages
98      last_avg_env_id = last_avg_env_id + 1
99      averages%id_nr = last_avg_env_id
100      averages%ref_count = 1
101      averages%itimes_start = -1
102      averages%avetemp = 0.0_dp
103      averages%avepot = 0.0_dp
104      averages%avekin = 0.0_dp
105      averages%avevol = 0.0_dp
106      averages%aveca = 0.0_dp
107      averages%avecb = 0.0_dp
108      averages%avecc = 0.0_dp
109      averages%avetemp_baro = 0.0_dp
110      averages%avehugoniot = 0.0_dp
111      averages%avecpu = 0.0_dp
112      averages%aveal = 0.0_dp
113      averages%avebe = 0.0_dp
114      averages%avega = 0.0_dp
115      averages%avepress = 0.0_dp
116      averages%avekinc = 0.0_dp
117      averages%avetempc = 0.0_dp
118      averages%avepxx = 0.0_dp
119      averages%avetemp_qm = 0.0_dp
120      averages%avekin_qm = 0.0_dp
121      averages%econs = 0.0_dp
122      CALL section_vals_val_get(averages_section, "_SECTION_PARAMETERS_", l_val=averages%do_averages)
123      IF (averages%do_averages) THEN
124         ! Setup Virial if requested
125         IF (PRESENT(virial_avg)) THEN
126            IF (virial_avg) CALL virial_create(averages%virial)
127         END IF
128         CALL section_vals_val_get(averages_section, "AVERAGE_COLVAR", l_val=do_colvars)
129         ! Total number of COLVARs
130         nint = 0
131         IF (do_colvars) nint = number_of_colvar(force_env)
132         ALLOCATE (averages%avecolvar(nint))
133         ALLOCATE (averages%aveMmatrix(nint*nint))
134         DO i = 1, nint
135            averages%avecolvar(i) = 0.0_dp
136         END DO
137         DO i = 1, nint*nint
138            averages%aveMmatrix(i) = 0.0_dp
139         END DO
140      END IF
141   END SUBROUTINE create_averages
142
143! **************************************************************************************************
144!> \brief retains the given averages env
145!> \param averages ...
146!> \author Teodoro Laino [tlaino] - 03.2008 - University of Zurich
147! **************************************************************************************************
148   SUBROUTINE retain_averages(averages)
149      TYPE(average_quantities_type), POINTER             :: averages
150
151      CHARACTER(len=*), PARAMETER :: routineN = 'retain_averages', &
152         routineP = moduleN//':'//routineN
153
154      CPASSERT(ASSOCIATED(averages))
155      CPASSERT(averages%ref_count > 0)
156      averages%ref_count = averages%ref_count + 1
157   END SUBROUTINE retain_averages
158
159! **************************************************************************************************
160!> \brief releases the given averages env
161!> \param averages ...
162!> \author Teodoro Laino [tlaino] - 03.2008 - University of Zurich
163! **************************************************************************************************
164   SUBROUTINE release_averages(averages)
165      TYPE(average_quantities_type), POINTER             :: averages
166
167      CHARACTER(len=*), PARAMETER :: routineN = 'release_averages', &
168         routineP = moduleN//':'//routineN
169
170      TYPE(section_vals_type), POINTER                   :: work_section
171
172      IF (ASSOCIATED(averages)) THEN
173         CPASSERT(averages%ref_count > 0)
174         averages%ref_count = averages%ref_count - 1
175         IF (averages%ref_count == 0) THEN
176            CALL virial_release(averages%virial)
177            IF (ASSOCIATED(averages%avecolvar)) THEN
178               DEALLOCATE (averages%avecolvar)
179            END IF
180            IF (ASSOCIATED(averages%aveMmatrix)) THEN
181               DEALLOCATE (averages%aveMmatrix)
182            END IF
183            ! Removes restart values from the corresponding restart section..
184            work_section => section_vals_get_subs_vals(averages%averages_section, "RESTART_AVERAGES")
185            CALL section_vals_remove_values(work_section)
186            NULLIFY (averages%averages_section)
187            !
188            DEALLOCATE (averages)
189         END IF
190      END IF
191
192   END SUBROUTINE release_averages
193
194! **************************************************************************************************
195!> \brief computes the averages
196!> \param averages ...
197!> \param force_env ...
198!> \param md_ener ...
199!> \param cell ...
200!> \param virial ...
201!> \param pv_scalar ...
202!> \param pv_xx ...
203!> \param used_time ...
204!> \param hugoniot ...
205!> \param abc ...
206!> \param cell_angle ...
207!> \param nat ...
208!> \param itimes ...
209!> \param time ...
210!> \param my_pos ...
211!> \param my_act ...
212!> \author Teodoro Laino [tlaino] - 03.2008 - University of Zurich
213! **************************************************************************************************
214   SUBROUTINE compute_averages(averages, force_env, md_ener, cell, virial, &
215                               pv_scalar, pv_xx, used_time, hugoniot, abc, cell_angle, nat, itimes, &
216                               time, my_pos, my_act)
217      TYPE(average_quantities_type), POINTER             :: averages
218      TYPE(force_env_type), POINTER                      :: force_env
219      TYPE(md_ener_type), POINTER                        :: md_ener
220      TYPE(cell_type), POINTER                           :: cell
221      TYPE(virial_type), POINTER                         :: virial
222      REAL(KIND=dp), INTENT(IN)                          :: pv_scalar, pv_xx
223      REAL(KIND=dp), POINTER                             :: used_time
224      REAL(KIND=dp), INTENT(IN)                          :: hugoniot
225      REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: abc, cell_angle
226      INTEGER, INTENT(IN)                                :: nat, itimes
227      REAL(KIND=dp), INTENT(IN)                          :: time
228      CHARACTER(LEN=default_string_length), INTENT(IN)   :: my_pos, my_act
229
230      CHARACTER(len=*), PARAMETER :: routineN = 'compute_averages', &
231         routineP = moduleN//':'//routineN
232
233      CHARACTER(LEN=default_string_length)               :: ctmp
234      INTEGER                                            :: delta_t, handle, i, nint, output_unit
235      LOGICAL                                            :: restart_averages
236      REAL(KIND=dp)                                      :: start_time
237      REAL(KIND=dp), DIMENSION(:), POINTER               :: cvalues, Mmatrix, tmp
238      TYPE(cp_logger_type), POINTER                      :: logger
239      TYPE(section_vals_type), POINTER                   :: restart_section
240
241      CALL timeset(routineN, handle)
242      CALL section_vals_val_get(averages%averages_section, "ACQUISITION_START_TIME", &
243                                r_val=start_time)
244      IF (averages%do_averages) THEN
245         NULLIFY (cvalues, Mmatrix, logger)
246         logger => cp_get_default_logger()
247         ! Determine the nr. of internal colvar (if any/requested)
248         nint = 0
249         IF (ASSOCIATED(averages%avecolvar)) nint = SIZE(averages%avecolvar)
250
251         ! Evaluate averages if we collected enough statistics (user defined)
252         IF (time >= start_time) THEN
253
254            ! Handling properly the restart
255            IF (averages%itimes_start == -1) THEN
256               restart_section => section_vals_get_subs_vals(averages%averages_section, "RESTART_AVERAGES")
257               CALL section_vals_get(restart_section, explicit=restart_averages)
258               IF (restart_averages) THEN
259                  CALL section_vals_val_get(restart_section, "ITIMES_START", i_val=averages%itimes_start)
260                  CALL section_vals_val_get(restart_section, "AVECPU", r_val=averages%avecpu)
261                  CALL section_vals_val_get(restart_section, "AVEHUGONIOT", r_val=averages%avehugoniot)
262                  CALL section_vals_val_get(restart_section, "AVETEMP_BARO", r_val=averages%avetemp_baro)
263                  CALL section_vals_val_get(restart_section, "AVEPOT", r_val=averages%avepot)
264                  CALL section_vals_val_get(restart_section, "AVEKIN", r_val=averages%avekin)
265                  CALL section_vals_val_get(restart_section, "AVETEMP", r_val=averages%avetemp)
266                  CALL section_vals_val_get(restart_section, "AVEKIN_QM", r_val=averages%avekin_qm)
267                  CALL section_vals_val_get(restart_section, "AVETEMP_QM", r_val=averages%avetemp_qm)
268                  CALL section_vals_val_get(restart_section, "AVEVOL", r_val=averages%avevol)
269                  CALL section_vals_val_get(restart_section, "AVECELL_A", r_val=averages%aveca)
270                  CALL section_vals_val_get(restart_section, "AVECELL_B", r_val=averages%avecb)
271                  CALL section_vals_val_get(restart_section, "AVECELL_C", r_val=averages%avecc)
272                  CALL section_vals_val_get(restart_section, "AVEALPHA", r_val=averages%aveal)
273                  CALL section_vals_val_get(restart_section, "AVEBETA", r_val=averages%avebe)
274                  CALL section_vals_val_get(restart_section, "AVEGAMMA", r_val=averages%avega)
275                  CALL section_vals_val_get(restart_section, "AVE_ECONS", r_val=averages%econs)
276                  ! Virial
277                  IF (virial%pv_availability) THEN
278                     CALL section_vals_val_get(restart_section, "AVE_PRESS", r_val=averages%avepress)
279                     CALL section_vals_val_get(restart_section, "AVE_PXX", r_val=averages%avepxx)
280                     IF (ASSOCIATED(averages%virial)) THEN
281                        CALL section_vals_val_get(restart_section, "AVE_PV_TOT", r_vals=tmp)
282                        averages%virial%pv_total = RESHAPE(tmp, (/3, 3/))
283                        CALL section_vals_val_get(restart_section, "AVE_PV_VIR", r_vals=tmp)
284                        averages%virial%pv_virial = RESHAPE(tmp, (/3, 3/))
285                        CALL section_vals_val_get(restart_section, "AVE_PV_KIN", r_vals=tmp)
286                        averages%virial%pv_kinetic = RESHAPE(tmp, (/3, 3/))
287                        CALL section_vals_val_get(restart_section, "AVE_PV_CNSTR", r_vals=tmp)
288                        averages%virial%pv_constraint = RESHAPE(tmp, (/3, 3/))
289                        CALL section_vals_val_get(restart_section, "AVE_PV_XC", r_vals=tmp)
290                        averages%virial%pv_xc = RESHAPE(tmp, (/3, 3/))
291                        CALL section_vals_val_get(restart_section, "AVE_PV_FOCK_4C", r_vals=tmp)
292                        averages%virial%pv_fock_4c = RESHAPE(tmp, (/3, 3/))
293                     END IF
294                  END IF
295                  ! Colvars
296                  IF (nint > 0) THEN
297                     CALL section_vals_val_get(restart_section, "AVE_COLVARS", r_vals=cvalues)
298                     CALL section_vals_val_get(restart_section, "AVE_MMATRIX", r_vals=Mmatrix)
299                     CPASSERT(nint == SIZE(cvalues))
300                     CPASSERT(nint*nint == SIZE(Mmatrix))
301                     averages%avecolvar = cvalues
302                     averages%aveMmatrix = Mmatrix
303                  END IF
304               ELSE
305                  averages%itimes_start = itimes
306               END IF
307            END IF
308            delta_t = itimes - averages%itimes_start + 1
309
310            ! Perform averages
311            SELECT CASE (delta_t)
312            CASE (1)
313               averages%avecpu = used_time
314               averages%avehugoniot = hugoniot
315               averages%avetemp_baro = md_ener%temp_baro
316               averages%avepot = md_ener%epot
317               averages%avekin = md_ener%ekin
318               averages%avetemp = md_ener%temp_part
319               averages%avekin_qm = md_ener%ekin_qm
320               averages%avetemp_qm = md_ener%temp_qm
321               averages%avevol = cell%deth
322               averages%aveca = abc(1)
323               averages%avecb = abc(2)
324               averages%avecc = abc(3)
325               averages%aveal = cell_angle(3)
326               averages%avebe = cell_angle(2)
327               averages%avega = cell_angle(1)
328               averages%econs = 0._dp
329               ! Virial
330               IF (virial%pv_availability) THEN
331                  averages%avepress = pv_scalar
332                  averages%avepxx = pv_xx
333                  IF (ASSOCIATED(averages%virial)) THEN
334                     averages%virial%pv_total = virial%pv_total
335                     averages%virial%pv_virial = virial%pv_virial
336                     averages%virial%pv_kinetic = virial%pv_kinetic
337                     averages%virial%pv_constraint = virial%pv_constraint
338                     averages%virial%pv_xc = virial%pv_xc
339                     averages%virial%pv_fock_4c = virial%pv_fock_4c
340                  END IF
341               END IF
342               ! Colvars
343               IF (nint > 0) THEN
344                  CALL get_clv_force(force_env, nsize_xyz=nat*3, nsize_int=nint, &
345                                     cvalues=averages%avecolvar, Mmatrix=averages%aveMmatrix)
346               END IF
347            CASE DEFAULT
348               CALL get_averages(averages%avecpu, used_time, delta_t)
349               CALL get_averages(averages%avehugoniot, hugoniot, delta_t)
350               CALL get_averages(averages%avetemp_baro, md_ener%temp_baro, delta_t)
351               CALL get_averages(averages%avepot, md_ener%epot, delta_t)
352               CALL get_averages(averages%avekin, md_ener%ekin, delta_t)
353               CALL get_averages(averages%avetemp, md_ener%temp_part, delta_t)
354               CALL get_averages(averages%avekin_qm, md_ener%ekin_qm, delta_t)
355               CALL get_averages(averages%avetemp_qm, md_ener%temp_qm, delta_t)
356               CALL get_averages(averages%avevol, cell%deth, delta_t)
357               CALL get_averages(averages%aveca, abc(1), delta_t)
358               CALL get_averages(averages%avecb, abc(2), delta_t)
359               CALL get_averages(averages%avecc, abc(3), delta_t)
360               CALL get_averages(averages%aveal, cell_angle(3), delta_t)
361               CALL get_averages(averages%avebe, cell_angle(2), delta_t)
362               CALL get_averages(averages%avega, cell_angle(1), delta_t)
363               CALL get_averages(averages%econs, md_ener%delta_cons, delta_t)
364               ! Virial
365               IF (virial%pv_availability) THEN
366                  CALL get_averages(averages%avepress, pv_scalar, delta_t)
367                  CALL get_averages(averages%avepxx, pv_xx, delta_t)
368                  IF (ASSOCIATED(averages%virial)) THEN
369                     CALL get_averages(averages%virial%pv_total, virial%pv_total, delta_t)
370                     CALL get_averages(averages%virial%pv_virial, virial%pv_virial, delta_t)
371                     CALL get_averages(averages%virial%pv_kinetic, virial%pv_kinetic, delta_t)
372                     CALL get_averages(averages%virial%pv_constraint, virial%pv_constraint, delta_t)
373                     CALL get_averages(averages%virial%pv_xc, virial%pv_xc, delta_t)
374                     CALL get_averages(averages%virial%pv_fock_4c, virial%pv_fock_4c, delta_t)
375                  END IF
376               END IF
377               ! Colvars
378               IF (nint > 0) THEN
379                  ALLOCATE (cvalues(nint))
380                  ALLOCATE (Mmatrix(nint*nint))
381                  CALL get_clv_force(force_env, nsize_xyz=nat*3, nsize_int=nint, cvalues=cvalues, &
382                                     Mmatrix=Mmatrix)
383                  CALL get_averages(averages%avecolvar, cvalues, delta_t)
384                  CALL get_averages(averages%aveMmatrix, Mmatrix, delta_t)
385                  DEALLOCATE (cvalues)
386                  DEALLOCATE (Mmatrix)
387               END IF
388            END SELECT
389         END IF
390
391         ! Possibly print averages
392         output_unit = cp_print_key_unit_nr(logger, averages%averages_section, "PRINT_AVERAGES", &
393                                            extension=".avg", file_position=my_pos, file_action=my_act)
394         IF (output_unit > 0) THEN
395            WRITE (output_unit, FMT='(A15,1X,"=",1X,G15.9,"   NSTEP #",I15)') &
396               "AVECPU", averages%avecpu, itimes, &
397               "AVEHUGONIOT", averages%avehugoniot, itimes, &
398               "AVETEMP_BARO", averages%avetemp_baro, itimes, &
399               "AVEPOT", averages%avepot, itimes, &
400               "AVEKIN", averages%avekin, itimes, &
401               "AVETEMP", averages%avetemp, itimes, &
402               "AVEKIN_QM", averages%avekin_qm, itimes, &
403               "AVETEMP_QM", averages%avetemp_qm, itimes, &
404               "AVEVOL", averages%avevol, itimes, &
405               "AVECELL_A", averages%aveca, itimes, &
406               "AVECELL_B", averages%avecb, itimes, &
407               "AVECELL_C", averages%avecc, itimes, &
408               "AVEALPHA", averages%aveal, itimes, &
409               "AVEBETA", averages%avebe, itimes, &
410               "AVEGAMMA", averages%avega, itimes, &
411               "AVE_ECONS", averages%econs, itimes
412            ! Print the virial
413            IF (virial%pv_availability) THEN
414               WRITE (output_unit, FMT='(A15,1X,"=",1X,G15.9,"   NSTEP #",I15)') &
415                  "AVE_PRESS", averages%avepress, itimes, &
416                  "AVE_PXX", averages%avepxx, itimes
417               IF (ASSOCIATED(averages%virial)) THEN
418                  WRITE (output_unit, FMT='(A15,1X,"=",1X,G15.9,"   NSTEP #",I15)') &
419                     "AVE_PV_TOT", averages%virial%pv_total, itimes, &
420                     "AVE_PV_VIR", averages%virial%pv_virial, itimes, &
421                     "AVE_PV_KIN", averages%virial%pv_kinetic, itimes, &
422                     "AVE_PV_CNSTR", averages%virial%pv_constraint, itimes, &
423                     "AVE_PV_XC", averages%virial%pv_xc, itimes, &
424                     "AVE_PV_FOCK_4C", averages%virial%pv_fock_4c, itimes
425               END IF
426            END IF
427            DO i = 1, nint
428               ctmp = cp_to_string(i)
429               WRITE (output_unit, FMT='(A15,1X,"=",1X,G15.9,"   NSTEP #",I15)') &
430                  TRIM("AVE_CV-"//ADJUSTL(ctmp)), averages%avecolvar(i), itimes
431            END DO
432            WRITE (output_unit, FMT='(/)')
433         END IF
434         CALL cp_print_key_finished_output(output_unit, logger, averages%averages_section, &
435                                           "PRINT_AVERAGES")
436      END IF
437      CALL timestop(handle)
438   END SUBROUTINE compute_averages
439
440! **************************************************************************************************
441!> \brief computes the averages - low level for REAL
442!> \param avg ...
443!> \param add ...
444!> \param delta_t ...
445!> \author Teodoro Laino [tlaino] - 03.2008 - University of Zurich
446! **************************************************************************************************
447   SUBROUTINE get_averages_rs(avg, add, delta_t)
448      REAL(KIND=dp), INTENT(INOUT)                       :: avg
449      REAL(KIND=dp), INTENT(IN)                          :: add
450      INTEGER, INTENT(IN)                                :: delta_t
451
452      CHARACTER(len=*), PARAMETER :: routineN = 'get_averages_rs', &
453         routineP = moduleN//':'//routineN
454
455      avg = (avg*REAL(delta_t - 1, dp) + add)/REAL(delta_t, dp)
456   END SUBROUTINE get_averages_rs
457
458! **************************************************************************************************
459!> \brief computes the averages - low level for REAL vector
460!> \param avg ...
461!> \param add ...
462!> \param delta_t ...
463!> \author Teodoro Laino [tlaino] - 10.2008 - University of Zurich
464! **************************************************************************************************
465   SUBROUTINE get_averages_rv(avg, add, delta_t)
466      REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: avg
467      REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: add
468      INTEGER, INTENT(IN)                                :: delta_t
469
470      CHARACTER(len=*), PARAMETER :: routineN = 'get_averages_rv', &
471         routineP = moduleN//':'//routineN
472
473      INTEGER                                            :: i
474      LOGICAL                                            :: check
475
476      check = SIZE(avg) == SIZE(add)
477      CPASSERT(check)
478      DO i = 1, SIZE(avg)
479         avg(i) = (avg(i)*REAL(delta_t - 1, dp) + add(i))/REAL(delta_t, dp)
480      END DO
481   END SUBROUTINE get_averages_rv
482
483! **************************************************************************************************
484!> \brief computes the averages - low level for REAL matrix
485!> \param avg ...
486!> \param add ...
487!> \param delta_t ...
488!> \author Teodoro Laino [tlaino] - 10.2008 - University of Zurich
489! **************************************************************************************************
490   SUBROUTINE get_averages_rm(avg, add, delta_t)
491      REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: avg
492      REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: add
493      INTEGER, INTENT(IN)                                :: delta_t
494
495      CHARACTER(len=*), PARAMETER :: routineN = 'get_averages_rm', &
496         routineP = moduleN//':'//routineN
497
498      INTEGER                                            :: i, j
499      LOGICAL                                            :: check
500
501      check = SIZE(avg, 1) == SIZE(add, 1)
502      CPASSERT(check)
503      check = SIZE(avg, 2) == SIZE(add, 2)
504      CPASSERT(check)
505      DO i = 1, SIZE(avg, 2)
506         DO j = 1, SIZE(avg, 1)
507            avg(j, i) = (avg(j, i)*REAL(delta_t - 1, dp) + add(j, i))/REAL(delta_t, dp)
508         END DO
509      END DO
510   END SUBROUTINE get_averages_rm
511
512END MODULE averages_types
513