69 pw_integrate_function,&
87 realspace_grid_input_type,&
96 #include "./base/base_uses.f90"
102 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_sccs'
121 SUBROUTINE sccs(qs_env, rho_tot_gspace, v_hartree_gspace, v_sccs, h_stress)
123 TYPE(qs_environment_type),
POINTER :: qs_env
124 TYPE(pw_c1d_gs_type),
INTENT(INOUT) :: rho_tot_gspace, v_hartree_gspace
125 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: v_sccs
126 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT), &
129 CHARACTER(LEN=*),
PARAMETER :: routinen =
'sccs'
130 REAL(kind=
dp),
PARAMETER :: epstol = 1.0e-8_dp
132 CHARACTER(LEN=4*default_string_length) :: message
133 CHARACTER(LEN=default_path_length) :: mpi_filename
134 CHARACTER(LEN=default_string_length) :: cube_path, filename, my_pos_cube, &
136 INTEGER :: cube_unit, handle, i, ispin, iter, j, k, &
137 nspin, output_unit, print_level
138 INTEGER(KIND=int_8) :: ngpts
139 INTEGER,
DIMENSION(3) :: lb, ub
140 LOGICAL :: append_cube, calculate_stress_tensor, &
141 mpi_io, should_output
142 REAL(kind=
dp) :: cavity_surface, cavity_volume, cell_volume, dphi2, dvol, e_tot, &
143 epsilon_solvent, f, polarisation_charge, rho_delta, rho_delta_avg, rho_delta_max, &
144 rho_iter_new, tot_rho_elec, tot_rho_solute
145 REAL(kind=
dp),
DIMENSION(3) :: abc
146 TYPE(cp_logger_type),
POINTER :: logger
147 TYPE(cp_subsys_type),
POINTER :: cp_subsys
148 TYPE(dft_control_type),
POINTER :: dft_control
149 TYPE(mp_para_env_type),
POINTER :: para_env
150 TYPE(particle_list_type),
POINTER :: particles
151 TYPE(pw_env_type),
POINTER :: pw_env
152 TYPE(pw_poisson_type),
POINTER :: poisson_env
153 TYPE(pw_pool_p_type),
DIMENSION(:),
POINTER :: pw_pools
154 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool
155 TYPE(pw_r3d_rs_type) :: deps_elec, eps_elec
156 TYPE(pw_r3d_rs_type),
DIMENSION(3) :: dln_eps_elec, dphi_tot
157 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: rho_pw_r
158 TYPE(pw_r3d_rs_type),
POINTER :: rho_pw_r_sccs
159 TYPE(qs_energy_type),
POINTER :: energy
160 TYPE(qs_rho_type),
POINTER :: rho
161 TYPE(qs_scf_env_type),
POINTER :: scf_env
162 TYPE(sccs_control_type),
POINTER :: sccs_control
163 TYPE(section_vals_type),
POINTER :: input
165 CALL timeset(routinen, handle)
167 NULLIFY (auxbas_pw_pool)
169 NULLIFY (dft_control)
175 NULLIFY (poisson_env)
179 NULLIFY (sccs_control)
184 cp_subsys=cp_subsys, &
185 dft_control=dft_control, &
194 sccs_control => dft_control%sccs_control
196 cpassert(
ASSOCIATED(qs_env))
198 IF (
PRESENT(h_stress))
THEN
199 calculate_stress_tensor = .true.
200 h_stress(:, :) = 0.0_dp
201 cpwarn(
"The stress tensor for SCCS has not yet been fully validated")
203 calculate_stress_tensor = .false.
208 auxbas_pw_pool=auxbas_pw_pool, &
210 poisson_env=poisson_env)
215 IF (.NOT. sccs_control%sccs_activated)
THEN
216 IF (sccs_control%eps_scf > 0.0_dp)
THEN
217 IF ((scf_env%iter_delta > sccs_control%eps_scf) .OR. &
218 ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
219 (qs_env%scf_env%iter_count <= 1)))
THEN
220 IF (calculate_stress_tensor)
THEN
222 CALL pw_poisson_solve(poisson_env=poisson_env, &
223 density=rho_tot_gspace, &
224 ehartree=energy%hartree, &
225 vhartree=v_hartree_gspace, &
228 CALL pw_poisson_solve(poisson_env=poisson_env, &
229 density=rho_tot_gspace, &
230 ehartree=energy%hartree, &
231 vhartree=v_hartree_gspace)
233 energy%sccs_pol = 0.0_dp
234 energy%sccs_cav = 0.0_dp
235 energy%sccs_dis = 0.0_dp
236 energy%sccs_rep = 0.0_dp
237 energy%sccs_sol = 0.0_dp
238 energy%sccs_hartree = energy%hartree
239 CALL timestop(handle)
243 sccs_control%sccs_activated = .true.
246 nspin = dft_control%nspins
250 print_level = logger%iter_info%print_level
251 print_path =
"DFT%PRINT%SCCS"
256 ignore_should_output=should_output, &
257 log_filename=.false.)
262 rho_r_sccs=rho_pw_r_sccs)
265 cpassert(
ASSOCIATED(rho_pw_r_sccs))
269 TYPE(pw_r3d_rs_type) :: rho_elec
270 CALL auxbas_pw_pool%create_pw(rho_elec)
273 ngpts = rho_elec%pw_grid%ngpts
274 dvol = rho_elec%pw_grid%dvol
275 cell_volume = rho_elec%pw_grid%vol
276 abc(1:3) = real(rho_elec%pw_grid%npts(1:3), kind=
dp)*rho_elec%pw_grid%dr(1:3)
277 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
278 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
280 CALL pw_copy(rho_pw_r(1), rho_elec)
282 CALL pw_axpy(rho_pw_r(ispin), rho_elec)
284 tot_rho_elec = pw_integrate_function(rho_elec)
287 CALL auxbas_pw_pool%create_pw(eps_elec)
288 CALL auxbas_pw_pool%create_pw(deps_elec)
290 epsilon_solvent = sccs_control%epsilon_solvent
291 SELECT CASE (sccs_control%method_id)
293 CALL andreussi(rho_elec, eps_elec, deps_elec, epsilon_solvent, sccs_control%rho_max, &
294 sccs_control%rho_min)
296 CALL fattebert_gygi(rho_elec, eps_elec, deps_elec, epsilon_solvent, sccs_control%beta, &
297 sccs_control%rho_zero)
299 cpabort(
"Invalid method specified for SCCS model")
303 filename =
"DIELECTRIC_FUNCTION"
304 cube_path = trim(print_path)//
"%"//trim(filename)
308 my_pos_cube =
"REWIND"
309 IF (append_cube) my_pos_cube =
"APPEND"
312 extension=
".cube", middle_name=trim(filename), &
313 file_position=my_pos_cube, log_filename=.false., &
314 mpi_io=mpi_io, fout=mpi_filename)
315 IF (output_unit > 0)
THEN
316 IF (.NOT. mpi_io)
THEN
317 INQUIRE (unit=cube_unit, name=filename)
319 filename = mpi_filename
321 WRITE (unit=output_unit, fmt=
"(T3,A)") &
322 "SCCS| The dielectric function is written in cube file format to the file:", &
323 "SCCS| "//trim(filename)
325 CALL cp_pw_to_cube(eps_elec, cube_unit, trim(filename), particles=particles, &
332 cavity_surface = 0.0_dp
333 cavity_volume = 0.0_dp
335 IF (abs(epsilon_solvent - 1.0_dp) > epstol)
THEN
338 TYPE(pw_r3d_rs_type) :: theta, norm_drho_elec
339 TYPE(pw_r3d_rs_type),
DIMENSION(3) :: drho_elec
340 CALL auxbas_pw_pool%create_pw(theta)
344 f = 1.0_dp/(epsilon_solvent - 1.0_dp)
351 theta%array(i, j, k) = f*(epsilon_solvent - eps_elec%array(i, j, k))
356 cavity_volume = pw_integrate_function(theta)
361 CALL auxbas_pw_pool%create_pw(drho_elec(i))
365 CALL auxbas_pw_pool%create_pw(norm_drho_elec)
374 norm_drho_elec%array(i, j, k) = sqrt(drho_elec(1)%array(i, j, k)* &
375 drho_elec(1)%array(i, j, k) + &
376 drho_elec(2)%array(i, j, k)* &
377 drho_elec(2)%array(i, j, k) + &
378 drho_elec(3)%array(i, j, k)* &
379 drho_elec(3)%array(i, j, k))
386 filename =
"DENSITY_GRADIENT"
387 cube_path = trim(print_path)//
"%"//trim(filename)
391 my_pos_cube =
"REWIND"
392 IF (append_cube) my_pos_cube =
"APPEND"
395 extension=
".cube", middle_name=trim(filename), &
396 file_position=my_pos_cube, log_filename=.false., &
397 mpi_io=mpi_io, fout=mpi_filename)
398 IF (output_unit > 0)
THEN
399 IF (.NOT. mpi_io)
THEN
400 INQUIRE (unit=cube_unit, name=filename)
402 filename = mpi_filename
404 WRITE (unit=output_unit, fmt=
"(T3,A)") &
405 "SCCS| The norm of the density gradient is written in cube file format to the file:", &
406 "SCCS| "//trim(filename)
408 CALL cp_pw_to_cube(norm_drho_elec, cube_unit, trim(filename), particles=particles, &
415 SELECT CASE (sccs_control%method_id)
417 CALL surface_andreussi(rho_elec, norm_drho_elec, theta, epsilon_solvent, &
418 sccs_control%rho_max, sccs_control%rho_min, &
419 sccs_control%delta_rho)
421 CALL surface_fattebert_gygi(rho_elec, norm_drho_elec, theta, epsilon_solvent, &
422 sccs_control%beta, sccs_control%rho_zero, &
423 sccs_control%delta_rho)
425 cpabort(
"Invalid method specified for SCCS model")
427 cavity_surface = pw_integrate_function(theta)
430 CALL auxbas_pw_pool%give_back_pw(theta)
431 CALL auxbas_pw_pool%give_back_pw(norm_drho_elec)
433 CALL auxbas_pw_pool%give_back_pw(drho_elec(i))
439 CALL auxbas_pw_pool%give_back_pw(rho_elec)
443 TYPE(pw_r3d_rs_type) :: rho_tot, phi_tot, rho_solute, rho_tot_zero
445 CALL auxbas_pw_pool%create_pw(rho_solute)
446 CALL pw_zero(rho_solute)
447 CALL pw_transfer(rho_tot_gspace, rho_solute)
448 tot_rho_solute = pw_integrate_function(rho_solute)
451 IF (abs(tot_rho_solute) >= 1.0e-6_dp)
THEN
452 IF ((poisson_env%parameters%solver /= pw_poisson_analytic) .AND. &
453 (poisson_env%parameters%solver /= pw_poisson_mt))
THEN
454 WRITE (unit=message, fmt=
"(A,SP,F0.6,A)") &
455 "The system (solute) has a non-negligible charge of ", -tot_rho_solute, &
456 ". It is recommended to use non-periodic boundary conditions (PERIODIC none) "// &
457 "combined with an appropriate Poisson solver (POISSON_SOLVER MT or analytic)"
463 CALL auxbas_pw_pool%create_pw(rho_tot_zero)
474 IF (eps_elec%array(i, j, k) < 1.0_dp)
THEN
475 WRITE (unit=message, fmt=
"(A,ES12.3,A,3(I0,A))") &
476 "SCCS| Invalid dielectric function value ", eps_elec%array(i, j, k), &
477 " encountered at grid point (", i,
",", j,
",", k,
")"
480 rho_tot_zero%array(i, j, k) = rho_solute%array(i, j, k)/eps_elec%array(i, j, k)
481 eps_elec%array(i, j, k) = log(eps_elec%array(i, j, k))
489 CALL auxbas_pw_pool%create_pw(dln_eps_elec(i))
490 CALL pw_zero(dln_eps_elec(i))
492 CALL derive(eps_elec, dln_eps_elec, sccs_control%derivative_method, pw_env, input)
493 CALL auxbas_pw_pool%give_back_pw(eps_elec)
496 IF (should_output .AND. (output_unit > 0))
THEN
497 IF (print_level > low_print_level)
THEN
498 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.12)") &
499 "SCCS| Total electronic charge density ", -tot_rho_elec, &
500 "SCCS| Total charge density (solute) ", -tot_rho_solute
501 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.3)") &
502 "SCCS| Volume of the cell [bohr^3]", cell_volume, &
503 "SCCS| [angstrom^3]", &
504 cp_unit_from_cp2k(cell_volume,
"angstrom^3")
505 IF (abs(epsilon_solvent - 1.0_dp) > epstol)
THEN
506 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.3)") &
507 "SCCS| Volume of the solute cavity [bohr^3]", cavity_volume, &
508 "SCCS| [angstrom^3]", &
509 cp_unit_from_cp2k(cavity_volume,
"angstrom^3"), &
510 "SCCS| Surface of the solute cavity [bohr^2]", cavity_surface, &
511 "SCCS| [angstrom^2]", &
512 cp_unit_from_cp2k(cavity_surface,
"angstrom^2")
514 WRITE (unit=output_unit, fmt=
"(T3,A)") &
516 "SCCS| Step Average residual Maximum residual E(Hartree) [a.u.]"
522 CALL auxbas_pw_pool%create_pw(dphi_tot(i))
526 CALL auxbas_pw_pool%create_pw(rho_tot)
527 CALL pw_copy(rho_tot_zero, rho_tot)
528 CALL pw_axpy(rho_pw_r_sccs, rho_tot)
530 CALL auxbas_pw_pool%create_pw(phi_tot)
531 CALL pw_zero(phi_tot)
542 IF (iter > sccs_control%max_iter)
THEN
543 IF (output_unit > 0)
THEN
544 WRITE (unit=output_unit, fmt=
"(T3,A,/,T3,A,I0,A)") &
545 "SCCS| Maximum number of SCCS iterations reached", &
546 "SCCS| Iteration cycle did not converge in ", sccs_control%max_iter,
" steps"
548 WRITE (unit=message, fmt=
"(A,I0,A)") &
549 "The SCCS iteration cycle did not converge in ", sccs_control%max_iter,
" steps"
556 CALL pw_poisson_solve(poisson_env=poisson_env, &
560 energy%sccs_hartree = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
565 rho_delta_avg = 0.0_dp
566 rho_delta_max = 0.0_dp
576 rho_iter_new = (dln_eps_elec(1)%array(i, j, k)*dphi_tot(1)%array(i, j, k) + &
577 dln_eps_elec(2)%array(i, j, k)*dphi_tot(2)%array(i, j, k) + &
578 dln_eps_elec(3)%array(i, j, k)*dphi_tot(3)%array(i, j, k))*f
579 rho_iter_new = rho_pw_r_sccs%array(i, j, k) + &
580 sccs_control%mixing*(rho_iter_new - rho_pw_r_sccs%array(i, j, k))
581 rho_delta = abs(rho_iter_new - rho_pw_r_sccs%array(i, j, k))
582 rho_delta_max = max(rho_delta, rho_delta_max)
583 rho_delta_avg = rho_delta_avg + rho_delta
584 rho_tot%array(i, j, k) = rho_tot_zero%array(i, j, k) + rho_iter_new
585 rho_pw_r_sccs%array(i, j, k) = rho_iter_new
591 CALL para_env%sum(rho_delta_avg)
592 rho_delta_avg = rho_delta_avg/real(ngpts, kind=dp)
593 CALL para_env%max(rho_delta_max)
595 IF (should_output .AND. (output_unit > 0))
THEN
596 IF (print_level > low_print_level)
THEN
597 IF ((abs(rho_delta_avg) < 1.0e-8_dp) .OR. &
598 (abs(rho_delta_avg) >= 1.0e5_dp))
THEN
599 WRITE (unit=output_unit, fmt=
"(T3,A,I6,4X,ES16.4,4X,ES16.4,1X,F25.12)") &
600 "SCCS| ", iter, rho_delta_avg, rho_delta_max, energy%sccs_hartree
602 WRITE (unit=output_unit, fmt=
"(T3,A,I6,4X,F16.8,4X,F16.8,1X,F25.12)") &
603 "SCCS| ", iter, rho_delta_avg, rho_delta_max, energy%sccs_hartree
609 IF (rho_delta_max <= sccs_control%eps_sccs)
THEN
610 IF (should_output .AND. (output_unit > 0))
THEN
611 WRITE (unit=output_unit, fmt=
"(T3,A,I0,A)") &
612 "SCCS| Iteration cycle converged in ", iter,
" steps"
620 CALL auxbas_pw_pool%give_back_pw(rho_tot_zero)
622 CALL auxbas_pw_pool%give_back_pw(dln_eps_elec(i))
626 filename =
"TOTAL_CHARGE_DENSITY"
627 cube_path = trim(print_path)//
"%"//trim(filename)
628 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), cp_p_file))
THEN
629 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
630 my_pos_cube =
"REWIND"
631 IF (append_cube) my_pos_cube =
"APPEND"
633 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
634 extension=
".cube", middle_name=trim(filename), &
635 file_position=my_pos_cube, log_filename=.false., &
636 mpi_io=mpi_io, fout=mpi_filename)
637 IF (output_unit > 0)
THEN
638 IF (.NOT. mpi_io)
THEN
639 INQUIRE (unit=cube_unit, name=filename)
641 filename = mpi_filename
643 WRITE (unit=output_unit, fmt=
"(T3,A)") &
644 "SCCS| The total SCCS charge density is written in cube file format to the file:", &
645 "SCCS| "//trim(filename)
647 CALL cp_pw_to_cube(rho_tot, cube_unit, trim(filename), particles=particles, &
648 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
649 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
654 CALL pw_transfer(rho_tot, rho_tot_gspace)
655 IF (calculate_stress_tensor)
THEN
657 CALL pw_poisson_solve(poisson_env=poisson_env, &
658 density=rho_tot_gspace, &
660 vhartree=v_hartree_gspace, &
661 dvhartree=dphi_tot, &
664 CALL pw_poisson_solve(poisson_env=poisson_env, &
665 density=rho_tot_gspace, &
667 vhartree=v_hartree_gspace, &
670 CALL pw_transfer(v_hartree_gspace, phi_tot)
671 energy%sccs_hartree = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
675 TYPE(pw_r3d_rs_type) :: phi_solute
676 CALL auxbas_pw_pool%create_pw(phi_solute)
677 CALL pw_zero(phi_solute)
678 CALL pw_poisson_solve(poisson_env=poisson_env, &
679 density=rho_solute, &
680 ehartree=energy%hartree, &
685 CALL pw_axpy(phi_solute, phi_tot, alpha=-1.0_dp)
686 CALL auxbas_pw_pool%give_back_pw(phi_solute)
690 filename =
"POLARISATION_POTENTIAL"
691 cube_path = trim(print_path)//
"%"//trim(filename)
692 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), &
694 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
695 my_pos_cube =
"REWIND"
696 IF (append_cube) my_pos_cube =
"APPEND"
698 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
699 extension=
".cube", middle_name=trim(filename), &
700 file_position=my_pos_cube, log_filename=.false., &
701 mpi_io=mpi_io, fout=mpi_filename)
702 IF (output_unit > 0)
THEN
703 IF (.NOT. mpi_io)
THEN
704 INQUIRE (unit=cube_unit, name=filename)
706 filename = mpi_filename
708 WRITE (unit=output_unit, fmt=
"(T3,A)") &
709 "SCCS| The SCCS polarisation potential is written in cube file format to the file:", &
710 "SCCS| "//trim(filename)
712 CALL cp_pw_to_cube(phi_tot, cube_unit, trim(filename), particles=particles, &
713 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
714 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
719 CALL pw_axpy(rho_solute, rho_tot, alpha=-1.0_dp)
720 polarisation_charge = pw_integrate_function(rho_tot)
723 filename =
"POLARISATION_CHARGE_DENSITY"
724 cube_path = trim(print_path)//
"%"//trim(filename)
725 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), &
727 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
728 my_pos_cube =
"REWIND"
729 IF (append_cube) my_pos_cube =
"APPEND"
731 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
732 extension=
".cube", middle_name=trim(filename), &
733 file_position=my_pos_cube, log_filename=.false., &
734 mpi_io=mpi_io, fout=mpi_filename)
735 IF (output_unit > 0)
THEN
736 IF (.NOT. mpi_io)
THEN
737 INQUIRE (unit=cube_unit, name=filename)
739 filename = mpi_filename
741 WRITE (unit=output_unit, fmt=
"(T3,A)") &
742 "SCCS| The SCCS polarisation charge density is written in cube file format to the file:", &
743 "SCCS| "//trim(filename)
745 CALL cp_pw_to_cube(rho_tot, cube_unit, trim(filename), particles=particles, &
746 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
747 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
751 energy%sccs_pol = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
752 CALL auxbas_pw_pool%give_back_pw(rho_solute)
753 CALL auxbas_pw_pool%give_back_pw(phi_tot)
754 CALL auxbas_pw_pool%give_back_pw(rho_tot)
758 energy%sccs_cav = sccs_control%gamma_solvent*cavity_surface
759 energy%sccs_dis = sccs_control%beta_solvent*cavity_volume
760 energy%sccs_rep = sccs_control%alpha_solvent*cavity_surface
762 energy%sccs_sol = energy%sccs_pol + energy%sccs_rep + energy%sccs_cav + energy%sccs_dis
764 IF (should_output .AND. (output_unit > 0))
THEN
765 WRITE (unit=output_unit, fmt=
"(T3,A)") &
767 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.12)") &
768 "SCCS| Polarisation charge", polarisation_charge
770 WRITE (unit=output_unit, fmt=
"(T3,A)") &
776 f = -0.5_dp*dvol/fourpi
784 dphi2 = dphi_tot(1)%array(i, j, k)*dphi_tot(1)%array(i, j, k) + &
785 dphi_tot(2)%array(i, j, k)*dphi_tot(2)%array(i, j, k) + &
786 dphi_tot(3)%array(i, j, k)*dphi_tot(3)%array(i, j, k)
787 v_sccs%array(i, j, k) = v_sccs%array(i, j, k) + f*deps_elec%array(i, j, k)*dphi2
793 CALL auxbas_pw_pool%give_back_pw(deps_elec)
795 CALL auxbas_pw_pool%give_back_pw(dphi_tot(i))
799 CALL cp_print_key_finished_output(output_unit, logger, input, trim(print_path), &
800 ignore_should_output=should_output)
802 CALL timestop(handle)
820 SUBROUTINE andreussi(rho_elec, eps_elec, deps_elec, epsilon_solvent, rho_max, &
823 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, eps_elec, deps_elec
824 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, rho_max, rho_min
826 CHARACTER(LEN=*),
PARAMETER :: routinen =
'andreussi'
827 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
829 INTEGER :: handle, i, j, k
830 INTEGER,
DIMENSION(3) :: lb, ub
831 REAL(kind=dp) :: diff, dq, dt, f, ln_rho_max, ln_rho_min, &
834 CALL timeset(routinen, handle)
836 f = log(epsilon_solvent)/twopi
837 diff = rho_max - rho_min
838 IF (diff < sqrt(rhotol)) cpabort(
"SCCS: Difference between rho(min) and rho(max) is too small")
839 IF (rho_min >= rhotol)
THEN
840 ln_rho_max = log(rho_max)
841 ln_rho_min = log(rho_min)
842 q = twopi/(ln_rho_max - ln_rho_min)
846 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
847 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
857 rho = rho_elec%array(i, j, k)
858 IF (rho < rho_min)
THEN
859 eps_elec%array(i, j, k) = epsilon_solvent
860 deps_elec%array(i, j, k) = 0.0_dp
861 ELSE IF (rho <= rho_max)
THEN
863 y = q*(ln_rho_max - x)
865 eps_elec%array(i, j, k) = exp(t)
866 dt = dq*(1.0_dp - cos(y))
867 deps_elec%array(i, j, k) = eps_elec%array(i, j, k)*dt/rho
869 eps_elec%array(i, j, k) = 1.0_dp
870 deps_elec%array(i, j, k) = 0.0_dp
877 CALL timestop(handle)
879 END SUBROUTINE andreussi
894 SUBROUTINE fattebert_gygi(rho_elec, eps_elec, deps_elec, epsilon_solvent, beta, &
897 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, eps_elec, deps_elec
898 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, beta, rho_zero
900 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fattebert_gygi'
901 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
903 INTEGER :: handle, i, j, k
904 INTEGER,
DIMENSION(3) :: lb, ub
905 REAL(kind=dp) :: df, f, p, q, rho, s, t, twobeta
907 CALL timeset(routinen, handle)
909 df = (1.0_dp - epsilon_solvent)/rho_zero
910 f = 0.5_dp*(epsilon_solvent - 1.0_dp)
912 twobeta = 2.0_dp*beta
914 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
915 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
925 rho = rho_elec%array(i, j, k)
926 IF (rho < rhotol)
THEN
927 eps_elec%array(i, j, k) = epsilon_solvent
928 deps_elec%array(i, j, k) = 0.0_dp
932 t = 1.0_dp/(1.0_dp + p)
933 eps_elec%array(i, j, k) = 1.0_dp + f*(1.0_dp + (1.0_dp - p)*t)
934 deps_elec%array(i, j, k) = df*twobeta*t*t*p/s
941 CALL timestop(handle)
943 END SUBROUTINE fattebert_gygi
957 SUBROUTINE derive(f, df, method, pw_env, input)
959 TYPE(pw_r3d_rs_type),
INTENT(IN) :: f
960 TYPE(pw_r3d_rs_type),
DIMENSION(3),
INTENT(INOUT) :: df
961 INTEGER,
INTENT(IN) :: method
962 TYPE(pw_env_type),
POINTER :: pw_env
963 TYPE(section_vals_type),
POINTER :: input
965 CHARACTER(LEN=*),
PARAMETER :: routinen =
'derive'
967 INTEGER :: border_points, handle, i
968 INTEGER,
DIMENSION(3) :: lb, n, ub
969 TYPE(pw_c1d_gs_type),
DIMENSION(2) :: work_g1d
970 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool
971 TYPE(realspace_grid_desc_type),
POINTER :: rs_desc
972 TYPE(realspace_grid_input_type) :: input_settings
973 TYPE(realspace_grid_type),
POINTER :: rs_grid
974 TYPE(section_vals_type),
POINTER :: rs_grid_section
976 CALL timeset(routinen, handle)
978 cpassert(
ASSOCIATED(pw_env))
982 CASE (sccs_derivative_cd3, sccs_derivative_cd5, sccs_derivative_cd7)
984 rs_grid_section => section_vals_get_subs_vals(input,
"DFT%MGRID%RS_GRID")
986 CASE (sccs_derivative_cd3)
988 CASE (sccs_derivative_cd5)
990 CASE (sccs_derivative_cd7)
993 CALL init_input_type(input_settings, 2*border_points + 1, rs_grid_section, &
995 CALL rs_grid_create_descriptor(rs_desc, f%pw_grid, input_settings, &
996 border_points=border_points)
998 CALL rs_grid_create(rs_grid, rs_desc)
1000 CASE (sccs_derivative_fft)
1001 lb(1:3) = f%pw_grid%bounds_local(1, 1:3)
1002 ub(1:3) = f%pw_grid%bounds_local(2, 1:3)
1003 NULLIFY (auxbas_pw_pool)
1004 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1006 DO i = 1,
SIZE(work_g1d)
1007 CALL auxbas_pw_pool%create_pw(work_g1d(i))
1012 SELECT CASE (method)
1013 CASE (sccs_derivative_cd3)
1014 CALL derive_fdm_cd3(f, df, rs_grid)
1015 CASE (sccs_derivative_cd5)
1016 CALL derive_fdm_cd5(f, df, rs_grid)
1017 CASE (sccs_derivative_cd7)
1018 CALL derive_fdm_cd7(f, df, rs_grid)
1019 CASE (sccs_derivative_fft)
1021 CALL pw_transfer(f, work_g1d(1))
1025 CALL pw_copy(work_g1d(1), work_g1d(2))
1026 CALL pw_derive(work_g1d(2), n(:))
1027 CALL pw_transfer(work_g1d(2), df(i))
1030 cpabort(
"Invalid derivative method for SCCS specified")
1034 SELECT CASE (method)
1035 CASE (sccs_derivative_cd3, sccs_derivative_cd5, sccs_derivative_cd7)
1036 CALL rs_grid_release(rs_grid)
1037 DEALLOCATE (rs_grid)
1038 CALL rs_grid_release_descriptor(rs_desc)
1039 CASE (sccs_derivative_fft)
1040 DO i = 1,
SIZE(work_g1d)
1041 CALL auxbas_pw_pool%give_back_pw(work_g1d(i))
1045 CALL timestop(handle)
1047 END SUBROUTINE derive
1066 SUBROUTINE surface_andreussi(rho_elec, norm_drho_elec, dtheta, &
1067 epsilon_solvent, rho_max, rho_min, delta_rho)
1069 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, norm_drho_elec, dtheta
1070 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, rho_max, rho_min, &
1073 CHARACTER(LEN=*),
PARAMETER :: routinen =
'surface_andreussi'
1074 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
1076 INTEGER :: handle, i, j, k, l
1077 INTEGER,
DIMENSION(3) :: lb, ub
1078 REAL(kind=dp) :: diff, e, eps_elec, f, ln_rho_max, &
1079 ln_rho_min, q, rho, t, x, y
1080 REAL(kind=dp),
DIMENSION(2) :: theta
1082 CALL timeset(routinen, handle)
1084 e = epsilon_solvent - 1.0_dp
1085 f = log(epsilon_solvent)/twopi
1086 diff = rho_max - rho_min
1087 IF (diff < sqrt(rhotol)) cpabort(
"SCCS: Difference between rho(min) and rho(max) is too small")
1088 IF (rho_min >= rhotol)
THEN
1089 ln_rho_max = log(rho_max)
1090 ln_rho_min = log(rho_min)
1091 q = twopi/(ln_rho_max - ln_rho_min)
1094 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
1095 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
1106 rho = rho_elec%array(i, j, k) + (real(l, kind=dp) - 1.5_dp)*delta_rho
1107 IF (rho < rho_min)
THEN
1108 eps_elec = epsilon_solvent
1109 ELSE IF (rho <= rho_max)
THEN
1111 y = q*(ln_rho_max - x)
1117 theta(l) = (epsilon_solvent - eps_elec)/e
1119 dtheta%array(i, j, k) = (theta(2) - theta(1))*norm_drho_elec%array(i, j, k)/delta_rho
1125 CALL timestop(handle)
1127 END SUBROUTINE surface_andreussi
1146 SUBROUTINE surface_fattebert_gygi(rho_elec, norm_drho_elec, dtheta, &
1147 epsilon_solvent, beta, rho_zero, delta_rho)
1149 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, norm_drho_elec, dtheta
1150 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, beta, rho_zero, &
1153 CHARACTER(LEN=*),
PARAMETER :: routinen =
'surface_fattebert_gygi'
1154 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
1156 INTEGER :: handle, i, j, k, l
1157 INTEGER,
DIMENSION(3) :: lb, ub
1158 REAL(kind=dp) :: e, eps_elec, f, p, q, rho, s, t, twobeta
1159 REAL(kind=dp),
DIMENSION(2) :: theta
1161 CALL timeset(routinen, handle)
1163 e = epsilon_solvent - 1.0_dp
1166 twobeta = 2.0_dp*beta
1168 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
1169 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
1180 rho = rho_elec%array(i, j, k) + (real(l, kind=dp) - 1.5_dp)*delta_rho
1181 IF (rho < rhotol)
THEN
1182 eps_elec = epsilon_solvent
1186 t = 1.0_dp/(1.0_dp + p)
1187 eps_elec = 1.0_dp + f*(1.0_dp + (1.0_dp - p)*t)
1189 theta(l) = (epsilon_solvent - eps_elec)/e
1191 dtheta%array(i, j, k) = (theta(2) - theta(1))*norm_drho_elec%array(i, j, k)/delta_rho
1197 CALL timestop(handle)
1199 END SUBROUTINE surface_fattebert_gygi
1213 TYPE(qs_energy_type),
POINTER :: energy
1214 TYPE(sccs_control_type),
POINTER :: sccs_control
1215 INTEGER,
INTENT(IN) :: output_unit
1217 IF (output_unit > 0)
THEN
1218 cpassert(
ASSOCIATED(energy))
1219 cpassert(
ASSOCIATED(sccs_control))
1220 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1221 "SCCS| Hartree energy of solute and solvent [Hartree]", energy%sccs_hartree, &
1222 "SCCS| Hartree energy of the solute only [Hartree]", energy%hartree
1223 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14,/,T3,A,T61,F20.3)") &
1224 "SCCS| Polarisation energy [Hartree]", energy%sccs_pol, &
1225 "SCCS| [kcal/mol]", &
1226 cp_unit_from_cp2k(energy%sccs_pol,
"kcalmol"), &
1227 "SCCS| Cavitation energy [Hartree]", energy%sccs_cav, &
1228 "SCCS| [kcal/mol]", &
1229 cp_unit_from_cp2k(energy%sccs_cav,
"kcalmol"), &
1230 "SCCS| Dispersion free energy [Hartree]", energy%sccs_dis, &
1231 "SCCS| [kcal/mol]", &
1232 cp_unit_from_cp2k(energy%sccs_dis,
"kcalmol"), &
1233 "SCCS| Repulsion free energy [Hartree]", energy%sccs_rep, &
1234 "SCCS| [kcal/mol]", &
1235 cp_unit_from_cp2k(energy%sccs_rep,
"kcalmol"), &
1236 "SCCS| Solvation free energy [Hartree]", energy%sccs_sol, &
1237 "SCCS| [kcal/mol]", &
1238 cp_unit_from_cp2k(energy%sccs_sol,
"kcalmol")
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
integer, parameter, public low_print_level
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, stride, zero_tails, silent, mpi_io)
...
subroutine, public init_input_type(input_settings, nsmax, rs_grid_section, ilevel, higher_grid_layout)
parses an input section to assign the proper values to the input type
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell)
returns information about various attributes of the given subsys
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Definition of mathematical constants and functions.
real(kind=dp), parameter, public fourpi
real(kind=dp), parameter, public twopi
Interface to the message passing library MPI.
represent a simple array based list of the given type
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
subroutine, public pw_derive(pw, n)
Calculate the derivative of a plane wave vector.
functions related to the poisson solver on regular grids
integer, parameter, public pw_poisson_mt
integer, parameter, public pw_poisson_analytic
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
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.
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Self-consistent continuum solvation (SCCS) model implementation.
subroutine, public sccs(qs_env, rho_tot_gspace, v_hartree_gspace, v_sccs, h_stress)
Self-consistent continuum solvation (SCCS) model implementation.
subroutine, public print_sccs_results(energy, sccs_control, output_unit)
Print SCCS results.
module that contains the definitions of the scf types
subroutine, public rs_grid_create(rs, desc)
...
subroutine, public rs_grid_create_descriptor(desc, pw_grid, input_settings, border_points)
Determine the setup of real space grids - this is divided up into the creation of a descriptor and th...
subroutine, public rs_grid_release_descriptor(rs_desc)
releases the given rs grid descriptor (see doc/ReferenceCounting.html)
subroutine, public rs_grid_release(rs_grid)
releases the given rs grid (see doc/ReferenceCounting.html)
numerical operations on real-space grid
subroutine, public derive_fdm_cd7(f, df, rs_grid)
6th order finite difference derivative of a function on realspace grid
subroutine, public derive_fdm_cd5(f, df, rs_grid)
4th order finite difference derivative of a function on realspace grid
subroutine, public derive_fdm_cd3(f, df, rs_grid)
2nd order finite difference derivative of a function on realspace grid