LCOV - code coverage report
Current view: top level - src - cell_methods.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 310 339 91.4 %
Date: 2024-12-21 06:28:57 Functions: 11 11 100.0 %

          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 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 to cell_types.F.
      13             : !> \author Matthias KracK (16.01.2002, based on a earlier version of CJM, JGH)
      14             : ! **************************************************************************************************
      15             : MODULE cell_methods
      16             :    USE cell_types,                      ONLY: &
      17             :         cell_clone, cell_release, cell_sym_cubic, cell_sym_hexagonal_gamma_120, &
      18             :         cell_sym_hexagonal_gamma_60, cell_sym_monoclinic, cell_sym_monoclinic_gamma_ab, &
      19             :         cell_sym_none, cell_sym_orthorhombic, cell_sym_rhombohedral, cell_sym_tetragonal_ab, &
      20             :         cell_sym_tetragonal_ac, cell_sym_tetragonal_bc, cell_sym_triclinic, cell_type, get_cell, &
      21             :         plane_distance, use_perd_none, use_perd_x, use_perd_xy, use_perd_xyz, use_perd_xz, &
      22             :         use_perd_y, use_perd_yz, use_perd_z
      23             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      24             :                                               cp_logger_type
      25             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      26             :                                               cp_print_key_unit_nr
      27             :    USE cp_parser_methods,               ONLY: parser_get_next_line,&
      28             :                                               parser_get_object,&
      29             :                                               parser_search_string
      30             :    USE cp_parser_types,                 ONLY: cp_parser_type,&
      31             :                                               parser_create,&
      32             :                                               parser_release
      33             :    USE cp_units,                        ONLY: cp_unit_from_cp2k,&
      34             :                                               cp_unit_to_cp2k
      35             :    USE input_constants,                 ONLY: do_cell_cif,&
      36             :                                               do_cell_cp2k,&
      37             :                                               do_cell_xsc
      38             :    USE input_cp2k_subsys,               ONLY: create_cell_section
      39             :    USE input_enumeration_types,         ONLY: enum_i2c,&
      40             :                                               enumeration_type
      41             :    USE input_keyword_types,             ONLY: keyword_get,&
      42             :                                               keyword_type
      43             :    USE input_section_types,             ONLY: &
      44             :         section_get_keyword, section_release, section_type, section_vals_get, &
      45             :         section_vals_get_subs_vals, section_vals_type, section_vals_val_get, section_vals_val_set, &
      46             :         section_vals_val_unset
      47             :    USE kinds,                           ONLY: default_path_length,&
      48             :                                               default_string_length,&
      49             :                                               dp
      50             :    USE machine,                         ONLY: default_output_unit
      51             :    USE mathconstants,                   ONLY: degree,&
      52             :                                               sqrt3
      53             :    USE mathlib,                         ONLY: angle,&
      54             :                                               det_3x3,&
      55             :                                               inv_3x3
      56             :    USE message_passing,                 ONLY: mp_para_env_type
      57             : #include "./base/base_uses.f90"
      58             : 
      59             :    IMPLICIT NONE
      60             : 
      61             :    PRIVATE
      62             : 
      63             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cell_methods'
      64             : 
      65             :    PUBLIC :: cell_create, &
      66             :              init_cell, &
      67             :              read_cell, &
      68             :              read_cell_cif, &
      69             :              set_cell_param, &
      70             :              write_cell
      71             : 
      72             : CONTAINS
      73             : 
      74             : ! **************************************************************************************************
      75             : !> \brief allocates and initializes a cell
      76             : !> \param cell the cell to initialize
      77             : !> \param hmat the h matrix that defines the cell
      78             : !> \param periodic periodicity of the cell
      79             : !> \param tag ...
      80             : !> \par History
      81             : !>      09.2003 created [fawzi]
      82             : !> \author Fawzi Mohamed
      83             : ! **************************************************************************************************
      84       60452 :    SUBROUTINE cell_create(cell, hmat, periodic, tag)
      85             : 
      86             :       TYPE(cell_type), POINTER                           :: cell
      87             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN), &
      88             :          OPTIONAL                                        :: hmat
      89             :       INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL        :: periodic
      90             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: tag
      91             : 
      92           0 :       CPASSERT(.NOT. ASSOCIATED(cell))
      93     1813560 :       ALLOCATE (cell)
      94       60452 :       cell%ref_count = 1
      95       60452 :       IF (PRESENT(periodic)) THEN
      96        1332 :          cell%perd = periodic
      97             :       ELSE
      98      240476 :          cell%perd = 1
      99             :       END IF
     100             :       cell%orthorhombic = .FALSE.
     101       60452 :       cell%symmetry_id = cell_sym_none
     102       60452 :       IF (PRESENT(hmat)) CALL init_cell(cell, hmat)
     103       60452 :       IF (PRESENT(tag)) cell%tag = tag
     104             : 
     105       60452 :    END SUBROUTINE cell_create
     106             : 
     107             : ! **************************************************************************************************
     108             : !> \brief   Initialise/readjust a simulation cell after hmat has been changed
     109             : !> \param cell ...
     110             : !> \param hmat ...
     111             : !> \param periodic ...
     112             : !> \date    16.01.2002
     113             : !> \author  Matthias Krack
     114             : !> \version 1.0
     115             : ! **************************************************************************************************
     116      343549 :    SUBROUTINE init_cell(cell, hmat, periodic)
     117             : 
     118             :       TYPE(cell_type), POINTER                           :: cell
     119             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN), &
     120             :          OPTIONAL                                        :: hmat
     121             :       INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL        :: periodic
     122             : 
     123             :       REAL(KIND=dp), PARAMETER                           :: eps_hmat = 1.0E-14_dp
     124             : 
     125             :       INTEGER                                            :: dim
     126             :       REAL(KIND=dp)                                      :: a, acosa, acosah, acosg, alpha, asina, &
     127             :                                                             asinah, asing, beta, gamma, norm, &
     128             :                                                             norm_c
     129             :       REAL(KIND=dp), DIMENSION(3)                        :: abc
     130             : 
     131      343549 :       CPASSERT(ASSOCIATED(cell))
     132             : 
     133      443497 :       IF (PRESENT(hmat)) cell%hmat(:, :) = hmat(:, :)
     134      343627 :       IF (PRESENT(periodic)) cell%perd(:) = periodic(:)
     135             : 
     136      343549 :       cell%deth = ABS(det_3x3(cell%hmat))
     137             : 
     138      343549 :       IF (cell%deth < 1.0E-10_dp) THEN
     139           0 :          CALL write_cell_low(cell, "angstrom", default_output_unit)
     140             :          CALL cp_abort(__LOCATION__, &
     141             :                        "An invalid set of cell vectors was specified. "// &
     142           0 :                        "The cell volume is too small")
     143             :       END IF
     144             : 
     145      347593 :       SELECT CASE (cell%symmetry_id)
     146             :       CASE (cell_sym_cubic, &
     147             :             cell_sym_tetragonal_ab, &
     148             :             cell_sym_tetragonal_ac, &
     149             :             cell_sym_tetragonal_bc, &
     150             :             cell_sym_orthorhombic)
     151        4044 :          CALL get_cell(cell=cell, abc=abc)
     152        4044 :          abc(2) = plane_distance(0, 1, 0, cell=cell)
     153        4044 :          abc(3) = plane_distance(0, 0, 1, cell=cell)
     154        4044 :          SELECT CASE (cell%symmetry_id)
     155             :          CASE (cell_sym_cubic)
     156        7621 :             abc(1:3) = SUM(abc(1:3))/3.0_dp
     157             :          CASE (cell_sym_tetragonal_ab, &
     158             :                cell_sym_tetragonal_ac, &
     159             :                cell_sym_tetragonal_bc)
     160        1322 :             SELECT CASE (cell%symmetry_id)
     161             :             CASE (cell_sym_tetragonal_ab)
     162        1322 :                a = 0.5_dp*(abc(1) + abc(2))
     163        1322 :                abc(1) = a
     164        1322 :                abc(2) = a
     165             :             CASE (cell_sym_tetragonal_ac)
     166         661 :                a = 0.5_dp*(abc(1) + abc(3))
     167         661 :                abc(1) = a
     168         661 :                abc(3) = a
     169             :             CASE (cell_sym_tetragonal_bc)
     170         612 :                a = 0.5_dp*(abc(2) + abc(3))
     171         612 :                abc(2) = a
     172         612 :                abc(3) = a
     173             :             END SELECT
     174             :          END SELECT
     175        4044 :          cell%hmat(1, 1) = abc(1); cell%hmat(1, 2) = 0.0_dp; cell%hmat(1, 3) = 0.0_dp
     176        4044 :          cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = abc(2); cell%hmat(2, 3) = 0.0_dp
     177        4044 :          cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = abc(3)
     178             :       CASE (cell_sym_hexagonal_gamma_60, cell_sym_hexagonal_gamma_120)
     179        2634 :          CALL get_cell(cell=cell, abc=abc)
     180        2634 :          a = 0.5_dp*(abc(1) + abc(2))
     181        2634 :          acosg = 0.5_dp*a
     182        2634 :          asing = sqrt3*acosg
     183        2634 :          IF (cell%symmetry_id == cell_sym_hexagonal_gamma_120) acosg = -acosg
     184        2634 :          cell%hmat(1, 1) = a; cell%hmat(1, 2) = acosg; cell%hmat(1, 3) = 0.0_dp
     185        2634 :          cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = asing; cell%hmat(2, 3) = 0.0_dp
     186        2634 :          cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = abc(3)
     187             :       CASE (cell_sym_rhombohedral)
     188         665 :          CALL get_cell(cell=cell, abc=abc)
     189        2660 :          a = SUM(abc(1:3))/3.0_dp
     190             :          alpha = (angle(cell%hmat(:, 3), cell%hmat(:, 2)) + &
     191             :                   angle(cell%hmat(:, 1), cell%hmat(:, 3)) + &
     192         665 :                   angle(cell%hmat(:, 1), cell%hmat(:, 2)))/3.0_dp
     193         665 :          acosa = a*COS(alpha)
     194         665 :          asina = a*SIN(alpha)
     195         665 :          acosah = a*COS(0.5_dp*alpha)
     196         665 :          asinah = a*SIN(0.5_dp*alpha)
     197         665 :          norm = acosa/acosah
     198         665 :          norm_c = SQRT(1.0_dp - norm*norm)
     199         665 :          cell%hmat(1, 1) = a; cell%hmat(1, 2) = acosa; cell%hmat(1, 3) = acosah*norm
     200         665 :          cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = asina; cell%hmat(2, 3) = asinah*norm
     201         665 :          cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = a*norm_c
     202             :       CASE (cell_sym_monoclinic)
     203         880 :          CALL get_cell(cell=cell, abc=abc)
     204         880 :          beta = angle(cell%hmat(:, 1), cell%hmat(:, 3))
     205         880 :          cell%hmat(1, 1) = abc(1); cell%hmat(1, 2) = 0.0_dp; cell%hmat(1, 3) = abc(3)*COS(beta)
     206         880 :          cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = abc(2); cell%hmat(2, 3) = 0.0_dp
     207         880 :          cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = abc(3)*SIN(beta)
     208             :       CASE (cell_sym_monoclinic_gamma_ab)
     209             :          ! Cell symmetry with a = b, alpha = beta = 90 degree and gammma not equal 90 degree
     210         742 :          CALL get_cell(cell=cell, abc=abc)
     211         742 :          a = 0.5_dp*(abc(1) + abc(2))
     212         742 :          gamma = angle(cell%hmat(:, 1), cell%hmat(:, 2))
     213         742 :          acosg = a*COS(gamma)
     214         742 :          asing = a*SIN(gamma)
     215         742 :          cell%hmat(1, 1) = a; cell%hmat(1, 2) = acosg; cell%hmat(1, 3) = 0.0_dp
     216         742 :          cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = asing; cell%hmat(2, 3) = 0.0_dp
     217      344291 :          cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = abc(3)
     218             :       CASE (cell_sym_triclinic)
     219             :          ! Nothing to do
     220             :       END SELECT
     221             : 
     222             :       ! Do we have an (almost) orthorhombic cell?
     223             :       IF ((ABS(cell%hmat(1, 2)) < eps_hmat) .AND. (ABS(cell%hmat(1, 3)) < eps_hmat) .AND. &
     224             :           (ABS(cell%hmat(2, 1)) < eps_hmat) .AND. (ABS(cell%hmat(2, 3)) < eps_hmat) .AND. &
     225      343549 :           (ABS(cell%hmat(3, 1)) < eps_hmat) .AND. (ABS(cell%hmat(3, 2)) < eps_hmat)) THEN
     226      318863 :          cell%orthorhombic = .TRUE.
     227             :       ELSE
     228       24686 :          cell%orthorhombic = .FALSE.
     229             :       END IF
     230             : 
     231             :       ! Retain an exact orthorhombic cell
     232             :       ! (off-diagonal elements must remain zero identically to keep QS fast)
     233      343549 :       IF (cell%orthorhombic) THEN
     234      318863 :          cell%hmat(1, 2) = 0.0_dp
     235      318863 :          cell%hmat(1, 3) = 0.0_dp
     236      318863 :          cell%hmat(2, 1) = 0.0_dp
     237      318863 :          cell%hmat(2, 3) = 0.0_dp
     238      318863 :          cell%hmat(3, 1) = 0.0_dp
     239      318863 :          cell%hmat(3, 2) = 0.0_dp
     240             :       END IF
     241             : 
     242     1374196 :       dim = COUNT(cell%perd == 1)
     243      343549 :       IF ((dim == 1) .AND. (.NOT. cell%orthorhombic)) THEN
     244           0 :          CPABORT("Non-orthorhombic and not periodic")
     245             :       END IF
     246             : 
     247             :       ! Update deth and hmat_inv with enforced symmetry
     248      343549 :       cell%deth = ABS(det_3x3(cell%hmat))
     249      343549 :       IF (cell%deth < 1.0E-10_dp) THEN
     250             :          CALL cp_abort(__LOCATION__, &
     251             :                        "An invalid set of cell vectors was obtained after applying "// &
     252           0 :                        "the requested cell symmetry. The cell volume is too small")
     253             :       END IF
     254     4466137 :       cell%h_inv = inv_3x3(cell%hmat)
     255             : 
     256      343549 :    END SUBROUTINE init_cell
     257             : 
     258             : ! **************************************************************************************************
     259             : !> \brief ...
     260             : !> \param cell ...
     261             : !> \param cell_ref ...
     262             : !> \param use_ref_cell ...
     263             : !> \param cell_section ...
     264             : !> \param check_for_ref ...
     265             : !> \param para_env ...
     266             : !> \par History
     267             : !>      03.2005 created [teo]
     268             : !> \author Teodoro Laino
     269             : ! **************************************************************************************************
     270      138929 :    RECURSIVE SUBROUTINE read_cell(cell, cell_ref, use_ref_cell, cell_section, &
     271             :                                   check_for_ref, para_env)
     272             : 
     273             :       TYPE(cell_type), POINTER                           :: cell, cell_ref
     274             :       LOGICAL, INTENT(INOUT), OPTIONAL                   :: use_ref_cell
     275             :       TYPE(section_vals_type), OPTIONAL, POINTER         :: cell_section
     276             :       LOGICAL, INTENT(IN), OPTIONAL                      :: check_for_ref
     277             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     278             : 
     279             :       INTEGER                                            :: my_per
     280       19847 :       INTEGER, DIMENSION(:), POINTER                     :: multiple_unit_cell
     281             :       LOGICAL                                            :: cell_read_a, cell_read_abc, cell_read_b, &
     282             :                                                             cell_read_c, cell_read_file, check, &
     283             :                                                             my_check
     284       19847 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: cell_angles, cell_par
     285             :       TYPE(section_vals_type), POINTER                   :: cell_ref_section
     286             : 
     287       19847 :       my_check = .TRUE.
     288       19847 :       NULLIFY (cell_ref_section, cell_par, multiple_unit_cell)
     289       19803 :       IF (.NOT. ASSOCIATED(cell)) CALL cell_create(cell, tag="CELL")
     290       19847 :       IF (.NOT. ASSOCIATED(cell_ref)) CALL cell_create(cell_ref, tag="CELL_REF")
     291       19847 :       IF (PRESENT(check_for_ref)) my_check = check_for_ref
     292             : 
     293       19847 :       cell%deth = 0.0_dp
     294       19847 :       cell%orthorhombic = .FALSE.
     295       79388 :       cell%perd(:) = 1
     296       19847 :       cell%symmetry_id = cell_sym_none
     297      258011 :       cell%hmat(:, :) = 0.0_dp
     298      258011 :       cell%h_inv(:, :) = 0.0_dp
     299             :       cell_read_file = .FALSE.
     300             :       cell_read_a = .FALSE.
     301       19847 :       cell_read_b = .FALSE.
     302       19847 :       cell_read_c = .FALSE.
     303             :       ! Trying to read cell info from file
     304       19847 :       CALL section_vals_val_get(cell_section, "CELL_FILE_NAME", explicit=cell_read_file)
     305       19847 :       IF (cell_read_file) CALL read_cell_from_external_file(cell_section, para_env)
     306             : 
     307             :       ! Trying to read cell info from the separate A, B, C vectors
     308             :       ! If cell information is provided through file A,B,C contain the file information..
     309             :       ! a print warning is shown on screen..
     310       19847 :       CALL section_vals_val_get(cell_section, "A", explicit=cell_read_a)
     311       19847 :       IF (cell_read_a) THEN
     312        2422 :          CALL section_vals_val_get(cell_section, "A", r_vals=cell_par)
     313       19376 :          cell%hmat(:, 1) = cell_par(:)
     314             :       END IF
     315       19847 :       CALL section_vals_val_get(cell_section, "B", explicit=cell_read_b)
     316       19847 :       IF (cell_read_b) THEN
     317        2422 :          CALL section_vals_val_get(cell_section, "B", r_vals=cell_par)
     318       19376 :          cell%hmat(:, 2) = cell_par(:)
     319             :       END IF
     320       19847 :       CALL section_vals_val_get(cell_section, "C", explicit=cell_read_c)
     321       19847 :       IF (cell_read_c) THEN
     322        2422 :          CALL section_vals_val_get(cell_section, "C", r_vals=cell_par)
     323       19376 :          cell%hmat(:, 3) = cell_par(:)
     324             :       END IF
     325       19847 :       check = ((cell_read_a .EQV. cell_read_b) .AND. (cell_read_b .EQV. cell_read_c))
     326             :       IF (.NOT. check) &
     327             :          CALL cp_warn(__LOCATION__, &
     328             :                       "Cell Information provided through vectors A, B and C. Not all three "// &
     329           0 :                       "vectors were provided! Cell setup may be incomplete!")
     330             : 
     331             :       ! Very last option.. Trying to read cell info from ABC keyword
     332       19847 :       CALL section_vals_val_get(cell_section, "ABC", explicit=cell_read_abc)
     333       19847 :       IF (cell_read_abc) THEN
     334       17425 :          check = (cell_read_a .OR. cell_read_b .OR. cell_read_c)
     335             :          IF (check) &
     336             :             CALL cp_warn(__LOCATION__, &
     337             :                          "Cell Information provided through vectors A, B and C in conjunction with ABC."// &
     338           0 :                          " The definition of the ABC keyword will override the one provided by A,B and C.")
     339      226525 :          cell%hmat = 0.0_dp
     340       17425 :          CALL section_vals_val_get(cell_section, "ABC", r_vals=cell_par)
     341       17425 :          CALL section_vals_val_get(cell_section, "ALPHA_BETA_GAMMA", r_vals=cell_angles)
     342       17425 :          CALL set_cell_param(cell, cell_par, cell_angles, do_init_cell=.FALSE.)
     343             :       END IF
     344             : 
     345             :       ! Multiple unit cell
     346       19847 :       CALL section_vals_val_get(cell_section, "MULTIPLE_UNIT_CELL", i_vals=multiple_unit_cell)
     347       78508 :       IF (ANY(multiple_unit_cell /= 1)) CALL set_multiple_unit_cell(cell, multiple_unit_cell)
     348             : 
     349       19847 :       CALL section_vals_val_get(cell_section, "PERIODIC", i_val=my_per)
     350           0 :       SELECT CASE (my_per)
     351             :       CASE (use_perd_x)
     352           0 :          cell%perd = (/1, 0, 0/)
     353             :       CASE (use_perd_y)
     354           0 :          cell%perd = (/0, 1, 0/)
     355             :       CASE (use_perd_z)
     356          32 :          cell%perd = (/0, 0, 1/)
     357             :       CASE (use_perd_xy)
     358         112 :          cell%perd = (/1, 1, 0/)
     359             :       CASE (use_perd_xz)
     360          48 :          cell%perd = (/1, 0, 1/)
     361             :       CASE (use_perd_yz)
     362         208 :          cell%perd = (/0, 1, 1/)
     363             :       CASE (use_perd_xyz)
     364       51868 :          cell%perd = (/1, 1, 1/)
     365             :       CASE (use_perd_none)
     366       27120 :          cell%perd = (/0, 0, 0/)
     367             :       CASE DEFAULT
     368       19847 :          CPABORT("")
     369             :       END SELECT
     370             : 
     371             :       ! Load requested cell symmetry
     372       19847 :       CALL section_vals_val_get(cell_section, "SYMMETRY", i_val=cell%symmetry_id)
     373             : 
     374             :       ! Initialize cell
     375       19847 :       CALL init_cell(cell)
     376             : 
     377       19847 :       IF (my_check) THEN
     378             :          ! Recursive check for reference cell requested
     379       19409 :          cell_ref_section => section_vals_get_subs_vals(cell_section, "CELL_REF")
     380       19409 :          IF (parsed_cp2k_input(cell_ref_section, check_this_section=.TRUE.)) THEN
     381          44 :             IF (PRESENT(use_ref_cell)) use_ref_cell = .TRUE.
     382             :             CALL read_cell(cell_ref, cell_ref, use_ref_cell=use_ref_cell, &
     383             :                            cell_section=cell_ref_section, check_for_ref=.FALSE., &
     384          44 :                            para_env=para_env)
     385             :          ELSE
     386       19365 :             CALL cell_clone(cell, cell_ref, tag="CELL_REF")
     387       19365 :             IF (PRESENT(use_ref_cell)) use_ref_cell = .FALSE.
     388             :          END IF
     389             :       END IF
     390             : 
     391       19847 :    END SUBROUTINE read_cell
     392             : 
     393             : ! **************************************************************************************************
     394             : !> \brief utility function to ease the transition to the new input.
     395             : !>      returns true if the new input was parsed
     396             : !> \param input_file the parsed input file
     397             : !> \param check_this_section ...
     398             : !> \return ...
     399             : !> \author fawzi
     400             : ! **************************************************************************************************
     401       19409 :    FUNCTION parsed_cp2k_input(input_file, check_this_section) RESULT(res)
     402             : 
     403             :       TYPE(section_vals_type), POINTER                   :: input_file
     404             :       LOGICAL, INTENT(IN), OPTIONAL                      :: check_this_section
     405             :       LOGICAL                                            :: res
     406             : 
     407             :       LOGICAL                                            :: my_check
     408             :       TYPE(section_vals_type), POINTER                   :: glob_section
     409             : 
     410       19409 :       my_check = .FALSE.
     411       19409 :       IF (PRESENT(check_this_section)) my_check = check_this_section
     412       19409 :       res = ASSOCIATED(input_file)
     413       19409 :       IF (res) THEN
     414       19409 :          CPASSERT(input_file%ref_count > 0)
     415       19409 :          IF (.NOT. my_check) THEN
     416           0 :             glob_section => section_vals_get_subs_vals(input_file, "GLOBAL")
     417           0 :             CALL section_vals_get(glob_section, explicit=res)
     418             :          ELSE
     419       19409 :             CALL section_vals_get(input_file, explicit=res)
     420             :          END IF
     421             :       END IF
     422             : 
     423       19409 :    END FUNCTION parsed_cp2k_input
     424             : 
     425             : ! **************************************************************************************************
     426             : !> \brief   Sets the cell using the internal parameters (a,b,c) (alpha,beta,gamma)
     427             : !>          using the convention: a parallel to the x axis, b in the x-y plane and
     428             : !>          and c univoquely determined; gamma is the angle between a and b; beta
     429             : !>          is the angle between c and a and alpha is the angle between c and b
     430             : !> \param cell ...
     431             : !> \param cell_length ...
     432             : !> \param cell_angle ...
     433             : !> \param periodic ...
     434             : !> \param do_init_cell ...
     435             : !> \date    03.2008
     436             : !> \author  Teodoro Laino
     437             : ! **************************************************************************************************
     438       17451 :    SUBROUTINE set_cell_param(cell, cell_length, cell_angle, periodic, do_init_cell)
     439             : 
     440             :       TYPE(cell_type), POINTER                           :: cell
     441             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: cell_length, cell_angle
     442             :       INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL        :: periodic
     443             :       LOGICAL, INTENT(IN)                                :: do_init_cell
     444             : 
     445             :       REAL(KIND=dp), PARAMETER                           :: eps = EPSILON(0.0_dp)
     446             : 
     447             :       REAL(KIND=dp)                                      :: cos_alpha, cos_beta, cos_gamma, sin_gamma
     448             : 
     449       17451 :       CPASSERT(ASSOCIATED(cell))
     450       69804 :       CPASSERT(ALL(cell_angle /= 0.0_dp))
     451             : 
     452       17451 :       cos_gamma = COS(cell_angle(3)); IF (ABS(cos_gamma) < eps) cos_gamma = 0.0_dp
     453       17451 :       IF (ABS(ABS(cos_gamma) - 1.0_dp) < eps) cos_gamma = SIGN(1.0_dp, cos_gamma)
     454       17451 :       sin_gamma = SIN(cell_angle(3)); IF (ABS(sin_gamma) < eps) sin_gamma = 0.0_dp
     455       17451 :       IF (ABS(ABS(sin_gamma) - 1.0_dp) < eps) sin_gamma = SIGN(1.0_dp, sin_gamma)
     456       17451 :       cos_beta = COS(cell_angle(2)); IF (ABS(cos_beta) < eps) cos_beta = 0.0_dp
     457       17451 :       IF (ABS(ABS(cos_beta) - 1.0_dp) < eps) cos_beta = SIGN(1.0_dp, cos_beta)
     458       17451 :       cos_alpha = COS(cell_angle(1)); IF (ABS(cos_alpha) < eps) cos_alpha = 0.0_dp
     459       17451 :       IF (ABS(ABS(cos_alpha) - 1.0_dp) < eps) cos_alpha = SIGN(1.0_dp, cos_alpha)
     460             : 
     461       69804 :       cell%hmat(:, 1) = (/1.0_dp, 0.0_dp, 0.0_dp/)
     462       69804 :       cell%hmat(:, 2) = (/cos_gamma, sin_gamma, 0.0_dp/)
     463       69804 :       cell%hmat(:, 3) = (/cos_beta, (cos_alpha - cos_gamma*cos_beta)/sin_gamma, 0.0_dp/)
     464       17451 :       cell%hmat(3, 3) = SQRT(1.0_dp - cell%hmat(1, 3)**2 - cell%hmat(2, 3)**2)
     465             : 
     466       69804 :       cell%hmat(:, 1) = cell%hmat(:, 1)*cell_length(1)
     467       69804 :       cell%hmat(:, 2) = cell%hmat(:, 2)*cell_length(2)
     468       69804 :       cell%hmat(:, 3) = cell%hmat(:, 3)*cell_length(3)
     469             : 
     470       17451 :       IF (do_init_cell) THEN
     471          26 :          IF (PRESENT(periodic)) THEN
     472          26 :             CALL init_cell(cell=cell, periodic=periodic)
     473             :          ELSE
     474           0 :             CALL init_cell(cell=cell)
     475             :          END IF
     476             :       END IF
     477             : 
     478       17451 :    END SUBROUTINE set_cell_param
     479             : 
     480             : ! **************************************************************************************************
     481             : !> \brief   Setup of the multiple unit_cell
     482             : !> \param cell ...
     483             : !> \param multiple_unit_cell ...
     484             : !> \date    05.2009
     485             : !> \author  Teodoro Laino [tlaino]
     486             : !> \version 1.0
     487             : ! **************************************************************************************************
     488         300 :    SUBROUTINE set_multiple_unit_cell(cell, multiple_unit_cell)
     489             : 
     490             :       TYPE(cell_type), POINTER                           :: cell
     491             :       INTEGER, DIMENSION(:), POINTER                     :: multiple_unit_cell
     492             : 
     493         300 :       CPASSERT(ASSOCIATED(cell))
     494             : 
     495             :       ! Abort, if one of the value is set to zero
     496        1200 :       IF (ANY(multiple_unit_cell <= 0)) &
     497             :          CALL cp_abort(__LOCATION__, &
     498             :                        "CELL%MULTIPLE_UNIT_CELL accepts only integer values larger than 0! "// &
     499           0 :                        "A value of 0 or negative is meaningless!")
     500             : 
     501             :       ! Scale abc according to user request
     502        1200 :       cell%hmat(:, 1) = cell%hmat(:, 1)*multiple_unit_cell(1)
     503        1200 :       cell%hmat(:, 2) = cell%hmat(:, 2)*multiple_unit_cell(2)
     504        1200 :       cell%hmat(:, 3) = cell%hmat(:, 3)*multiple_unit_cell(3)
     505             : 
     506         300 :    END SUBROUTINE set_multiple_unit_cell
     507             : 
     508             : ! **************************************************************************************************
     509             : !> \brief   Read cell information from an external file
     510             : !> \param cell_section ...
     511             : !> \param para_env ...
     512             : !> \date    02.2008
     513             : !> \author  Teodoro Laino [tlaino] - University of Zurich
     514             : !> \version 1.0
     515             : ! **************************************************************************************************
     516          12 :    SUBROUTINE read_cell_from_external_file(cell_section, para_env)
     517             : 
     518             :       TYPE(section_vals_type), POINTER                   :: cell_section
     519             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     520             : 
     521             :       CHARACTER(LEN=default_path_length)                 :: cell_file_name
     522             :       INTEGER                                            :: i, idum, j, my_format, n_rep
     523             :       LOGICAL                                            :: explicit, my_end
     524             :       REAL(KIND=dp)                                      :: xdum
     525             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
     526          12 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: cell_par
     527             :       TYPE(cell_type), POINTER                           :: cell
     528             :       TYPE(cp_parser_type)                               :: parser
     529             : 
     530          12 :       CALL section_vals_val_get(cell_section, "CELL_FILE_NAME", c_val=cell_file_name)
     531          12 :       CALL section_vals_val_get(cell_section, "CELL_FILE_FORMAT", i_val=my_format)
     532           2 :       SELECT CASE (my_format)
     533             :       CASE (do_cell_cp2k)
     534           2 :          CALL parser_create(parser, cell_file_name, para_env=para_env)
     535           2 :          CALL parser_get_next_line(parser, 1)
     536           2 :          my_end = .FALSE.
     537          24 :          DO WHILE (.NOT. my_end)
     538          22 :             READ (parser%input_line, *) idum, xdum, hmat(:, 1), hmat(:, 2), hmat(:, 3)
     539          24 :             CALL parser_get_next_line(parser, 1, at_end=my_end)
     540             :          END DO
     541           2 :          CALL parser_release(parser)
     542             :          ! Convert to CP2K units
     543           8 :          DO i = 1, 3
     544          26 :             DO j = 1, 3
     545          24 :                hmat(j, i) = cp_unit_to_cp2k(hmat(j, i), "angstrom")
     546             :             END DO
     547             :          END DO
     548             :       CASE (do_cell_xsc)
     549           0 :          CALL parser_create(parser, cell_file_name, para_env=para_env)
     550           0 :          CALL parser_get_next_line(parser, 1)
     551           0 :          READ (parser%input_line, *) idum, hmat(:, 1), hmat(:, 2), hmat(:, 3)
     552           0 :          CALL parser_release(parser)
     553             :          ! Convert to CP2K units
     554           0 :          DO i = 1, 3
     555           0 :             DO j = 1, 3
     556           0 :                hmat(j, i) = cp_unit_to_cp2k(hmat(j, i), "angstrom")
     557             :             END DO
     558             :          END DO
     559             :       CASE (do_cell_cif)
     560          10 :          NULLIFY (cell)
     561          10 :          CALL cell_create(cell)
     562          10 :          CALL read_cell_cif(cell_file_name, cell, para_env)
     563         130 :          hmat = cell%hmat
     564          22 :          CALL cell_release(cell)
     565             :       END SELECT
     566          12 :       CALL section_vals_val_unset(cell_section, "CELL_FILE_NAME")
     567          12 :       CALL section_vals_val_unset(cell_section, "CELL_FILE_FORMAT")
     568             :       ! Check if the cell was already defined
     569          12 :       explicit = .FALSE.
     570          12 :       CALL section_vals_val_get(cell_section, "A", n_rep_val=n_rep)
     571          12 :       explicit = explicit .OR. (n_rep == 1)
     572          12 :       CALL section_vals_val_get(cell_section, "B", n_rep_val=n_rep)
     573          12 :       explicit = explicit .OR. (n_rep == 1)
     574          12 :       CALL section_vals_val_get(cell_section, "C", n_rep_val=n_rep)
     575          12 :       explicit = explicit .OR. (n_rep == 1)
     576          12 :       CALL section_vals_val_get(cell_section, "ABC", n_rep_val=n_rep)
     577          12 :       explicit = explicit .OR. (n_rep == 1)
     578             :       ! Possibly print a warning
     579             :       IF (explicit) &
     580             :          CALL cp_warn(__LOCATION__, &
     581             :                       "Cell specification (A,B,C or ABC) provided together with the external "// &
     582             :                       "cell setup! Ignoring (A,B,C or ABC) and proceeding with info read from the "// &
     583           0 :                       "external file! ")
     584             :       ! Copy cell information in the A, B, C fields..(we may need them later on..)
     585          12 :       ALLOCATE (cell_par(3))
     586          48 :       cell_par = hmat(:, 1)
     587          12 :       CALL section_vals_val_set(cell_section, "A", r_vals_ptr=cell_par)
     588          12 :       ALLOCATE (cell_par(3))
     589          48 :       cell_par = hmat(:, 2)
     590          12 :       CALL section_vals_val_set(cell_section, "B", r_vals_ptr=cell_par)
     591          12 :       ALLOCATE (cell_par(3))
     592          48 :       cell_par = hmat(:, 3)
     593          12 :       CALL section_vals_val_set(cell_section, "C", r_vals_ptr=cell_par)
     594             :       ! Unset possible keywords
     595          12 :       CALL section_vals_val_unset(cell_section, "ABC")
     596          12 :       CALL section_vals_val_unset(cell_section, "ALPHA_BETA_GAMMA")
     597             : 
     598          84 :    END SUBROUTINE read_cell_from_external_file
     599             : 
     600             : ! **************************************************************************************************
     601             : !> \brief  Reads cell information from CIF file
     602             : !> \param cif_file_name ...
     603             : !> \param cell ...
     604             : !> \param para_env ...
     605             : !> \date   12.2008
     606             : !> \par    Format Information implemented:
     607             : !>            _cell_length_a
     608             : !>            _cell_length_b
     609             : !>            _cell_length_c
     610             : !>            _cell_angle_alpha
     611             : !>            _cell_angle_beta
     612             : !>            _cell_angle_gamma
     613             : !>
     614             : !> \author Teodoro Laino [tlaino]
     615             : !>         moved from topology_cif (1/2019 JHU)
     616             : ! **************************************************************************************************
     617          48 :    SUBROUTINE read_cell_cif(cif_file_name, cell, para_env)
     618             : 
     619             :       CHARACTER(len=*)                                   :: cif_file_name
     620             :       TYPE(cell_type), POINTER                           :: cell
     621             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     622             : 
     623             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'read_cell_cif'
     624             : 
     625             :       INTEGER                                            :: handle
     626             :       INTEGER, DIMENSION(3)                              :: periodic
     627             :       LOGICAL                                            :: found
     628             :       REAL(KIND=dp), DIMENSION(3)                        :: cell_angles, cell_lengths
     629             :       TYPE(cp_parser_type)                               :: parser
     630             : 
     631          24 :       CALL timeset(routineN, handle)
     632             : 
     633             :       CALL parser_create(parser, cif_file_name, &
     634          24 :                          para_env=para_env, apply_preprocessing=.FALSE.)
     635             : 
     636             :       ! Parsing cell infos
     637          96 :       periodic = 1
     638             :       ! Check for   _cell_length_a
     639             :       CALL parser_search_string(parser, "_cell_length_a", ignore_case=.FALSE., found=found, &
     640          24 :                                 begin_line=.FALSE., search_from_begin_of_file=.TRUE.)
     641          24 :       IF (.NOT. found) &
     642           0 :          CPABORT("The field (_cell_length_a) was not found in CIF file! ")
     643          24 :       CALL cif_get_real(parser, cell_lengths(1))
     644          24 :       cell_lengths(1) = cp_unit_to_cp2k(cell_lengths(1), "angstrom")
     645             : 
     646             :       ! Check for   _cell_length_b
     647             :       CALL parser_search_string(parser, "_cell_length_b", ignore_case=.FALSE., found=found, &
     648          24 :                                 begin_line=.FALSE., search_from_begin_of_file=.TRUE.)
     649          24 :       IF (.NOT. found) &
     650           0 :          CPABORT("The field (_cell_length_b) was not found in CIF file! ")
     651          24 :       CALL cif_get_real(parser, cell_lengths(2))
     652          24 :       cell_lengths(2) = cp_unit_to_cp2k(cell_lengths(2), "angstrom")
     653             : 
     654             :       ! Check for   _cell_length_c
     655             :       CALL parser_search_string(parser, "_cell_length_c", ignore_case=.FALSE., found=found, &
     656          24 :                                 begin_line=.FALSE., search_from_begin_of_file=.TRUE.)
     657          24 :       IF (.NOT. found) &
     658           0 :          CPABORT("The field (_cell_length_c) was not found in CIF file! ")
     659          24 :       CALL cif_get_real(parser, cell_lengths(3))
     660          24 :       cell_lengths(3) = cp_unit_to_cp2k(cell_lengths(3), "angstrom")
     661             : 
     662             :       ! Check for   _cell_angle_alpha
     663             :       CALL parser_search_string(parser, "_cell_angle_alpha", ignore_case=.FALSE., found=found, &
     664          24 :                                 begin_line=.FALSE., search_from_begin_of_file=.TRUE.)
     665          24 :       IF (.NOT. found) &
     666           0 :          CPABORT("The field (_cell_angle_alpha) was not found in CIF file! ")
     667          24 :       CALL cif_get_real(parser, cell_angles(1))
     668          24 :       cell_angles(1) = cp_unit_to_cp2k(cell_angles(1), "deg")
     669             : 
     670             :       ! Check for   _cell_angle_beta
     671             :       CALL parser_search_string(parser, "_cell_angle_beta", ignore_case=.FALSE., found=found, &
     672          24 :                                 begin_line=.FALSE., search_from_begin_of_file=.TRUE.)
     673          24 :       IF (.NOT. found) &
     674           0 :          CPABORT("The field (_cell_angle_beta) was not found in CIF file! ")
     675          24 :       CALL cif_get_real(parser, cell_angles(2))
     676          24 :       cell_angles(2) = cp_unit_to_cp2k(cell_angles(2), "deg")
     677             : 
     678             :       ! Check for   _cell_angle_gamma
     679             :       CALL parser_search_string(parser, "_cell_angle_gamma", ignore_case=.FALSE., found=found, &
     680          24 :                                 begin_line=.FALSE., search_from_begin_of_file=.TRUE.)
     681          24 :       IF (.NOT. found) &
     682           0 :          CPABORT("The field (_cell_angle_gamma) was not found in CIF file! ")
     683          24 :       CALL cif_get_real(parser, cell_angles(3))
     684          24 :       cell_angles(3) = cp_unit_to_cp2k(cell_angles(3), "deg")
     685             : 
     686             :       ! Create cell
     687             :       CALL set_cell_param(cell, cell_lengths, cell_angles, periodic=periodic, &
     688          24 :                           do_init_cell=.TRUE.)
     689             : 
     690          24 :       CALL parser_release(parser)
     691             : 
     692          24 :       CALL timestop(handle)
     693             : 
     694          72 :    END SUBROUTINE read_cell_cif
     695             : 
     696             : ! **************************************************************************************************
     697             : !> \brief  Reads REAL from the CIF file.. This wrapper is needed in order to
     698             : !>         treat properly the accuracy specified in the CIF file, i.e. 3.45(6)
     699             : !> \param parser ...
     700             : !> \param r ...
     701             : !> \date   12.2008
     702             : !> \author Teodoro Laino [tlaino]
     703             : ! **************************************************************************************************
     704         144 :    SUBROUTINE cif_get_real(parser, r)
     705             : 
     706             :       TYPE(cp_parser_type), INTENT(INOUT)                :: parser
     707             :       REAL(KIND=dp), INTENT(OUT)                         :: r
     708             : 
     709             :       CHARACTER(LEN=default_string_length)               :: s_tag
     710             :       INTEGER                                            :: iln
     711             : 
     712         144 :       CALL parser_get_object(parser, s_tag)
     713         144 :       iln = LEN_TRIM(s_tag)
     714         144 :       IF (INDEX(s_tag, "(") /= 0) iln = INDEX(s_tag, "(") - 1
     715         144 :       READ (s_tag(1:iln), *) r
     716             : 
     717         144 :    END SUBROUTINE cif_get_real
     718             : 
     719             : ! **************************************************************************************************
     720             : !> \brief   Write the cell parameters to the output unit.
     721             : !> \param cell ...
     722             : !> \param subsys_section ...
     723             : !> \param tag ...
     724             : !> \date    02.06.2000
     725             : !> \par     History
     726             : !>    - 11.2008 Teodoro Laino [tlaino] - rewrite and enabling user driven units
     727             : !> \author  Matthias Krack
     728             : !> \version 1.0
     729             : ! **************************************************************************************************
     730       36141 :    SUBROUTINE write_cell(cell, subsys_section, tag)
     731             : 
     732             :       TYPE(cell_type), POINTER                           :: cell
     733             :       TYPE(section_vals_type), POINTER                   :: subsys_section
     734             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: tag
     735             : 
     736             :       CHARACTER(LEN=default_string_length)               :: label, unit_str
     737             :       INTEGER                                            :: output_unit
     738             :       TYPE(cp_logger_type), POINTER                      :: logger
     739             : 
     740       36141 :       NULLIFY (logger)
     741       36141 :       logger => cp_get_default_logger()
     742       36141 :       IF (PRESENT(tag)) THEN
     743        9628 :          label = TRIM(tag)//"|"
     744             :       ELSE
     745       26513 :          label = TRIM(cell%tag)//"|"
     746             :       END IF
     747             : 
     748       36141 :       output_unit = cp_print_key_unit_nr(logger, subsys_section, "PRINT%CELL", extension=".Log")
     749       36141 :       CALL section_vals_val_get(subsys_section, "PRINT%CELL%UNIT", c_val=unit_str)
     750       36141 :       CALL write_cell_low(cell, unit_str, output_unit, label)
     751       36141 :       CALL cp_print_key_finished_output(output_unit, logger, subsys_section, "PRINT%CELL")
     752             : 
     753       36141 :    END SUBROUTINE write_cell
     754             : 
     755             : ! **************************************************************************************************
     756             : !> \brief  Write the cell parameters to the output unit
     757             : !> \param cell ...
     758             : !> \param unit_str ...
     759             : !> \param output_unit ...
     760             : !> \param label ...
     761             : !> \date  17.05.2023
     762             : !> \par   History
     763             : !>        - Extracted from write_cell (17.05.2023, MK)
     764             : !> \version 1.0
     765             : ! **************************************************************************************************
     766       36141 :    SUBROUTINE write_cell_low(cell, unit_str, output_unit, label)
     767             : 
     768             :       TYPE(cell_type), POINTER                           :: cell
     769             :       CHARACTER(LEN=*), INTENT(IN)                       :: unit_str
     770             :       INTEGER, INTENT(IN)                                :: output_unit
     771             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: label
     772             : 
     773             :       CHARACTER(LEN=12)                                  :: tag
     774             :       CHARACTER(LEN=3)                                   :: string
     775             :       CHARACTER(LEN=default_string_length)               :: my_label
     776             :       REAL(KIND=dp)                                      :: alpha, beta, gamma, val
     777             :       REAL(KIND=dp), DIMENSION(3)                        :: abc
     778             :       TYPE(enumeration_type), POINTER                    :: enum
     779             :       TYPE(keyword_type), POINTER                        :: keyword
     780             :       TYPE(section_type), POINTER                        :: section
     781             : 
     782       36141 :       NULLIFY (enum)
     783       36141 :       NULLIFY (keyword)
     784       36141 :       NULLIFY (section)
     785             : 
     786       47328 :       IF (output_unit > 0) THEN
     787       11187 :          CALL get_cell(cell=cell, abc=abc, alpha=alpha, beta=beta, gamma=gamma, tag=tag)
     788       11187 :          IF (PRESENT(label)) THEN
     789       11187 :             my_label = label
     790             :          ELSE
     791           0 :             my_label = TRIM(tag)//"|"
     792             :          END IF
     793       11187 :          val = cp_unit_from_cp2k(cell%deth, TRIM(unit_str)//"^3")
     794             :          WRITE (UNIT=output_unit, FMT="(/,T2,A,T61,F20.6)") &
     795       11187 :             TRIM(my_label)//" Volume ["//TRIM(unit_str)//"^3]:", val
     796       11187 :          val = cp_unit_from_cp2k(1.0_dp, TRIM(unit_str))
     797             :          WRITE (UNIT=output_unit, FMT="(T2,A,T30,3F10.3,3X,A6,F12.6)") &
     798       44748 :             TRIM(my_label)//" Vector a ["//TRIM(unit_str)//"]:", cell%hmat(:, 1)*val, &
     799       11187 :             "|a| = ", abc(1)*val, &
     800       44748 :             TRIM(my_label)//" Vector b ["//TRIM(unit_str)//"]:", cell%hmat(:, 2)*val, &
     801       11187 :             "|b| = ", abc(2)*val, &
     802       44748 :             TRIM(my_label)//" Vector c ["//TRIM(unit_str)//"]:", cell%hmat(:, 3)*val, &
     803       22374 :             "|c| = ", abc(3)*val
     804             :          WRITE (UNIT=output_unit, FMT="(T2,A,T69,F12.6)") &
     805       11187 :             TRIM(my_label)//" Angle (b,c), alpha [degree]: ", alpha, &
     806       11187 :             TRIM(my_label)//" Angle (a,c), beta  [degree]: ", beta, &
     807       22374 :             TRIM(my_label)//" Angle (a,b), gamma [degree]: ", gamma
     808       11187 :          IF (cell%symmetry_id /= cell_sym_none) THEN
     809        1453 :             CALL create_cell_section(section)
     810        1453 :             keyword => section_get_keyword(section, "SYMMETRY")
     811        1453 :             CALL keyword_get(keyword, enum=enum)
     812             :             WRITE (UNIT=output_unit, FMT="(T2,A,T61,A20)") &
     813        1453 :                TRIM(my_label)//" Requested initial symmetry: ", &
     814        2906 :                ADJUSTR(TRIM(enum_i2c(enum, cell%symmetry_id)))
     815        1453 :             CALL section_release(section)
     816             :          END IF
     817       11187 :          IF (cell%orthorhombic) THEN
     818             :             WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
     819        7957 :                TRIM(my_label)//" Numerically orthorhombic: ", "YES"
     820             :          ELSE
     821             :             WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
     822        3230 :                TRIM(my_label)//" Numerically orthorhombic: ", " NO"
     823             :          END IF
     824       44748 :          IF (SUM(cell%perd(1:3)) == 0) THEN
     825             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     826        2327 :                TRIM(my_label)//" Periodicity", "NONE"
     827             :          ELSE
     828        8860 :             string = ""
     829        8860 :             IF (cell%perd(1) == 1) string = TRIM(string)//"X"
     830        8860 :             IF (cell%perd(2) == 1) string = TRIM(string)//"Y"
     831        8860 :             IF (cell%perd(3) == 1) string = TRIM(string)//"Z"
     832             :             WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
     833        8860 :                TRIM(my_label)//" Periodicity", ADJUSTR(string)
     834             :          END IF
     835             :       END IF
     836             : 
     837       36141 :    END SUBROUTINE write_cell_low
     838             : 
     839             : END MODULE cell_methods

Generated by: LCOV version 1.15