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)
64 use,
intrinsic :: iso_c_binding
69 real(c_double) :: cutoff
70 integer(c_int) :: number_of_particles
71 type(c_ptr) :: neighbor_list_pointer
82 recursive subroutine get_neigh(data_object, number_of_neighbor_lists, &
83 cutoffs, neighbor_list_index, request, &
84 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(*)
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 > numberofparticles) .or. (request < 1))
then 128 call my_warning(
"Invalid part ID in get_neigh")
134 numnei = neighborlist(1, request)
137 pnei1part = c_loc(neighborlist(2, request))
157 half, numberOfParticles, coords, cutoff, neighObject)
158 use,
intrinsic :: iso_c_binding
163 logical,
intent(in) :: half
164 integer(c_int),
intent(in) :: numberOfParticles
165 real(c_double),
dimension(3, numberOfParticles), &
167 real(c_double),
intent(in) :: cutoff
171 integer(c_int) i, j, a
174 real(c_double) cutoff2
175 integer(c_int),
pointer :: neighborList(:, :)
177 call c_f_pointer(neighobject%neighbor_list_pointer, neighborlist, &
178 [numberofparticles + 1, numberofparticles])
180 neighobject%cutoff = cutoff
184 do i = 1, numberofparticles
186 do j = 1, numberofparticles
187 dx(:) = coords(:, j) - coords(:, i)
188 r2 = dot_product(dx, dx)
189 if (r2 <= cutoff2)
then 191 if ((j > i) .OR. ((.not. half) .AND. (i /= j)))
then 193 neighborlist(a, i) = j
198 neighborlist(1, i) = a - 1
223 periodic, coords, MiddlePartId)
224 use,
intrinsic :: iso_c_binding
226 integer(c_int),
parameter :: cd = c_double
229 real(c_double),
intent(in) :: FCCspacing
230 integer(c_int),
intent(in) :: nCellsPerSide
231 logical,
intent(in) :: periodic
232 real(c_double),
intent(out) :: coords(3, *)
233 integer(c_int),
intent(out) :: MiddlePartId
237 real(c_double) FCCshifts(3, 4)
238 real(c_double) latVec(3)
239 integer(c_int) a, i, j, k, m
243 fccshifts(1, 1) = 0.0_cd
244 fccshifts(2, 1) = 0.0_cd
245 fccshifts(3, 1) = 0.0_cd
246 fccshifts(1, 2) = 0.5_cd * fccspacing
247 fccshifts(2, 2) = 0.5_cd * fccspacing
248 fccshifts(3, 2) = 0.0_cd
249 fccshifts(1, 3) = 0.5_cd * fccspacing
250 fccshifts(2, 3) = 0.0_cd
251 fccshifts(3, 3) = 0.5_cd * fccspacing
252 fccshifts(1, 4) = 0.0_cd
253 fccshifts(2, 4) = 0.5_cd * fccspacing
254 fccshifts(3, 4) = 0.5_cd * fccspacing
258 do i = 1, ncellsperside
259 latvec(1) = (i - 1) * fccspacing
260 do j = 1, ncellsperside
261 latvec(2) = (j - 1) * fccspacing
262 do k = 1, ncellsperside
263 latvec(3) = (k - 1) * fccspacing
266 coords(:, a) = latvec + fccshifts(:, m)
267 if ((i == ncellsperside / 2 + 1) &
268 .and. (j == ncellsperside / 2 + 1) &
269 .and. (k == ncellsperside / 2 + 1) &
273 coords(:, 1) = latvec + fccshifts(:, m)
278 if (.not. periodic)
then 281 latvec(1) = ncellsperside * fccspacing
282 latvec(2) = (i - 1) * fccspacing
283 latvec(3) = (j - 1) * fccspacing
284 a = a + 1; coords(:, a) = latvec
285 a = a + 1; coords(:, a) = latvec + fccshifts(:, 4)
287 latvec(1) = (i - 1) * fccspacing
288 latvec(2) = ncellsperside * fccspacing
289 latvec(3) = (j - 1) * fccspacing
290 a = a + 1; coords(:, a) = latvec
291 a = a + 1; coords(:, a) = latvec + fccshifts(:, 3)
293 latvec(1) = (i - 1) * fccspacing
294 latvec(2) = (j - 1) * fccspacing
295 latvec(3) = ncellsperside * fccspacing
296 a = a + 1; coords(:, a) = latvec
297 a = a + 1; coords(:, a) = latvec + fccshifts(:, 2)
300 if (.not. periodic)
then 302 latvec(1) = (i - 1) * fccspacing
303 latvec(2) = ncellsperside * fccspacing
304 latvec(3) = ncellsperside * fccspacing
305 a = a + 1; coords(:, a) = latvec
306 latvec(1) = ncellsperside * fccspacing
307 latvec(2) = (i - 1) * fccspacing
308 latvec(3) = ncellsperside * fccspacing
309 a = a + 1; coords(:, a) = latvec
310 latvec(1) = ncellsperside * fccspacing
311 latvec(2) = ncellsperside * fccspacing
312 latvec(3) = (i - 1) * fccspacing
313 a = a + 1; coords(:, a) = latvec
316 if (.not. periodic)
then 318 a = a + 1; coords(:, a) = ncellsperside * fccspacing
341 use,
intrinsic :: iso_c_binding
348 integer(c_int),
parameter :: cd = c_double
350 integer(c_int),
parameter :: nCellsPerSide = 2
351 integer(c_int),
parameter :: DIM = 3
353 real(c_double),
parameter :: cutpad = 0.75_cd
354 real(c_double),
parameter :: FCCspacing = 5.260_cd
355 real(c_double),
parameter :: min_spacing = 0.8 * fccspacing
356 real(c_double),
parameter :: max_spacing = 1.2 * fccspacing
357 real(c_double),
parameter :: spacing_incr = 0.025 * fccspacing
358 real(c_double) :: current_spacing
359 real(c_double) :: force_norm
361 character(len=256, kind=c_char) :: modelname
363 integer(c_int),
parameter :: N = 4 * (ncellsperside)**3 &
364 + 6 * (ncellsperside)**2 &
365 + 3 * (ncellsperside) + 1
368 integer(c_int),
allocatable,
target :: neighborList(:, :)
370 type(kim_model_handle_type) :: model_handle
371 type(kim_compute_arguments_handle_type) :: compute_arguments_handle
372 real(c_double) :: influence_distance
373 integer(c_int) :: number_of_neighbor_lists
374 real(c_double) :: cutoff
375 real(c_double) :: cutoffs(1)
377 model_will_not_request_neighbors_of_noncontributing_particles(1)
378 integer(c_int),
target :: particle_species_codes(n)
379 integer(c_int),
target :: particle_contributing(n)
380 real(c_double),
target :: energy
381 real(c_double),
target :: coords(dim, n)
382 real(c_double),
target :: forces(dim, n)
383 integer(c_int) i, j, ierr, ierr2
385 integer(c_int) species_is_supported
386 integer(c_int) species_code
387 integer(c_int) requested_units_accepted
388 integer(c_int) number_of_model_routine_names
389 type(kim_model_routine_name_type) model_routine_name
390 integer(c_int) present
391 integer(c_int) required
392 type(kim_supported_extensions_type),
target :: supported_extensions
393 character(len=KIM_MAX_EXTENSION_ID_LENGTH, kind=c_char) :: id_string
399 supported_extensions%number_of_supported_extensions = 0
402 print
'("Please enter a valid KIM model name: ")' 403 read (*, *) modelname
407 call kim_model_create(kim_numbering_one_based, &
409 kim_energy_unit_ev, &
411 kim_temperature_unit_k, &
414 requested_units_accepted, &
421 if (requested_units_accepted == 0)
then 422 call my_error(
"Must adapt to model units")
426 call kim_get_number_of_model_routine_names(number_of_model_routine_names)
427 do i = 1, number_of_model_routine_names
428 call kim_get_model_routine_name(i, model_routine_name, ierr)
430 call my_error(
"kim_get_model_routine_name")
432 call kim_is_routine_present(model_handle, model_routine_name,
present, &
435 call my_error(
"kim_is_routine_present")
438 if ((
present == 1) .and. (required == 1))
then 439 if (.not. ((model_routine_name == kim_model_routine_name_create) &
440 .or. (model_routine_name == &
441 kim_model_routine_name_compute_arguments_create) &
442 .or. (model_routine_name == kim_model_routine_name_compute) &
443 .or. (model_routine_name == kim_model_routine_name_refresh) &
444 .or. (model_routine_name == &
445 kim_model_routine_name_compute_arguments_destroy) &
446 .or. (model_routine_name == kim_model_routine_name_destroy))) &
448 call my_error(
"Unknown required ModelRoutineName found.")
455 call kim_get_species_support_and_code( &
456 model_handle, kim_species_name_ar, species_is_supported, species_code, ierr)
457 if ((ierr /= 0) .or. (species_is_supported /= 1))
then 458 call my_error(
"Model does not support Ar")
462 call kim_is_routine_present( &
463 model_handle, kim_model_routine_name_extension,
present, required, ierr)
465 call my_error(
"Unable to get Extension present/required.")
467 if (
present /= 0)
then 469 c_loc(supported_extensions), ierr)
471 call my_error(
"Error returned from kim_model_extension().")
473 write (*,
'(A,I2,A)')
"Model Supports ", &
474 supported_extensions%number_of_supported_extensions, &
476 do i = 1, supported_extensions%number_of_supported_extensions
477 call kim_c_char_array_to_string( &
478 supported_extensions%supported_extension_id(:, i), id_string)
479 write (*,
'(A,I2,A,A,A,A,I2)')
" supportedExtensionID[", i,
'] = "', &
480 trim(id_string),
'" ', &
481 "which has required = ", &
482 supported_extensions%supported_extension_required(i)
490 call kim_compute_arguments_create( &
491 model_handle, compute_arguments_handle, ierr)
493 call my_error(
"kim_model_compute_arguments_create")
498 call kim_set_argument_pointer( &
499 compute_arguments_handle, kim_compute_argument_name_number_of_particles, &
502 call kim_set_argument_pointer( &
503 compute_arguments_handle, &
504 kim_compute_argument_name_particle_species_codes, &
505 particle_species_codes, ierr2)
507 call kim_set_argument_pointer( &
508 compute_arguments_handle, &
509 kim_compute_argument_name_particle_contributing, particle_contributing, &
512 call kim_set_argument_pointer( &
513 compute_arguments_handle, kim_compute_argument_name_coordinates, coords, &
516 call kim_set_argument_pointer( &
517 compute_arguments_handle, kim_compute_argument_name_partial_energy, &
520 call kim_set_argument_pointer( &
521 compute_arguments_handle, kim_compute_argument_name_partial_forces, &
525 call my_error(
"set_argument_pointer")
530 allocate (neighborlist(n + 1, n))
531 neighobject%neighbor_list_pointer = c_loc(neighborlist)
532 neighobject%number_of_particles = n
536 call kim_set_callback_pointer( &
537 compute_arguments_handle, kim_compute_callback_name_get_neighbor_list, &
538 kim_language_name_fortran, c_funloc(
get_neigh), c_loc(neighobject), ierr)
540 call my_error(
"set_callback_pointer")
543 call kim_get_influence_distance(model_handle, influence_distance)
544 call kim_get_number_of_neighbor_lists(model_handle, &
545 number_of_neighbor_lists)
546 if (number_of_neighbor_lists /= 1)
then 547 call my_error(
"too many neighbor lists")
549 call kim_get_neighbor_list_values( &
550 model_handle, cutoffs, &
551 model_will_not_request_neighbors_of_noncontributing_particles, ierr)
553 call my_error(
"get_neighbor_list_values")
560 particle_species_codes(i) = species_code
565 particle_contributing(i) = 1
571 print *,
'This is Test : ex_test_Ar_fcc_cluster_fortran' 574 print
'("Results for KIM Model : ",A)', trim(modelname)
577 print
'(3A20)',
"Energy",
"Force Norm",
"Lattice Spacing" 579 current_spacing = min_spacing
580 do while (current_spacing < max_spacing)
586 (cutoff + cutpad), neighobject)
589 call kim_compute(model_handle, compute_arguments_handle, ierr)
591 call my_error(
"kim_api_model_compute")
598 force_norm = force_norm + forces(j, i) * forces(j, i)
601 force_norm = sqrt(force_norm)
605 print
'(3ES20.10)', energy, force_norm, current_spacing
607 current_spacing = current_spacing + spacing_incr
611 deallocate (neighborlist)
613 call kim_compute_arguments_destroy( &
614 model_handle, compute_arguments_handle, ierr)
616 call my_error(
"compute_arguments_destroy")
618 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.