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
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
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
223 density=rho_tot_gspace, &
224 ehartree=energy%hartree, &
225 vhartree=v_hartree_gspace, &
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))
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)
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
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))
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")
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_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)
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.