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)
124 TYPE(
pw_c1d_gs_type),
INTENT(INOUT) :: rho_tot_gspace, v_hartree_gspace
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, my_pos_cube
133 CHARACTER(LEN=default_path_length) :: cube_path, filename, mpi_filename, &
135 INTEGER :: cube_unit, handle, i, ispin, iter, j, k, &
136 nspin, output_unit, print_level
137 INTEGER(KIND=int_8) :: ngpts
138 INTEGER,
DIMENSION(3) :: lb, ub
139 LOGICAL :: append_cube, calculate_stress_tensor, &
140 mpi_io, should_output
141 REAL(kind=
dp) :: cavity_surface, cavity_volume, cell_volume, dphi2, dvol, e_tot, &
142 epsilon_solvent, f, polarisation_charge, rho_delta, rho_delta_avg, rho_delta_max, &
143 rho_iter_new, tot_rho_elec, tot_rho_solute
144 REAL(kind=
dp),
DIMENSION(3) :: abc
164 CALL timeset(routinen, handle)
166 NULLIFY (auxbas_pw_pool)
168 NULLIFY (dft_control)
174 NULLIFY (poisson_env)
178 NULLIFY (sccs_control)
183 cp_subsys=cp_subsys, &
184 dft_control=dft_control, &
193 sccs_control => dft_control%sccs_control
195 cpassert(
ASSOCIATED(qs_env))
197 IF (
PRESENT(h_stress))
THEN
198 calculate_stress_tensor = .true.
199 h_stress(:, :) = 0.0_dp
200 cpwarn(
"The stress tensor for SCCS has not yet been fully validated")
202 calculate_stress_tensor = .false.
207 auxbas_pw_pool=auxbas_pw_pool, &
209 poisson_env=poisson_env)
214 IF (.NOT. sccs_control%sccs_activated)
THEN
215 IF (sccs_control%eps_scf > 0.0_dp)
THEN
216 IF ((scf_env%iter_delta > sccs_control%eps_scf) .OR. &
217 ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
218 (qs_env%scf_env%iter_count <= 1)))
THEN
219 IF (calculate_stress_tensor)
THEN
222 density=rho_tot_gspace, &
223 ehartree=energy%hartree, &
224 vhartree=v_hartree_gspace, &
228 density=rho_tot_gspace, &
229 ehartree=energy%hartree, &
230 vhartree=v_hartree_gspace)
232 energy%sccs_pol = 0.0_dp
233 energy%sccs_cav = 0.0_dp
234 energy%sccs_dis = 0.0_dp
235 energy%sccs_rep = 0.0_dp
236 energy%sccs_sol = 0.0_dp
237 energy%sccs_hartree = energy%hartree
238 CALL timestop(handle)
242 sccs_control%sccs_activated = .true.
245 nspin = dft_control%nspins
249 print_level = logger%iter_info%print_level
250 print_path =
"DFT%PRINT%SCCS"
255 ignore_should_output=should_output, &
256 log_filename=.false.)
261 rho_r_sccs=rho_pw_r_sccs)
264 cpassert(
ASSOCIATED(rho_pw_r_sccs))
269 CALL auxbas_pw_pool%create_pw(rho_elec)
272 ngpts = rho_elec%pw_grid%ngpts
273 dvol = rho_elec%pw_grid%dvol
274 cell_volume = rho_elec%pw_grid%vol
275 abc(1:3) = real(rho_elec%pw_grid%npts(1:3), kind=
dp)*rho_elec%pw_grid%dr(1:3)
276 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
277 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
279 CALL pw_copy(rho_pw_r(1), rho_elec)
281 CALL pw_axpy(rho_pw_r(ispin), rho_elec)
286 CALL auxbas_pw_pool%create_pw(eps_elec)
287 CALL auxbas_pw_pool%create_pw(deps_elec)
289 epsilon_solvent = sccs_control%epsilon_solvent
290 SELECT CASE (sccs_control%method_id)
292 CALL andreussi(rho_elec, eps_elec, deps_elec, epsilon_solvent, sccs_control%rho_max, &
293 sccs_control%rho_min)
295 CALL fattebert_gygi(rho_elec, eps_elec, deps_elec, epsilon_solvent, sccs_control%beta, &
296 sccs_control%rho_zero)
298 cpabort(
"Invalid method specified for SCCS model")
302 filename =
"DIELECTRIC_FUNCTION"
303 cube_path = trim(print_path)//
"%"//trim(filename)
307 my_pos_cube =
"REWIND"
308 IF (append_cube) my_pos_cube =
"APPEND"
311 extension=
".cube", middle_name=trim(filename), &
312 file_position=my_pos_cube, log_filename=.false., &
313 mpi_io=mpi_io, fout=mpi_filename)
314 IF (output_unit > 0)
THEN
315 IF (.NOT. mpi_io)
THEN
316 INQUIRE (unit=cube_unit, name=filename)
318 filename = mpi_filename
320 WRITE (unit=output_unit, fmt=
"(T3,A)") &
321 "SCCS| The dielectric function is written in cube file format to the file:", &
322 "SCCS| "//trim(filename)
324 CALL cp_pw_to_cube(eps_elec, cube_unit, trim(filename), particles=particles, &
331 cavity_surface = 0.0_dp
332 cavity_volume = 0.0_dp
334 IF (abs(epsilon_solvent - 1.0_dp) > epstol)
THEN
339 CALL auxbas_pw_pool%create_pw(theta)
343 f = 1.0_dp/(epsilon_solvent - 1.0_dp)
350 theta%array(i, j, k) = f*(epsilon_solvent - eps_elec%array(i, j, k))
360 CALL auxbas_pw_pool%create_pw(drho_elec(i))
364 CALL auxbas_pw_pool%create_pw(norm_drho_elec)
373 norm_drho_elec%array(i, j, k) = sqrt(drho_elec(1)%array(i, j, k)* &
374 drho_elec(1)%array(i, j, k) + &
375 drho_elec(2)%array(i, j, k)* &
376 drho_elec(2)%array(i, j, k) + &
377 drho_elec(3)%array(i, j, k)* &
378 drho_elec(3)%array(i, j, k))
385 filename =
"DENSITY_GRADIENT"
386 cube_path = trim(print_path)//
"%"//trim(filename)
390 my_pos_cube =
"REWIND"
391 IF (append_cube) my_pos_cube =
"APPEND"
394 extension=
".cube", middle_name=trim(filename), &
395 file_position=my_pos_cube, log_filename=.false., &
396 mpi_io=mpi_io, fout=mpi_filename)
397 IF (output_unit > 0)
THEN
398 IF (.NOT. mpi_io)
THEN
399 INQUIRE (unit=cube_unit, name=filename)
401 filename = mpi_filename
403 WRITE (unit=output_unit, fmt=
"(T3,A)") &
404 "SCCS| The norm of the density gradient is written in cube file format to the file:", &
405 "SCCS| "//trim(filename)
407 CALL cp_pw_to_cube(norm_drho_elec, cube_unit, trim(filename), particles=particles, &
414 SELECT CASE (sccs_control%method_id)
416 CALL surface_andreussi(rho_elec, norm_drho_elec, theta, epsilon_solvent, &
417 sccs_control%rho_max, sccs_control%rho_min, &
418 sccs_control%delta_rho)
420 CALL surface_fattebert_gygi(rho_elec, norm_drho_elec, theta, epsilon_solvent, &
421 sccs_control%beta, sccs_control%rho_zero, &
422 sccs_control%delta_rho)
424 cpabort(
"Invalid method specified for SCCS model")
429 CALL auxbas_pw_pool%give_back_pw(theta)
430 CALL auxbas_pw_pool%give_back_pw(norm_drho_elec)
432 CALL auxbas_pw_pool%give_back_pw(drho_elec(i))
438 CALL auxbas_pw_pool%give_back_pw(rho_elec)
442 TYPE(pw_r3d_rs_type) :: rho_tot, phi_tot, rho_solute, rho_tot_zero
444 CALL auxbas_pw_pool%create_pw(rho_solute)
445 CALL pw_zero(rho_solute)
446 CALL pw_transfer(rho_tot_gspace, rho_solute)
447 tot_rho_solute = pw_integrate_function(rho_solute)
450 IF (abs(tot_rho_solute) >= 1.0e-6_dp)
THEN
451 IF ((poisson_env%parameters%solver /= pw_poisson_analytic) .AND. &
452 (poisson_env%parameters%solver /= pw_poisson_mt))
THEN
453 WRITE (unit=message, fmt=
"(A,SP,F0.6,A)") &
454 "The system (solute) has a non-negligible charge of ", -tot_rho_solute, &
455 ". It is recommended to use non-periodic boundary conditions (PERIODIC none) "// &
456 "combined with an appropriate Poisson solver (POISSON_SOLVER MT or analytic)"
462 CALL auxbas_pw_pool%create_pw(rho_tot_zero)
473 IF (eps_elec%array(i, j, k) < 1.0_dp)
THEN
474 WRITE (unit=message, fmt=
"(A,ES12.3,A,3(I0,A))") &
475 "SCCS| Invalid dielectric function value ", eps_elec%array(i, j, k), &
476 " encountered at grid point (", i,
",", j,
",", k,
")"
479 rho_tot_zero%array(i, j, k) = rho_solute%array(i, j, k)/eps_elec%array(i, j, k)
480 eps_elec%array(i, j, k) = log(eps_elec%array(i, j, k))
488 CALL auxbas_pw_pool%create_pw(dln_eps_elec(i))
489 CALL pw_zero(dln_eps_elec(i))
491 CALL derive(eps_elec, dln_eps_elec, sccs_control%derivative_method, pw_env, input)
492 CALL auxbas_pw_pool%give_back_pw(eps_elec)
495 IF (should_output .AND. (output_unit > 0))
THEN
496 IF (print_level > low_print_level)
THEN
497 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.12)") &
498 "SCCS| Total electronic charge density ", -tot_rho_elec, &
499 "SCCS| Total charge density (solute) ", -tot_rho_solute
500 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.3)") &
501 "SCCS| Volume of the cell [bohr^3]", cell_volume, &
502 "SCCS| [angstrom^3]", &
503 cp_unit_from_cp2k(cell_volume,
"angstrom^3")
504 IF (abs(epsilon_solvent - 1.0_dp) > epstol)
THEN
505 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.3)") &
506 "SCCS| Volume of the solute cavity [bohr^3]", cavity_volume, &
507 "SCCS| [angstrom^3]", &
508 cp_unit_from_cp2k(cavity_volume,
"angstrom^3"), &
509 "SCCS| Surface of the solute cavity [bohr^2]", cavity_surface, &
510 "SCCS| [angstrom^2]", &
511 cp_unit_from_cp2k(cavity_surface,
"angstrom^2")
513 WRITE (unit=output_unit, fmt=
"(T3,A)") &
515 "SCCS| Step Average residual Maximum residual E(Hartree) [a.u.]"
521 CALL auxbas_pw_pool%create_pw(dphi_tot(i))
525 CALL auxbas_pw_pool%create_pw(rho_tot)
526 CALL pw_copy(rho_tot_zero, rho_tot)
527 CALL pw_axpy(rho_pw_r_sccs, rho_tot)
529 CALL auxbas_pw_pool%create_pw(phi_tot)
530 CALL pw_zero(phi_tot)
541 IF (iter > sccs_control%max_iter)
THEN
542 IF (output_unit > 0)
THEN
543 WRITE (unit=output_unit, fmt=
"(T3,A,/,T3,A,I0,A)") &
544 "SCCS| Maximum number of SCCS iterations reached", &
545 "SCCS| Iteration cycle did not converge in ", sccs_control%max_iter,
" steps"
547 WRITE (unit=message, fmt=
"(A,I0,A)") &
548 "The SCCS iteration cycle did not converge in ", sccs_control%max_iter,
" steps"
555 CALL pw_poisson_solve(poisson_env=poisson_env, &
559 energy%sccs_hartree = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
564 rho_delta_avg = 0.0_dp
565 rho_delta_max = 0.0_dp
575 rho_iter_new = (dln_eps_elec(1)%array(i, j, k)*dphi_tot(1)%array(i, j, k) + &
576 dln_eps_elec(2)%array(i, j, k)*dphi_tot(2)%array(i, j, k) + &
577 dln_eps_elec(3)%array(i, j, k)*dphi_tot(3)%array(i, j, k))*f
578 rho_iter_new = rho_pw_r_sccs%array(i, j, k) + &
579 sccs_control%mixing*(rho_iter_new - rho_pw_r_sccs%array(i, j, k))
580 rho_delta = abs(rho_iter_new - rho_pw_r_sccs%array(i, j, k))
581 rho_delta_max = max(rho_delta, rho_delta_max)
582 rho_delta_avg = rho_delta_avg + rho_delta
583 rho_tot%array(i, j, k) = rho_tot_zero%array(i, j, k) + rho_iter_new
584 rho_pw_r_sccs%array(i, j, k) = rho_iter_new
590 CALL para_env%sum(rho_delta_avg)
591 rho_delta_avg = rho_delta_avg/real(ngpts, kind=dp)
592 CALL para_env%max(rho_delta_max)
594 IF (should_output .AND. (output_unit > 0))
THEN
595 IF (print_level > low_print_level)
THEN
596 IF ((abs(rho_delta_avg) < 1.0e-8_dp) .OR. &
597 (abs(rho_delta_avg) >= 1.0e5_dp))
THEN
598 WRITE (unit=output_unit, fmt=
"(T3,A,I6,4X,ES16.4,4X,ES16.4,1X,F25.12)") &
599 "SCCS| ", iter, rho_delta_avg, rho_delta_max, energy%sccs_hartree
601 WRITE (unit=output_unit, fmt=
"(T3,A,I6,4X,F16.8,4X,F16.8,1X,F25.12)") &
602 "SCCS| ", iter, rho_delta_avg, rho_delta_max, energy%sccs_hartree
608 IF (rho_delta_max <= sccs_control%eps_sccs)
THEN
609 IF (should_output .AND. (output_unit > 0))
THEN
610 WRITE (unit=output_unit, fmt=
"(T3,A,I0,A)") &
611 "SCCS| Iteration cycle converged in ", iter,
" steps"
619 CALL auxbas_pw_pool%give_back_pw(rho_tot_zero)
621 CALL auxbas_pw_pool%give_back_pw(dln_eps_elec(i))
625 filename =
"TOTAL_CHARGE_DENSITY"
626 cube_path = trim(print_path)//
"%"//trim(filename)
627 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), cp_p_file))
THEN
628 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
629 my_pos_cube =
"REWIND"
630 IF (append_cube) my_pos_cube =
"APPEND"
632 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
633 extension=
".cube", middle_name=trim(filename), &
634 file_position=my_pos_cube, log_filename=.false., &
635 mpi_io=mpi_io, fout=mpi_filename)
636 IF (output_unit > 0)
THEN
637 IF (.NOT. mpi_io)
THEN
638 INQUIRE (unit=cube_unit, name=filename)
640 filename = mpi_filename
642 WRITE (unit=output_unit, fmt=
"(T3,A)") &
643 "SCCS| The total SCCS charge density is written in cube file format to the file:", &
644 "SCCS| "//trim(filename)
646 CALL cp_pw_to_cube(rho_tot, cube_unit, trim(filename), particles=particles, &
647 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
648 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
653 CALL pw_transfer(rho_tot, rho_tot_gspace)
654 IF (calculate_stress_tensor)
THEN
656 CALL pw_poisson_solve(poisson_env=poisson_env, &
657 density=rho_tot_gspace, &
659 vhartree=v_hartree_gspace, &
660 dvhartree=dphi_tot, &
663 CALL pw_poisson_solve(poisson_env=poisson_env, &
664 density=rho_tot_gspace, &
666 vhartree=v_hartree_gspace, &
669 CALL pw_transfer(v_hartree_gspace, phi_tot)
670 energy%sccs_hartree = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
674 TYPE(pw_r3d_rs_type) :: phi_solute
675 CALL auxbas_pw_pool%create_pw(phi_solute)
676 CALL pw_zero(phi_solute)
677 CALL pw_poisson_solve(poisson_env=poisson_env, &
678 density=rho_solute, &
679 ehartree=energy%hartree, &
684 CALL pw_axpy(phi_solute, phi_tot, alpha=-1.0_dp)
685 CALL auxbas_pw_pool%give_back_pw(phi_solute)
689 filename =
"POLARISATION_POTENTIAL"
690 cube_path = trim(print_path)//
"%"//trim(filename)
691 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), &
693 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
694 my_pos_cube =
"REWIND"
695 IF (append_cube) my_pos_cube =
"APPEND"
697 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
698 extension=
".cube", middle_name=trim(filename), &
699 file_position=my_pos_cube, log_filename=.false., &
700 mpi_io=mpi_io, fout=mpi_filename)
701 IF (output_unit > 0)
THEN
702 IF (.NOT. mpi_io)
THEN
703 INQUIRE (unit=cube_unit, name=filename)
705 filename = mpi_filename
707 WRITE (unit=output_unit, fmt=
"(T3,A)") &
708 "SCCS| The SCCS polarisation potential is written in cube file format to the file:", &
709 "SCCS| "//trim(filename)
711 CALL cp_pw_to_cube(phi_tot, cube_unit, trim(filename), particles=particles, &
712 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
713 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
718 CALL pw_axpy(rho_solute, rho_tot, alpha=-1.0_dp)
719 polarisation_charge = pw_integrate_function(rho_tot)
722 filename =
"POLARISATION_CHARGE_DENSITY"
723 cube_path = trim(print_path)//
"%"//trim(filename)
724 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), &
726 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
727 my_pos_cube =
"REWIND"
728 IF (append_cube) my_pos_cube =
"APPEND"
730 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
731 extension=
".cube", middle_name=trim(filename), &
732 file_position=my_pos_cube, log_filename=.false., &
733 mpi_io=mpi_io, fout=mpi_filename)
734 IF (output_unit > 0)
THEN
735 IF (.NOT. mpi_io)
THEN
736 INQUIRE (unit=cube_unit, name=filename)
738 filename = mpi_filename
740 WRITE (unit=output_unit, fmt=
"(T3,A)") &
741 "SCCS| The SCCS polarisation charge density is written in cube file format to the file:", &
742 "SCCS| "//trim(filename)
744 CALL cp_pw_to_cube(rho_tot, cube_unit, trim(filename), particles=particles, &
745 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
746 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
750 energy%sccs_pol = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
751 CALL auxbas_pw_pool%give_back_pw(rho_solute)
752 CALL auxbas_pw_pool%give_back_pw(phi_tot)
753 CALL auxbas_pw_pool%give_back_pw(rho_tot)
757 energy%sccs_cav = sccs_control%gamma_solvent*cavity_surface
758 energy%sccs_dis = sccs_control%beta_solvent*cavity_volume
759 energy%sccs_rep = sccs_control%alpha_solvent*cavity_surface
761 energy%sccs_sol = energy%sccs_pol + energy%sccs_rep + energy%sccs_cav + energy%sccs_dis
763 IF (should_output .AND. (output_unit > 0))
THEN
764 WRITE (unit=output_unit, fmt=
"(T3,A)") &
766 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.12)") &
767 "SCCS| Polarisation charge", polarisation_charge
769 WRITE (unit=output_unit, fmt=
"(T3,A)") &
775 f = -0.5_dp*dvol/fourpi
783 dphi2 = dphi_tot(1)%array(i, j, k)*dphi_tot(1)%array(i, j, k) + &
784 dphi_tot(2)%array(i, j, k)*dphi_tot(2)%array(i, j, k) + &
785 dphi_tot(3)%array(i, j, k)*dphi_tot(3)%array(i, j, k)
786 v_sccs%array(i, j, k) = v_sccs%array(i, j, k) + f*deps_elec%array(i, j, k)*dphi2
792 CALL auxbas_pw_pool%give_back_pw(deps_elec)
794 CALL auxbas_pw_pool%give_back_pw(dphi_tot(i))
798 CALL cp_print_key_finished_output(output_unit, logger, input, trim(print_path), &
799 ignore_should_output=should_output)
801 CALL timestop(handle)
819 SUBROUTINE andreussi(rho_elec, eps_elec, deps_elec, epsilon_solvent, rho_max, &
822 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, eps_elec, deps_elec
823 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, rho_max, rho_min
825 CHARACTER(LEN=*),
PARAMETER :: routinen =
'andreussi'
826 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
828 INTEGER :: handle, i, j, k
829 INTEGER,
DIMENSION(3) :: lb, ub
830 REAL(kind=dp) :: diff, dq, dt, f, ln_rho_max, ln_rho_min, &
833 CALL timeset(routinen, handle)
835 f = log(epsilon_solvent)/twopi
836 diff = rho_max - rho_min
837 IF (diff < sqrt(rhotol)) cpabort(
"SCCS: Difference between rho(min) and rho(max) is too small")
838 IF (rho_min >= rhotol)
THEN
839 ln_rho_max = log(rho_max)
840 ln_rho_min = log(rho_min)
841 q = twopi/(ln_rho_max - ln_rho_min)
845 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
846 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
856 rho = rho_elec%array(i, j, k)
857 IF (rho < rho_min)
THEN
858 eps_elec%array(i, j, k) = epsilon_solvent
859 deps_elec%array(i, j, k) = 0.0_dp
860 ELSE IF (rho <= rho_max)
THEN
862 y = q*(ln_rho_max - x)
864 eps_elec%array(i, j, k) = exp(t)
865 dt = dq*(1.0_dp - cos(y))
866 deps_elec%array(i, j, k) = eps_elec%array(i, j, k)*dt/rho
868 eps_elec%array(i, j, k) = 1.0_dp
869 deps_elec%array(i, j, k) = 0.0_dp
876 CALL timestop(handle)
878 END SUBROUTINE andreussi
893 SUBROUTINE fattebert_gygi(rho_elec, eps_elec, deps_elec, epsilon_solvent, beta, &
896 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, eps_elec, deps_elec
897 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, beta, rho_zero
899 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fattebert_gygi'
900 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
902 INTEGER :: handle, i, j, k
903 INTEGER,
DIMENSION(3) :: lb, ub
904 REAL(kind=dp) :: df, f, p, q, rho, s, t, twobeta
906 CALL timeset(routinen, handle)
908 df = (1.0_dp - epsilon_solvent)/rho_zero
909 f = 0.5_dp*(epsilon_solvent - 1.0_dp)
911 twobeta = 2.0_dp*beta
913 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
914 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
924 rho = rho_elec%array(i, j, k)
925 IF (rho < rhotol)
THEN
926 eps_elec%array(i, j, k) = epsilon_solvent
927 deps_elec%array(i, j, k) = 0.0_dp
931 t = 1.0_dp/(1.0_dp + p)
932 eps_elec%array(i, j, k) = 1.0_dp + f*(1.0_dp + (1.0_dp - p)*t)
933 deps_elec%array(i, j, k) = df*twobeta*t*t*p/s
940 CALL timestop(handle)
942 END SUBROUTINE fattebert_gygi
956 SUBROUTINE derive(f, df, method, pw_env, input)
958 TYPE(pw_r3d_rs_type),
INTENT(IN) :: f
959 TYPE(pw_r3d_rs_type),
DIMENSION(3),
INTENT(INOUT) :: df
960 INTEGER,
INTENT(IN) :: method
961 TYPE(pw_env_type),
POINTER :: pw_env
962 TYPE(section_vals_type),
POINTER :: input
964 CHARACTER(LEN=*),
PARAMETER :: routinen =
'derive'
966 INTEGER :: border_points, handle, i
967 INTEGER,
DIMENSION(3) :: lb, n, ub
968 TYPE(pw_c1d_gs_type),
DIMENSION(2) :: work_g1d
969 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool
970 TYPE(realspace_grid_desc_type),
POINTER :: rs_desc
971 TYPE(realspace_grid_input_type) :: input_settings
972 TYPE(realspace_grid_type),
POINTER :: rs_grid
973 TYPE(section_vals_type),
POINTER :: rs_grid_section
975 CALL timeset(routinen, handle)
977 cpassert(
ASSOCIATED(pw_env))
981 CASE (sccs_derivative_cd3, sccs_derivative_cd5, sccs_derivative_cd7)
983 rs_grid_section => section_vals_get_subs_vals(input,
"DFT%MGRID%RS_GRID")
985 CASE (sccs_derivative_cd3)
987 CASE (sccs_derivative_cd5)
989 CASE (sccs_derivative_cd7)
992 CALL init_input_type(input_settings, 2*border_points + 1, rs_grid_section, &
994 CALL rs_grid_create_descriptor(rs_desc, f%pw_grid, input_settings, &
995 border_points=border_points)
997 CALL rs_grid_create(rs_grid, rs_desc)
999 CASE (sccs_derivative_fft)
1000 lb(1:3) = f%pw_grid%bounds_local(1, 1:3)
1001 ub(1:3) = f%pw_grid%bounds_local(2, 1:3)
1002 NULLIFY (auxbas_pw_pool)
1003 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1005 DO i = 1,
SIZE(work_g1d)
1006 CALL auxbas_pw_pool%create_pw(work_g1d(i))
1011 SELECT CASE (method)
1012 CASE (sccs_derivative_cd3)
1013 CALL derive_fdm_cd3(f, df, rs_grid)
1014 CASE (sccs_derivative_cd5)
1015 CALL derive_fdm_cd5(f, df, rs_grid)
1016 CASE (sccs_derivative_cd7)
1017 CALL derive_fdm_cd7(f, df, rs_grid)
1018 CASE (sccs_derivative_fft)
1020 CALL pw_transfer(f, work_g1d(1))
1024 CALL pw_copy(work_g1d(1), work_g1d(2))
1025 CALL pw_derive(work_g1d(2), n(:))
1026 CALL pw_transfer(work_g1d(2), df(i))
1029 cpabort(
"Invalid derivative method for SCCS specified")
1033 SELECT CASE (method)
1034 CASE (sccs_derivative_cd3, sccs_derivative_cd5, sccs_derivative_cd7)
1035 CALL rs_grid_release(rs_grid)
1036 DEALLOCATE (rs_grid)
1037 CALL rs_grid_release_descriptor(rs_desc)
1038 CASE (sccs_derivative_fft)
1039 DO i = 1,
SIZE(work_g1d)
1040 CALL auxbas_pw_pool%give_back_pw(work_g1d(i))
1044 CALL timestop(handle)
1046 END SUBROUTINE derive
1065 SUBROUTINE surface_andreussi(rho_elec, norm_drho_elec, dtheta, &
1066 epsilon_solvent, rho_max, rho_min, delta_rho)
1068 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, norm_drho_elec, dtheta
1069 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, rho_max, rho_min, &
1072 CHARACTER(LEN=*),
PARAMETER :: routinen =
'surface_andreussi'
1073 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
1075 INTEGER :: handle, i, j, k, l
1076 INTEGER,
DIMENSION(3) :: lb, ub
1077 REAL(kind=dp) :: diff, e, eps_elec, f, ln_rho_max, &
1078 ln_rho_min, q, rho, t, x, y
1079 REAL(kind=dp),
DIMENSION(2) :: theta
1081 CALL timeset(routinen, handle)
1083 e = epsilon_solvent - 1.0_dp
1084 f = log(epsilon_solvent)/twopi
1085 diff = rho_max - rho_min
1086 IF (diff < sqrt(rhotol)) cpabort(
"SCCS: Difference between rho(min) and rho(max) is too small")
1087 IF (rho_min >= rhotol)
THEN
1088 ln_rho_max = log(rho_max)
1089 ln_rho_min = log(rho_min)
1090 q = twopi/(ln_rho_max - ln_rho_min)
1093 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
1094 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
1105 rho = rho_elec%array(i, j, k) + (real(l, kind=dp) - 1.5_dp)*delta_rho
1106 IF (rho < rho_min)
THEN
1107 eps_elec = epsilon_solvent
1108 ELSE IF (rho <= rho_max)
THEN
1110 y = q*(ln_rho_max - x)
1116 theta(l) = (epsilon_solvent - eps_elec)/e
1118 dtheta%array(i, j, k) = (theta(2) - theta(1))*norm_drho_elec%array(i, j, k)/delta_rho
1124 CALL timestop(handle)
1126 END SUBROUTINE surface_andreussi
1145 SUBROUTINE surface_fattebert_gygi(rho_elec, norm_drho_elec, dtheta, &
1146 epsilon_solvent, beta, rho_zero, delta_rho)
1148 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, norm_drho_elec, dtheta
1149 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, beta, rho_zero, &
1152 CHARACTER(LEN=*),
PARAMETER :: routinen =
'surface_fattebert_gygi'
1153 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
1155 INTEGER :: handle, i, j, k, l
1156 INTEGER,
DIMENSION(3) :: lb, ub
1157 REAL(kind=dp) :: e, eps_elec, f, p, q, rho, s, t, twobeta
1158 REAL(kind=dp),
DIMENSION(2) :: theta
1160 CALL timeset(routinen, handle)
1162 e = epsilon_solvent - 1.0_dp
1165 twobeta = 2.0_dp*beta
1167 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
1168 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
1179 rho = rho_elec%array(i, j, k) + (real(l, kind=dp) - 1.5_dp)*delta_rho
1180 IF (rho < rhotol)
THEN
1181 eps_elec = epsilon_solvent
1185 t = 1.0_dp/(1.0_dp + p)
1186 eps_elec = 1.0_dp + f*(1.0_dp + (1.0_dp - p)*t)
1188 theta(l) = (epsilon_solvent - eps_elec)/e
1190 dtheta%array(i, j, k) = (theta(2) - theta(1))*norm_drho_elec%array(i, j, k)/delta_rho
1196 CALL timestop(handle)
1198 END SUBROUTINE surface_fattebert_gygi
1212 TYPE(qs_energy_type),
POINTER :: energy
1213 TYPE(sccs_control_type),
POINTER :: sccs_control
1214 INTEGER,
INTENT(IN) :: output_unit
1216 IF (output_unit > 0)
THEN
1217 cpassert(
ASSOCIATED(energy))
1218 cpassert(
ASSOCIATED(sccs_control))
1219 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1220 "SCCS| Hartree energy of solute and solvent [Hartree]", energy%sccs_hartree, &
1221 "SCCS| Hartree energy of the solute only [Hartree]", energy%hartree
1222 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14,/,T3,A,T61,F20.3)") &
1223 "SCCS| Polarisation energy [Hartree]", energy%sccs_pol, &
1224 "SCCS| [kcal/mol]", &
1225 cp_unit_from_cp2k(energy%sccs_pol,
"kcalmol"), &
1226 "SCCS| Cavitation energy [Hartree]", energy%sccs_cav, &
1227 "SCCS| [kcal/mol]", &
1228 cp_unit_from_cp2k(energy%sccs_cav,
"kcalmol"), &
1229 "SCCS| Dispersion free energy [Hartree]", energy%sccs_dis, &
1230 "SCCS| [kcal/mol]", &
1231 cp_unit_from_cp2k(energy%sccs_dis,
"kcalmol"), &
1232 "SCCS| Repulsion free energy [Hartree]", energy%sccs_rep, &
1233 "SCCS| [kcal/mol]", &
1234 cp_unit_from_cp2k(energy%sccs_rep,
"kcalmol"), &
1235 "SCCS| Solvation free energy [Hartree]", energy%sccs_sol, &
1236 "SCCS| [kcal/mol]", &
1237 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_pp, 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, harris_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, eeq, rhs, do_rixs, tb_tblite)
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
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represents a system: atoms, molecules, their pos,vel,...
stores all the informations relevant to an mpi environment
represent a list of objects
contained for different pw related things
environment for the poisson solver
to create arrays of pools
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
keeps the density in various representations, keeping track of which ones are valid.