Skip to content

Commit

Permalink
Merge pull request i-pi#272 from sabia-group/instanton3
Browse files Browse the repository at this point in the history
Instanton3 (Position dependent RPI)
  • Loading branch information
mahrossi authored Mar 7, 2024
2 parents 59c56e0 + 21d4307 commit 5550ce1
Show file tree
Hide file tree
Showing 84 changed files with 6,268 additions and 586 deletions.
1 change: 1 addition & 0 deletions bin/i-pi-driver-py
5 changes: 4 additions & 1 deletion drivers/f90/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
.PHONY: all modules clean

FLAGS=-g -O3 -Wall
#FLAGS=-g -O0 -Wall -fbacktrace
CFLAGS=$(FLAGS)
FFLAGS=$(FLAGS) -ffree-line-length-none -ffixed-line-length-none -Wno-maybe-uninitialized
#FFLAGS=-g -O0 -fcheck=all -Wall -pedantic -ffree-line-length-none

MODULES=distance.f90 LJ.f90 SG.f90 pes/pswater.f90 pes/LEPS.f90 LJPolymer.f90 pes/efield.f90 pes/eckart.f90 pes/doublewell.f90 pes/doublewell_1D.f90 pes/MB.f90

MODULES=distance.f90 LJ.f90 SG.f90 pes/pswater.f90 pes/LEPS.f90 LJPolymer.f90 pes/efield.f90 pes/eckart.f90 pes/doublewell.f90 pes/doublewell_1D.f90 pes/MB.f90 pes/harmonic_bath.f90
PES=pes/zundel.f pes/morse.f pes/qtip4pf.f pes/utility.f pes/ch52008.f pes/h2o_dip_pol.f

OBJECTS=$(MODULES:%.f90=%.o) $(PES:%.f=%.o)
FC=gfortran
CC=gcc
Expand Down
106 changes: 95 additions & 11 deletions drivers/f90/driver.f90
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ PROGRAM DRIVER
INTEGER, ALLOCATABLE :: seed(:)
INTEGER verbose
INTEGER commas(4), par_count ! stores the index of commas in the parameter string
DOUBLE PRECISION vpars(4) ! array to store the parameters of the potential

DOUBLE PRECISION vpars(6) ! array to store the parameters of the potential
! SOCKET COMMUNICATION BUFFERS
CHARACTER(LEN=12) :: header
LOGICAL :: isinit=.false., hasdata=.false.
Expand All @@ -68,6 +68,7 @@ PROGRAM DRIVER
DOUBLE PRECISION, ALLOCATABLE :: friction(:,:)
DOUBLE PRECISION volume
DOUBLE PRECISION, PARAMETER :: fddx = 1.0d-5

DOUBLE PRECISION, ALLOCATABLE :: dipz_der(:, :) ! Dipole (z-component) derivative (water_dip_pol model)
DOUBLE PRECISION :: pol(3, 3) !Polarizability (water_dip_pol model)

Expand All @@ -80,7 +81,7 @@ PROGRAM DRIVER
! DMW
DOUBLE PRECISION efield(3)
INTEGER i, j

! parse the command line parameters
! intialize defaults
ccmd = 0
Expand Down Expand Up @@ -168,8 +169,12 @@ PROGRAM DRIVER
vstyle = 26
ELSEIF (trim(cmdbuffer) == "qtip4pf-sr") THEN
vstyle = 27
ELSEIF (trim(cmdbuffer) == "water_dip_pol") THEN
ELSEIF (trim(cmdbuffer) == "harmonic_bath") THEN
vstyle = 28
ELSEIF (trim(cmdbuffer) == "meanfield_bath") THEN
vstyle = 29
ELSEIF (trim(cmdbuffer) == "water_dip_pol") THEN
vstyle = 31
ELSEIF (trim(cmdbuffer) == "qtip4pf-c-1") THEN
vstyle = 60
ELSEIF (trim(cmdbuffer) == "qtip4pf-c-2") THEN
Expand All @@ -186,7 +191,7 @@ PROGRAM DRIVER
vstyle = 99 ! returns non-zero but otherwise meaningless values
ELSE
WRITE(*,*) " Unrecognized potential type ", trim(cmdbuffer)
WRITE(*,*) " Use -m [dummy|gas|lj|sg|harm|harm3d|morse|morsedia|zundel|qtip4pf|pswater|lepsm1|lepsm2|qtip4pf-efield|eckart|ch4hcbe|ljpolymer|MB|doublewell|doublewell_1D|water_dip_pol|qtip4pf-sr|qtip4pf-c-1|qtip4pf-c-2|qtip4pf-c-json|qtip4pf-c-1-delta|qtip4pf-c-2-delta] "
WRITE(*,*) " Use -m [dummy|gas|lj|sg|harm|harm3d|morse|morsedia|zundel|qtip4pf|pswater|lepsm1|lepsm2|qtip4pf-efield|eckart|ch4hcbe|ljpolymer|MB|doublewell|doublewell_1D|water_dip_pol|qtip4pf-sr|qtip4pf-c-1|qtip4pf-c-2|qtip4pf-c-json|qtip4pf-c-1-delta|qtip4pf-c-2-delta|harmonic_bath|meanfield_bath] "
STOP "ENDED"
ENDIF
ELSEIF (ccmd == 4) THEN
Expand Down Expand Up @@ -297,6 +302,39 @@ PROGRAM DRIVER
STOP "ENDED"
ENDIF
isinit = .true.
ELSEIF (28 == vstyle) THEN !harmonic_bath
WRITE(*,*) "This driver implementation is deprecated. Please use the python driver version "
STOP "ENDED"
IF (par_count == 3) THEN ! defaults values
vpars(4) = 0
vpars(5) = 0
vpars(6) = 1
ELSEIF (par_count /= 6) THEN
WRITE(*,*) "Error: parameters not initialized correctly."
WRITE(*,*) "For harmonic bath use <bath_type> <friction (atomic units)> <omega_c (invcm)> eps(a.u.) delta (a.u.) deltaQ(a.u.)"
WRITE(*,*) "Available bath_type are: "
WRITE(*,*) "1 = Ohmic "
STOP "ENDED"
ENDIF
IF (vpars(1) /= 1) THEN
WRITE(*,*) "Only Ohmic bath implemented"
STOP "ENDED"
END IF
vpars(3) = vpars(3) * 4.5563353e-06 !Change omega_c from invcm to a.u.
isinit = .true.
ELSEIF (29 == vstyle) THEN !meanfield bath
WRITE(*,*) "This driver implementation is deprecated. Please use the python driver version "
STOP "ENDED"
IF (par_count == 3) THEN ! defaults values
vpars(2) = 0
vpars(3) = 0
vpars(4) = 1
ELSEIF (par_count /= 4) THEN
WRITE(*,*) "Error: parameters not initialized correctly."
WRITE(*,*) "For harmonic meanfield bath use <friction (atomic units)> eps(a.u.) delta (a.u.) deltaQ(a.u.)"
STOP "ENDED"
ENDIF
isinit = .true.
ELSEIF (22 == vstyle) THEN !ljpolymer
IF (4/= par_count) THEN
WRITE(*,*) "Error: parameters not initialized correctly."
Expand Down Expand Up @@ -408,7 +446,7 @@ PROGRAM DRIVER
WRITE(*,*) "For morse potential use -o r0,D,a (in a.u.) "
STOP "ENDED"
ENDIF
ELSEIF (vstyle == 28) THEN !water dipole and polarizability
ELSEIF (vstyle == 31) THEN !water dipole and polarizability
IF (par_count == 0) THEN
vpars(1) = 1
ELSEIF (par_count /= 1 .OR. (vpars(1) /= 0 .AND. vpars(1) /= 1)) THEN
Expand Down Expand Up @@ -769,6 +807,9 @@ PROGRAM DRIVER
atoms(3,:)=vecdiff(:)
! O in center
atoms(1,:)=0.d0



atoms = atoms*0.52917721d0 ! pot_nasa wants angstrom
call pot_nasa(atoms, forces, pot)
call dms_nasa(atoms, charges, dummy) ! MR: trying to print out the right charges
Expand All @@ -792,7 +833,10 @@ PROGRAM DRIVER

ELSEIF (vstyle == 20) THEN ! eckart potential.
CALL geteckart(nat,vpars(1), vpars(2), vpars(3),vpars(4), atoms, pot, forces)

ELSEIF (vstyle == 28) THEN ! harmonic_bath.
CALL get_harmonic_bath(nat,vpars(1),vpars(2),vpars(3),vpars(4),vpars(5),vpars(6),atoms, pot, forces)
ELSEIF (vstyle == 29) THEN ! meanfield_bath.
CALL get_meanfield_harmonic_bath(nat,vpars(1),vpars(2),vpars(3),vpars(4),atoms, pot, forces,friction)
ELSEIF (vstyle == 23) THEN ! MB.
IF (nat/=1) THEN
WRITE(*,*) "Expecting 1 atom for MB"
Expand All @@ -809,7 +853,7 @@ PROGRAM DRIVER
CALL dw1d_friction(nat, atoms, friction)
CALL dw1d_dipole(nat, atoms, dip)

ELSEIF (vstyle == 28) THEN ! Sets force and potential to zero,
ELSEIF (vstyle == 31) THEN ! Sets force and potential to zero,
! computes only dipole moment, its gradient, and polarizability.
pot = 0
forces = 0.0d0
Expand Down Expand Up @@ -878,7 +922,45 @@ PROGRAM DRIVER
CALL writebuffer(socket,reshape(virial,(/9/)),9) ! Writing the virial tensor, NOT divided by the volume
IF (verbose > 1) WRITE(*,*) " !write!=> strss: ", reshape(virial,(/9/))

IF (vstyle==24 .or. vstyle==25) THEN ! returns fantasy friction
125 format(es21.14,a,es21.14,a,es21.14,a,es21.14,a,es21.14,a,es21.14,a)
126 format(es21.14,a,es21.14,a,es21.14,a,es21.14,a,es21.14,a)

IF (vstyle == 29) THEN ! returns meanfield friction
WRITE(initbuffer,'(a)') "{"
WRITE(32,'(a)') '{'
WRITE(string,'(a)') '"friction": ['
WRITE(32,'(a)') '"friction": ['

string2 = TRIM(initbuffer) // TRIM(string)
initbuffer = TRIM(string2)
DO i=1,3*nat
IF(i/=3*nat) THEN
WRITE(string,125) ( friction(i,j), "," , j=1,3*nat)
WRITE(32,125) ( friction(i,j), "," , j=1,3*nat)
ELSE
WRITE(string,126) ( friction(i,j), "," , j=1,3*nat-1)
WRITE(string2,'(es21.14)') friction(i,3*nat)
string3 = TRIM(string) // TRIM(string2)
string = string3
WRITE(32,126) ( friction(i,j), "," , j=1,3*nat-1)
WRITE(32,'(es21.14)') friction(i,3*nat)
ENDIF
string2 = TRIM(initbuffer) // TRIM(string)
initbuffer = TRIM(string2)
END DO
string = TRIM(initbuffer) // ']}'
initbuffer = TRIM(string)
WRITE(32,'(a)') "]"
WRITE(32,'(a)') "}"

cbuf = LEN_TRIM(initbuffer)
CALL writebuffer(socket,cbuf)

IF (verbose > 1) WRITE(*,*) "!write!=> extra_length:", cbuf
CALL writebuffer(socket,initbuffer,cbuf)
IF (verbose > 1) WRITE(*,*) " !write!=> extra: ", initbuffer

ELSEIF (vstyle==24 .or. vstyle==25) THEN ! returns fantasy friction
WRITE(initbuffer,'(a)') "{"
WRITE(string, '(a,3x,f15.8,a,f15.8,a,f15.8,&
& 3x,a)') '"dipole": [',dip(1),",",dip(2),",",dip(3),"],"
Expand Down Expand Up @@ -921,7 +1003,7 @@ PROGRAM DRIVER
IF (verbose > 1) WRITE(*,*) " !write!=> extra: ", &
& initbuffer(1:cbuf)

ELSEIF (vstyle==28) THEN ! returns the dipole, dipole derivative, and polarizability through initbuffer
ELSEIF (vstyle==31) THEN ! returns the dipole, dipole derivative, and polarizability through initbuffer
WRITE(string, '(a,3x,f15.8,a,f15.8,a,f15.8, 3x,a)') '{"dipole": [',dip(1),",",dip(2),",",dip(3),"],"
longbuffer = TRIM(string)
WRITE(string2, *) "(a,3x,", 3*nat - 1, '(f15.8, ","),f15.8,3x,a)'
Expand Down Expand Up @@ -964,7 +1046,9 @@ PROGRAM DRIVER
CONTAINS
SUBROUTINE helpmessage
! Help banner
WRITE(*,*) " SYNTAX: driver.x [-u] -a address -p port -m [dummy|gas|lj|sg|harm|harm3d|morse|morsedia|zundel|qtip4pf|pswater|lepsm1|lepsm2|qtip4p-efield|eckart|ch4hcbe|ljpolymer|MB|doublewell|doublewell_1D|water_dip_pol|qtip4pf-sr|qtip4pf-c-1|qtip4pf-c-2|qtip4pf-c-json]"

WRITE(*,*) " SYNTAX: driver.x [-u] -h hostname -p port -m [dummy|gas|lj|sg|harm|harm3d|morse|zundel|qtip4pf|pswater|lepsm1|lepsm2|qtip4p-efield|eckart|ch4hcbe|ljpolymer|..."
WRITE(*,*) "...|MB|doublewell|doublewell_1D|harmonic_bath|meanfield_bath|morsedia|qtip4pf-sr|water_dip_pol]"
WRITE(*,*) " -o 'comma_separated_parameters' [-v] "
WRITE(*,*) ""
WRITE(*,*) " For LJ potential use -o sigma,epsilon,cutoff "
Expand Down
125 changes: 125 additions & 0 deletions drivers/f90/pes/harmonic_bath.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
!Harmonic bath

! V(q,x1,..,xn) = sum_1^(nat-1) [ 0.5 m omega_i^2(q - (c_i s(q))/(m omega_i)^2)^2 ]
! s(q) = q *sd(q)
! sd(q) = [1+eps exp( (q-0)^2 / (2deltaQ^2) ) ] + delta tanh(q/deltaQ)
! If eps=delta=0 then sd(q) =1 and s(q) = q


SUBROUTINE get_harmonic_bath(nat,bath_type,friction,omega_c,eps,delta,deltaQ,q,pot,force)
IMPLICIT NONE
integer :: nat, i
real(kind=8),PARAMETER :: pi= 3.141592653589793D0
real(kind=8) :: bath_type,friction,omega_c,mass
real(kind=8) :: eps,delta,deltaQ,S,dSD_dq
real(kind=8) :: A,B
real(kind=8) :: q(nat*3),pot,force(nat*3),x(nat*3-1)
real(kind=8) :: c(nat*3-1),omega(nat*3-1), omega2(nat*3-1),aux
mass = 1837.36223469
pot = 0.0
A = -0.00476705894242374
B = 0.0005980249683218661

DO i = 1, 3*nat -1
x(i) = q(i+1)
ENDDO

!Get omega and c_i
IF (IDINT(bath_type) .EQ. 1 ) THEN !Ohmic
DO i = 1, 3*nat -1
omega(i) = - omega_c * LOG( (i - 0.5 ) / (3*nat-1) )
omega2(i) = omega(i)**2
c(i) = omega(i) * ( ( 2 * friction * mass *omega_c) / ( (3*nat-1) * pi ) )**0.5
ENDDO
END IF

!SYSTEM
pot = A * (q(1) ** 2) + B * (q(1) ** 4)
force(1) = - ( 2 * A * (q(1)) + 4 * B * (q(1) ** 3) )

!BATH
DO i = 1,3*nat-1
aux = x(i) - ( c(i)*S(q(1),eps,delta,deltaQ) / ( mass*omega2(i) ) )

pot = pot + 0.5 * mass * omega2(i) * aux **2
force(1) = force(1) + aux * c(i)*dSD_dq(q(1),eps,delta,deltaQ)
force(i+1) = -mass * omega2(i) * aux


ENDDO

return
end

REAL*8 FUNCTION SD(q,eps,delta,deltaQ)
IMPLICIT NONE
real(kind=8), intent(in) :: q,eps,delta,deltaQ ! q system position
real(kind=8) :: dx

dx = q / deltaQ
SD = 1.0 + eps*DEXP(-0.5 * (dx**2) ) + delta*DTANH(dx)
!write(6,*) 'ALBERTO', 1,eps, dx, DEXP(-0.5 * (dx**2) ), eps*DEXP(-0.5 * (dx**2) )
END FUNCTION SD

REAL*8 FUNCTION S(q,eps,delta,deltaQ)
IMPLICIT NONE
real(kind=8), intent(in) :: q,eps,delta,deltaQ
real(kind=8) :: SD
S = q* SD(q,eps,delta,deltaQ)
END FUNCTION S

REAL*8 FUNCTION dSD_dq(q,eps,delta,deltaQ)
IMPLICIT NONE
real(kind=8), intent(in) :: q,eps,delta,deltaQ
real(kind=8) :: dx,dsddq1,dsddq2,SD
dx = q / deltaQ
dsddq1 = eps*DEXP(-0.5 * (dx**2))*(-dx/deltaQ)
dsddq2 = delta* (1- DTANH(DX)**2) / deltaQ
dSD_dq = q *(dsddq1 + dsddq2) + SD(q,eps,delta,deltaQ)

END FUNCTION dSD_dq

SUBROUTINE get_meanfield_harmonic_bath(nat,eta,eps,delta,deltaQ,q,pot,force,friction)
IMPLICIT NONE
integer :: nat, i
real(kind=8) :: A,B,k,eta
real(kind=8) :: eps,delta,deltaQ,dSD_dq
real(kind=8) :: x,y,z,fx,fy,fz
real(kind=8) :: q(nat,3),pot,force(nat,3)
real(kind=8) :: friction(3*nat,3*nat)

k = 1836*(3800.0d0/219323d0)**2

A = -0.00476705894242374
B = 0.0005980249683218661

DO i = 1,nat
x = q(i,1)
y = q(i,2)
z = q(i,3)

pot = 0.0

pot = pot+ 0.5*k*y**2
fy = -k*y
pot = pot+ 0.5*k*z**2
fz = -k*z

pot = pot + A * (x ** 2) + B * (x ** 4)


fx = - ( 2 * A * (x) + 4 * B * (x ** 3) )

force(i,1) = fx
force(i,2) = fy
force(i,3) = fz

friction(nat*3*(i-1)+1,nat*3*(i-1)+1) = eta * (dSD_dq(x,eps,delta,deltaQ) )**2
friction(nat*3*(i-1)+2,nat*3*(i-1)+2) = 0 !eta * (dSD_dq(y,eps,delta,deltaQ) )**2
friction(nat*3*(i-1)+3,nat*3*(i-1)+3) = 0 !eta * (dSD_dq(z,eps,delta,deltaQ) )**2

ENDDO

return
end

1 change: 1 addition & 0 deletions drivers/py/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import argparse
import numpy as np


try:
from pes import *
except ImportError:
Expand Down
7 changes: 4 additions & 3 deletions drivers/py/pes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
__drivers__[driver_name] = getattr(module, driver_class)
globals()[driver_class] = getattr(module, driver_class) # add class to globals
else:
raise ImportError(
f"PES module `{module_name}` does not define __DRIVER_CLASS__ and __DRIVER_NAME__"
)
if driver_class != "driver_tools":
raise ImportError(
f"PES module `{module_name}` does not define __DRIVER_CLASS__ and __DRIVER_NAME__"
)

__all__.append("__drivers__")
Loading

0 comments on commit 5550ce1

Please sign in to comment.