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 : MODULE atom
10 : USE atom_basis, ONLY: atom_basis_opt
11 : USE atom_energy, ONLY: atom_energy_opt
12 : USE atom_pseudo, ONLY: atom_pseudo_opt
13 : USE cp_log_handling, ONLY: cp_get_default_logger,&
14 : cp_logger_type
15 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
16 : cp_print_key_unit_nr
17 : USE header, ONLY: atom_footer,&
18 : atom_header
19 : USE input_constants, ONLY: atom_basis_run,&
20 : atom_energy_run,&
21 : atom_no_run,&
22 : atom_pseudo_run
23 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
24 : section_vals_type,&
25 : section_vals_val_get
26 : USE kinds, ONLY: default_string_length
27 : USE periodic_table, ONLY: nelem,&
28 : ptable
29 : #include "./base/base_uses.f90"
30 :
31 : IMPLICIT NONE
32 : PRIVATE
33 : PUBLIC :: atom_code
34 :
35 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'atom'
36 :
37 : CONTAINS
38 :
39 : ! **************************************************************************************************
40 : !> \brief Driver routine to perform atomic calculations.
41 : !> \param root_section root input section
42 : !> \par History
43 : !> * 08.2008 created [Juerg Hutter]
44 : ! **************************************************************************************************
45 720 : SUBROUTINE atom_code(root_section)
46 : TYPE(section_vals_type), POINTER :: root_section
47 :
48 : CHARACTER(len=*), PARAMETER :: routineN = 'atom_code'
49 :
50 : INTEGER :: handle, iw, run_type_id
51 : TYPE(cp_logger_type), POINTER :: logger
52 : TYPE(section_vals_type), POINTER :: atom_section
53 :
54 360 : CALL timeset(routineN, handle)
55 :
56 360 : logger => cp_get_default_logger()
57 360 : NULLIFY (atom_section)
58 360 : atom_section => section_vals_get_subs_vals(root_section, "ATOM")
59 :
60 360 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%PROGRAM_BANNER", extension=".log")
61 360 : CALL atom_header(iw)
62 360 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%PROGRAM_BANNER")
63 :
64 360 : CALL atom_test(atom_section)
65 :
66 360 : CALL section_vals_val_get(atom_section, "RUN_TYPE", i_val=run_type_id)
67 324 : SELECT CASE (run_type_id)
68 : CASE (atom_no_run)
69 : ! do (almost) nothing
70 : CASE (atom_energy_run)
71 324 : CALL atom_energy_opt(atom_section)
72 : CASE (atom_basis_run)
73 10 : CALL atom_basis_opt(atom_section)
74 : CASE (atom_pseudo_run)
75 26 : CALL atom_pseudo_opt(atom_section)
76 : CASE default
77 360 : CPABORT("")
78 : END SELECT
79 :
80 360 : iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%PROGRAM_BANNER", extension=".log")
81 360 : CALL atom_footer(iw)
82 360 : CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%PROGRAM_BANNER")
83 :
84 360 : CALL timestop(handle)
85 :
86 360 : END SUBROUTINE atom_code
87 :
88 : ! **************************************************************************************************
89 : !> \brief Check consistency between the element symbol and its atomic number.
90 : !> \param atom_section ATOM input section
91 : !> \par History
92 : !> * 08.2008 created [Juerg Hutter]
93 : ! **************************************************************************************************
94 1080 : SUBROUTINE atom_test(atom_section)
95 : TYPE(section_vals_type), POINTER :: atom_section
96 :
97 : CHARACTER(len=*), PARAMETER :: routineN = 'atom_test'
98 :
99 : CHARACTER(len=2) :: elem
100 : CHARACTER(len=default_string_length) :: z_string
101 : INTEGER :: handle, i, z
102 : LOGICAL :: explicit_elem, explicit_z
103 :
104 360 : CALL timeset(routineN, handle)
105 :
106 360 : CALL section_vals_val_get(atom_section, "ATOMIC_NUMBER", i_val=z, explicit=explicit_z)
107 360 : CALL section_vals_val_get(atom_section, "ELEMENT", c_val=elem, explicit=explicit_elem)
108 :
109 : IF (explicit_z .AND. (z <= 0 .AND. z > nelem)) THEN
110 : ! an explicit atomic number is not found in the periodic table
111 : WRITE (z_string, '(I0)') z
112 : CALL cp_abort(__LOCATION__, &
113 : "The element with the atomic number "//TRIM(z_string)//" is not found in the periodic table.")
114 : END IF
115 :
116 360 : IF (explicit_elem) THEN
117 : ! check that the element symbol is part of the periodic table
118 11896 : DO i = 1, nelem
119 11896 : IF (ptable(i)%symbol == elem) EXIT
120 : END DO
121 :
122 320 : IF (i > nelem) THEN
123 : CALL cp_abort(__LOCATION__, &
124 0 : "The element symbol ("//TRIM(elem)//") is not found in the periodic table.")
125 : END IF
126 : END IF
127 :
128 360 : IF (explicit_z .AND. explicit_elem) THEN
129 : ! check that the element symbol read from the input file
130 : ! matches for the explicitly given atomic number
131 0 : IF (ptable(z)%symbol /= elem) THEN
132 0 : WRITE (z_string, '(I0)') z
133 : CALL cp_abort(__LOCATION__, &
134 : "The element symbol ("//TRIM(elem)// &
135 : ") contradicts with the explicitly given atomic number ("// &
136 0 : TRIM(z_string)//").")
137 : END IF
138 360 : ELSE IF (.NOT. (explicit_z .OR. explicit_elem)) THEN
139 : ! default (implicit) element symbol and atomic number are usually consistent,
140 : ! but check them just in case
141 0 : CPASSERT(ptable(z)%symbol == elem)
142 : END IF
143 :
144 360 : CALL timestop(handle)
145 360 : END SUBROUTINE atom_test
146 :
147 : END MODULE atom
|