(git:374b731)
Loading...
Searching...
No Matches
pair_potential.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \par History
10!> September 2005 - Introduced the Born-Mayer-Huggins-Fumi-Tosi Potential (BMHTF)
11!> 2006 - Major rewriting of the routines.. Linear scaling setup of splines
12!> 2007 - Teodoro Laino - University of Zurich - Multiple potential
13!> Major rewriting nr.2
14!> \author CJM
15! **************************************************************************************************
17
20 USE cp_files, ONLY: close_file,&
25 USE fparser, ONLY: finalizef,&
26 initf,&
27 parsef
28 USE kinds, ONLY: default_path_length,&
30 dp
31 USE pair_potential_types, ONLY: &
36 USE pair_potential_util, ONLY: ener_pot,&
37 ener_zbl,&
39 USE physcon, ONLY: bohr,&
40 evolt,&
41 kjmol
42 USE splines_methods, ONLY: init_spline,&
52 USE string_table, ONLY: str2id
53 USE util, ONLY: sort
54#include "./base/base_uses.f90"
55
56 IMPLICIT NONE
57
58 PRIVATE
59 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pair_potential'
60 REAL(KIND=dp), PARAMETER, PRIVATE :: min_hicut_value = 1.0e-15_dp, &
61 default_hicut_value = 1.0e3_dp
62 INTEGER, PARAMETER, PRIVATE :: MAX_POINTS = 2000000
63
64 PUBLIC :: spline_nonbond_control, &
67
68CONTAINS
69
70! **************************************************************************************************
71!> \brief Initialize genpot
72!> \param potparm ...
73!> \param ntype ...
74!> \par History
75!> Teo 2007.06 - Zurich University
76! **************************************************************************************************
77 SUBROUTINE init_genpot(potparm, ntype)
78 TYPE(pair_potential_pp_type), POINTER :: potparm
79 INTEGER, INTENT(IN) :: ntype
80
81 CHARACTER(len=*), PARAMETER :: routinen = 'init_genpot'
82
83 INTEGER :: handle, i, j, k, ngp
84 TYPE(pair_potential_single_type), POINTER :: pot
85
86 CALL timeset(routinen, handle)
87
88 NULLIFY (pot)
89 ngp = 0
90 ! Prescreen for general potential type
91 DO i = 1, ntype ! i: first atom type
92 DO j = 1, i ! j: second atom type
93 pot => potparm%pot(i, j)%pot
94 ngp = ngp + count(pot%type == gp_type)
95 END DO
96 END DO
97 CALL initf(ngp)
98 ngp = 0
99 DO i = 1, ntype ! i: first atom type
100 DO j = 1, i ! j: second atom type
101 pot => potparm%pot(i, j)%pot
102 DO k = 1, SIZE(pot%type)
103 IF (pot%type(k) == gp_type) THEN
104 ngp = ngp + 1
105 pot%set(k)%gp%myid = ngp
106 CALL parsef(ngp, trim(pot%set(k)%gp%potential), pot%set(k)%gp%parameters)
107 END IF
108 END DO
109 END DO
110 END DO
111 CALL timestop(handle)
112
113 END SUBROUTINE init_genpot
114
115! **************************************************************************************************
116!> \brief creates the splines for the potentials
117!> \param spline_env ...
118!> \param potparm ...
119!> \param atomic_kind_set ...
120!> \param eps_spline ...
121!> \param max_energy ...
122!> \param rlow_nb ...
123!> \param emax_spline ...
124!> \param npoints ...
125!> \param iw ...
126!> \param iw2 ...
127!> \param iw3 ...
128!> \param do_zbl ...
129!> \param shift_cutoff ...
130!> \param nonbonded_type ...
131!> \par History
132!> Teo 2006.05 : Improved speed and accuracy. Linear scaling of the setup
133! **************************************************************************************************
134 SUBROUTINE spline_nonbond_control(spline_env, potparm, atomic_kind_set, &
135 eps_spline, max_energy, rlow_nb, emax_spline, npoints, iw, iw2, iw3, do_zbl, &
136 shift_cutoff, nonbonded_type)
137
138 TYPE(spline_environment_type), POINTER :: spline_env
139 TYPE(pair_potential_pp_type), POINTER :: potparm
140 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
141 REAL(kind=dp), INTENT(IN) :: eps_spline, max_energy, rlow_nb, &
142 emax_spline
143 INTEGER, INTENT(IN) :: npoints, iw, iw2, iw3
144 LOGICAL, INTENT(IN) :: do_zbl, shift_cutoff
145 CHARACTER(LEN=*), INTENT(IN) :: nonbonded_type
146
147 CHARACTER(len=*), PARAMETER :: routinen = 'spline_nonbond_control'
148
149 INTEGER :: handle, i, ip, j, k, n, ncount, &
150 npoints_spline, ntype
151 LOGICAL :: found_locut
152 REAL(kind=dp) :: energy_cutoff, hicut, hicut0, locut
153 TYPE(pair_potential_single_type), POINTER :: pot
154
155 n = 0
156 ncount = 0
157
158 ntype = SIZE(atomic_kind_set)
159 CALL timeset(routinen, handle)
160 IF (iw3 > 0) THEN
161 WRITE (iw3, "(/,T2,A,I0,A,I0,A)") &
162 "SPLINE_INFO| Generating ", (ntype*(ntype + 1))/2, " splines for "// &
163 trim(adjustl(nonbonded_type))//" interactions "
164 WRITE (iw3, "(T2,A,I0,A)") &
165 " Due to ", ntype, " different atomic kinds"
166 END IF
167 CALL init_genpot(potparm, ntype)
168 ! Real computation of splines
169 ip = 0
170 DO i = 1, ntype
171 DO j = 1, i
172 pot => potparm%pot(i, j)%pot
173 IF (iw3 > 0 .AND. iw <= 0) THEN
174 IF (mod(i*(i - 1)/2 + j, max(1, (ntype*(ntype + 1))/(2*10))) == 0) THEN
175 WRITE (unit=iw3, advance="NO", fmt='(2X,A3,I0)') '...', i*(i - 1)/2 + j
176 ip = ip + 1
177 IF (ip >= 11) THEN
178 WRITE (iw3, *)
179 ip = 0
180 END IF
181 END IF
182 END IF
183 ! Setup of Exclusion Types
184 pot%no_pp = .true.
185 pot%no_mb = .true.
186 DO k = 1, SIZE(pot%type)
187 SELECT CASE (pot%type(k))
190 pot%no_pp = .false.
191 CASE (tersoff_type)
192 pot%no_mb = .false.
193 CASE (siepmann_type)
194 pot%no_mb = .false.
195 CASE (gal_type)
196 pot%no_mb = .false.
197 CASE (gal21_type)
198 pot%no_mb = .false.
199 CASE (nn_type)
200 ! Do nothing..
201 CASE DEFAULT
202 ! Never reach this point
203 cpabort("")
204 END SELECT
205 ! Special case for EAM
206 SELECT CASE (pot%type(k))
208 pot%no_mb = .false.
209 END SELECT
210 END DO
211
212 ! Starting SetUp of splines
213 IF (.NOT. pot%undef) cycle
214 ncount = ncount + 1
215 n = spline_env%spltab(i, j)
216 locut = rlow_nb
217 hicut0 = sqrt(pot%rcutsq)
218 IF (abs(hicut0) <= min_hicut_value) hicut0 = default_hicut_value
219 hicut = hicut0/sqrt(pot%spl_f%rcutsq_f)
220
221 energy_cutoff = pot%spl_f%cutoff
222
223 ! Find the real locut according emax_spline
224 CALL get_spline_cutoff(hicut, locut, found_locut, pot, do_zbl, &
225 energy_cutoff, emax_spline)
226 locut = max(locut*sqrt(pot%spl_f%rcutsq_f), rlow_nb)
227
228 ! Real Generation of the Spline
229 npoints_spline = npoints
230 CALL generate_spline_low(spline_env%spl_pp(n)%spl_p, npoints_spline, locut, &
231 hicut, eps_spline, iw, iw2, i, j, n, ncount, max_energy, pot, &
232 energy_cutoff, found_locut, do_zbl, atomic_kind_set, &
233 nonbonded_type)
234
235 pot%undef = .false.
236 ! Unique Spline working only for a pure LJ potential..
237 IF (SIZE(pot%type) == 1) THEN
238 IF (any(potential_single_allocation == pot%type(1))) THEN
239 ! Restoring the proper values for the generating spline pot
240 IF ((pot%type(1) == lj_type) .OR. (pot%type(1) == lj_charmm_type)) THEN
241 pot%set(1)%lj%sigma6 = pot%set(1)%lj%sigma6*pot%spl_f%rscale(1)**3
242 pot%set(1)%lj%sigma12 = pot%set(1)%lj%sigma6**2
243 pot%set(1)%lj%epsilon = pot%set(1)%lj%epsilon*pot%spl_f%fscale(1)
244 END IF
245 END IF
246 END IF
247 ! Correct Cutoff...
248 IF (shift_cutoff) THEN
249 pot%spl_f%cutoff = pot%spl_f%cutoff*pot%spl_f%fscale(1) - &
250 ener_pot(pot, hicut0, 0.0_dp)
251 END IF
252 END DO
253 END DO
254 CALL finalizef()
255
256 IF (iw > 0) THEN
257 WRITE (iw, '(/,T2,A,I0)') &
258 "SPLINE_INFO| Number of pair potential splines allocated: ", maxval(spline_env%spltab)
259 END IF
260 IF (iw3 > 0) THEN
261 WRITE (iw3, '(/,T2,A,I0,/,T2,A)') &
262 "SPLINE_INFO| Number of unique splines computed: ", maxval(spline_env%spltab), &
263 "SPLINE_INFO| Done"
264 END IF
265
266 CALL timestop(handle)
267
268 END SUBROUTINE spline_nonbond_control
269
270! **************************************************************************************************
271!> \brief Finds the cutoff for the generation of the spline
272!> In a two pass approach, first with low resolution, refine in a second iteration
273!> \param hicut ...
274!> \param locut ...
275!> \param found_locut ...
276!> \param pot ...
277!> \param do_zbl ...
278!> \param energy_cutoff ...
279!> \param emax_spline ...
280!> \par History
281!> Splitting in order to make some season cleaning..
282!> \author Teodoro Laino [tlaino] 2007.06
283! **************************************************************************************************
284 SUBROUTINE get_spline_cutoff(hicut, locut, found_locut, pot, do_zbl, &
285 energy_cutoff, emax_spline)
286
287 REAL(kind=dp), INTENT(IN) :: hicut
288 REAL(kind=dp), INTENT(INOUT) :: locut
289 LOGICAL, INTENT(OUT) :: found_locut
290 TYPE(pair_potential_single_type), OPTIONAL, &
291 POINTER :: pot
292 LOGICAL, INTENT(IN) :: do_zbl
293 REAL(kind=dp), INTENT(IN) :: energy_cutoff, emax_spline
294
295 INTEGER :: ilevel, jx
296 REAL(kind=dp) :: dx2, e, locut_found, x
297
298 dx2 = (hicut - locut)
299 x = hicut
300 locut_found = locut
301 found_locut = .false.
302 DO ilevel = 1, 2
303 dx2 = dx2/100.0_dp
304 DO jx = 1, 100
305 e = ener_pot(pot, x, energy_cutoff)
306 IF (do_zbl) THEN
307 e = e + ener_zbl(pot, x)
308 END IF
309 IF (abs(e) > emax_spline) THEN
310 locut_found = x
311 found_locut = .true.
312 EXIT
313 END IF
314 x = x - dx2
315 END DO
316 x = x + dx2
317 END DO
318 locut = locut_found
319
320 END SUBROUTINE get_spline_cutoff
321
322! **************************************************************************************************
323!> \brief Real Generation of spline..
324!> \param spl_p ...
325!> \param npoints ...
326!> \param locut ...
327!> \param hicut ...
328!> \param eps_spline ...
329!> \param iw ...
330!> \param iw2 ...
331!> \param i ...
332!> \param j ...
333!> \param n ...
334!> \param ncount ...
335!> \param max_energy ...
336!> \param pot ...
337!> \param energy_cutoff ...
338!> \param found_locut ...
339!> \param do_zbl ...
340!> \param atomic_kind_set ...
341!> \param nonbonded_type ...
342!> \par History
343!> Splitting in order to make some season cleaning..
344!> \author Teodoro Laino [tlaino] 2007.06
345! **************************************************************************************************
346 SUBROUTINE generate_spline_low(spl_p, npoints, locut, hicut, eps_spline, &
347 iw, iw2, i, j, n, ncount, max_energy, pot, energy_cutoff, &
348 found_locut, do_zbl, atomic_kind_set, nonbonded_type)
349
350 TYPE(spline_data_p_type), DIMENSION(:), POINTER :: spl_p
351 INTEGER, INTENT(INOUT) :: npoints
352 REAL(kind=dp), INTENT(IN) :: locut, hicut, eps_spline
353 INTEGER, INTENT(IN) :: iw, iw2, i, j, n, ncount
354 REAL(kind=dp), INTENT(IN) :: max_energy
355 TYPE(pair_potential_single_type), POINTER :: pot
356 REAL(kind=dp), INTENT(IN), OPTIONAL :: energy_cutoff
357 LOGICAL, INTENT(IN) :: found_locut, do_zbl
358 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
359 CHARACTER(LEN=*), INTENT(IN) :: nonbonded_type
360
361 CHARACTER(LEN=2*default_string_length) :: message, tmp
362 CHARACTER(LEN=default_path_length) :: file_name
363 INTEGER :: ix, jx, mfac, nppa, nx, unit_number
364 LOGICAL :: fixed_spline_points
365 REAL(kind=dp) :: df, dg, dh, diffmax, dx, dx2, e, &
366 e_spline, f, g, h, r, rcut, x, x2, &
367 xdum, xdum1, xsav
368 TYPE(cp_logger_type), POINTER :: logger
369 TYPE(spline_data_type), POINTER :: spline_data
370 TYPE(spline_factor_type), POINTER :: spl_f
371
372 NULLIFY (logger, spl_f)
373 logger => cp_get_default_logger()
374
375 CALL spline_factor_create(spl_f)
376 mfac = 5
377 IF (npoints > 0) THEN
378 fixed_spline_points = .true.
379 ELSE
380 fixed_spline_points = .false.
381 npoints = 20
382 IF (.NOT. found_locut) npoints = 2
383 END IF
384 spline_data => spl_p(1)%spline_data
385 DO WHILE (.true.)
386 CALL init_splinexy(spline_data, npoints + 1)
387 dx2 = (1.0_dp/locut**2 - 1.0_dp/hicut**2)/real(npoints, kind=dp)
388 x2 = 1.0_dp/hicut**2
389 spline_data%x1 = x2
390 DO jx = 1, npoints + 1
391 ! jx: loop over 1/distance**2
392 x = sqrt(1.0_dp/x2)
393 e = ener_pot(pot, x, energy_cutoff)
394 IF (do_zbl) THEN
395 e = e + ener_zbl(pot, x)
396 END IF
397 spline_data%y(jx) = e
398 x2 = x2 + dx2
399 END DO
400 CALL init_spline(spline_data, dx=dx2)
401 ! This is the check for required accuracy on spline setup
402 dx2 = (hicut - locut)/real(mfac*npoints + 1, kind=dp)
403 x2 = locut + dx2
404 diffmax = -1.0_dp
405 xsav = hicut
406 ! if a fixed number of points is requested, no check on its error
407 IF (fixed_spline_points) EXIT
408 DO jx = 1, mfac*npoints
409 x = x2
410 e = ener_pot(pot, x, energy_cutoff)
411 IF (do_zbl) THEN
412 e = e + ener_zbl(pot, x)
413 END IF
414 IF (abs(e) < max_energy) THEN
415 xdum1 = abs(e - potential_s(spl_p, x*x, xdum, spl_f, logger))
416 diffmax = max(diffmax, xdum1)
417 xsav = min(x, xsav)
418 END IF
419 x2 = x2 + dx2
420 IF (x2 > hicut) EXIT
421 END DO
422 IF (npoints > max_points) THEN
423 WRITE (message, '(A,I8,A,G12.6,A)') "SPLINE_INFO| Number of points: ", npoints, &
424 " obtained accuracy ", diffmax, ". MM SPLINE: no convergence on required"// &
425 " accuracy (adjust EPS_SPLINE and rerun)"
426 CALL cp_abort(__location__, trim(message))
427 END IF
428 ! accuracy is poor or we have found no points below max_energy, refine mesh
429 IF (diffmax > eps_spline .OR. diffmax < 0.0_dp) THEN
430 npoints = ceiling(1.2_dp*real(npoints, kind=dp))
431 ELSE
432 EXIT
433 END IF
434 END DO
435 ! Print spline info to STDOUT if requested
436 IF (iw > 0) THEN
437 WRITE (unit=iw, &
438 fmt="(/,A,I0,/,A,I0,/,A,I0,1X,I0,/,A,/,A,I0,2(/,A,ES13.6),2(/,A,2ES13.6))") &
439 " SPLINE_INFO| Spline number: ", ncount, &
440 " SPLINE_INFO| Unique spline number: ", n, &
441 " SPLINE_INFO| Atomic kind numbers: ", i, j, &
442 " SPLINE_INFO| Atomic kind names: "//trim(adjustl(atomic_kind_set(i)%name))//" "// &
443 trim(adjustl(atomic_kind_set(j)%name)), &
444 " SPLINE_INFO| Number of spline points: ", npoints, &
445 " SPLINE_INFO| Requested accuracy [Hartree]: ", eps_spline, &
446 " SPLINE_INFO| Achieved accuracy [Hartree]: ", diffmax, &
447 " SPLINE_INFO| Spline range [bohr]: ", locut, hicut, &
448 " SPLINE_INFO| Spline range used to achieve accuracy [bohr]:", xsav, hicut
449 dx2 = (hicut - locut)/real(npoints + 1, kind=dp)
450 x = locut + dx2
451 WRITE (unit=iw, fmt='(A,ES17.9)') &
452 " SPLINE_INFO| Spline value at RMIN [Hartree]: ", potential_s(spl_p, x*x, xdum, spl_f, logger), &
453 " SPLINE_INFO| Spline value at RMAX [Hartree]: ", potential_s(spl_p, hicut*hicut, xdum, spl_f, logger), &
454 " SPLINE_INFO| Non-bonded energy cutoff [Hartree]: ", energy_cutoff
455 END IF
456 ! Print spline data on file if requested
457 IF (iw2 > 0) THEN
458 ! Set increment to 200 points per Angstrom
459 nppa = 200
460 dx = bohr/real(nppa, kind=dp)
461 nx = nint(hicut/dx)
462 file_name = ""
463 tmp = adjustl(cp_to_string(n))
464 WRITE (unit=file_name, fmt="(A,I0,A)") &
465 trim(adjustl(nonbonded_type))//"_SPLINE_"//trim(tmp)//"_"// &
466 trim(adjustl(atomic_kind_set(i)%name))//"_"// &
467 trim(adjustl(atomic_kind_set(j)%name))
468 CALL open_file(file_name=file_name, &
469 file_status="UNKNOWN", &
470 file_form="FORMATTED", &
471 file_action="WRITE", &
472 unit_number=unit_number)
473 WRITE (unit=unit_number, &
474 fmt="(2(A,I0,/),A,I0,1X,I0,/,A,/,A,I0,2(/,A,ES13.6),2(/,A,2ES13.6),/,A,ES13.6,/,A,I0,A,/,A)") &
475 "# Spline number: ", ncount, &
476 "# Unique spline number: ", n, &
477 "# Atomic kind numbers: ", i, j, &
478 "# Atomic kind names: "//trim(adjustl(atomic_kind_set(i)%name))//" "// &
479 trim(adjustl(atomic_kind_set(j)%name)), &
480 "# Number of spline points: ", npoints, &
481 "# Requested accuracy [eV]: ", eps_spline*evolt, &
482 "# Achieved accuracy [eV]: ", diffmax*evolt, &
483 "# Spline range [Angstrom]: ", locut/bohr, hicut/bohr, &
484 "# Spline range used to achieve accuracy [Angstrom]:", xsav/bohr, hicut/bohr, &
485 "# Non-bonded energy cutoff [eV]: ", energy_cutoff*evolt, &
486 "# Test spline using ", nppa, " points per Angstrom:", &
487 "# Abscissa [Angstrom] Energy [eV] Splined energy [eV] Derivative [eV/Angstrom]"// &
488 " |Energy error| [eV]"
489 x = 0.0_dp
490 DO jx = 0, nx
491 IF (x > hicut) x = hicut
492 IF (x > locut) THEN
493 e = ener_pot(pot, x, energy_cutoff)
494 IF (do_zbl) e = e + ener_zbl(pot, x)
495 e_spline = potential_s(spl_p, x*x, xdum, spl_f, logger)
496 WRITE (unit=unit_number, fmt="(5ES25.12)") &
497 x/bohr, e*evolt, e_spline*evolt, -bohr*x*xdum*evolt, abs((e - e_spline)*evolt)
498 END IF
499 x = x + dx
500 END DO
501 CALL close_file(unit_number=unit_number)
502 !MK Write table.xvf for GROMACS 4.5.5
503 WRITE (unit=file_name, fmt="(A,I0,A)") &
504 "table_"// &
505 trim(adjustl(atomic_kind_set(i)%name))//"_"// &
506 trim(adjustl(atomic_kind_set(j)%name))//".xvg"
507 CALL open_file(file_name=file_name, &
508 file_status="UNKNOWN", &
509 file_form="FORMATTED", &
510 file_action="WRITE", &
511 unit_number=unit_number)
512 ! Recommended increment for dp is 0.0005 nm = 0.005 Angstrom
513 ! which are 200 points/Angstrom
514 rcut = 0.1_dp*hicut/bohr
515 x = 0.0_dp
516 DO jx = 0, nx
517 IF (x > hicut) x = hicut
518 r = 0.1_dp*x/bohr ! Convert bohr to nm
519 IF (x <= locut) THEN
520 WRITE (unit=unit_number, fmt="(7ES25.12)") &
521 r, (0.0_dp, ix=1, 6)
522 ELSE
523 e_spline = potential_s(spl_p, x*x, xdum, spl_f, logger)
524 f = 1.0_dp/r
525 df = -1.0_dp/r**2
526 g = -1.0_dp/r**6 + 1.0_dp/rcut**6
527 dg = 6.0_dp/r**7
528 h = e_spline*kjmol
529 dh = -10.0_dp*bohr*x*xdum*kjmol
530 WRITE (unit=unit_number, fmt="(7ES25.12)") &
531 r, f, -df, & ! r, f(r), -f'(r) => probably not used
532 g, -dg, & ! g(r), -g'(r) => not used, if C = 0
533 h, -dh ! h(r), -h'(r) => used, if A = 1
534 END IF
535 x = x + dx
536 END DO
537 CALL close_file(unit_number=unit_number)
538 END IF
539
540 CALL spline_factor_release(spl_f)
541
542 END SUBROUTINE generate_spline_low
543
544! **************************************************************************************************
545!> \brief Prescreening of the effective bonds evaluations. linear scaling algorithm
546!> \param spline_env ...
547!> \param potparm ...
548!> \param atomic_kind_set ...
549!> \param do_zbl ...
550!> \param shift_cutoff ...
551!> \author Teodoro Laino [tlaino] 2006.05
552! **************************************************************************************************
553 SUBROUTINE get_nonbond_storage(spline_env, potparm, atomic_kind_set, do_zbl, &
554 shift_cutoff)
555
556 TYPE(spline_environment_type), POINTER :: spline_env
557 TYPE(pair_potential_pp_type), POINTER :: potparm
558 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
559 LOGICAL, INTENT(IN) :: do_zbl, shift_cutoff
560
561 CHARACTER(len=*), PARAMETER :: routinen = 'get_nonbond_storage'
562
563 INTEGER :: handle, i, idim, iend, istart, j, k, &
564 locij, n, ndim, nk, ntype, nunique, &
565 nvar, pot_target, tmpij(2), tmpij0(2)
566 INTEGER, ALLOCATABLE, DIMENSION(:) :: iwork1, iwork2, my_index
567 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: tmp_index
568 LOGICAL :: at_least_one, check
569 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: cwork, rwork, wtmp
570 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: pot_par
571
572 CALL timeset(routinen, handle)
573
574 ntype = SIZE(atomic_kind_set)
575 DO i = 1, ntype
576 DO j = 1, i
577 potparm%pot(i, j)%pot%undef = .false.
578 END DO
579 END DO
580 ALLOCATE (tmp_index(ntype, ntype))
581 !
582 nunique = 0
583 tmp_index = huge(0)
584 DO pot_target = minval(list_pot), maxval(list_pot)
585 ndim = 0
586 DO i = 1, ntype
587 DO j = 1, i
588 IF (SIZE(potparm%pot(i, j)%pot%type) /= 1) cycle
589 IF (potparm%pot(i, j)%pot%type(1) == pot_target) THEN
590 tmp_index(i, j) = 1
591 tmp_index(j, i) = 1
592 ndim = ndim + 1
593 END IF
594 END DO
595 END DO
596 IF (ndim == 0) cycle ! No potential of this kind found
597 nvar = 0
598 SELECT CASE (pot_target)
599 CASE (lj_type, lj_charmm_type)
600 nvar = 3 + nvar
601 CASE (wl_type)
602 nvar = 3 + nvar
603 CASE (gw_type)
604 nvar = 5 + nvar
605 CASE (ea_type)
606 nvar = 4 + nvar
607 CASE (quip_type)
608 nvar = 1 + nvar
609 CASE (nequip_type)
610 nvar = 1 + nvar
611 CASE (allegro_type)
612 nvar = 1 + nvar
613 CASE (deepmd_type)
614 nvar = 2 + nvar
615 CASE (ft_type)
616 nvar = 4 + nvar
617 CASE (ftd_type)
618 nvar = 6 + nvar
619 CASE (ip_type)
620 nvar = 3 + nvar
621 CASE (b4_type)
622 nvar = 6 + nvar
623 CASE (bm_type)
624 nvar = 9 + nvar
625 CASE (gp_type)
626 nvar = 2 + nvar
627 CASE (tersoff_type)
628 nvar = 13 + nvar
629 CASE (siepmann_type)
630 nvar = 5 + nvar
631 CASE (gal_type)
632 nvar = 12 + nvar
633 CASE (gal21_type)
634 nvar = 30 + nvar
635 CASE (nn_type)
636 nvar = nvar
637 CASE (tab_type)
638 nvar = 4 + nvar
639 CASE DEFAULT
640 cpabort("")
641 END SELECT
642 ! Setup a table of the indexes..
643 ALLOCATE (my_index(ndim))
644 n = 0
645 nk = 0
646 DO i = 1, ntype
647 DO j = 1, i
648 n = n + 1
649 IF (SIZE(potparm%pot(i, j)%pot%type) /= 1) cycle
650 IF (potparm%pot(i, j)%pot%type(1) == pot_target) THEN
651 nk = nk + 1
652 my_index(nk) = n
653 END IF
654 END DO
655 END DO
656 IF (nvar /= 0) THEN
657 ALLOCATE (pot_par(ndim, nvar))
658 n = 0
659 nk = 0
660 DO i = 1, ntype
661 DO j = 1, i
662 n = n + 1
663 IF (SIZE(potparm%pot(i, j)%pot%type) /= 1) cycle
664 IF (potparm%pot(i, j)%pot%type(1) == pot_target) THEN
665 nk = nk + 1
666 my_index(nk) = n
667 SELECT CASE (pot_target)
668 CASE (lj_type, lj_charmm_type)
669 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%lj%epsilon
670 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%lj%sigma6
671 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%lj%sigma12
672 CASE (gp_type)
673 pot_par(nk, 1) = str2id(potparm%pot(i, j)%pot%set(1)%gp%potential)
674 pot_par(nk, 2) = str2id(potparm%pot(i, j)%pot%set(1)%gp%variables)
675 CASE (wl_type)
676 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%willis%a
677 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%willis%b
678 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%willis%c
679 CASE (gw_type)
680 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%goodwin%vr0
681 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%goodwin%m
682 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%goodwin%mc
683 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%goodwin%d
684 pot_par(nk, 5) = potparm%pot(i, j)%pot%set(1)%goodwin%dc
685 CASE (ea_type)
686 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%eam%drar
687 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%eam%drhoar
688 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%eam%acutal
689 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%eam%npoints
690 CASE (quip_type)
691 pot_par(nk, 1) = str2id( &
692 trim(potparm%pot(i, j)%pot%set(1)%quip%quip_file_name)// &
693 trim(potparm%pot(i, j)%pot%set(1)%quip%init_args)// &
694 trim(potparm%pot(i, j)%pot%set(1)%quip%calc_args))
695 CASE (nequip_type)
696 pot_par(nk, 1) = str2id( &
697 trim(potparm%pot(i, j)%pot%set(1)%nequip%nequip_file_name))
698 CASE (allegro_type)
699 pot_par(nk, 1) = str2id( &
700 trim(potparm%pot(i, j)%pot%set(1)%allegro%allegro_file_name))
701 CASE (deepmd_type)
702 pot_par(nk, 1) = str2id( &
703 trim(potparm%pot(i, j)%pot%set(1)%deepmd%deepmd_file_name))
704 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%deepmd%atom_deepmd_type
705 CASE (ft_type)
706 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%ft%A
707 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%ft%B
708 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%ft%C
709 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%ft%D
710 CASE (ftd_type)
711 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%ftd%A
712 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%ftd%B
713 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%ftd%C
714 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%ftd%D
715 pot_par(nk, 5) = potparm%pot(i, j)%pot%set(1)%ftd%BD(1)
716 pot_par(nk, 6) = potparm%pot(i, j)%pot%set(1)%ftd%BD(2)
717 CASE (ip_type)
718 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%ipbv%rcore
719 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%ipbv%m
720 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%ipbv%b
721 CASE (b4_type)
722 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%buck4r%a
723 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%buck4r%b
724 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%buck4r%c
725 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%buck4r%r1
726 pot_par(nk, 5) = potparm%pot(i, j)%pot%set(1)%buck4r%r2
727 pot_par(nk, 6) = potparm%pot(i, j)%pot%set(1)%buck4r%r3
728 CASE (bm_type)
729 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%buckmo%f0
730 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%buckmo%a1
731 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%buckmo%a2
732 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%buckmo%b1
733 pot_par(nk, 5) = potparm%pot(i, j)%pot%set(1)%buckmo%b2
734 pot_par(nk, 6) = potparm%pot(i, j)%pot%set(1)%buckmo%c
735 pot_par(nk, 7) = potparm%pot(i, j)%pot%set(1)%buckmo%d
736 pot_par(nk, 8) = potparm%pot(i, j)%pot%set(1)%buckmo%r0
737 pot_par(nk, 9) = potparm%pot(i, j)%pot%set(1)%buckmo%beta
738 CASE (tersoff_type)
739 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%tersoff%A
740 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%tersoff%B
741 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%tersoff%lambda1
742 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%tersoff%lambda2
743 pot_par(nk, 5) = potparm%pot(i, j)%pot%set(1)%tersoff%alpha
744 pot_par(nk, 6) = potparm%pot(i, j)%pot%set(1)%tersoff%beta
745 pot_par(nk, 7) = potparm%pot(i, j)%pot%set(1)%tersoff%n
746 pot_par(nk, 8) = potparm%pot(i, j)%pot%set(1)%tersoff%c
747 pot_par(nk, 9) = potparm%pot(i, j)%pot%set(1)%tersoff%d
748 pot_par(nk, 10) = potparm%pot(i, j)%pot%set(1)%tersoff%h
749 pot_par(nk, 11) = potparm%pot(i, j)%pot%set(1)%tersoff%lambda3
750 pot_par(nk, 12) = potparm%pot(i, j)%pot%set(1)%tersoff%bigR
751 pot_par(nk, 13) = potparm%pot(i, j)%pot%set(1)%tersoff%bigD
752 CASE (siepmann_type)
753 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%siepmann%B
754 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%siepmann%D
755 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%siepmann%E
756 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%siepmann%F
757 pot_par(nk, 5) = potparm%pot(i, j)%pot%set(1)%siepmann%beta
758 CASE (gal_type)
759 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%gal%epsilon
760 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%gal%bxy
761 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%gal%bz
762 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%gal%r1
763 pot_par(nk, 5) = potparm%pot(i, j)%pot%set(1)%gal%r2
764 pot_par(nk, 6) = potparm%pot(i, j)%pot%set(1)%gal%a1
765 pot_par(nk, 7) = potparm%pot(i, j)%pot%set(1)%gal%a2
766 pot_par(nk, 8) = potparm%pot(i, j)%pot%set(1)%gal%a3
767 pot_par(nk, 9) = potparm%pot(i, j)%pot%set(1)%gal%a4
768 pot_par(nk, 10) = potparm%pot(i, j)%pot%set(1)%gal%a
769 pot_par(nk, 11) = potparm%pot(i, j)%pot%set(1)%gal%b
770 pot_par(nk, 12) = potparm%pot(i, j)%pot%set(1)%gal%c
771 CASE (gal21_type)
772 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%gal21%epsilon1
773 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%gal21%epsilon2
774 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%gal21%epsilon3
775 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%gal21%bxy1
776 pot_par(nk, 5) = potparm%pot(i, j)%pot%set(1)%gal21%bxy2
777 pot_par(nk, 6) = potparm%pot(i, j)%pot%set(1)%gal21%bz1
778 pot_par(nk, 7) = potparm%pot(i, j)%pot%set(1)%gal21%bz2
779 pot_par(nk, 8) = potparm%pot(i, j)%pot%set(1)%gal21%r1
780 pot_par(nk, 9) = potparm%pot(i, j)%pot%set(1)%gal21%r2
781 pot_par(nk, 10) = potparm%pot(i, j)%pot%set(1)%gal21%a11
782 pot_par(nk, 11) = potparm%pot(i, j)%pot%set(1)%gal21%a12
783 pot_par(nk, 12) = potparm%pot(i, j)%pot%set(1)%gal21%a13
784 pot_par(nk, 13) = potparm%pot(i, j)%pot%set(1)%gal21%a21
785 pot_par(nk, 14) = potparm%pot(i, j)%pot%set(1)%gal21%a22
786 pot_par(nk, 15) = potparm%pot(i, j)%pot%set(1)%gal21%a23
787 pot_par(nk, 16) = potparm%pot(i, j)%pot%set(1)%gal21%a31
788 pot_par(nk, 17) = potparm%pot(i, j)%pot%set(1)%gal21%a32
789 pot_par(nk, 18) = potparm%pot(i, j)%pot%set(1)%gal21%a33
790 pot_par(nk, 19) = potparm%pot(i, j)%pot%set(1)%gal21%a41
791 pot_par(nk, 20) = potparm%pot(i, j)%pot%set(1)%gal21%a42
792 pot_par(nk, 21) = potparm%pot(i, j)%pot%set(1)%gal21%a43
793 pot_par(nk, 22) = potparm%pot(i, j)%pot%set(1)%gal21%AO1
794 pot_par(nk, 23) = potparm%pot(i, j)%pot%set(1)%gal21%AO2
795 pot_par(nk, 24) = potparm%pot(i, j)%pot%set(1)%gal21%BO1
796 pot_par(nk, 25) = potparm%pot(i, j)%pot%set(1)%gal21%BO2
797 pot_par(nk, 26) = potparm%pot(i, j)%pot%set(1)%gal21%c
798 pot_par(nk, 27) = potparm%pot(i, j)%pot%set(1)%gal21%AH1
799 pot_par(nk, 28) = potparm%pot(i, j)%pot%set(1)%gal21%AH2
800 pot_par(nk, 29) = potparm%pot(i, j)%pot%set(1)%gal21%BH1
801 pot_par(nk, 30) = potparm%pot(i, j)%pot%set(1)%gal21%BH2
802 CASE (tab_type)
803 pot_par(nk, 1) = potparm%pot(i, j)%pot%set(1)%tab%dr
804 pot_par(nk, 2) = potparm%pot(i, j)%pot%set(1)%tab%rcut
805 pot_par(nk, 3) = potparm%pot(i, j)%pot%set(1)%tab%npoints
806 pot_par(nk, 4) = potparm%pot(i, j)%pot%set(1)%tab%index
807 CASE (nn_type)
808 ! no checks
809 CASE DEFAULT
810 cpabort("")
811 END SELECT
812 IF (any(potential_single_allocation == pot_target)) THEN
813 pot_par(nk, :) = real(pot_target, kind=dp)
814 END IF
815 END IF
816 END DO
817 END DO
818 ! Main Sorting Loop
819 ALLOCATE (rwork(ndim))
820 ALLOCATE (iwork1(ndim))
821 ALLOCATE (iwork2(ndim))
822 ALLOCATE (wtmp(nvar))
823 CALL sort(pot_par(:, 1), ndim, iwork1)
824 ! Sort all the other components of the potential
825 DO k = 2, nvar
826 rwork(:) = pot_par(:, k)
827 DO i = 1, ndim
828 pot_par(i, k) = rwork(iwork1(i))
829 END DO
830 END DO
831 iwork2(:) = my_index
832 DO i = 1, ndim
833 my_index(i) = iwork2(iwork1(i))
834 END DO
835 ! Iterative sorting
836 DO k = 2, nvar
837 wtmp(1:k - 1) = pot_par(1, 1:k - 1)
838 istart = 1
839 at_least_one = .false.
840 DO j = 1, ndim
841 rwork(j) = pot_par(j, k)
842 IF (all(pot_par(j, 1:k - 1) == wtmp(1:k - 1))) cycle
843 iend = j - 1
844 wtmp(1:k - 1) = pot_par(j, 1:k - 1)
845 ! If the ordered array has no two same consecutive elements
846 ! does not make any sense to proceed ordering the others
847 ! related parameters..
848 idim = iend - istart + 1
849 CALL sort(rwork(istart:iend), idim, iwork1(istart:iend))
850 iwork1(istart:iend) = iwork1(istart:iend) - 1 + istart
851 IF (idim /= 1) at_least_one = .true.
852 istart = j
853 END DO
854 iend = ndim
855 idim = iend - istart + 1
856 CALL sort(rwork(istart:iend), idim, iwork1(istart:iend))
857 iwork1(istart:iend) = iwork1(istart:iend) - 1 + istart
858 IF (idim /= 1) at_least_one = .true.
859 pot_par(:, k) = rwork
860 IF (.NOT. at_least_one) EXIT
861 ! Sort other components
862 DO j = k + 1, nvar
863 rwork(:) = pot_par(:, j)
864 DO i = 1, ndim
865 pot_par(i, j) = rwork(iwork1(i))
866 END DO
867 END DO
868 iwork2(:) = my_index
869 DO i = 1, ndim
870 my_index(i) = iwork2(iwork1(i))
871 END DO
872 END DO
873 DEALLOCATE (wtmp)
874 DEALLOCATE (iwork1)
875 DEALLOCATE (iwork2)
876 DEALLOCATE (rwork)
877 !
878 ! Let's determine the number of unique potentials and tag them
879 !
880 ALLOCATE (cwork(nvar))
881 cwork(:) = pot_par(1, :)
882 locij = my_index(1)
883 CALL get_indexes(locij, ntype, tmpij0)
884 istart = 1
885 DO j = 1, ndim
886 ! Special cases for EAM and IPBV
887 locij = my_index(j)
888 CALL get_indexes(locij, ntype, tmpij)
889 SELECT CASE (pot_target)
890 !NB should do something about QUIP here?
891 CASE (ea_type, ip_type)
892 ! check the array components
893 CALL compare_pot(potparm%pot(tmpij(1), tmpij(2))%pot, &
894 potparm%pot(tmpij0(1), tmpij0(2))%pot, &
895 check)
896 CASE (gp_type)
897 check = .true.
898 IF (ASSOCIATED(potparm%pot(tmpij(1), tmpij(2))%pot%set(1)%gp%parameters) .AND. &
899 ASSOCIATED(potparm%pot(tmpij0(1), tmpij0(2))%pot%set(1)%gp%parameters)) THEN
900 IF (SIZE(potparm%pot(tmpij(1), tmpij(2))%pot%set(1)%gp%parameters) == &
901 SIZE(potparm%pot(tmpij0(1), tmpij0(2))%pot%set(1)%gp%parameters)) THEN
902 IF (any(potparm%pot(tmpij(1), tmpij(2))%pot%set(1)%gp%parameters /= &
903 potparm%pot(tmpij0(1), tmpij0(2))%pot%set(1)%gp%parameters)) check = .false.
904 END IF
905 END IF
906 IF (ASSOCIATED(potparm%pot(tmpij(1), tmpij(2))%pot%set(1)%gp%values) .AND. &
907 ASSOCIATED(potparm%pot(tmpij0(1), tmpij0(2))%pot%set(1)%gp%values)) THEN
908 IF (SIZE(potparm%pot(tmpij(1), tmpij(2))%pot%set(1)%gp%values) == &
909 SIZE(potparm%pot(tmpij0(1), tmpij0(2))%pot%set(1)%gp%values)) THEN
910 IF (any(potparm%pot(tmpij(1), tmpij(2))%pot%set(1)%gp%values /= &
911 potparm%pot(tmpij0(1), tmpij0(2))%pot%set(1)%gp%values)) check = .false.
912 END IF
913 END IF
914 CASE default
915 check = .true.
916 END SELECT
917 IF (all(cwork == pot_par(j, :)) .AND. check) cycle
918 cwork(:) = pot_par(j, :)
919 nunique = nunique + 1
920 iend = j - 1
921 CALL set_potparm_index(potparm, my_index(istart:iend), pot_target, &
922 ntype, tmpij, atomic_kind_set, shift_cutoff, do_zbl)
923 !
924 DO i = istart, iend
925 locij = my_index(i)
926 CALL get_indexes(locij, ntype, tmpij)
927 tmp_index(tmpij(1), tmpij(2)) = nunique
928 tmp_index(tmpij(2), tmpij(1)) = nunique
929 END DO
930 istart = j
931 locij = my_index(j)
932 CALL get_indexes(locij, ntype, tmpij0)
933 END DO
934 nunique = nunique + 1
935 iend = ndim
936 CALL set_potparm_index(potparm, my_index(istart:iend), pot_target, &
937 ntype, tmpij, atomic_kind_set, shift_cutoff, do_zbl)
938 DO i = istart, iend
939 locij = my_index(i)
940 CALL get_indexes(locij, ntype, tmpij)
941 tmp_index(tmpij(1), tmpij(2)) = nunique
942 tmp_index(tmpij(2), tmpij(1)) = nunique
943 END DO
944 DEALLOCATE (cwork)
945 DEALLOCATE (pot_par)
946 ELSE
947 nunique = nunique + 1
948 CALL set_potparm_index(potparm, my_index, pot_target, ntype, tmpij, &
949 atomic_kind_set, shift_cutoff, do_zbl)
950 END IF
951 DEALLOCATE (my_index)
952 END DO
953 ! Multiple defined potential
954 n = 0
955 DO i = 1, ntype
956 DO j = 1, i
957 n = n + 1
958 IF (SIZE(potparm%pot(i, j)%pot%type) == 1) cycle
959 nunique = nunique + 1
960 tmp_index(i, j) = nunique
961 tmp_index(j, i) = nunique
962 !
963 CALL set_potparm_index(potparm, (/n/), multi_type, ntype, tmpij, &
964 atomic_kind_set, shift_cutoff, do_zbl)
965 END DO
966 END DO
967 ! Concluding the postprocess..
968 ALLOCATE (spline_env)
969 CALL spline_env_create(spline_env, ntype, nunique)
970 spline_env%spltab = tmp_index
971 DEALLOCATE (tmp_index)
972 CALL timestop(handle)
973 END SUBROUTINE get_nonbond_storage
974
975! **************************************************************************************************
976!> \brief Trivial for non LJ potential.. gives back in the case of LJ
977!> the potparm with the smallest sigma..
978!> \param potparm ...
979!> \param my_index ...
980!> \param pot_target ...
981!> \param ntype ...
982!> \param tmpij_out ...
983!> \param atomic_kind_set ...
984!> \param shift_cutoff ...
985!> \param do_zbl ...
986!> \author Teodoro Laino [tlaino] 2007.06
987! **************************************************************************************************
988 SUBROUTINE set_potparm_index(potparm, my_index, pot_target, ntype, tmpij_out, &
989 atomic_kind_set, shift_cutoff, do_zbl)
990
991 TYPE(pair_potential_pp_type), POINTER :: potparm
992 INTEGER, INTENT(IN) :: my_index(:), pot_target, ntype
993 INTEGER, INTENT(OUT) :: tmpij_out(2)
994 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
995 LOGICAL, INTENT(IN) :: shift_cutoff, do_zbl
996
997 CHARACTER(len=*), PARAMETER :: routinen = 'set_potparm_index'
998
999 INTEGER :: handle, i, min_val, nvalues, tmpij(2), &
1000 value, zi, zj
1001 INTEGER, ALLOCATABLE, DIMENSION(:) :: wrk
1002 LOGICAL :: check
1003 REAL(kind=dp) :: hicut0, l_epsilon, l_sigma6, m_epsilon, &
1004 m_sigma6, min_sigma6, rcovi, rcovj
1005 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: sigma6
1006 TYPE(atomic_kind_type), POINTER :: atomic_kind
1007 TYPE(pair_potential_single_type), POINTER :: pot, pot_ref
1008
1009 CALL timeset(routinen, handle)
1010
1011 NULLIFY (pot, pot_ref)
1012 nvalues = SIZE(my_index)
1013 IF ((pot_target == lj_type) .OR. (pot_target == lj_charmm_type)) THEN
1014 ALLOCATE (sigma6(nvalues))
1015 ALLOCATE (wrk(nvalues))
1016 min_sigma6 = huge(0.0_dp)
1017 m_epsilon = -huge(0.0_dp)
1018 DO i = 1, nvalues
1019 value = my_index(i)
1020 CALL get_indexes(value, ntype, tmpij)
1021 pot => potparm%pot(tmpij(1), tmpij(2))%pot
1022 ! Preliminary check..
1023 check = SIZE(pot%type) == 1
1024 cpassert(check)
1025
1026 sigma6(i) = pot%set(1)%lj%sigma6
1027 l_epsilon = pot%set(1)%lj%epsilon
1028 IF (sigma6(i) /= 0.0_dp) min_sigma6 = min(min_sigma6, sigma6(i))
1029 IF (sigma6(i) == 0.0_dp) sigma6(i) = -huge(0.0_dp)
1030 IF (l_epsilon /= 0.0_dp) m_epsilon = max(m_epsilon, l_epsilon)
1031 END DO
1032 CALL sort(sigma6, nvalues, wrk)
1033 min_val = my_index(wrk(nvalues))
1034 m_sigma6 = sigma6(nvalues)
1035 ! In case there are only zeros.. let's consider them properly..
1036 IF (m_sigma6 == -huge(0.0_dp)) m_sigma6 = 1.0_dp
1037 IF (m_epsilon == -huge(0.0_dp)) m_epsilon = 0.0_dp
1038 IF (min_sigma6 == huge(0.0_dp)) min_sigma6 = 0.0_dp
1039 DEALLOCATE (sigma6)
1040 DEALLOCATE (wrk)
1041 ELSE
1042 min_val = minval(my_index(:))
1043 END IF
1044 CALL get_indexes(min_val, ntype, tmpij)
1045 tmpij_out = tmpij
1046 pot => potparm%pot(tmpij(1), tmpij(2))%pot
1047 pot%undef = .true.
1048 IF (shift_cutoff) THEN
1049 hicut0 = sqrt(pot%rcutsq)
1050 IF (abs(hicut0) <= min_hicut_value) hicut0 = default_hicut_value
1051 END IF
1052 CALL init_genpot(potparm, ntype)
1053
1054 DO i = 1, nvalues
1055 value = my_index(i)
1056 CALL get_indexes(value, ntype, tmpij)
1057 pot => potparm%pot(tmpij(1), tmpij(2))%pot
1058 CALL spline_factor_create(pot%spl_f)
1059 pot%spl_f%rcutsq_f = 1.0_dp
1060 pot%spl_f%rscale = 1.0_dp
1061 pot%spl_f%fscale = 1.0_dp
1062 END DO
1063
1064 IF (any(potential_single_allocation == pot_target)) THEN
1065 DO i = 1, nvalues
1066 value = my_index(i)
1067 CALL get_indexes(value, ntype, tmpij)
1068 pot => potparm%pot(tmpij(1), tmpij(2))%pot
1069
1070 check = SIZE(pot%type) == 1
1071 cpassert(check)
1072 ! Undef potential.. this will be used to compute the splines..
1073 IF ((pot_target == lj_type) .OR. (pot_target == lj_charmm_type)) THEN
1074 l_sigma6 = pot%set(1)%lj%sigma6
1075 l_epsilon = pot%set(1)%lj%epsilon
1076 ! Undef potential.. this will be used to compute the splines..
1077 IF (pot%undef) THEN
1078 pot%set(1)%lj%sigma6 = m_sigma6
1079 pot%set(1)%lj%sigma12 = m_sigma6**2
1080 pot%set(1)%lj%epsilon = m_epsilon
1081 END IF
1082 pot%spl_f%rscale(1) = 1.0_dp
1083 pot%spl_f%fscale(1) = 0.0_dp
1084 IF (l_sigma6*l_epsilon /= 0.0_dp) THEN
1085 pot%spl_f%rcutsq_f = (min_sigma6/m_sigma6)**(1.0_dp/3.0_dp)
1086 pot%spl_f%rscale(1) = (l_sigma6/m_sigma6)**(1.0_dp/3.0_dp)
1087 pot%spl_f%fscale(1) = l_epsilon/m_epsilon
1088 END IF
1089 END IF
1090 END DO
1091 END IF
1092
1093 DO i = 1, nvalues
1094 value = my_index(i)
1095 CALL get_indexes(value, ntype, tmpij)
1096 pot => potparm%pot(tmpij(1), tmpij(2))%pot
1097
1098 IF (do_zbl) THEN
1099 atomic_kind => atomic_kind_set(tmpij(1))
1100 CALL get_atomic_kind(atomic_kind, rcov=rcovi, z=zi)
1101 atomic_kind => atomic_kind_set(tmpij(2))
1102 CALL get_atomic_kind(atomic_kind, rcov=rcovj, z=zj)
1103 CALL zbl_matching_polinomial(pot, rcovi, rcovj, real(zi, kind=dp), &
1104 REAL(zj, kind=dp))
1105 END IF
1106 ! Derivative factors
1107 pot%spl_f%dscale = pot%spl_f%fscale/pot%spl_f%rscale
1108 ! Cutoff for the potentials on splines
1109 IF (shift_cutoff) THEN
1110 ! Cutoff NonBonded
1111 pot%spl_f%cutoff = ener_pot(pot, hicut0, 0.0_dp)
1112 END IF
1113 END DO
1114
1115 ! Handle the cutoff
1116 IF (shift_cutoff) THEN
1117 pot_ref => potparm%pot(tmpij_out(1), tmpij_out(2))%pot
1118 DO i = 1, nvalues
1119 value = my_index(i)
1120 CALL get_indexes(value, ntype, tmpij)
1121 pot => potparm%pot(tmpij(1), tmpij(2))%pot
1122 IF (value == min_val) cycle
1123 ! Cutoff NonBonded
1124 pot%spl_f%cutoff = pot_ref%spl_f%cutoff*pot%spl_f%fscale(1) - pot%spl_f%cutoff
1125 END DO
1126 END IF
1127 CALL finalizef()
1128
1129 CALL timestop(handle)
1130
1131 END SUBROUTINE set_potparm_index
1132
1133! **************************************************************************************************
1134!> \brief Gives back the indices of the matrix w.r.t. the collective array index
1135!> \param Inind ...
1136!> \param ndim ...
1137!> \param ij ...
1138!> \author Teodoro Laino [tlaino] 2006.05
1139! **************************************************************************************************
1140 SUBROUTINE get_indexes(Inind, ndim, ij)
1141 INTEGER, INTENT(IN) :: inind, ndim
1142 INTEGER, DIMENSION(2), INTENT(OUT) :: ij
1143
1144 INTEGER :: i, tmp
1145
1146 tmp = 0
1147 ij = huge(0)
1148 DO i = 1, ndim
1149 tmp = tmp + i
1150 IF (tmp >= inind) THEN
1151 ij(1) = i
1152 ij(2) = inind - tmp + i
1153 EXIT
1154 END IF
1155 END DO
1156 END SUBROUTINE get_indexes
1157
1158END MODULE pair_potential
1159
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:308
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:119
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
This public domain function parser module is intended for applications where a set of mathematical ex...
Definition fparser.F:17
subroutine, public parsef(i, funcstr, var)
Parse ith function string FuncStr and compile it into bytecode.
Definition fparser.F:148
subroutine, public finalizef()
...
Definition fparser.F:101
subroutine, public initf(n)
...
Definition fparser.F:130
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
integer, dimension(21), parameter, public list_pot
integer, parameter, public lj_charmm_type
integer, parameter, public allegro_type
integer, parameter, public bm_type
integer, parameter, public gal_type
integer, parameter, public nequip_type
integer, parameter, public wl_type
integer, parameter, public ft_type
integer, parameter, public tab_type
integer, parameter, public ftd_type
integer, parameter, public ip_type
integer, parameter, public lj_type
integer, parameter, public deepmd_type
integer, parameter, public nn_type
integer, parameter, public multi_type
integer, parameter, public quip_type
integer, parameter, public gp_type
integer, parameter, public siepmann_type
subroutine, public compare_pot(pot1, pot2, compare)
compare two different potentials
integer, parameter, public gw_type
integer, parameter, public b4_type
integer, parameter, public gal21_type
integer, dimension(2), public potential_single_allocation
integer, parameter, public ea_type
integer, parameter, public tersoff_type
real(kind=dp) function, public ener_zbl(pot, r)
Evaluates the ZBL scattering potential, very short range Only shell-model for interactions among pair...
real(kind=dp) function, public ener_pot(pot, r, energy_cutoff)
Evaluates the nonbond potential energy for the implemented FF kinds.
subroutine, public zbl_matching_polinomial(pot, rcov1, rcov2, z1, z2)
Determine the polinomial coefficients used to set to zero the zbl potential at the cutoff radius,...
subroutine, public spline_nonbond_control(spline_env, potparm, atomic_kind_set, eps_spline, max_energy, rlow_nb, emax_spline, npoints, iw, iw2, iw3, do_zbl, shift_cutoff, nonbonded_type)
creates the splines for the potentials
subroutine, public get_nonbond_storage(spline_env, potparm, atomic_kind_set, do_zbl, shift_cutoff)
Prescreening of the effective bonds evaluations. linear scaling algorithm.
subroutine, public init_genpot(potparm, ntype)
Initialize genpot.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public evolt
Definition physcon.F:183
real(kind=dp), parameter, public kjmol
Definition physcon.F:168
real(kind=dp), parameter, public bohr
Definition physcon.F:147
routines for handling splines
pure subroutine, public init_splinexy(spl, nn)
allocates storage for function table to be interpolated both x and y are allocated
pure subroutine, public init_spline(spl, dx, y1a, y1b)
allocates storage for y2 table calculates y2 table and other spline parameters
real(kind=dp) function, public potential_s(spl_p, xxi, y1, spl_f, logger)
calculates the potential interpolated with splines value at a given point and the first derivative....
routines for handling splines_types
subroutine, public spline_factor_release(spline_factor)
releases spline_factor
subroutine, public spline_factor_create(spline_factor)
releases spline_factor
subroutine, public spline_env_create(spline_env, ntype, ntab_in)
Data-structure that holds all needed information about a specific spline interpolation.
generates a unique id number for a string (str2id) that can be used two compare two strings....
integer function, public str2id(str)
returns a unique id for a given string, and stores the string for later retrieval using the id.
All kind of helpful little routines.
Definition util.F:14
Provides all information about an atomic kind.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Data-structure that holds all needed information about a specific spline interpolation.