32 use,
intrinsic :: iso_c_binding
38 recursive subroutine my_error(message)
40 character(len=*, kind=c_char),
intent(in) :: message
42 print *,
"* Error : ", trim(message)
48 character(len=*, kind=c_char),
intent(in) :: message
50 print *,
"* Warning : ", trim(message)
65 use,
intrinsic :: iso_c_binding
70 real(c_double) :: cutoff
71 integer(c_int) :: number_of_particles
72 type(c_ptr) :: neighbor_list_pointer
83 recursive subroutine get_neigh(data_object, number_of_neighbor_lists, cutoffs, &
84 neighbor_list_index, request, numnei, pnei1part, ierr) bind(c)
89 type(c_ptr),
value,
intent(in) :: data_object
90 integer(c_int),
value,
intent(in) :: number_of_neighbor_lists
91 real(c_double),
intent(in) :: cutoffs(number_of_neighbor_lists)
92 integer(c_int),
value,
intent(in) :: neighbor_list_index
93 integer(c_int),
value,
intent(in) :: request
94 integer(c_int),
intent(out) :: numnei
95 type(c_ptr),
intent(out) :: pnei1part
96 integer(c_int),
intent(out) :: ierr
99 integer(c_int) numberOfParticles
101 integer(c_int),
pointer :: neighborList(:,:)
103 call c_f_pointer(data_object, neighobject)
104 numberofparticles = neighobject%number_of_particles
105 call c_f_pointer(neighobject%neighbor_list_pointer, neighborlist, &
106 [numberofparticles+1, numberofparticles])
108 if (number_of_neighbor_lists /= 1)
then 114 if (cutoffs(1) > neighobject%cutoff)
then 115 call my_warning(
"neighbor list cutoff too small for model cutoff")
120 if (neighbor_list_index /= 1)
then 126 if ( (request.gt.numberofparticles) .or. (request.lt.1))
then 128 call my_warning(
"Invalid part ID in get_neigh")
134 numnei = neighborlist(1,request)
137 pnei1part = c_loc(neighborlist(2,request))
158 coords, cutoff, neighObject)
159 use,
intrinsic :: iso_c_binding
164 logical,
intent(in) :: half
165 integer(c_int),
intent(in) :: numberOfParticles
166 real(c_double),
dimension(3,numberOfParticles), &
168 real(c_double),
intent(in) :: cutoff
172 integer(c_int) i, j, a
175 real(c_double) cutoff2
176 integer(c_int),
pointer :: neighborList(:,:)
178 call c_f_pointer(neighobject%neighbor_list_pointer, neighborlist, &
179 [numberofparticles+1, numberofparticles])
181 neighobject%cutoff = cutoff
185 do i=1,numberofparticles
187 do j=1,numberofparticles
188 dx(:) = coords(:, j) - coords(:, i)
189 r2 = dot_product(dx, dx)
190 if (r2.le.cutoff2)
then 192 if ( (j .gt. i) .OR. ((.not. half) .AND. (i.ne.j)) )
then 194 neighborlist(a,i) = j
199 neighborlist(1,i) = a-1
224 periodic, coords, MiddlePartId)
225 use,
intrinsic :: iso_c_binding
227 integer(c_int),
parameter :: cd = c_double
230 real(c_double),
intent(in) :: FCCspacing
231 integer(c_int),
intent(in) :: nCellsPerSide
232 logical,
intent(in) :: periodic
233 real(c_double),
intent(out) :: coords(3,*)
234 integer(c_int),
intent(out) :: MiddlePartId
238 real(c_double) FCCshifts(3,4)
239 real(c_double) latVec(3)
240 integer(c_int) a, i, j, k, m
244 fccshifts(1,1) = 0.0_cd
245 fccshifts(2,1) = 0.0_cd
246 fccshifts(3,1) = 0.0_cd
247 fccshifts(1,2) = 0.5_cd*fccspacing
248 fccshifts(2,2) = 0.5_cd*fccspacing
249 fccshifts(3,2) = 0.0_cd
250 fccshifts(1,3) = 0.5_cd*fccspacing
251 fccshifts(2,3) = 0.0_cd
252 fccshifts(3,3) = 0.5_cd*fccspacing
253 fccshifts(1,4) = 0.0_cd
254 fccshifts(2,4) = 0.5_cd*fccspacing
255 fccshifts(3,4) = 0.5_cd*fccspacing
260 latvec(1) = (i-1)*fccspacing
262 latvec(2) = (j-1)*fccspacing
264 latvec(3) = (k-1)*fccspacing
267 coords(:,a) = latvec + fccshifts(:,m)
268 if ((i.eq.ncellsperside/2+1).and.(j.eq.ncellsperside/2+1) .and. &
269 (k.eq.ncellsperside/2+1) .and. (m.eq.1))
then 270 coords(:,1) = latvec + fccshifts(:,m)
275 if (.not. periodic)
then 278 latvec(1) = ncellsperside*fccspacing
279 latvec(2) = (i-1)*fccspacing
280 latvec(3) = (j-1)*fccspacing
281 a = a+1; coords(:,a) = latvec
282 a = a+1; coords(:,a) = latvec + fccshifts(:,4)
284 latvec(1) = (i-1)*fccspacing
285 latvec(2) = ncellsperside*fccspacing
286 latvec(3) = (j-1)*fccspacing
287 a = a+1; coords(:,a) = latvec
288 a = a+1; coords(:,a) = latvec + fccshifts(:,3)
290 latvec(1) = (i-1)*fccspacing
291 latvec(2) = (j-1)*fccspacing
292 latvec(3) = ncellsperside*fccspacing
293 a = a+1; coords(:,a) = latvec
294 a = a+1; coords(:,a) = latvec + fccshifts(:,2)
297 if (.not. periodic)
then 299 latvec(1) = (i-1)*fccspacing
300 latvec(2) = ncellsperside*fccspacing
301 latvec(3) = ncellsperside*fccspacing
302 a = a+1; coords(:,a) = latvec
303 latvec(1) = ncellsperside*fccspacing
304 latvec(2) = (i-1)*fccspacing
305 latvec(3) = ncellsperside*fccspacing
306 a = a+1; coords(:,a) = latvec
307 latvec(1) = ncellsperside*fccspacing
308 latvec(2) = ncellsperside*fccspacing
309 latvec(3) = (i-1)*fccspacing
310 a = a+1; coords(:,a) = latvec
313 if (.not. periodic)
then 315 a = a+1; coords(:,a) = ncellsperside*fccspacing
338 use,
intrinsic :: iso_c_binding
345 integer(c_int),
parameter :: cd = c_double
347 integer(c_int),
parameter :: nCellsPerSide = 2
348 integer(c_int),
parameter :: DIM = 3
350 real(c_double),
parameter :: cutpad = 0.75_cd
351 real(c_double),
parameter :: FCCspacing = 5.260_cd
352 real(c_double),
parameter :: min_spacing = 0.8*fccspacing
353 real(c_double),
parameter :: max_spacing = 1.2*fccspacing
354 real(c_double),
parameter :: spacing_incr = 0.025*fccspacing
355 real(c_double) :: current_spacing
356 real(c_double) :: force_norm
358 character(len=256, kind=c_char) :: modelname
360 integer(c_int),
parameter :: &
361 N = 4*(ncellsperside)**3 + 6*(ncellsperside)**2 + 3*(ncellsperside) + 1
364 integer(c_int),
allocatable,
target :: neighborList(:,:)
366 type(kim_model_handle_type) :: model_handle
367 type(kim_compute_arguments_handle_type) :: compute_arguments_handle
368 real(c_double) :: influence_distance
369 integer(c_int) :: number_of_neighbor_lists
370 real(c_double) :: cutoff
371 real(c_double) :: cutoffs(1)
373 model_will_not_request_neighbors_of_noncontributing_particles(1)
374 integer(c_int),
target :: particle_species_codes(n)
375 integer(c_int),
target :: particle_contributing(n)
376 real(c_double),
target :: energy
377 real(c_double),
target :: coords(dim, n)
378 real(c_double),
target :: forces(dim, n)
379 integer(c_int) i, j, ierr, ierr2
381 integer(c_int) species_is_supported
382 integer(c_int) species_code
383 integer(c_int) requested_units_accepted
384 integer(c_int) number_of_model_routine_names
385 type(kim_model_routine_name_type) model_routine_name
386 integer(c_int) present
387 integer(c_int) required
388 type(kim_supported_extensions_type),
target :: supported_extensions
389 character(len=KIM_MAX_EXTENSION_ID_LENGTH, kind=c_char) :: id_string
395 supported_extensions%number_of_supported_extensions = 0
398 print
'("Please enter a valid KIM model name: ")' 403 call kim_model_create(kim_numbering_one_based, &
405 kim_energy_unit_ev, &
407 kim_temperature_unit_k, &
410 requested_units_accepted, &
417 if (requested_units_accepted == 0)
then 418 call my_error(
"Must adapt to model units")
422 call kim_get_number_of_model_routine_names(number_of_model_routine_names)
423 do i=1,number_of_model_routine_names
424 call kim_get_model_routine_name(i, model_routine_name, ierr)
426 call my_error(
"kim_get_model_routine_name")
428 call kim_is_routine_present(model_handle, model_routine_name,
present, &
431 call my_error(
"kim_is_routine_present")
434 if ((
present == 1) .and. (required == 1))
then 435 if (.not. ((model_routine_name == kim_model_routine_name_create) &
436 .or. (model_routine_name == &
437 kim_model_routine_name_compute_arguments_create) &
438 .or. (model_routine_name == kim_model_routine_name_compute) &
439 .or. (model_routine_name == kim_model_routine_name_refresh) &
440 .or. (model_routine_name == &
441 kim_model_routine_name_compute_arguments_destroy) &
442 .or. (model_routine_name == kim_model_routine_name_destroy)))
then 444 call my_error(
"Unknown required ModelRoutineName found.")
451 call kim_get_species_support_and_code(model_handle, &
452 kim_species_name_ar, species_is_supported, species_code, ierr)
453 if ((ierr /= 0) .or. (species_is_supported /= 1))
then 454 call my_error(
"Model does not support Ar")
458 call kim_is_routine_present(model_handle, &
459 kim_model_routine_name_extension,
present, required, ierr)
461 call my_error(
"Unable to get Extension present/required.")
463 if (
present /= 0)
then 465 c_loc(supported_extensions), ierr)
467 call my_error(
"Error returned from kim_model_extension().")
469 write (*,
'(A,I2,A)')
"Model Supports ", &
470 supported_extensions%number_of_supported_extensions, &
472 do i = 1, supported_extensions%number_of_supported_extensions
473 call kim_c_char_array_to_string(&
474 supported_extensions%supported_extension_id(:,i), id_string)
475 write (*,
'(A,I2,A,A,A,A,I2)')
" supportedExtensionID[", i,
'] = "', &
476 trim(id_string),
'" ', &
477 "which has required = ", &
478 supported_extensions%supported_extension_required(i)
486 call kim_compute_arguments_create( &
487 model_handle, compute_arguments_handle, ierr)
489 call my_error(
"kim_model_compute_arguments_create")
494 call kim_set_argument_pointer(compute_arguments_handle, &
495 kim_compute_argument_name_number_of_particles, n, ierr2)
497 call kim_set_argument_pointer(compute_arguments_handle, &
498 kim_compute_argument_name_particle_species_codes, particle_species_codes, &
501 call kim_set_argument_pointer(compute_arguments_handle, &
502 kim_compute_argument_name_particle_contributing, particle_contributing, &
505 call kim_set_argument_pointer(compute_arguments_handle, &
506 kim_compute_argument_name_coordinates, coords, ierr2)
508 call kim_set_argument_pointer(compute_arguments_handle, &
509 kim_compute_argument_name_partial_energy, energy, ierr2)
511 call kim_set_argument_pointer(compute_arguments_handle, &
512 kim_compute_argument_name_partial_forces, forces, ierr2)
515 call my_error(
"set_argument_pointer")
520 allocate(neighborlist(n+1,n))
521 neighobject%neighbor_list_pointer = c_loc(neighborlist)
522 neighobject%number_of_particles = n
526 call kim_set_callback_pointer(compute_arguments_handle, &
527 kim_compute_callback_name_get_neighbor_list, kim_language_name_fortran, &
528 c_funloc(
get_neigh), c_loc(neighobject), ierr)
530 call my_error(
"set_callback_pointer")
533 call kim_get_influence_distance(model_handle, influence_distance)
534 call kim_get_number_of_neighbor_lists(model_handle, &
535 number_of_neighbor_lists)
536 if (number_of_neighbor_lists /= 1)
then 537 call my_error(
"too many neighbor lists")
539 call kim_get_neighbor_list_values(model_handle, cutoffs, &
540 model_will_not_request_neighbors_of_noncontributing_particles, ierr)
542 call my_error(
"get_neighbor_list_values")
549 particle_species_codes(i) = species_code
554 particle_contributing(i) = 1
560 print *,
'This is Test : ex_test_Ar_fcc_cluster_fortran' 563 print
'("Results for KIM Model : ",A)', trim(modelname)
566 print
'(3A20)',
"Energy",
"Force Norm",
"Lattice Spacing" 568 current_spacing = min_spacing
569 do while (current_spacing < max_spacing)
578 call kim_compute(model_handle, compute_arguments_handle, ierr)
580 call my_error(
"kim_api_model_compute")
587 force_norm = force_norm + forces(j,i)*forces(j,i)
590 force_norm = sqrt(force_norm)
594 print
'(3ES20.10)', energy, force_norm, current_spacing
596 current_spacing = current_spacing + spacing_incr
600 deallocate( neighborlist )
602 call kim_compute_arguments_destroy(&
603 model_handle, compute_arguments_handle, ierr)
605 call my_error(
"compute_arguments_destroy")
607 call kim_model_destroy(model_handle)
recursive subroutine, public get_neigh(data_object, number_of_neighbor_lists, cutoffs, neighbor_list_index, request, numnei, pnei1part, ierr)
recursive subroutine my_warning(message)
recursive subroutine neigh_pure_cluster_neighborlist(half, numberOfParticles, coords, cutoff, neighObject)
recursive subroutine my_error(message)
recursive subroutine create_fcc_configuration(FCCspacing, nCellsPerSide, periodic, coords, MiddlePartId)
character(len= *, kind=c_char), parameter, public kim_supported_extensions_id
program ex_test_ar_fcc_cluster_fortran
The only standard extension defined by the KIM API.