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