191 INTEGER,
INTENT(IN) :: nr, na, llmax, ll, quadrature
193 CHARACTER(len=*),
PARAMETER :: routinen =
'create_grid_atom'
195 INTEGER :: handle, ia, ir, l
196 REAL(
dp) :: cosia, pol
197 REAL(
dp),
DIMENSION(:),
POINTER :: rad, rad2, wr
199 CALL timeset(routinen, handle)
201 NULLIFY (rad, rad2, wr)
203 IF (
ASSOCIATED(grid_atom))
THEN
210 CALL reallocate(grid_atom%weight, 1, na, 1, nr)
218 CALL reallocate(grid_atom%rad2l, 1, nr, 0, llmax + 1)
219 CALL reallocate(grid_atom%oorad2l, 1, nr, 0, llmax + 1)
223 rad2 => grid_atom%rad2
226 grid_atom%quadrature = quadrature
227 CALL radial_grid(nr, rad, rad2, wr, quadrature)
229 grid_atom%rad2l(:, 0) = 1._dp
230 grid_atom%oorad2l(:, 0) = 1._dp
232 grid_atom%rad2l(:, l) = grid_atom%rad2l(:, l - 1)*rad(:)
233 grid_atom%oorad2l(:, l) = grid_atom%oorad2l(:, l - 1)/rad(:)
240 grid_atom%weight(ia, ir) = grid_atom%wr(ir)*grid_atom%wa(ia)
247 grid_atom%cos_pol(ia) = cosia
249 IF (abs(
lebedev_grid(ll)%r(2, ia)) < epsilon(1.0_dp) .AND. &
251 grid_atom%azi(ia) = 0.0_dp
255 grid_atom%cos_azi(ia) = cos(grid_atom%azi(ia))
257 grid_atom%pol(ia) = pol
258 grid_atom%sin_pol(ia) = sin(grid_atom%pol(ia))
260 grid_atom%sin_azi(ia) = sin(grid_atom%azi(ia))
261 IF (abs(grid_atom%sin_azi(ia)) > epsilon(1.0_dp))
THEN
262 grid_atom%usin_azi(ia) = 1.0_dp/grid_atom%sin_azi(ia)
264 grid_atom%usin_azi(ia) = 1.0_dp
272 cpabort(
"The pointer grid_atom is not associated")
275 CALL timestop(handle)
293 INTEGER,
INTENT(IN) :: nr, na
294 REAL(kind=
dp),
INTENT(IN) :: rmax
295 INTEGER,
INTENT(IN),
OPTIONAL :: quadrature, iunit
297 INTEGER :: ia, ig, ir, ix, iy, iz, la, ll, my_quad, &
298 n1, n2, n3, nbatch, ng, no, np, ntot, &
300 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: icell
301 REAL(kind=
dp) :: ag, dd, dmax, r1, r2, r3
302 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: rad, rad2, wa, wc, wr
303 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: rang, rco
304 REAL(kind=
dp),
DIMENSION(10) :: dco
305 REAL(kind=
dp),
DIMENSION(3) :: rm
311 IF (
PRESENT(quadrature))
THEN
319 ALLOCATE (rad(nr), rad2(nr), wr(nr))
320 CALL radial_grid(nr, rad, rad2, wr, my_quad)
323 ALLOCATE (igr%rr(nr))
324 ALLOCATE (igr%wr(nr))
326 IF (rad(1) > rad(nr))
THEN
328 igr%rr(nr - ir + 1) = rad(ir)
329 igr%wr(nr - ir + 1) = wr(ir)
332 igr%rr(1:nr) = rad(1:nr)
333 igr%wr(1:nr) = wr(1:nr)
338 IF (igr%rr(ir) < rmax)
THEN
351 ALLOCATE (rang(3, np), wa(np))
354 igr%lebedev_grid = ll
355 ALLOCATE (igr%wa(np))
357 igr%wa(1:np) = wa(1:np)
362 ALLOCATE (rco(3, ntot), wc(ntot))
367 rco(1:3, ig) = rang(1:3, ia)*rad(ir)
368 wc(ig) = wa(ia)*wr(ir)
372 ng = nint((real(ntot,
dp)/32._dp)**0.33333_dp)
373 ng = ng + mod(ng + 1, 2)
376 ag = real(igr%np,
dp)/ng
377 cpassert(
SIZE(dco) >= (ng + 1)/2)
379 ir = min(nint(ag)*ig, igr%np)
384 ALLOCATE (icell(ntot))
388 ix = grid_coord(rco(1, ig), dco, nx + 1) + nx
389 iy = grid_coord(rco(2, ig), dco, nx + 1) + nx
390 iz = grid_coord(rco(3, ig), dco, nx + 1) + nx
391 icell(ig) = iz*ng*ng + iy*ng + ix + 1
394 igr%nbatch = ng*ng*ng
395 ALLOCATE (igr%batch(igr%nbatch))
399 igr%batch(ia)%np = igr%batch(ia)%np + 1
401 DO ig = 1, igr%nbatch
402 np = igr%batch(ig)%np
403 ALLOCATE (igr%batch(ig)%rco(3, np), igr%batch(ig)%weight(np))
408 igr%batch(ia)%np = igr%batch(ia)%np + 1
409 np = igr%batch(ia)%np
410 igr%batch(ia)%rco(1:3, np) = rco(1:3, ig)
411 igr%batch(ia)%weight(np) = wc(ig)
414 DEALLOCATE (rad, rad2, rang, wr, wa)
415 DEALLOCATE (rco, wc, icell)
419 ALLOCATE (int_grid%rr(igr%nr), int_grid%wr(igr%nr), int_grid%wa(igr%na))
423 int_grid%ntot = igr%ntot
424 int_grid%lebedev_grid = igr%lebedev_grid
425 int_grid%rr(:) = igr%rr(:)
426 int_grid%wr(:) = igr%wr(:)
427 int_grid%wa(:) = igr%wa(:)
431 DO ig = 1, igr%nbatch
432 IF (igr%batch(ig)%np == 0)
THEN
434 ELSE IF (igr%batch(ig)%np <= 48)
THEN
439 nbatch = nbatch + nint(igr%batch(ig)%np/32._dp)
442 int_grid%nbatch = nbatch
443 ALLOCATE (int_grid%batch(nbatch))
446 DO ig = 1, igr%nbatch
447 IF (igr%batch(ig)%np == 0)
THEN
449 ELSE IF (igr%batch(ig)%np <= 48)
THEN
452 np = igr%batch(ig)%np
453 ALLOCATE (int_grid%batch(n1)%rco(3, np), int_grid%batch(n1)%weight(np))
454 int_grid%batch(n1)%np = np
455 int_grid%batch(n1)%rco(1:3, 1:np) = igr%batch(ig)%rco(1:3, 1:np)
456 int_grid%batch(n1)%weight(1:np) = igr%batch(ig)%weight(1:np)
459 n2 = nint(igr%batch(ig)%np/32._dp)
460 n3 = igr%batch(ig)%np/n2
461 DO ia = n1 + 1, n1 + n2
462 nu = (ia - n1 - 1)*n3 + 1
464 IF (ia == n1 + n2) no = igr%batch(ig)%np
466 ALLOCATE (int_grid%batch(ia)%rco(3, np), int_grid%batch(ia)%weight(np))
467 int_grid%batch(ia)%np = np
468 int_grid%batch(ia)%rco(1:3, 1:np) = igr%batch(ig)%rco(1:3, nu:no)
469 int_grid%batch(ia)%weight(1:np) = igr%batch(ig)%weight(nu:no)
474 cpassert(nbatch == n1)
476 DO ig = 1, int_grid%nbatch
477 np = int_grid%batch(ig)%np
479 rm(1) = sum(int_grid%batch(ig)%rco(1, 1:np))
480 rm(2) = sum(int_grid%batch(ig)%rco(2, 1:np))
481 rm(3) = sum(int_grid%batch(ig)%rco(3, 1:np))
482 rm(1:3) = rm(1:3)/real(np, kind=
dp)
486 int_grid%batch(ig)%rcenter(1:3) = rm(1:3)
489 dd = sum((int_grid%batch(ig)%rco(1:3, ia) - rm(1:3))**2)
492 int_grid%batch(ig)%rad = sqrt(dmax)
497 IF (
PRESENT(iunit))
THEN
499 WRITE (iunit,
"(/,A)")
" Atomic Integration Grid Information"
500 WRITE (iunit,
"(A,T51,3I10)")
" Number of grid points [radial,angular,total]", &
501 int_grid%np, int_grid%na, int_grid%ntot
502 WRITE (iunit,
"(A,T71,I10)")
" Lebedev grid number", int_grid%lebedev_grid
503 WRITE (iunit,
"(A,T61,F20.5)")
" Maximum of radial grid [Bohr]", &
504 int_grid%rr(int_grid%np)
505 nbatch = int_grid%nbatch
506 WRITE (iunit,
"(A,T71,I10)")
" Total number of gridpoint batches", nbatch
509 n3 = nint(real(int_grid%ntot,
dp)/real(nbatch,
dp))
511 n1 = min(n1, int_grid%batch(ig)%np)
512 n2 = max(n2, int_grid%batch(ig)%np)
514 WRITE (iunit,
"(A,T51,3I10)")
" Number of grid points/batch [min,max,ave]", n1, n2, n3
518 DO ig = 1, int_grid%nbatch
519 r1 = min(r1, int_grid%batch(ig)%rad)
520 r2 = max(r2, int_grid%batch(ig)%rad)
521 r3 = r3 + int_grid%batch(ig)%rad
523 r3 = r3/real(ng*ng*ng, kind=
dp)
524 WRITE (iunit,
"(A,T51,3F10.2)")
" Batch radius (bohr) [min,max,ave]", r1, r2, r3