40#include "./base/base_uses.f90"
45 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
46 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'ewald_spline_util'
70 param_section, tag, print_section)
74 REAL(kind=
dp),
DIMENSION(:),
POINTER :: lg, gx, gy, gz
75 REAL(kind=
dp),
INTENT(IN) :: hmat(3, 3)
76 INTEGER,
INTENT(IN) :: npts(3)
78 CHARACTER(LEN=*),
INTENT(IN) :: tag
81 INTEGER :: bo(2, 3), iounit
90 cpassert(.NOT.
ASSOCIATED(pw_grid))
91 cpassert(.NOT.
ASSOCIATED(pw_pool))
92 cpassert(.NOT.
ASSOCIATED(coeff))
95 CALL cell_create(cell, hmat=hmat, periodic=(/1, 1, 1/))
100 bo(2, 1:3) = npts(1:3) - 1
108 CALL pw_pool%create_pw(pw)
109 CALL pw_pool%create_pw(coeff)
111 CALL eval_pw_tablr(pw, pw_pool, coeff, lg, gx, gy, gz, hmat_mm=hmat, &
112 param_section=param_section, tag=tag)
113 CALL pw_pool%give_back_pw(pw)
135 SUBROUTINE eval_pw_tablr(grid, pw_pool, TabLR, Lg, gx, gy, gz, hmat_mm, &
140 REAL(kind=
dp),
DIMENSION(:),
POINTER :: lg, gx, gy, gz
141 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat_mm
143 CHARACTER(LEN=*),
INTENT(IN) :: tag
145 CHARACTER(len=*),
PARAMETER :: routinen =
'eval_pw_TabLR'
147 INTEGER :: act_nx, act_ny, aint_precond, handle, i, iii, is, j, js, k, ks, lg_loc_max, &
148 lg_loc_min, max_iter, my_i, my_j, my_k, n1, n2, n3, n_extra, nlg_loc, nxlim, nylim, &
150 INTEGER,
DIMENSION(2, 3) :: gbo
152 REAL(kind=
dp) :: dr1, dr2, dr3, eps_r, eps_x, xs1, xs2, &
154 REAL(kind=
dp),
ALLOCATABLE :: cos_gx(:, :), cos_gy(:, :), &
155 cos_gz(:, :), lhs(:, :), rhs(:, :), &
156 sin_gx(:, :), sin_gy(:, :), &
166 CALL timeset(routinen, handle)
167 n1 = grid%pw_grid%npts(1)
168 n2 = grid%pw_grid%npts(2)
169 n3 = grid%pw_grid%npts(3)
170 dr1 = grid%pw_grid%dr(1)
171 dr2 = grid%pw_grid%dr(2)
172 dr3 = grid%pw_grid%dr(3)
173 gbo = grid%pw_grid%bounds
174 nxlim = floor(real(n1, kind=
dp)/2.0_dp)
175 nylim = floor(real(n2, kind=
dp)/2.0_dp)
176 nzlim = floor(real(n3, kind=
dp)/2.0_dp)
180 IF (2*nxlim /= n1) is = 1
181 IF (2*nylim /= n2) js = 1
182 IF (2*nzlim /= n3) ks = 1
189 ALLOCATE (cos_gx(
SIZE(lg), gbo(1, 1):gbo(2, 1)))
190 ALLOCATE (sin_gx(
SIZE(lg), gbo(1, 1):gbo(2, 1)))
191 ALLOCATE (cos_gy(
SIZE(lg), gbo(1, 2):gbo(2, 2)))
192 ALLOCATE (sin_gy(
SIZE(lg), gbo(1, 2):gbo(2, 2)))
193 ALLOCATE (cos_gz(
SIZE(lg), gbo(1, 3):gbo(2, 3)))
194 ALLOCATE (sin_gz(
SIZE(lg), gbo(1, 3):gbo(2, 3)))
196 DO k = gbo(1, 3), gbo(2, 3)
198 xs3 = real(my_k,
dp)*dr3
200 cos_gz(1:
SIZE(lg), k) = cos(gz(1:
SIZE(lg))*xs3)
201 sin_gz(1:
SIZE(lg), k) = sin(gz(1:
SIZE(lg))*xs3)
204 DO j = gbo(1, 2), gbo(2, 2)
206 cos_gy(1:
SIZE(lg), j) = cos(gy(1:
SIZE(lg))*xs2)
207 sin_gy(1:
SIZE(lg), j) = sin(gy(1:
SIZE(lg))*xs2)
211 DO i = gbo(1, 1), gbo(2, 1)
213 cos_gx(1:
SIZE(lg), i) = cos(gx(1:
SIZE(lg))*xs1)
214 sin_gx(1:
SIZE(lg), i) = sin(gx(1:
SIZE(lg))*xs1)
220 nlg_loc =
SIZE(lg)/grid%pw_grid%para%group%num_pe
222 n_extra = mod(
SIZE(lg), grid%pw_grid%para%group%num_pe)
224 IF (grid%pw_grid%para%group%mepos < n_extra)
THEN
225 lg_loc_min = (nlg_loc + 1)*grid%pw_grid%para%group%mepos + 1
226 lg_loc_max = lg_loc_min + (nlg_loc + 1) - 1
228 lg_loc_min = (nlg_loc + 1)*n_extra + nlg_loc*(grid%pw_grid%para%group%mepos - n_extra) + 1
229 lg_loc_max = lg_loc_min + nlg_loc - 1
232 lg_loc_max = min(
SIZE(lg), lg_loc_max)
233 nlg_loc = lg_loc_max - lg_loc_min + 1
235 IF (nlg_loc > 0)
THEN
237 act_nx = min(gbo(2, 1), nxlim) - gbo(1, 1) + 1
238 act_ny = min(gbo(2, 2), nylim) - gbo(1, 2) + 1
240 ALLOCATE (lhs(act_nx, nlg_loc))
241 ALLOCATE (rhs(act_ny, nlg_loc))
244 DO i = gbo(1, 1), gbo(2, 1)
246 lhs(i - gbo(1, 1) + 1, 1:nlg_loc) = lg(lg_loc_min:lg_loc_max)*cos_gx(lg_loc_min:lg_loc_max, i)
248 DO k = gbo(1, 3), gbo(2, 3)
250 DO j = gbo(1, 2), gbo(2, 2)
252 rhs(j - gbo(1, 2) + 1, 1:nlg_loc) = cos_gy(lg_loc_min:lg_loc_max, j)*cos_gz(lg_loc_min:lg_loc_max, k) - &
253 sin_gy(lg_loc_min:lg_loc_max, j)*sin_gz(lg_loc_min:lg_loc_max, k)
255 CALL dgemm(
'N',
'T', act_nx, act_ny, nlg_loc, 1.0d0, lhs(1, 1), act_nx, rhs(1, 1), act_ny, 0.0d0, &
256 grid%array(gbo(1, 1), gbo(1, 2), k),
SIZE(grid%array, 1))
260 DO i = gbo(1, 1), gbo(2, 1)
262 lhs(i - gbo(1, 1) + 1, 1:nlg_loc) = -lg(lg_loc_min:lg_loc_max)*sin_gx(lg_loc_min:lg_loc_max, i)
264 DO k = gbo(1, 3), gbo(2, 3)
266 DO j = gbo(1, 2), gbo(2, 2)
268 rhs(j - gbo(1, 2) + 1, 1:nlg_loc) = cos_gy(lg_loc_min:lg_loc_max, j)*sin_gz(lg_loc_min:lg_loc_max, k) + &
269 sin_gy(lg_loc_min:lg_loc_max, j)*cos_gz(lg_loc_min:lg_loc_max, k)
271 CALL dgemm(
'N',
'T', act_nx, act_ny, nlg_loc, 1.0d0, lhs(1, 1), act_nx, rhs(1, 1), act_ny, 1.0d0, &
272 grid%array(gbo(1, 1), gbo(1, 2), k),
SIZE(grid%array, 1))
287 grid%array(gbo(1, 1):nxlim, gbo(1, 2):nylim, gbo(1, 3):nzlim) = 0.0_dp
290 CALL grid%pw_grid%para%group%sum(grid%array(gbo(1, 1):nxlim, gbo(1, 2):nylim, gbo(1, 3):nzlim))
292 fake_loopongrid:
DO k = gbo(1, 3), gbo(2, 3)
294 IF (k > nzlim) my_k = nzlim - abs(nzlim - k) + ks
295 DO j = gbo(1, 2), gbo(2, 2)
297 IF (j > nylim) my_j = nylim - abs(nylim - j) + js
298 DO i = gbo(1, 1), gbo(2, 1)
300 IF (i > nxlim) my_i = nxlim - abs(nxlim - i) + is
301 grid%array(i, j, k) = grid%array(my_i, my_j, my_k)
304 END DO fake_loopongrid
318 pool=pw_pool,
pbc=.true., transpose=.false.)
323 eps_r=eps_r, eps_x=eps_x, &
330 CALL check_spline_interp_tablr(hmat_mm, lg, gx, gy, gz, tablr, param_section, &
332 CALL timestop(handle)
333 END SUBROUTINE eval_pw_tablr
349 SUBROUTINE check_spline_interp_tablr(hmat_mm, Lg, gx, gy, gz, TabLR, &
351 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat_mm
352 REAL(kind=
dp),
DIMENSION(:),
POINTER :: lg, gx, gy, gz
355 CHARACTER(LEN=*),
INTENT(IN) :: tag
357 CHARACTER(len=*),
PARAMETER :: routinen =
'check_spline_interp_TabLR'
359 INTEGER :: handle, i, iw, kg, npoints
360 REAL(kind=
dp) :: dn(3), dr1, dr2, dr3, dxterm, dyterm, &
361 dzterm, errd, errf, fterm, maxerrord, &
362 maxerrorf, na, nn, term, tmp1, tmp2, &
363 vec(3), xs1, xs2, xs3
369 extension=
"."//trim(tag)//
"Log")
370 CALL timeset(routinen, handle)
377 dr1 = hmat_mm(1, 1)/real(npoints, kind=
dp)
378 dr2 = hmat_mm(2, 2)/real(npoints, kind=
dp)
379 dr3 = hmat_mm(3, 3)/real(npoints, kind=
dp)
383 WRITE (iw,
'(A,T5,A15,4X,A17,T50,4X,A,5X,A,T80,A,T85,A15,4X,A17,T130,4X,A,5X,A)') &
384 "#",
"Analytical Term",
"Interpolated Term",
"Error",
"MaxError", &
385 "*",
" Analyt Deriv ",
"Interp Deriv Mod ",
"Error",
"MaxError"
386 DO i = 1, npoints + 1
393 vec = (/real(gx(kg), kind=
dp), real(gy(kg), kind=
dp), real(gz(kg), kind=
dp)/)
394 term = term + lg(kg)*cos(vec(1)*xs1 + vec(2)*xs2 + vec(3)*xs3)
395 dxterm = dxterm - lg(kg)*sin(vec(1)*xs1 + vec(2)*xs2 + vec(3)*xs3)*vec(1)
396 dyterm = dyterm - lg(kg)*sin(vec(1)*xs1 + vec(2)*xs2 + vec(3)*xs3)*vec(2)
397 dzterm = dzterm - lg(kg)*sin(vec(1)*xs1 + vec(2)*xs2 + vec(3)*xs3)*vec(3)
399 na = sqrt(dxterm*dxterm + dyterm*dyterm + dzterm*dzterm)
401 nn = sqrt(dot_product(dn, dn))
403 tmp1 = abs(term - fterm)
404 tmp2 = sqrt(dot_product(dn - (/dxterm, dyterm, dzterm/), dn - (/dxterm, dyterm, dzterm/)))
406 maxerrorf = max(maxerrorf, tmp1)
408 maxerrord = max(maxerrord, tmp2)
409 WRITE (iw,
'(T5,F15.10,5X,F15.10,T50,2F12.9,T80,A,T85,F15.10,5X,F15.10,T130,2F12.9)') &
410 term, fterm, tmp1, maxerrorf,
"*", na, nn, tmp2, maxerrord
415 WRITE (iw,
'(A,T5,A,T50,F12.9,T130,F12.9)')
"#",
"Averages", errf/real(npoints, kind=
dp), &
416 errd/real(npoints, kind=
dp)
418 CALL timestop(handle)
421 END SUBROUTINE check_spline_interp_tablr
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Handles all functions related to the CELL.
subroutine, public cell_create(cell, hmat, periodic, tag)
allocates and initializes a cell
Handles all functions related to the CELL.
subroutine, public cell_release(cell)
releases the given cell (see doc/ReferenceCounting.html)
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)
...
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,...
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)
Setup of the G-space Ewald Term Spline Coefficients.
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.
type(mp_comm_type), parameter, public mp_comm_self
computes preconditioners, and implements methods to apply them currently used in qs_ot
integer, parameter, public halfspace
This module defines the grid data type and some basic operations on it.
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public pw_pool_create(pool, pw_grid, max_cache)
creates a pool for pw
different utils that are useful to manipulate splines on the regular grid of a pw
subroutine, public pw_spline_precond_release(preconditioner)
releases the preconditioner
subroutine, public pw_spline_precond_create(preconditioner, precond_kind, pool, pbc, transpose)
...
subroutine, public pw_spline_do_precond(preconditioner, in_v, out_v)
applies the preconditioner to the system of equations to find the coefficients of the spline
subroutine, public pw_spline_precond_set_kind(preconditioner, precond_kind, pbc, transpose)
switches the types of precoditioner to use
real(kind=dp) function, dimension(3), public eval_d_interp_spl3_pbc(vec, pw)
Evaluates the derivatives of the PBC interpolated Spline (pw) function on the generic input vector (v...
real(kind=dp) function, public eval_interp_spl3_pbc(vec, pw)
Evaluates the PBC interpolated Spline (pw) function on the generic input vector (vec)
logical function, public find_coeffs(values, coeffs, linop, preconditioner, pool, eps_r, eps_x, max_iter, sumtype)
solves iteratively (CG) a systmes of linear equations linOp(coeffs)=values (for example those needed ...
subroutine, public spl3_pbc(pw_in, pw_out)
...
Type defining parameters related to the simulation cell.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
stores information for the preconditioner used to calculate the coeffs of splines