111 lines
3.8 KiB
Fortran
111 lines
3.8 KiB
Fortran
module callback
|
|
implicit none
|
|
contains
|
|
subroutine fortran_callback(lmp, timestep, nlocal, ids, c_pos, c_fext) &
|
|
& bind(C, name='f_callback')
|
|
use, intrinsic :: ISO_C_binding
|
|
use LAMMPS
|
|
implicit none
|
|
type (C_ptr), value :: lmp
|
|
integer(C_int64_t), intent(in), value :: timestep
|
|
integer(C_int), intent(in), value :: nlocal
|
|
real (C_double), dimension(:,:), pointer :: x
|
|
type(c_ptr) :: c_pos, c_fext, c_ids
|
|
double precision, pointer :: fext(:,:), pos(:,:)
|
|
integer, intent(in) :: ids(nlocal)
|
|
real(C_double) :: virial(6)
|
|
real (C_double) :: etot
|
|
real(C_double), pointer :: ts_lmp
|
|
double precision :: stress(3,3), ts_dftb
|
|
integer :: natom , i
|
|
real (C_double), parameter :: econv = 627.4947284155114 ! converts from Ha to
|
|
double precision, parameter :: fconv = 1185.793095983065 ! converts from Ha/bohr to
|
|
double precision, parameter :: autoatm = 2.9037166638E8
|
|
double precision lx, ly, lz
|
|
real (C_double), pointer :: boxxlo, boxxhi
|
|
real (C_double), pointer :: boxylo, boxyhi
|
|
real (C_double), pointer :: boxzlo, boxzhi
|
|
double precision, parameter :: nktv2p = 68568.4149999999935972
|
|
double precision :: volume
|
|
type (C_ptr) :: Cptr
|
|
type (C_ptr), pointer, dimension(:) :: Catom
|
|
|
|
call c_f_pointer(c_pos, pos, [3,nlocal])
|
|
call c_f_pointer(c_fext, fext, [3,nlocal])
|
|
call lammps_extract_global(boxxlo, lmp, 'boxxlo')
|
|
call lammps_extract_global(boxxhi, lmp, 'boxxhi')
|
|
call lammps_extract_global(boxylo, lmp, 'boxylo')
|
|
call lammps_extract_global(boxyhi, lmp, 'boxyhi')
|
|
call lammps_extract_global(boxzlo, lmp, 'boxzlo')
|
|
call lammps_extract_global(boxzhi, lmp, 'boxzhi')
|
|
lx = boxxhi - boxxlo
|
|
ly = boxyhi - boxylo
|
|
lz = boxzhi - boxzlo
|
|
volume = lx*ly*lz
|
|
open (unit = 10, status = 'replace', action = 'write', file='lammps.gen')
|
|
write(10,*)nlocal,"S"
|
|
write(10,*) "C"
|
|
do i = 1, nlocal
|
|
write(10,'(2I,3F15.6)')i,1,pos(:,ids(i))
|
|
enddo
|
|
write(10,*)"0.0 0.0 0.0"
|
|
write(10,*)lx,0,0
|
|
write(10,*)0,ly,0
|
|
write(10,*)0,0,lz
|
|
close(10)
|
|
call system("./dftb+ > dftb.out")
|
|
open (unit = 10, status = 'old', file = 'results.out')
|
|
read(10,*)etot
|
|
read(10,*)ts_dftb
|
|
do i = 1, 3
|
|
read(10,*)stress(i,:)
|
|
enddo
|
|
stress (:,:) = stress(:,:)*autoatm
|
|
virial(1) = stress(1,1)/(nktv2p/volume)
|
|
virial(2) = stress(2,2)/(nktv2p/volume)
|
|
virial(3) = stress(3,3)/(nktv2p/volume)
|
|
virial(4) = stress(1,2)/(nktv2p/volume)
|
|
virial(5) = stress(1,3)/(nktv2p/volume)
|
|
virial(6) = stress(2,3)/(nktv2p/volume)
|
|
etot = etot*econv
|
|
call lammps_set_external_vector(lmp,1,ts_dftb*econv)
|
|
do i = 1, nlocal
|
|
read(10,*)fext(:,ids(i))
|
|
fext(:,ids(i)) = fext(:,ids(i))*fconv
|
|
enddo
|
|
close(10)
|
|
call lammps_set_user_energy (lmp, etot)
|
|
call lammps_set_user_virial (lmp, virial)
|
|
|
|
end subroutine
|
|
end module callback
|
|
|
|
|
|
program simple_fortran_callback
|
|
|
|
use MPI
|
|
use LAMMPS
|
|
use callback
|
|
use, intrinsic :: ISO_C_binding, only : C_double, C_ptr, C_int, C_FUNPTR
|
|
implicit none
|
|
type (C_ptr) :: lmp
|
|
integer :: error, narg, me, nprocs
|
|
|
|
call MPI_Init (error)
|
|
call MPI_Comm_rank (MPI_COMM_WORLD, me, error)
|
|
call MPI_Comm_size (MPI_COMM_WORLD, nprocs, error)
|
|
|
|
call lammps_open_no_mpi ('lmp -log log.simple', lmp)
|
|
call lammps_file (lmp, 'in.simple')
|
|
call lammps_set_callback(lmp)
|
|
call lammps_set_external_vector_length(lmp,2)
|
|
|
|
call lammps_command (lmp, 'run 10')
|
|
call lammps_close (lmp)
|
|
call MPI_Finalize (error)
|
|
|
|
|
|
end program simple_fortran_callback
|
|
|
|
|