37 #include "../base/base_uses.f90"
68 RECURSIVE SUBROUTINE fes_compute_low(idim, nn, fes, gauss, ind, ind0, nfes, ndim, &
70 INTEGER,
INTENT(in) :: idim
71 INTEGER,
DIMENSION(:) :: nn
72 REAL(kind=
dp),
DIMENSION(:),
POINTER :: fes
73 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: gauss
74 INTEGER,
DIMENSION(:) :: ind, ind0
75 INTEGER,
INTENT(in) :: nfes, ndim, ngauss
76 INTEGER,
DIMENSION(:),
POINTER :: ngrid
77 INTEGER,
DIMENSION(:) :: iperd
79 INTEGER :: i, j, k, pnt
80 INTEGER,
DIMENSION(:),
POINTER :: ll, pos
83 ALLOCATE (pos(ndim), ll(ndim))
88 pos(idim) = ind(idim) + i
89 IF (iperd(idim) == 0)
THEN
90 IF (pos(idim) .GT. ngrid(idim)) cycle
91 IF (pos(idim) .LT. 1) cycle
94 CALL fes_compute_low(idim - 1, nn, fes, gauss, pos, ind0, nfes, ndim, ngauss, ngrid, iperd)
99 ll(j) = pos(j) - ind0(j)
100 prod = prod*gauss(ll(j), j)
102 fes(pnt) = fes(pnt) + prod
127 RECURSIVE SUBROUTINE fes_write(unit_nr, idim, fes, pos, ndim, ngrid, &
128 dp_grid, x0, ndw, l_fes_int, array)
129 INTEGER,
INTENT(IN) :: unit_nr, idim
130 REAL(kind=
dp),
DIMENSION(:),
POINTER :: fes
131 INTEGER,
DIMENSION(:),
POINTER :: pos
132 INTEGER,
INTENT(IN) :: ndim
133 INTEGER,
DIMENSION(:),
POINTER :: ngrid
134 REAL(kind=
dp),
DIMENSION(:),
POINTER :: dp_grid, x0
135 INTEGER,
INTENT(IN) :: ndw
136 LOGICAL,
INTENT(IN) :: l_fes_int
137 REAL(kind=
dp),
DIMENSION(:),
OPTIONAL :: array
139 INTEGER :: dimval, i, id, ind, is, it, itt, np, pnt
140 REAL(kind=
dp) :: dvol, sum_fes
141 REAL(kind=
dp),
DIMENSION(:),
POINTER :: xx
145 DO i = 1, ngrid(idim)
147 IF (idim /= ndim - ndw + 1)
THEN
148 IF (
PRESENT(array))
THEN
149 CALL fes_write(unit_nr, idim - 1, fes, pos, ndim, ngrid, dp_grid, &
150 x0, ndw, l_fes_int, array)
152 CALL fes_write(unit_nr, idim - 1, fes, pos, ndim, ngrid, dp_grid, &
156 IF (
PRESENT(array))
THEN
158 np = ngrid(ndim)*ngrid(ndim - 1)*ngrid(ndim - 2)
162 itt = itt*ngrid(ndim - it)
164 ind = ind + (pos(ndim - is + 1) - 1)*itt
166 IF (ind > np) cpabort(
"something wrong in indexing ..")
169 xx = x0 + dp_grid*(pos - 1)
170 dimval = product(ngrid(1:ndim - ndw))
172 IF (.NOT. l_fes_int)
THEN
173 IF (
PRESENT(array))
THEN
174 array(ind) = minval(-fes(pnt:pnt + dimval - 1))
176 WRITE (unit_nr,
'(10f20.10)') (xx(id), id=ndim, ndim - ndw + 1, -1), minval(-fes(pnt:pnt + dimval - 1))
181 dvol = product(dp_grid(1:ndim - ndw))
182 DO is = pnt, pnt + dimval - 1
183 sum_fes = sum_fes + fes(is)*dvol
185 IF (
PRESENT(array))
THEN
186 array(ind) = -sum_fes
188 WRITE (unit_nr,
'(10f20.10)') (xx(id), id=ndim, ndim - ndw + 1, -1), -sum_fes
213 RECURSIVE SUBROUTINE fes_only_write(idim, fes, pos, ndim, ngrid, dp_grid, ndw, l_fes_int, unit_nr)
214 INTEGER,
INTENT(IN) :: idim
215 REAL(kind=
dp),
DIMENSION(:),
POINTER :: fes
216 INTEGER,
DIMENSION(:),
POINTER :: pos
217 INTEGER,
INTENT(IN) :: ndim
218 INTEGER,
DIMENSION(:),
POINTER :: ngrid
219 REAL(kind=
dp),
DIMENSION(:),
POINTER :: dp_grid
220 INTEGER,
INTENT(IN) :: ndw
221 LOGICAL,
INTENT(IN) :: l_fes_int
224 INTEGER :: dimval, i, is, pnt
225 REAL(kind=
dp) :: dvol, sum_fes
227 DO i = 1, ngrid(idim)
229 IF (idim /= ndim - ndw + 1)
THEN
230 CALL fes_only_write(idim - 1, fes, pos, ndim, ngrid, dp_grid, ndw, l_fes_int, unit_nr)
233 dimval = product(ngrid(1:ndim - ndw))
235 WRITE (unit_nr,
'(1f12.5)') minval(-fes(pnt:pnt + dimval - 1))
238 dvol = product(dp_grid(1:ndim - ndw))
239 DO is = pnt, pnt + dimval - 1
240 sum_fes = sum_fes + fes(is)*dvol
242 WRITE (unit_nr,
'(1f12.5)') - sum_fes
263 SUBROUTINE fes_min(fes, ndim, iperd, ngrid, dp_grid, x0, ndw)
264 REAL(kind=
dp),
DIMENSION(:),
POINTER :: fes
265 INTEGER,
INTENT(IN) :: ndim
266 INTEGER,
DIMENSION(:),
POINTER :: iperd, ngrid
267 REAL(kind=
dp),
DIMENSION(:),
POINTER :: dp_grid, x0
268 INTEGER,
INTENT(IN) :: ndw
270 INTEGER :: i, id, iter, j, k, max_ntrust, nacc, &
272 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: history
273 INTEGER,
DIMENSION(:),
POINTER :: pos, pos0
274 INTEGER,
DIMENSION(ndim) :: dpos, ntrust
276 REAL(kind=
dp) :: fes_now, fes_old, norm_dx, resto
277 REAL(kind=
dp),
DIMENSION(:),
POINTER :: dx, rnd, xx
279 IF (ndw /= ndim) cpabort(
"Not implemented for projected FES!")
282 ntrials = product(ngrid)
283 WRITE (*,
'(A,10I6)', advance=
"no")
"FES| Trust hyper-radius ", ntrust
284 WRITE (*,
'(A,10F12.6)')
" which is equivalent to: ", ntrust*dp_grid
286 ALLOCATE (xx(ndim), dx(ndim), pos0(ndim), rnd(ndim), pos(ndim))
287 ALLOCATE (history(ndim, ntrials))
290 trials:
DO j = 1, ntrials
294 pos0(k) = pnt/product(ngrid(1:k - 1))
295 resto = mod(pnt, product(ngrid(1:k - 1)))
297 pnt = pnt - pos0(k)*product(ngrid(1:k - 1))
298 pos0(k) = pos0(k) + 1
300 pnt = product(ngrid(1:k - 1))
307 IF ((iperd(k) == 0) .AND. (pos0(k) < ntrust(k))) cycle trials
308 IF ((iperd(k) == 0) .AND. (pos0(k) > ngrid(k) - ntrust(k))) cycle trials
313 xx = x0 + dp_grid*(pos - 1)
314 dx =
derivative(fes, pos, iperd, ndim, ngrid, dp_grid)
319 fes_old = huge(0.0_dp)
322 DO WHILE ((i <= 100) .OR. (fes_now < fes_old))
326 norm_dx = sqrt(dot_product(dx, dx))
327 IF (norm_dx == 0.0_dp)
EXIT
328 xx = xx - min(0.1_dp, norm_dx)*dx/norm_dx
330 pos = ceiling((xx - x0)/dp_grid) + 1
331 CALL pbc(pos, iperd, ngrid, ndim)
334 dx =
derivative(fes, pos, iperd, ndim, ngrid, dp_grid)
343 do_save = fes(pnt) >= 1.0e-3_dp
346 dpos = pos - history(:, i)
347 norm_dx = dot_product(dpos, dpos)
348 max_ntrust = maxval(ntrust)
350 IF ((norm_dx <= real(max_ntrust*max_ntrust, kind=
dp)) .OR. (fes(pnt) < 1.0e-3_dp))
THEN
358 xx = x0 + dp_grid*(pos - 1)
359 WRITE (*,
'(A,5F12.6)', advance=
"NO")
"FES| Minimum found (", (xx(id), id=ndim, ndim - ndw + 1, -1)
360 WRITE (*,
'(A,F12.6,A,I6)')
" ). FES value = ", -fes(pnt),
" Hartree. Number of Iter: ", iter
362 history(:, nacc) = pos
365 WRITE (*,
'(A,I6,A)')
"FES| Number of Minimum found: ", nacc,
"."
367 DEALLOCATE (xx, dx, pos0, rnd, pos)
388 SUBROUTINE fes_path(fes, ndim, ngrid, dp_grid, iperd, x0, ndw, mep_input_data, l_int)
389 REAL(kind=
dp),
DIMENSION(:),
POINTER :: fes
390 INTEGER,
INTENT(IN) :: ndim
391 INTEGER,
DIMENSION(:),
POINTER :: ngrid
392 REAL(kind=
dp),
DIMENSION(:),
POINTER :: dp_grid
393 INTEGER,
DIMENSION(:),
POINTER :: iperd
394 REAL(kind=
dp),
DIMENSION(:),
POINTER :: x0
395 INTEGER,
INTENT(IN) :: ndw
396 TYPE(mep_input_data_type),
INTENT(IN) :: mep_input_data
399 INTEGER :: i, id, irep, iter, nf, nreplica, ns, &
401 INTEGER,
DIMENSION(:),
POINTER :: ipos
403 REAL(kind=
dp) :: avg1, avg2, diff, ene, norm_dx, xx0, yy0
404 REAL(kind=
dp),
DIMENSION(:),
POINTER :: davg1, davg2, dxx, dyy, fes_rep, tang, &
406 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: dx, pos, pos_old
408 IF (ndw /= ndim) cpabort(
"Not implemented for projected FES!")
409 nreplica = mep_input_data%nreplica
410 ALLOCATE (xx(ndim), dx(ndim, nreplica), pos_old(ndim, nreplica), pos(ndim, nreplica), &
411 ipos(ndim), fes_rep(nreplica), dxx(ndim), dyy(ndim), yy(ndim), davg1(ndim), &
412 tang(ndim), davg2(ndim))
416 DO i = ndim, ndim - ndw + 1, -1
418 pos(i, 1) = mep_input_data%minima(id, 1)
419 pos(i, nreplica) = mep_input_data%minima(id, 2)
423 xx = (pos(:, nreplica) - pos(:, 1))/real(nreplica - 1, kind=
dp)
424 DO irep = 2, nreplica - 1
425 pos(:, irep) = pos(:, 1) + xx(:)*real(irep - 1, kind=
dp)
429 pos = mep_input_data%minima
433 DO irep = 1, nreplica
434 ipos = floor((pos(:, irep) - x0)/dp_grid) + 1
436 dx(:, irep) =
derivative(fes, ipos, iperd, ndim, ngrid, dp_grid)
437 fes_rep(irep) = -fes(pnt)
445 DO WHILE ((.NOT. converged) .AND. (iter <= mep_input_data%max_iter))
449 DO irep = 2, nreplica
450 xx = pos(:, irep) - pos(:, irep - 1)
451 avg1 = avg1 + sqrt(dot_product(xx, xx))
453 avg1 = avg1/real(nreplica - 1, kind=
dp)
457 DO irep = 3, nreplica
458 xx = pos(:, irep) - pos(:, irep - 2)
459 avg2 = avg2 + sqrt(dot_product(xx, xx))
461 avg2 = avg2/real(nreplica - 2, kind=
dp)
468 DO irep = 1, nreplica
470 ipos = floor((pos(:, irep) - x0)/dp_grid) + 1
472 fes_rep(irep) = -fes(pnt)
473 IF ((irep == 1) .OR. (irep == nreplica)) cycle
479 IF (irep < nf - 1)
THEN
480 xx = pos(:, irep) - pos(:, irep + 2)
481 xx0 = sqrt(dot_product(xx, xx))
483 ene = ene + 0.25_dp*mep_input_data%kb*(xx0 - avg2)**2
487 IF (irep > ns + 1)
THEN
488 xx = pos(:, irep) - pos(:, irep - 2)
489 yy0 = sqrt(dot_product(xx, xx))
493 davg2 = davg2/real(nreplica - 2, kind=
dp)
495 IF (irep < nf - 1)
THEN
496 dx(:, irep) = dx(:, irep) + 0.5_dp*mep_input_data%kb*(xx0 - avg2)*(dxx - davg2)
498 IF (irep > ns + 1)
THEN
499 dx(:, irep) = dx(:, irep) + 0.5_dp*mep_input_data%kb*(yy0 - avg2)*(dyy - davg2)
505 xx = pos(:, irep) - pos(:, irep + 1)
506 yy0 = sqrt(dot_product(xx, xx))
509 xx = pos(:, irep) - pos(:, irep - 1)
510 xx0 = sqrt(dot_product(xx, xx))
512 davg1 = (dxx + dyy)/real(nreplica - 1, kind=
dp)
514 ene = ene + 0.5_dp*mep_input_data%kb*(xx0 - avg1)**2
515 dx(:, irep) = dx(:, irep) + mep_input_data%kb*(xx0 - avg1)*(dxx - davg1) + &
516 mep_input_data%kb*(yy0 - avg1)*(dyy - davg1)
519 xx = pos(:, irep + 1) - pos(:, irep)
520 xx = xx/sqrt(dot_product(xx, xx))
521 yy = pos(:, irep) - pos(:, irep - 1)
522 yy = yy/sqrt(dot_product(yy, yy))
524 tang = tang/sqrt(dot_product(tang, tang))
526 xx =
derivative(fes, ipos, iperd, ndim, ngrid, dp_grid)
527 dx(:, irep) = dot_product(dx(:, irep), tang)*tang + &
528 xx - dot_product(xx, tang)*tang
531 dx(:, nreplica) = 0.0_dp
535 DO irep = 1, nreplica
536 ene = ene + fes_rep(irep)
537 IF ((irep == 1) .OR. (irep == nreplica)) cycle
539 norm_dx = sqrt(dot_product(dx(:, irep), dx(:, irep)))
540 IF (norm_dx /= 0.0_dp)
THEN
541 pos(:, irep) = pos(:, irep) - min(0.1_dp, norm_dx)*dx(:, irep)/norm_dx
543 xx = pos(:, irep) - pos_old(:, irep)
544 diff = diff + dot_product(xx, xx)
547 IF (diff <= 1.0e-6_dp)
THEN
551 WRITE (*, *)
"Iteration nr.", iter, sqrt(diff)
554 WRITE (*, *)
"MEP saved on <mep.data> file."
555 CALL open_file(unit_number=unit_nr, file_name=
"mep.data", file_action=
"WRITE", file_status=
"UNKNOWN", file_form=
"FORMATTED")
556 DO irep = 1, nreplica
558 ipos = floor((pos(:, irep) - x0)/dp_grid) + 1
560 fes_rep(irep) = -fes(pnt)
561 WRITE (unit_nr, *) irep, pos(:, nreplica - irep + 1), fes_rep(nreplica - irep + 1)
565 DEALLOCATE (xx, dx, pos, fes_rep, ipos, pos_old, yy, dyy, dxx, davg1, tang, davg2)
585 SUBROUTINE fes_cube_write(idim, fes, pos, ndim, ngrid, dp_grid, x0, ndw, l_fes_int, file)
586 INTEGER,
INTENT(IN) :: idim
587 REAL(kind=
dp),
DIMENSION(:),
POINTER :: fes
588 INTEGER,
DIMENSION(:),
POINTER :: pos
589 INTEGER,
INTENT(IN) :: ndim
590 INTEGER,
DIMENSION(:),
POINTER :: ngrid
591 REAL(kind=
dp),
DIMENSION(:),
POINTER :: dp_grid, x0
592 INTEGER,
INTENT(IN) :: ndw
593 LOGICAL,
INTENT(IN) :: l_fes_int
594 CHARACTER(LEN=80) :: file
596 CHARACTER(LEN=120) :: line
597 CHARACTER(LEN=5) :: label, labelp
598 INTEGER :: i, id(3), ii, iix, iiy, iiz, ix, iy, iz, &
600 INTEGER,
DIMENSION(:),
POINTER :: izat
601 REAL(kind=
dp) :: cell(3, 3), delta(3), dr(3), residual, &
603 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: rho, rhot
604 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xat
609 WRITE (*, *)
'ERROR: GAUSSIAN format can only handle FES on 3 CV !'
613 OPEN (10, file=file, status=
'old')
614 CALL get_val_res(unit=10, section=
"&SUBSYS", subsection=
"&CELL")
615 READ (10, *) label, cell(1, 1), cell(2, 1), cell(3, 1)
616 READ (10, *) label, cell(1, 2), cell(2, 2), cell(3, 2)
617 READ (10, *) label, cell(1, 3), cell(2, 3), cell(3, 3)
618 rt(1) = -(cell(1, 1)/2._dp)
619 rt(2) = -(cell(2, 2)/2._dp)
620 rt(3) = -(cell(3, 3)/2._dp)
622 WRITE (*, *)
'Dumping GAUSSIAN CUBE format'
623 WRITE (*, *)
'Cell vectors'
629 residual = residual + cell(ix, iy)**2
633 IF (residual .GT. 1.0d-6)
THEN
635 WRITE (*, *)
'ERROR: this program can only handle orthogonal cells'
636 WRITE (*, *)
' with vectors pointing in the X, Y and Z directions'
641 WRITE (*, *)
'Cube grid mesh: ', ngrid(1),
'x', ngrid(2),
'x', ngrid(3)
642 WRITE (*, *)
'Origin in:', rt
646 dr(ix) = cell(ix, ix)/real(ngrid(ix), kind=
dp)
649 np = ngrid(1)*ngrid(2)*ngrid(3)
650 ALLOCATE (rho(np), rhot(np))
651 CALL fes_write(123, idim, fes, pos, ndim, ngrid, dp_grid, x0, ndw, l_fes_int, rho)
652 WRITE (*, *)
'Internal FES transfer completed!'
656 delta(ix) = rt(ix)/dr(ix)
657 id(ix) = int(delta(ix))
658 delta(ix) = rt(ix) - id(ix)*dr(ix)
667 IF (iix .LT. 1) iix = iix + ngrid(1)
668 IF (iiy .LT. 1) iiy = iiy + ngrid(2)
669 IF (iiz .LT. 1) iiz = iiz + ngrid(3)
670 IF (iix .GT. ngrid(1)) iix = iix - ngrid(1)
671 IF (iiy .GT. ngrid(2)) iiy = iiy - ngrid(2)
672 IF (iiz .GT. ngrid(3)) iiz = iiz - ngrid(3)
674 IF (iix .LT. 1) cpabort(
"ix < 0")
675 IF (iiy .LT. 1) cpabort(
"iy < 0")
676 IF (iiz .LT. 1) cpabort(
"iz < 0")
677 IF (iix .GT. ngrid(1)) cpabort(
"ix > cell")
678 IF (iiy .GT. ngrid(2)) cpabort(
"iy > cell")
679 IF (iiz .GT. ngrid(3)) cpabort(
"iz > cell")
680 i = ix + (iy - 1)*ngrid(1) + (iz - 1)*ngrid(1)*ngrid(2)
681 ii = iix + (iiy - 1)*ngrid(1) + (iiz - 1)*ngrid(1)*ngrid(2)
688 CALL get_val_res(unit=10, section=
"&SUBSYS", subsection=
"&COORD")
690 ALLOCATE (xat(1000, 3))
691 ALLOCATE (izat(1000))
693 READ (10,
'(A)') line
694 IF (index(line,
'&END') /= 0)
EXIT
696 READ (line, *) label, (xat(natoms, ix), ix=1, 3)
697 IF (natoms ==
SIZE(xat, 1))
THEN
698 CALL reallocate(xat, 1,
SIZE(xat, 1)*2, 1, 3)
699 CALL reallocate(izat, 1,
SIZE(izat)*2)
705 IF (trim(label) == trim(labelp))
EXIT
707 IF (i ==
nelem + 1)
THEN
708 WRITE (*, *) trim(label),
"In line: ", line
709 cpabort(
"Element not recognized!")
713 CALL reallocate(xat, 1, natoms, 1, 3)
714 CALL reallocate(izat, 1, natoms)
718 xat(i, ix) = xat(i, ix) + rt(ix) - delta(ix)
719 IF (xat(i, ix) .LT. rt(ix)) xat(i, ix) = xat(i, ix) + cell(ix, ix)
720 IF (xat(i, ix) .GT. -rt(ix)) xat(i, ix) = xat(i, ix) - cell(ix, ix)
724 WRITE (123, *)
"FES on CUBE"
725 WRITE (123, *)
"created by fes in CP2K"
726 WRITE (123,
'(i5,3f12.6)') natoms, rt(1:3)*
bohr
730 WRITE (123,
'(i5,4f12.6)') ii, (cell(ix, iy)/ii*
bohr, iy=1, 3)
734 WRITE (123,
'(i5,4f12.6)') izat(i), 0.0, (xat(i, ix)*
bohr, ix=1, 3)
740 WRITE (123,
'(6e13.5)') (rhot(ix + (iy - 1)*ngrid(1) + (iz - 1)*ngrid(1)&
741 &*ngrid(2)), iz=1, ngrid(3))
744 DEALLOCATE (xat, rho, rhot)
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Program to Map on grid the hills spawned during a metadynamics run.
subroutine, public fes_min(fes, ndim, iperd, ngrid, dp_grid, x0, ndw)
Finds minima of the FES.
recursive subroutine, public fes_compute_low(idim, nn, fes, gauss, ind, ind0, nfes, ndim, ngauss, ngrid, iperd)
Efficiently map the gaussians on the grid.
subroutine, public fes_cube_write(idim, fes, pos, ndim, ngrid, dp_grid, x0, ndw, l_fes_int, file)
Dump FES with a GAUSSIAN cube format - Useful for multidimensional FES.
recursive subroutine, public fes_write(unit_nr, idim, fes, pos, ndim, ngrid, dp_grid, x0, ndw, l_fes_int, array)
Writes the FES on the file.
recursive subroutine, public fes_only_write(idim, fes, pos, ndim, ngrid, dp_grid, ndw, l_fes_int, unit_nr)
Writes the FES on the file when stride is requested.
subroutine, public fes_path(fes, ndim, ngrid, dp_grid, iperd, x0, ndw, mep_input_data, l_int)
Finds path between two points (a) and (b)
Module containing utils for mapping FESs.
real(kind=dp) function, dimension(ndim), public derivative(fes, pos0, iperd, ndim, ngrid, dp_grid)
computes the derivative of the FES w.r.t CVs
subroutine, public get_val_res(unit, section, keyword, subsection, i_val, r_val)
Parser informations from the cp2k input/restart.
integer function, public point_no_pbc(pos, ngrid, ndim)
Computes the pointer to the 1D array given the n-dimensional position non-PBC version.
subroutine, public pbc(pos, iperd, ngrid, ndim)
Computes the pointer to the 1D array given the n-dimensional position PBC version.
integer function, public point_pbc(pos, iperd, ngrid, ndim)
Computes the pointer to the 1D array given the n-dimensional position PBC version.
Defines the basic variable types.
integer, parameter, public dp
Utility routines for the memory handling.
Periodic Table related data definitions.
type(atom), dimension(0:nelem), public ptable
subroutine, public init_periodic_table()
Initialization of Periodic Table related data.
integer, parameter, public nelem
Definition of physical constants:
real(kind=dp), parameter, public bohr
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.