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