45 use,
intrinsic :: iso_c_binding
65 integer(c_int),
parameter :: cd = c_double
66 integer(c_int),
parameter :: dim = 3
74 type, bind(c) :: buffer_type
75 character(c_char) :: species_name(100)
76 real(c_double) :: influence_distance(1)
77 real(c_double) :: pcutoff(1)
78 real(c_double) :: cutsq(1)
80 model_will_not_request_neighbors_of_noncontributing_particles(1)
81 real(c_double) :: epsilon(1)
82 real(c_double) :: sigma(1)
83 real(c_double) :: shift(1)
93 recursive subroutine calc_phi(model_epsilon, &
100 real(c_double),
intent(in) :: model_epsilon
101 real(c_double),
intent(in) :: model_sigma
102 real(c_double),
intent(in) :: model_shift
103 real(c_double),
intent(in) :: model_cutoff
104 real(c_double),
intent(in) :: r
105 real(c_double),
intent(out) :: phi
108 real(c_double) rsq, sor, sor6, sor12
111 sor = model_sigma / r
112 sor6 = sor * sor * sor
115 if (r > model_cutoff)
then 119 phi = 4.0_cd * model_epsilon * (sor12 - sor6) + model_shift
132 model_cutoff, r, phi, dphi)
136 real(c_double),
intent(in) :: model_epsilon
137 real(c_double),
intent(in) :: model_sigma
138 real(c_double),
intent(in) :: model_shift
139 real(c_double),
intent(in) :: model_cutoff
140 real(c_double),
intent(in) :: r
141 real(c_double),
intent(out) :: phi, dphi
144 real(c_double) rsq, sor, sor6, sor12
147 sor = model_sigma / r
148 sor6 = sor * sor * sor
151 if (r > model_cutoff)
then 156 phi = 4.0_cd * model_epsilon * (sor12 - sor6) + model_shift
157 dphi = 24.0_cd * model_epsilon * (-2.0_cd * sor12 + sor6) / r
170 model_cutoff, r, phi, dphi, d2phi)
174 real(c_double),
intent(in) :: model_epsilon
175 real(c_double),
intent(in) :: model_sigma
176 real(c_double),
intent(in) :: model_shift
177 real(c_double),
intent(in) :: model_cutoff
178 real(c_double),
intent(in) :: r
179 real(c_double),
intent(out) :: phi, dphi, d2phi
182 real(c_double) rsq, sor, sor6, sor12
185 sor = model_sigma / r
186 sor6 = sor * sor * sor
189 if (r > model_cutoff)
then 195 phi = 4.0_cd * model_epsilon * (sor12 - sor6) + model_shift
196 dphi = 24.0_cd * model_epsilon * (-2.0_cd * sor12 + sor6) / r
197 d2phi = 24.0_cd * model_epsilon * (26.0_cd * sor12 - 7.0_cd * sor6) / rsq
208 model_compute_handle, model_compute_arguments_handle, ierr) bind(c)
212 type(kim_model_compute_handle_type),
intent(in) :: model_compute_handle
213 type(kim_model_compute_arguments_handle_type),
intent(in) :: &
214 model_compute_arguments_handle
215 integer(c_int),
intent(out) :: ierr
218 real(c_double) :: r, Rsqij, phi, dphi, d2phi, dEidr, d2Eidr
219 integer(c_int) :: i, j, jj, numnei
220 integer(c_int) :: ierr2
221 integer(c_int) :: comp_force, comp_energy, comp_enepot, comp_process_dEdr, &
223 type(buffer_type),
pointer :: buf;
type(c_ptr) :: pbuf
225 real(c_double),
target :: Rij(dim)
226 real(c_double),
target :: Rij_pairs(dim, 2)
227 real(c_double),
target :: r_pairs(2)
228 integer(c_int),
target :: i_pairs(2), j_pairs(2)
231 real(c_double) :: model_cutoff
232 integer(c_int),
pointer :: N
233 real(c_double),
pointer :: energy
234 real(c_double),
pointer :: coor(:, :)
235 real(c_double),
pointer :: force(:, :)
236 real(c_double),
pointer :: enepot(:)
237 integer(c_int),
pointer :: nei1part(:)
238 integer(c_int),
pointer :: particleSpeciesCodes(:)
239 integer(c_int),
pointer :: particleContributing(:)
242 call kim_get_model_buffer_pointer(model_compute_handle, pbuf)
243 call c_f_pointer(pbuf, buf)
245 model_cutoff = buf%influence_distance(1)
251 call kim_is_callback_present( &
252 model_compute_arguments_handle, &
253 kim_compute_callback_name_process_dedr_term, comp_process_dedr, ierr2)
255 call kim_is_callback_present( &
256 model_compute_arguments_handle, &
257 kim_compute_callback_name_process_d2edr2_term, comp_process_d2edr2, ierr2)
260 call kim_log_entry(model_compute_arguments_handle, &
261 kim_log_verbosity_error,
"get_compute")
269 call kim_get_argument_pointer( &
270 model_compute_arguments_handle, &
271 kim_compute_argument_name_number_of_particles, n, ierr2)
274 call kim_get_argument_pointer( &
275 model_compute_arguments_handle, &
276 kim_compute_argument_name_particle_species_codes, &
277 n, particlespeciescodes, ierr2)
279 call kim_get_argument_pointer( &
280 model_compute_arguments_handle, &
281 kim_compute_argument_name_particle_contributing, &
282 n, particlecontributing, ierr2)
284 call kim_get_argument_pointer( &
285 model_compute_arguments_handle, &
286 kim_compute_argument_name_coordinates, dim, n, coor, ierr2)
288 call kim_get_argument_pointer( &
289 model_compute_arguments_handle, &
290 kim_compute_argument_name_partial_energy, energy, ierr2)
292 call kim_get_argument_pointer( &
293 model_compute_arguments_handle, &
294 kim_compute_argument_name_partial_forces, dim, n, force, ierr2)
296 call kim_get_argument_pointer( &
297 model_compute_arguments_handle, &
298 kim_compute_argument_name_partial_particle_energy, n, enepot, ierr2)
301 call kim_log_entry(model_compute_arguments_handle, &
302 kim_log_verbosity_error,
"get_argument_pointer")
307 if (
associated(energy))
then 312 if (
associated(force))
then 317 if (
associated(enepot))
then 328 if (particlespeciescodes(i) /=
speccode)
then 329 call kim_log_entry( &
330 model_compute_arguments_handle, kim_log_verbosity_error, &
331 "Unexpected species code detected")
340 if (comp_enepot == 1) enepot = 0.0_cd
341 if (comp_energy == 1) energy = 0.0_cd
342 if (comp_force == 1) force = 0.0_cd
352 if (particlecontributing(i) == 1)
then 355 call kim_get_neighbor_list( &
356 model_compute_arguments_handle, 1, i, numnei, nei1part, ierr)
359 call kim_log_entry( &
360 model_compute_arguments_handle, kim_log_verbosity_error, &
374 rij(:) = coor(:, j) - coor(:, i)
378 rsqij = dot_product(rij, rij)
379 if (rsqij < buf%cutsq(1))
then 382 if (comp_process_d2edr2 == 1)
then 389 deidr = 0.5_cd * dphi
390 d2eidr = 0.5_cd * d2phi
391 elseif (comp_force == 1 .or. comp_process_dedr == 1)
then 399 deidr = 0.5_cd * dphi
410 if (comp_enepot == 1)
then 411 enepot(i) = enepot(i) + 0.5_cd * phi
413 if (comp_energy == 1)
then 414 energy = energy + 0.5_cd * phi
419 if (comp_process_dedr == 1)
then 420 call kim_process_dedr_term( &
421 model_compute_arguments_handle, deidr, r, rij, i, j, ierr)
425 if (comp_process_d2edr2 == 1)
then 428 rij_pairs(:, 1) = rij
429 rij_pairs(:, 2) = rij
435 call kim_process_d2edr2_term( &
436 model_compute_arguments_handle, d2eidr, &
437 r_pairs, rij_pairs, i_pairs, j_pairs, ierr)
442 if (comp_force == 1)
then 443 force(:, i) = force(:, i) + deidr * rij / r
444 force(:, j) = force(:, j) - deidr * rij / r
467 recursive subroutine refresh(model_refresh_handle, ierr) bind(c)
471 type(kim_model_refresh_handle_type),
intent(in) :: model_refresh_handle
472 integer(c_int),
intent(out) :: ierr
475 real(c_double) energy_at_cutoff
476 type(buffer_type),
pointer :: buf;
type(c_ptr) :: pbuf
479 call kim_get_model_buffer_pointer(model_refresh_handle, pbuf)
480 call c_f_pointer(pbuf, buf)
482 call kim_set_influence_distance_pointer(model_refresh_handle, &
483 buf%influence_distance(1))
484 call kim_set_neighbor_list_pointers( &
485 model_refresh_handle, 1, buf%influence_distance, &
486 buf%model_will_not_request_neighbors_of_noncontributing_particles)
490 buf%influence_distance(1) = buf%Pcutoff(1)
491 buf%cutsq(1) = (buf%Pcutoff(1))**2
497 buf%Pcutoff(1), energy_at_cutoff)
498 buf%shift(1) = -energy_at_cutoff
511 model_write_parameterized_model_handle, ierr) bind(c)
515 type(kim_model_write_parameterized_model_handle_type),
intent(in) &
516 :: model_write_parameterized_model_handle
517 integer(c_int),
intent(out) :: ierr
521 type(buffer_type),
pointer :: buf;
type(c_ptr) :: pbuf
522 character(len=512, kind=c_char) :: path
523 character(len=512, kind=c_char) :: model_name
524 character(len=512, kind=c_char) :: string_buffer
525 character(len=100, kind=c_char) :: species_name
528 call kim_get_model_buffer_pointer( &
529 model_write_parameterized_model_handle, pbuf)
530 call c_f_pointer(pbuf, buf)
532 call kim_get_path(model_write_parameterized_model_handle, path)
533 call kim_get_model_name(model_write_parameterized_model_handle, model_name)
535 write (string_buffer,
'(A)') trim(model_name)//
".params" 536 call kim_set_parameter_file_name(model_write_parameterized_model_handle, &
538 write (string_buffer,
'(A)') trim(path)//
"/"//trim(string_buffer)
540 open (42, file=trim(string_buffer), &
541 status=
"REPLACE", action=
"WRITE", iostat=ierr)
543 call kim_log_entry( &
544 model_write_parameterized_model_handle, kim_log_verbosity_error, &
545 "Unable to open parameter file for writing.")
550 species_name(i:i) = buf%species_name(i)
552 write (42,
'(A)') trim(species_name)
553 write (42,
'(ES20.10)') buf%Pcutoff(1)
554 write (42,
'(ES20.10)') buf%epsilon(1)
555 write (42,
'(ES20.10)') buf%sigma(1)
567 recursive subroutine destroy(model_destroy_handle, ierr) bind(c)
571 type(kim_model_destroy_handle_type),
intent(in) :: model_destroy_handle
572 integer(c_int),
intent(out) :: ierr
575 type(buffer_type),
pointer :: buf;
type(c_ptr) :: pbuf
578 call kim_get_model_buffer_pointer(model_destroy_handle, pbuf)
579 call c_f_pointer(pbuf, buf)
594 model_compute_handle, model_compute_arguments_create_handle, ierr) bind(c)
598 type(kim_model_compute_handle_type),
intent(in) :: model_compute_handle
599 type(kim_model_compute_arguments_create_handle_type),
intent(in) :: &
600 model_compute_arguments_create_handle
601 integer(c_int),
intent(out) :: ierr
606 if (model_compute_handle == kim_model_compute_null_handle)
continue 612 call kim_set_argument_support_status( &
613 model_compute_arguments_create_handle, &
614 kim_compute_argument_name_partial_energy, &
615 kim_support_status_optional, ierr)
616 call kim_set_argument_support_status( &
617 model_compute_arguments_create_handle, &
618 kim_compute_argument_name_partial_forces, &
619 kim_support_status_optional, ierr2)
621 call kim_set_argument_support_status( &
622 model_compute_arguments_create_handle, &
623 kim_compute_argument_name_partial_particle_energy, &
624 kim_support_status_optional, ierr2)
627 call kim_log_entry( &
628 model_compute_arguments_create_handle, kim_log_verbosity_error, &
629 "Unable to register arguments support_statuss")
635 call kim_set_callback_support_status( &
636 model_compute_arguments_create_handle, &
637 kim_compute_callback_name_process_dedr_term, &
638 kim_support_status_optional, ierr)
639 call kim_set_callback_support_status( &
640 model_compute_arguments_create_handle, &
641 kim_compute_callback_name_process_d2edr2_term, &
642 kim_support_status_optional, ierr2)
645 call kim_log_entry( &
646 model_compute_arguments_create_handle, kim_log_verbosity_error, &
647 "Unable to register callbacks support_statuss")
664 model_compute_handle, model_compute_arguments_destroy_handle, ierr) bind(c)
668 type(kim_model_compute_handle_type),
intent(in) :: model_compute_handle
669 type(kim_model_compute_arguments_destroy_handle_type),
intent(in) :: &
670 model_compute_arguments_destroy_handle
671 integer(c_int),
intent(out) :: ierr
674 if (model_compute_handle == kim_model_compute_null_handle)
continue 675 if (model_compute_arguments_destroy_handle == &
676 kim_model_compute_arguments_destroy_null_handle)
continue 689 recursive subroutine model_driver_create_routine( &
690 model_driver_create_handle, requested_length_unit, requested_energy_unit, &
691 requested_charge_unit, requested_temperature_unit, requested_time_unit, &
693 use,
intrinsic :: iso_c_binding
697 integer(c_int),
parameter :: cd = c_double
700 type(kim_model_driver_create_handle_type),
intent(in) &
701 :: model_driver_create_handle
702 type(kim_length_unit_type),
intent(in),
value :: requested_length_unit
703 type(kim_energy_unit_type),
intent(in),
value :: requested_energy_unit
704 type(kim_charge_unit_type),
intent(in),
value :: requested_charge_unit
705 type(kim_temperature_unit_type),
intent(in),
value :: &
706 requested_temperature_unit
707 type(kim_time_unit_type),
intent(in),
value :: requested_time_unit
708 integer(c_int),
intent(out) :: ierr
712 integer(c_int) :: number_of_parameter_files
713 character(len=1024, kind=c_char) :: parameter_file_directory_name
714 character(len=1024, kind=c_char) :: parameter_file_basename
715 character(len=1024, kind=c_char) :: parameter_file_name
716 integer(c_int) :: ierr2
717 type(buffer_type),
pointer :: buf
718 type(kim_species_name_type) species_name
720 real(c_double) factor
721 character(len=100, kind=c_char) in_species
722 real(c_double) in_cutoff
723 real(c_double) in_epsilon
724 real(c_double) in_sigma
725 real(c_double) energy_at_cutoff
728 call kim_set_units( &
729 model_driver_create_handle, &
730 requested_length_unit, &
731 requested_energy_unit, &
732 kim_charge_unit_unused, &
733 kim_temperature_unit_unused, &
734 kim_time_unit_unused, ierr)
736 call kim_log_entry(model_driver_create_handle, &
737 kim_log_verbosity_error,
"Unable to set units")
743 call kim_set_model_numbering( &
744 model_driver_create_handle, kim_numbering_one_based, ierr)
746 call kim_log_entry(model_driver_create_handle, &
747 kim_log_verbosity_error,
"Unable to set numbering")
753 call kim_set_routine_pointer( &
754 model_driver_create_handle, kim_model_routine_name_compute, &
756 call kim_set_routine_pointer( &
757 model_driver_create_handle, &
758 kim_model_routine_name_compute_arguments_create, &
761 call kim_set_routine_pointer( &
762 model_driver_create_handle, kim_model_routine_name_refresh, &
763 kim_language_name_fortran, 1, c_funloc(
refresh), ierr2)
765 call kim_set_routine_pointer( &
766 model_driver_create_handle, &
767 kim_model_routine_name_write_parameterized_model, &
768 kim_language_name_fortran, 0, c_funloc(
write_model), ierr2)
770 call kim_set_routine_pointer( &
771 model_driver_create_handle, &
772 kim_model_routine_name_compute_arguments_destroy, &
775 call kim_set_routine_pointer( &
776 model_driver_create_handle, kim_model_routine_name_destroy, &
777 kim_language_name_fortran, 1, c_funloc(
destroy), ierr2)
780 call kim_log_entry( &
781 model_driver_create_handle, kim_log_verbosity_error, &
782 "Unable to store callback pointers")
788 call kim_get_number_of_parameter_files( &
789 model_driver_create_handle, number_of_parameter_files)
790 if (number_of_parameter_files /= 1)
then 791 call kim_log_entry( &
792 model_driver_create_handle, kim_log_verbosity_error, &
793 "Wrong number of parameter files")
800 call kim_get_parameter_file_directory_name( &
801 model_driver_create_handle, parameter_file_directory_name)
802 call kim_get_parameter_file_basename( &
803 model_driver_create_handle, 1, parameter_file_basename, ierr)
805 call kim_log_entry( &
806 model_driver_create_handle, kim_log_verbosity_error, &
807 "Unable to get parameter file basename")
811 parameter_file_name = trim(parameter_file_directory_name)//
"/"// &
812 trim(parameter_file_basename)
813 open (10, file=parameter_file_name, status=
"old")
814 read (10, *, iostat=ierr, err=100) in_species
815 read (10, *, iostat=ierr, err=100) in_cutoff
816 read (10, *, iostat=ierr, err=100) in_epsilon
817 read (10, *, iostat=ierr, err=100) in_sigma
823 call kim_log_entry(model_driver_create_handle, &
824 kim_log_verbosity_error,
"Unable to read LJ parameters")
831 call kim_from_string(in_species, species_name)
832 call kim_set_species_code( &
833 model_driver_create_handle, species_name,
speccode, ierr)
835 call kim_log_entry(model_driver_create_handle, &
836 kim_log_verbosity_error,
"Unable to set species code")
842 call kim_convert_unit( &
844 kim_energy_unit_ev, &
846 kim_temperature_unit_k, &
848 requested_length_unit, &
849 requested_energy_unit, &
850 requested_charge_unit, &
851 requested_temperature_unit, &
852 requested_time_unit, &
853 1.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, factor, ierr)
855 call kim_log_entry(model_driver_create_handle, &
856 kim_log_verbosity_error,
"kim_api_convert_to_act_unit")
860 in_cutoff = in_cutoff * factor
862 call kim_convert_unit( &
864 kim_energy_unit_ev, &
866 kim_temperature_unit_k, &
868 requested_length_unit, &
869 requested_energy_unit, &
870 requested_charge_unit, &
871 requested_temperature_unit, &
872 requested_time_unit, &
873 0.0_cd, 1.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, factor, ierr)
875 call kim_log_entry(model_driver_create_handle, &
876 kim_log_verbosity_error,
"kim_api_convert_to_act_unit")
880 in_epsilon = in_epsilon * factor
882 call kim_convert_unit( &
884 kim_energy_unit_ev, &
886 kim_temperature_unit_k, &
888 requested_length_unit, &
889 requested_energy_unit, &
890 requested_charge_unit, &
891 requested_temperature_unit, &
892 requested_time_unit, &
893 1.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, factor, ierr)
895 call kim_log_entry(model_driver_create_handle, &
896 kim_log_verbosity_error,
"kim_api_convert_to_act_unit")
900 in_sigma = in_sigma * factor
907 buf%species_name(i) = in_species(i:i)
909 buf%influence_distance(1) = in_cutoff
910 buf%Pcutoff(1) = in_cutoff
911 buf%cutsq(1) = in_cutoff**2
912 buf%model_will_not_request_neighbors_of_noncontributing_particles = 1
913 buf%epsilon(1) = in_epsilon
914 buf%sigma(1) = in_sigma
919 in_cutoff, energy_at_cutoff)
920 buf%shift(1) = -energy_at_cutoff
923 call kim_set_influence_distance_pointer( &
924 model_driver_create_handle, buf%influence_distance(1))
925 call kim_set_neighbor_list_pointers( &
926 model_driver_create_handle, 1, buf%influence_distance, &
927 buf%model_will_not_request_neighbors_of_noncontributing_particles)
932 call kim_set_model_buffer_pointer( &
933 model_driver_create_handle, c_loc(buf))
936 call kim_set_parameter_pointer( &
937 model_driver_create_handle, buf%pcutoff,
"cutoff", &
938 "Distance beyond which particles do not interact with one another.", ierr)
940 call kim_log_entry(model_driver_create_handle, &
941 kim_log_verbosity_error,
"set_parameter")
946 call kim_set_parameter_pointer( &
947 model_driver_create_handle, buf%epsilon,
"epsilon", &
948 "Maximum depth of the potential well.", ierr)
950 call kim_log_entry(model_driver_create_handle, &
951 kim_log_verbosity_error,
"set_parameter")
956 call kim_set_parameter_pointer( &
957 model_driver_create_handle, buf%sigma,
"sigma", &
958 "Distance at which energy is zero and force is repulsive.", ierr)
960 call kim_log_entry(model_driver_create_handle, &
961 kim_log_verbosity_error,
"set_parameter")
970 end subroutine model_driver_create_routine
recursive subroutine, public compute_energy_forces(model_compute_handle, model_compute_arguments_handle, ierr)
recursive subroutine, public destroy(model_destroy_handle, ierr)
recursive subroutine, public compute_arguments_destroy(model_compute_handle, model_compute_arguments_destroy_handle, ierr)
recursive subroutine, public refresh(model_refresh_handle, ierr)
recursive subroutine, public calc_phi_dphi_d2phi(model_epsilon, model_sigma, model_shift, model_cutoff, r, phi, dphi, d2phi)
recursive subroutine, public calc_phi_dphi(model_epsilon, model_sigma, model_shift, model_cutoff, r, phi, dphi)
recursive subroutine, public compute_arguments_create(model_compute_handle, model_compute_arguments_create_handle, ierr)
integer(c_int), parameter, public speccode
recursive subroutine, public calc_phi(model_epsilon, model_sigma, model_shift, model_cutoff, r, phi)
recursive subroutine, public write_model(model_write_parameterized_model_handle, ierr)