LCOV - code coverage report
Current view: top level - src/subsys - cell_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:85b8a9b) Lines: 95.5 % 178 170
Test Date: 2026-06-14 06:48:14 Functions: 83.3 % 18 15

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Handles all functions related to the CELL
      10              : !> \par History
      11              : !>      11.2008 Teodoro Laino [tlaino] - deeply cleaning cell_type from units
      12              : !>      10.2014 Moved many routines from cell_types.F here.
      13              : !> \author Matthias KracK (16.01.2002, based on a earlier version of CJM, JGH)
      14              : ! **************************************************************************************************
      15              : MODULE cell_types
      16              :    USE cp_units,                        ONLY: cp_unit_to_cp2k
      17              :    USE kinds,                           ONLY: dp
      18              :    USE mathconstants,                   ONLY: degree
      19              :    USE mathlib,                         ONLY: angle
      20              : #include "../base/base_uses.f90"
      21              : 
      22              :    IMPLICIT NONE
      23              : 
      24              :    PRIVATE
      25              : 
      26              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cell_types'
      27              : 
      28              :    ! Impose cell symmetry
      29              :    INTEGER, PARAMETER, PUBLIC               :: cell_sym_none = 0, &
      30              :                                                cell_sym_triclinic = 1, &
      31              :                                                cell_sym_monoclinic = 2, &
      32              :                                                cell_sym_monoclinic_gamma_ab = 3, &
      33              :                                                cell_sym_orthorhombic = 4, &
      34              :                                                cell_sym_tetragonal_ab = 5, &
      35              :                                                cell_sym_tetragonal_ac = 6, &
      36              :                                                cell_sym_tetragonal_bc = 7, &
      37              :                                                cell_sym_rhombohedral = 8, &
      38              :                                                cell_sym_hexagonal_gamma_60 = 9, &
      39              :                                                cell_sym_hexagonal_gamma_120 = 10, &
      40              :                                                cell_sym_cubic = 11
      41              : 
      42              :    INTEGER, PARAMETER, PUBLIC               :: use_perd_none = 0, &
      43              :                                                use_perd_x = 1, &
      44              :                                                use_perd_y = 2, &
      45              :                                                use_perd_z = 3, &
      46              :                                                use_perd_xy = 4, &
      47              :                                                use_perd_xz = 5, &
      48              :                                                use_perd_yz = 6, &
      49              :                                                use_perd_xyz = 7
      50              : 
      51              :    CHARACTER(LEN=3), DIMENSION(7), &
      52              :       PARAMETER, PUBLIC                     :: periodicity_string = ["  X", "  Y", "  Z", &
      53              :                                                                      " XY", " XZ", " YZ", &
      54              :                                                                      "XYZ"]
      55              : 
      56              : ! **************************************************************************************************
      57              : !> \brief   Type defining parameters related to the simulation cell
      58              : !> \version 1.0
      59              : ! **************************************************************************************************
      60              :    TYPE cell_type
      61              :       CHARACTER(LEN=12)                 :: tag = "CELL"
      62              :       INTEGER                           :: ref_count = -1, &
      63              :                                            symmetry_id = use_perd_none
      64              :       LOGICAL                           :: orthorhombic = .FALSE. ! actually means a diagonal hmat
      65              :       LOGICAL                           :: input_cell_canonicalized = .FALSE.
      66              :       REAL(KIND=dp)                     :: deth = 0.0_dp
      67              :       INTEGER, DIMENSION(3)             :: perd = -1
      68              :       REAL(KIND=dp), DIMENSION(3, 3)    :: hmat = 0.0_dp, &
      69              :                                            h_inv = 0.0_dp, &
      70              :                                            input_hmat = 0.0_dp, &
      71              :                                            input_to_canonical = 0.0_dp, &
      72              :                                            input_recip_to_canonical = 0.0_dp
      73              :    END TYPE cell_type
      74              : 
      75              :    TYPE cell_p_type
      76              :       TYPE(cell_type), POINTER :: cell => NULL()
      77              :    END TYPE cell_p_type
      78              : 
      79              :    ! Public data types
      80              :    PUBLIC :: cell_type, &
      81              :              cell_p_type
      82              : 
      83              :    ! Public subroutines
      84              :    PUBLIC :: cell_clone, &
      85              :              cell_copy, &
      86              :              cell_transform_input_cartesian, &
      87              :              cell_transform_input_reciprocal, &
      88              :              cell_release, &
      89              :              cell_retain, &
      90              :              get_cell, &
      91              :              parse_cell_line
      92              : 
      93              : #if defined (__PLUMED2)
      94              :    PUBLIC :: pbc_cp2k_plumed_getset_cell
      95              : #endif
      96              : 
      97              :    ! Public functions
      98              :    PUBLIC :: plane_distance, &
      99              :              pbc, &
     100              :              real_to_scaled, &
     101              :              scaled_to_real
     102              : 
     103              :    INTERFACE pbc
     104              :       MODULE PROCEDURE pbc1, pbc2, pbc3, pbc4
     105              :    END INTERFACE
     106              : 
     107              : CONTAINS
     108              : 
     109              : ! **************************************************************************************************
     110              : !> \brief Clone cell variable
     111              : !> \param cell_in Cell variable to be clone
     112              : !> \param cell_out Cloned cell variable
     113              : !> \param tag Optional new tag for cloned cell variable
     114              : !> \par History
     115              : !>      - Optional tag added (17.05.2023, MK)
     116              : ! **************************************************************************************************
     117        66245 :    SUBROUTINE cell_clone(cell_in, cell_out, tag)
     118              : 
     119              :       TYPE(cell_type), POINTER                           :: cell_in, cell_out
     120              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: tag
     121              : 
     122        66245 :       cell_out = cell_in
     123        66245 :       cell_out%ref_count = 1
     124        11110 :       IF (PRESENT(tag)) cell_out%tag = tag
     125              : 
     126        66245 :    END SUBROUTINE cell_clone
     127              : 
     128              : ! **************************************************************************************************
     129              : !> \brief Copy cell variable
     130              : !> \param cell_in Cell variable to be copied
     131              : !> \param cell_out Copy of cell variable
     132              : !> \param tag Optional new tag
     133              : !> \par History
     134              : !>      - Optional tag added (17.05.2023, MK)
     135              : ! **************************************************************************************************
     136       232654 :    SUBROUTINE cell_copy(cell_in, cell_out, tag)
     137              : 
     138              :       TYPE(cell_type), POINTER                           :: cell_in, cell_out
     139              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: tag
     140              : 
     141       232654 :       cell_out%deth = cell_in%deth
     142      1861232 :       cell_out%perd = cell_in%perd
     143      6049004 :       cell_out%hmat = cell_in%hmat
     144      6049004 :       cell_out%h_inv = cell_in%h_inv
     145       232654 :       cell_out%input_cell_canonicalized = cell_in%input_cell_canonicalized
     146      6049004 :       cell_out%input_hmat = cell_in%input_hmat
     147      6049004 :       cell_out%input_to_canonical = cell_in%input_to_canonical
     148      6049004 :       cell_out%input_recip_to_canonical = cell_in%input_recip_to_canonical
     149       232654 :       cell_out%orthorhombic = cell_in%orthorhombic
     150       232654 :       cell_out%symmetry_id = cell_in%symmetry_id
     151       232654 :       IF (PRESENT(tag)) THEN
     152        12994 :          cell_out%tag = tag
     153              :       ELSE
     154       219660 :          cell_out%tag = cell_in%tag
     155              :       END IF
     156              : 
     157       232654 :    END SUBROUTINE cell_copy
     158              : 
     159              : ! **************************************************************************************************
     160              : !> \brief   Read cell info from a line (parsed from a file)
     161              : !> \param input_line ...
     162              : !> \param cell_itimes ...
     163              : !> \param cell_time ...
     164              : !> \param h ...
     165              : !> \param vol ...
     166              : !> \date    19.02.2008
     167              : !> \author  Teodoro Laino [tlaino] - University of Zurich
     168              : !> \version 1.0
     169              : ! **************************************************************************************************
     170          368 :    SUBROUTINE parse_cell_line(input_line, cell_itimes, cell_time, h, vol)
     171              : 
     172              :       CHARACTER(LEN=*), INTENT(IN)                       :: input_line
     173              :       INTEGER, INTENT(OUT)                               :: cell_itimes
     174              :       REAL(KIND=dp), INTENT(OUT)                         :: cell_time
     175              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT)        :: h
     176              :       REAL(KIND=dp), INTENT(OUT)                         :: vol
     177              : 
     178              :       INTEGER                                            :: i, j
     179              : 
     180          368 :       READ (input_line, *) cell_itimes, cell_time, &
     181          736 :          h(1, 1), h(2, 1), h(3, 1), h(1, 2), h(2, 2), h(3, 2), h(1, 3), h(2, 3), h(3, 3), vol
     182         1472 :       DO i = 1, 3
     183         4784 :          DO j = 1, 3
     184         4416 :             h(j, i) = cp_unit_to_cp2k(h(j, i), "angstrom")
     185              :          END DO
     186              :       END DO
     187              : 
     188          368 :    END SUBROUTINE parse_cell_line
     189              : 
     190              : ! **************************************************************************************************
     191              : !> \brief   Get informations about a simulation cell.
     192              : !> \param cell ...
     193              : !> \param alpha ...
     194              : !> \param beta ...
     195              : !> \param gamma ...
     196              : !> \param deth ...
     197              : !> \param orthorhombic ...
     198              : !> \param abc ...
     199              : !> \param periodic ...
     200              : !> \param h ...
     201              : !> \param h_inv ...
     202              : !> \param symmetry_id ...
     203              : !> \param tag ...
     204              : !> \date    16.01.2002
     205              : !> \author  Matthias Krack
     206              : !> \version 1.0
     207              : ! **************************************************************************************************
     208    136235612 :    SUBROUTINE get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, &
     209              :                        h, h_inv, symmetry_id, tag)
     210              : 
     211              :       TYPE(cell_type), POINTER                           :: cell
     212              :       REAL(KIND=dp), INTENT(OUT), OPTIONAL               :: alpha, beta, gamma, deth
     213              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: orthorhombic
     214              :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT), OPTIONAL :: abc
     215              :       INTEGER, DIMENSION(3), INTENT(OUT), OPTIONAL       :: periodic
     216              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT), &
     217              :          OPTIONAL                                        :: h, h_inv
     218              :       INTEGER, INTENT(OUT), OPTIONAL                     :: symmetry_id
     219              :       CHARACTER(LEN=*), INTENT(OUT), OPTIONAL            :: tag
     220              : 
     221            0 :       CPASSERT(ASSOCIATED(cell))
     222              : 
     223    136235612 :       IF (PRESENT(deth)) deth = cell%deth ! the volume
     224    136235612 :       IF (PRESENT(orthorhombic)) orthorhombic = cell%orthorhombic
     225    522349709 :       IF (PRESENT(periodic)) periodic(:) = cell%perd(:)
     226    136454108 :       IF (PRESENT(h)) h(:, :) = cell%hmat(:, :)
     227    136236116 :       IF (PRESENT(h_inv)) h_inv(:, :) = cell%h_inv(:, :)
     228              : 
     229              :       ! Calculate the lengths of the cell vectors a, b, and c
     230    136235612 :       IF (PRESENT(abc)) THEN
     231              :          abc(1) = SQRT(cell%hmat(1, 1)*cell%hmat(1, 1) + &
     232              :                        cell%hmat(2, 1)*cell%hmat(2, 1) + &
     233      7339427 :                        cell%hmat(3, 1)*cell%hmat(3, 1))
     234              :          abc(2) = SQRT(cell%hmat(1, 2)*cell%hmat(1, 2) + &
     235              :                        cell%hmat(2, 2)*cell%hmat(2, 2) + &
     236      7339427 :                        cell%hmat(3, 2)*cell%hmat(3, 2))
     237              :          abc(3) = SQRT(cell%hmat(1, 3)*cell%hmat(1, 3) + &
     238              :                        cell%hmat(2, 3)*cell%hmat(2, 3) + &
     239      7339427 :                        cell%hmat(3, 3)*cell%hmat(3, 3))
     240              :       END IF
     241              : 
     242              :       ! Angles between the cell vectors a, b, and c
     243              :       ! alpha = <(b,c)
     244    136235612 :       IF (PRESENT(alpha)) alpha = angle(cell%hmat(:, 2), cell%hmat(:, 3))*degree
     245              :       ! beta = <(a,c)
     246    136235612 :       IF (PRESENT(beta)) beta = angle(cell%hmat(:, 1), cell%hmat(:, 3))*degree
     247              :       ! gamma = <(a,b)
     248    136235612 :       IF (PRESENT(gamma)) gamma = angle(cell%hmat(:, 1), cell%hmat(:, 2))*degree
     249    136235612 :       IF (PRESENT(symmetry_id)) symmetry_id = cell%symmetry_id
     250    136235612 :       IF (PRESENT(tag)) tag = cell%tag
     251              : 
     252    136235612 :    END SUBROUTINE get_cell
     253              : 
     254              : ! **************************************************************************************************
     255              : !> \brief Transform a Cartesian real-space vector from the user input cell frame
     256              : !>        into CP2K's canonical internal cell frame.
     257              : !> \param cell ...
     258              : !> \param vector ...
     259              : ! **************************************************************************************************
     260       784157 :    SUBROUTINE cell_transform_input_cartesian(cell, vector)
     261              : 
     262              :       TYPE(cell_type), POINTER                           :: cell
     263              :       REAL(KIND=dp), DIMENSION(3), INTENT(INOUT)         :: vector
     264              : 
     265       784157 :       CPASSERT(ASSOCIATED(cell))
     266              : 
     267       950549 :       IF (cell%input_cell_canonicalized) vector = MATMUL(cell%input_to_canonical, vector)
     268              : 
     269       784157 :    END SUBROUTINE cell_transform_input_cartesian
     270              : 
     271              : ! **************************************************************************************************
     272              : !> \brief Transform a Cartesian reciprocal-space vector from the user input cell
     273              : !>        frame into CP2K's canonical internal cell frame.
     274              : !> \param cell ...
     275              : !> \param vector ...
     276              : ! **************************************************************************************************
     277            0 :    SUBROUTINE cell_transform_input_reciprocal(cell, vector)
     278              : 
     279              :       TYPE(cell_type), POINTER                           :: cell
     280              :       REAL(KIND=dp), DIMENSION(3), INTENT(INOUT)         :: vector
     281              : 
     282            0 :       CPASSERT(ASSOCIATED(cell))
     283              : 
     284            0 :       IF (cell%input_cell_canonicalized) vector = MATMUL(cell%input_recip_to_canonical, vector)
     285              : 
     286            0 :    END SUBROUTINE cell_transform_input_reciprocal
     287              : 
     288              : ! **************************************************************************************************
     289              : !> \brief   Calculate the distance between two lattice planes as defined by
     290              : !>          a triple of Miller indices (hkl).
     291              : !> \param h ...
     292              : !> \param k ...
     293              : !> \param l ...
     294              : !> \param cell ...
     295              : !> \return ...
     296              : !> \date    18.11.2004
     297              : !> \author  Matthias Krack
     298              : !> \version 1.0
     299              : ! **************************************************************************************************
     300      7236380 :    FUNCTION plane_distance(h, k, l, cell) RESULT(distance)
     301              : 
     302              :       INTEGER, INTENT(IN)                                :: h, k, l
     303              :       TYPE(cell_type), POINTER                           :: cell
     304              :       REAL(KIND=dp)                                      :: distance
     305              : 
     306              :       REAL(KIND=dp)                                      :: a, alpha, b, beta, c, cosa, cosb, cosg, &
     307              :                                                             d, gamma, x, y, z
     308              :       REAL(KIND=dp), DIMENSION(3)                        :: abc
     309              : 
     310      7236380 :       x = REAL(h, KIND=dp)
     311      7236380 :       y = REAL(k, KIND=dp)
     312      7236380 :       z = REAL(l, KIND=dp)
     313              : 
     314      7236380 :       CALL get_cell(cell=cell, abc=abc)
     315              : 
     316      7236380 :       a = abc(1)
     317      7236380 :       b = abc(2)
     318      7236380 :       c = abc(3)
     319              : 
     320      7236380 :       IF (cell%orthorhombic) THEN
     321              : 
     322      7042433 :          d = (x/a)**2 + (y/b)**2 + (z/c)**2
     323              : 
     324              :       ELSE
     325              : 
     326              :          CALL get_cell(cell=cell, &
     327              :                        alpha=alpha, &
     328              :                        beta=beta, &
     329       193947 :                        gamma=gamma)
     330              : 
     331       193947 :          alpha = alpha/degree
     332       193947 :          beta = beta/degree
     333       193947 :          gamma = gamma/degree
     334              : 
     335       193947 :          cosa = COS(alpha)
     336       193947 :          cosb = COS(beta)
     337       193947 :          cosg = COS(gamma)
     338              : 
     339              :          d = ((x*b*c*SIN(alpha))**2 + &
     340              :               (y*c*a*SIN(beta))**2 + &
     341              :               (z*a*b*SIN(gamma))**2 + &
     342              :               2.0_dp*a*b*c*(x*y*c*(cosa*cosb - cosg) + &
     343              :                             z*x*b*(cosg*cosa - cosb) + &
     344              :                             y*z*a*(cosb*cosg - cosa)))/ &
     345              :              ((a*b*c)**2*(1.0_dp - cosa**2 - cosb**2 - cosg**2 + &
     346       193947 :                           2.0_dp*cosa*cosb*cosg))
     347              : 
     348              :       END IF
     349              : 
     350      7236380 :       distance = 1.0_dp/SQRT(d)
     351              : 
     352      7236380 :    END FUNCTION plane_distance
     353              : 
     354              : ! **************************************************************************************************
     355              : !> \brief   Apply the periodic boundary conditions defined by a simulation
     356              : !>          cell to a position vector r.
     357              : !> \param r ...
     358              : !> \param cell ...
     359              : !> \return ...
     360              : !> \date    16.01.2002
     361              : !> \author  Matthias Krack
     362              : !> \version 1.0
     363              : ! **************************************************************************************************
     364    395239065 :    FUNCTION pbc1(r, cell) RESULT(r_pbc)
     365              : 
     366              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: r
     367              :       TYPE(cell_type), POINTER                           :: cell
     368              :       REAL(KIND=dp), DIMENSION(3)                        :: r_pbc
     369              : 
     370              :       REAL(KIND=dp), DIMENSION(3)                        :: s
     371              : 
     372    395239065 :       CPASSERT(ASSOCIATED(cell))
     373              : 
     374    395239065 :       IF (cell%orthorhombic) THEN
     375    369675300 :          r_pbc(1) = r(1) - cell%hmat(1, 1)*cell%perd(1)*ANINT(cell%h_inv(1, 1)*r(1))
     376    369675300 :          r_pbc(2) = r(2) - cell%hmat(2, 2)*cell%perd(2)*ANINT(cell%h_inv(2, 2)*r(2))
     377    369675300 :          r_pbc(3) = r(3) - cell%hmat(3, 3)*cell%perd(3)*ANINT(cell%h_inv(3, 3)*r(3))
     378              :       ELSE
     379     25563765 :          s(1) = cell%h_inv(1, 1)*r(1) + cell%h_inv(1, 2)*r(2) + cell%h_inv(1, 3)*r(3)
     380     25563765 :          s(2) = cell%h_inv(2, 1)*r(1) + cell%h_inv(2, 2)*r(2) + cell%h_inv(2, 3)*r(3)
     381     25563765 :          s(3) = cell%h_inv(3, 1)*r(1) + cell%h_inv(3, 2)*r(2) + cell%h_inv(3, 3)*r(3)
     382     25563765 :          s(1) = s(1) - cell%perd(1)*ANINT(s(1))
     383     25563765 :          s(2) = s(2) - cell%perd(2)*ANINT(s(2))
     384     25563765 :          s(3) = s(3) - cell%perd(3)*ANINT(s(3))
     385     25563765 :          r_pbc(1) = cell%hmat(1, 1)*s(1) + cell%hmat(1, 2)*s(2) + cell%hmat(1, 3)*s(3)
     386     25563765 :          r_pbc(2) = cell%hmat(2, 1)*s(1) + cell%hmat(2, 2)*s(2) + cell%hmat(2, 3)*s(3)
     387     25563765 :          r_pbc(3) = cell%hmat(3, 1)*s(1) + cell%hmat(3, 2)*s(2) + cell%hmat(3, 3)*s(3)
     388              :       END IF
     389              : 
     390    395239065 :    END FUNCTION pbc1
     391              : 
     392              : ! **************************************************************************************************
     393              : !> \brief   Apply the periodic boundary conditions defined by a simulation
     394              : !>          cell to a position vector r subtracting nl from the periodic images
     395              : !> \param r ...
     396              : !> \param cell ...
     397              : !> \param nl ...
     398              : !> \return ...
     399              : !> \date    16.01.2002
     400              : !> \author  Matthias Krack
     401              : !> \version 1.0
     402              : ! **************************************************************************************************
     403    142966578 :    FUNCTION pbc2(r, cell, nl) RESULT(r_pbc)
     404              : 
     405              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: r
     406              :       TYPE(cell_type), POINTER                           :: cell
     407              :       INTEGER, DIMENSION(3), INTENT(IN)                  :: nl
     408              :       REAL(KIND=dp), DIMENSION(3)                        :: r_pbc
     409              : 
     410              :       REAL(KIND=dp), DIMENSION(3)                        :: s
     411              : 
     412    142966578 :       CPASSERT(ASSOCIATED(cell))
     413              : 
     414    142966578 :       IF (cell%orthorhombic) THEN
     415              :          r_pbc(1) = r(1) - cell%hmat(1, 1)*cell%perd(1)* &
     416    132353154 :                     REAL(NINT(cell%h_inv(1, 1)*r(1)) - nl(1), dp)
     417              :          r_pbc(2) = r(2) - cell%hmat(2, 2)*cell%perd(2)* &
     418    132353154 :                     REAL(NINT(cell%h_inv(2, 2)*r(2)) - nl(2), dp)
     419              :          r_pbc(3) = r(3) - cell%hmat(3, 3)*cell%perd(3)* &
     420    132353154 :                     REAL(NINT(cell%h_inv(3, 3)*r(3)) - nl(3), dp)
     421              :       ELSE
     422     10613424 :          s(1) = cell%h_inv(1, 1)*r(1) + cell%h_inv(1, 2)*r(2) + cell%h_inv(1, 3)*r(3)
     423     10613424 :          s(2) = cell%h_inv(2, 1)*r(1) + cell%h_inv(2, 2)*r(2) + cell%h_inv(2, 3)*r(3)
     424     10613424 :          s(3) = cell%h_inv(3, 1)*r(1) + cell%h_inv(3, 2)*r(2) + cell%h_inv(3, 3)*r(3)
     425     10613424 :          s(1) = s(1) - cell%perd(1)*REAL(NINT(s(1)) - nl(1), dp)
     426     10613424 :          s(2) = s(2) - cell%perd(2)*REAL(NINT(s(2)) - nl(2), dp)
     427     10613424 :          s(3) = s(3) - cell%perd(3)*REAL(NINT(s(3)) - nl(3), dp)
     428     10613424 :          r_pbc(1) = cell%hmat(1, 1)*s(1) + cell%hmat(1, 2)*s(2) + cell%hmat(1, 3)*s(3)
     429     10613424 :          r_pbc(2) = cell%hmat(2, 1)*s(1) + cell%hmat(2, 2)*s(2) + cell%hmat(2, 3)*s(3)
     430     10613424 :          r_pbc(3) = cell%hmat(3, 1)*s(1) + cell%hmat(3, 2)*s(2) + cell%hmat(3, 3)*s(3)
     431              :       END IF
     432              : 
     433    142966578 :    END FUNCTION pbc2
     434              : 
     435              : ! **************************************************************************************************
     436              : !> \brief   Apply the periodic boundary conditions defined by the simulation
     437              : !>          cell cell to the vector pointing from atom a to atom b.
     438              : !> \param ra ...
     439              : !> \param rb ...
     440              : !> \param cell ...
     441              : !> \return ...
     442              : !> \date    11.03.2004
     443              : !> \author  Matthias Krack
     444              : !> \version 1.0
     445              : ! **************************************************************************************************
     446    128490057 :    FUNCTION pbc3(ra, rb, cell) RESULT(rab_pbc)
     447              : 
     448              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: ra, rb
     449              :       TYPE(cell_type), POINTER                           :: cell
     450              :       REAL(KIND=dp), DIMENSION(3)                        :: rab_pbc
     451              : 
     452              :       INTEGER                                            :: icell, jcell, kcell
     453              :       INTEGER, DIMENSION(3)                              :: periodic
     454              :       REAL(KIND=dp)                                      :: rab2, rab2_pbc
     455              :       REAL(KIND=dp), DIMENSION(3)                        :: r, ra_pbc, rab, rb_image, rb_pbc, s2r
     456              : 
     457    128490057 :       CALL get_cell(cell=cell, periodic=periodic)
     458              : 
     459    128490057 :       ra_pbc(:) = pbc(ra(:), cell)
     460    128490057 :       rb_pbc(:) = pbc(rb(:), cell)
     461              : 
     462    128490057 :       rab2_pbc = HUGE(1.0_dp)
     463              : 
     464    509570884 :       DO icell = -periodic(1), periodic(1)
     465   1648425681 :          DO jcell = -periodic(2), periodic(2)
     466   4932107303 :             DO kcell = -periodic(3), periodic(3)
     467  13648686716 :                r = REAL([icell, jcell, kcell], dp)
     468   3412171679 :                CALL scaled_to_real(s2r, r, cell)
     469  13648686716 :                rb_image(:) = rb_pbc(:) + s2r
     470  13648686716 :                rab(:) = rb_image(:) - ra_pbc(:)
     471   3412171679 :                rab2 = rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3)
     472   4551026476 :                IF (rab2 < rab2_pbc) THEN
     473   2678646096 :                   rab2_pbc = rab2
     474   2678646096 :                   rab_pbc(:) = rab(:)
     475              :                END IF
     476              :             END DO
     477              :          END DO
     478              :       END DO
     479              : 
     480    128490057 :    END FUNCTION pbc3
     481              : 
     482              :    !if positive_range == true, r(i) (or s(i)) in range [0, hmat(i,i)],
     483              :    !else, r(i) (s(i)) in range [-hmat(i,i)/2, hmat(i,i)/2]
     484              : ! **************************************************************************************************
     485              : !> \brief ...
     486              : !> \param r ...
     487              : !> \param cell ...
     488              : !> \param positive_range ...
     489              : !> \return ...
     490              : ! **************************************************************************************************
     491        19091 :    FUNCTION pbc4(r, cell, positive_range) RESULT(r_pbc)
     492              : 
     493              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: r
     494              :       TYPE(cell_type), POINTER                           :: cell
     495              :       LOGICAL                                            :: positive_range
     496              :       REAL(KIND=dp), DIMENSION(3)                        :: r_pbc
     497              : 
     498              :       REAL(KIND=dp), DIMENSION(3)                        :: s
     499              : 
     500        19091 :       CPASSERT(ASSOCIATED(cell))
     501              : 
     502        19091 :       IF (positive_range) THEN
     503        19091 :          IF (cell%orthorhombic) THEN
     504        11556 :             r_pbc(1) = r(1) - cell%hmat(1, 1)*cell%perd(1)*FLOOR(cell%h_inv(1, 1)*r(1))
     505        11556 :             r_pbc(2) = r(2) - cell%hmat(2, 2)*cell%perd(2)*FLOOR(cell%h_inv(2, 2)*r(2))
     506        11556 :             r_pbc(3) = r(3) - cell%hmat(3, 3)*cell%perd(3)*FLOOR(cell%h_inv(3, 3)*r(3))
     507              :          ELSE
     508         7535 :             s(1) = cell%h_inv(1, 1)*r(1) + cell%h_inv(1, 2)*r(2) + cell%h_inv(1, 3)*r(3)
     509         7535 :             s(2) = cell%h_inv(2, 1)*r(1) + cell%h_inv(2, 2)*r(2) + cell%h_inv(2, 3)*r(3)
     510         7535 :             s(3) = cell%h_inv(3, 1)*r(1) + cell%h_inv(3, 2)*r(2) + cell%h_inv(3, 3)*r(3)
     511         7535 :             s(1) = s(1) - cell%perd(1)*FLOOR(s(1))
     512         7535 :             s(2) = s(2) - cell%perd(2)*FLOOR(s(2))
     513         7535 :             s(3) = s(3) - cell%perd(3)*FLOOR(s(3))
     514         7535 :             r_pbc(1) = cell%hmat(1, 1)*s(1) + cell%hmat(1, 2)*s(2) + cell%hmat(1, 3)*s(3)
     515         7535 :             r_pbc(2) = cell%hmat(2, 1)*s(1) + cell%hmat(2, 2)*s(2) + cell%hmat(2, 3)*s(3)
     516         7535 :             r_pbc(3) = cell%hmat(3, 1)*s(1) + cell%hmat(3, 2)*s(2) + cell%hmat(3, 3)*s(3)
     517              :          END IF
     518              :       ELSE
     519            0 :          r_pbc = pbc1(r, cell)
     520              :       END IF
     521              : 
     522        19091 :    END FUNCTION pbc4
     523              : 
     524              : ! **************************************************************************************************
     525              : !> \brief   Transform real to scaled cell coordinates.
     526              : !>          s=h_inv*r
     527              : !> \param s ...
     528              : !> \param r ...
     529              : !> \param cell ...
     530              : !> \date    16.01.2002
     531              : !> \author  Matthias Krack
     532              : !> \version 1.0
     533              : ! **************************************************************************************************
     534    110624578 :    SUBROUTINE real_to_scaled(s, r, cell)
     535              : 
     536              :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: s
     537              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: r
     538              :       TYPE(cell_type), POINTER                           :: cell
     539              : 
     540    110624578 :       CPASSERT(ASSOCIATED(cell))
     541              : 
     542    110624578 :       IF (cell%orthorhombic) THEN
     543     99964564 :          s(1) = cell%h_inv(1, 1)*r(1)
     544     99964564 :          s(2) = cell%h_inv(2, 2)*r(2)
     545     99964564 :          s(3) = cell%h_inv(3, 3)*r(3)
     546              :       ELSE
     547     10660014 :          s(1) = cell%h_inv(1, 1)*r(1) + cell%h_inv(1, 2)*r(2) + cell%h_inv(1, 3)*r(3)
     548     10660014 :          s(2) = cell%h_inv(2, 1)*r(1) + cell%h_inv(2, 2)*r(2) + cell%h_inv(2, 3)*r(3)
     549     10660014 :          s(3) = cell%h_inv(3, 1)*r(1) + cell%h_inv(3, 2)*r(2) + cell%h_inv(3, 3)*r(3)
     550              :       END IF
     551              : 
     552    110624578 :    END SUBROUTINE real_to_scaled
     553              : 
     554              : ! **************************************************************************************************
     555              : !> \brief   Transform scaled cell coordinates real coordinates.
     556              : !>          r=h*s
     557              : !> \param r ...
     558              : !> \param s ...
     559              : !> \param cell ...
     560              : !> \date    16.01.2002
     561              : !> \author  Matthias Krack
     562              : !> \version 1.0
     563              : ! **************************************************************************************************
     564   3576745176 :    SUBROUTINE scaled_to_real(r, s, cell)
     565              : 
     566              :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: r
     567              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: s
     568              :       TYPE(cell_type), POINTER                           :: cell
     569              : 
     570   3576745176 :       CPASSERT(ASSOCIATED(cell))
     571              : 
     572   3576745176 :       IF (cell%orthorhombic) THEN
     573   3302903255 :          r(1) = cell%hmat(1, 1)*s(1)
     574   3302903255 :          r(2) = cell%hmat(2, 2)*s(2)
     575   3302903255 :          r(3) = cell%hmat(3, 3)*s(3)
     576              :       ELSE
     577    273841921 :          r(1) = cell%hmat(1, 1)*s(1) + cell%hmat(1, 2)*s(2) + cell%hmat(1, 3)*s(3)
     578    273841921 :          r(2) = cell%hmat(2, 1)*s(1) + cell%hmat(2, 2)*s(2) + cell%hmat(2, 3)*s(3)
     579    273841921 :          r(3) = cell%hmat(3, 1)*s(1) + cell%hmat(3, 2)*s(2) + cell%hmat(3, 3)*s(3)
     580              :       END IF
     581              : 
     582   3576745176 :    END SUBROUTINE scaled_to_real
     583              : ! **************************************************************************************************
     584              : !> \brief retains the given cell (see doc/ReferenceCounting.html)
     585              : !> \param cell the cell to retain
     586              : !> \par History
     587              : !>      09.2003 created [fawzi]
     588              : !> \author Fawzi Mohamed
     589              : ! **************************************************************************************************
     590        75688 :    SUBROUTINE cell_retain(cell)
     591              : 
     592              :       TYPE(cell_type), POINTER                           :: cell
     593              : 
     594        75688 :       CPASSERT(ASSOCIATED(cell))
     595        75688 :       CPASSERT(cell%ref_count > 0)
     596        75688 :       cell%ref_count = cell%ref_count + 1
     597              : 
     598        75688 :    END SUBROUTINE cell_retain
     599              : 
     600              : ! **************************************************************************************************
     601              : !> \brief releases the given cell (see doc/ReferenceCounting.html)
     602              : !> \param cell the cell to release
     603              : !> \par History
     604              : !>      09.2003 created [fawzi]
     605              : !> \author Fawzi Mohamed
     606              : ! **************************************************************************************************
     607       203034 :    SUBROUTINE cell_release(cell)
     608              : 
     609              :       TYPE(cell_type), POINTER                           :: cell
     610              : 
     611       203034 :       IF (ASSOCIATED(cell)) THEN
     612       155306 :          CPASSERT(cell%ref_count > 0)
     613       155306 :          cell%ref_count = cell%ref_count - 1
     614       155306 :          IF (cell%ref_count == 0) THEN
     615        79618 :             DEALLOCATE (cell)
     616              :          END IF
     617       155306 :          NULLIFY (cell)
     618              :       END IF
     619              : 
     620       203034 :    END SUBROUTINE cell_release
     621              : 
     622              : #if defined (__PLUMED2)
     623              : ! **************************************************************************************************
     624              : !> \brief   For the interface with plumed, pass a cell pointer and retrieve it
     625              : !>          later. It's a hack, but avoids passing the cell back and forth
     626              : !>          across the Fortran/C++ interface
     627              : !> \param cell ...
     628              : !> \param set ...
     629              : !> \date    28.02.2013
     630              : !> \author  RK
     631              : !> \version 1.0
     632              : ! **************************************************************************************************
     633            2 :    SUBROUTINE pbc_cp2k_plumed_getset_cell(cell, set)
     634              : 
     635              :       TYPE(cell_type), POINTER                           :: cell
     636              :       LOGICAL                                            :: set
     637              : 
     638              :       TYPE(cell_type), POINTER, SAVE                     :: stored_cell
     639              : 
     640            2 :       IF (set) THEN
     641            2 :          stored_cell => cell
     642              :       ELSE
     643            0 :          cell => stored_cell
     644              :       END IF
     645              : 
     646            2 :    END SUBROUTINE pbc_cp2k_plumed_getset_cell
     647              : #endif
     648              : 
     649            0 : END MODULE cell_types
        

Generated by: LCOV version 2.0-1