LCOV - code coverage report
Current view: top level - src - atomic_charges.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:262480d) Lines: 39 75 52.0 %
Date: 2024-11-22 07:00:40 Functions: 1 3 33.3 %

          Line data    Source code
       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             : !> \brief simple routine to print charges for all atomic charge methods
      10             : !>      (currently mulliken, lowdin and ddapc)
      11             : !> \par History
      12             : !>      Joost VandeVondele [2006.03]
      13             : ! **************************************************************************************************
      14             : MODULE atomic_charges
      15             :    USE atomic_kind_types,               ONLY: get_atomic_kind
      16             :    USE kinds,                           ONLY: dp
      17             :    USE particle_types,                  ONLY: particle_type
      18             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      19             :                                               qs_kind_type
      20             : #include "./base/base_uses.f90"
      21             : 
      22             :    IMPLICIT NONE
      23             : 
      24             :    PRIVATE
      25             : 
      26             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'atomic_charges'
      27             : 
      28             :    PUBLIC :: print_atomic_charges, print_bond_orders
      29             : 
      30             : CONTAINS
      31             : 
      32             : ! **************************************************************************************************
      33             : !> \brief generates a unified output format for atomic charges
      34             : !> \param particle_set ...
      35             : !> \param qs_kind_set ...
      36             : !> \param scr ...
      37             : !> \param title ...
      38             : !> \param electronic_charges (natom,nspin), the number of electrons of (so positive) per spin
      39             : !>                            if (nspin==1) it is the sum of alpha and beta electrons
      40             : !> \param atomic_charges truly the atomic charge (taking Z into account, atoms negative, no spin)
      41             : !> \par History
      42             : !>      03.2006 created [Joost VandeVondele]
      43             : !> \note
      44             : !>      charges are computed per spin in the LSD case
      45             : ! **************************************************************************************************
      46        2780 :    SUBROUTINE print_atomic_charges(particle_set, qs_kind_set, scr, title, electronic_charges, &
      47        1390 :                                    atomic_charges)
      48             : 
      49             :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
      50             :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN)       :: qs_kind_set
      51             :       INTEGER, INTENT(IN)                                :: scr
      52             :       CHARACTER(LEN=*), INTENT(IN)                       :: title
      53             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
      54             :          OPTIONAL                                        :: electronic_charges
      55             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: atomic_charges
      56             : 
      57             :       CHARACTER(len=*), PARAMETER :: routineN = 'print_atomic_charges'
      58             : 
      59             :       CHARACTER(LEN=2)                                   :: element_symbol
      60             :       INTEGER                                            :: handle, iatom, ikind, natom, nspin
      61             :       REAL(KIND=dp)                                      :: total_charge, zeff
      62             : 
      63        1390 :       CALL timeset(routineN, handle)
      64             : 
      65        1390 :       IF (PRESENT(electronic_charges)) THEN
      66          34 :          nspin = SIZE(electronic_charges, 2)
      67          34 :          natom = SIZE(electronic_charges, 1)
      68             :       ELSE
      69        1356 :          CPASSERT(PRESENT(atomic_charges))
      70        1356 :          natom = SIZE(atomic_charges, 1)
      71        1356 :          nspin = 0
      72             :       END IF
      73             : 
      74        1390 :       IF (scr > 0) THEN
      75         325 :          IF (SIZE(particle_set) /= natom) THEN
      76           0 :             CPABORT("Unexpected number of atoms/charges")
      77             :          END IF
      78         325 :          WRITE (scr, '(T2,A)') title
      79         324 :          SELECT CASE (nspin)
      80             :          CASE (0, 1)
      81         324 :             IF (title == "RESP charges:") THEN
      82           7 :                WRITE (scr, '(A)') "  Type |   Atom   |    Charge"
      83             :             ELSE
      84         317 :                WRITE (scr, '(A)') "  Atom     |    Charge"
      85             :             END IF
      86             :          CASE DEFAULT
      87         325 :             WRITE (scr, '(A)') "  Atom     |    Charge | Spin diff charge"
      88             :          END SELECT
      89         325 :          total_charge = 0.0_dp
      90             :          !WRITE (scr, '(A)') ""
      91        1221 :          DO iatom = 1, natom
      92             :             CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, &
      93         896 :                                  element_symbol=element_symbol, kind_number=ikind)
      94         896 :             CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
      95             : 
      96        1221 :             SELECT CASE (nspin)
      97             :             CASE (0)
      98         835 :                IF (title == "RESP charges:") THEN
      99          45 :                   WRITE (scr, '(T3,A4,2X,I6,A2,A2,F12.6)') "RESP", iatom, "  ", element_symbol, atomic_charges(iatom)
     100          45 :                   total_charge = total_charge + atomic_charges(iatom)
     101             :                ELSE
     102         790 :                   WRITE (scr, '(I6,A2,A2,F12.6)') iatom, "  ", element_symbol, atomic_charges(iatom)
     103         790 :                   total_charge = total_charge + atomic_charges(iatom)
     104             :                END IF
     105             :             CASE (1)
     106          58 :                WRITE (scr, '(I6,A2,A2,F12.6)') iatom, "  ", element_symbol, zeff - electronic_charges(iatom, 1)
     107          58 :                total_charge = total_charge + zeff - electronic_charges(iatom, 1)
     108             :             CASE DEFAULT
     109           3 :                WRITE (scr, '(I6,A2,A2,2F12.6)') iatom, "  ", element_symbol, &
     110           3 :                   zeff - (electronic_charges(iatom, 1) + electronic_charges(iatom, 2)), &
     111           6 :                   (electronic_charges(iatom, 1) - electronic_charges(iatom, 2))
     112         899 :                total_charge = total_charge + zeff - (electronic_charges(iatom, 1) + electronic_charges(iatom, 2))
     113             :             END SELECT
     114             :          END DO
     115         325 :          IF (title == "RESP charges:") THEN
     116           7 :             WRITE (scr, '(A,F10.6)') "  Total             ", total_charge
     117             :          ELSE
     118         318 :             WRITE (scr, '(A,F10.6)') "  Total     ", total_charge
     119             :          END IF
     120         325 :          WRITE (scr, '(A)') ""
     121             :       END IF
     122             : 
     123        1390 :       CALL timestop(handle)
     124             : 
     125        1390 :    END SUBROUTINE print_atomic_charges
     126             : 
     127             : ! **************************************************************************************************
     128             : !> \brief ...
     129             : !> \param particle_set ...
     130             : !> \param qs_kind_set ...
     131             : !> \param scr ...
     132             : !> \param charge ...
     133             : !> \param dipole ...
     134             : !> \param quadrupole ...
     135             : ! **************************************************************************************************
     136           0 :    SUBROUTINE print_multipoles(particle_set, qs_kind_set, scr, charge, dipole, quadrupole)
     137             : 
     138             :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     139             :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN)       :: qs_kind_set
     140             :       INTEGER, INTENT(IN)                                :: scr
     141             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: charge
     142             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     143             :          OPTIONAL                                        :: dipole
     144             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN), &
     145             :          OPTIONAL                                        :: quadrupole
     146             : 
     147             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'print_multipoles'
     148             : 
     149             :       CHARACTER(LEN=2)                                   :: element_symbol
     150             :       INTEGER                                            :: handle, i, iatom, ikind, natom
     151             :       REAL(KIND=dp)                                      :: zeff
     152             : 
     153           0 :       CALL timeset(routineN, handle)
     154             : 
     155           0 :       natom = 0
     156           0 :       IF (PRESENT(charge)) THEN
     157           0 :          natom = SIZE(charge)
     158             :       END IF
     159             : 
     160           0 :       IF (scr > 0) THEN
     161             : 
     162           0 :          WRITE (scr, '(T2,A)') 'multipoles:'
     163             : 
     164           0 :          DO iatom = 1, natom
     165             :             CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, &
     166           0 :                                  element_symbol=element_symbol, kind_number=ikind)
     167           0 :             CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
     168             : 
     169           0 :             WRITE (scr, '(a,i5)') ' iatom= ', iatom
     170           0 :             WRITE (scr, '(a,a2)') ' element_symbol= ', element_symbol
     171           0 :             WRITE (scr, '(a,f20.10)') ' zeff= ', zeff
     172             : 
     173           0 :             WRITE (scr, '(a, f20.10)') 'charge =     ', charge(iatom)
     174           0 :             WRITE (scr, '(a,3f20.10)') 'dipole =     ', dipole(:, iatom)
     175           0 :             WRITE (scr, '(a)') 'quadrupole = '
     176           0 :             DO i = 1, 3
     177           0 :                WRITE (scr, '(3f20.10)') quadrupole(i, :, iatom)
     178             :             END DO
     179             : 
     180             :          END DO
     181           0 :          WRITE (scr, '(A)') ""
     182             :       END IF
     183             : 
     184           0 :       CALL timestop(handle)
     185             : 
     186           0 :    END SUBROUTINE print_multipoles
     187             : 
     188             : ! **************************************************************************************************
     189             : !> \brief Print Mayer bond orders
     190             : !> \param particle_set ...
     191             : !> \param scr ...
     192             : !> \param bond_orders (natom,natom)
     193             : !> \par History
     194             : !>      12.2016 created [JGH]
     195             : ! **************************************************************************************************
     196           0 :    SUBROUTINE print_bond_orders(particle_set, scr, bond_orders)
     197             : 
     198             :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     199             :       INTEGER, INTENT(IN)                                :: scr
     200             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: bond_orders
     201             : 
     202             :       CHARACTER(LEN=2)                                   :: el1, el2
     203             :       INTEGER                                            :: iatom, jatom, natom
     204             : 
     205           0 :       IF (scr > 0) THEN
     206           0 :          natom = SIZE(bond_orders, 1)
     207           0 :          IF (SIZE(particle_set) /= natom) THEN
     208           0 :             CPABORT("Unexpected number of atoms/charges")
     209             :          END IF
     210           0 :          WRITE (scr, '(/,T2,A)') "Mayer Bond Orders"
     211           0 :          WRITE (scr, '(T2,A,T20,A,T40,A)') "  Type  Atom 1  ", "  Type  Atom 2  ", " Bond Order "
     212           0 :          DO iatom = 1, natom
     213           0 :             CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=el1)
     214           0 :             DO jatom = iatom + 1, natom
     215           0 :                CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, element_symbol=el2)
     216           0 :                IF (bond_orders(iatom, jatom) > 0.1_dp) THEN
     217           0 :                   WRITE (scr, '(T6,A2,I6,T24,A2,I6,T40,F12.6)') el1, iatom, el2, jatom, bond_orders(iatom, jatom)
     218             :                END IF
     219             :             END DO
     220             :          END DO
     221             :       END IF
     222             : 
     223           0 :    END SUBROUTINE print_bond_orders
     224             : 
     225             : END MODULE atomic_charges

Generated by: LCOV version 1.15