1!--------------------------------------------------------------------------------------------------! 2! CP2K: A general program to perform molecular dynamics simulations ! 3! Copyright (C) 2000 - 2019 CP2K developers group ! 4!--------------------------------------------------------------------------------------------------! 5 6! ************************************************************************************************** 7!> \brief New version of the module for the localization of the molecular orbitals 8!> This should be able to use different definition of the spread functional 9!> It should also calculate the integrals analytically so that it can be 10!> used irrespective of the pw_env and the collocation of wfn on the grids 11!> It should also work with a selected set of states, instead than all of them, 12!> in this case one should check that the selected states have the same occupation number 13!> The spread functional can be only estimated, or also optimized by minimization 14!> and in principle also maximization should be available. 15!> This operations can be required irrespective of the printing requirements 16!> It would be highly desirable to do all this along a MD run every N steps, 17!> and have a trajectory of the centeroids of the localized wfn 18!> In addition these functions can be used for properties calculations 19!> like NMR and XAS. Therefore it is necessary that the rotated wfn are then copied 20!> in the mos fm matrix to be available for next use. 21!> \author MI (05-2005) 22! ************************************************************************************************** 23MODULE qs_loc_types 24 25 USE cell_types, ONLY: cell_release,& 26 cell_retain,& 27 cell_type 28 USE cp_array_utils, ONLY: cp_2d_r_p_type 29 USE cp_fm_types, ONLY: cp_fm_p_type,& 30 cp_fm_release 31 USE cp_para_env, ONLY: cp_para_env_release,& 32 cp_para_env_retain 33 USE cp_para_types, ONLY: cp_para_env_type 34 USE dbcsr_api, ONLY: dbcsr_deallocate_matrix,& 35 dbcsr_p_type 36 USE distribution_1d_types, ONLY: distribution_1d_release,& 37 distribution_1d_retain,& 38 distribution_1d_type 39 USE kinds, ONLY: default_string_length,& 40 dp 41 USE particle_types, ONLY: particle_type 42#include "./base/base_uses.f90" 43 44 IMPLICIT NONE 45 46 PRIVATE 47 48! *** Global parameters *** 49 50 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_loc_types' 51 52!****t* qs_loc_types/qs_loc_env_new_type [1.0] * 53 54! ************************************************************************************************** 55!> \brief contains all the info needed by quickstep to calculate 56!> the spread of a selected set of orbitals and if required 57!> to minimize or maximize the spread by rotation of the orbitals 58!> \param para_env info for the distribution of the calculations 59!> \param mo_coeff full matrix containing only the selected subset of orbitals 60!> \param local_molecules molecules distributed 61!> \param cell box that contains the system 62!> \param localized_wfn_control variables and parameter that define the spread 63!> functional and the optimization algorithm 64!> \param particle_set position, type, ao_indexes etc for each atom 65!> \param op_sm_set set of sparse matrices used to define the spread operator 66!> when the functional is defined by the use operator acting on the 67!> basis functions, e.g. the Berry phase definition 68!> The matrix element of the type <a|O|b> are computed in initialization 69!> of qs_loc_env 70!> \param op_fm_set set of full matrices used to define the spread operator 71!> when the functional has to be defined directly using the products of MOS 72!> as in the case of the Pipek-Mezek definition. 73!> \param weights for a spread defined as extension of the orbitral in the box, these 74!> factors renormalize with respect to the box size 75!> \note 76!> this type should replace the previous set up for the localization of the wfn 77!> \par History 78!> 04-05 created 79!> \author MI 80! ************************************************************************************************** 81 TYPE qs_loc_env_new_type 82 INTEGER :: ref_count 83 LOGICAL :: molecular_states, do_localize, first_time 84 LOGICAL :: wannier_states 85 CHARACTER(LEN=default_string_length) :: tag_mo 86 TYPE(cp_para_env_type), POINTER :: para_env 87 TYPE(cp_fm_p_type), DIMENSION(:), & 88 POINTER :: moloc_coeff 89 TYPE(cp_fm_p_type), DIMENSION(:, :), & 90 POINTER :: op_fm_set 91 TYPE(distribution_1d_type), POINTER :: local_molecules 92 TYPE(cell_type), POINTER :: cell 93 TYPE(localized_wfn_control_type), & 94 POINTER :: localized_wfn_control 95 TYPE(particle_type), DIMENSION(:), & 96 POINTER :: particle_set 97 TYPE(dbcsr_p_type), DIMENSION(:, :), & 98 POINTER :: op_sm_set 99 100 REAL(KIND=dp) :: start_time, target_time 101 REAL(KIND=dp) :: weights(6) 102 INTEGER :: dim_op 103 END TYPE qs_loc_env_new_type 104 105! ************************************************************************************************** 106!> \brief A type that holds controling information for the 107!> calculation of the spread of wfn and the optimization of 108!> the spread functional 109!> \param ref_count ... 110!> \param localization_method which algorithm is used for the optimization 111!> \param operator_type how the spread is defined 112!> \param nloc_states number of states on which the spread is computed 113!> \param set_of_states how to choose the states 114!> \param lu_bound_states lower and upper bounds of the set of states 115!> print_cubes: 116!> print_centers: 117!> print_spreads: 118!> \param loc_states list of states on which the spread is computed 119!> \param centers_set arrais containing centers and spreads of the selected wfn 120!> \param centers_file_name output file names 121!> \param spreads_file_name output file names 122! ************************************************************************************************** 123 TYPE localized_wfn_control_type 124 INTEGER :: ref_count 125 INTEGER :: min_or_max 126 INTEGER :: localization_method 127 INTEGER :: operator_type 128 INTEGER, DIMENSION(2) :: nloc_states 129 INTEGER :: set_of_states 130 INTEGER, DIMENSION(2, 2) :: lu_bound_states 131 INTEGER :: max_iter 132 INTEGER :: out_each 133 REAL(KIND=dp) :: eps_localization 134 REAL(KIND=dp) :: max_crazy_angle 135 REAL(KIND=dp) :: crazy_scale 136 REAL(KIND=dp) :: eps_occ 137 REAL(KIND=dp), DIMENSION(2) :: lu_ene_bound 138 LOGICAL :: crazy_use_diag 139 LOGICAL :: print_cubes, jacobi_fallback, jacobi_refinement 140 LOGICAL :: print_centers 141 LOGICAL :: print_spreads 142 LOGICAL :: do_homo 143 LOGICAL :: loc_restart 144 LOGICAL :: use_history 145 INTEGER, POINTER, DIMENSION(:, :) :: loc_states 146 TYPE(cp_2d_r_p_type), DIMENSION(2) :: centers_set 147 END TYPE localized_wfn_control_type 148 149! *** Public *** 150 PUBLIC :: qs_loc_env_create, qs_loc_env_destroy, & 151 qs_loc_env_release, qs_loc_env_retain, & 152 get_qs_loc_env, set_qs_loc_env, & 153 localized_wfn_control_create, localized_wfn_control_release 154 PUBLIC :: qs_loc_env_new_type, localized_wfn_control_type 155 156CONTAINS 157 158!****f* qs_loc_types/qs_loc_env_create [1.0] * 159 160! ************************************************************************************************** 161!> \brief ... 162!> \param qs_loc_env ... 163!> \par History 164!> 04-05 created 165!> \author MI 166! ************************************************************************************************** 167 SUBROUTINE qs_loc_env_create(qs_loc_env) 168 169 TYPE(qs_loc_env_new_type), POINTER :: qs_loc_env 170 171 CHARACTER(len=*), PARAMETER :: routineN = 'qs_loc_env_create', & 172 routineP = moduleN//':'//routineN 173 174 CPASSERT(.NOT. ASSOCIATED(qs_loc_env)) 175 176 ALLOCATE (qs_loc_env) 177 178 qs_loc_env%ref_count = 1 179 qs_loc_env%tag_mo = "" 180 NULLIFY (qs_loc_env%para_env) 181 NULLIFY (qs_loc_env%cell) 182 NULLIFY (qs_loc_env%op_sm_set) 183 NULLIFY (qs_loc_env%op_fm_set) 184 NULLIFY (qs_loc_env%local_molecules) 185 NULLIFY (qs_loc_env%moloc_coeff) 186 NULLIFY (qs_loc_env%particle_set) 187 NULLIFY (qs_loc_env%localized_wfn_control) 188 qs_loc_env%weights = 0.0_dp 189 190 END SUBROUTINE qs_loc_env_create 191 192!****f* qs_loc_types/qs_loc_env_destroy [1.0] * 193 194! ************************************************************************************************** 195!> \brief ... 196!> \param qs_loc_env ... 197!> \par History 198!> 04-05 created 199!> \author MI 200! ************************************************************************************************** 201 SUBROUTINE qs_loc_env_destroy(qs_loc_env) 202 203 TYPE(qs_loc_env_new_type), POINTER :: qs_loc_env 204 205 CHARACTER(len=*), PARAMETER :: routineN = 'qs_loc_env_destroy', & 206 routineP = moduleN//':'//routineN 207 208 INTEGER :: i, ii, j 209 210 CPASSERT(ASSOCIATED(qs_loc_env)) 211 212 IF (ASSOCIATED(qs_loc_env%cell)) CALL cell_release(qs_loc_env%cell) 213 IF (ASSOCIATED(qs_loc_env%local_molecules)) & 214 CALL distribution_1d_release(qs_loc_env%local_molecules) 215 IF (ASSOCIATED(qs_loc_env%localized_wfn_control)) THEN 216 CALL localized_wfn_control_release(qs_loc_env%localized_wfn_control) 217 END IF 218 IF (ASSOCIATED(qs_loc_env%para_env)) CALL cp_para_env_release(qs_loc_env%para_env) 219 IF (ASSOCIATED(qs_loc_env%particle_set)) NULLIFY (qs_loc_env%particle_set) 220 221 IF (ASSOCIATED(qs_loc_env%moloc_coeff)) THEN 222 DO i = 1, SIZE(qs_loc_env%moloc_coeff, 1) 223 ii = LBOUND(qs_loc_env%moloc_coeff, 1) + i - 1 224 CALL cp_fm_release(qs_loc_env%moloc_coeff(ii)%matrix) 225 END DO 226 DEALLOCATE (qs_loc_env%moloc_coeff) 227 END IF 228 229 IF (ASSOCIATED(qs_loc_env%op_fm_set)) THEN 230 DO i = 1, SIZE(qs_loc_env%op_fm_set, 2) 231 DO j = 1, SIZE(qs_loc_env%op_fm_set, 1) 232 CALL cp_fm_release(qs_loc_env%op_fm_set(j, i)%matrix) 233 END DO 234 END DO 235 DEALLOCATE (qs_loc_env%op_fm_set) 236 END IF 237 238 IF (ASSOCIATED(qs_loc_env%op_sm_set)) THEN 239 DO i = 1, SIZE(qs_loc_env%op_sm_set, 2) 240 DO j = 1, SIZE(qs_loc_env%op_sm_set, 1) 241 CALL dbcsr_deallocate_matrix(qs_loc_env%op_sm_set(j, i)%matrix) 242 ENDDO 243 END DO 244 DEALLOCATE (qs_loc_env%op_sm_set) 245 END IF 246 247 DEALLOCATE (qs_loc_env) 248 249 END SUBROUTINE qs_loc_env_destroy 250 251!****f* qs_loc_types/qs_loc_env_release [1.0] * 252 253! ************************************************************************************************** 254!> \brief ... 255!> \param qs_loc_env ... 256!> \par History 257!> 04-05 created 258!> \author MI 259! ************************************************************************************************** 260 SUBROUTINE qs_loc_env_release(qs_loc_env) 261 262 TYPE(qs_loc_env_new_type), POINTER :: qs_loc_env 263 264 CHARACTER(len=*), PARAMETER :: routineN = 'qs_loc_env_release', & 265 routineP = moduleN//':'//routineN 266 267 IF (ASSOCIATED(qs_loc_env)) THEN 268 CPASSERT(qs_loc_env%ref_count > 0) 269 qs_loc_env%ref_count = qs_loc_env%ref_count - 1 270 IF (qs_loc_env%ref_count == 0) THEN 271 CALL qs_loc_env_destroy(qs_loc_env) 272 END IF 273 END IF 274 END SUBROUTINE qs_loc_env_release 275 276!****f* qs_loc_types/qs_loc_env_retain [1.0] * 277 278! ************************************************************************************************** 279!> \brief ... 280!> \param qs_loc_env ... 281!> \par History 282!> 04-05 created 283!> \author MI 284! ************************************************************************************************** 285 SUBROUTINE qs_loc_env_retain(qs_loc_env) 286 287 TYPE(qs_loc_env_new_type), POINTER :: qs_loc_env 288 289 CHARACTER(len=*), PARAMETER :: routineN = 'qs_loc_env_retain', & 290 routineP = moduleN//':'//routineN 291 292 CPASSERT(ASSOCIATED(qs_loc_env)) 293 CPASSERT(qs_loc_env%ref_count > 0) 294 qs_loc_env%ref_count = qs_loc_env%ref_count + 1 295 END SUBROUTINE qs_loc_env_retain 296 297! ************************************************************************************************** 298!> \brief create the localized_wfn_control_type 299!> \param localized_wfn_control ... 300!> \par History 301!> 04.2005 created [MI] 302! ************************************************************************************************** 303 SUBROUTINE localized_wfn_control_create(localized_wfn_control) 304 TYPE(localized_wfn_control_type), POINTER :: localized_wfn_control 305 306 CHARACTER(len=*), PARAMETER :: routineN = 'localized_wfn_control_create', & 307 routineP = moduleN//':'//routineN 308 309 CPASSERT(.NOT. ASSOCIATED(localized_wfn_control)) 310 ALLOCATE (localized_wfn_control) 311 312 localized_wfn_control%ref_count = 1 313 localized_wfn_control%nloc_states = 0 314 localized_wfn_control%lu_bound_states = 0 315 localized_wfn_control%lu_ene_bound = 0.0_dp 316 localized_wfn_control%print_cubes = .FALSE. 317 localized_wfn_control%print_centers = .FALSE. 318 localized_wfn_control%print_spreads = .FALSE. 319 localized_wfn_control%do_homo = .TRUE. 320 localized_wfn_control%use_history = .FALSE. 321 NULLIFY (localized_wfn_control%loc_states) 322 NULLIFY (localized_wfn_control%centers_set(1)%array) 323 NULLIFY (localized_wfn_control%centers_set(2)%array) 324 END SUBROUTINE localized_wfn_control_create 325 326! ************************************************************************************************** 327!> \brief release the localized_wfn_control_type 328!> \param localized_wfn_control ... 329!> \par History 330!> 04.2005 created [MI] 331! ************************************************************************************************** 332 SUBROUTINE localized_wfn_control_release(localized_wfn_control) 333 334 TYPE(localized_wfn_control_type), POINTER :: localized_wfn_control 335 336 CHARACTER(len=*), PARAMETER :: routineN = 'localized_wfn_control_release', & 337 routineP = moduleN//':'//routineN 338 339 IF (ASSOCIATED(localized_wfn_control)) THEN 340 CPASSERT(localized_wfn_control%ref_count > 0) 341 localized_wfn_control%ref_count = localized_wfn_control%ref_count - 1 342 IF (localized_wfn_control%ref_count == 0) THEN 343 IF (ASSOCIATED(localized_wfn_control%loc_states)) THEN 344 DEALLOCATE (localized_wfn_control%loc_states) 345 ENDIF 346 IF (ASSOCIATED(localized_wfn_control%centers_set(1)%array)) THEN 347 DEALLOCATE (localized_wfn_control%centers_set(1)%array) 348 ENDIF 349 IF (ASSOCIATED(localized_wfn_control%centers_set(2)%array)) THEN 350 DEALLOCATE (localized_wfn_control%centers_set(2)%array) 351 ENDIF 352 localized_wfn_control%ref_count = 0 353 DEALLOCATE (localized_wfn_control) 354 ENDIF 355 END IF 356 END SUBROUTINE localized_wfn_control_release 357 358! ************************************************************************************************** 359!> \brief retain the localized_wfn_control_type 360!> \param localized_wfn_control ... 361!> \par History 362!> 04.2005 created [MI] 363! ************************************************************************************************** 364 SUBROUTINE localized_wfn_control_retain(localized_wfn_control) 365 TYPE(localized_wfn_control_type), POINTER :: localized_wfn_control 366 367 CHARACTER(len=*), PARAMETER :: routineN = 'localized_wfn_control_retain', & 368 routineP = moduleN//':'//routineN 369 370 CPASSERT(ASSOCIATED(localized_wfn_control)) 371 372 localized_wfn_control%ref_count = localized_wfn_control%ref_count + 1 373 END SUBROUTINE localized_wfn_control_retain 374 375!****f* qs_loc_types/get_qs_loc_env [1.0] * 376 377! ************************************************************************************************** 378!> \brief ... 379!> \param qs_loc_env ... 380!> \param cell ... 381!> \param local_molecules ... 382!> \param localized_wfn_control ... 383!> \param moloc_coeff ... 384!> \param op_sm_set ... 385!> \param op_fm_set ... 386!> \param para_env ... 387!> \param particle_set ... 388!> \param weights ... 389!> \param dim_op ... 390!> \par History 391!> 04-05 created 392!> \author MI 393! ************************************************************************************************** 394 SUBROUTINE get_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, & 395 moloc_coeff, op_sm_set, op_fm_set, para_env, particle_set, weights, dim_op) 396 397 TYPE(qs_loc_env_new_type), POINTER :: qs_loc_env 398 TYPE(cell_type), OPTIONAL, POINTER :: cell 399 TYPE(distribution_1d_type), OPTIONAL, POINTER :: local_molecules 400 TYPE(localized_wfn_control_type), OPTIONAL, & 401 POINTER :: localized_wfn_control 402 TYPE(cp_fm_p_type), DIMENSION(:), OPTIONAL, & 403 POINTER :: moloc_coeff 404 TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, & 405 POINTER :: op_sm_set 406 TYPE(cp_fm_p_type), DIMENSION(:, :), OPTIONAL, & 407 POINTER :: op_fm_set 408 TYPE(cp_para_env_type), OPTIONAL, POINTER :: para_env 409 TYPE(particle_type), DIMENSION(:), OPTIONAL, & 410 POINTER :: particle_set 411 REAL(dp), DIMENSION(6), OPTIONAL :: weights 412 INTEGER, OPTIONAL :: dim_op 413 414 CHARACTER(len=*), PARAMETER :: routineN = 'get_qs_loc_env', routineP = moduleN//':'//routineN 415 416 CPASSERT(ASSOCIATED(qs_loc_env)) 417 418 IF (PRESENT(cell)) cell => qs_loc_env%cell 419 IF (PRESENT(moloc_coeff)) moloc_coeff => qs_loc_env%moloc_coeff 420 IF (PRESENT(local_molecules)) local_molecules => qs_loc_env%local_molecules 421 IF (PRESENT(localized_wfn_control)) & 422 localized_wfn_control => qs_loc_env%localized_wfn_control 423 IF (PRESENT(op_sm_set)) op_sm_set => qs_loc_env%op_sm_set 424 IF (PRESENT(op_fm_set)) op_fm_set => qs_loc_env%op_fm_set 425 IF (PRESENT(para_env)) para_env => qs_loc_env%para_env 426 IF (PRESENT(particle_set)) particle_set => qs_loc_env%particle_set 427 IF (PRESENT(weights)) weights(1:6) = qs_loc_env%weights(1:6) 428 IF (PRESENT(dim_op)) dim_op = qs_loc_env%dim_op 429 430 END SUBROUTINE get_qs_loc_env 431 432!****f* qs_loc_types/set_qs_loc_env [1.0] * 433 434! ************************************************************************************************** 435!> \brief ... 436!> \param qs_loc_env ... 437!> \param cell ... 438!> \param local_molecules ... 439!> \param localized_wfn_control ... 440!> \param moloc_coeff ... 441!> \param op_sm_set ... 442!> \param op_fm_set ... 443!> \param para_env ... 444!> \param particle_set ... 445!> \param weights ... 446!> \param dim_op ... 447!> \par History 448!> 04-05 created 449!> \author MI 450! ************************************************************************************************** 451 SUBROUTINE set_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, & 452 moloc_coeff, op_sm_set, op_fm_set, para_env, particle_set, weights, dim_op) 453 454 TYPE(qs_loc_env_new_type), POINTER :: qs_loc_env 455 TYPE(cell_type), OPTIONAL, POINTER :: cell 456 TYPE(distribution_1d_type), OPTIONAL, POINTER :: local_molecules 457 TYPE(localized_wfn_control_type), OPTIONAL, & 458 POINTER :: localized_wfn_control 459 TYPE(cp_fm_p_type), DIMENSION(:), OPTIONAL, & 460 POINTER :: moloc_coeff 461 TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, & 462 POINTER :: op_sm_set 463 TYPE(cp_fm_p_type), DIMENSION(:, :), OPTIONAL, & 464 POINTER :: op_fm_set 465 TYPE(cp_para_env_type), OPTIONAL, POINTER :: para_env 466 TYPE(particle_type), DIMENSION(:), OPTIONAL, & 467 POINTER :: particle_set 468 REAL(dp), DIMENSION(6), OPTIONAL :: weights 469 INTEGER, OPTIONAL :: dim_op 470 471 CHARACTER(len=*), PARAMETER :: routineN = 'set_qs_loc_env', routineP = moduleN//':'//routineN 472 473 INTEGER :: i 474 475 CPASSERT(ASSOCIATED(qs_loc_env)) 476 IF (PRESENT(cell)) THEN 477 CALL cell_retain(cell) 478 CALL cell_release(qs_loc_env%cell) 479 qs_loc_env%cell => cell 480 END IF 481 482 IF (PRESENT(local_molecules)) THEN 483 CALL distribution_1d_retain(local_molecules) 484 IF (ASSOCIATED(qs_loc_env%local_molecules)) & 485 CALL distribution_1d_release(qs_loc_env%local_molecules) 486 qs_loc_env%local_molecules => local_molecules 487 END IF 488 489 IF (PRESENT(localized_wfn_control)) THEN 490 CALL localized_wfn_control_retain(localized_wfn_control) 491 CALL localized_wfn_control_release(qs_loc_env%localized_wfn_control) 492 qs_loc_env%localized_wfn_control => localized_wfn_control 493 END IF 494 IF (PRESENT(para_env)) THEN 495 CALL cp_para_env_retain(para_env) 496 CALL cp_para_env_release(qs_loc_env%para_env) 497 qs_loc_env%para_env => para_env 498 END IF 499 IF (PRESENT(particle_set)) qs_loc_env%particle_set => particle_set 500 IF (PRESENT(moloc_coeff)) THEN 501 IF (ASSOCIATED(qs_loc_env%moloc_coeff)) THEN 502 DO i = 1, SIZE(qs_loc_env%moloc_coeff, 1) 503 CALL cp_fm_release(qs_loc_env%moloc_coeff(i)%matrix) 504 END DO 505 DEALLOCATE (qs_loc_env%moloc_coeff) 506 END IF 507 qs_loc_env%moloc_coeff => moloc_coeff 508 END IF 509 IF (PRESENT(op_sm_set)) THEN 510 qs_loc_env%op_sm_set => op_sm_set 511 END IF 512 IF (PRESENT(op_fm_set)) THEN 513 qs_loc_env%op_fm_set => op_fm_set 514 END IF 515 IF (PRESENT(weights)) THEN 516 qs_loc_env%weights = weights 517 END IF 518 IF (PRESENT(dim_op)) THEN 519 qs_loc_env%dim_op = dim_op 520 END IF 521 522 END SUBROUTINE set_qs_loc_env 523 524END MODULE qs_loc_types 525 526