kim-api  2.2.1+v2.2.1.GNU.GNU.
An Application Programming Interface (API) for the Knowledgebase of Interatomic Models (KIM).
ex_model_driver_P_LJ.f90
Go to the documentation of this file.
1 !
2 ! CDDL HEADER START
3 !
4 ! The contents of this file are subject to the terms of the Common Development
5 ! and Distribution License Version 1.0 (the "License").
6 !
7 ! You can obtain a copy of the license at
8 ! http://www.opensource.org/licenses/CDDL-1.0. See the License for the
9 ! specific language governing permissions and limitations under the License.
10 !
11 ! When distributing Covered Code, include this CDDL HEADER in each file and
12 ! include the License file in a prominent location with the name LICENSE.CDDL.
13 ! If applicable, add the following below this CDDL HEADER, with the fields
14 ! enclosed by brackets "[]" replaced with your own identifying information:
15 !
16 ! Portions Copyright (c) [yyyy] [name of copyright owner]. All rights reserved.
17 !
18 ! CDDL HEADER END
19 !
20 
21 !
22 ! Copyright (c) 2013--2020, Regents of the University of Minnesota.
23 ! All rights reserved.
24 !
25 ! Contributors:
26 ! Ryan S. Elliott
27 ! Ellad B. Tadmor
28 ! Valeriu Smirichinski
29 ! Stephen M. Whalen
30 !
31 
32 !****************************************************************************
33 !**
34 !** MODULE ex_model_driver_P_LJ
35 !**
36 !** Lennard-Jones pair potential KIM Model Driver
37 !** shifted to have zero energy at the cutoff radius
38 !**
39 !** Language: Fortran 2003
40 !**
41 !****************************************************************************
42 
44 
45  use, intrinsic :: iso_c_binding
47  implicit none
48 
49  save
50  private
51  public &
52  buffer_type, &
56  refresh, &
57  write_model, &
58  destroy, &
59  calc_phi, &
60  calc_phi_dphi, &
62  speccode
63 
64  ! Below are the definitions and values of all Model parameters
65  integer(c_int), parameter :: cd = c_double ! for literal constants
66  integer(c_int), parameter :: dim = 3 ! dimensionality of space
67  integer(c_int), parameter :: speccode = 1 ! internal species code
68 
69  !-----------------------------------------------------------------------------
70  !
71  ! Definition of Buffer type
72  !
73  !-----------------------------------------------------------------------------
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)
79  integer(c_int) :: &
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)
84  end type buffer_type
85 
86 contains
87 
88  !-----------------------------------------------------------------------------
89  !
90  ! Calculate pair potential phi(r)
91  !
92  !-----------------------------------------------------------------------------
93  recursive subroutine calc_phi(model_epsilon, &
94  model_sigma, &
95  model_shift, &
96  model_cutoff, r, phi)
97  implicit none
98 
99  !-- Transferred variables
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
106 
107  !-- Local variables
108  real(c_double) rsq, sor, sor6, sor12
109 
110  rsq = r * r ! r^2
111  sor = model_sigma / r ! (sig/r)
112  sor6 = sor * sor * sor !
113  sor6 = sor6 * sor6 ! (sig/r)^6
114  sor12 = sor6 * sor6 ! (sig/r)^12
115  if (r > model_cutoff) then
116  ! Argument exceeds cutoff radius
117  phi = 0.0_cd
118  else
119  phi = 4.0_cd * model_epsilon * (sor12 - sor6) + model_shift
120  end if
121 
122  end subroutine calc_phi
123 
124  !-----------------------------------------------------------------------------
125  !
126  ! Calculate pair potential phi(r) and its derivative dphi(r)
127  !
128  !-----------------------------------------------------------------------------
129  recursive subroutine calc_phi_dphi(model_epsilon, &
130  model_sigma, &
131  model_shift, &
132  model_cutoff, r, phi, dphi)
133  implicit none
134 
135  !-- Transferred variables
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
142 
143  !-- Local variables
144  real(c_double) rsq, sor, sor6, sor12
145 
146  rsq = r * r ! r^2
147  sor = model_sigma / r ! (sig/r)
148  sor6 = sor * sor * sor !
149  sor6 = sor6 * sor6 ! (sig/r)^6
150  sor12 = sor6 * sor6 ! (sig/r)^12
151  if (r > model_cutoff) then
152  ! Argument exceeds cutoff radius
153  phi = 0.0_cd
154  dphi = 0.0_cd
155  else
156  phi = 4.0_cd * model_epsilon * (sor12 - sor6) + model_shift
157  dphi = 24.0_cd * model_epsilon * (-2.0_cd * sor12 + sor6) / r
158  end if
159 
160  end subroutine calc_phi_dphi
161 
162  !-----------------------------------------------------------------------------
163  !
164  ! Calculate pair potential phi(r) and its derivatives dphi(r) and d2phi(r)
165  !
166  !-----------------------------------------------------------------------------
167  recursive subroutine calc_phi_dphi_d2phi(model_epsilon, &
168  model_sigma, &
169  model_shift, &
170  model_cutoff, r, phi, dphi, d2phi)
171  implicit none
172 
173  !-- Transferred variables
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
180 
181  !-- Local variables
182  real(c_double) rsq, sor, sor6, sor12
183 
184  rsq = r * r ! r^2
185  sor = model_sigma / r ! (sig/r)
186  sor6 = sor * sor * sor !
187  sor6 = sor6 * sor6 ! (sig/r)^6
188  sor12 = sor6 * sor6 ! (sig/r)^12
189  if (r > model_cutoff) then
190  ! Argument exceeds cutoff radius
191  phi = 0.0_cd
192  dphi = 0.0_cd
193  d2phi = 0.0_cd
194  else
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
198  end if
199 
200  end subroutine calc_phi_dphi_d2phi
201 
202  !-----------------------------------------------------------------------------
203  !
204  ! Compute energy and forces on particles from the positions.
205  !
206  !-----------------------------------------------------------------------------
207  recursive subroutine compute_energy_forces( &
208  model_compute_handle, model_compute_arguments_handle, ierr) bind(c)
209  implicit none
210 
211  !-- Transferred variables
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
216 
217  !-- Local variables
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, &
222  comp_process_d2Edr2
223  type(buffer_type), pointer :: buf; type(c_ptr) :: pbuf
224 
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)
229 
230  !-- KIM variables
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(:)
240 
241  ! get model buffer from KIM object
242  call kim_get_model_buffer_pointer(model_compute_handle, pbuf)
243  call c_f_pointer(pbuf, buf)
244 
245  model_cutoff = buf%influence_distance(1)
246 
247  ! Check to see if we have been asked to compute the forces, energyperpart,
248  ! energy and d1Edr
249  !
250  ierr = 0
251  call kim_is_callback_present( &
252  model_compute_arguments_handle, &
253  kim_compute_callback_name_process_dedr_term, comp_process_dedr, ierr2)
254  ierr = ierr + ierr2
255  call kim_is_callback_present( &
256  model_compute_arguments_handle, &
257  kim_compute_callback_name_process_d2edr2_term, comp_process_d2edr2, ierr2)
258  ierr = ierr + ierr2
259  if (ierr /= 0) then
260  call kim_log_entry(model_compute_arguments_handle, &
261  kim_log_verbosity_error, "get_compute")
262  ierr = 1
263  return
264  end if
265 
266  ! Unpack data from KIM object
267  !
268  ierr = 0
269  call kim_get_argument_pointer( &
270  model_compute_arguments_handle, &
271  kim_compute_argument_name_number_of_particles, n, ierr2)
272  ierr = ierr + ierr2
273 
274  call kim_get_argument_pointer( &
275  model_compute_arguments_handle, &
276  kim_compute_argument_name_particle_species_codes, &
277  n, particlespeciescodes, ierr2)
278  ierr = ierr + ierr2
279  call kim_get_argument_pointer( &
280  model_compute_arguments_handle, &
281  kim_compute_argument_name_particle_contributing, &
282  n, particlecontributing, ierr2)
283  ierr = ierr + ierr2
284  call kim_get_argument_pointer( &
285  model_compute_arguments_handle, &
286  kim_compute_argument_name_coordinates, dim, n, coor, ierr2)
287  ierr = ierr + ierr2
288  call kim_get_argument_pointer( &
289  model_compute_arguments_handle, &
290  kim_compute_argument_name_partial_energy, energy, ierr2)
291  ierr = ierr + ierr2
292  call kim_get_argument_pointer( &
293  model_compute_arguments_handle, &
294  kim_compute_argument_name_partial_forces, dim, n, force, ierr2)
295  ierr = ierr + ierr2
296  call kim_get_argument_pointer( &
297  model_compute_arguments_handle, &
298  kim_compute_argument_name_partial_particle_energy, n, enepot, ierr2)
299  ierr = ierr + ierr2
300  if (ierr /= 0) then
301  call kim_log_entry(model_compute_arguments_handle, &
302  kim_log_verbosity_error, "get_argument_pointer")
303  ierr = 1
304  return
305  end if
306 
307  if (associated(energy)) then
308  comp_energy = 1
309  else
310  comp_energy = 0
311  end if
312  if (associated(force)) then
313  comp_force = 1
314  else
315  comp_force = 0
316  end if
317  if (associated(enepot)) then
318  comp_enepot = 1
319  else
320  comp_enepot = 0
321  end if
322 
323  ! Check to be sure that the species are correct
324  !
325 
326  ierr = 1 ! assume an error
327  do i = 1, n
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")
332  ierr = 1
333  return
334  end if
335  end do
336  ierr = 0 ! everything is ok
337 
338  ! Initialize potential energies, forces
339  !
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
343 
344  !
345  ! Compute energy and forces
346  !
347 
348  ! Loop over particles and compute energy and forces
349  !
350  do i = 1, n
351 
352  if (particlecontributing(i) == 1) then
353  ! Set up neighbor list for next particle
354  !
355  call kim_get_neighbor_list( &
356  model_compute_arguments_handle, 1, i, numnei, nei1part, ierr)
357  if (ierr /= 0) then
358  ! some sort of problem, exit
359  call kim_log_entry( &
360  model_compute_arguments_handle, kim_log_verbosity_error, &
361  "kim_api_get_neigh")
362  ierr = 1
363  return
364  end if
365 
366  ! Loop over the neighbors of particle i
367  !
368  do jj = 1, numnei
369 
370  j = nei1part(jj) ! get neighbor ID
371 
372  ! compute relative position vector
373  !
374  rij(:) = coor(:, j) - coor(:, i) ! distance vector between i j
375 
376  ! compute energy and forces
377  !
378  rsqij = dot_product(rij, rij) ! compute square distance
379  if (rsqij < buf%cutsq(1)) then ! particles are interacting?
380 
381  r = sqrt(rsqij) ! compute distance
382  if (comp_process_d2edr2 == 1) then
383  call calc_phi_dphi_d2phi(buf%epsilon(1), &
384  buf%sigma(1), &
385  buf%shift(1), &
386  buf%Pcutoff(1), &
387  r, phi, dphi, d2phi) ! compute pair potential
388  ! and it derivatives
389  deidr = 0.5_cd * dphi ! regular contribution
390  d2eidr = 0.5_cd * d2phi
391  elseif (comp_force == 1 .or. comp_process_dedr == 1) then
392  call calc_phi_dphi(buf%epsilon(1), &
393  buf%sigma(1), &
394  buf%shift(1), &
395  buf%Pcutoff(1), &
396  r, phi, dphi) ! compute pair potential
397  ! and it derivative
398 
399  deidr = 0.5_cd * dphi ! regular contribution
400  else
401  call calc_phi(buf%epsilon(1), &
402  buf%sigma(1), &
403  buf%shift(1), &
404  buf%Pcutoff(1), &
405  r, phi) ! compute just pair potential
406  end if
407 
408  ! contribution to energy
409  !
410  if (comp_enepot == 1) then
411  enepot(i) = enepot(i) + 0.5_cd * phi ! accumulate energy
412  end if
413  if (comp_energy == 1) then
414  energy = energy + 0.5_cd * phi ! add half v to total energy
415  end if
416 
417  ! contribution to process_dEdr
418  !
419  if (comp_process_dedr == 1) then
420  call kim_process_dedr_term( &
421  model_compute_arguments_handle, deidr, r, rij, i, j, ierr)
422  end if
423 
424  ! contribution to process_d2Edr2
425  if (comp_process_d2edr2 == 1) then
426  r_pairs(1) = r
427  r_pairs(2) = r
428  rij_pairs(:, 1) = rij
429  rij_pairs(:, 2) = rij
430  i_pairs(1) = i
431  i_pairs(2) = i
432  j_pairs(1) = j
433  j_pairs(2) = j
434 
435  call kim_process_d2edr2_term( &
436  model_compute_arguments_handle, d2eidr, &
437  r_pairs, rij_pairs, i_pairs, j_pairs, ierr)
438  end if
439 
440  ! contribution to forces
441  !
442  if (comp_force == 1) then
443  force(:, i) = force(:, i) + deidr * rij / r ! accumulate force on particle i
444  force(:, j) = force(:, j) - deidr * rij / r ! accumulate force on particle j
445  end if
446 
447  end if
448 
449  end do ! loop on jj
450 
451  end if ! if particleContributing
452 
453  end do ! do i
454 
455  ! Everything is great
456  !
457  ierr = 0
458  return
459 
460  end subroutine compute_energy_forces
461 
462  !-----------------------------------------------------------------------------
463  !
464  ! Model driver refresh routine
465  !
466  !-----------------------------------------------------------------------------
467  recursive subroutine refresh(model_refresh_handle, ierr) bind(c)
468  implicit none
469 
470  !-- transferred variables
471  type(kim_model_refresh_handle_type), intent(in) :: model_refresh_handle
472  integer(c_int), intent(out) :: ierr
473 
474  !-- Local variables
475  real(c_double) energy_at_cutoff
476  type(buffer_type), pointer :: buf; type(c_ptr) :: pbuf
477 
478  ! get model buffer from KIM object
479  call kim_get_model_buffer_pointer(model_refresh_handle, pbuf)
480  call c_f_pointer(pbuf, buf)
481 
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)
487 
488  ! Set new values in KIM object and buffer
489  !
490  buf%influence_distance(1) = buf%Pcutoff(1)
491  buf%cutsq(1) = (buf%Pcutoff(1))**2
492  ! calculate pair potential at r=cutoff with shift=0.0
493  call calc_phi(buf%epsilon(1), &
494  buf%sigma(1), &
495  0.0_cd, &
496  buf%Pcutoff(1), &
497  buf%Pcutoff(1), energy_at_cutoff)
498  buf%shift(1) = -energy_at_cutoff
499 
500  ierr = 0
501  return
502 
503  end subroutine refresh
504 
505  !-----------------------------------------------------------------------------
506  !
507  ! Model driver write_model routine
508  !
509  !-----------------------------------------------------------------------------
510  recursive subroutine write_model( &
511  model_write_parameterized_model_handle, ierr) bind(c)
512  implicit none
513 
514  !-- transferred variables
515  type(kim_model_write_parameterized_model_handle_type), intent(in) &
516  :: model_write_parameterized_model_handle
517  integer(c_int), intent(out) :: ierr
518 
519  !-- Local variables
520  integer i
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
526 
527  ! get model buffer from KIM object
528  call kim_get_model_buffer_pointer( &
529  model_write_parameterized_model_handle, pbuf)
530  call c_f_pointer(pbuf, buf)
531 
532  call kim_get_path(model_write_parameterized_model_handle, path)
533  call kim_get_model_name(model_write_parameterized_model_handle, model_name)
534 
535  write (string_buffer, '(A)') trim(model_name)//".params"
536  call kim_set_parameter_file_name(model_write_parameterized_model_handle, &
537  string_buffer)
538  write (string_buffer, '(A)') trim(path)//"/"//trim(string_buffer)
539 
540  open (42, file=trim(string_buffer), &
541  status="REPLACE", action="WRITE", iostat=ierr)
542  if (ierr /= 0) then
543  call kim_log_entry( &
544  model_write_parameterized_model_handle, kim_log_verbosity_error, &
545  "Unable to open parameter file for writing.")
546  return
547  end if
548 
549  do i = 1, 100
550  species_name(i:i) = buf%species_name(i)
551  end do
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)
556 
557  ierr = 0
558  return
559 
560  end subroutine write_model
561 
562  !-----------------------------------------------------------------------------
563  !
564  ! Model driver destroy routine
565  !
566  !-----------------------------------------------------------------------------
567  recursive subroutine destroy(model_destroy_handle, ierr) bind(c)
568  implicit none
569 
570  !-- Transferred variables
571  type(kim_model_destroy_handle_type), intent(in) :: model_destroy_handle
572  integer(c_int), intent(out) :: ierr
573 
574  !-- Local variables
575  type(buffer_type), pointer :: buf; type(c_ptr) :: pbuf
576 
577  ! get model buffer from KIM object
578  call kim_get_model_buffer_pointer(model_destroy_handle, pbuf)
579  call c_f_pointer(pbuf, buf)
580 
581  deallocate (buf)
582 
583  ierr = 0
584  return
585 
586  end subroutine destroy
587 
588  !-----------------------------------------------------------------------------
589  !
590  ! Model driver compute arguments create routine
591  !
592  !-----------------------------------------------------------------------------
593  recursive subroutine compute_arguments_create( &
594  model_compute_handle, model_compute_arguments_create_handle, ierr) bind(c)
595  implicit none
596 
597  !-- Transferred variables
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
602 
603  integer(c_int) ierr2
604 
605  ! avoid unsed dummy argument warnings
606  if (model_compute_handle == kim_model_compute_null_handle) continue
607 
608  ierr = 0
609  ierr2 = 0
610 
611  ! register arguments
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)
620  ierr = ierr + 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)
625  ierr = ierr + ierr2
626  if (ierr /= 0) then
627  call kim_log_entry( &
628  model_compute_arguments_create_handle, kim_log_verbosity_error, &
629  "Unable to register arguments support_statuss")
630  ierr = 1
631  goto 42
632  end if
633 
634  ! register callbacks
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)
643  ierr = ierr + ierr2
644  if (ierr /= 0) then
645  call kim_log_entry( &
646  model_compute_arguments_create_handle, kim_log_verbosity_error, &
647  "Unable to register callbacks support_statuss")
648  ierr = 1
649  goto 42
650  end if
651 
652  ierr = 0
653 42 continue
654  return
655 
656  end subroutine compute_arguments_create
657 
658  !-----------------------------------------------------------------------------
659  !
660  ! Model driver compute arguments destroy routine
661  !
662  !-----------------------------------------------------------------------------
663  recursive subroutine compute_arguments_destroy( &
664  model_compute_handle, model_compute_arguments_destroy_handle, ierr) bind(c)
665  implicit none
666 
667  !-- Transferred variables
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
672 
673  ! avoid unsed dummy argument warnings
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
677 
678  ierr = 0
679  return
680  end subroutine compute_arguments_destroy
681 
682 end module ex_model_driver_p_lj
683 
684 !-----------------------------------------------------------------------------
685 !
686 ! Model driver create routine (REQUIRED)
687 !
688 !-----------------------------------------------------------------------------
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, &
692  ierr) bind(c)
693  use, intrinsic :: iso_c_binding
696  implicit none
697  integer(c_int), parameter :: cd = c_double ! used for literal constants
698 
699  !-- Transferred variables
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
709 
710  !-- Local variables
711  integer i
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
719  ! define variables for all model parameters to be read in
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
726 
727  ! register units
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)
735  if (ierr /= 0) then
736  call kim_log_entry(model_driver_create_handle, &
737  kim_log_verbosity_error, "Unable to set units")
738  ierr = 1
739  goto 42
740  end if
741 
742  ! register numbering
743  call kim_set_model_numbering( &
744  model_driver_create_handle, kim_numbering_one_based, ierr)
745  if (ierr /= 0) then
746  call kim_log_entry(model_driver_create_handle, &
747  kim_log_verbosity_error, "Unable to set numbering")
748  ierr = 1
749  goto 42
750  end if
751 
752  ! store callback pointers in KIM object
753  call kim_set_routine_pointer( &
754  model_driver_create_handle, kim_model_routine_name_compute, &
755  kim_language_name_fortran, 1, c_funloc(compute_energy_forces), ierr)
756  call kim_set_routine_pointer( &
757  model_driver_create_handle, &
758  kim_model_routine_name_compute_arguments_create, &
759  kim_language_name_fortran, 1, c_funloc(compute_arguments_create), ierr2)
760  ierr = ierr + ierr2
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)
764  ierr = ierr + 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)
769  ierr = ierr + ierr2
770  call kim_set_routine_pointer( &
771  model_driver_create_handle, &
772  kim_model_routine_name_compute_arguments_destroy, &
773  kim_language_name_fortran, 1, c_funloc(compute_arguments_destroy), ierr2)
774  ierr = ierr + ierr2
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)
778  ierr = ierr + ierr2
779  if (ierr /= 0) then
780  call kim_log_entry( &
781  model_driver_create_handle, kim_log_verbosity_error, &
782  "Unable to store callback pointers")
783  ierr = 1
784  goto 42
785  end if
786 
787  ! process parameter files
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")
794  ierr = 1
795  goto 42
796  end if
797 
798  ! Read in model parameters from parameter file
799  !
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)
804  if (ierr /= 0) then
805  call kim_log_entry( &
806  model_driver_create_handle, kim_log_verbosity_error, &
807  "Unable to get parameter file basename")
808  ierr = 1
809  goto 42
810  end if
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
818  close (10)
819 
820  goto 200
821 100 continue
822  ! reading parameters failed
823  call kim_log_entry(model_driver_create_handle, &
824  kim_log_verbosity_error, "Unable to read LJ parameters")
825  ierr = 1
826  goto 42
827 
828 200 continue
829 
830  ! register species
831  call kim_from_string(in_species, species_name)
832  call kim_set_species_code( &
833  model_driver_create_handle, species_name, speccode, ierr)
834  if (ierr /= 0) then
835  call kim_log_entry(model_driver_create_handle, &
836  kim_log_verbosity_error, "Unable to set species code")
837  ierr = 1
838  goto 42
839  end if
840 
841  ! convert to appropriate units
842  call kim_convert_unit( &
843  kim_length_unit_a, &
844  kim_energy_unit_ev, &
845  kim_charge_unit_e, &
846  kim_temperature_unit_k, &
847  kim_time_unit_ps, &
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)
854  if (ierr /= 0) then
855  call kim_log_entry(model_driver_create_handle, &
856  kim_log_verbosity_error, "kim_api_convert_to_act_unit")
857  ierr = 1
858  goto 42
859  end if
860  in_cutoff = in_cutoff * factor
861 
862  call kim_convert_unit( &
863  kim_length_unit_a, &
864  kim_energy_unit_ev, &
865  kim_charge_unit_e, &
866  kim_temperature_unit_k, &
867  kim_time_unit_ps, &
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)
874  if (ierr /= 0) then
875  call kim_log_entry(model_driver_create_handle, &
876  kim_log_verbosity_error, "kim_api_convert_to_act_unit")
877  ierr = 1
878  goto 42
879  end if
880  in_epsilon = in_epsilon * factor
881 
882  call kim_convert_unit( &
883  kim_length_unit_a, &
884  kim_energy_unit_ev, &
885  kim_charge_unit_e, &
886  kim_temperature_unit_k, &
887  kim_time_unit_ps, &
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)
894  if (ierr /= 0) then
895  call kim_log_entry(model_driver_create_handle, &
896  kim_log_verbosity_error, "kim_api_convert_to_act_unit")
897  ierr = 1
898  goto 42
899  end if
900  in_sigma = in_sigma * factor
901 
902  allocate (buf)
903 
904  ! setup buffer
905  ! set value of parameters
906  do i = 1, 100
907  buf%species_name(i) = in_species(i:i)
908  end do
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
915  call calc_phi(in_epsilon, &
916  in_sigma, &
917  0.0_cd, &
918  in_cutoff, &
919  in_cutoff, energy_at_cutoff)
920  buf%shift(1) = -energy_at_cutoff
921 
922  ! store model cutoff in KIM object
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)
928 
929  ! end setup buffer
930 
931  ! store in model buffer
932  call kim_set_model_buffer_pointer( &
933  model_driver_create_handle, c_loc(buf))
934 
935  ! set pointers to parameters in KIM object
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)
939  if (ierr /= 0) then
940  call kim_log_entry(model_driver_create_handle, &
941  kim_log_verbosity_error, "set_parameter")
942  ierr = 1
943  goto 42
944  end if
945 
946  call kim_set_parameter_pointer( &
947  model_driver_create_handle, buf%epsilon, "epsilon", &
948  "Maximum depth of the potential well.", ierr)
949  if (ierr /= 0) then
950  call kim_log_entry(model_driver_create_handle, &
951  kim_log_verbosity_error, "set_parameter")
952  ierr = 1
953  goto 42
954  end if
955 
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)
959  if (ierr /= 0) then
960  call kim_log_entry(model_driver_create_handle, &
961  kim_log_verbosity_error, "set_parameter")
962  ierr = 1
963  goto 42
964  end if
965 
966  ierr = 0
967 42 continue
968  return
969 
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)