I'm trying to convert my OpenKIM model as QUIP potential code to the
new API and F2003 pointers. I have a routine which I'm going to
register as a get_neigh method. I'm using a kim buffer to store some
data that needs to be communicated. Relevant source is below. When I
try to compile it, I get the following errors:
/Users/bernstei/src/work/QUIP/source/QUIP/QUIP_Core/IPModel_KIM.f95:287.23:
p_neigh_list = c_loc(buf%neigh_list)
1
Error: Argument 'buf' to 'c_loc' at (1) must be an associated scalar POINTER
/Users/bernstei/src/work/QUIP/source/QUIP/QUIP_Core/IPModel_KIM.f95:288.22:
p_neigh_rij = c_loc(buf%neigh_rij)
1
Error: Argument 'buf' to 'c_loc' at (1) must be an associated scalar POINTER
I have no idea why those calls to c_loc are invalid. This is with
gfortran 4.8.2 on OS X.
Any ideas?
thanks,
Noam
!!!!! start of code !!!!!!!
type quip_kim_buffer
integer :: kim_iterator_current_i = -1
type(Atoms), pointer :: kim_at => null()
integer(c_int), pointer :: neigh_list( => null()
real(c_double), pointer :: neigh_rij(:, => null()
end type quip_kim_buffer
function quip_neighbour_iterator(pkim, iterator_mode, request, atom,
nneigh, p_neigh_list, p_neigh_rij) bind(c) result(outval)
type(c_ptr) :: pkim
integer(c_int) :: iterator_mode, request, atom, nneigh
type(c_ptr) :: p_neigh_list
type(c_ptr) :: p_neigh_rij
integer(c_int) :: outval ! result
type(quip_kim_buffer), pointer :: buf; type(c_ptr) :: p_buf
integer :: kim_error
integer :: ji
real(dp) :: drij(3)
p_buf = kim_api_get_model_buffer(pkim, kim_error)
if (kim_error < KIM_STATUS_OK) then
call system_abort("quip_neighbor_iterator failed to get kim buffer
with error "//kim_error)
endif
call c_f_pointer(p_buf, buf)
if (iterator_mode == 1) then ! locator mode
if (request < 1 .or. request > buf%kim_at%N) then
outval = KIM_STATUS_NEIGH_INVALID_REQUEST
return
endif
atom = request
else if (iterator_mode == 0) then ! iterator mode
if (request == 0) then
buf%kim_iterator_current_i = 1
outval = KIM_STATUS_NEIGH_ITER_INIT_OK
return
else if (request == 1) then
if (buf%kim_iterator_current_i > buf%kim_at%N) then
outval = KIM_STATUS_NEIGH_ITER_PAST_END
return
endif
atom = buf%kim_iterator_current_i
buf%kim_iterator_current_i = buf%kim_iterator_current_i + 1
else ! other iterator requests
outval = KIM_STATUS_NEIGH_INVALID_REQUEST
return
endif
else ! other mode
outval = KIM_STATUS_NEIGH_INVALID_MODE
return
endif
nneigh = n_neighbours(buf%kim_at, atom)
if (associated(buf%neigh_list)) then
if (size(buf%neigh_list) < nneigh) deallocate(buf%neigh_list)
endif
if (.not. associated(buf%neigh_list)) allocate(buf%neigh_list(nneigh))
if (associated(buf%neigh_rij)) then
if (size(buf%neigh_rij,2) < nneigh) deallocate(buf%neigh_rij)
endif
if (.not. associated(buf%neigh_rij)) allocate(buf%neigh_rij(3,nneigh))
p_neigh_list = c_loc(buf%neigh_list)
p_neigh_rij = c_loc(buf%neigh_rij)
do ji=1, nneigh
buf%neigh_list(ji) = neighbour(buf%kim_at, atom, ji, diff = drij)
buf%neigh_rij(1:3,ji) = drij
end do
outval = KIM_STATUS_OK
end function quip_neighbour_iterator