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 Contains type used for a Simulation Cell Optimization
10 : !> \par History
11 : !> none
12 : !> \author Teodoro Laino - created [tlaino] - 03.2008 - Zurich University
13 : ! **************************************************************************************************
14 : MODULE cell_opt_types
15 :
16 : USE cell_methods, ONLY: cell_create
17 : USE cell_opt_utils, ONLY: read_external_press_tensor
18 : USE cell_types, ONLY: cell_clone,&
19 : cell_release,&
20 : cell_type
21 : USE cp_log_handling, ONLY: cp_get_default_logger,&
22 : cp_logger_type
23 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
24 : cp_print_key_unit_nr
25 : USE cp_subsys_types, ONLY: cp_subsys_get,&
26 : cp_subsys_type
27 : USE cp_units, ONLY: cp_unit_from_cp2k
28 : USE force_env_types, ONLY: force_env_get,&
29 : force_env_type
30 : USE input_constants, ONLY: fix_none,&
31 : fix_x,&
32 : fix_xy,&
33 : fix_xz,&
34 : fix_y,&
35 : fix_yz,&
36 : fix_z
37 : USE input_section_types, ONLY: section_vals_type,&
38 : section_vals_val_get
39 : USE kinds, ONLY: dp
40 : USE particle_list_types, ONLY: particle_list_type
41 : #include "../base/base_uses.f90"
42 :
43 : IMPLICIT NONE
44 : PRIVATE
45 :
46 : LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .FALSE.
47 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cell_opt_types'
48 :
49 : PUBLIC :: cell_opt_env_type, &
50 : cell_opt_env_create, &
51 : cell_opt_env_release
52 :
53 : ! **************************************************************************************************
54 : !> \brief Type containing all informations abour the simulation cell optimization
55 : !> \par History
56 : !> none
57 : !> \author Teodoro Laino - created [tlaino] - 03.2008 - Zurich University
58 : ! **************************************************************************************************
59 : TYPE cell_opt_env_type
60 : ! Simulation cell optimization parameters
61 : INTEGER :: constraint_id = fix_none
62 : LOGICAL :: keep_angles = .FALSE., &
63 : keep_symmetry = .FALSE., &
64 : keep_volume = .FALSE.
65 : REAL(KIND=dp) :: pres_ext = 0.0_dp, pres_int = 0.0_dp, pres_tol = 0.0_dp, pres_constr = 0.0_dp
66 : REAL(KIND=dp), DIMENSION(3, 3) :: mtrx = 0.0_dp
67 : REAL(KIND=dp), DIMENSION(3, 3) :: rot_matrix = 0.0_dp
68 : TYPE(cell_type), POINTER :: ref_cell => NULL()
69 : END TYPE cell_opt_env_type
70 :
71 : CONTAINS
72 :
73 : ! **************************************************************************************************
74 : !> \brief ...
75 : !> \param cell_env ...
76 : !> \param force_env ...
77 : !> \param geo_section ...
78 : !> \par History
79 : !> none
80 : !> \author Teodoro Laino - created [tlaino] - 03.2008 - Zurich University
81 : ! **************************************************************************************************
82 5304 : SUBROUTINE cell_opt_env_create(cell_env, force_env, geo_section)
83 : TYPE(cell_opt_env_type), INTENT(OUT) :: cell_env
84 : TYPE(force_env_type), POINTER :: force_env
85 : TYPE(section_vals_type), POINTER :: geo_section
86 :
87 : CHARACTER(LEN=4) :: label
88 : INTEGER :: ip, output_unit, required_constraint_id
89 : LOGICAL :: constraint_explicit, valid_constraint
90 : REAL(KIND=dp), DIMENSION(3) :: r
91 : TYPE(cell_type), POINTER :: cell
92 : TYPE(cp_logger_type), POINTER :: logger
93 : TYPE(cp_subsys_type), POINTER :: subsys
94 : TYPE(particle_list_type), POINTER :: particles
95 :
96 204 : NULLIFY (cell_env%ref_cell, cell, subsys, particles)
97 204 : CALL force_env_get(force_env, cell=cell, subsys=subsys)
98 204 : CALL cell_create(cell_env%ref_cell)
99 204 : CALL cell_clone(cell, cell_env%ref_cell, tag="REF_CELL_OPT")
100 204 : CALL section_vals_val_get(geo_section, "KEEP_VOLUME", l_val=cell_env%keep_volume)
101 204 : CALL section_vals_val_get(geo_section, "KEEP_ANGLES", l_val=cell_env%keep_angles)
102 204 : CALL section_vals_val_get(geo_section, "KEEP_SYMMETRY", l_val=cell_env%keep_symmetry)
103 204 : CALL section_vals_val_get(geo_section, "PRESSURE_TOLERANCE", r_val=cell_env%pres_tol)
104 : CALL section_vals_val_get(geo_section, "CONSTRAINT", &
105 204 : i_val=cell_env%constraint_id, explicit=constraint_explicit)
106 :
107 816 : IF (COUNT(cell%perd /= 0) == 2) THEN
108 0 : required_constraint_id = fix_none
109 0 : IF (cell%perd(1) == 0) required_constraint_id = fix_x
110 0 : IF (cell%perd(2) == 0) required_constraint_id = fix_y
111 0 : IF (cell%perd(3) == 0) required_constraint_id = fix_z
112 :
113 0 : SELECT CASE (required_constraint_id)
114 : CASE (fix_x)
115 : valid_constraint = cell_env%constraint_id == fix_x .OR. &
116 : cell_env%constraint_id == fix_xy .OR. &
117 0 : cell_env%constraint_id == fix_xz
118 : CASE (fix_y)
119 : valid_constraint = cell_env%constraint_id == fix_y .OR. &
120 : cell_env%constraint_id == fix_xy .OR. &
121 0 : cell_env%constraint_id == fix_yz
122 : CASE (fix_z)
123 : valid_constraint = cell_env%constraint_id == fix_z .OR. &
124 : cell_env%constraint_id == fix_xz .OR. &
125 0 : cell_env%constraint_id == fix_yz
126 : CASE DEFAULT
127 0 : valid_constraint = .FALSE.
128 : END SELECT
129 :
130 0 : IF (cell_env%constraint_id == fix_none .AND. .NOT. constraint_explicit) THEN
131 0 : cell_env%constraint_id = required_constraint_id
132 : CALL cp_warn(__LOCATION__, &
133 0 : "2D CELL_OPT: constraining non-periodic cell direction.")
134 0 : ELSE IF (.NOT. valid_constraint) THEN
135 : CALL cp_abort(__LOCATION__, &
136 0 : "2D CELL_OPT needs constrained non-periodic cell direction.")
137 : END IF
138 : END IF
139 :
140 : ! Compute the rotation matrix that give the cell vectors in the "canonical" orientation
141 10812 : cell_env%rot_matrix = MATMUL(cell_env%ref_cell%hmat, cell%h_inv)
142 :
143 : ! Get the external pressure
144 : CALL read_external_press_tensor(geo_section, cell, cell_env%pres_ext, cell_env%mtrx, &
145 204 : cell_env%rot_matrix)
146 :
147 : ! Rotate particles accordingly
148 204 : CALL cp_subsys_get(subsys, particles=particles)
149 17398 : DO ip = 1, particles%n_els
150 17194 : r = MATMUL(TRANSPOSE(cell_env%rot_matrix), particles%els(ip)%r)
151 68980 : particles%els(ip)%r = r
152 : END DO
153 :
154 : ! Print cell optimisation setup
155 204 : NULLIFY (logger)
156 204 : logger => cp_get_default_logger()
157 204 : output_unit = cp_print_key_unit_nr(logger, geo_section, "PRINT%CELL", extension=".Log")
158 204 : IF (output_unit > 0) THEN
159 : WRITE (UNIT=output_unit, FMT="(/,T2,A,T61,F20.1)") &
160 102 : "CELL_OPT| Pressure tolerance [bar]: ", cp_unit_from_cp2k(cell_env%pres_tol, "bar")
161 102 : IF (cell_env%keep_volume) THEN
162 : WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
163 3 : "CELL_OPT| Keep volume of cell: ", "YES"
164 : ELSE
165 : WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
166 99 : "CELL_OPT| Keep volume of cell: ", " NO"
167 : END IF
168 102 : IF (cell_env%keep_angles) THEN
169 : WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
170 16 : "CELL_OPT| Keep angles between the cell vectors: ", "YES"
171 : ELSE
172 : WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
173 86 : "CELL_OPT| Keep angles between the cell vectors: ", " NO"
174 : END IF
175 102 : IF (cell_env%keep_symmetry) THEN
176 : WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
177 21 : "CELL_OPT| Keep cell symmetry: ", "YES"
178 : ELSE
179 : WRITE (UNIT=output_unit, FMT="(T2,A,T78,A3)") &
180 81 : "CELL_OPT| Keep cell symmetry: ", " NO"
181 : END IF
182 102 : SELECT CASE (cell_env%constraint_id)
183 : CASE (fix_x)
184 0 : label = " X"
185 : CASE (fix_y)
186 0 : label = " Y"
187 : CASE (fix_z)
188 1 : label = " Z"
189 : CASE (fix_xy)
190 1 : label = " XY"
191 : CASE (fix_xz)
192 0 : label = " XZ"
193 : CASE (fix_yz)
194 0 : label = " YZ"
195 : CASE (fix_none)
196 102 : label = "NONE"
197 : END SELECT
198 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
199 102 : "CELL_OPT| Constraint: ", label
200 : END IF
201 204 : CALL cp_print_key_finished_output(output_unit, logger, geo_section, "PRINT%CELL")
202 :
203 204 : END SUBROUTINE cell_opt_env_create
204 :
205 : ! **************************************************************************************************
206 : !> \brief ...
207 : !> \param cell_env ...
208 : !> \par History
209 : !> none
210 : !> \author Teodoro Laino - created [tlaino] - 03.2008 - Zurich University
211 : ! **************************************************************************************************
212 204 : SUBROUTINE cell_opt_env_release(cell_env)
213 : TYPE(cell_opt_env_type), INTENT(INOUT) :: cell_env
214 :
215 204 : CALL cell_release(cell_env%ref_cell)
216 :
217 204 : END SUBROUTINE cell_opt_env_release
218 :
219 0 : END MODULE cell_opt_types
|