(git:e7e05ae)
optimize_dmfet_potential.F
Go to the documentation of this file.
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 
11  cp_blacs_env_type
12  USE cp_control_types, ONLY: dft_control_type
16  cp_fm_struct_type
17  USE cp_fm_types, ONLY: cp_fm_copy_general,&
18  cp_fm_create,&
20  cp_fm_release,&
22  cp_fm_type
23  USE dbcsr_api, ONLY: dbcsr_create,&
24  dbcsr_init_p,&
25  dbcsr_multiply,&
26  dbcsr_p_type,&
27  dbcsr_release,&
28  dbcsr_trace,&
29  dbcsr_type,&
30  dbcsr_type_no_symmetry
31  USE embed_types, ONLY: opt_dmfet_pot_type
32  USE input_section_types, ONLY: section_vals_type,&
34  USE kinds, ONLY: dp
35  USE message_passing, ONLY: mp_para_env_type
36  USE parallel_gemm_api, ONLY: parallel_gemm
37  USE qs_environment_types, ONLY: get_qs_env,&
38  qs_environment_type
39  USE qs_mo_types, ONLY: get_mo_set,&
40  mo_set_type
41 #include "./base/base_uses.f90"
42 
43  IMPLICIT NONE
44 
45  PRIVATE
46 
47  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'optimize_dmfet_potential'
48 
50 
51 CONTAINS
52 
53 ! **************************************************************************************************
54 !> \brief ...
55 !> \param opt_dmfet ...
56 !> \param opt_dmfet_section ...
57 ! **************************************************************************************************
58  SUBROUTINE read_opt_dmfet_section(opt_dmfet, opt_dmfet_section)
59  TYPE(opt_dmfet_pot_type) :: opt_dmfet
60  TYPE(section_vals_type), POINTER :: opt_dmfet_section
61 
62  ! Read keywords
63 
64  CALL section_vals_val_get(opt_dmfet_section, "N_ITER", &
65  i_val=opt_dmfet%n_iter)
66 
67  CALL section_vals_val_get(opt_dmfet_section, "TRUST_RAD", &
68  r_val=opt_dmfet%trust_rad)
69 
70  CALL section_vals_val_get(opt_dmfet_section, "DM_CONV_MAX", &
71  r_val=opt_dmfet%conv_max)
72 
73  CALL section_vals_val_get(opt_dmfet_section, "DM_CONV_INT", &
74  r_val=opt_dmfet%conv_int)
75 
76  CALL section_vals_val_get(opt_dmfet_section, "BETA_DM_CONV_MAX", &
77  r_val=opt_dmfet%conv_max_beta)
78 
79  CALL section_vals_val_get(opt_dmfet_section, "BETA_DM_CONV_INT", &
80  r_val=opt_dmfet%conv_int_beta)
81 
82  CALL section_vals_val_get(opt_dmfet_section, "READ_DMFET_POT", &
83  l_val=opt_dmfet%read_dmfet_pot)
84 
85  END SUBROUTINE read_opt_dmfet_section
86 
87 ! **************************************************************************************************
88 !> \brief ...
89 !> \param qs_env ...
90 !> \return ...
91 ! **************************************************************************************************
92  FUNCTION subsys_spin(qs_env) RESULT(subsys_open_shell)
93  TYPE(qs_environment_type), POINTER :: qs_env
94  LOGICAL :: subsys_open_shell
95 
96  TYPE(dft_control_type), POINTER :: dft_control
97 
98  NULLIFY (dft_control)
99  CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
100  subsys_open_shell = .false.
101  IF (dft_control%nspins == 2) subsys_open_shell = .true.
102 
103  END FUNCTION subsys_spin
104 
105 ! **************************************************************************************************
106 !> \brief ...
107 !> \param qs_env ...
108 !> \param opt_dmfet ...
109 !> \param opt_dmfet_section ...
110 ! **************************************************************************************************
111  SUBROUTINE prepare_dmfet_opt(qs_env, opt_dmfet, opt_dmfet_section)
112  TYPE(qs_environment_type), POINTER :: qs_env
113  TYPE(opt_dmfet_pot_type) :: opt_dmfet
114  TYPE(section_vals_type), POINTER :: opt_dmfet_section
115 
116  INTEGER :: diff_size, nao
117  TYPE(cp_blacs_env_type), POINTER :: blacs_env
118  TYPE(cp_fm_struct_type), POINTER :: fm_struct
119  TYPE(cp_fm_type), POINTER :: mo_coeff
120  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
121  TYPE(mp_para_env_type), POINTER :: para_env
122 
123  ! Read the input
124  CALL read_opt_dmfet_section(opt_dmfet, opt_dmfet_section)
125 
126  ! Get the orbital coefficients
127  CALL get_qs_env(qs_env=qs_env, mos=mos, para_env=para_env)
128  CALL get_mo_set(mo_set=mos(1), mo_coeff=mo_coeff, nao=nao)
129 
130  ! Make cp_fm matrices
131  NULLIFY (blacs_env)
132  CALL cp_blacs_env_create(blacs_env=blacs_env, para_env=para_env)
133 
134  NULLIFY (opt_dmfet%dmfet_pot, opt_dmfet%dm_1, opt_dmfet%dm_2, opt_dmfet%dm_total, opt_dmfet%dm_diff)
135  DEALLOCATE (opt_dmfet%dmfet_pot, opt_dmfet%dm_subsys, opt_dmfet%dm_total, opt_dmfet%dm_diff)
136  NULLIFY (fm_struct)
137 
138  CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
139  nrow_global=nao, ncol_global=nao)
140  CALL cp_fm_create(opt_dmfet%dmfet_pot, fm_struct, name="dmfet_pot")
141  CALL cp_fm_create(opt_dmfet%dm_subsys, fm_struct, name="dm_subsys")
142  CALL cp_fm_create(opt_dmfet%dm_total, fm_struct, name="dm_total")
143  CALL cp_fm_create(opt_dmfet%dm_diff, fm_struct, name="dm_diff")
144 
145  CALL cp_fm_set_all(opt_dmfet%dmfet_pot, 0.0_dp)
146  CALL cp_fm_set_all(opt_dmfet%dm_subsys, 0.0_dp)
147  CALL cp_fm_set_all(opt_dmfet%dm_total, 0.0_dp)
148  CALL cp_fm_set_all(opt_dmfet%dm_diff, 0.0_dp)
149 
150  ! Beta spin counterparts
151  IF (opt_dmfet%open_shell_embed) THEN
152  NULLIFY (opt_dmfet%dmfet_pot_beta, opt_dmfet%dm_subsys_beta, &
153  opt_dmfet%dm_total_beta, opt_dmfet%dm_diff_beta)
154  ALLOCATE (opt_dmfet%dmfet_pot_beta, opt_dmfet%dm_subsys_beta, &
155  opt_dmfet%dm_total_beta, opt_dmfet%dm_diff_beta)
156  CALL cp_fm_create(opt_dmfet%dmfet_pot_beta, fm_struct, name="dmfet_pot_beta")
157  CALL cp_fm_create(opt_dmfet%dm_subsys_beta, fm_struct, name="dm_subsys_beta")
158  CALL cp_fm_create(opt_dmfet%dm_total_beta, fm_struct, name="dm_total_beta")
159  CALL cp_fm_create(opt_dmfet%dm_diff_beta, fm_struct, name="dm_diff_beta")
160 
161  CALL cp_fm_set_all(opt_dmfet%dmfet_pot_beta, 0.0_dp)
162  CALL cp_fm_set_all(opt_dmfet%dm_subsys_beta, 0.0_dp)
163  CALL cp_fm_set_all(opt_dmfet%dm_total_beta, 0.0_dp)
164  CALL cp_fm_set_all(opt_dmfet%dm_diff_beta, 0.0_dp)
165  END IF
166 
167  ! Release structure and context
168  CALL cp_fm_struct_release(fm_struct)
169  CALL cp_blacs_env_release(blacs_env)
170 
171  ! Array to store functional values
172  ALLOCATE (opt_dmfet%w_func(opt_dmfet%n_iter))
173  opt_dmfet%w_func = 0.0_dp
174 
175  ! Allocate max_diff and int_diff
176  diff_size = 1
177  IF (opt_dmfet%open_shell_embed) diff_size = 2
178  ALLOCATE (opt_dmfet%max_diff(diff_size))
179  ALLOCATE (opt_dmfet%int_diff(diff_size))
180 
181  END SUBROUTINE prepare_dmfet_opt
182 
183 ! **************************************************************************************************
184 !> \brief ...
185 !> \param opt_dmfet ...
186 ! **************************************************************************************************
187  SUBROUTINE release_dmfet_opt(opt_dmfet)
188  TYPE(opt_dmfet_pot_type) :: opt_dmfet
189 
190  IF (ASSOCIATED(opt_dmfet%dmfet_pot)) THEN
191  CALL cp_fm_release(opt_dmfet%dmfet_pot)
192  DEALLOCATE (opt_dmfet%dmfet_pot)
193  NULLIFY (opt_dmfet%dmfet_pot)
194  END IF
195  IF (ASSOCIATED(opt_dmfet%dm_subsys)) THEN
196  CALL cp_fm_release(opt_dmfet%dm_subsys)
197  DEALLOCATE (opt_dmfet%dm_subsys)
198  NULLIFY (opt_dmfet%dm_subsys)
199  END IF
200  IF (ASSOCIATED(opt_dmfet%dm_total)) THEN
201  CALL cp_fm_release(opt_dmfet%dm_total)
202  DEALLOCATE (opt_dmfet%dm_total)
203  NULLIFY (opt_dmfet%dm_total)
204  END IF
205  IF (ASSOCIATED(opt_dmfet%dm_diff)) THEN
206  CALL cp_fm_release(opt_dmfet%dm_diff)
207  DEALLOCATE (opt_dmfet%dm_diff)
208  NULLIFY (opt_dmfet%dm_diff)
209  END IF
210 
211  IF (opt_dmfet%open_shell_embed) THEN
212  IF (ASSOCIATED(opt_dmfet%dmfet_pot_beta)) THEN
213  CALL cp_fm_release(opt_dmfet%dmfet_pot_beta)
214  DEALLOCATE (opt_dmfet%dmfet_pot_beta)
215  NULLIFY (opt_dmfet%dmfet_pot_beta)
216  END IF
217  IF (ASSOCIATED(opt_dmfet%dm_subsys_beta)) THEN
218  CALL cp_fm_release(opt_dmfet%dm_subsys_beta)
219  DEALLOCATE (opt_dmfet%dm_subsys_beta)
220  NULLIFY (opt_dmfet%dm_subsys_beta)
221  END IF
222  IF (ASSOCIATED(opt_dmfet%dm_total_beta)) THEN
223  CALL cp_fm_release(opt_dmfet%dm_total_beta)
224  DEALLOCATE (opt_dmfet%dm_total_beta)
225  NULLIFY (opt_dmfet%dm_total_beta)
226  END IF
227  IF (ASSOCIATED(opt_dmfet%dm_diff_beta)) THEN
228  CALL cp_fm_release(opt_dmfet%dm_diff_beta)
229  DEALLOCATE (opt_dmfet%dm_diff_beta)
230  NULLIFY (opt_dmfet%dm_diff_beta)
231  END IF
232  END IF
233 
234  DEALLOCATE (opt_dmfet%w_func)
235  DEALLOCATE (opt_dmfet%max_diff)
236  DEALLOCATE (opt_dmfet%int_diff)
237  DEALLOCATE (opt_dmfet%all_nspins)
238 
239  END SUBROUTINE release_dmfet_opt
240 
241 ! **************************************************************************************************
242 !> \brief Builds density matrices from MO coefficients in full matrix format
243 !> \param qs_env ...
244 !> \param dm ...
245 !> \param open_shell Subsystem is open shell
246 !> \param open_shell_embed Embedding is open shell
247 !> \param dm_beta ...
248 ! **************************************************************************************************
249  SUBROUTINE build_full_dm(qs_env, dm, open_shell, open_shell_embed, dm_beta)
250  TYPE(qs_environment_type), POINTER :: qs_env
251  TYPE(cp_fm_type), INTENT(IN) :: dm
252  LOGICAL :: open_shell, open_shell_embed
253  TYPE(cp_fm_type), INTENT(IN) :: dm_beta
254 
255  CHARACTER(LEN=*), PARAMETER :: routinen = 'build_full_dm'
256 
257  INTEGER :: handle, homo, nao
258  REAL(kind=dp) :: coeff
259  TYPE(cp_fm_type), POINTER :: mo_coeff
260  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
261  TYPE(mp_para_env_type), POINTER :: para_env
262 
263  CALL timeset(routinen, handle)
264 
265  coeff = 2.0_dp
266  IF (open_shell_embed) coeff = 1.0_dp
267 
268  ! Get the orbital coefficients
269  CALL get_qs_env(qs_env=qs_env, mos=mos)
270  CALL get_mo_set(mo_set=mos(1), mo_coeff=mo_coeff, nao=nao, homo=homo)
271 
272  ! Build the density matrix
273  CALL parallel_gemm(transa="N", transb="T", m=nao, n=nao, &
274  k=homo, alpha=coeff, &
275  matrix_a=mo_coeff, matrix_b=mo_coeff, &
276  beta=0.0_dp, matrix_c=dm)
277 
278  ! Open shell
279  IF (open_shell) THEN
280  CALL get_mo_set(mo_set=mos(2), mo_coeff=mo_coeff, nao=nao, homo=homo)
281 
282  ! Build the density matrix
283  CALL parallel_gemm(transa="N", transb="T", m=nao, n=nao, &
284  k=homo, alpha=coeff, &
285  matrix_a=mo_coeff, matrix_b=mo_coeff, &
286  beta=0.0_dp, matrix_c=dm_beta)
287  END IF
288 
289  ! If embedding is open shell, but subsystem is not, copy alpha-spin DM into beta-spin DM
290  IF (open_shell_embed .AND. (.NOT. open_shell)) THEN
291  CALL get_qs_env(qs_env=qs_env, para_env=para_env)
292  CALL cp_fm_copy_general(dm, dm_beta, para_env)
293 
294  END IF
295 
296  CALL timestop(handle)
297 
298  END SUBROUTINE build_full_dm
299 
300 ! **************************************************************************************************
301 !> \brief ...
302 !> \param opt_dmfet ...
303 !> \param qs_env ...
304 ! **************************************************************************************************
305  SUBROUTINE check_dmfet(opt_dmfet, qs_env)
306  TYPE(opt_dmfet_pot_type) :: opt_dmfet
307  TYPE(qs_environment_type), POINTER :: qs_env
308 
309  REAL(kind=dp) :: max_diff, max_diff_beta, trace
310  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
311  TYPE(dbcsr_type), POINTER :: diff_dbcsr, dm_s
312 
313  CALL get_qs_env(qs_env, matrix_s=matrix_s)
314 
315  NULLIFY (diff_dbcsr)
316  CALL dbcsr_init_p(diff_dbcsr)
317  CALL dbcsr_create(matrix=diff_dbcsr, &
318  template=matrix_s(1)%matrix, &
319  matrix_type=dbcsr_type_no_symmetry)
320 
321  NULLIFY (dm_s)
322  CALL dbcsr_init_p(dm_s)
323  CALL dbcsr_create(matrix=dm_s, &
324  template=matrix_s(1)%matrix, &
325  matrix_type=dbcsr_type_no_symmetry)
326 
327  CALL copy_fm_to_dbcsr(opt_dmfet%dm_diff, diff_dbcsr, keep_sparsity=.false.)
328 
329  CALL dbcsr_multiply("N", "N", 1.0_dp, diff_dbcsr, matrix_s(1)%matrix, &
330  0.0_dp, dm_s)
331 
332  CALL dbcsr_trace(dm_s, trace)
333 
334  IF (opt_dmfet%open_shell_embed) THEN
335  CALL copy_fm_to_dbcsr(opt_dmfet%dm_diff_beta, diff_dbcsr, keep_sparsity=.false.)
336 
337  CALL dbcsr_multiply("N", "N", 1.0_dp, diff_dbcsr, matrix_s(1)%matrix, &
338  0.0_dp, dm_s)
339 
340  CALL dbcsr_trace(dm_s, trace)
341 
342  END IF
343 
344  ! Release dbcsr objects
345  CALL dbcsr_release(diff_dbcsr)
346  CALL dbcsr_release(dm_s)
347 
348  ! Find the absolute maximum value of the DM difference
349  CALL cp_fm_maxabsval(opt_dmfet%dm_diff, max_diff)
350  IF (opt_dmfet%open_shell_embed) THEN
351  CALL cp_fm_maxabsval(opt_dmfet%dm_diff_beta, max_diff_beta)
352  END IF
353 
354  END SUBROUTINE check_dmfet
355 
356 END MODULE optimize_dmfet_potential
methods related to the blacs parallel environment
Definition: cp_blacs_env.F:15
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
Definition: cp_blacs_env.F:282
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Definition: cp_blacs_env.F:123
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
DBCSR operations in CP2K.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
represent the structure of a full matrix
Definition: cp_fm_struct.F:14
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
Definition: cp_fm_struct.F:125
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
Definition: cp_fm_struct.F:320
represent a full matrix distributed on many processors
Definition: cp_fm_types.F:15
subroutine, public cp_fm_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
Definition: cp_fm_types.F:1538
subroutine, public cp_fm_maxabsval(matrix, a_max, ir_max, ic_max)
find the maximum absolute value of the matrix element maxval(abs(matrix))
Definition: cp_fm_types.F:1064
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
Definition: cp_fm_types.F:535
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Definition: cp_fm_types.F:167
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
Interface to the message passing library MPI.
subroutine, public check_dmfet(opt_dmfet, qs_env)
...
subroutine, public release_dmfet_opt(opt_dmfet)
...
subroutine, public build_full_dm(qs_env, dm, open_shell, open_shell_embed, dm_beta)
Builds density matrices from MO coefficients in full matrix format.
subroutine, public prepare_dmfet_opt(qs_env, opt_dmfet, opt_dmfet_section)
...
logical function, public subsys_spin(qs_env)
...
basic linear algebra operations for full matrixes
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_RI_aux_kp, matrix_s, matrix_s_RI_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, WannierCentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
Definition and initialisation of the mo data type.
Definition: qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kTS, mu, flexible_electron_count)
Get the components of a MO set data structure.
Definition: qs_mo_types.F:397