Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(ommp_nonbonded_type), | intent(inout) | :: | vdw |
Non-bonded structure to be initialized |
||
type(ommp_topology_type), | intent(inout) | :: | top |
Topology structure |
||
character(len=OMMP_STR_CHAR_MAX), | intent(in) | :: | prm_buf(:) |
Char buffer containing the prm file loaded in RAM |
subroutine assign_vdw(vdw, top, prm_buf)
use mod_memory, only: mallocate, mfree
use mod_io, only: fatal_error
use mod_nonbonded, only: ommp_nonbonded_type, vdw_init, vdw_set_pair
use mod_constants, only: angstrom2au, kcalmol2au, OMMP_DEFAULT_NL_CUTOFF
implicit none
type(ommp_nonbonded_type), intent(inout) :: vdw
!! Non-bonded structure to be initialized
type(ommp_topology_type), intent(inout) :: top
!! Topology structure
character(len=OMMP_STR_CHAR_MAX), intent(in) :: prm_buf(:)
!! Char buffer containing the prm file loaded in RAM
integer(ip) :: il, i, j, l, tokb, toke
character(len=OMMP_STR_CHAR_MAX) :: line, errstring
character(len=20) :: radrule, radsize, radtype, vdwtype, epsrule
integer(ip), allocatable :: vdwat(:), vdwpr_a(:), vdwpr_b(:)
real(rp), allocatable :: vdw_e_prm(:), vdw_r_prm(:), vdw_f_prm(:), &
vdwpr_r(:), vdwpr_e(:)
integer(ip) :: nvdw, ivdw, atc, nvdwpr, ivdwpr
logical :: done
logical(lp), allocatable :: maska(:), maskb(:)
if(.not. top%atclass_initialized .or. .not. top%atz_initialized) then
call read_atom_cards(top, prm_buf)
end if
! Read all the lines of file just to count how large vector should be
! allocated
nvdw = 0
nvdwpr = 0
do il=1, size(prm_buf)
line = prm_buf(il)
if(line(:4) == 'vdw ') nvdw = nvdw + 1
if(line(:6) == 'vdwpr ' .or. line(:8) == 'vdwpair ') &
nvdwpr = nvdwpr + 1
end do
! VDW
call mallocate('read_prm [vdwat]', nvdw, vdwat)
call mallocate('read_prm [vdw_r_prm]', nvdw, vdw_r_prm)
call mallocate('read_prm [vdw_e_prm]', nvdw, vdw_e_prm)
call mallocate('read_prm [vdw_f_prm]', nvdw, vdw_f_prm)
vdw_f_prm = 1.0_rp
ivdw = 1
! VDWPR
call mallocate('read_prm [vdwpr_a]', nvdwpr, vdwpr_a)
call mallocate('read_prm [vdwpr_b]', nvdwpr, vdwpr_b)
call mallocate('read_prm [vdwpr_e]', nvdwpr, vdwpr_e)
call mallocate('read_prm [vdwpr_r]', nvdwpr, vdwpr_r)
allocate(maska(top%mm_atoms), maskb(top%mm_atoms))
ivdwpr = 1
! Default rules for VDW (from Tinker Manual)
radrule = "arithmetic"
radsize = "radius"
radtype = "r-min"
vdwtype = "lennard-jones"
epsrule = "geometric"
! Those are defaults defined in Tinker manual
vdw%vdw_screening = [0.0, 0.0, 1.0, 1.0]
! Restart the reading from the beginning to actually save the parameters
i=1
do il=1, size(prm_buf)
line = prm_buf(il)
if(line(:13) == 'vdw-12-scale ') then
tokb = 14
toke = tokenize(line, tokb)
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDW-12-SCALE card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdw%vdw_screening(1)
if(vdw%vdw_screening(1) > 1.0) &
vdw%vdw_screening(1) = 1/vdw%vdw_screening(1)
else if(line(:13) == 'vdw-13-scale ') then
tokb = 14
toke = tokenize(line, tokb)
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDW-13-SCALE card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdw%vdw_screening(2)
if(vdw%vdw_screening(2) > 1.0) &
vdw%vdw_screening(2) = 1/vdw%vdw_screening(2)
else if(line(:13) == 'vdw-14-scale ') then
tokb = 14
toke = tokenize(line, tokb)
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDW-14-SCALE card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdw%vdw_screening(3)
if(vdw%vdw_screening(3) > 1.0) &
vdw%vdw_screening(3) = 1/vdw%vdw_screening(3)
else if(line(:13) == 'vdw-15-scale ') then
tokb = 14
toke = tokenize(line, tokb)
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDW-15-SCALE card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdw%vdw_screening(4)
if(vdw%vdw_screening(4) > 1.0) &
vdw%vdw_screening(4) = 1/vdw%vdw_screening(4)
else if(line(:12) == 'epsilonrule ') then
tokb = 12
toke = tokenize(line, tokb)
read(line(tokb:toke), *) epsrule
else if(line(:8) == 'vdwtype ') then
tokb = 9
toke = tokenize(line, tokb)
read(line(tokb:toke), *) vdwtype
else if(line(:11) == 'radiusrule ') then
tokb = 12
toke = tokenize(line, tokb)
read(line(tokb:toke), *) radrule
else if(line(:11) == 'radiussize ') then
tokb = 12
toke = tokenize(line, tokb)
read(line(tokb:toke), *) radsize
else if(line(:11) == 'radiustype ') then
tokb = 12
toke = tokenize(line, tokb)
read(line(tokb:toke), *) radtype
else if(line(:4) == 'vdw ') then
tokb = 5
toke = tokenize(line, tokb)
if(.not. isint(line(tokb:toke))) then
write(errstring, *) "Wrong VDW card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdwat(ivdw)
tokb = toke + 1
toke = tokenize(line, tokb)
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDW card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdw_r_prm(ivdw)
tokb = toke + 1
toke = tokenize(line, tokb)
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDW card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdw_e_prm(ivdw)
tokb = toke + 1
toke = tokenize(line, tokb)
if(toke > 0) then
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDW card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdw_f_prm(ivdw)
endif
ivdw = ivdw + 1
else if(line(:6) == 'vdwpr ' .or. line(:8) == 'vdwpair ') then
if(line(:6) == 'vdwpr ') then
tokb = 7
else
tokb = 9
end if
toke = tokenize(line, tokb)
if(.not. isint(line(tokb:toke))) then
write(errstring, *) "Wrong VDWPR card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdwpr_a(ivdwpr)
tokb = toke + 1
toke = tokenize(line, tokb)
if(.not. isint(line(tokb:toke))) then
write(errstring, *) "Wrong VDWPR card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdwpr_b(ivdwpr)
tokb = toke + 1
toke = tokenize(line, tokb)
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDWPR card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdwpr_r(ivdwpr)
tokb = toke + 1
toke = tokenize(line, tokb)
if(.not. isreal(line(tokb:toke))) then
write(errstring, *) "Wrong VDWPR card"
call fatal_error(errstring)
end if
read(line(tokb:toke), *) vdwpr_e(ivdwpr)
ivdwpr = ivdwpr + 1
end if
i = i+1
end do
call vdw_init(vdw, top, vdwtype, radrule, radsize, &
radtype, epsrule, OMMP_DEFAULT_NL_CUTOFF)
!$omp parallel do default(shared) schedule(dynamic) &
!$omp private(i,j,atc,done)
do i=1, top%mm_atoms
! Atom class for current atom
atc = top%atclass(i)
! VdW parameters
done = .false.
do j=1, nvdw
if(vdwat(j) == atc) then
done = .true.
vdw%vdw_e(i) = vdw_e_prm(j) * kcalmol2au
vdw%vdw_r(i) = vdw_r_prm(j) * angstrom2au
vdw%vdw_f(i) = vdw_f_prm(j)
exit
end if
end do
if(.not. done) then
call fatal_error("VdW parameter not found!")
end if
end do
! VdW pair parameters
do l=1, nvdwpr
maska = (top%atclass == vdwpr_a(l))
maskb = (top%atclass == vdwpr_b(l))
call vdw_set_pair(vdw, maska, maskb, &
vdwpr_r(l) * angstrom2au, &
vdwpr_e(l) * kcalmol2au)
end do
call mfree('read_prm [vdwat]', vdwat)
call mfree('read_prm [vdw_r_prm]', vdw_r_prm)
call mfree('read_prm [vdw_e_prm]', vdw_e_prm)
call mfree('read_prm [vdw_f_prm]', vdw_f_prm)
call mfree('read_prm [vdwpr_a]', vdwpr_a)
call mfree('read_prm [vdwpr_b]', vdwpr_b)
call mfree('read_prm [vdwpr_e]', vdwpr_e)
call mfree('read_prm [vdwpr_r]', vdwpr_r)
deallocate(maska, maskb)
end subroutine assign_vdw