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 do_kpoints, 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, &
185 do_kpoints=do_kpoints, &
194 sccs_control => dft_control%sccs_control
196 cpassert(
ASSOCIATED(qs_env))
199 cpwarn(
"SCCS with k-points has not yet been fully validated")
202 IF (
PRESENT(h_stress))
THEN
203 calculate_stress_tensor = .true.
204 h_stress(:, :) = 0.0_dp
205 cpwarn(
"The stress tensor for SCCS has not yet been fully validated")
207 calculate_stress_tensor = .false.
212 auxbas_pw_pool=auxbas_pw_pool, &
214 poisson_env=poisson_env)
219 IF (.NOT. sccs_control%sccs_activated)
THEN
220 IF (sccs_control%eps_scf > 0.0_dp)
THEN
221 IF ((scf_env%iter_delta > sccs_control%eps_scf) .OR. &
222 ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
223 (qs_env%scf_env%iter_count <= 1)))
THEN
224 IF (calculate_stress_tensor)
THEN
227 density=rho_tot_gspace, &
228 ehartree=energy%hartree, &
229 vhartree=v_hartree_gspace, &
233 density=rho_tot_gspace, &
234 ehartree=energy%hartree, &
235 vhartree=v_hartree_gspace)
237 energy%sccs_pol = 0.0_dp
238 energy%sccs_cav = 0.0_dp
239 energy%sccs_dis = 0.0_dp
240 energy%sccs_rep = 0.0_dp
241 energy%sccs_sol = 0.0_dp
242 energy%sccs_hartree = energy%hartree
243 CALL timestop(handle)
247 sccs_control%sccs_activated = .true.
250 nspin = dft_control%nspins
254 print_level = logger%iter_info%print_level
255 print_path =
"DFT%PRINT%SCCS"
260 ignore_should_output=should_output, &
261 log_filename=.false.)
266 rho_r_sccs=rho_pw_r_sccs)
269 cpassert(
ASSOCIATED(rho_pw_r_sccs))
274 CALL auxbas_pw_pool%create_pw(rho_elec)
277 ngpts = rho_elec%pw_grid%ngpts
278 dvol = rho_elec%pw_grid%dvol
279 cell_volume = rho_elec%pw_grid%vol
280 abc(1:3) = real(rho_elec%pw_grid%npts(1:3), kind=
dp)*rho_elec%pw_grid%dr(1:3)
281 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
282 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
284 CALL pw_copy(rho_pw_r(1), rho_elec)
286 CALL pw_axpy(rho_pw_r(ispin), rho_elec)
291 CALL auxbas_pw_pool%create_pw(eps_elec)
292 CALL auxbas_pw_pool%create_pw(deps_elec)
294 epsilon_solvent = sccs_control%epsilon_solvent
295 SELECT CASE (sccs_control%method_id)
297 CALL andreussi(rho_elec, eps_elec, deps_elec, epsilon_solvent, sccs_control%rho_max, &
298 sccs_control%rho_min)
300 CALL fattebert_gygi(rho_elec, eps_elec, deps_elec, epsilon_solvent, sccs_control%beta, &
301 sccs_control%rho_zero)
303 cpabort(
"Invalid method specified for SCCS model")
307 filename =
"DIELECTRIC_FUNCTION"
308 cube_path = trim(print_path)//
"%"//trim(filename)
312 my_pos_cube =
"REWIND"
313 IF (append_cube) my_pos_cube =
"APPEND"
316 extension=
".cube", middle_name=trim(filename), &
317 file_position=my_pos_cube, log_filename=.false., &
318 mpi_io=mpi_io, fout=mpi_filename)
319 IF (output_unit > 0)
THEN
320 IF (.NOT. mpi_io)
THEN
321 INQUIRE (unit=cube_unit, name=filename)
323 filename = mpi_filename
325 WRITE (unit=output_unit, fmt=
"(T3,A)") &
326 "SCCS| The dielectric function is written in cube file format to the file:", &
327 "SCCS| "//trim(filename)
329 CALL cp_pw_to_cube(eps_elec, cube_unit, trim(filename), particles=particles, &
336 cavity_surface = 0.0_dp
337 cavity_volume = 0.0_dp
339 IF (abs(epsilon_solvent - 1.0_dp) > epstol)
THEN
344 CALL auxbas_pw_pool%create_pw(theta)
348 f = 1.0_dp/(epsilon_solvent - 1.0_dp)
355 theta%array(i, j, k) = f*(epsilon_solvent - eps_elec%array(i, j, k))
365 CALL auxbas_pw_pool%create_pw(drho_elec(i))
369 CALL auxbas_pw_pool%create_pw(norm_drho_elec)
378 norm_drho_elec%array(i, j, k) = sqrt(drho_elec(1)%array(i, j, k)* &
379 drho_elec(1)%array(i, j, k) + &
380 drho_elec(2)%array(i, j, k)* &
381 drho_elec(2)%array(i, j, k) + &
382 drho_elec(3)%array(i, j, k)* &
383 drho_elec(3)%array(i, j, k))
390 filename =
"DENSITY_GRADIENT"
391 cube_path = trim(print_path)//
"%"//trim(filename)
395 my_pos_cube =
"REWIND"
396 IF (append_cube) my_pos_cube =
"APPEND"
399 extension=
".cube", middle_name=trim(filename), &
400 file_position=my_pos_cube, log_filename=.false., &
401 mpi_io=mpi_io, fout=mpi_filename)
402 IF (output_unit > 0)
THEN
403 IF (.NOT. mpi_io)
THEN
404 INQUIRE (unit=cube_unit, name=filename)
406 filename = mpi_filename
408 WRITE (unit=output_unit, fmt=
"(T3,A)") &
409 "SCCS| The norm of the density gradient is written in cube file format to the file:", &
410 "SCCS| "//trim(filename)
412 CALL cp_pw_to_cube(norm_drho_elec, cube_unit, trim(filename), particles=particles, &
419 SELECT CASE (sccs_control%method_id)
421 CALL surface_andreussi(rho_elec, norm_drho_elec, theta, epsilon_solvent, &
422 sccs_control%rho_max, sccs_control%rho_min, &
423 sccs_control%delta_rho)
425 CALL surface_fattebert_gygi(rho_elec, norm_drho_elec, theta, epsilon_solvent, &
426 sccs_control%beta, sccs_control%rho_zero, &
427 sccs_control%delta_rho)
429 cpabort(
"Invalid method specified for SCCS model")
434 CALL auxbas_pw_pool%give_back_pw(theta)
435 CALL auxbas_pw_pool%give_back_pw(norm_drho_elec)
437 CALL auxbas_pw_pool%give_back_pw(drho_elec(i))
443 CALL auxbas_pw_pool%give_back_pw(rho_elec)
447 TYPE(pw_r3d_rs_type) :: rho_tot, phi_tot, rho_solute, rho_tot_zero
449 CALL auxbas_pw_pool%create_pw(rho_solute)
450 CALL pw_zero(rho_solute)
451 CALL pw_transfer(rho_tot_gspace, rho_solute)
452 tot_rho_solute = pw_integrate_function(rho_solute)
455 IF (abs(tot_rho_solute) >= 1.0e-6_dp)
THEN
456 IF ((poisson_env%parameters%solver /= pw_poisson_analytic) .AND. &
457 (poisson_env%parameters%solver /= pw_poisson_mt))
THEN
458 WRITE (unit=message, fmt=
"(A,SP,F0.6,A)") &
459 "The system (solute) has a non-negligible charge of ", -tot_rho_solute, &
460 ". It is recommended to use non-periodic boundary conditions (PERIODIC none) "// &
461 "combined with an appropriate Poisson solver (POISSON_SOLVER MT or analytic)"
467 CALL auxbas_pw_pool%create_pw(rho_tot_zero)
478 IF (eps_elec%array(i, j, k) < 1.0_dp)
THEN
479 WRITE (unit=message, fmt=
"(A,ES12.3,A,3(I0,A))") &
480 "SCCS| Invalid dielectric function value ", eps_elec%array(i, j, k), &
481 " encountered at grid point (", i,
",", j,
",", k,
")"
484 rho_tot_zero%array(i, j, k) = rho_solute%array(i, j, k)/eps_elec%array(i, j, k)
485 eps_elec%array(i, j, k) = log(eps_elec%array(i, j, k))
493 CALL auxbas_pw_pool%create_pw(dln_eps_elec(i))
494 CALL pw_zero(dln_eps_elec(i))
496 CALL derive(eps_elec, dln_eps_elec, sccs_control%derivative_method, pw_env, input)
497 CALL auxbas_pw_pool%give_back_pw(eps_elec)
500 IF (should_output .AND. (output_unit > 0))
THEN
501 IF (print_level > low_print_level)
THEN
502 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.12)") &
503 "SCCS| Total electronic charge density ", -tot_rho_elec, &
504 "SCCS| Total charge density (solute) ", -tot_rho_solute
505 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.3)") &
506 "SCCS| Volume of the cell [bohr^3]", cell_volume, &
507 "SCCS| [angstrom^3]", &
508 cp_unit_from_cp2k(cell_volume,
"angstrom^3")
509 IF (abs(epsilon_solvent - 1.0_dp) > epstol)
THEN
510 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.3)") &
511 "SCCS| Volume of the solute cavity [bohr^3]", cavity_volume, &
512 "SCCS| [angstrom^3]", &
513 cp_unit_from_cp2k(cavity_volume,
"angstrom^3"), &
514 "SCCS| Surface of the solute cavity [bohr^2]", cavity_surface, &
515 "SCCS| [angstrom^2]", &
516 cp_unit_from_cp2k(cavity_surface,
"angstrom^2")
518 WRITE (unit=output_unit, fmt=
"(T3,A)") &
520 "SCCS| Step Average residual Maximum residual E(Hartree) [a.u.]"
526 CALL auxbas_pw_pool%create_pw(dphi_tot(i))
530 CALL auxbas_pw_pool%create_pw(rho_tot)
531 CALL pw_copy(rho_tot_zero, rho_tot)
532 CALL pw_axpy(rho_pw_r_sccs, rho_tot)
534 CALL auxbas_pw_pool%create_pw(phi_tot)
535 CALL pw_zero(phi_tot)
546 IF (iter > sccs_control%max_iter)
THEN
547 IF (output_unit > 0)
THEN
548 WRITE (unit=output_unit, fmt=
"(T3,A,/,T3,A,I0,A)") &
549 "SCCS| Maximum number of SCCS iterations reached", &
550 "SCCS| Iteration cycle did not converge in ", sccs_control%max_iter,
" steps"
552 WRITE (unit=message, fmt=
"(A,I0,A)") &
553 "The SCCS iteration cycle did not converge in ", sccs_control%max_iter,
" steps"
560 CALL pw_poisson_solve(poisson_env=poisson_env, &
564 energy%sccs_hartree = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
569 rho_delta_avg = 0.0_dp
570 rho_delta_max = 0.0_dp
580 rho_iter_new = (dln_eps_elec(1)%array(i, j, k)*dphi_tot(1)%array(i, j, k) + &
581 dln_eps_elec(2)%array(i, j, k)*dphi_tot(2)%array(i, j, k) + &
582 dln_eps_elec(3)%array(i, j, k)*dphi_tot(3)%array(i, j, k))*f
583 rho_iter_new = rho_pw_r_sccs%array(i, j, k) + &
584 sccs_control%mixing*(rho_iter_new - rho_pw_r_sccs%array(i, j, k))
585 rho_delta = abs(rho_iter_new - rho_pw_r_sccs%array(i, j, k))
586 rho_delta_max = max(rho_delta, rho_delta_max)
587 rho_delta_avg = rho_delta_avg + rho_delta
588 rho_tot%array(i, j, k) = rho_tot_zero%array(i, j, k) + rho_iter_new
589 rho_pw_r_sccs%array(i, j, k) = rho_iter_new
595 CALL para_env%sum(rho_delta_avg)
596 rho_delta_avg = rho_delta_avg/real(ngpts, kind=dp)
597 CALL para_env%max(rho_delta_max)
599 IF (should_output .AND. (output_unit > 0))
THEN
600 IF (print_level > low_print_level)
THEN
601 IF ((abs(rho_delta_avg) < 1.0e-8_dp) .OR. &
602 (abs(rho_delta_avg) >= 1.0e5_dp))
THEN
603 WRITE (unit=output_unit, fmt=
"(T3,A,I6,4X,ES16.4,4X,ES16.4,1X,F25.12)") &
604 "SCCS| ", iter, rho_delta_avg, rho_delta_max, energy%sccs_hartree
606 WRITE (unit=output_unit, fmt=
"(T3,A,I6,4X,F16.8,4X,F16.8,1X,F25.12)") &
607 "SCCS| ", iter, rho_delta_avg, rho_delta_max, energy%sccs_hartree
613 IF (rho_delta_max <= sccs_control%eps_sccs)
THEN
614 IF (should_output .AND. (output_unit > 0))
THEN
615 WRITE (unit=output_unit, fmt=
"(T3,A,I0,A)") &
616 "SCCS| Iteration cycle converged in ", iter,
" steps"
624 CALL auxbas_pw_pool%give_back_pw(rho_tot_zero)
626 CALL auxbas_pw_pool%give_back_pw(dln_eps_elec(i))
630 filename =
"TOTAL_CHARGE_DENSITY"
631 cube_path = trim(print_path)//
"%"//trim(filename)
632 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), cp_p_file))
THEN
633 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
634 my_pos_cube =
"REWIND"
635 IF (append_cube) my_pos_cube =
"APPEND"
637 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
638 extension=
".cube", middle_name=trim(filename), &
639 file_position=my_pos_cube, log_filename=.false., &
640 mpi_io=mpi_io, fout=mpi_filename)
641 IF (output_unit > 0)
THEN
642 IF (.NOT. mpi_io)
THEN
643 INQUIRE (unit=cube_unit, name=filename)
645 filename = mpi_filename
647 WRITE (unit=output_unit, fmt=
"(T3,A)") &
648 "SCCS| The total SCCS charge density is written in cube file format to the file:", &
649 "SCCS| "//trim(filename)
651 CALL cp_pw_to_cube(rho_tot, cube_unit, trim(filename), particles=particles, &
652 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
653 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
658 CALL pw_transfer(rho_tot, rho_tot_gspace)
659 IF (calculate_stress_tensor)
THEN
661 CALL pw_poisson_solve(poisson_env=poisson_env, &
662 density=rho_tot_gspace, &
664 vhartree=v_hartree_gspace, &
665 dvhartree=dphi_tot, &
668 CALL pw_poisson_solve(poisson_env=poisson_env, &
669 density=rho_tot_gspace, &
671 vhartree=v_hartree_gspace, &
674 CALL pw_transfer(v_hartree_gspace, phi_tot)
675 energy%sccs_hartree = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
679 TYPE(pw_r3d_rs_type) :: phi_solute
680 CALL auxbas_pw_pool%create_pw(phi_solute)
681 CALL pw_zero(phi_solute)
682 CALL pw_poisson_solve(poisson_env=poisson_env, &
683 density=rho_solute, &
684 ehartree=energy%hartree, &
689 CALL pw_axpy(phi_solute, phi_tot, alpha=-1.0_dp)
690 CALL auxbas_pw_pool%give_back_pw(phi_solute)
694 filename =
"POLARISATION_POTENTIAL"
695 cube_path = trim(print_path)//
"%"//trim(filename)
696 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), &
698 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
699 my_pos_cube =
"REWIND"
700 IF (append_cube) my_pos_cube =
"APPEND"
702 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
703 extension=
".cube", middle_name=trim(filename), &
704 file_position=my_pos_cube, log_filename=.false., &
705 mpi_io=mpi_io, fout=mpi_filename)
706 IF (output_unit > 0)
THEN
707 IF (.NOT. mpi_io)
THEN
708 INQUIRE (unit=cube_unit, name=filename)
710 filename = mpi_filename
712 WRITE (unit=output_unit, fmt=
"(T3,A)") &
713 "SCCS| The SCCS polarisation potential is written in cube file format to the file:", &
714 "SCCS| "//trim(filename)
716 CALL cp_pw_to_cube(phi_tot, cube_unit, trim(filename), particles=particles, &
717 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
718 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
723 CALL pw_axpy(rho_solute, rho_tot, alpha=-1.0_dp)
724 polarisation_charge = pw_integrate_function(rho_tot)
727 filename =
"POLARISATION_CHARGE_DENSITY"
728 cube_path = trim(print_path)//
"%"//trim(filename)
729 IF (btest(cp_print_key_should_output(logger%iter_info, input, trim(cube_path)), &
731 append_cube = section_get_lval(input, trim(cube_path)//
"%APPEND")
732 my_pos_cube =
"REWIND"
733 IF (append_cube) my_pos_cube =
"APPEND"
735 cube_unit = cp_print_key_unit_nr(logger, input, trim(cube_path), &
736 extension=
".cube", middle_name=trim(filename), &
737 file_position=my_pos_cube, log_filename=.false., &
738 mpi_io=mpi_io, fout=mpi_filename)
739 IF (output_unit > 0)
THEN
740 IF (.NOT. mpi_io)
THEN
741 INQUIRE (unit=cube_unit, name=filename)
743 filename = mpi_filename
745 WRITE (unit=output_unit, fmt=
"(T3,A)") &
746 "SCCS| The SCCS polarisation charge density is written in cube file format to the file:", &
747 "SCCS| "//trim(filename)
749 CALL cp_pw_to_cube(rho_tot, cube_unit, trim(filename), particles=particles, &
750 stride=section_get_ivals(input, trim(cube_path)//
"%STRIDE"), mpi_io=mpi_io)
751 CALL cp_print_key_finished_output(cube_unit, logger, input, trim(cube_path), mpi_io=mpi_io)
755 energy%sccs_pol = 0.5_dp*pw_integral_ab(rho_solute, phi_tot)
756 CALL auxbas_pw_pool%give_back_pw(rho_solute)
757 CALL auxbas_pw_pool%give_back_pw(phi_tot)
758 CALL auxbas_pw_pool%give_back_pw(rho_tot)
762 energy%sccs_cav = sccs_control%gamma_solvent*cavity_surface
763 energy%sccs_dis = sccs_control%beta_solvent*cavity_volume
764 energy%sccs_rep = sccs_control%alpha_solvent*cavity_surface
766 energy%sccs_sol = energy%sccs_pol + energy%sccs_rep + energy%sccs_cav + energy%sccs_dis
768 IF (should_output .AND. (output_unit > 0))
THEN
769 WRITE (unit=output_unit, fmt=
"(T3,A)") &
771 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.12)") &
772 "SCCS| Polarisation charge", polarisation_charge
774 WRITE (unit=output_unit, fmt=
"(T3,A)") &
780 f = -0.5_dp*dvol/fourpi
788 dphi2 = dphi_tot(1)%array(i, j, k)*dphi_tot(1)%array(i, j, k) + &
789 dphi_tot(2)%array(i, j, k)*dphi_tot(2)%array(i, j, k) + &
790 dphi_tot(3)%array(i, j, k)*dphi_tot(3)%array(i, j, k)
791 v_sccs%array(i, j, k) = v_sccs%array(i, j, k) + f*deps_elec%array(i, j, k)*dphi2
797 CALL auxbas_pw_pool%give_back_pw(deps_elec)
799 CALL auxbas_pw_pool%give_back_pw(dphi_tot(i))
803 CALL cp_print_key_finished_output(output_unit, logger, input, trim(print_path), &
804 ignore_should_output=should_output)
806 CALL timestop(handle)
824 SUBROUTINE andreussi(rho_elec, eps_elec, deps_elec, epsilon_solvent, rho_max, &
827 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, eps_elec, deps_elec
828 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, rho_max, rho_min
830 CHARACTER(LEN=*),
PARAMETER :: routinen =
'andreussi'
831 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
833 INTEGER :: handle, i, j, k
834 INTEGER,
DIMENSION(3) :: lb, ub
835 REAL(kind=dp) :: diff, dq, dt, f, ln_rho_max, ln_rho_min, &
838 CALL timeset(routinen, handle)
840 f = log(epsilon_solvent)/twopi
841 diff = rho_max - rho_min
842 IF (diff < sqrt(rhotol)) cpabort(
"SCCS: Difference between rho(min) and rho(max) is too small")
843 IF (rho_min >= rhotol)
THEN
844 ln_rho_max = log(rho_max)
845 ln_rho_min = log(rho_min)
846 q = twopi/(ln_rho_max - ln_rho_min)
850 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
851 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
861 rho = rho_elec%array(i, j, k)
862 IF (rho < rho_min)
THEN
863 eps_elec%array(i, j, k) = epsilon_solvent
864 deps_elec%array(i, j, k) = 0.0_dp
865 ELSE IF (rho <= rho_max)
THEN
867 y = q*(ln_rho_max - x)
869 eps_elec%array(i, j, k) = exp(t)
870 dt = dq*(1.0_dp - cos(y))
871 deps_elec%array(i, j, k) = eps_elec%array(i, j, k)*dt/rho
873 eps_elec%array(i, j, k) = 1.0_dp
874 deps_elec%array(i, j, k) = 0.0_dp
881 CALL timestop(handle)
883 END SUBROUTINE andreussi
898 SUBROUTINE fattebert_gygi(rho_elec, eps_elec, deps_elec, epsilon_solvent, beta, &
901 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, eps_elec, deps_elec
902 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, beta, rho_zero
904 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fattebert_gygi'
905 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
907 INTEGER :: handle, i, j, k
908 INTEGER,
DIMENSION(3) :: lb, ub
909 REAL(kind=dp) :: df, f, p, q, rho, s, t, twobeta
911 CALL timeset(routinen, handle)
913 df = (1.0_dp - epsilon_solvent)/rho_zero
914 f = 0.5_dp*(epsilon_solvent - 1.0_dp)
916 twobeta = 2.0_dp*beta
918 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
919 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
929 rho = rho_elec%array(i, j, k)
930 IF (rho < rhotol)
THEN
931 eps_elec%array(i, j, k) = epsilon_solvent
932 deps_elec%array(i, j, k) = 0.0_dp
936 t = 1.0_dp/(1.0_dp + p)
937 eps_elec%array(i, j, k) = 1.0_dp + f*(1.0_dp + (1.0_dp - p)*t)
938 deps_elec%array(i, j, k) = df*twobeta*t*t*p/s
945 CALL timestop(handle)
947 END SUBROUTINE fattebert_gygi
961 SUBROUTINE derive(f, df, method, pw_env, input)
963 TYPE(pw_r3d_rs_type),
INTENT(IN) :: f
964 TYPE(pw_r3d_rs_type),
DIMENSION(3),
INTENT(INOUT) :: df
965 INTEGER,
INTENT(IN) :: method
966 TYPE(pw_env_type),
POINTER :: pw_env
967 TYPE(section_vals_type),
POINTER :: input
969 CHARACTER(LEN=*),
PARAMETER :: routinen =
'derive'
971 INTEGER :: border_points, handle, i
972 INTEGER,
DIMENSION(3) :: lb, n, ub
973 TYPE(pw_c1d_gs_type),
DIMENSION(2) :: work_g1d
974 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool
975 TYPE(realspace_grid_desc_type),
POINTER :: rs_desc
976 TYPE(realspace_grid_input_type) :: input_settings
977 TYPE(realspace_grid_type),
POINTER :: rs_grid
978 TYPE(section_vals_type),
POINTER :: rs_grid_section
980 CALL timeset(routinen, handle)
982 cpassert(
ASSOCIATED(pw_env))
986 CASE (sccs_derivative_cd3, sccs_derivative_cd5, sccs_derivative_cd7)
988 rs_grid_section => section_vals_get_subs_vals(input,
"DFT%MGRID%RS_GRID")
990 CASE (sccs_derivative_cd3)
992 CASE (sccs_derivative_cd5)
994 CASE (sccs_derivative_cd7)
997 CALL init_input_type(input_settings, 2*border_points + 1, rs_grid_section, &
999 CALL rs_grid_create_descriptor(rs_desc, f%pw_grid, input_settings, &
1000 border_points=border_points)
1002 CALL rs_grid_create(rs_grid, rs_desc)
1004 CASE (sccs_derivative_fft)
1005 lb(1:3) = f%pw_grid%bounds_local(1, 1:3)
1006 ub(1:3) = f%pw_grid%bounds_local(2, 1:3)
1007 NULLIFY (auxbas_pw_pool)
1008 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1010 DO i = 1,
SIZE(work_g1d)
1011 CALL auxbas_pw_pool%create_pw(work_g1d(i))
1016 SELECT CASE (method)
1017 CASE (sccs_derivative_cd3)
1018 CALL derive_fdm_cd3(f, df, rs_grid)
1019 CASE (sccs_derivative_cd5)
1020 CALL derive_fdm_cd5(f, df, rs_grid)
1021 CASE (sccs_derivative_cd7)
1022 CALL derive_fdm_cd7(f, df, rs_grid)
1023 CASE (sccs_derivative_fft)
1025 CALL pw_transfer(f, work_g1d(1))
1029 CALL pw_copy(work_g1d(1), work_g1d(2))
1030 CALL pw_derive(work_g1d(2), n(:))
1031 CALL pw_transfer(work_g1d(2), df(i))
1034 cpabort(
"Invalid derivative method for SCCS specified")
1038 SELECT CASE (method)
1039 CASE (sccs_derivative_cd3, sccs_derivative_cd5, sccs_derivative_cd7)
1040 CALL rs_grid_release(rs_grid)
1041 DEALLOCATE (rs_grid)
1042 CALL rs_grid_release_descriptor(rs_desc)
1043 CASE (sccs_derivative_fft)
1044 DO i = 1,
SIZE(work_g1d)
1045 CALL auxbas_pw_pool%give_back_pw(work_g1d(i))
1049 CALL timestop(handle)
1051 END SUBROUTINE derive
1070 SUBROUTINE surface_andreussi(rho_elec, norm_drho_elec, dtheta, &
1071 epsilon_solvent, rho_max, rho_min, delta_rho)
1073 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, norm_drho_elec, dtheta
1074 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, rho_max, rho_min, &
1077 CHARACTER(LEN=*),
PARAMETER :: routinen =
'surface_andreussi'
1078 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
1080 INTEGER :: handle, i, j, k, l
1081 INTEGER,
DIMENSION(3) :: lb, ub
1082 REAL(kind=dp) :: diff, e, eps_elec, f, ln_rho_max, &
1083 ln_rho_min, q, rho, t, x, y
1084 REAL(kind=dp),
DIMENSION(2) :: theta
1086 CALL timeset(routinen, handle)
1088 e = epsilon_solvent - 1.0_dp
1089 f = log(epsilon_solvent)/twopi
1090 diff = rho_max - rho_min
1091 IF (diff < sqrt(rhotol)) cpabort(
"SCCS: Difference between rho(min) and rho(max) is too small")
1092 IF (rho_min >= rhotol)
THEN
1093 ln_rho_max = log(rho_max)
1094 ln_rho_min = log(rho_min)
1095 q = twopi/(ln_rho_max - ln_rho_min)
1098 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
1099 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
1110 rho = rho_elec%array(i, j, k) + (real(l, kind=dp) - 1.5_dp)*delta_rho
1111 IF (rho < rho_min)
THEN
1112 eps_elec = epsilon_solvent
1113 ELSE IF (rho <= rho_max)
THEN
1115 y = q*(ln_rho_max - x)
1121 theta(l) = (epsilon_solvent - eps_elec)/e
1123 dtheta%array(i, j, k) = (theta(2) - theta(1))*norm_drho_elec%array(i, j, k)/delta_rho
1129 CALL timestop(handle)
1131 END SUBROUTINE surface_andreussi
1150 SUBROUTINE surface_fattebert_gygi(rho_elec, norm_drho_elec, dtheta, &
1151 epsilon_solvent, beta, rho_zero, delta_rho)
1153 TYPE(pw_r3d_rs_type),
INTENT(IN) :: rho_elec, norm_drho_elec, dtheta
1154 REAL(kind=dp),
INTENT(IN) :: epsilon_solvent, beta, rho_zero, &
1157 CHARACTER(LEN=*),
PARAMETER :: routinen =
'surface_fattebert_gygi'
1158 REAL(kind=dp),
PARAMETER :: rhotol = 1.0e-12_dp
1160 INTEGER :: handle, i, j, k, l
1161 INTEGER,
DIMENSION(3) :: lb, ub
1162 REAL(kind=dp) :: e, eps_elec, f, p, q, rho, s, t, twobeta
1163 REAL(kind=dp),
DIMENSION(2) :: theta
1165 CALL timeset(routinen, handle)
1167 e = epsilon_solvent - 1.0_dp
1170 twobeta = 2.0_dp*beta
1172 lb(1:3) = rho_elec%pw_grid%bounds_local(1, 1:3)
1173 ub(1:3) = rho_elec%pw_grid%bounds_local(2, 1:3)
1184 rho = rho_elec%array(i, j, k) + (real(l, kind=dp) - 1.5_dp)*delta_rho
1185 IF (rho < rhotol)
THEN
1186 eps_elec = epsilon_solvent
1190 t = 1.0_dp/(1.0_dp + p)
1191 eps_elec = 1.0_dp + f*(1.0_dp + (1.0_dp - p)*t)
1193 theta(l) = (epsilon_solvent - eps_elec)/e
1195 dtheta%array(i, j, k) = (theta(2) - theta(1))*norm_drho_elec%array(i, j, k)/delta_rho
1201 CALL timestop(handle)
1203 END SUBROUTINE surface_fattebert_gygi
1217 TYPE(qs_energy_type),
POINTER :: energy
1218 TYPE(sccs_control_type),
POINTER :: sccs_control
1219 INTEGER,
INTENT(IN) :: output_unit
1221 IF (output_unit > 0)
THEN
1222 cpassert(
ASSOCIATED(energy))
1223 cpassert(
ASSOCIATED(sccs_control))
1224 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1225 "SCCS| Hartree energy of solute and solvent [Hartree]", energy%sccs_hartree, &
1226 "SCCS| Hartree energy of the solute only [Hartree]", energy%hartree
1227 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14,/,T3,A,T61,F20.3)") &
1228 "SCCS| Polarisation energy [Hartree]", energy%sccs_pol, &
1229 "SCCS| [kcal/mol]", &
1230 cp_unit_from_cp2k(energy%sccs_pol,
"kcalmol"), &
1231 "SCCS| Cavitation energy [Hartree]", energy%sccs_cav, &
1232 "SCCS| [kcal/mol]", &
1233 cp_unit_from_cp2k(energy%sccs_cav,
"kcalmol"), &
1234 "SCCS| Dispersion free energy [Hartree]", energy%sccs_dis, &
1235 "SCCS| [kcal/mol]", &
1236 cp_unit_from_cp2k(energy%sccs_dis,
"kcalmol"), &
1237 "SCCS| Repulsion free energy [Hartree]", energy%sccs_rep, &
1238 "SCCS| [kcal/mol]", &
1239 cp_unit_from_cp2k(energy%sccs_rep,
"kcalmol"), &
1240 "SCCS| Solvation free energy [Hartree]", energy%sccs_sol, &
1241 "SCCS| [kcal/mol]", &
1242 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, zeff, stride, max_file_size_mb, 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, cell_ref, use_ref_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, mimic, 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, sab_cneo, 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, xcint_weights, 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, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_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.