25 ewald_environment_type,&
49 #include "./base/base_uses.f90"
54 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
55 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qmmm_per_elpot'
82 pgfs, qm_cell_small, mm_cell, para_env, compatibility, qmmm_periodic, print_section, &
83 eps_mm_rspace, maxchrg, ncp, ncpl)
84 INTEGER,
INTENT(IN) :: qmmm_coupl_type
85 TYPE(qmmm_per_pot_p_type),
DIMENSION(:),
POINTER :: per_potentials
86 TYPE(qmmm_pot_p_type),
DIMENSION(:),
POINTER :: potentials
87 TYPE(qmmm_gaussian_p_type),
DIMENSION(:),
POINTER :: pgfs
88 TYPE(cell_type),
POINTER :: qm_cell_small, mm_cell
89 TYPE(mp_para_env_type),
POINTER :: para_env
90 LOGICAL,
INTENT(IN) :: compatibility
91 TYPE(section_vals_type),
POINTER :: qmmm_periodic, print_section
92 REAL(kind=
dp),
INTENT(IN) :: eps_mm_rspace, maxchrg
93 INTEGER,
INTENT(IN) :: ncp(3), ncpl(3)
95 INTEGER :: i, idim, ig, ig_start, iw, ix, iy, iz, &
96 k, kmax(3), n_rep_real(3), &
97 n_rep_real_val, ncoarsel, ncoarset, &
99 INTEGER,
DIMENSION(:),
POINTER :: mm_atom_index
100 REAL(kind=
dp) :: ak, alpha, box(3),
fac(3), fs, g, g2, &
101 gk, gmax, mymaxradius, npl, npt, &
102 prefactor, rc, rc2, rmax, tmp, vec(3), &
104 REAL(kind=
dp),
DIMENSION(:),
POINTER :: gx, gy, gz, lg
105 TYPE(cp_logger_type),
POINTER :: logger
106 TYPE(qmmm_gaussian_type),
POINTER :: pgf
108 NULLIFY (lg, gx, gy, gz)
109 ncoarset = product(ncp)
110 ncoarsel = product(ncpl)
113 rmax = sqrt(mm_cell%hmat(1, 1)**2 + &
114 mm_cell%hmat(2, 2)**2 + &
115 mm_cell%hmat(3, 3)**2)
118 fac = 2.0e0_dp*
pi/(/mm_cell%hmat(1, 1), mm_cell%hmat(2, 2), mm_cell%hmat(3, 3)/)
119 kmax = ceiling(gmax/
fac)
120 vol = mm_cell%hmat(1, 1)* &
121 mm_cell%hmat(2, 2)* &
123 ndim = (kmax(1) + 1)*(2*kmax(2) + 1)*(2*kmax(3) + 1)
125 n_rep_real = n_rep_real_val
126 IF (compatibility .AND. (qmmm_coupl_type ==
do_qmmm_gauss)) ig_start = 2
128 cpassert(.NOT.
ASSOCIATED(per_potentials))
129 ALLOCATE (per_potentials(
SIZE(pgfs)))
130 cpassert(
SIZE(pgfs) ==
SIZE(potentials))
131 potential_type:
DO k = 1,
SIZE(pgfs)
133 rc = pgfs(k)%pgf%Elp_Radius
134 ALLOCATE (per_potentials(k)%Pot)
135 SELECT CASE (qmmm_coupl_type)
151 SELECT CASE (qmmm_coupl_type)
159 DO iy = -kmax(2), kmax(2)
160 DO iz = -kmax(3), kmax(3)
162 IF (ix == 0 .AND. iy == 0 .AND. iz == 0)
THEN
163 DO ig = ig_start, pgf%number_of_gaussians
165 ak = pgf%Ak(ig)*
pi**(3.0_dp/2.0_dp)*gk**3.0_dp
166 lg(idim) = lg(idim) - ak
169 fs = 2.0_dp;
IF (ix == 0) fs = 1.0_dp
170 vec =
fac*(/real(ix, kind=
dp), real(iy, kind=
dp), real(iz, kind=
dp)/)
171 g2 = dot_product(vec, vec)
175 lg(idim) = 4.0_dp*
pi/g2*exp(-(g2*rc2)/4.0_dp)
178 lg(idim) = 4.0_dp*
pi*tmp**2/(g2*(g2 + tmp)**2)
180 DO ig = ig_start, pgf%number_of_gaussians
182 ak = pgf%Ak(ig)*
pi**(3.0_dp/2.0_dp)*gk**3.0_dp
183 lg(idim) = lg(idim) - ak*exp(-(g*gk)**2.0_dp/4.0_dp)
186 lg(idim) = fs*lg(idim)*1.0_dp/vol
187 gx(idim) =
fac(1)*real(ix, kind=
dp)
188 gy(idim) =
fac(2)*real(iy, kind=
dp)
189 gz(idim) =
fac(3)*real(iz, kind=
dp)
194 IF (all(n_rep_real == -1))
THEN
196 DO i = 1, pgf%number_of_gaussians
197 IF (pgf%Gk(i) /= 0.0_dp)
THEN
198 alpha = 1.0_dp/pgf%Gk(i)
200 prefactor = pgf%Ak(i)*maxchrg
201 mymaxradius = max(mymaxradius,
exp_radius(0, alpha, eps_mm_rspace, prefactor, rlow=mymaxradius))
204 box(1) = (qm_cell_small%hmat(1, 1) - mm_cell%hmat(1, 1))/2.0_dp
205 box(2) = (qm_cell_small%hmat(2, 2) - mm_cell%hmat(2, 2))/2.0_dp
206 box(3) = (qm_cell_small%hmat(3, 3) - mm_cell%hmat(3, 3))/2.0_dp
207 IF (any(box > 0.0_dp))
THEN
210 n_rep_real(1) = ceiling((box(1) + mymaxradius)/mm_cell%hmat(1, 1))
211 n_rep_real(2) = ceiling((box(2) + mymaxradius)/mm_cell%hmat(2, 2))
212 n_rep_real(3) = ceiling((box(3) + mymaxradius)/mm_cell%hmat(3, 3))
216 DEALLOCATE (per_potentials(k)%Pot)
217 IF (output_unit > 0)
WRITE (output_unit,
'(A)')
" QMMM Periodic Potential - not Initialized!"
221 NULLIFY (mm_atom_index)
222 ALLOCATE (mm_atom_index(
SIZE(potentials(k)%pot%mm_atom_index)))
223 mm_atom_index = potentials(k)%pot%mm_atom_index
225 NULLIFY (per_potentials(k)%Pot%LG, per_potentials(k)%Pot%mm_atom_index, &
226 per_potentials(k)%Pot%gx, per_potentials(k)%Pot%gy, per_potentials(k)%Pot%gz)
227 CALL qmmm_per_pot_type_create(per_potentials(k)%Pot, lg=lg, gx=gx, gy=gy, gz=gz, &
228 gmax=gmax, kmax=kmax, n_rep_real=n_rep_real, &
229 fac=
fac, mm_atom_index=mm_atom_index, &
230 mm_cell=mm_cell, para_env=para_env, &
231 qmmm_per_section=qmmm_periodic, print_section=print_section)
236 npt = real(ncoarset, kind=
dp)*real(ndim, kind=
dp)*real(
SIZE(mm_atom_index), kind=
dp)
237 npl = real(ncoarsel, kind=
dp)*real(ndim, kind=
dp)*real(
SIZE(mm_atom_index), kind=
dp)
238 WRITE (unit=iw, fmt=
"(/,T2,A)") repeat(
"-", 79)
239 WRITE (unit=iw, fmt=
"(T2,A,T20,A,T80,A)")
"-",
"QMMM PERIODIC BOUNDARY CONDITION INFO",
"-"
240 WRITE (unit=iw, fmt=
"(T2,A)") repeat(
"-", 79)
241 WRITE (unit=iw, fmt=
"(T2,A,T10,A,F15.6,T50,A,3I5,T80,A)")
"-",
"RADIUS =", rc,
"REPLICA =", n_rep_real,
"-"
242 WRITE (unit=iw, fmt=
"(T2,A,T10,A,F15.6,T50,A,I15,T80,A)")
"-",
"MINGVAL =", minval(abs(lg)), &
243 "GPOINTS =", ndim,
"-"
244 WRITE (unit=iw, fmt=
"(T2,A,T10,A,3I5,T50,A,3I5,T80,A)")
"-",
"NCOARSL =", ncpl, &
245 "NCOARST =", ncp,
"-"
246 WRITE (unit=iw, fmt=
"(T2,A,T10,A,F15.0,T50,A,F15.0,T80,A)")
"-",
"NFLOP-L ~", npl, &
247 "NFLOP-T ~", npt,
"-"
248 WRITE (unit=iw, fmt=
"(T2,A)") repeat(
"-", 79)
253 END DO potential_type
277 SUBROUTINE qmmm_per_pot_type_create(Pot, LG, gx, gy, gz, GMax, Kmax, n_rep_real, &
278 Fac, mm_atom_index, mm_cell, para_env, qmmm_per_section, print_section)
279 TYPE(qmmm_per_pot_type),
POINTER :: pot
280 REAL(kind=
dp),
DIMENSION(:),
POINTER :: lg, gx, gy, gz
281 REAL(kind=
dp),
INTENT(IN) :: gmax
282 INTEGER,
INTENT(IN) :: kmax(3), n_rep_real(3)
283 REAL(kind=
dp),
INTENT(IN) ::
fac(3)
284 INTEGER,
DIMENSION(:),
POINTER :: mm_atom_index
285 TYPE(cell_type),
POINTER :: mm_cell
286 TYPE(mp_para_env_type),
POINTER :: para_env
287 TYPE(section_vals_type),
POINTER :: qmmm_per_section, print_section
290 INTEGER,
DIMENSION(:),
POINTER :: ngrids
291 REAL(kind=
dp) :: hmat(3, 3)
292 TYPE(section_vals_type),
POINTER :: grid_print_section
298 pot%mm_atom_index => mm_atom_index
301 pot%n_rep_real = n_rep_real
306 NULLIFY (pot%pw_grid)
307 NULLIFY (pot%pw_pool)
308 NULLIFY (pot%TabLR, ngrids)
315 lg=lg, gx=gx, gy=gy, gz=gz, hmat=hmat, npts=npts, param_section=qmmm_per_section, &
316 tag=
"qmmm", para_env=para_env, print_section=grid_print_section)
318 END SUBROUTINE qmmm_per_pot_type_create
335 qmmm_periodic, print_section)
336 TYPE(ewald_environment_type),
POINTER :: ewald_env
337 TYPE(ewald_pw_type),
POINTER :: ewald_pw
338 INTEGER,
INTENT(IN) :: qmmm_coupl_type
339 TYPE(cell_type),
POINTER :: mm_cell
340 TYPE(mp_para_env_type),
POINTER :: para_env
341 TYPE(section_vals_type),
POINTER :: qmmm_periodic, print_section
343 INTEGER :: ewald_type, gmax(3), iw, o_spline, ounit
344 LOGICAL :: do_multipoles
345 REAL(kind=
dp) :: alpha, rcut
346 TYPE(cp_logger_type),
POINTER :: logger
347 TYPE(section_vals_type),
POINTER :: ewald_print_section, ewald_section, &
352 cpassert(.NOT.
ASSOCIATED(ewald_env))
353 cpassert(.NOT.
ASSOCIATED(ewald_pw))
359 CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
364 CALL ewald_pw_create(ewald_pw, ewald_env, mm_cell, mm_cell, print_section=ewald_print_section)
366 CALL ewald_env_get(ewald_env, ewald_type=ewald_type, do_multipoles=do_multipoles, &
367 gmax=gmax, o_spline=o_spline, alpha=alpha, rcut=rcut)
369 cpabort(
"No multipole force fields allowed in QM-QM Ewald long range correction")
371 SELECT CASE (qmmm_coupl_type)
373 cpabort(
"QM-QM long range correction not possible with COULOMB coupling")
377 cpabort(
"QM-QM long range correction not possible with GAUSS/SWAVE coupling")
385 WRITE (unit=iw, fmt=
"(/,T2,A)") repeat(
"-", 79)
386 WRITE (unit=iw, fmt=
"(T2,A,T20,A,T80,A)")
"-",
"QMMM PERIODIC BOUNDARY CONDITION INFO",
"-"
387 WRITE (unit=iw, fmt=
"(T2,A,T25,A,T80,A)")
"-",
"QM-QM Long Range Correction",
"-"
388 WRITE (unit=iw, fmt=
"(T2,A)") repeat(
"-", 79)
389 SELECT CASE (ewald_type)
391 cpabort(
"QM-QM long range correction not compatible with Ewald=NONE")
393 cpabort(
"QM-QM long range correction not possible with Ewald=PME")
395 cpabort(
"QM-QM long range correction not possible with Ewald method")
397 WRITE (unit=iw, fmt=
"(T2,A,T35,A,T75,A,T80,A)")
"-",
"Ewald type",
"SPME",
"-"
398 WRITE (unit=iw, fmt=
"(T2,A,T35,A,T61,3I6,T80,A)")
"-",
"GMAX values", gmax,
"-"
399 WRITE (unit=iw, fmt=
"(T2,A,T35,A,T73,I6,T80,A)")
"-",
"Spline order", o_spline,
"-"
400 WRITE (unit=iw, fmt=
"(T2,A,T35,A,T67,F12.4,T80,A)")
"-",
"Alpha value", alpha,
"-"
401 WRITE (unit=iw, fmt=
"(T2,A,T35,A,T67,F12.4,T80,A)")
"-",
"Real space cutoff value", rcut,
"-"
403 WRITE (unit=iw, fmt=
"(T2,A)") repeat(
"-", 79)
static GRID_HOST_DEVICE double fac(const int i)
Factorial function, e.g. fac(5) = 5! = 120.
All kind of helpful little routines.
real(kind=dp) function, public exp_radius(l, alpha, threshold, prefactor, epsabs, epsrel, rlow)
The radius of a primitive Gaussian function for a given threshold is calculated. g(r) = prefactor*r**...
Handles all functions related to the CELL.
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
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)
...
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,...
subroutine, public ewald_env_set(ewald_env, ewald_type, alpha, epsilon, eps_pol, gmax, ns_max, precs, o_spline, para_env, poisson_section, interaction_cutoffs, cell_hmat)
Purpose: Set the EWALD environment.
subroutine, public ewald_env_create(ewald_env, para_env)
allocates and intitializes a ewald_env
subroutine, public read_ewald_section(ewald_env, ewald_section)
Purpose: read the EWALD section.
subroutine, public ewald_env_get(ewald_env, ewald_type, alpha, eps_pol, epsilon, gmax, ns_max, o_spline, group, para_env, poisson_section, precs, rcut, do_multipoles, max_multipole, do_ipol, max_ipol_iter, interaction_cutoffs, cell_hmat)
Purpose: Get the EWALD environment.
subroutine, public ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section)
creates the structure ewald_pw_type
Setting up the Spline coefficients used to Interpolate the G-Term in Ewald sums.
subroutine, public setup_ewald_spline(pw_grid, pw_pool, coeff, LG, gx, gy, gz, hmat, npts, param_section, tag, print_section, para_env)
Setup of the G-space Ewald Term Spline Coefficients.
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Interface to the message passing library MPI.
functions related to the poisson solver on regular grids
integer, parameter, public do_ewald_pme
integer, parameter, public do_ewald_ewald
integer, parameter, public do_ewald_none
integer, parameter, public do_ewald_spme
Sets the typo for the gaussian treatment of the qm/mm interaction.
Setting up the potential for QM/MM periodic boundary conditions calculations.
subroutine, public qmmm_per_potential_init(qmmm_coupl_type, per_potentials, potentials, pgfs, qm_cell_small, mm_cell, para_env, compatibility, qmmm_periodic, print_section, eps_mm_rspace, maxchrg, ncp, ncpl)
Initialize the QMMM potential stored on vector, according the qmmm_coupl_type.
subroutine, public qmmm_ewald_potential_init(ewald_env, ewald_pw, qmmm_coupl_type, mm_cell, para_env, qmmm_periodic, print_section)
Initialize the QMMM Ewald potential needed for QM-QM Coupling using point charges.