30 USE mathlib,
ONLY: invert_matrix
36 #include "./base/base_uses.f90"
42 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_cdft_scf_utils'
64 coeff, step_multiplier, dh)
65 TYPE(qs_environment_type),
POINTER :: qs_env
66 INTEGER :: output_unit, nwork, pwork
67 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coeff, step_multiplier, dh
69 CHARACTER(len=15) :: fmt_code
71 TYPE(dft_control_type),
POINTER :: dft_control
72 TYPE(qs_scf_env_type),
POINTER :: scf_env
73 TYPE(scf_control_type),
POINTER :: scf_control
75 NULLIFY (scf_env, scf_control, dft_control)
77 cpassert(
ASSOCIATED(qs_env))
79 scf_control=scf_control, &
80 dft_control=dft_control)
82 IF (
SIZE(scf_control%outer_scf%cdft_opt_control%jacobian_step) /= 1 .AND. &
83 SIZE(scf_control%outer_scf%cdft_opt_control%jacobian_step) /=
SIZE(scf_env%outer_scf%variables, 1)) &
84 CALL cp_abort(__location__, &
85 cp_to_string(
SIZE(scf_control%outer_scf%cdft_opt_control%jacobian_step))// &
86 " values passed to keyword JACOBIAN_STEP, expected 1 or "// &
87 cp_to_string(
SIZE(scf_env%outer_scf%variables, 1)))
89 ALLOCATE (dh(
SIZE(scf_env%outer_scf%variables, 1)))
90 IF (
SIZE(dh) /=
SIZE(scf_control%outer_scf%cdft_opt_control%jacobian_step))
THEN
92 dh(ivar) = scf_control%outer_scf%cdft_opt_control%jacobian_step(1)
95 dh(:) = scf_control%outer_scf%cdft_opt_control%jacobian_step
98 SELECT CASE (scf_control%outer_scf%cdft_opt_control%jacobian_type)
100 CALL cp_abort(__location__, &
101 "Unknown Jacobian type: "// &
102 cp_to_string(scf_control%outer_scf%cdft_opt_control%jacobian_type))
107 ALLOCATE (coeff(nwork:pwork), step_multiplier(nwork:pwork))
108 coeff(nwork) = -1.0_dp
109 coeff(pwork) = 1.0_dp
110 step_multiplier = 1.0_dp
115 ALLOCATE (coeff(nwork:pwork), step_multiplier(nwork:pwork))
116 coeff(nwork) = -1.0_dp
117 coeff(pwork) = 1.0_dp
118 step_multiplier = -1.0_dp
123 ALLOCATE (coeff(nwork:pwork), step_multiplier(nwork:pwork))
127 step_multiplier(0) = 0.0_dp
128 step_multiplier(1) = 1.0_dp
129 step_multiplier(2) = 2.0_dp
135 ALLOCATE (coeff(nwork:pwork), step_multiplier(nwork:pwork))
139 step_multiplier(0) = 0.0_dp
140 step_multiplier(-1) = -1.0_dp
141 step_multiplier(-2) = -2.0_dp
147 ALLOCATE (coeff(nwork:pwork), step_multiplier(nwork:pwork))
149 coeff(nwork) = -1.0_dp
150 coeff(pwork) = 1.0_dp
151 step_multiplier(0) = 0.0_dp
152 step_multiplier(nwork) = -1.0_dp
153 step_multiplier(pwork) = 1.0_dp
157 IF (output_unit > 0)
THEN
158 WRITE (output_unit, fmt=
"(/,A)") &
159 " ================================== JACOBIAN CALCULATION ================================="
160 WRITE (output_unit, fmt=
"(A)") &
161 " Evaluating inverse Jacobian using finite differences"
162 WRITE (output_unit,
'(A,I10,A,I10)') &
163 " Energy evaluation: ", dft_control%qs_control%cdft_control%ienergy, &
164 ", CDFT SCF iteration: ", scf_env%outer_scf%iter_count
165 SELECT CASE (scf_control%outer_scf%cdft_opt_control%jacobian_type)
167 WRITE (output_unit,
'(A)')
" Type : First order forward difference"
169 WRITE (output_unit,
'(A)')
" Type : First order backward difference"
171 WRITE (output_unit,
'(A)')
" Type : Second order forward difference"
173 WRITE (output_unit,
'(A)')
" Type : Second order backward difference"
175 WRITE (output_unit,
'(A)')
" Type : First order central difference"
177 CALL cp_abort(__location__,
"Unknown Jacobian type: "// &
178 cp_to_string(scf_control%outer_scf%cdft_opt_control%jacobian_type))
180 IF (
SIZE(scf_control%outer_scf%cdft_opt_control%jacobian_step) == 1)
THEN
181 WRITE (output_unit,
'(A,ES12.4)')
" Step size : ", scf_control%outer_scf%cdft_opt_control%jacobian_step
183 WRITE (output_unit,
'(A,ES12.4,A)') &
184 " Step sizes : ", scf_control%outer_scf%cdft_opt_control%jacobian_step(1),
' (constraint 1)'
185 IF (
SIZE(scf_control%outer_scf%cdft_opt_control%jacobian_step) < 10)
THEN
186 fmt_code =
'(ES34.4,A,I2,A)'
188 fmt_code =
'(ES34.4,A,I3,A)'
190 DO ivar = 2,
SIZE(scf_control%outer_scf%cdft_opt_control%jacobian_step)
191 WRITE (output_unit, fmt_code) scf_control%outer_scf%cdft_opt_control%jacobian_step(ivar),
" (constraint", ivar,
")"
205 TYPE(qs_environment_type),
POINTER :: qs_env
206 LOGICAL :: used_history
208 INTEGER :: i, ihistory, nvar, outer_scf_ihistory
209 LOGICAL :: use_md_history
210 REAL(kind=
dp) :: inv_error
211 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: jacobian
212 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gradient_history, inv_jacobian, &
214 TYPE(qs_scf_env_type),
POINTER :: scf_env
215 TYPE(scf_control_type),
POINTER :: scf_control
217 NULLIFY (scf_control, scf_env)
220 scf_control=scf_control, &
221 outer_scf_ihistory=outer_scf_ihistory)
222 ihistory = scf_env%outer_scf%iter_count
224 IF (outer_scf_ihistory .GE. 3 .AND. .NOT. used_history)
THEN
226 CALL get_qs_env(qs_env, gradient_history=gradient_history, &
227 variable_history=variable_history)
228 nvar =
SIZE(scf_env%outer_scf%variables, 1)
229 use_md_history = .true.
232 IF (abs(variable_history(i, 2) - variable_history(i, 1)) .LT. 1.0e-12_dp) &
233 use_md_history = .false.
235 IF (use_md_history)
THEN
236 ALLOCATE (jacobian(nvar, nvar))
238 jacobian(i, i) = (gradient_history(i, 2) - gradient_history(i, 1))/ &
239 (variable_history(i, 2) - variable_history(i, 1))
241 IF (.NOT.
ASSOCIATED(scf_env%outer_scf%inv_jacobian)) &
242 ALLOCATE (scf_env%outer_scf%inv_jacobian(nvar, nvar))
243 inv_jacobian => scf_env%outer_scf%inv_jacobian
244 CALL invert_matrix(jacobian, inv_jacobian, inv_error)
245 DEALLOCATE (jacobian)
248 scf_control%outer_scf%cdft_opt_control%broyden_update = .false.
250 used_history = .true.
253 IF (ihistory .GE. 2 .AND. .NOT.
ASSOCIATED(scf_env%outer_scf%inv_jacobian))
THEN
255 nvar =
SIZE(scf_env%outer_scf%variables, 1)
256 IF (
SIZE(scf_env%outer_scf%gradient, 2) .LT. 3) &
257 CALL cp_abort(__location__, &
258 "Keyword EXTRAPOLATION_ORDER in section OUTER_SCF must be greater than or equal "// &
259 "to 3 for optimizers that build the Jacobian from SCF history.")
260 ALLOCATE (jacobian(nvar, nvar))
262 jacobian(i, i) = (scf_env%outer_scf%gradient(i, ihistory) - scf_env%outer_scf%gradient(i, ihistory - 1))/ &
263 (scf_env%outer_scf%variables(i, ihistory) - scf_env%outer_scf%variables(i, ihistory - 1))
265 IF (.NOT.
ASSOCIATED(scf_env%outer_scf%inv_jacobian)) &
266 ALLOCATE (scf_env%outer_scf%inv_jacobian(nvar, nvar))
267 inv_jacobian => scf_env%outer_scf%inv_jacobian
268 CALL invert_matrix(jacobian, inv_jacobian, inv_error)
269 DEALLOCATE (jacobian)
270 scf_control%outer_scf%cdft_opt_control%broyden_update = .false.
284 TYPE(qs_environment_type),
POINTER :: qs_env
286 INTEGER :: i, iwork, j, nvar
287 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: inv_jacobian
288 TYPE(qs_scf_env_type),
POINTER :: scf_env
289 TYPE(scf_control_type),
POINTER :: scf_control
291 NULLIFY (scf_env, scf_control)
292 cpassert(
ASSOCIATED(qs_env))
293 CALL get_qs_env(qs_env, scf_env=scf_env, scf_control=scf_control)
295 cpassert(
ASSOCIATED(scf_control%outer_scf%cdft_opt_control%jacobian_vector))
296 nvar =
SIZE(scf_env%outer_scf%variables, 1)
297 IF (
SIZE(scf_control%outer_scf%cdft_opt_control%jacobian_vector) /= nvar**2) &
298 CALL cp_abort(__location__, &
299 "Too many or too few values defined for restarting inverse Jacobian.")
300 IF (.NOT.
ASSOCIATED(scf_env%outer_scf%inv_jacobian)) &
301 ALLOCATE (scf_env%outer_scf%inv_jacobian(nvar, nvar))
302 inv_jacobian => scf_env%outer_scf%inv_jacobian
306 inv_jacobian(i, j) = scf_control%outer_scf%cdft_opt_control%jacobian_vector(iwork)
310 DEALLOCATE (scf_control%outer_scf%cdft_opt_control%jacobian_vector)
311 scf_control%outer_scf%cdft_opt_control%jacobian_restart = .false.
312 scf_control%outer_scf%cdft_opt_control%broyden_update = .false.
313 scf_env%outer_scf%deallocate_jacobian = .false.
326 TYPE(cp_logger_type),
POINTER :: logger
327 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
328 POINTER :: inv_jacobian
329 INTEGER :: iter_count
331 CHARACTER(len=default_path_length) :: project_name
332 INTEGER :: i, j, lp, nvar, output_unit
334 nvar =
SIZE(inv_jacobian, 1)
336 project_name = logger%iter_info%project_name
337 lp = len_trim(project_name)
338 project_name(lp + 1:len(project_name)) =
".inverseJacobian"
339 CALL open_file(file_name=project_name, file_status=
"UNKNOWN", &
340 file_action=
"WRITE", file_position=
"APPEND", &
341 unit_number=output_unit)
342 WRITE (output_unit, fmt=
"(/,A)")
"Inverse Jacobian matrix in row major order"
343 WRITE (output_unit, fmt=
"(A,I10)")
"Iteration: ", iter_count
346 WRITE (output_unit, *) inv_jacobian(i, j)
364 TYPE(mp_para_env_type),
POINTER :: para_env
365 CHARACTER(len=*) :: project_name, suffix
366 INTEGER,
INTENT(OUT) :: output_unit
367 TYPE(cp_logger_type),
INTENT(OUT),
POINTER :: tmp_logger
371 IF (para_env%is_source())
THEN
372 lp = len_trim(project_name)
373 project_name(lp + 1:len(project_name)) = suffix
374 CALL open_file(file_name=project_name, file_status=
"UNKNOWN", &
375 file_action=
"WRITE", file_position=
"APPEND", &
376 unit_number=output_unit)
382 default_global_unit_nr=output_unit, &
383 close_global_unit_on_dealloc=.false.)
398 should_build, used_history)
399 TYPE(scf_control_type),
POINTER :: scf_control
400 TYPE(qs_scf_env_type),
POINTER :: scf_env
401 LOGICAL :: explicit_jacobian, should_build, &
404 cpassert(
ASSOCIATED(scf_control))
405 cpassert(
ASSOCIATED(scf_env))
407 SELECT CASE (scf_control%outer_scf%optimizer)
409 cpabort(
"Noncompatible optimizer requested.")
411 cpassert(
ASSOCIATED(scf_control%outer_scf%cdft_opt_control))
412 scf_control%outer_scf%cdft_opt_control%build_jacobian = .true.
413 explicit_jacobian = .true.
415 cpassert(
ASSOCIATED(scf_control%outer_scf%cdft_opt_control))
416 SELECT CASE (scf_control%outer_scf%cdft_opt_control%broyden_type)
418 scf_control%outer_scf%cdft_opt_control%build_jacobian = .true.
419 explicit_jacobian = .false.
421 scf_control%outer_scf%cdft_opt_control%build_jacobian = .true.
422 explicit_jacobian = .true.
425 IF (scf_control%outer_scf%cdft_opt_control%build_jacobian)
THEN
427 IF (scf_env%outer_scf%iter_count == 1) scf_control%outer_scf%cdft_opt_control%ijacobian(1) = 0
429 IF (
ASSOCIATED(scf_env%outer_scf%inv_jacobian))
THEN
431 IF (scf_control%outer_scf%cdft_opt_control%ijacobian(2) .GE. &
432 scf_control%outer_scf%cdft_opt_control%jacobian_freq(2) .AND. .NOT. used_history .AND. &
433 scf_control%outer_scf%cdft_opt_control%jacobian_freq(2) > 0)
THEN
434 should_build = .true.
436 scf_control%outer_scf%cdft_opt_control%ijacobian(:) = 0
438 ELSE IF (scf_control%outer_scf%cdft_opt_control%ijacobian(1) .GE. &
439 scf_control%outer_scf%cdft_opt_control%jacobian_freq(1) .AND. &
440 scf_control%outer_scf%cdft_opt_control%jacobian_freq(1) > 0)
THEN
441 should_build = .true.
443 scf_control%outer_scf%cdft_opt_control%ijacobian(1) = 0
445 IF (should_build)
DEALLOCATE (scf_env%outer_scf%inv_jacobian)
447 should_build = .true.
449 scf_control%outer_scf%cdft_opt_control%ijacobian(:) = 0
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
integer function, public get_unit_number(file_name)
Returns the first logical unit that is not preconnected.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
various routines to log and control the output. The idea is that decisions about where to log should ...
subroutine, public cp_logger_create(logger, para_env, print_level, default_global_unit_nr, default_local_unit_nr, global_filename, local_filename, close_global_unit_on_dealloc, iter_info, close_local_unit_on_dealloc, suffix, template_logger)
initializes a logger
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_path_length
Collection of simple mathematical functions and subroutines.
Interface to the message passing library MPI.
Auxiliary routines for performing a constrained DFT SCF run with Quickstep.
subroutine, public prepare_jacobian_stencil(qs_env, output_unit, nwork, pwork, coeff, step_multiplier, dh)
Prepares the finite difference stencil for computing the Jacobian. The constraints are re-evaluated b...
subroutine, public build_diagonal_jacobian(qs_env, used_history)
Builds a strictly diagonal inverse Jacobian from MD/SCF history.
subroutine, public print_inverse_jacobian(logger, inv_jacobian, iter_count)
Prints the finite difference inverse Jacobian to file.
subroutine, public create_tmp_logger(para_env, project_name, suffix, output_unit, tmp_logger)
Creates a temporary logger for redirecting output to a new file.
subroutine, public restart_inverse_jacobian(qs_env)
Restarts the finite difference inverse Jacobian.
subroutine, public initialize_inverse_jacobian(scf_control, scf_env, explicit_jacobian, should_build, used_history)
Checks if the inverse Jacobian should be calculated and initializes the calculation.
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.
module that contains the definitions of the scf types
parameters that control an scf iteration