46 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)
94 recursive subroutine calc_phi(model_epsilon, &
101 real(c_double),
intent(in) :: model_epsilon
102 real(c_double),
intent(in) :: model_sigma
103 real(c_double),
intent(in) :: model_shift
104 real(c_double),
intent(in) :: model_cutoff
105 real(c_double),
intent(in) :: r
106 real(c_double),
intent(out) :: phi
109 real(c_double) rsq,sor,sor6,sor12
116 if (r .gt. model_cutoff)
then 120 phi = 4.0_cd*model_epsilon*(sor12-sor6) + model_shift
133 model_cutoff,r,phi,dphi)
137 real(c_double),
intent(in) :: model_epsilon
138 real(c_double),
intent(in) :: model_sigma
139 real(c_double),
intent(in) :: model_shift
140 real(c_double),
intent(in) :: model_cutoff
141 real(c_double),
intent(in) :: r
142 real(c_double),
intent(out) :: phi,dphi
145 real(c_double) rsq,sor,sor6,sor12
152 if (r .gt. model_cutoff)
then 157 phi = 4.0_cd*model_epsilon*(sor12-sor6) + model_shift
158 dphi = 24.0_cd*model_epsilon*(-2.0_cd*sor12+sor6)/r
171 model_cutoff,r,phi,dphi,d2phi)
175 real(c_double),
intent(in) :: model_epsilon
176 real(c_double),
intent(in) :: model_sigma
177 real(c_double),
intent(in) :: model_shift
178 real(c_double),
intent(in) :: model_cutoff
179 real(c_double),
intent(in) :: r
180 real(c_double),
intent(out) :: phi,dphi,d2phi
183 real(c_double) rsq,sor,sor6,sor12
190 if (r .gt. model_cutoff)
then 196 phi = 4.0_cd*model_epsilon*(sor12-sor6) + model_shift
197 dphi = 24.0_cd*model_epsilon*(-2.0_cd*sor12+sor6)/r
198 d2phi = 24.0_cd*model_epsilon*(26.0_cd*sor12-7.0_cd*sor6)/rsq
209 model_compute_arguments_handle, ierr) bind(c)
213 type(kim_model_compute_handle_type),
intent(in) :: model_compute_handle
214 type(kim_model_compute_arguments_handle_type),
intent(in) :: &
215 model_compute_arguments_handle
216 integer(c_int),
intent(out) :: ierr
219 real(c_double) :: r,Rsqij,phi,dphi,d2phi,dEidr,d2Eidr
220 integer(c_int) :: i,j,jj,numnei
221 integer(c_int) :: ierr2
222 integer(c_int) :: comp_force,comp_energy,comp_enepot,comp_process_dEdr, &
224 type(buffer_type),
pointer :: buf;
type(c_ptr) :: pbuf
226 real(c_double),
target :: Rij(dim)
227 real(c_double),
target :: Rij_pairs(dim,2)
228 real(c_double),
target :: r_pairs(2)
229 integer(c_int),
target :: i_pairs(2), j_pairs(2)
232 real(c_double) :: model_cutoff
233 integer(c_int),
pointer :: N
234 real(c_double),
pointer :: energy
235 real(c_double),
pointer :: coor(:,:)
236 real(c_double),
pointer :: force(:,:)
237 real(c_double),
pointer :: enepot(:)
238 integer(c_int),
pointer :: nei1part(:)
239 integer(c_int),
pointer :: particleSpeciesCodes(:)
240 integer(c_int),
pointer :: particleContributing(:)
243 call kim_get_model_buffer_pointer(model_compute_handle, pbuf)
244 call c_f_pointer(pbuf, buf)
246 model_cutoff = buf%influence_distance(1)
252 call kim_is_callback_present( &
253 model_compute_arguments_handle, &
254 kim_compute_callback_name_process_dedr_term, comp_process_dedr, ierr2)
256 call kim_is_callback_present( &
257 model_compute_arguments_handle, &
258 kim_compute_callback_name_process_d2edr2_term, comp_process_d2edr2, ierr2)
261 call kim_log_entry(model_compute_arguments_handle, &
262 kim_log_verbosity_error,
"get_compute")
270 call kim_get_argument_pointer( &
271 model_compute_arguments_handle, &
272 kim_compute_argument_name_number_of_particles, n, ierr2)
275 call kim_get_argument_pointer( &
276 model_compute_arguments_handle, &
277 kim_compute_argument_name_particle_species_codes, &
278 n, particlespeciescodes, ierr2)
280 call kim_get_argument_pointer( &
281 model_compute_arguments_handle, &
282 kim_compute_argument_name_particle_contributing, n, particlecontributing, &
285 call kim_get_argument_pointer( &
286 model_compute_arguments_handle, &
287 kim_compute_argument_name_coordinates, dim, n, coor, ierr2)
289 call kim_get_argument_pointer( &
290 model_compute_arguments_handle, &
291 kim_compute_argument_name_partial_energy, energy, ierr2)
293 call kim_get_argument_pointer( &
294 model_compute_arguments_handle, &
295 kim_compute_argument_name_partial_forces, dim, n, force, ierr2)
297 call kim_get_argument_pointer( &
298 model_compute_arguments_handle, &
299 kim_compute_argument_name_partial_particle_energy, n, enepot, ierr2)
302 call kim_log_entry(model_compute_arguments_handle, &
303 kim_log_verbosity_error,
"get_argument_pointer")
308 if (
associated(energy))
then 313 if (
associated(force))
then 318 if (
associated(enepot))
then 329 if (particlespeciescodes(i).ne.
speccode)
then 330 call kim_log_entry(model_compute_arguments_handle,&
331 kim_log_verbosity_error,
"Unexpected species code detected")
340 if (comp_enepot.eq.1) enepot = 0.0_cd
341 if (comp_energy.eq.1) energy = 0.0_cd
342 if (comp_force.eq.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 .lt. buf%cutsq(1) )
then 382 if (comp_process_d2edr2.eq.1)
then 390 d2eidr = 0.5_cd*d2phi
391 elseif (comp_force.eq.1.or.comp_process_dedr.eq.1)
then 410 if (comp_enepot.eq.1)
then 411 enepot(i) = enepot(i) + 0.5_cd*phi
413 if (comp_energy.eq.1)
then 414 energy = energy + 0.5_cd*phi
419 if (comp_process_dedr.eq.1)
then 420 call kim_process_dedr_term( &
421 model_compute_arguments_handle, deidr, r, rij, i, j, ierr)
425 if (comp_process_d2edr2.eq.1)
then 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.eq.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(model_refresh_handle, &
485 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
510 recursive subroutine write_model(model_write_parameterized_model_handle, ierr) &
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(model_write_parameterized_model_handle, pbuf)
529 call c_f_pointer(pbuf, buf)
531 call kim_get_path(model_write_parameterized_model_handle, path)
532 call kim_get_model_name(model_write_parameterized_model_handle, model_name)
534 write(string_buffer,
'(A)') trim(model_name)//
".params" 535 call kim_set_parameter_file_name(model_write_parameterized_model_handle, &
537 write(string_buffer,
'(A)') trim(path)//
"/"//trim(string_buffer)
539 open(42,file=trim(string_buffer), status=
"REPLACE", action=
"WRITE", iostat=ierr)
541 call kim_log_entry(model_write_parameterized_model_handle, &
542 kim_log_verbosity_error,
"Unable to open parameter file for writing.")
547 species_name(i:i) = buf%species_name(i)
549 write(42,
'(A)') trim(species_name)
550 write(42,
'(ES20.10)') buf%Pcutoff(1)
551 write(42,
'(ES20.10)') buf%epsilon(1)
552 write(42,
'(ES20.10)') buf%sigma(1)
566 recursive subroutine destroy(model_destroy_handle, ierr) bind(c)
570 type(kim_model_destroy_handle_type),
intent(in) :: model_destroy_handle
571 integer(c_int),
intent(out) :: ierr
574 type(buffer_type),
pointer :: buf;
type(c_ptr) :: pbuf
577 call kim_get_model_buffer_pointer(model_destroy_handle, pbuf)
578 call c_f_pointer(pbuf, buf)
593 model_compute_arguments_create_handle, ierr) bind(c)
597 type(kim_model_compute_handle_type),
intent(in) :: model_compute_handle
598 type(kim_model_compute_arguments_create_handle_type),
intent(in) :: &
599 model_compute_arguments_create_handle
600 integer(c_int),
intent(out) :: ierr
605 if (model_compute_handle .eq. kim_model_compute_null_handle)
continue 611 call kim_set_argument_support_status( &
612 model_compute_arguments_create_handle, &
613 kim_compute_argument_name_partial_energy, &
614 kim_support_status_optional, ierr)
615 call kim_set_argument_support_status( &
616 model_compute_arguments_create_handle, &
617 kim_compute_argument_name_partial_forces, &
618 kim_support_status_optional, ierr2)
620 call kim_set_argument_support_status( &
621 model_compute_arguments_create_handle, &
622 kim_compute_argument_name_partial_particle_energy, &
623 kim_support_status_optional, ierr2)
627 model_compute_arguments_create_handle, kim_log_verbosity_error, &
628 "Unable to register arguments support_statuss")
634 call kim_set_callback_support_status( &
635 model_compute_arguments_create_handle, &
636 kim_compute_callback_name_process_dedr_term, &
637 kim_support_status_optional, ierr)
638 call kim_set_callback_support_status( &
639 model_compute_arguments_create_handle, &
640 kim_compute_callback_name_process_d2edr2_term, &
641 kim_support_status_optional, ierr2)
645 model_compute_arguments_create_handle, kim_log_verbosity_error, &
646 "Unable to register callbacks support_statuss")
663 model_compute_arguments_destroy_handle, ierr) bind(c)
667 type(kim_model_compute_handle_type),
intent(in) :: model_compute_handle
668 type(kim_model_compute_arguments_destroy_handle_type),
intent(in) :: &
669 model_compute_arguments_destroy_handle
670 integer(c_int),
intent(out) :: ierr
673 if (model_compute_handle .eq. kim_model_compute_null_handle)
continue 674 if (model_compute_arguments_destroy_handle .eq. &
675 kim_model_compute_arguments_destroy_null_handle)
continue 688 recursive subroutine model_driver_create_routine(model_driver_create_handle, &
689 requested_length_unit, requested_energy_unit, requested_charge_unit, &
690 requested_temperature_unit, requested_time_unit, ierr) bind(c)
691 use,
intrinsic :: iso_c_binding
695 integer(c_int),
parameter :: cd = c_double
698 type(kim_model_driver_create_handle_type),
intent(in) &
699 :: model_driver_create_handle
700 type(kim_length_unit_type),
intent(in),
value :: requested_length_unit
701 type(kim_energy_unit_type),
intent(in),
value :: requested_energy_unit
702 type(kim_charge_unit_type),
intent(in),
value :: requested_charge_unit
703 type(kim_temperature_unit_type),
intent(in),
value :: requested_temperature_unit
704 type(kim_time_unit_type),
intent(in),
value :: requested_time_unit
705 integer(c_int),
intent(out) :: ierr
709 integer(c_int) :: number_of_parameter_files
710 character(len=1024, kind=c_char) :: parameter_file_name
711 integer(c_int) :: ierr2
712 type(buffer_type),
pointer :: buf;
713 type(kim_species_name_type) species_name
715 real(c_double) factor
716 character(len=100, kind=c_char) in_species
717 real(c_double) in_cutoff
718 real(c_double) in_epsilon
719 real(c_double) in_sigma
720 real(c_double) energy_at_cutoff
723 call kim_set_units( &
724 model_driver_create_handle, &
725 requested_length_unit, &
726 requested_energy_unit, &
727 kim_charge_unit_unused, &
728 kim_temperature_unit_unused, &
729 kim_time_unit_unused, ierr)
731 call kim_log_entry(model_driver_create_handle, &
732 kim_log_verbosity_error,
"Unable to set units")
738 call kim_set_model_numbering( &
739 model_driver_create_handle, kim_numbering_one_based, ierr)
741 call kim_log_entry(model_driver_create_handle, &
742 kim_log_verbosity_error,
"Unable to set numbering")
749 call kim_set_routine_pointer( &
750 model_driver_create_handle, kim_model_routine_name_compute, &
752 call kim_set_routine_pointer( &
753 model_driver_create_handle, kim_model_routine_name_compute_arguments_create, &
756 call kim_set_routine_pointer( &
757 model_driver_create_handle, kim_model_routine_name_refresh, &
758 kim_language_name_fortran, 1, c_funloc(
refresh), ierr2)
760 call kim_set_routine_pointer( &
761 model_driver_create_handle, &
762 kim_model_routine_name_write_parameterized_model, &
763 kim_language_name_fortran, 0, c_funloc(
write_model), ierr2)
765 call kim_set_routine_pointer( &
766 model_driver_create_handle, &
767 kim_model_routine_name_compute_arguments_destroy, &
770 call kim_set_routine_pointer( &
771 model_driver_create_handle, kim_model_routine_name_destroy, &
772 kim_language_name_fortran, 1, c_funloc(
destroy), ierr2)
775 call kim_log_entry(model_driver_create_handle, &
776 kim_log_verbosity_error,
"Unable to store callback pointers")
783 call kim_get_number_of_parameter_files( &
784 model_driver_create_handle, number_of_parameter_files)
785 if (number_of_parameter_files .ne. 1)
then 786 call kim_log_entry(model_driver_create_handle, &
787 kim_log_verbosity_error,
"Wrong number of parameter files")
794 call kim_get_parameter_file_name( &
795 model_driver_create_handle, 1, parameter_file_name, ierr)
797 call kim_log_entry(model_driver_create_handle, &
798 kim_log_verbosity_error,
"Unable to get parameter file name")
802 open(10,file=parameter_file_name,status=
"old")
803 read(10,*,iostat=ierr,err=100) in_species
804 read(10,*,iostat=ierr,err=100) in_cutoff
805 read(10,*,iostat=ierr,err=100) in_epsilon
806 read(10,*,iostat=ierr,err=100) in_sigma
812 call kim_log_entry(model_driver_create_handle, &
813 kim_log_verbosity_error,
"Unable to read LJ parameters")
821 call kim_from_string(in_species, species_name)
822 call kim_set_species_code( &
823 model_driver_create_handle, species_name,
speccode, ierr)
825 call kim_log_entry(model_driver_create_handle, &
826 kim_log_verbosity_error,
"Unable to set species code")
832 call kim_convert_unit( &
834 kim_energy_unit_ev, &
836 kim_temperature_unit_k, &
838 requested_length_unit, &
839 requested_energy_unit, &
840 requested_charge_unit, &
841 requested_temperature_unit, &
842 requested_time_unit, &
843 1.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, factor, ierr)
845 call kim_log_entry(model_driver_create_handle, &
846 kim_log_verbosity_error,
"kim_api_convert_to_act_unit")
850 in_cutoff = in_cutoff * factor
852 call kim_convert_unit( &
854 kim_energy_unit_ev, &
856 kim_temperature_unit_k, &
858 requested_length_unit, &
859 requested_energy_unit, &
860 requested_charge_unit, &
861 requested_temperature_unit, &
862 requested_time_unit, &
863 0.0_cd, 1.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, factor, ierr)
865 call kim_log_entry(model_driver_create_handle, &
866 kim_log_verbosity_error,
"kim_api_convert_to_act_unit")
870 in_epsilon = in_epsilon * factor
872 call kim_convert_unit( &
874 kim_energy_unit_ev, &
876 kim_temperature_unit_k, &
878 requested_length_unit, &
879 requested_energy_unit, &
880 requested_charge_unit, &
881 requested_temperature_unit, &
882 requested_time_unit, &
883 1.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, 0.0_cd, factor, ierr)
885 call kim_log_entry(model_driver_create_handle, &
886 kim_log_verbosity_error,
"kim_api_convert_to_act_unit")
890 in_sigma = in_sigma * factor
897 buf%species_name(i) = in_species(i:i)
899 buf%influence_distance(1) = in_cutoff
900 buf%Pcutoff(1) = in_cutoff
901 buf%cutsq(1) = in_cutoff**2
902 buf%model_will_not_request_neighbors_of_noncontributing_particles = 1
903 buf%epsilon(1) = in_epsilon
904 buf%sigma(1) = in_sigma
909 in_cutoff, energy_at_cutoff)
910 buf%shift(1) = -energy_at_cutoff
913 call kim_set_influence_distance_pointer( &
914 model_driver_create_handle, buf%influence_distance(1))
915 call kim_set_neighbor_list_pointers( &
916 model_driver_create_handle, 1, buf%influence_distance, &
917 buf%model_will_not_request_neighbors_of_noncontributing_particles)
922 call kim_set_model_buffer_pointer( &
923 model_driver_create_handle, c_loc(buf))
926 call kim_set_parameter_pointer( &
927 model_driver_create_handle, buf%pcutoff,
"cutoff", &
928 "Distance beyond which particles do not interact with one another.", ierr)
930 call kim_log_entry(model_driver_create_handle, &
931 kim_log_verbosity_error,
"set_parameter")
936 call kim_set_parameter_pointer( &
937 model_driver_create_handle, buf%epsilon,
"epsilon", &
938 "Maximum depth of the potential well.", 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%sigma,
"sigma", &
948 "Distance at which energy is zero and force is repulsive.", ierr)
950 call kim_log_entry(model_driver_create_handle, &
951 kim_log_verbosity_error,
"set_parameter")
960 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)